index.vue 23 KB

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