index.vue 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009
  1. <template>
  2. <view class="device-details-page">
  3. <cu-custom :isBack="true">
  4. <template slot="content">
  5. <view class="nav-title">{{ deviceInfo.devName }}</view>
  6. </template>
  7. </cu-custom>
  8. <!-- 设备基本信息 -->
  9. <view class="device-info">
  10. <view class="operation" @click.stop="isShowOperation = !isShowOperation">操作</view>
  11. <view class="operation-container" v-if="isShowOperation" @click="closeOperationHandler">
  12. <view class="operation-background"></view>
  13. <view class="operation-content">
  14. <view class="operation-item" @click="goPage('devRepair')">
  15. <image :src="serviceIcon" class="operation-icon"></image>
  16. 维修
  17. </view>
  18. <view class="operation-item" @click="goPage('devControl')">
  19. <image :src="settingIcon" class="operation-icon"></image>
  20. 设置
  21. </view>
  22. <view class="operation-item" @click="goPage('simDetail')">
  23. <image :src="simIcon" class="operation-icon"></image>
  24. SIM卡
  25. </view>
  26. <!-- <view class="operation-item" @click="modification">
  27. <image :src="editIcon" class="operation-icon"></image>
  28. 修改
  29. </view> -->
  30. </view>
  31. </view>
  32. <view @click="copy(deviceInfo.devBid)" class="info-item">
  33. <text class="info-label">设备ID</text>
  34. <text class="info-value">{{ deviceInfo.devBid }}</text>
  35. <image
  36. src="/static/images/device/copy.svg"
  37. mode=""
  38. class="info-img"
  39. ></image>
  40. </view>
  41. <view class="info-item">
  42. <text class="info-label">上报时间</text>
  43. <text class="info-value">{{ formatTimestamp(deviceInfo.uptime) }}</text>
  44. </view>
  45. <view class="info-item">
  46. <text class="info-label">设备位置</text>
  47. <text class="info-value">{{ deviceInfo.address }}</text>
  48. </view>
  49. <view class="dev-status">{{
  50. deviceInfo.devStatus == '1' ? '在线' : '离线'
  51. }}</view>
  52. </view>
  53. <!-- 标签页切换 -->
  54. <view class="tab-container">
  55. <view class="tab-top">
  56. <view
  57. class="tab-item"
  58. :class="{ active: activeTab === 'monitoring' }"
  59. @click="switchTab('monitoring')"
  60. >
  61. <text class="tab-text">监测要素</text>
  62. <image
  63. v-if="activeTab === 'monitoring'"
  64. src="/static/images/device/smile.svg"
  65. mode=""
  66. class="smile"
  67. ></image>
  68. </view>
  69. <view
  70. class="tab-item"
  71. :class="{ active: activeTab === 'details' }"
  72. @click="switchTab('details')"
  73. >
  74. <text class="tab-text">设备数据</text>
  75. <image
  76. v-if="activeTab === 'details'"
  77. src="/static/images/device/smile.svg"
  78. mode=""
  79. class="smile"
  80. ></image>
  81. </view>
  82. </view>
  83. </view>
  84. <!-- 标签页内容 -->
  85. <view class="tab-content">
  86. <!-- 监测要素页面 -->
  87. <view v-if="activeTab === 'monitoring'" class="monitoring-page">
  88. <view
  89. class="data-card"
  90. v-for="(item, index) in monitorList"
  91. :key="index"
  92. @click="goPage('eleDetail', item)"
  93. >
  94. <view class="card-title">{{ item.name }}</view>
  95. <view class="data-value-row">
  96. <view>
  97. <text v-if="item.value && item.value.length" class="data-value">{{
  98. item.value
  99. }}</text>
  100. <text class="data-unit">{{ item.unit }}</text>
  101. </view>
  102. <image
  103. class="device-img"
  104. :src="`/static/images/device/${item.key}-default.svg`"
  105. mode="aspectFit"
  106. ></image>
  107. </view>
  108. </view>
  109. </view>
  110. <!-- 设备详情页面 -->
  111. <view v-if="activeTab === 'details'" class="details-page">
  112. <view class="device-params">
  113. <view class="device-control">
  114. <view class="control-left">
  115. <view>{{formatTimestamp(deviceInfo.uptime)}}</view>
  116. <u-icon name="reload" color="#0BBC58" style="margin-left: 12rpx" @click="refreshData"></u-icon>
  117. </view>
  118. </view>
  119. <view class="params-board">
  120. <view class="params-left-container">
  121. <view class="params-left">
  122. <view
  123. v-for="(item, index) in statusList.slice(0, 4)"
  124. :key="index"
  125. class="params-item"
  126. >
  127. <view class="params-val">
  128. {{ item.value }}
  129. <span class="unit">{{ item.unit }}</span>
  130. </view>
  131. <view class="params-label">{{ item.name }}</view>
  132. </view>
  133. </view><view class="params-left">
  134. <view
  135. v-for="(item, index) in statusList.slice(4, 8)"
  136. :key="index"
  137. class="params-item"
  138. >
  139. <view class="params-val">
  140. {{ item.value }}
  141. <span class="unit">{{ item.unit }}</span>
  142. </view>
  143. <view class="params-label">{{ item.name }}</view>
  144. </view>
  145. </view>
  146. </view>
  147. <view class="params-right">
  148. <image
  149. class="device-img"
  150. style="width: 150rpx; height: 300rpx;"
  151. :src="qxzImg"
  152. mode="aspectFit"
  153. ></image>
  154. </view>
  155. </view>
  156. </view>
  157. <!-- 设备数据表格 -->
  158. <view class="table-container">
  159. <view class="table-control">
  160. <view class="title">设备数据</view>
  161. <view class="date-board" @click="openDatePicker">
  162. <text>{{ startDate }}</text>
  163. <text class="line">至</text>
  164. <text>{{ endDate }}</text>
  165. <image class="date-icon" src="/static/images/device/date.svg" />
  166. </view>
  167. </view>
  168. <u-calendar
  169. v-model="show"
  170. :mode="mode"
  171. @change="onDateChange"
  172. range-color="#999" btn-type="success" active-bg-color="#0BBC58" range-bg-color="rgba(11,188,88,0.13)"
  173. ref="calendar"
  174. ></u-calendar>
  175. <view class="table-wrap" v-if="tableData && tableData.length > 0">
  176. <view class="fixed-column">
  177. <view class="table-cell header">上报时间</view>
  178. <view
  179. class="table-cell"
  180. v-for="(item, idx) in tableData"
  181. :key="idx"
  182. >
  183. {{ item.time }}
  184. </view>
  185. </view>
  186. <view class="table-bg"></view>
  187. <scroll-view class="scroll-column" scroll-x="true">
  188. <view class="scroll-content">
  189. <view class="table-row">
  190. <view
  191. class="table-cell header"
  192. v-for="(item, index) in tableColumn"
  193. :key="index"
  194. >{{ item.label }}</view
  195. >
  196. </view>
  197. <view
  198. class="table-row"
  199. v-for="(item, idx) in tableData"
  200. :key="idx"
  201. >
  202. <view
  203. class="table-cell"
  204. v-for="(item1, index1) in tableColumn"
  205. :key="index1"
  206. >{{ item[item1.prop] }}</view
  207. >
  208. </view>
  209. </view>
  210. </scroll-view>
  211. </view>
  212. <view class="empty-state" v-else>
  213. <u-empty text="暂无数据" mode="list"></u-empty>
  214. </view>
  215. <view class="pagination" v-if="tableData && tableData.length > 0">
  216. <view
  217. class="page-item prev"
  218. :class="{ disabled: page <= 1 }"
  219. @click="prevPage"
  220. >上一页</view
  221. >
  222. <view class="page-info">
  223. <text class="curret-page">{{ page }}</text>
  224. <text>/</text>
  225. <text>{{ totalPages }}</text>
  226. </view>
  227. <view
  228. class="page-item next"
  229. :class="{ disabled: page >= totalPages }"
  230. @click="nextPage"
  231. >下一页</view
  232. >
  233. </view>
  234. </view>
  235. </view>
  236. </view>
  237. </view>
  238. </template>
  239. <script>
  240. import qxzImg from '@/static/images/device/qxz_low.png';
  241. export default {
  242. onLoad(options) {
  243. this.deviceInfo = options;
  244. this.initDateRange(options.uptime);
  245. this.getQxzObData();
  246. // this.getDeviceStatus();
  247. this.getDeviceData();
  248. },
  249. data() {
  250. return {
  251. qxzImg,
  252. deviceInfo: {},
  253. isShowOperation: false,
  254. activeTab: 'monitoring',
  255. monitorList: [],
  256. statusList: [],
  257. show: false,
  258. mode: 'range',
  259. startDate: '',
  260. endDate: '',
  261. page: 1,
  262. photoIcon:'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/newImg/home/photoIcon.png',
  263. editIcon:'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/newImg/home/editIcon.png',
  264. serviceIcon:'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/newImg/home/serviceIcon.png',
  265. simIcon:'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/newImg/home/simIcon.png',
  266. settingIcon:'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/newImg/home/settingIcon.png',
  267. isShowPhoto:false,
  268. pageSize: 9,
  269. total: 0,
  270. tableData: [],
  271. tableColumn: [],
  272. };
  273. },
  274. computed: {
  275. totalPages() {
  276. return Math.ceil(this.total / this.pageSize) || 1;
  277. },
  278. },
  279. methods: {
  280. closeOperationHandler(){
  281. this.isShowOperation = false;
  282. },
  283. async refreshData(){
  284. //api/api_gateway?method=qxz.device.control
  285. await this.$myRequest({
  286. url: '/api/api_gateway?method=qxz.device.control',
  287. data: {
  288. device_id: this.deviceInfo.devBid,
  289. cmd: 'READ',
  290. },
  291. });
  292. //弹框提示
  293. uni.showToast({
  294. title: '刷新成功',
  295. icon: 'success',
  296. });
  297. this.getDeviceData();
  298. },
  299. formatTimestamp(timestamp) {
  300. if (!timestamp) return '';
  301. const date = new Date(Number(timestamp) * 1000);
  302. const year = date.getFullYear();
  303. const month = String(date.getMonth() + 1).padStart(2, '0');
  304. const day = String(date.getDate()).padStart(2, '0');
  305. const hours = String(date.getHours()).padStart(2, '0');
  306. const minutes = String(date.getMinutes()).padStart(2, '0');
  307. const seconds = String(date.getSeconds()).padStart(2, '0');
  308. return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  309. },
  310. formatDate(date) {
  311. const year = date.getFullYear();
  312. const month = String(date.getMonth() + 1).padStart(2, '0');
  313. const day = String(date.getDate()).padStart(2, '0');
  314. return `${year}-${month}-${day}`;
  315. },
  316. initDateRange(timestamp) {
  317. if (!timestamp) {
  318. const today = new Date();
  319. this.endDate = this.formatDate(today);
  320. const startDate = new Date(today);
  321. startDate.setDate(startDate.getDate() - 7);
  322. this.startDate = this.formatDate(startDate);
  323. return;
  324. }
  325. const date = new Date(Number(timestamp) * 1000);
  326. this.endDate = this.formatDate(date);
  327. const startDate = new Date(date);
  328. startDate.setDate(startDate.getDate() - 7);
  329. this.startDate = this.formatDate(startDate);
  330. },
  331. switchTab(tab) {
  332. this.activeTab = tab;
  333. },
  334. copy(item) {
  335. uni.setClipboardData({
  336. data: item,
  337. success: function () {
  338. },
  339. });
  340. },
  341. goPage(type, eleItem) {
  342. let url = '';
  343. console.log(type,eleItem,'deviceInfodeviceInfo')
  344. if (eleItem && eleItem.key) {
  345. url = `/pages/deviceDetails/weatherStation1/${type}?deviceInfo=${encodeURIComponent(JSON.stringify(this.deviceInfo))}&eleKey=${eleItem.name}`;
  346. } else {
  347. url = `/pages/deviceDetails/weatherStation1/${type}?deviceInfo=${encodeURIComponent(JSON.stringify(this.deviceInfo))}`;
  348. }
  349. if (type === 'devRepair') {
  350. url = `/pages/afterSale/addafter?d_id=${this.deviceInfo.d_id}&device_id=${this.deviceInfo.devBid}&device_type=${this.deviceInfo.deviceType}`;
  351. }
  352. uni.navigateTo({
  353. url,
  354. });
  355. },
  356. openDatePicker() {
  357. this.show = true;
  358. },
  359. onDateChange(event) {
  360. if (event && event.startDate && event.endDate) {
  361. this.startDate = event.startDate;
  362. this.endDate = event.endDate;
  363. this.show = false;
  364. this.page = 1;
  365. this.getDeviceData();
  366. }
  367. },
  368. prevPage() {
  369. if (this.page <= 1) return;
  370. this.page--;
  371. this.getDeviceData();
  372. },
  373. nextPage() {
  374. if (this.page >= this.totalPages) return;
  375. this.page++;
  376. this.getDeviceData();
  377. },
  378. // 获取设备最新监测数据
  379. async getQxzObData() {
  380. const res = await this.$myRequest({
  381. url: '/api/api_gateway?method=greenhouse.env_first.recent_data',
  382. data: {
  383. device_id: this.deviceInfo.devBid,
  384. },
  385. });
  386. const recent = res.recent || [];
  387. this.statusList = recent;
  388. // recent.forEach(item => {
  389. // this.statusList.push({
  390. // label: item.name,
  391. // val: item.value,
  392. // key: item.name,
  393. // })
  394. // })
  395. this.monitorList = this.formatChartData(res.recent);
  396. },
  397. async getMonitorData(){
  398. const res = await this.$myRequest({
  399. url: '/api/api_gateway?method=greenhouse.env_first.monitor_data',
  400. data: {
  401. device_id: this.deviceInfo.devBid,
  402. },
  403. });
  404. },
  405. formatChartData(data) {
  406. data.forEach(item => {
  407. if(item.name == '空气温度'){
  408. item.key = 'TEMPA';
  409. }else if(item.name == '空气湿度'){
  410. item.key = 'HUMIA';
  411. }else if(item.name == '风速'){
  412. item.key = 'PRESA';
  413. }else if(item.name == '风向'){
  414. item.key = 'WDIRA';
  415. }else if(item.name == '光照度'){
  416. item.key = 'ILLUA';
  417. }else if(item.name == '降雨量累计'){
  418. item.key = 'PRECA';
  419. }else{
  420. item.key = 'TEMPA';
  421. }
  422. })
  423. return data;
  424. },
  425. convertDynamic(data, getLabelValue) {
  426. if (!data || typeof data !== 'object') return [];
  427. const result = [];
  428. const keys = Object.keys(data);
  429. for (const prop of keys) {
  430. const arr = data[prop];
  431. const value = getLabelValue(prop, arr, data);
  432. if (value !== undefined && value !== null) {
  433. result.push({
  434. label: String(value),
  435. prop,
  436. align: 'center',
  437. });
  438. }
  439. }
  440. return result;
  441. },
  442. // 获取设备状态数据
  443. async getDeviceStatus() {
  444. const res = await this.$myRequest({
  445. url: '/api/api_gateway?method=qxz.data.qxz_status',
  446. data: {
  447. device_id: this.deviceInfo.devBid,
  448. },
  449. });
  450. const newArr = this.transformObjectToArray(res);
  451. this.statusList = newArr;
  452. },
  453. transformObjectToArray(originalData) {
  454. if (
  455. typeof originalData !== 'object' ||
  456. originalData === null ||
  457. Array.isArray(originalData)
  458. ) {
  459. return [];
  460. }
  461. return Object.keys(originalData).map((key) => {
  462. const [val = '', label = ''] = originalData[key] || [];
  463. return {
  464. label,
  465. val,
  466. key,
  467. };
  468. });
  469. },
  470. // 设备数据列表
  471. async getDeviceData() {
  472. const data = await this.$myRequest({
  473. url: '/api/api_gateway?method=greenhouse.env_first.history_data',
  474. data: {
  475. device_id: this.deviceInfo.devBid,
  476. page: String(this.page),
  477. page_size: String(this.pageSize),
  478. start: String(
  479. Math.floor(new Date(this.startDate + ' 00:00:00').getTime() / 1000),
  480. ),
  481. end: String(
  482. Math.floor(new Date(this.endDate + ' 23:59:59').getTime() / 1000),
  483. ),
  484. },
  485. });
  486. this.total = data?.total || 0;
  487. this.tableData = data.table || [];
  488. const title = data.title;
  489. this.tableColumn = title
  490. .map((item) => {
  491. return {
  492. label: item.name,
  493. prop: item.key,
  494. };
  495. })
  496. .filter((item) => item.key !== 'time');
  497. },
  498. },
  499. };
  500. </script>
  501. <style lang="scss">
  502. .device-details-page {
  503. background:
  504. linear-gradient(180deg, #ffffff00 0%, #f5f6fa 23.64%, #f5f6fa 100%),
  505. linear-gradient(102deg, #bfeadd 6.77%, #b8f1e7 40.15%, #b9eef5 84.02%);
  506. min-height: 100vh;
  507. padding: 0 32rpx;
  508. padding-top: 98rpx;
  509. }
  510. .nav-title{
  511. //超出隐藏
  512. overflow: hidden;
  513. text-overflow: ellipsis;
  514. white-space: nowrap;
  515. text-align: center;
  516. }
  517. /* 设备基本信息 */
  518. .device-info {
  519. background-color: #ffffff;
  520. margin: 46rpx 0 24rpx 0;
  521. padding: 32rpx 24rpx;
  522. border-radius: 16rpx;
  523. background: linear-gradient(180deg, #eff 0%, #fff 23.56%);
  524. position: relative;
  525. .info-item {
  526. display: flex;
  527. align-items: center;
  528. margin-bottom: 16rpx;
  529. }
  530. .info-item:last-child {
  531. margin-bottom: 0;
  532. }
  533. .operation-container{
  534. position: fixed;
  535. right: 0;
  536. top: 0;
  537. width: 100%;
  538. height: 100%;
  539. z-index: 99;
  540. }
  541. .operation{
  542. position: fixed;
  543. top: 260rpx;
  544. right: 0;
  545. z-index: 999;
  546. width:48rpx;
  547. height: 100rpx;
  548. line-height: 50rpx;
  549. border-radius: 8px 0 0 8px;
  550. border-top: 4rpx solid #FFF;
  551. border-bottom: 4rpx solid #FFF;
  552. border-left: 4rpx solid #FFF;
  553. background: #dddfe6a3;
  554. color: #515153;
  555. text-align: center;
  556. font-family: "Source Han Sans CN VF";
  557. font-size: 24rpx;
  558. font-weight: 500;
  559. writing-mode: vertical-rl;
  560. }
  561. .operation-background{
  562. position: fixed;
  563. right: 0;
  564. top: 0;
  565. width: 100%;
  566. height: 100%;
  567. z-index: 998;
  568. background: #00000040;
  569. }
  570. .operation-content{
  571. position: fixed;
  572. top: 240rpx;
  573. right: 80rpx;
  574. height: 126rpx;
  575. display: flex;
  576. padding: 16rpx 32rpx;
  577. align-items: center;
  578. gap: 64rpx;
  579. z-index: 999;
  580. border-radius: 32rpx;
  581. border: 2rpx solid #FFF;
  582. background: #FFF;
  583. backdrop-filter: blur(8rpx);
  584. .operation-item{
  585. display: flex;
  586. flex-direction: column;
  587. align-items: center;
  588. justify-content: center;
  589. color: #333333;
  590. text-align: center;
  591. font-family: "Source Han Sans CN VF";
  592. font-size: 24rpx;
  593. font-weight: 400;
  594. }
  595. .operation-icon{
  596. width: 58rpx;
  597. height: 58rpx;
  598. }
  599. }
  600. .info-label {
  601. width: 116rpx;
  602. color: #999999;
  603. text-align: right;
  604. font-family: 'Source Han Sans CN VF';
  605. font-size: 28rpx;
  606. font-style: normal;
  607. font-weight: 400;
  608. line-height: normal;
  609. margin-right: 32rpx;
  610. white-space: nowrap;
  611. }
  612. .info-value {
  613. color: #333333;
  614. font-family: 'Source Han Sans CN VF';
  615. font-size: 28rpx;
  616. font-style: normal;
  617. font-weight: 400;
  618. line-height: normal;
  619. text-overflow: ellipsis;
  620. overflow: hidden;
  621. white-space: nowrap;
  622. }
  623. .info-img {
  624. width: 32rpx;
  625. height: 32rpx;
  626. margin-left: 16rpx;
  627. background: #0bbc581a;
  628. display: flex;
  629. align-items: center;
  630. justify-content: center;
  631. }
  632. .tishi {
  633. width: 24rpx;
  634. height: 24rpx;
  635. }
  636. .dev-status {
  637. position: absolute;
  638. right: 0;
  639. top: 0;
  640. border: 2rpx solid #ffffff;
  641. background: #0bbc581a;
  642. width: 152rpx;
  643. height: 56rpx;
  644. color: #0bbc58;
  645. text-align: center;
  646. font-size: 28rpx;
  647. font-weight: 400;
  648. line-height: 52rpx;
  649. border-radius: 0 16rpx 0 64rpx;
  650. }
  651. }
  652. /* 标签页切换 */
  653. .tab-container {
  654. background-color: #ffffff;
  655. border-radius: 16rpx;
  656. overflow: hidden;
  657. padding: 0 32rpx;
  658. margin-bottom: 24rpx;
  659. .tab-top {
  660. display: flex;
  661. }
  662. .tab-item {
  663. flex: 1;
  664. height: 80rpx;
  665. display: flex;
  666. flex-direction: column;
  667. align-items: center;
  668. position: relative;
  669. color: #666666;
  670. text-align: center;
  671. font-family: 'Source Han Sans CN VF';
  672. font-size: 28rpx;
  673. font-style: normal;
  674. font-weight: 400;
  675. line-height: normal;
  676. .tab-text {
  677. margin-top: 16rpx;
  678. }
  679. .smile {
  680. width: 24rpx;
  681. height: 18rpx;
  682. }
  683. }
  684. .tab-item.active {
  685. color: #333333;
  686. font-weight: 700;
  687. }
  688. .time-board {
  689. display: flex;
  690. align-items: center;
  691. justify-content: space-between;
  692. margin-bottom: 16rpx;
  693. }
  694. .time-filter {
  695. display: flex;
  696. align-items: center;
  697. justify-content: space-between;
  698. width: 256rpx;
  699. height: 48rpx;
  700. padding: 6rpx 8rpx;
  701. border-radius: 32rpx;
  702. background: #f1f4f8;
  703. color: #303133;
  704. font-size: 20rpx;
  705. font-weight: 400;
  706. .filter-item {
  707. padding: 4rpx 16rpx;
  708. height: 36rpx;
  709. line-height: 36rpx;
  710. }
  711. .active {
  712. border-radius: 32rpx;
  713. background: #fff;
  714. }
  715. }
  716. }
  717. /* 监测要素页面 */
  718. .monitoring-page {
  719. padding-bottom: 20px;
  720. display: flex;
  721. flex-wrap: wrap;
  722. justify-content: space-between;
  723. .data-card {
  724. width: calc(50% - 8rpx);
  725. margin-bottom: 16rpx;
  726. background-color: #ffffff;
  727. border-radius: 16rpx;
  728. padding: 16rpx 24rpx;
  729. height: 186rpx;
  730. font-family: 'Source Han Sans CN VF';
  731. font-size: 28rpx;
  732. font-weight: 400;
  733. box-sizing: border-box;
  734. .card-title {
  735. color: #042118;
  736. margin-bottom: 6rpx;
  737. }
  738. .data-value-row {
  739. display: flex;
  740. justify-content: space-between;
  741. align-items: center;
  742. color: #042118;
  743. font-family: 'Source Han Sans CN VF';
  744. font-weight: 400;
  745. .data-value {
  746. font-size: 40rpx;
  747. font-weight: 700;
  748. margin-right: 8rpx;
  749. }
  750. .data-unit {
  751. font-size: 24rpx;
  752. }
  753. .device-img {
  754. width: 52rpx;
  755. height: 52rpx;
  756. }
  757. }
  758. .card-thrid {
  759. color: #687a74;
  760. margin-top: 6rpx;
  761. }
  762. }
  763. }
  764. /* 设备详情页面 */
  765. .details-page {
  766. .device-params {
  767. background-color: #ffffff;
  768. border-radius: 16rpx;
  769. padding: 32rpx;
  770. margin-bottom: 24rpx;
  771. .device-control {
  772. position: relative;
  773. z-index: 3;
  774. display: flex;
  775. align-items: center;
  776. justify-content: space-between;
  777. margin-bottom: 24rpx;
  778. .control-left {
  779. color: #999999;
  780. font-family: 'Source Han Sans CN VF';
  781. font-size: 28rpx;
  782. display: flex;
  783. align-items: center;
  784. .reload-img {
  785. font-size: 32rpx;
  786. color: #0bbc58;
  787. margin-left: 14rpx;
  788. }
  789. }
  790. .control-right {
  791. display: flex;
  792. align-items: center;
  793. .control-img {
  794. width: 48rpx;
  795. height: 48rpx;
  796. margin-left: 24rpx;
  797. }
  798. }
  799. }
  800. .params-board {
  801. display: flex;
  802. justify-content: space-between;
  803. align-items: center;
  804. position: relative;
  805. .params-left-container{
  806. display: flex;
  807. justify-content: space-between;
  808. }
  809. .params-left {
  810. flex:1;
  811. display: flex;
  812. flex-wrap: wrap;
  813. .params-item {
  814. display: flex;
  815. flex-direction: column;
  816. width: 100%;
  817. // width: calc(50% - 20rpx);
  818. margin-bottom: 24rpx;
  819. .params-val {
  820. color: #303133;
  821. font-size: 28rpx;
  822. font-weight: 700;
  823. .unit {
  824. font-size: 24rpx;
  825. font-weight: 400;
  826. color:#999999;
  827. }
  828. }
  829. .params-label {
  830. color: #999999;
  831. font-size: 24rpx;
  832. font-weight: 400;
  833. }
  834. }
  835. }
  836. .params-right {
  837. position: absolute;
  838. right: 0;
  839. top:0;
  840. .device-img {
  841. width: 150rpx;
  842. height: 300rpx;
  843. }
  844. }
  845. }
  846. }
  847. .table-container {
  848. padding: 16rpx 32rpx 32rpx 32rpx;
  849. border-radius: 16rpx;
  850. background: #fff;
  851. .table-control {
  852. display: flex;
  853. align-items: center;
  854. justify-content: space-between;
  855. margin-bottom: 16rpx;
  856. .title {
  857. color: #042118;
  858. font-family: 'Source Han Sans CN VF';
  859. font-size: 28rpx;
  860. font-style: normal;
  861. font-weight: 700;
  862. line-height: normal;
  863. }
  864. .date-board {
  865. display: flex;
  866. align-items: center;
  867. color: #020305;
  868. font-family: 'Source Han Sans CN VF';
  869. font-size: 24rpx;
  870. font-weight: 400;
  871. border-radius: 32rpx;
  872. background: #f1f4f8;
  873. padding: 16rpx 24rpx;
  874. .line {
  875. color: #656565;
  876. margin: 0 10rpx;
  877. }
  878. .date-icon {
  879. width: 32rpx;
  880. height: 32rpx;
  881. margin-left: 16rpx;
  882. }
  883. }
  884. }
  885. .table-wrap {
  886. display: flex;
  887. width: 100%;
  888. height: 850rpx;
  889. box-sizing: border-box;
  890. margin: 20rpx 0;
  891. color: #042118;
  892. font-family: 'Source Han Sans CN VF';
  893. font-size: 24rpx;
  894. font-style: normal;
  895. font-weight: 400;
  896. line-height: normal;
  897. .fixed-column {
  898. width: 250rpx;
  899. .table-cell {
  900. width: 100%;
  901. white-space: nowrap;
  902. }
  903. }
  904. .table-bg {
  905. width: 16rpx;
  906. background: linear-gradient(270deg, #ffffff33 0%, #9598a433 100%);
  907. }
  908. .scroll-column {
  909. flex: 1;
  910. height: auto;
  911. overflow: hidden;
  912. margin-left: -10rpx;
  913. }
  914. .scroll-content {
  915. min-width: 100%;
  916. width: fit-content;
  917. display: flex;
  918. flex-direction: column;
  919. .table-row {
  920. display: flex;
  921. .table-cell {
  922. flex: 1;
  923. }
  924. }
  925. }
  926. .table-cell {
  927. width: 160rpx;
  928. height: 80rpx;
  929. line-height: 80rpx;
  930. text-align: center;
  931. border-bottom: 2px solid #e4e7ed;
  932. box-sizing: border-box;
  933. overflow: hidden;
  934. padding: 0 4rpx;
  935. text-overflow: ellipsis;
  936. }
  937. .table-cell.header {
  938. background: #f6f8fc;
  939. }
  940. }
  941. .pagination {
  942. display: flex;
  943. align-items: center;
  944. justify-content: space-between;
  945. margin-top: 24rpx;
  946. .page-item {
  947. width: 104rpx;
  948. height: 48rpx;
  949. color: #656565;
  950. font-size: 24rpx;
  951. line-height: 48rpx;
  952. text-align: center;
  953. border: 2rpx solid #e4e7ed;
  954. border-radius: 8rpx;
  955. }
  956. .prev.disabled {
  957. color: #c0c4cc;
  958. border-color: #e4e7ed;
  959. }
  960. .next {
  961. color: #0bbc58;
  962. border: 2px solid #0bbc58;
  963. }
  964. .next.disabled {
  965. color: #c0c4cc;
  966. border-color: #e4e7ed;
  967. }
  968. .page-info {
  969. color: #999999;
  970. font-family: 'Source Han Sans CN VF';
  971. font-size: 24rpx;
  972. font-style: normal;
  973. font-weight: 400;
  974. line-height: normal;
  975. .curret-page {
  976. color: #303133;
  977. }
  978. }
  979. }
  980. .empty-state {
  981. padding: 80rpx 0;
  982. }
  983. }
  984. }
  985. ::v-deep .u-calendar__action {
  986. display: flex;
  987. justify-content: center;
  988. }
  989. </style>