index.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903
  1. <template>
  2. <view class="warning-center">
  3. <!-- 顶部导航栏 -->
  4. <custom-card>
  5. <block slot="backText">预警中心</block>
  6. </custom-card>
  7. <!-- 主要内容 -->
  8. <view class="content">
  9. <!-- 宣传语区域 -->
  10. <view class="banner">
  11. <view class="banner-text">
  12. <text class="banner-title">天灾虫害,预警在先</text>
  13. <text class="banner-subtitle">全天候监测,风险早知晓</text>
  14. </view>
  15. <view class="warning-icon">
  16. <view class="icon-triangle">
  17. <image :src="exclamation" class="icon-image" />
  18. </view>
  19. </view>
  20. </view>
  21. <!-- 日期选择器 -->
  22. <view class="date-picker">
  23. <view class="date-inputs" @click="showDatePickerHandle()">
  24. <text class="date-label">{{ startTime }}</text>
  25. <text class="date-separator">-</text>
  26. <text class="date-label">{{ endTime }}</text>
  27. <u-icon name="calendar" size="28rpx" color="#999" />
  28. </view>
  29. <view class="date-icons">
  30. <image :src="warning" class="icon-image" />
  31. </view>
  32. </view>
  33. <!-- 标签导航 -->
  34. <view class="tab-nav">
  35. <view
  36. v-for="(tab, index) in tabs"
  37. :key="index"
  38. class="tab-item"
  39. :class="{ active: activeTab === index }"
  40. @click="activeTabHandler(index)"
  41. >
  42. {{ tab.name }}
  43. </view>
  44. </view>
  45. <!-- 预警列表 -->
  46. <scroll-view
  47. v-if="activeTab == 0"
  48. class="warning-list"
  49. scroll-y
  50. :scroll-top="listScrollTop"
  51. scroll-with-animation
  52. @scrolltolower="loadMore"
  53. @scrolltoupper="refresh"
  54. >
  55. <view
  56. v-for="(warning, index) in warningList"
  57. :key="index"
  58. class="warning-item"
  59. @click="popupShowHandler(warning)"
  60. >
  61. <view class="warning-header">
  62. <view class="warning-type">
  63. <view class="type-icon" :class="warning.status == '0' ? 'type-blue' : 'type-gray'">
  64. <image :src="weather" class="icon-image" />
  65. </view>
  66. <text class="type-text">{{ warning.warning_title }}</text>
  67. <text class="device-type">{{ warning.device_type }}</text>
  68. </view>
  69. <view class="warning-level"
  70. :class="
  71. warning.level == '0' ? (warning.status != '0' ? 'level-normal-gray' : 'level-normal') :
  72. warning.level == '1'? (warning.status != '0' ? 'level-important-gray' : 'level-important'):
  73. (warning.status != '0' ? 'level-urgent-gray' : 'level-urgent')
  74. ">
  75. </view>
  76. </view>
  77. <view class="warning-content">
  78. {{ warning.warning_content }}
  79. </view>
  80. <view class="warning-footer">
  81. <text class="warning-time">{{ formatTime(warning.upl_time) }}</text>
  82. <view class="warning-location">
  83. <u-icon name="location" size="20rpx" color="#999" />
  84. </view>
  85. </view>
  86. <view class="location-text">
  87. <u-icon name="map" size="28"></u-icon>
  88. <text style="margin-left: 10rpx">{{ warning.address || '-' }}</text>
  89. </view>
  90. </view>
  91. <!-- 加载更多提示 -->
  92. <view class="loading-more">
  93. <text v-if="loading">加载中...</text>
  94. <text v-else-if="finished">没有更多数据了</text>
  95. <text v-else>上拉加载更多</text>
  96. </view>
  97. </scroll-view>
  98. <scroll-view
  99. v-if="activeTab == 1"
  100. class="warning-list"
  101. scroll-y
  102. :scroll-top="listScrollTop"
  103. scroll-with-animation
  104. @scrolltolower="loadMore"
  105. @scrolltoupper="refresh"
  106. >
  107. <view
  108. v-for="(warning, index) in manualWarningList"
  109. :key="index"
  110. class="warning-item"
  111. @click="popupManualShowHandler(warning)"
  112. >
  113. <view class="warning-content">
  114. {{ warning.conf }}
  115. </view>
  116. <view class="warning-footer">
  117. <text class="warning-time">{{ formatTime(warning.create_time) }}</text>
  118. <view class="warning-location">
  119. <u-icon name="location" size="20rpx" color="#999" />
  120. </view>
  121. </view>
  122. </view>
  123. <!-- 加载更多提示 -->
  124. <view class="loading-more">
  125. <text v-if="loading">加载中...</text>
  126. <text v-else-if="finished">没有更多数据了</text>
  127. <text v-else>上拉加载更多</text>
  128. </view>
  129. </scroll-view>
  130. <!-- 回到顶部 -->
  131. <view class="back-to-top" @click="scrollToTop">
  132. <u-icon name="arrow-up" size="28rpx" color="#999" />
  133. </view>
  134. </view>
  135. <u-calendar v-model="showDatePicker" :mode="mode" @change="changeCalendar" range-color="#999"
  136. btn-type="success"
  137. active-bg-color="#0BBC58"
  138. range-bg-color="rgba(11,188,88,0.13)"></u-calendar>
  139. <u-popup v-model="popupShow" mode="bottom" height="50%" border-radius="20">
  140. <view class="popup-container">
  141. <view class="popup-icon" :class="
  142. current.level == '0' ? (current.status != '0' ? 'popup-level-normal-gray' : 'popup-level-normal') :
  143. current.level == '1'? (current.status != '0' ? 'popup-level-important-gray' : 'popup-level-important'):
  144. (current.status != '0' ? 'popup-level-urgent-gray' : 'popup-level-urgent')
  145. ">
  146. </view>
  147. <view class="popup-header">{{ current.warning_title }}</view>
  148. <view class="popup-type">
  149. <text class="type-text">{{ current.device_type }}</text>
  150. </view>
  151. <view class="popup-content">{{ current.warning_content }}</view>
  152. <view class="popup-time">{{ formatTime(current.upl_time) }}</view>
  153. <view class="popup-text">
  154. <u-icon name="map" size="28"></u-icon>
  155. <text style="margin-left: 10rpx">{{ warning.address || '-' }}</text>
  156. </view>
  157. </view>
  158. </u-popup>
  159. <u-popup v-model="popupManualShow" mode="bottom" height="50%" border-radius="20">
  160. <view class="popup-container" style="margin-top:40rpx">
  161. <view class="popup-content">{{ currentManual.conf }}</view>
  162. <view class="popup-time">{{ formatTime(currentManual.create_time) }}</view>
  163. </view>
  164. </u-popup>
  165. </view>
  166. </template>
  167. <script>
  168. import exclamation from './assets/exclamation.png';
  169. import warning from './assets/warning.png';
  170. import pest from './assets/pest.png';
  171. import weather from './assets/weather.png';
  172. import offline from './assets/offline.png';
  173. export default {
  174. data() {
  175. return {
  176. current:{},
  177. currentManual:{},
  178. popupShow: false,
  179. popupManualShow: false,
  180. exclamation,
  181. warning,
  182. pest,
  183. weather,
  184. offline,
  185. showDatePicker: false,
  186. mode: 'range',
  187. activeTab: 0,
  188. listScrollTop: 0,
  189. tabs: [],
  190. warningList: [],
  191. manualWarningList: [],
  192. page_size: 10,
  193. page: 1,
  194. // 获取7天前的日期
  195. startTime: this.getSevenDaysAgo() || '开始日期',
  196. endTime: this.getCurrentDate() || '结束日期',
  197. deviceId: '',
  198. device_type_id:'',
  199. total: 0,
  200. loading: false,
  201. finished: false,
  202. refreshing: false,
  203. };
  204. },
  205. onLoad() {
  206. this.init();
  207. },
  208. methods: {
  209. async init(){
  210. await this.getLoginUSerSimpleMenusForAlert();
  211. this.getWarningList();
  212. },
  213. activeTabHandler(index){
  214. this.activeTab = index;
  215. this.page = 1;
  216. if(index == 0 || index == 1){
  217. this.getWarningList();
  218. }else if(index == 2){
  219. this.getWarningManualList();
  220. }
  221. },
  222. popupManualShowHandler(warning){
  223. this.currentManual = warning;
  224. this.popupManualShow = true;
  225. },
  226. popupShowHandler(warning){
  227. this.current = warning;
  228. const params = {
  229. record_ids: warning.id,
  230. };
  231. this.readHandler(params)
  232. this.popupShow = true;
  233. },
  234. changeCalendar(e){
  235. this.startTime = e.startDate;
  236. this.endTime = e.endDate;
  237. // 重置分页参数
  238. this.page = 1;
  239. this.loading = false;
  240. this.finished = false;
  241. if(this.activeTab == 0 || this.activeTab == 1){
  242. this.getWarningList();
  243. }else if(this.activeTab == 2){
  244. this.getWarningManualList();
  245. }
  246. },
  247. // 加载更多
  248. loadMore() {
  249. if (this.finished) return;
  250. if(this.activeTab == 0 || this.activeTab == 1){
  251. this.getWarningList();
  252. }else if(this.activeTab == 2){
  253. this.getWarningManualList();
  254. }
  255. },
  256. // 下拉刷新
  257. refresh() {
  258. if (this.loading) return;
  259. // 重置分页参数
  260. this.page = 1;
  261. this.loading = false;
  262. this.finished = false;
  263. this.refreshing = true;
  264. if(this.activeTab == 0 || this.activeTab == 1){
  265. this.getWarningList();
  266. }else if(this.activeTab == 2){
  267. this.getWarningManualList();
  268. }
  269. },
  270. async getLoginUSerSimpleMenusForAlert(){
  271. await this.$myRequest({
  272. url:'/api/api_gateway?method=user.login.user_simple_menus_for_alert',
  273. method:'POST',
  274. }).then(res => {
  275. this.tabs = res || [];
  276. this.tabs.push({
  277. id: '0',
  278. name:'手动预警'
  279. })
  280. })
  281. },
  282. // 已读
  283. async readHandler(params){
  284. await this.$myRequest({
  285. url:'/api/api_gateway?method=device.env_sec_alert.update_env_sec_alert_record',
  286. method:'POST',
  287. data: params,
  288. })
  289. this.page = 1;
  290. if(this.activeTab == 0){
  291. this.getWarningList();
  292. }
  293. },
  294. formatTime(time){
  295. if(!time){
  296. return '';
  297. }
  298. const date = new Date(time * 1000);
  299. const year = date.getFullYear();
  300. const month = String(date.getMonth() + 1).padStart(2, '0');
  301. const day = String(date.getDate()).padStart(2, '0');
  302. const hour = String(date.getHours()).padStart(2, '0');
  303. const minute = String(date.getMinutes()).padStart(2, '0');
  304. const second = String(date.getSeconds()).padStart(2, '0');
  305. return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
  306. },
  307. // 获取7天前的日期
  308. getSevenDaysAgo() {
  309. const today = new Date();
  310. const sevenDaysAgo = new Date(today);
  311. sevenDaysAgo.setDate(today.getDate() - 7);
  312. const year = sevenDaysAgo.getFullYear();
  313. const month = String(sevenDaysAgo.getMonth() + 1).padStart(2, '0');
  314. const day = String(sevenDaysAgo.getDate()).padStart(2, '0');
  315. return `${year}-${month}-${day}`;
  316. },
  317. // 获取当前日期
  318. getCurrentDate() {
  319. const today = new Date();
  320. const year = today.getFullYear();
  321. const month = String(today.getMonth() + 1).padStart(2, '0');
  322. const day = String(today.getDate()).padStart(2, '0');
  323. return `${year}-${month}-${day}`;
  324. },
  325. showDatePickerHandle(){
  326. this.showDatePicker = true;
  327. },
  328. // 把日期转成秒数
  329. dateToTimestamp(date) {
  330. return Math.floor(new Date(date).getTime() / 1000);
  331. },
  332. async getWarningManualList(){
  333. if (this.loading) return;
  334. this.loading = true;
  335. const start = this.dateToTimestamp(this.startTime + ' 00:00:00');
  336. const end = this.dateToTimestamp(this.endTime + ' 23:59:59');
  337. const params = {
  338. start,
  339. end,
  340. page: this.page,
  341. page_size: this.page_size,
  342. fk_type: this.tabs[this.activeTab].id,
  343. device_id: this.deviceId,
  344. device_type_id: this.device_type_id
  345. }
  346. try {
  347. const res = await this.$myRequest({
  348. url:'/api/api_gateway?method=device.env_sec_alert.get_manual_env_sec_alert_record',
  349. method:'POST',
  350. data: params,
  351. })
  352. const resData = res?.data || [];
  353. const list = resData || [];
  354. if (this.page === 1) {
  355. this.manualWarningList = list;
  356. } else {
  357. this.manualWarningList = [...this.manualWarningList, ...list];
  358. }
  359. this.total = res?.total || 0;
  360. this.loading = false;
  361. // 计算是否还有更多数据
  362. if (this.manualWarningList.length >= this.total) {
  363. this.finished = true;
  364. } else {
  365. this.page++;
  366. }
  367. // 结束刷新状态
  368. if (this.refreshing) {
  369. this.refreshing = false;
  370. }
  371. } catch (error) {
  372. console.error('获取预警列表失败:', error);
  373. this.loading = false;
  374. if (this.refreshing) {
  375. this.refreshing = false;
  376. }
  377. }
  378. },
  379. async getWarningList(){
  380. if (this.loading) return;
  381. this.loading = true;
  382. const start = this.dateToTimestamp(this.startTime + ' 00:00:00');
  383. const end = this.dateToTimestamp(this.endTime + ' 23:59:59');
  384. console.log(this.activeTab,this.tabs,'activeTabactiveTabactiveTab')
  385. const params = {
  386. start,
  387. end,
  388. page: this.page,
  389. fk_type: this.tabs[this.activeTab].id,
  390. page_size: this.page_size,
  391. device_id: this.deviceId,
  392. device_type_id: this.device_type_id
  393. }
  394. try {
  395. const res = await this.$myRequest({
  396. url:'/api/api_gateway?method=device.env_sec_alert.get_env_sec_alert',
  397. method:'POST',
  398. data: params,
  399. })
  400. const resData = res?.data || [];
  401. const list = resData || [];
  402. if (this.page === 1) {
  403. this.warningList = list;
  404. } else {
  405. this.warningList = [...this.warningList, ...list];
  406. }
  407. this.total = res?.total_num || 0;
  408. this.loading = false;
  409. // 计算是否还有更多数据
  410. if (this.warningList.length >= this.total) {
  411. this.finished = true;
  412. } else {
  413. this.page++;
  414. }
  415. // 结束刷新状态
  416. if (this.refreshing) {
  417. this.refreshing = false;
  418. }
  419. } catch (error) {
  420. console.error('获取预警列表失败:', error);
  421. this.loading = false;
  422. if (this.refreshing) {
  423. this.refreshing = false;
  424. }
  425. }
  426. },
  427. // 回到顶部
  428. scrollToTop() {
  429. this.listScrollTop = 0;
  430. }
  431. }
  432. };
  433. </script>
  434. <style scoped lang="scss">
  435. .warning-center {
  436. min-height: 100vh;
  437. font-family: 'Source Han Sans CN';
  438. background: linear-gradient(0deg, #F5F6FA 79.64%, #FFEEEC 99.35%);
  439. }
  440. ::v-deep .u-calendar__action{
  441. display:flex;
  442. }
  443. ::v-deep .u-calendar__action__icon{
  444. width: 40rpx;
  445. }
  446. ::v-deep .u-calendar__action__text{
  447. width: calc(100% - 160rpx);
  448. text-align: center;
  449. }
  450. .content {
  451. padding: 0 32rpx;
  452. }
  453. /* 宣传语区域 */
  454. .banner {
  455. display: flex;
  456. align-items: center;
  457. justify-content: space-between;
  458. margin: 32rpx 0;
  459. margin-bottom: 0rpx;
  460. padding: 24rpx;
  461. .banner-text {
  462. flex: 1;
  463. .banner-title {
  464. font-style: italic;
  465. display: block;
  466. color: #303133;
  467. font-family: "Source Han Sans CN VF";
  468. font-size: 40rpx;
  469. font-weight: 700;
  470. margin-bottom: 8rpx;
  471. }
  472. .banner-subtitle {
  473. display: block;
  474. font-size: 24rpx;
  475. color: #666666;
  476. }
  477. }
  478. .warning-icon {
  479. .icon-triangle {
  480. width: 130rpx;
  481. height: 130rpx;
  482. position: relative;
  483. .icon-image{
  484. width: 100%;
  485. height: 100%;
  486. }
  487. }
  488. }
  489. }
  490. .popup-container{
  491. position:relative;
  492. .popup-icon {
  493. position: absolute;
  494. top:0;
  495. right:0;
  496. margin-left: 12rpx;
  497. width: 112rpx;
  498. height: 48rpx;
  499. background: url('./assets/normal-gray.png');
  500. background-repeat: no-repeat;
  501. background-size: 100%;
  502. &.popup-level-normal {
  503. background: url('./assets/normal.png');
  504. background-repeat: no-repeat;
  505. background-size: 100%;
  506. }
  507. &.popup-level-normal-gray {
  508. background: url('./assets/normal-gray.png');
  509. background-repeat: no-repeat;
  510. background-size: 100%;
  511. }
  512. &.popup-level-important-gray {
  513. background: url('./assets/important-gray.png');
  514. background-repeat: no-repeat;
  515. background-size: 100%;
  516. }
  517. &.popup-level-important {
  518. background: url('./assets/important.png');
  519. background-repeat: no-repeat;
  520. background-size: 100%;
  521. }
  522. &.popup-level-urgent-gray {
  523. background: url('./assets/urgent-gray.png');
  524. background-repeat: no-repeat;
  525. background-size: 100%;
  526. }
  527. &.popup-level-urgent {
  528. background: url('./assets/urgent.png');
  529. background-repeat: no-repeat;
  530. background-size: 100%;
  531. }
  532. }
  533. }
  534. .popup-header{
  535. padding: 20rpx 32rpx;
  536. width: 100%;
  537. text-align: left;
  538. color: #303133;
  539. font-family: "Source Han Sans CN VF";
  540. font-size: 32rx;
  541. font-weight: 700;
  542. }
  543. .popup-type{
  544. border-radius:32rpx;
  545. margin-left: 32rpx;
  546. display:inline-block;
  547. border: 2rpx solid #E4E7ED;
  548. padding: 2rpx 12rpx;
  549. color: #666666;
  550. font-family: "Source Han Sans CN VF";
  551. font-size: 24rpx;
  552. font-weight: 400;
  553. margin-bottom: 24rpx;
  554. }
  555. .popup-content{
  556. padding: 0 32rpx;
  557. line-height: 50rpx;
  558. }
  559. .popup-time{
  560. padding:0 32rpx;
  561. margin-top: 36rpx;
  562. color:#999999;
  563. font-size: 24rpx;
  564. text-align: left;
  565. color: #bdbdbd;
  566. font-family: "Source Han Sans CN VF";
  567. font-style: normal;
  568. font-weight: 400;
  569. }
  570. .popup-location{
  571. font-size: 24rpx;
  572. margin-top: 16rpx;
  573. padding-top: 16rpx;
  574. font-family: "Source Han Sans CN VF";
  575. color: #999999;
  576. display:flex;
  577. align-items: center;
  578. }
  579. .popup-text {
  580. padding: 0 32rpx;
  581. font-size: 24rpx;
  582. margin-top: 16rpx;
  583. padding-top: 16rpx;
  584. font-family: "Source Han Sans CN VF";
  585. color: #999999;
  586. display:flex;
  587. align-items: center;
  588. }
  589. /* 日期选择器 */
  590. .date-picker {
  591. display: flex;
  592. align-items: center;
  593. justify-content: space-between;
  594. margin-bottom: 32rpx;
  595. .date-inputs {
  596. display: flex;
  597. align-items: center;
  598. background: #ffffff;
  599. border-radius: 48rpx;
  600. padding: 14rpx;
  601. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
  602. .date-label {
  603. width:250rpx;
  604. font-size: 26rpx;
  605. color: #999999;
  606. text-align: center;
  607. }
  608. .date-separator {
  609. margin: 0 24rpx;
  610. font-size: 26rpx;
  611. color: #999999;
  612. }
  613. }
  614. .date-icons {
  615. display: flex;
  616. align-items: center;
  617. justify-content: center;
  618. width: 60rpx ;
  619. height: 60rpx;
  620. border-radius: 50%;
  621. background:#ffffff;
  622. .icon-image{
  623. width: 32rpx;
  624. height: 32rpx;
  625. }
  626. }
  627. }
  628. /* 标签导航 */
  629. .tab-nav {
  630. display: flex;
  631. margin-bottom: 24rpx;
  632. border-bottom: 1rpx solid #e5e5e5;
  633. .tab-item {
  634. padding: 20rpx 0;
  635. font-size: 28rpx;
  636. color: #666666;
  637. position: relative;
  638. margin-right: 30rpx;
  639. &.active {
  640. color: #333333;
  641. font-weight: 500;
  642. &::after {
  643. content: '';
  644. position: absolute;
  645. bottom: 0;
  646. left: 50%;
  647. transform: translateX(-50%);
  648. width: 100%;
  649. height: 4rpx;
  650. background: #515153;
  651. border-radius: 2rpx;
  652. }
  653. }
  654. }
  655. }
  656. /* 预警列表 */
  657. .warning-list {
  658. margin-bottom: 100rpx;
  659. height: calc(100vh - 600rpx);
  660. overflow-y: auto;
  661. .warning-item {
  662. position: relative;
  663. padding: 28rpx 24rpx;
  664. margin-bottom: 24rpx;
  665. background: #ffffff;
  666. border-radius: 16rpx;
  667. box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
  668. .warning-header {
  669. display: flex;
  670. align-items: center;
  671. justify-content: space-between;
  672. margin-bottom: 16rpx;
  673. .warning-type {
  674. display: flex;
  675. align-items: center;
  676. flex: 1;
  677. min-width: 0;
  678. .type-icon {
  679. width: 48rpx;
  680. height: 48rpx;
  681. border-radius: 50%;
  682. margin-right: 12rpx;
  683. flex-shrink: 0;
  684. display:flex;
  685. align-items: center;
  686. justify-content: center;
  687. &.type-red {
  688. background: linear-gradient(180deg, #FFA9A5 0%, #FF716A 100%);
  689. }
  690. &.type-blue {
  691. background: linear-gradient(180deg, #83D2FF 0%, #09A5FC 100%);
  692. }
  693. &.type-yellow {
  694. background: linear-gradient(180deg, #FED057 0%, #FFAF40 100%);
  695. }
  696. &.type-gray {
  697. background: #DDDFE6;
  698. }
  699. .icon-image{
  700. width: 28rpx;
  701. height: 28rpx;
  702. }
  703. }
  704. .type-text {
  705. font-size: 26rpx;
  706. font-weight: 500;
  707. color: #333333;
  708. margin-right: 12rpx;
  709. flex-shrink: 0;
  710. }
  711. .device-type {
  712. font-size: 22rpx;
  713. color: #515153;
  714. font-family: "Source Han Sans CN VF";
  715. font-style: normal;
  716. font-weight: 400;
  717. border: 2rpx solid #E4E7ED;
  718. padding: 2rpx 12rpx;
  719. border-radius: 32rpx;
  720. margin-left: 8rpx;
  721. flex-shrink: 0;
  722. }
  723. }
  724. .warning-level {
  725. position: absolute;
  726. top:0;
  727. right:0;
  728. margin-left: 12rpx;
  729. width: 112rpx;
  730. height: 48rpx;
  731. background: url('./assets/normal-gray.png');
  732. background-repeat: no-repeat;
  733. background-size: 100%;
  734. &.level-normal {
  735. background: url('./assets/normal.png');
  736. background-repeat: no-repeat;
  737. background-size: 100%;
  738. }
  739. &.level-normal-gray {
  740. background: url('./assets/normal-gray.png');
  741. background-repeat: no-repeat;
  742. background-size: 100%;
  743. }
  744. &.level-important {
  745. background: url('./assets/important.png');
  746. background-repeat: no-repeat;
  747. background-size: 100%;
  748. }
  749. &.level-important-gray {
  750. background: url('./assets/important-gray.png');
  751. background-repeat: no-repeat;
  752. background-size: 100%;
  753. }
  754. &.level-urgent-gray {
  755. background: url('./assets/urgent-gray.png');
  756. background-repeat: no-repeat;
  757. background-size: 100%;
  758. }
  759. &.level-urgent {
  760. background: url('./assets/urgent.png');
  761. background-repeat: no-repeat;
  762. background-size: 100%;
  763. }
  764. }
  765. }
  766. .warning-content {
  767. font-size: 28rpx;
  768. color: #333333;
  769. line-height: 40rpx;
  770. margin-bottom: 20rpx;
  771. //最多显示2行
  772. overflow: hidden;
  773. text-overflow: ellipsis;
  774. display: -webkit-box;
  775. -webkit-line-clamp: 2;
  776. -webkit-box-orient: vertical;
  777. }
  778. .warning-footer {
  779. display: flex;
  780. align-items: center;
  781. justify-content: space-between;
  782. .warning-time {
  783. font-size: 24rpx;
  784. color: #999999;
  785. }
  786. .warning-location {
  787. display: flex;
  788. align-items: center;
  789. }
  790. }
  791. .location-text {
  792. font-size: 24rpx;
  793. margin-top: 16rpx;
  794. padding-top: 16rpx;
  795. border-top: 1rpx solid #f0f0f0;
  796. font-family: "Source Han Sans CN VF";
  797. color: #999999;
  798. display:flex;
  799. align-items: center;
  800. }
  801. }
  802. }
  803. /* 加载更多提示 */
  804. .loading-more {
  805. text-align: center;
  806. padding: 32rpx 0;
  807. font-size: 24rpx;
  808. color: #999999;
  809. }
  810. /* 回到顶部 */
  811. .back-to-top {
  812. position: fixed;
  813. bottom: 80rpx;
  814. right: 32rpx;
  815. width: 64rpx;
  816. height: 64rpx;
  817. background: #ffffff;
  818. border-radius: 50%;
  819. display: flex;
  820. align-items: center;
  821. justify-content: center;
  822. box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
  823. z-index: 99;
  824. }
  825. /* 顶部导航栏右侧图标 */
  826. .header-right {
  827. display: flex;
  828. align-items: center;
  829. .notification-icon {
  830. position: relative;
  831. margin-right: 32rpx;
  832. .badge {
  833. position: absolute;
  834. top: -4rpx;
  835. right: -4rpx;
  836. width: 12rpx;
  837. height: 12rpx;
  838. background: #ff6b6b;
  839. border-radius: 50%;
  840. }
  841. }
  842. }
  843. </style>