home.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794
  1. <template>
  2. <view class="container">
  3. <view v-if="!menushow" class="main">
  4. <view class="u-page">
  5. <view :class="{ empty: showList.length === 0 }">
  6. <template v-if="showList.length > 0">
  7. <view v-for="(item, index) in showList" :key="index">
  8. <view class="device-card">
  9. <!-- 标题 -->
  10. <view class="card-title-row">
  11. <text class="card-title">{{ item.strinstallpos }}</text>
  12. </view>
  13. <view class="card-divider"></view>
  14. <!-- 状态标签行 -->
  15. <view class="status-row">
  16. <view class="status-left">
  17. <view
  18. v-if="item.netStatus == 0"
  19. class="status-tag tag-offline"
  20. >
  21. <image
  22. src="/static/model/connectFalse.svg"
  23. class="tag-icon"
  24. />
  25. <text>断开</text>
  26. </view>
  27. <view v-else class="status-tag tag-online">
  28. <image
  29. src="/static/model/connectTrue.svg"
  30. class="tag-icon"
  31. />
  32. <text>连接</text>
  33. </view>
  34. <view
  35. v-if="item.warnFlag == 0"
  36. class="status-tag tag-normal"
  37. >
  38. <image
  39. src="/static/model/alarmTrue.svg"
  40. class="tag-icon"
  41. />
  42. <text>正常</text>
  43. </view>
  44. <view
  45. v-else
  46. class="status-tag tag-warn"
  47. @click="toggleWarn()"
  48. >
  49. <image
  50. src="/static/model/alarmFalse.svg"
  51. class="tag-icon"
  52. />
  53. <text class="warn-text">{{ item.warnDes }}</text>
  54. </view>
  55. </view>
  56. <view v-if="hasDoorUse" class="door-use-btn">
  57. <text>{{ getDoorUseText(item.doorUse) }}</text>
  58. </view>
  59. </view>
  60. <!-- 普通设备数据 -->
  61. <view
  62. v-if="TabCur != 'fanmain' && TabCur != 'fanlocal'"
  63. class="data-grid"
  64. @tap="openNewPage(item)"
  65. >
  66. <view
  67. class="datacard"
  68. v-for="(showitem, sIndex) in deviceShowList"
  69. :key="sIndex"
  70. v-show="isDataField(showitem)"
  71. >
  72. <view class="data-icon">
  73. <view class="data-icon-glass">
  74. <!-- <u-icon
  75. :name="getFieldIcon(showitem.monitorcode)"
  76. color="#ffffff"
  77. size="14"
  78. ></u-icon> -->
  79. <image
  80. class="icon-top"
  81. :src="getIcon1(showitem.monitorcode)"
  82. mode="aspectFit"
  83. ></image>
  84. </view>
  85. </view>
  86. <view class="data-text">
  87. <text class="data-value">{{
  88. getFieldValue(item, showitem)
  89. }}</text>
  90. <text class="data-label">{{ showitem.des }}</text>
  91. </view>
  92. </view>
  93. <!-- 更新时间 -->
  94. <view class="datacard" v-if="item.readTime">
  95. <view class="data-icon">
  96. <view class="data-icon-glass">
  97. <image
  98. class="icon-top"
  99. src="/static/warndata/shijian.svg"
  100. mode="aspectFit"
  101. ></image>
  102. </view>
  103. </view>
  104. <view class="data-text">
  105. <text class="data-value">{{ item.readTime }}</text>
  106. <text class="data-label">更新时间</text>
  107. </view>
  108. </view>
  109. </view>
  110. <!-- 风机设备:主机 / 备机 -->
  111. <view class="fanContent" @tap="openNewPage(item)" v-else>
  112. <view class="fan-block">
  113. <view class="fan-label"><text class="">主机</text></view>
  114. <view class="data-grid">
  115. <view
  116. class="datacard"
  117. v-for="(showitem, sIndex) in deviceShowList"
  118. :key="'f1-' + sIndex"
  119. v-show="isDataField(showitem)"
  120. >
  121. <view class="data-icon">
  122. <view class="data-icon-glass">
  123. <u-icon
  124. :name="getFieldIcon(showitem.monitorcode)"
  125. color="#ffffff"
  126. size="14"
  127. ></u-icon>
  128. </view>
  129. </view>
  130. <view class="data-text">
  131. <text class="data-value">{{
  132. getFanFieldValue(item, showitem, 1)
  133. }}</text>
  134. <text class="data-label">{{ showitem.des }}</text>
  135. </view>
  136. </view>
  137. </view>
  138. </view>
  139. <view class="fan-block">
  140. <view class="fan-label"><text class="">备机</text></view>
  141. <view class="data-grid">
  142. <view
  143. class="datacard"
  144. v-for="(showitem, sIndex) in deviceShowList"
  145. :key="'f2-' + sIndex"
  146. v-show="isDataField(showitem)"
  147. >
  148. <view class="data-icon">
  149. <view class="data-icon-glass">
  150. <u-icon
  151. :name="getFieldIcon(showitem.monitorcode)"
  152. color="#ffffff"
  153. size="14"
  154. ></u-icon>
  155. </view>
  156. </view>
  157. <view class="data-text">
  158. <text class="data-value">{{
  159. getFanFieldValue(item, showitem, 2)
  160. }}</text>
  161. <text class="data-label">{{ showitem.des }}</text>
  162. </view>
  163. </view>
  164. </view>
  165. </view>
  166. <!-- 更新时间 -->
  167. <view class="data-grid" v-if="item.readTime">
  168. <view class="datacard">
  169. <view class="data-icon">
  170. <view class="data-icon-glass">
  171. <image
  172. class="icon-top"
  173. src="/static/warndata/shijian.svg"
  174. mode="aspectFit"
  175. ></image>
  176. </view>
  177. </view>
  178. <view class="data-text">
  179. <text class="data-value">{{ item.readTime }}</text>
  180. <text class="data-label">更新时间</text>
  181. </view>
  182. </view>
  183. </view>
  184. </view>
  185. </view>
  186. </view>
  187. </template>
  188. <template v-else>
  189. <view class="empty-message">数据为空</view>
  190. </template>
  191. </view>
  192. </view>
  193. </view>
  194. </view>
  195. </template>
  196. <script>
  197. import api from "@/api/api";
  198. import { computed } from "vue";
  199. export default {
  200. data() {
  201. return {
  202. deviceShow1: false,
  203. menushow: false,
  204. TabCur: "",
  205. curlist: [],
  206. deviceList: {},
  207. List: [],
  208. colums: {},
  209. typeList: [], //详情页展示数据
  210. deviceShowList: [], //设备展示字段
  211. isWarnVisible: false,
  212. deviceType1: "",
  213. devices1: [],
  214. showList: [],
  215. };
  216. },
  217. props: ["showColum", "deviceType"],
  218. computed: {
  219. hasDoorUse() {
  220. return (this.deviceShowList || []).some(
  221. (item) => item.appShow == 1 && item.monitorcode == "doorUse"
  222. );
  223. },
  224. },
  225. watch: {
  226. showColum(data) {
  227. this.colums = data;
  228. },
  229. deviceType: {
  230. async handler(data) {
  231. if (data) {
  232. this.TabCur = data;
  233. this.curlist = this.deviceList[this.TabCur];
  234. if (this.curlist == null) {
  235. this.curlist = [];
  236. }
  237. // 选择设备分类,重新获取数据
  238. await this.loadData(this.TabCur);
  239. this.$emit("setMenushow", {
  240. menushow: false,
  241. });
  242. }
  243. },
  244. immediate: true,
  245. },
  246. },
  247. created() {
  248. this.colums = this.showColum;
  249. // this.deviceShowList = this.colums[key];
  250. },
  251. mounted() {
  252. this.startTimer();
  253. },
  254. methods: {
  255. toggleWarn() {
  256. console.log("测试");
  257. this.isWarnVisible = !this.isWarnVisible;
  258. },
  259. isDataField(showitem) {
  260. return (
  261. showitem.appShow == 1 &&
  262. showitem.monitorcode != "strinstallpos" &&
  263. showitem.monitorcode != "netStatus" &&
  264. showitem.monitorcode != "warnFlag" &&
  265. showitem.monitorcode != "readTime" &&
  266. showitem.monitorcode != "doorUse" &&
  267. showitem.monitorcode != ""
  268. );
  269. },
  270. getDoorUseText(val) {
  271. if (val == "2") return "行人";
  272. if (val == "1") return "行车";
  273. if (val == "3") return "短路";
  274. return "-";
  275. },
  276. getFieldValue(item, showitem) {
  277. if (showitem.monitorcode == "doorUse") {
  278. return this.getDoorUseText(item[showitem.monitorcode]);
  279. }
  280. const val = item[showitem.monitorcode];
  281. if (val == null || val == "") return "-";
  282. return val;
  283. },
  284. getFanFieldValue(item, showitem, fanNo) {
  285. const code = showitem.monitorcode;
  286. let key = code;
  287. if (code.startsWith("fan")) {
  288. key = code.replace(/^fan/, "fan" + fanNo);
  289. } else if (code.startsWith("Fan")) {
  290. key = code.replace(/^Fan/, "Fan" + fanNo);
  291. }
  292. if (item[key] !== undefined && item[key] !== null) {
  293. return item[key];
  294. }
  295. return "-";
  296. },
  297. getFieldIcon(monitorcode) {
  298. const code = (monitorcode || "").toLowerCase();
  299. if (code.indexOf("gate") > -1 || code.indexOf("door") > -1) {
  300. return "grid-fill";
  301. }
  302. if (code.indexOf("press") > -1 || code.indexOf("pressure") > -1) {
  303. return "level";
  304. }
  305. if (code.indexOf("wind") > -1 || code.indexOf("speed") > -1) {
  306. return "reload";
  307. }
  308. return "list";
  309. },
  310. getIcon1(monitorcode) {
  311. const code = (monitorcode || "").toLowerCase();
  312. if (code.indexOf("frontarea") > -1) {
  313. return "/static/home/gfmj.svg";
  314. }
  315. if (code.indexOf("area") > -1) {
  316. return "/static/icon-new/dmj.svg";
  317. }
  318. if (
  319. code.indexOf("m3") > -1 ||
  320. code.indexOf("va") > -1 ||
  321. code.indexOf("forward") > -1
  322. ) {
  323. return "/static/icon-new/fl.svg";
  324. }
  325. if (code.indexOf("gate") > -1 || code.indexOf("door") > -1) {
  326. return "/static/icon-new/door-icon.svg";
  327. }
  328. if (
  329. code.indexOf("press") > -1 ||
  330. code.indexOf("pressure") > -1 ||
  331. code.indexOf("pa1") > -1 ||
  332. code.indexOf("pa2") > -1 ||
  333. code.indexOf("dp") > -1
  334. ) {
  335. return "/static/icon-new/qyyl-icon.svg";
  336. }
  337. return "/static/icon-new/dmj.svg";
  338. },
  339. startTimer() {
  340. // 避免重复创建定时器
  341. this.stopTimer();
  342. // 每隔一段时间执行某个操作
  343. this.timer = setInterval(async () => {
  344. // 执行定时任务
  345. await this.loadData(this.deviceType);
  346. console.log("定时任务执行中...");
  347. }, 5000);
  348. },
  349. stopTimer() {
  350. // 停止定时器
  351. if (this.timer) {
  352. clearInterval(this.timer);
  353. this.timer = null;
  354. }
  355. },
  356. // 从详情页返回时:恢复轮询并立即刷新一次数据
  357. restartTimer() {
  358. this.startTimer();
  359. if (this.deviceType) {
  360. this.loadData(this.deviceType);
  361. }
  362. },
  363. getIcon(itemValue) {
  364. // 根据itemValue获取对应的图标路径,如果找不到对应关系则返回默认图标
  365. return "/static/sidebar/" + itemValue + ".svg";
  366. },
  367. getValueIcon(itemValue) {
  368. // 根据itemValue获取对应的图标路径,如果找不到对应关系则返回默认图标
  369. return "/static/sidebar/" + itemValue + ".svg";
  370. },
  371. loadData(type) {
  372. return new Promise((resolve, reject) => {
  373. api
  374. .getDeviceMonitor({
  375. devicetype: type,
  376. pagetype: "normal",
  377. })
  378. .then((response) => {
  379. if (response.data.code == 200) {
  380. this.deviceList[type] = response.data.result.msgTxt[0].datalist;
  381. this.curlist = this.deviceList[type];
  382. const processedList = this.curlist.map((item) => {
  383. const { readData, ...baseFields } = item;
  384. return { ...baseFields, ...readData };
  385. });
  386. this.showList = processedList;
  387. this.showList.forEach((item) => {
  388. if (item.frontGateOpen == 1) {
  389. item.frontGateOpen = "打开";
  390. } else {
  391. item.frontGateOpen = "关闭";
  392. }
  393. if (item.midGateOpen == 1) {
  394. item.midGateOpen = "打开";
  395. } else {
  396. item.midGateOpen = "关闭";
  397. }
  398. if (item.rearGateOpen == 1) {
  399. item.rearGateOpen = "打开";
  400. } else {
  401. item.rearGateOpen = "关闭";
  402. }
  403. if (item.midGateOpen == 1) {
  404. item.midGateOpen = "打开";
  405. } else {
  406. item.midGateOpen = "关闭";
  407. }
  408. this.deviceType1 = item.deviceType;
  409. let original = this.TabCur;
  410. let newName = original.startsWith("sys_")
  411. ? original.substring(4)
  412. : original;
  413. const key = newName + "_monitor";
  414. const key1 = this.deviceType1 + "_monitor";
  415. if (this.showColum?.[key1]?.length > 0) {
  416. this.deviceShowList = this.showColum[key1];
  417. console.log(this.deviceShowList, "this.deviceShowList");
  418. } else {
  419. this.deviceShowList = this.showColum[key] ?? [];
  420. console.log(this.deviceShowList, "this.deviceShowList");
  421. }
  422. });
  423. if (this.TabCur == "sys_pulping") {
  424. this.loadNewData(this.curlist[0].deviceID);
  425. }
  426. } else {
  427. resolve(response);
  428. }
  429. })
  430. .catch((error) => {
  431. // console.log("catch===>response", response);
  432. reject(error);
  433. });
  434. });
  435. },
  436. loadNewData(ID) {
  437. return new Promise((resolve, reject) => {
  438. api
  439. .getDeviceMonitor({
  440. devicetype: "sys",
  441. systemID: ID,
  442. })
  443. .then((response) => {
  444. if (response.data.code == 200) {
  445. this.curlist = [];
  446. this.List = response.data.result.msgTxt;
  447. this.List.forEach((item) => {
  448. if (item.type === "pulping_auto") {
  449. this.curlist.push(item.datalist[0]);
  450. }
  451. });
  452. } else {
  453. resolve(response);
  454. }
  455. })
  456. .catch((error) => {
  457. // console.log("catch===>response", response);
  458. reject(error);
  459. });
  460. });
  461. },
  462. devicemenuShow(e) {
  463. this.menushow = !this.menushow;
  464. },
  465. //获取app展示字段数据
  466. getShowList(type) {
  467. const params = {
  468. devicekind: type,
  469. pagetype: "monitor",
  470. pageNo: 1,
  471. pageSize: 100,
  472. };
  473. return new Promise((resolve, reject) => {
  474. api
  475. .getShowColumList(params)
  476. .then((response) => {
  477. if (response.data.code == 200) {
  478. this.typeList = response.data.result.records;
  479. resolve(response);
  480. } else {
  481. resolve(response);
  482. }
  483. })
  484. .catch((error) => {
  485. reject(error);
  486. });
  487. });
  488. },
  489. openNewPage(params) {
  490. const reqData = {
  491. id: params.deviceID,
  492. name: params.strinstallpos,
  493. type: this.TabCur,
  494. };
  495. const reqparams = uni.$u.queryParams(reqData);
  496. // const key = this.deviceType1 + "_monitor";
  497. if (this.deviceShowList.length > 0) {
  498. // 仅暂停轮询,不能 $destroy(否则返回后组件不再响应 deviceType 变化)
  499. this.stopTimer();
  500. uni.navigateTo({
  501. url: `/pages/home/detail/autodoor/autodoor${reqparams}`,
  502. });
  503. }
  504. // this.$destroy();
  505. // uni.navigateTo({
  506. // url: `/pages/home/detail/autodoor/autodoor?id=${params.deviceID}&name=${params.strinstallpos}&type=${this.TabCur}`,
  507. // });
  508. // },
  509. },
  510. },
  511. destroyed() {
  512. // 停止定时器
  513. this.stopTimer();
  514. },
  515. };
  516. </script>
  517. <style scoped>
  518. .container {
  519. min-height: 100%;
  520. /* background: #f4f7fd; */
  521. }
  522. .main {
  523. display: flex;
  524. flex-direction: column;
  525. /* background: #f4f7fd; */
  526. }
  527. .u-page {
  528. padding: 20rpx 24rpx;
  529. box-sizing: border-box;
  530. }
  531. .empty {
  532. background: url("/static/empty.png") no-repeat;
  533. background-size: 100% 50%;
  534. }
  535. .empty-message {
  536. display: flex;
  537. justify-content: center;
  538. align-items: center;
  539. font-size: 16px;
  540. line-height: 80vh;
  541. color: #000;
  542. }
  543. /* ===== 设备卡片 ===== */
  544. .device-card {
  545. background: #f9f9fb;
  546. border-radius: 20rpx;
  547. padding: 28rpx 24rpx 24rpx;
  548. margin-bottom: 24rpx;
  549. border: 1rpx solid #fff;
  550. }
  551. .card-title-row {
  552. display: flex;
  553. flex-direction: row;
  554. align-items: center;
  555. justify-content: space-between;
  556. }
  557. .card-title {
  558. flex: 1;
  559. font-size: 28rpx;
  560. font-weight: 700;
  561. color: #000;
  562. line-height: 1.3;
  563. overflow: hidden;
  564. text-overflow: ellipsis;
  565. white-space: nowrap;
  566. }
  567. .card-divider {
  568. height: 1rpx;
  569. background: #efeff0;
  570. margin: 20rpx 0;
  571. }
  572. /* ===== 状态行 ===== */
  573. .status-row {
  574. display: flex;
  575. flex-direction: row;
  576. align-items: center;
  577. justify-content: space-between;
  578. margin-bottom: 20rpx;
  579. }
  580. .status-left {
  581. display: flex;
  582. flex-direction: row;
  583. align-items: center;
  584. flex-wrap: wrap;
  585. flex: 1;
  586. min-width: 0;
  587. }
  588. .status-tag {
  589. display: flex;
  590. flex-direction: row;
  591. align-items: center;
  592. height: 48rpx;
  593. padding: 0 16rpx;
  594. margin-right: 12rpx;
  595. margin-bottom: 4rpx;
  596. border-radius: 8rpx;
  597. border-width: 1rpx;
  598. border-style: solid;
  599. font-size: 24rpx;
  600. box-sizing: border-box;
  601. }
  602. .tag-icon {
  603. width: 24rpx;
  604. height: 24rpx;
  605. margin-right: 8rpx;
  606. flex-shrink: 0;
  607. }
  608. .tag-offline {
  609. color: #888888;
  610. background: #f5f5f5;
  611. border-color: #d1d1d1;
  612. }
  613. .tag-online {
  614. color: #42c000;
  615. background: #e8f8e0;
  616. border-color: #a8e08a;
  617. }
  618. .tag-normal {
  619. color: #42c000;
  620. background: #e8f8e0;
  621. border-color: #a8e08a;
  622. }
  623. .tag-warn {
  624. color: #e90000;
  625. background: #ffebee;
  626. border-color: #ef9a9a;
  627. max-width: 280rpx;
  628. }
  629. .warn-text {
  630. overflow: hidden;
  631. text-overflow: ellipsis;
  632. white-space: nowrap;
  633. }
  634. .door-use-btn {
  635. flex-shrink: 0;
  636. height: 48rpx;
  637. padding: 0 24rpx;
  638. border-radius: 8rpx;
  639. border: 1rpx solid #7eb6ff;
  640. background: #e0edfa;
  641. display: flex;
  642. align-items: center;
  643. justify-content: center;
  644. color: #0065f8;
  645. font-size: 28rpx;
  646. font-weight: 500;
  647. }
  648. /* ===== 数据网格 ===== */
  649. .data-grid {
  650. display: flex;
  651. flex-direction: row;
  652. flex-wrap: wrap;
  653. margin: 0 -6rpx;
  654. }
  655. .datacard {
  656. display: flex;
  657. flex-direction: row;
  658. align-items: center;
  659. width: 48%;
  660. margin: 6rpx;
  661. padding: 16rpx 12rpx;
  662. box-sizing: border-box;
  663. border-radius: 12rpx;
  664. background: linear-gradient(
  665. to bottom,
  666. rgba(175, 195, 252, 0.6) 0%,
  667. rgba(175, 195, 252, 0.1) 100%
  668. );
  669. }
  670. .data-icon {
  671. position: relative;
  672. width: 48rpx;
  673. height: 48rpx;
  674. border-radius: 10rpx;
  675. background: #2b7cff;
  676. box-shadow: 0 4rpx 10rpx rgba(43, 124, 255, 0.22);
  677. display: flex;
  678. align-items: center;
  679. justify-content: center;
  680. flex-shrink: 0;
  681. margin-right: 10rpx;
  682. }
  683. .data-icon-glass {
  684. position: absolute;
  685. left: -5rpx;
  686. bottom: -5rpx;
  687. width: 43rpx;
  688. height: 43rpx;
  689. border-radius: 10rpx;
  690. background: transparent;
  691. box-shadow: 0 0 0 0.6px #ffffff inset;
  692. box-sizing: border-box;
  693. backdrop-filter: blur(4rpx);
  694. -webkit-backdrop-filter: blur(4rpx);
  695. display: flex;
  696. align-items: center;
  697. justify-content: center;
  698. }
  699. .icon-top {
  700. width: 30rpx;
  701. height: 28rpx;
  702. }
  703. .data-text {
  704. flex: 1;
  705. min-width: 0;
  706. display: flex;
  707. flex-direction: column;
  708. }
  709. .data-value {
  710. font-size: 28rpx;
  711. font-weight: 700;
  712. color: #0065f8;
  713. line-height: 1.3;
  714. overflow: hidden;
  715. text-overflow: ellipsis;
  716. white-space: nowrap;
  717. }
  718. .data-label {
  719. margin-top: 4rpx;
  720. font-size: 24rpx;
  721. color: #333333;
  722. line-height: 1.3;
  723. overflow: hidden;
  724. text-overflow: ellipsis;
  725. white-space: nowrap;
  726. }
  727. /* ===== 风机 ===== */
  728. .fanContent {
  729. display: flex;
  730. flex-direction: column;
  731. }
  732. .fan-block {
  733. margin-bottom: 12rpx;
  734. }
  735. .fan-label {
  736. display: flex;
  737. flex-direction: row;
  738. align-items: center;
  739. height: 28px;
  740. width: 100%;
  741. margin-bottom: 20rpx;
  742. padding-left: 30rpx;
  743. background: url("../../static/warndata/1-1.png") no-repeat center;
  744. background-size: 100% 100%;
  745. }
  746. .fan-label text {
  747. font-size: 24rpx;
  748. font-weight: 600;
  749. color: #000;
  750. margin: 4rpx 6rpx 8rpx;
  751. }
  752. .menupage {
  753. position: absolute;
  754. z-index: 2;
  755. width: 100%;
  756. }
  757. </style>