menus.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  1. <template>
  2. <view v-show="!isSortType && menus.length">
  3. <common-wrapper :config="configData" :style="[boxContentStyle]">
  4. <view>
  5. <view
  6. class="menu-header"
  7. v-if="
  8. headerConfig.enable && (leftTopText.enable || rightTopText.enable)
  9. "
  10. :style="[headerBoxStyle]"
  11. >
  12. <text
  13. class="left-text"
  14. v-if="leftTopText.enable"
  15. :style="[leftTextStyle]"
  16. >
  17. {{ leftTopText.text }}
  18. </text>
  19. <view
  20. class="right-text"
  21. v-if="rightTopText.enable"
  22. :style="[rightTextStyle]"
  23. @click="goMenuPage(rightTopText.link, item)"
  24. >
  25. {{ rightTopText.text }}
  26. <text
  27. class="iconfont icon-xiangyou"
  28. v-if="rightTopText.text && rightTopText.link"
  29. :style="[rightIconStyle]"
  30. ></text>
  31. </view>
  32. </view>
  33. <!-- 列表样式 -->
  34. <view class="list-menu" v-if="menuStyleConfig === 2">
  35. <view class="list-item" v-for="(item, index) in menus" :key="index">
  36. <view
  37. v-if="
  38. !item.routine_contact_type ||
  39. item.info[1].value !== '/pages/extension/customer_list/chat'
  40. "
  41. class="list-item-content"
  42. @click="goMenuPage(item.info[1].value)"
  43. >
  44. <view class="list-img-box" v-if="navDisplayStyle !== 2">
  45. <block v-if="listStyle == 0">
  46. <easy-loadimage
  47. v-if="item.img"
  48. :image-src="item.img"
  49. width="90rpx"
  50. height="90rpx"
  51. :borderRadius="imgStyle"
  52. ></easy-loadimage>
  53. <view class="list-empty-box" v-else>
  54. <image
  55. src="/static/images/shan.png"
  56. mode="aspectFill"
  57. ></image>
  58. </view>
  59. </block>
  60. <block v-else>
  61. <view class="icon-box" :style="[iconBoxStyle]">
  62. <view
  63. :class="['iconfont', item.icon]"
  64. :style="[iconContentStyle]"
  65. ></view>
  66. <text v-if="item.num" class="num">{{ item.num }}</text>
  67. </view>
  68. </block>
  69. </view>
  70. <view
  71. class="list-text"
  72. :style="[textColor]"
  73. v-if="navDisplayStyle !== 1"
  74. >
  75. {{ item.info[0].value }}
  76. </view>
  77. </view>
  78. <template v-else>
  79. <!-- #ifdef MP -->
  80. <button
  81. class="list-item-content"
  82. open-type="contact"
  83. v-if="item.routine_contact_type"
  84. >
  85. <view class="list-img-box" v-if="navDisplayStyle !== 2">
  86. <block v-if="listStyle == 0">
  87. <easy-loadimage
  88. v-if="item.img"
  89. :image-src="item.img"
  90. width="90rpx"
  91. height="90rpx"
  92. :borderRadius="imgStyle"
  93. ></easy-loadimage>
  94. <view class="list-empty-box" v-else>
  95. <image
  96. src="/static/images/shan.png"
  97. mode="aspectFill"
  98. ></image>
  99. </view>
  100. </block>
  101. <block v-else>
  102. <view class="icon-box" :style="[iconBoxStyle]">
  103. <view
  104. :class="['iconfont', item.icon]"
  105. :style="[iconContentStyle]"
  106. ></view>
  107. <text v-if="item.num" class="num">{{ item.num }}</text>
  108. </view>
  109. </block>
  110. </view>
  111. <view
  112. class="list-text"
  113. :style="[textColor]"
  114. v-if="navDisplayStyle !== 1"
  115. >
  116. {{ item.info[0].value }}
  117. </view>
  118. </button>
  119. <!-- #endif -->
  120. </template>
  121. <text class="iconfont icon-xiangyou list-arrow"></text>
  122. </view>
  123. </view>
  124. <!-- 宫格/排列样式 -->
  125. <view v-else>
  126. <view class="swiper" v-if="isShowConfig">
  127. <swiper
  128. :interval="3000"
  129. :duration="500"
  130. :style="'height:' + navHigh + 'px;'"
  131. @change="bannerfun"
  132. >
  133. <block>
  134. <swiper-item v-for="(item, indexw) in menuList" :key="indexw">
  135. <view
  136. class="menu"
  137. :id="'nav' + indexw"
  138. :class="{
  139. 'grid-three': menuStyleConfig === 1 && gridStyle === 0,
  140. 'grid-four': menuStyleConfig === 1 && gridStyle === 1,
  141. }"
  142. :style="[gridContainerStyle]"
  143. >
  144. <template v-for="(itemn, indexn) in item.list">
  145. <view
  146. v-if="
  147. !itemn.routine_contact_type ||
  148. itemn.info[1].value !==
  149. '/pages/extension/customer_list/chat'
  150. "
  151. class="flex-col flex-center"
  152. :class="{
  153. 'grid-item': menuStyleConfig === 1,
  154. }"
  155. :key="indexn"
  156. @click="goMenuPage(itemn.info[1].value)"
  157. :style="[gridItemContentStyle]"
  158. >
  159. <view
  160. class="pictrue skeleton-radius"
  161. v-if="navDisplayStyle !== 2"
  162. >
  163. <block v-if="listStyle == 0">
  164. <easy-loadimage
  165. :image-src="itemn.img"
  166. width="90rpx"
  167. height="90rpx"
  168. :borderRadius="imgStyle"
  169. ></easy-loadimage>
  170. </block>
  171. <block v-else>
  172. <view class="icon-box" :style="[iconBoxStyle]">
  173. <view
  174. :class="['iconfont', itemn.icon]"
  175. :style="[iconContentStyle]"
  176. ></view>
  177. <text v-if="itemn.num" class="num">{{
  178. itemn.num
  179. }}</text>
  180. </view>
  181. </block>
  182. </view>
  183. <view
  184. class="fs-24"
  185. :class="{ 'mt-10': listStyle === 0 }"
  186. :style="[textColor]"
  187. v-if="navDisplayStyle !== 1"
  188. >{{ itemn.info[0].value }}</view
  189. >
  190. </view>
  191. <template v-else>
  192. <!-- #ifdef MP -->
  193. <button
  194. class="flex-col flex-center reset-btn"
  195. :class="{
  196. 'grid-item': menuStyleConfig === 1,
  197. }"
  198. :key="'btn_' + indexn"
  199. open-type="contact"
  200. v-if="itemn.routine_contact_type"
  201. :style="[gridItemContentStyle]"
  202. >
  203. <view
  204. class="pictrue skeleton-radius"
  205. v-if="navDisplayStyle !== 2"
  206. >
  207. <block v-if="listStyle == 0">
  208. <easy-loadimage
  209. :image-src="itemn.img"
  210. width="90rpx"
  211. height="90rpx"
  212. :borderRadius="imgStyle"
  213. ></easy-loadimage>
  214. </block>
  215. <block v-else>
  216. <view class="icon-box" :style="[iconBoxStyle]">
  217. <view
  218. :class="['iconfont', itemn.icon]"
  219. :style="[iconContentStyle]"
  220. ></view>
  221. <text v-if="itemn.num" class="num">{{
  222. itemn.num
  223. }}</text>
  224. </view>
  225. </block>
  226. </view>
  227. <view
  228. class="fs-24"
  229. :class="{ 'mt-10': listStyle === 0 }"
  230. :style="[textColor]"
  231. v-if="navDisplayStyle !== 1"
  232. >{{ itemn.info[0].value }}</view
  233. >
  234. </button>
  235. <!-- #endif -->
  236. </template>
  237. </template>
  238. </view>
  239. </swiper-item>
  240. </block>
  241. </swiper>
  242. </view>
  243. <view v-else>
  244. <view
  245. class="menu"
  246. :class="{
  247. 'grid-three': menuStyleConfig === 1 && gridStyle === 0,
  248. 'grid-four': menuStyleConfig === 1 && gridStyle === 1,
  249. }"
  250. :style="[gridContainerStyle]"
  251. >
  252. <template v-for="(item, index) in menus">
  253. <view
  254. v-if="
  255. !item.routine_contact_type ||
  256. item.info[1].value !== '/pages/extension/customer_list/chat'
  257. "
  258. class="flex-col flex-center"
  259. :class="{
  260. 'grid-item': menuStyleConfig === 1,
  261. }"
  262. :key="index"
  263. @click="goMenuPage(item.info[1].value)"
  264. :style="[gridItemContentStyle]"
  265. >
  266. <view
  267. class="pictrue skeleton-radius"
  268. v-if="navDisplayStyle !== 2"
  269. >
  270. <block v-if="listStyle == 0">
  271. <easy-loadimage
  272. :image-src="item.img"
  273. width="90rpx"
  274. height="90rpx"
  275. :borderRadius="imgStyle"
  276. ></easy-loadimage>
  277. </block>
  278. <block v-else>
  279. <view class="icon-box" :style="[iconBoxStyle]">
  280. <view
  281. :class="['iconfont', item.icon]"
  282. :style="[iconContentStyle]"
  283. ></view>
  284. <!-- 角标数量 -->
  285. <text v-if="item.num" class="num">{{ item.num }}</text>
  286. </view>
  287. </block>
  288. </view>
  289. <view
  290. class="fs-24"
  291. :class="{ 'mt-10': listStyle === 0 }"
  292. :style="[textColor]"
  293. v-if="navDisplayStyle !== 1"
  294. >{{ item.info[0].value }}</view
  295. >
  296. </view>
  297. <template v-else>
  298. <!-- #ifdef MP -->
  299. <button
  300. class="flex-col flex-center reset-btn"
  301. :class="{
  302. 'grid-item': menuStyleConfig === 1,
  303. }"
  304. :key="'btn_' + index"
  305. open-type="contact"
  306. v-if="item.routine_contact_type"
  307. :style="[gridItemContentStyle]"
  308. >
  309. <view
  310. class="pictrue skeleton-radius"
  311. v-if="navDisplayStyle !== 2"
  312. >
  313. <block v-if="listStyle == 0">
  314. <easy-loadimage
  315. :image-src="item.img"
  316. width="90rpx"
  317. height="90rpx"
  318. :borderRadius="imgStyle"
  319. ></easy-loadimage>
  320. </block>
  321. <block v-else>
  322. <view class="icon-box" :style="[iconBoxStyle]">
  323. <view
  324. :class="['iconfont', item.icon]"
  325. :style="[iconContentStyle]"
  326. ></view>
  327. <!-- 角标数量 -->
  328. <text v-if="item.num" class="num">{{
  329. item.num
  330. }}</text>
  331. </view>
  332. </block>
  333. </view>
  334. <view
  335. class="fs-24"
  336. :class="{ 'mt-10': listStyle === 0 }"
  337. :style="[textColor]"
  338. v-if="navDisplayStyle !== 1"
  339. >{{ item.info[0].value }}</view
  340. >
  341. </button>
  342. <!-- #endif -->
  343. </template>
  344. </template>
  345. </view>
  346. </view>
  347. <view
  348. class="dot acea-row row-center-wrapper"
  349. v-if="menuList.length > 1 && isShowConfig"
  350. >
  351. <view
  352. class="dot-item line_dot-item"
  353. :style="[getDotStyle(index)]"
  354. v-for="(item, index) in menuList"
  355. :key="index"
  356. ></view>
  357. </view>
  358. </view>
  359. </view>
  360. </common-wrapper>
  361. </view>
  362. </template>
  363. <script>
  364. import commonWrapper from "./commonWrapper.vue";
  365. import { getCustomer } from "@/utils/index.js";
  366. import { toLogin } from "@/libs/login.js";
  367. import { mapGetters } from "vuex";
  368. export default {
  369. components: { commonWrapper },
  370. name: "menus",
  371. props: {
  372. dataConfig: {
  373. type: Object,
  374. default: () => {},
  375. },
  376. isSortType: {
  377. type: String | Number,
  378. default: 0,
  379. },
  380. },
  381. data() {
  382. return {
  383. navHigh: 0,
  384. menuList: [],
  385. active: 0,
  386. };
  387. },
  388. computed: {
  389. ...mapGetters({
  390. isLogin: "isLogin",
  391. }),
  392. rowsNum() {
  393. return this.dataConfig.rowsNum.tabVal;
  394. },
  395. number() {
  396. return this.dataConfig.number.tabVal;
  397. },
  398. configData() {
  399. return {
  400. ...this.dataConfig,
  401. };
  402. },
  403. menus() {
  404. let list = this.dataConfig.menuConfig.list || [];
  405. let menuList = [];
  406. list.forEach((item) => {
  407. if (item.show) {
  408. menuList.push(item);
  409. }
  410. });
  411. return menuList;
  412. },
  413. isShowConfig() {
  414. return this.dataConfig.showConfig.tabVal;
  415. },
  416. textColor() {
  417. return {
  418. color: this.dataConfig.textColor
  419. ? this.dataConfig.textColor.color[0].item
  420. : "#333",
  421. };
  422. },
  423. boxContentStyle() {
  424. let borderRadius = `${this.dataConfig.fillet.val * 2}rpx`;
  425. if (this.dataConfig.fillet.type) {
  426. borderRadius = `${this.dataConfig.fillet.valList[0].val * 2}rpx ${
  427. this.dataConfig.fillet.valList[1].val * 2
  428. }rpx ${this.dataConfig.fillet.valList[3].val * 2}rpx ${
  429. this.dataConfig.fillet.valList[2].val * 2
  430. }rpx`;
  431. }
  432. return {
  433. background: `linear-gradient(90deg, ${this.dataConfig.bgColor.color[0].item} 0%, ${this.dataConfig.bgColor.color[1].item} 100%)`,
  434. };
  435. },
  436. imgStyle() {
  437. let borderRadius = `${this.dataConfig.filletImg.val * 2}rpx`;
  438. if (this.dataConfig.filletImg.type) {
  439. borderRadius = `${this.dataConfig.filletImg.valList[0].val * 2}rpx ${
  440. this.dataConfig.filletImg.valList[1].val * 2
  441. }rpx ${this.dataConfig.filletImg.valList[3].val * 2}rpx ${
  442. this.dataConfig.filletImg.valList[2].val * 2
  443. }rpx`;
  444. }
  445. return borderRadius;
  446. },
  447. //分几行展示,一行展示多少个
  448. gridColumns() {
  449. if (this.dataConfig.number.tabVal == 0) {
  450. return {
  451. gridTemplateColumns: "repeat(3, 1fr)",
  452. };
  453. } else if (this.dataConfig.number.tabVal == 1) {
  454. return {
  455. gridTemplateColumns: "repeat(4, 1fr)",
  456. };
  457. } else {
  458. return {
  459. gridTemplateColumns: "repeat(5, 1fr)",
  460. };
  461. }
  462. },
  463. menuStyleConfig() {
  464. return this.dataConfig.menuStyleConfig.tabVal;
  465. },
  466. dotColor() {
  467. return this.dataConfig.pointerBgColor.color[0].item;
  468. },
  469. dotSelectColor() {
  470. return this.dataConfig.pointerColor.color[0].item;
  471. },
  472. headerConfig() {
  473. return this.dataConfig.headerConfig || {};
  474. },
  475. leftTopText() {
  476. return this.dataConfig.leftTopText || {};
  477. },
  478. rightTopText() {
  479. return this.dataConfig.rightTopText || {};
  480. },
  481. headerStyle() {
  482. return this.dataConfig.headerStyle || {};
  483. },
  484. navDisplayStyle() {
  485. return this.dataConfig.navDisplayStyle
  486. ? this.dataConfig.navDisplayStyle.tabVal
  487. : 0;
  488. },
  489. gridStyle() {
  490. return this.dataConfig.gridStyle ? this.dataConfig.gridStyle.tabVal : 0;
  491. },
  492. gridItemStyle() {
  493. return (
  494. this.dataConfig.gridItemStyle || {
  495. itemPadding: 8,
  496. itemBgColor: "#ffffff",
  497. itemRadius: 0,
  498. itemPaddingTop: 0,
  499. }
  500. );
  501. },
  502. listStyle() {
  503. return this.dataConfig.menuConfig.listStyle || 0;
  504. },
  505. iconStyleConfig() {
  506. let iconConfig = this.dataConfig.iconStyleConfig || {};
  507. return {
  508. color: iconConfig.color ? iconConfig.color.color[0].item : "#333",
  509. size: iconConfig.size ? iconConfig.size.val : 24,
  510. position: iconConfig.position ? iconConfig.position.tabVal : 1,
  511. padding: iconConfig.padding ? iconConfig.padding.val : 0,
  512. rotate: iconConfig.rotate ? iconConfig.rotate.val : 0,
  513. shadow: iconConfig.shadow ? iconConfig.shadow.tabVal : 0,
  514. };
  515. },
  516. iconBoxStyle() {
  517. const position = this.iconStyleConfig.position;
  518. return {
  519. justifyContent:
  520. position === 0
  521. ? "flex-start"
  522. : position === 1
  523. ? "center"
  524. : "flex-end",
  525. };
  526. },
  527. headerBoxStyle() {
  528. return {
  529. paddingTop: this.headerStyle.topPadding * 2 + "rpx",
  530. paddingBottom: this.headerStyle.bottomPadding * 2 + "rpx",
  531. paddingLeft: this.headerStyle.leftRightPadding * 2 + "rpx",
  532. paddingRight: this.headerStyle.leftRightPadding * 2 + "rpx",
  533. };
  534. },
  535. leftTextStyle() {
  536. return {
  537. color: this.headerStyle.leftColor,
  538. fontSize: this.headerStyle.fontSize * 2 + "rpx",
  539. fontWeight: this.headerStyle.leftWeight,
  540. };
  541. },
  542. rightTextStyle() {
  543. return {
  544. color: this.headerStyle.rightColor,
  545. fontSize: (this.headerStyle.rightFontSize || 12) * 2 + "rpx",
  546. fontWeight: this.headerStyle.rightWeight,
  547. };
  548. },
  549. rightIconStyle() {
  550. return {
  551. fontSize: (this.headerStyle.rightFontSize || 12) * 2 + "rpx",
  552. };
  553. },
  554. iconContentStyle() {
  555. const config = this.iconStyleConfig;
  556. return {
  557. color: config.color,
  558. fontSize: config.size * 2 + "rpx",
  559. padding: config.padding * 2 + "rpx",
  560. transform: "rotate(" + config.rotate + "deg)",
  561. textShadow: config.shadow ? "0px 2px 4px rgba(0,0,0,0.2)" : "none",
  562. };
  563. },
  564. gridContainerStyle() {
  565. if (this.menuStyleConfig === 1) {
  566. return {
  567. padding: this.gridItemStyle.itemPadding * 2 + "rpx",
  568. };
  569. } else {
  570. return this.gridColumns;
  571. }
  572. },
  573. gridItemContentStyle() {
  574. if (this.menuStyleConfig === 1) {
  575. return {
  576. backgroundColor: this.gridItemStyle.itemBgColor,
  577. borderRadius: this.gridItemStyle.itemRadius * 2 + "rpx",
  578. paddingTop: this.gridItemStyle.itemPaddingTop * 2 + "rpx",
  579. paddingBottom: this.gridItemStyle.itemPaddingTop * 2 + "rpx",
  580. };
  581. } else {
  582. return {};
  583. }
  584. },
  585. },
  586. mounted() {
  587. this.getSwiperCount();
  588. this.$nextTick(() => {
  589. if (this.menuList.length && this.isShowConfig) {
  590. let that = this;
  591. // #ifdef H5
  592. that.menuHeight();
  593. // #endif
  594. // #ifndef H5
  595. setTimeout(() => {
  596. that.menuHeight();
  597. }, 150);
  598. // #endif
  599. }
  600. });
  601. },
  602. methods: {
  603. getSwiperCount() {
  604. /* rowsNum 显示行数 0: 1行 1: 2行 2: 3行 3 4行 */
  605. /* number 单行显示 0: 3个 1: 4个 2: 5个 */
  606. this.pageNum((this.rowsNum + 1) * (this.number + 3));
  607. },
  608. bannerfun(e) {
  609. this.active = e.detail.current;
  610. },
  611. menuHeight() {
  612. let that = this;
  613. const query = uni.createSelectorQuery().in(this);
  614. query
  615. .select("#nav0")
  616. .boundingClientRect((data) => {
  617. that.navHigh = data.height;
  618. })
  619. .exec();
  620. },
  621. pageNum(num) {
  622. let count = Math.ceil(this.menus.length / num);
  623. let goodArray = new Array();
  624. for (let i = 0; i < count; i++) {
  625. let list = this.menus.slice(i * num, i * num + num);
  626. if (list.length)
  627. goodArray.push({
  628. list: list,
  629. });
  630. }
  631. this.$set(this, "menuList", goodArray);
  632. },
  633. getDotStyle(index) {
  634. return {
  635. "background-color":
  636. this.active === index ? this.dotSelectColor : this.dotColor,
  637. };
  638. },
  639. menusTap(url) {
  640. this.$util.JumpPath(url);
  641. },
  642. goMenuPage(url) {
  643. if (this.isLogin) {
  644. if (url.indexOf("http") === -1) {
  645. if (url== "/kefu/mobile_list") {
  646. return uni.navigateTo({
  647. url: `/pages/annex/web_view/index?url=${location.origin}${url}`,
  648. });
  649. } else if (url == "/pages/extension/customer_list/chat") {
  650. return getCustomer(url);
  651. }
  652. uni.navigateTo({
  653. url: url,
  654. fail(err) {
  655. uni.switchTab({
  656. url: url,
  657. });
  658. },
  659. });
  660. } else {
  661. uni.navigateTo({
  662. url: `/pages/annex/web_view/index?url=${url}`,
  663. });
  664. }
  665. } else {
  666. toLogin();
  667. }
  668. },
  669. },
  670. };
  671. </script>
  672. <style lang="scss">
  673. .menu-header {
  674. display: flex;
  675. justify-content: space-between;
  676. align-items: center;
  677. .right-text {
  678. display: flex;
  679. align-items: center;
  680. }
  681. }
  682. .dot {
  683. width: 100%;
  684. padding-bottom: 20rpx;
  685. .instruct {
  686. width: 50rpx;
  687. height: 36rpx;
  688. line-height: 36rpx;
  689. background-color: rgba(0, 0, 0, 0.8);
  690. color: #fff;
  691. border-radius: 16rpx;
  692. font-size: 24rpx;
  693. text-align: center;
  694. }
  695. .dot-item {
  696. width: 10rpx;
  697. height: 10rpx;
  698. background: rgba(0, 0, 0, 0.4);
  699. border-radius: 50%;
  700. margin: 0 4px;
  701. &.line_dot-item {
  702. width: 20rpx;
  703. height: 6rpx;
  704. border-radius: 3rpx;
  705. }
  706. }
  707. }
  708. .nav {
  709. .item {
  710. margin-right: 42rpx;
  711. width: 90rpx;
  712. text-align: center;
  713. font-size: 24rpx;
  714. display: inline-block;
  715. }
  716. }
  717. .menu {
  718. display: grid;
  719. grid-template-rows: auto;
  720. grid-row-gap: 24rpx;
  721. width: 100%;
  722. padding: 0 0 20rpx 0;
  723. }
  724. .swiper {
  725. z-index: 20;
  726. position: relative;
  727. overflow: hidden;
  728. swiper,
  729. .swiper-item {
  730. width: 100%;
  731. display: block;
  732. }
  733. }
  734. .list-menu {
  735. .list-item {
  736. display: flex;
  737. justify-content: space-between;
  738. align-items: center;
  739. margin: 0 24rpx;
  740. padding: 24rpx 0;
  741. border-bottom: 1rpx solid #eee;
  742. &:first-child {
  743. margin-top: 0;
  744. }
  745. &:last-child {
  746. border-bottom: none;
  747. margin-bottom: 0;
  748. }
  749. .list-item-content {
  750. display: flex;
  751. align-items: center;
  752. .list-img-box {
  753. margin-right: 20rpx;
  754. display: flex;
  755. align-items: center;
  756. justify-content: center;
  757. }
  758. .list-text {
  759. font-size: 28rpx;
  760. }
  761. }
  762. .list-arrow {
  763. color: #999;
  764. font-size: 24rpx;
  765. }
  766. }
  767. }
  768. .icon-box {
  769. display: flex;
  770. align-items: center;
  771. justify-content: center;
  772. position: relative;
  773. width: 90rpx;
  774. height: 90rpx;
  775. }
  776. .num {
  777. position: absolute;
  778. top: 10rpx;
  779. right: 8rpx;
  780. height: 28rpx;
  781. min-width: 20rpx;
  782. padding: 4rpx 8rpx;
  783. line-height: 20rpx;
  784. text-align: center;
  785. font-size: 20rpx;
  786. color: #fff;
  787. background-color: #ff4444;
  788. border-radius: 50%;
  789. }
  790. .grid-three {
  791. grid-template-columns: repeat(3, 1fr) !important;
  792. }
  793. .grid-four {
  794. grid-template-columns: repeat(4, 1fr) !important;
  795. }
  796. .grid-item {
  797. width: 100%;
  798. }
  799. </style>