index.vue 26 KB

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