index.vue 26 KB

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