index.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904
  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. fk_type:this.tabs[this.activeTab].id,
  231. };
  232. this.readHandler(params)
  233. this.popupShow = true;
  234. },
  235. changeCalendar(e){
  236. this.startTime = e.startDate;
  237. this.endTime = e.endDate;
  238. // 重置分页参数
  239. this.page = 1;
  240. this.loading = false;
  241. this.finished = false;
  242. if(this.activeTab == 0 || this.activeTab == 1){
  243. this.getWarningList();
  244. }else if(this.activeTab == 2){
  245. this.getWarningManualList();
  246. }
  247. },
  248. // 加载更多
  249. loadMore() {
  250. if (this.finished) return;
  251. if(this.activeTab == 0 || this.activeTab == 1){
  252. this.getWarningList();
  253. }else if(this.activeTab == 2){
  254. this.getWarningManualList();
  255. }
  256. },
  257. // 下拉刷新
  258. refresh() {
  259. if (this.loading) return;
  260. // 重置分页参数
  261. this.page = 1;
  262. this.loading = false;
  263. this.finished = false;
  264. this.refreshing = true;
  265. if(this.activeTab == 0 || this.activeTab == 1){
  266. this.getWarningList();
  267. }else if(this.activeTab == 2){
  268. this.getWarningManualList();
  269. }
  270. },
  271. async getLoginUSerSimpleMenusForAlert(){
  272. await this.$myRequest({
  273. url:'/api/api_gateway?method=user.login.user_simple_menus_for_alert',
  274. method:'POST',
  275. }).then(res => {
  276. this.tabs = res || [];
  277. this.tabs.push({
  278. id: '0',
  279. name:'手动预警'
  280. })
  281. })
  282. },
  283. // 已读
  284. async readHandler(params){
  285. await this.$myRequest({
  286. url:'/api/api_gateway?method=device.env_sec_alert.update_env_sec_alert_record',
  287. method:'POST',
  288. data: params,
  289. })
  290. this.page = 1;
  291. if(this.activeTab == 0){
  292. this.getWarningList();
  293. }
  294. },
  295. formatTime(time){
  296. if(!time){
  297. return '';
  298. }
  299. const date = new Date(time * 1000);
  300. const year = date.getFullYear();
  301. const month = String(date.getMonth() + 1).padStart(2, '0');
  302. const day = String(date.getDate()).padStart(2, '0');
  303. const hour = String(date.getHours()).padStart(2, '0');
  304. const minute = String(date.getMinutes()).padStart(2, '0');
  305. const second = String(date.getSeconds()).padStart(2, '0');
  306. return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
  307. },
  308. // 获取7天前的日期
  309. getSevenDaysAgo() {
  310. const today = new Date();
  311. const sevenDaysAgo = new Date(today);
  312. sevenDaysAgo.setDate(today.getDate() - 7);
  313. const year = sevenDaysAgo.getFullYear();
  314. const month = String(sevenDaysAgo.getMonth() + 1).padStart(2, '0');
  315. const day = String(sevenDaysAgo.getDate()).padStart(2, '0');
  316. return `${year}-${month}-${day}`;
  317. },
  318. // 获取当前日期
  319. getCurrentDate() {
  320. const today = new Date();
  321. const year = today.getFullYear();
  322. const month = String(today.getMonth() + 1).padStart(2, '0');
  323. const day = String(today.getDate()).padStart(2, '0');
  324. return `${year}-${month}-${day}`;
  325. },
  326. showDatePickerHandle(){
  327. this.showDatePicker = true;
  328. },
  329. // 把日期转成秒数
  330. dateToTimestamp(date) {
  331. return Math.floor(new Date(date).getTime() / 1000);
  332. },
  333. async getWarningManualList(){
  334. if (this.loading) return;
  335. this.loading = true;
  336. const start = this.dateToTimestamp(this.startTime + ' 00:00:00');
  337. const end = this.dateToTimestamp(this.endTime + ' 23:59:59');
  338. const params = {
  339. start,
  340. end,
  341. page: this.page,
  342. page_size: this.page_size,
  343. fk_type: this.tabs[this.activeTab].id,
  344. device_id: this.deviceId,
  345. device_type_id: this.device_type_id
  346. }
  347. try {
  348. const res = await this.$myRequest({
  349. url:'/api/api_gateway?method=device.env_sec_alert.get_manual_env_sec_alert_record',
  350. method:'POST',
  351. data: params,
  352. })
  353. const resData = res?.data || [];
  354. const list = resData || [];
  355. if (this.page === 1) {
  356. this.manualWarningList = list;
  357. } else {
  358. this.manualWarningList = [...this.manualWarningList, ...list];
  359. }
  360. this.total = res?.total || 0;
  361. this.loading = false;
  362. // 计算是否还有更多数据
  363. if (this.manualWarningList.length >= this.total) {
  364. this.finished = true;
  365. } else {
  366. this.page++;
  367. }
  368. // 结束刷新状态
  369. if (this.refreshing) {
  370. this.refreshing = false;
  371. }
  372. } catch (error) {
  373. console.error('获取预警列表失败:', error);
  374. this.loading = false;
  375. if (this.refreshing) {
  376. this.refreshing = false;
  377. }
  378. }
  379. },
  380. async getWarningList(){
  381. if (this.loading) return;
  382. this.loading = true;
  383. const start = this.dateToTimestamp(this.startTime + ' 00:00:00');
  384. const end = this.dateToTimestamp(this.endTime + ' 23:59:59');
  385. console.log(this.activeTab,this.tabs,'activeTabactiveTabactiveTab')
  386. const params = {
  387. start,
  388. end,
  389. page: this.page,
  390. fk_type: this.tabs[this.activeTab].id,
  391. page_size: this.page_size,
  392. device_id: this.deviceId,
  393. device_type_id: this.device_type_id
  394. }
  395. try {
  396. const res = await this.$myRequest({
  397. url:'/api/api_gateway?method=device.env_sec_alert.get_env_sec_alert',
  398. method:'POST',
  399. data: params,
  400. })
  401. const resData = res?.data || [];
  402. const list = resData || [];
  403. if (this.page === 1) {
  404. this.warningList = list;
  405. } else {
  406. this.warningList = [...this.warningList, ...list];
  407. }
  408. this.total = res?.total_num || 0;
  409. this.loading = false;
  410. // 计算是否还有更多数据
  411. if (this.warningList.length >= this.total) {
  412. this.finished = true;
  413. } else {
  414. this.page++;
  415. }
  416. // 结束刷新状态
  417. if (this.refreshing) {
  418. this.refreshing = false;
  419. }
  420. } catch (error) {
  421. console.error('获取预警列表失败:', error);
  422. this.loading = false;
  423. if (this.refreshing) {
  424. this.refreshing = false;
  425. }
  426. }
  427. },
  428. // 回到顶部
  429. scrollToTop() {
  430. this.listScrollTop = 0;
  431. }
  432. }
  433. };
  434. </script>
  435. <style scoped lang="scss">
  436. .warning-center {
  437. min-height: 100vh;
  438. font-family: 'Source Han Sans CN';
  439. background: linear-gradient(0deg, #F5F6FA 79.64%, #FFEEEC 99.35%);
  440. }
  441. ::v-deep .u-calendar__action{
  442. display:flex;
  443. }
  444. ::v-deep .u-calendar__action__icon{
  445. width: 40rpx;
  446. }
  447. ::v-deep .u-calendar__action__text{
  448. width: calc(100% - 160rpx);
  449. text-align: center;
  450. }
  451. .content {
  452. padding: 0 32rpx;
  453. }
  454. /* 宣传语区域 */
  455. .banner {
  456. display: flex;
  457. align-items: center;
  458. justify-content: space-between;
  459. margin: 32rpx 0;
  460. margin-bottom: 0rpx;
  461. padding: 24rpx;
  462. .banner-text {
  463. flex: 1;
  464. .banner-title {
  465. font-style: italic;
  466. display: block;
  467. color: #303133;
  468. font-family: "Source Han Sans CN VF";
  469. font-size: 40rpx;
  470. font-weight: 700;
  471. margin-bottom: 8rpx;
  472. }
  473. .banner-subtitle {
  474. display: block;
  475. font-size: 24rpx;
  476. color: #666666;
  477. }
  478. }
  479. .warning-icon {
  480. .icon-triangle {
  481. width: 130rpx;
  482. height: 130rpx;
  483. position: relative;
  484. .icon-image{
  485. width: 100%;
  486. height: 100%;
  487. }
  488. }
  489. }
  490. }
  491. .popup-container{
  492. position:relative;
  493. .popup-icon {
  494. position: absolute;
  495. top:0;
  496. right:0;
  497. margin-left: 12rpx;
  498. width: 112rpx;
  499. height: 48rpx;
  500. background: url('./assets/normal-gray.png');
  501. background-repeat: no-repeat;
  502. background-size: 100%;
  503. &.popup-level-normal {
  504. background: url('./assets/normal.png');
  505. background-repeat: no-repeat;
  506. background-size: 100%;
  507. }
  508. &.popup-level-normal-gray {
  509. background: url('./assets/normal-gray.png');
  510. background-repeat: no-repeat;
  511. background-size: 100%;
  512. }
  513. &.popup-level-important-gray {
  514. background: url('./assets/important-gray.png');
  515. background-repeat: no-repeat;
  516. background-size: 100%;
  517. }
  518. &.popup-level-important {
  519. background: url('./assets/important.png');
  520. background-repeat: no-repeat;
  521. background-size: 100%;
  522. }
  523. &.popup-level-urgent-gray {
  524. background: url('./assets/urgent-gray.png');
  525. background-repeat: no-repeat;
  526. background-size: 100%;
  527. }
  528. &.popup-level-urgent {
  529. background: url('./assets/urgent.png');
  530. background-repeat: no-repeat;
  531. background-size: 100%;
  532. }
  533. }
  534. }
  535. .popup-header{
  536. padding: 20rpx 32rpx;
  537. width: 100%;
  538. text-align: left;
  539. color: #303133;
  540. font-family: "Source Han Sans CN VF";
  541. font-size: 32rx;
  542. font-weight: 700;
  543. }
  544. .popup-type{
  545. border-radius:32rpx;
  546. margin-left: 32rpx;
  547. display:inline-block;
  548. border: 2rpx solid #E4E7ED;
  549. padding: 2rpx 12rpx;
  550. color: #666666;
  551. font-family: "Source Han Sans CN VF";
  552. font-size: 24rpx;
  553. font-weight: 400;
  554. margin-bottom: 24rpx;
  555. }
  556. .popup-content{
  557. padding: 0 32rpx;
  558. line-height: 50rpx;
  559. }
  560. .popup-time{
  561. padding:0 32rpx;
  562. margin-top: 36rpx;
  563. color:#999999;
  564. font-size: 24rpx;
  565. text-align: left;
  566. color: #bdbdbd;
  567. font-family: "Source Han Sans CN VF";
  568. font-style: normal;
  569. font-weight: 400;
  570. }
  571. .popup-location{
  572. font-size: 24rpx;
  573. margin-top: 16rpx;
  574. padding-top: 16rpx;
  575. font-family: "Source Han Sans CN VF";
  576. color: #999999;
  577. display:flex;
  578. align-items: center;
  579. }
  580. .popup-text {
  581. padding: 0 32rpx;
  582. font-size: 24rpx;
  583. margin-top: 16rpx;
  584. padding-top: 16rpx;
  585. font-family: "Source Han Sans CN VF";
  586. color: #999999;
  587. display:flex;
  588. align-items: center;
  589. }
  590. /* 日期选择器 */
  591. .date-picker {
  592. display: flex;
  593. align-items: center;
  594. justify-content: space-between;
  595. margin-bottom: 32rpx;
  596. .date-inputs {
  597. display: flex;
  598. align-items: center;
  599. background: #ffffff;
  600. border-radius: 48rpx;
  601. padding: 14rpx;
  602. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
  603. .date-label {
  604. width:250rpx;
  605. font-size: 26rpx;
  606. color: #999999;
  607. text-align: center;
  608. }
  609. .date-separator {
  610. margin: 0 24rpx;
  611. font-size: 26rpx;
  612. color: #999999;
  613. }
  614. }
  615. .date-icons {
  616. display: flex;
  617. align-items: center;
  618. justify-content: center;
  619. width: 60rpx ;
  620. height: 60rpx;
  621. border-radius: 50%;
  622. background:#ffffff;
  623. .icon-image{
  624. width: 32rpx;
  625. height: 32rpx;
  626. }
  627. }
  628. }
  629. /* 标签导航 */
  630. .tab-nav {
  631. display: flex;
  632. margin-bottom: 24rpx;
  633. border-bottom: 1rpx solid #e5e5e5;
  634. .tab-item {
  635. padding: 20rpx 0;
  636. font-size: 28rpx;
  637. color: #666666;
  638. position: relative;
  639. margin-right: 30rpx;
  640. &.active {
  641. color: #333333;
  642. font-weight: 500;
  643. &::after {
  644. content: '';
  645. position: absolute;
  646. bottom: 0;
  647. left: 50%;
  648. transform: translateX(-50%);
  649. width: 100%;
  650. height: 4rpx;
  651. background: #515153;
  652. border-radius: 2rpx;
  653. }
  654. }
  655. }
  656. }
  657. /* 预警列表 */
  658. .warning-list {
  659. margin-bottom: 100rpx;
  660. height: calc(100vh - 600rpx);
  661. overflow-y: auto;
  662. .warning-item {
  663. position: relative;
  664. padding: 28rpx 24rpx;
  665. margin-bottom: 24rpx;
  666. background: #ffffff;
  667. border-radius: 16rpx;
  668. box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
  669. .warning-header {
  670. display: flex;
  671. align-items: center;
  672. justify-content: space-between;
  673. margin-bottom: 16rpx;
  674. .warning-type {
  675. display: flex;
  676. align-items: center;
  677. flex: 1;
  678. min-width: 0;
  679. .type-icon {
  680. width: 48rpx;
  681. height: 48rpx;
  682. border-radius: 50%;
  683. margin-right: 12rpx;
  684. flex-shrink: 0;
  685. display:flex;
  686. align-items: center;
  687. justify-content: center;
  688. &.type-red {
  689. background: linear-gradient(180deg, #FFA9A5 0%, #FF716A 100%);
  690. }
  691. &.type-blue {
  692. background: linear-gradient(180deg, #83D2FF 0%, #09A5FC 100%);
  693. }
  694. &.type-yellow {
  695. background: linear-gradient(180deg, #FED057 0%, #FFAF40 100%);
  696. }
  697. &.type-gray {
  698. background: #DDDFE6;
  699. }
  700. .icon-image{
  701. width: 28rpx;
  702. height: 28rpx;
  703. }
  704. }
  705. .type-text {
  706. font-size: 26rpx;
  707. font-weight: 500;
  708. color: #333333;
  709. margin-right: 12rpx;
  710. flex-shrink: 0;
  711. }
  712. .device-type {
  713. font-size: 22rpx;
  714. color: #515153;
  715. font-family: "Source Han Sans CN VF";
  716. font-style: normal;
  717. font-weight: 400;
  718. border: 2rpx solid #E4E7ED;
  719. padding: 2rpx 12rpx;
  720. border-radius: 32rpx;
  721. margin-left: 8rpx;
  722. flex-shrink: 0;
  723. }
  724. }
  725. .warning-level {
  726. position: absolute;
  727. top:0;
  728. right:0;
  729. margin-left: 12rpx;
  730. width: 112rpx;
  731. height: 48rpx;
  732. background: url('./assets/normal-gray.png');
  733. background-repeat: no-repeat;
  734. background-size: 100%;
  735. &.level-normal {
  736. background: url('./assets/normal.png');
  737. background-repeat: no-repeat;
  738. background-size: 100%;
  739. }
  740. &.level-normal-gray {
  741. background: url('./assets/normal-gray.png');
  742. background-repeat: no-repeat;
  743. background-size: 100%;
  744. }
  745. &.level-important {
  746. background: url('./assets/important.png');
  747. background-repeat: no-repeat;
  748. background-size: 100%;
  749. }
  750. &.level-important-gray {
  751. background: url('./assets/important-gray.png');
  752. background-repeat: no-repeat;
  753. background-size: 100%;
  754. }
  755. &.level-urgent-gray {
  756. background: url('./assets/urgent-gray.png');
  757. background-repeat: no-repeat;
  758. background-size: 100%;
  759. }
  760. &.level-urgent {
  761. background: url('./assets/urgent.png');
  762. background-repeat: no-repeat;
  763. background-size: 100%;
  764. }
  765. }
  766. }
  767. .warning-content {
  768. font-size: 28rpx;
  769. color: #333333;
  770. line-height: 40rpx;
  771. margin-bottom: 20rpx;
  772. //最多显示2行
  773. overflow: hidden;
  774. text-overflow: ellipsis;
  775. display: -webkit-box;
  776. -webkit-line-clamp: 2;
  777. -webkit-box-orient: vertical;
  778. }
  779. .warning-footer {
  780. display: flex;
  781. align-items: center;
  782. justify-content: space-between;
  783. .warning-time {
  784. font-size: 24rpx;
  785. color: #999999;
  786. }
  787. .warning-location {
  788. display: flex;
  789. align-items: center;
  790. }
  791. }
  792. .location-text {
  793. font-size: 24rpx;
  794. margin-top: 16rpx;
  795. padding-top: 16rpx;
  796. border-top: 1rpx solid #f0f0f0;
  797. font-family: "Source Han Sans CN VF";
  798. color: #999999;
  799. display:flex;
  800. align-items: center;
  801. }
  802. }
  803. }
  804. /* 加载更多提示 */
  805. .loading-more {
  806. text-align: center;
  807. padding: 32rpx 0;
  808. font-size: 24rpx;
  809. color: #999999;
  810. }
  811. /* 回到顶部 */
  812. .back-to-top {
  813. position: fixed;
  814. bottom: 80rpx;
  815. right: 32rpx;
  816. width: 64rpx;
  817. height: 64rpx;
  818. background: #ffffff;
  819. border-radius: 50%;
  820. display: flex;
  821. align-items: center;
  822. justify-content: center;
  823. box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
  824. z-index: 99;
  825. }
  826. /* 顶部导航栏右侧图标 */
  827. .header-right {
  828. display: flex;
  829. align-items: center;
  830. .notification-icon {
  831. position: relative;
  832. margin-right: 32rpx;
  833. .badge {
  834. position: absolute;
  835. top: -4rpx;
  836. right: -4rpx;
  837. width: 12rpx;
  838. height: 12rpx;
  839. background: #ff6b6b;
  840. border-radius: 50%;
  841. }
  842. }
  843. }
  844. </style>