租房小程序前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

815 lines
28 KiB

10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
  1. <template>
  2. <view class="Locations">
  3. <map style="width: 100%;height: 60vh"
  4. :layer-style='5'
  5. :show-location='true'
  6. :latitude="position.latitude"
  7. :longitude="position.longitude"
  8. :markers="spotGuideMarkers"
  9. :scale="scale"
  10. @markertap="markertap"
  11. id="mapId"
  12. @callouttap="callouttap"
  13. :enable-zoom="true"
  14. :enable-scroll="true"
  15. :enable-rotate="true">
  16. </map>
  17. <!-- 测试按钮 -->
  18. <view class="test-button" @click="testLoadHouseList">
  19. <text>测试加载房源</text>
  20. </view>
  21. <!-- 搜索功能 -->
  22. <view class="search-container">
  23. <view class="se-bgc-white se-pb-20 se-pt-30 se-px-40">
  24. <uv-search @search="onSearch()" placeholder="搜索租房信息" :showAction="false" v-model="keyword"></uv-search>
  25. </view>
  26. <view class="se-pb-10 se-px-40 se-bgc-white">
  27. <uv-drop-down ref="dropDown" sign="dropDown_1" text-active-color="#1EC77A"
  28. :extra-icon="{name:'arrow-down-fill',color:'#666',size:'26rpx'}"
  29. :extra-active-icon="{name:'arrow-up-fill',color:'#1EC77A',size:'26rpx'}" :defaultValue="defaultValue"
  30. :custom-style="{padding: '0rpx 0rpx',borderBottom:'1rpx solid transparent'}" @click="selectMenu">
  31. <uv-drop-down-item name="region" type="2" :label="dropItem('region').label" :value="dropItem('region').value">
  32. </uv-drop-down-item>
  33. <uv-drop-down-item name="rent" type="2" :label="dropItem('rent').label" :value="dropItem('rent').value">
  34. </uv-drop-down-item>
  35. <uv-drop-down-item name="type" type="2" :label="dropItem('type').label" :value="dropItem('type').value">
  36. </uv-drop-down-item>
  37. <uv-drop-down-item name="duration" type="2" :label="dropItem('duration').label" :value="dropItem('duration').value">
  38. </uv-drop-down-item>
  39. </uv-drop-down>
  40. <uv-drop-down-popup sign="dropDown_1" :click-overlay-on-close="true" :currentDropItem="currentDropItem"
  41. @clickItem="clickItem" @popupChange="change"></uv-drop-down-popup>
  42. </view>
  43. </view>
  44. <uv-tabs :list="houseTypeList" :activeStyle="{ color: '#1EC77A', fontWeight: 600 }" lineColor="#1EC77A"
  45. lineHeight="8rpx" lineWidth="50rpx" keyName="title" :current="currentHouseType"
  46. @click="onClickHouseType"></uv-tabs>
  47. <view class="Locations-list">
  48. <!-- 房源列表 -->
  49. <view v-if="list.length > 0">
  50. <view @click="onDetail(item)" class="se-my-10 se-mx-20 se-px-20 se-py-20 se-br-20 se-bgc-white se-flex"
  51. v-for="(item, index) in list" :key="index">
  52. <view class="se-pos se-w-260 se-h-180">
  53. <image v-if="item.iconImage" class="se-a-80 se-pos-lt" :src="item.iconImage" mode=""></image>
  54. <image class="se-w-260 se-h-180 se-br-10" :src="item.images[0]" mode=""></image>
  55. </view>
  56. <view class="se-pl-10 se-w-p-100">
  57. <view class="se-c-black se-fs-28">
  58. {{ item.title }}
  59. </view>
  60. <view class="se-flex se-flex-h-sb se-flex-ai-c se-fs-24 se-mt-10 se-c-66">
  61. <text>{{ item.homeType }}</text>
  62. <text>{{ item.timeGo }}</text>
  63. </view>
  64. <view class="se-flex se-flex-h-sb se-flex-ai-c se-mt-10">
  65. <template v-if="item.iconTitles.length > 0">
  66. <view class="se-flex">
  67. <view
  68. class="se-display-ib se-c-white se-bgc-orange se-fs-22 se-br-8 se-px-10 se-py-5 se-mr-10"
  69. v-for="(items, indexs) in item.iconTitles" :key="indexs">
  70. {{ items }}
  71. </view>
  72. </view>
  73. </template>
  74. <template v-else>
  75. <view></view>
  76. </template>
  77. <view class="se-c-66 se-flex se-flex-ai-c">
  78. <uv-icon name="eye"></uv-icon>
  79. <text class="se-ml-5 se-fs-18">{{ item.num }}</text>
  80. </view>
  81. </view>
  82. <view class="se-flex se-flex-h-sb se-flex-ai-c se-mt-10">
  83. <text class="se-c-red se-fs-24 se-fw-6 se-toe-1">{{ item.price }}/{{ item.unit }}</text>
  84. <text class="se-c-66 se-fs-22 se-toe-1">{{ item.address }}</text>
  85. </view>
  86. </view>
  87. </view>
  88. </view>
  89. <uv-empty v-else text="没有哦" textSize="30rpx" iconSize="200rpx" icon="list"></uv-empty>
  90. </view>
  91. </view>
  92. </template>
  93. <script>
  94. import { housePageList, houseType, houseArea, houseIconClass, housePrice, houseYear } from "@/common/api.js"
  95. import { getInfo } from "@/common/api.js"
  96. export default {
  97. data() {
  98. return {
  99. scale: 12, //缩放级别
  100. show: true,
  101. tabs: [],
  102. spotGuideIndex: 0, // 当前选中的菜单索引
  103. position: {
  104. latitude: 23.106574,
  105. longitude: 113.324587
  106. },
  107. areaId: null, // 当前选中的区域ID
  108. // 房源列表相关数据
  109. list: [],
  110. classId: null,
  111. pageNo: 1,
  112. pageSize: 10,
  113. houseTypeList: [], // 房源类型列表
  114. currentHouseType: 0, // 当前选中的房源类型索引
  115. userInfo: null, // 用户信息
  116. // 搜索功能相关数据
  117. keyword: "",
  118. // 表示value等于这些值,就属于默认值
  119. defaultValue: ['all', 'all', 'all','all'],
  120. // 筛选结果
  121. result: [],
  122. region:{
  123. label: '区域',
  124. value: 'all',
  125. activeIndex: 0,
  126. color: '#333',
  127. activeColor: '#1EC77A',
  128. child: []
  129. },
  130. rent:{
  131. label: '租金',
  132. value: 'all',
  133. activeIndex: 0,
  134. color: '#333',
  135. activeColor: '#1EC77A',
  136. child: []
  137. },
  138. type: {
  139. label: '类型',
  140. value: 'all',
  141. activeIndex: 0,
  142. color: '#333',
  143. activeColor: '#1EC77A',
  144. child: []
  145. },
  146. duration:{
  147. label: '年限',
  148. value: 'all',
  149. activeIndex: 0,
  150. color: '#333',
  151. activeColor: '#1EC77A',
  152. child: []
  153. },
  154. activeName: 'region',
  155. // 筛选条件
  156. priceId: null,
  157. typeId: null,
  158. yearId: null
  159. }
  160. },
  161. computed: {
  162. spotGuideMarkers() {
  163. let markers = [];
  164. console.log('计算地图标记点,房源列表长度:', this.list.length)
  165. this.list.forEach((item, index) => {
  166. if (item.latitude && item.longitude) {
  167. console.log(`添加标记点 ${index}:`, item.title, item.latitude, item.longitude)
  168. markers.push({
  169. id: index,
  170. latitude: parseFloat(item.latitude),
  171. longitude: parseFloat(item.longitude),
  172. iconPath: '/static/image/tourGuide/2.png',
  173. width: 30,
  174. height: 30,
  175. callout: {
  176. content: item.title || '房源',
  177. color: '#000000',
  178. fontSize: 14,
  179. borderRadius: 5,
  180. bgColor: '#ffffff',
  181. padding: 5,
  182. display: 'BYCLICK'
  183. }
  184. });
  185. }
  186. });
  187. console.log('生成的标记点数量:', markers.length)
  188. return markers;
  189. },
  190. // 搜索功能计算属性
  191. dropItem() {
  192. return (name) => {
  193. const result = {};
  194. const find = this.result.find(item => item.name === name);
  195. if (find) {
  196. result.label = find.label;
  197. result.value = find.value;
  198. } else {
  199. result.label = this[name].label;
  200. result.value = this[name].value;
  201. }
  202. return result;
  203. }
  204. },
  205. // 获取当前下拉筛选项
  206. currentDropItem() {
  207. return this[this.activeName];
  208. }
  209. },
  210. onLoad() {
  211. console.log('页面加载完成')
  212. // 确保在页面加载完成后初始化数据
  213. this.$nextTick(() => {
  214. if (this.list.length === 0) {
  215. this.onHousePageList()
  216. }
  217. })
  218. },
  219. onPageScroll() {
  220. // 滚动后及时更新下拉菜单位置
  221. if (this.$refs.dropDown) {
  222. this.$refs.dropDown.init();
  223. }
  224. },
  225. mounted() {
  226. this.getCurrentLocation()
  227. this.onHouseType() // 获取房源类型
  228. //this.getUserInfo() // 获取用户信息
  229. // 初始化搜索筛选数据
  230. this.initSearchData()
  231. // 延迟加载房源列表,确保用户信息已获取
  232. this.$nextTick(() => {
  233. this.onHousePageList() // 加载房源列表
  234. })
  235. },
  236. onPullDownRefresh() {
  237. let that = this
  238. that.pageNo = 1
  239. that.list = []
  240. that.onHousePageList()
  241. },
  242. onReachBottom() {
  243. let that = this
  244. that.pageNo = that.pageNo + 1
  245. that.onHousePageList()
  246. },
  247. methods: {
  248. getUserInfo(state){
  249. this.$store.commit('getUserInfo', (userInfo) => {
  250. this.userInfo = userInfo
  251. if(userInfo && userInfo.isPay != 1){
  252. uni.showModal({
  253. title: '开通会员可查看租房地图',
  254. content: '开通会员后可查看详细地址和联系方式',
  255. confirmText: '立即开通',
  256. cancelText: '取消',
  257. success : res => {
  258. if(res.confirm){
  259. // 跳转到会员页面
  260. uni.navigateTo({
  261. url: '/pages_subpack/member/index'
  262. })
  263. }
  264. }
  265. })
  266. }
  267. })
  268. },
  269. // 获取当前位置
  270. getCurrentLocation() {
  271. const that = this;
  272. uni.getLocation({
  273. type: 'wgs84',
  274. success: function (res) {
  275. console.log('当前位置的经度:' + res.longitude);
  276. console.log('当前位置的纬度:' + res.latitude);
  277. that.position.latitude = res.latitude;
  278. that.position.longitude = res.longitude;
  279. // 更新地图位置
  280. that.onHousePageList();
  281. },
  282. fail: function (err) {
  283. console.error('获取位置失败:', err);
  284. uni.showToast({
  285. title: '获取位置失败',
  286. icon: 'none'
  287. });
  288. }
  289. });
  290. },
  291. //点击tab栏
  292. clickTabs({ index, name }) {
  293. this.currentArea = index
  294. if (this.areaList[index]) {
  295. this.areaId = this.areaList[index].id
  296. }
  297. this.onHousePageList()
  298. this.$nextTick(() => {
  299. this.selectArea()
  300. })
  301. },
  302. setSpotGuideIndex(index) {
  303. this.spotGuideIndex = index
  304. this.onHousePageList()
  305. },
  306. textToSpeech() {
  307. console.log('textToSpeech');
  308. let self = this
  309. // self.context.src = this.$config.baseUrl + '/info/textToAudio?text=' + "你好"
  310. // self.context.play()
  311. // return
  312. plugin.textToSpeech({
  313. lang: "zh_CN",
  314. tts: true,
  315. content: "景德镇市陶阳里御窑景区位于景德镇的城市中心地带,北起瓷都大桥、昌江大道,南至昌江大桥、西至沿江西路,东至莲社路、胜利路。 自宋以来,景德镇先民“沿河建窑,因窑成市”,渐呈“码头—民窑—老街—里弄—御窑”聚落的历史空间和瓷业肌理,形成了世界建筑史上绝无仅有的老城格局,成就了中国“东方瓷国”的盛誉,陶瓷成为了中国走向世界,世界认识中国的文化符号。这里是景德镇历史上制瓷业的中心、原点和高峰,是“一带一路”海上陶瓷之路的零公里起点,是研究皇家御窑制瓷历史文化和景德镇陶瓷技艺,讲好景德镇故事,传播中国声音的“窗口”和“名片”。",
  316. success: function (res) {
  317. self.context.src = res.filename;
  318. self.context.play()
  319. },
  320. fail: function (res) {
  321. console.log("fail tts", res)
  322. }
  323. })
  324. },
  325. //地图点击事件
  326. markertap(e) {
  327. console.log("markertap===你点击了标记点===", e)
  328. let event = this.list[e.markerId]
  329. if (event) {
  330. this.onDetail(event)
  331. } else {
  332. console.error('未找到对应的房源数据')
  333. uni.showToast({
  334. title: '房源信息获取失败',
  335. icon: 'none'
  336. })
  337. }
  338. },
  339. openLocation(n) {
  340. uni.openLocation({
  341. latitude: n.spotLatitude,
  342. longitude: n.spotLongitude,
  343. })
  344. },
  345. //地图点击事件
  346. callouttap(e) {
  347. console.log('callouttap地图点击事件', e)
  348. let event = this.list[e.markerId]
  349. if (event && event.latitude && event.longitude) {
  350. uni.openLocation({
  351. latitude: event.latitude,
  352. longitude: event.longitude,
  353. })
  354. } else {
  355. console.error('未找到对应的房源位置信息')
  356. uni.showToast({
  357. title: '房源位置信息获取失败',
  358. icon: 'none'
  359. })
  360. }
  361. },
  362. toUrl(item) {
  363. console.log(item);
  364. if (item.categoryId == 0) {
  365. this.$utils.navigateTo(`/pages_order/service/articleDetail?id=${item.id}&type=Inheritance`)
  366. }
  367. },
  368. // 点击按钮将地图中心移动到指定定位点
  369. moveTolocation(latitude, longitude) {
  370. let mapObjs = uni.createMapContext('mapId', this)
  371. mapObjs.moveToLocation(
  372. {
  373. latitude,
  374. longitude
  375. },
  376. {
  377. complete: res => {
  378. console.log('移动完成:', res)
  379. }
  380. })
  381. // this.onRegionChange('',true)
  382. },
  383. // 点击景区,选择最近的一个景点
  384. selectArea() {
  385. let item = this.spotGuide[0]
  386. if (item && item.spotLatitude && item.spotLongitude) {
  387. this.moveTolocation(item.spotLatitude, item.spotLongitude)
  388. }
  389. },
  390. clickAreaDetail(id) {
  391. uni.navigateTo({
  392. url: '/pages_order/service/areaDetail?id=' + id
  393. })
  394. },
  395. // 获取房源类型列表
  396. onHouseType() {
  397. houseType({}).then(response => {
  398. console.info('houseType', response)
  399. this.houseTypeList = response.result
  400. }).catch(error => {
  401. })
  402. },
  403. // 点击房源类型
  404. onClickHouseType(event) {
  405. console.info(event)
  406. let that = this
  407. that.pageNo = 1
  408. that.classId = event.id
  409. that.currentHouseType = event.index
  410. that.list = []
  411. that.onHousePageList()
  412. },
  413. // 获取房源列表
  414. onHousePageList() {
  415. let that = this
  416. let params = {
  417. classId: that.classId,
  418. pageNo: that.pageNo,
  419. pageSize: that.pageSize,
  420. // 搜索和筛选参数
  421. title: that.keyword, // 关键词搜索
  422. areaId: that.areaId, // 区域筛选
  423. priceId: that.priceId, // 租金筛选
  424. typeId: that.typeId, // 类型筛选
  425. yearId: that.yearId // 年限筛选
  426. }
  427. // 如果有位置信息,添加到参数中
  428. if (that.position.latitude && that.position.longitude) {
  429. params.latitude = that.position.latitude
  430. params.longitude = that.position.longitude
  431. }
  432. console.log('请求房源列表参数:', params)
  433. housePageList(params).then((response) => {
  434. console.info("房源列表数据", response.result.records)
  435. if (response.result && response.result.records) {
  436. response.result.records.forEach((items, indexs) => {
  437. if (items.image) {
  438. items.images = items.image.split(',')
  439. } else {
  440. items.images = []
  441. }
  442. if (items.homeImage) {
  443. items.homeImages = items.homeImage.split(',')
  444. } else {
  445. items.homeImages = []
  446. }
  447. if (items.iconTitle) {
  448. items.iconTitles = items.iconTitle.split(',')
  449. } else {
  450. items.iconTitles = []
  451. }
  452. })
  453. that.list = that.list.concat(response.result.records)
  454. // 调试信息:检查有多少房源有位置信息
  455. let markersCount = that.list.filter(item => item.latitude && item.longitude).length
  456. console.log(`房源总数: ${that.list.length}, 有位置信息的房源: ${markersCount}`)
  457. // 如果有房源数据,更新地图中心点
  458. if (that.list.length > 0) {
  459. let firstHouse = that.list.find(item => item.latitude && item.longitude)
  460. if (firstHouse) {
  461. that.position.latitude = firstHouse.latitude
  462. that.position.longitude = firstHouse.longitude
  463. }
  464. // 强制更新地图组件
  465. that.$nextTick(() => {
  466. let mapContext = uni.createMapContext('mapId', that)
  467. if (mapContext) {
  468. mapContext.updateGroundOverlay({
  469. id: 'markers',
  470. 'include-points': that.spotGuideMarkers
  471. })
  472. }
  473. })
  474. }
  475. }
  476. }).catch((error) => {
  477. console.error('获取房源列表失败:', error)
  478. uni.showToast({
  479. title: '获取房源列表失败',
  480. icon: 'none'
  481. })
  482. })
  483. },
  484. // 点击房源详情
  485. onDetail(event) {
  486. uni.navigateTo({
  487. url: "/pages_subpack/detail/index?id=" + event.id
  488. })
  489. },
  490. // 搜索功能相关方法
  491. // 初始化搜索筛选数据
  492. initSearchData() {
  493. this.onhouseArea()
  494. this.onhouseIconClass()
  495. this.onhousePrice()
  496. this.onhouseYear()
  497. },
  498. // 处理搜索
  499. onSearch() {
  500. console.info('搜索关键词:', this.keyword)
  501. this.pageNo = 1
  502. this.list = []
  503. this.onHousePageList()
  504. },
  505. // 选择筛选菜单
  506. selectMenu(name) {
  507. this.activeName = name;
  508. },
  509. // 点击筛选项
  510. clickItem(item) {
  511. console.log('选择筛选项:', item);
  512. // 更新对应的筛选值
  513. this[this.activeName].label = item.label;
  514. this[this.activeName].value = item.value;
  515. // 处理筛选逻辑
  516. this.handleFilter(item);
  517. },
  518. // 处理筛选
  519. handleFilter(item) {
  520. console.info('筛选条件变化:', item)
  521. this.pageNo = 1
  522. // 根据筛选类型设置对应的参数
  523. if (this.activeName === 'region') {
  524. this.areaId = item.value === 'all' ? null : item.value
  525. } else if (this.activeName === 'rent') {
  526. this.priceId = item.value === 'all' ? null : item.value
  527. } else if (this.activeName === 'type') {
  528. this.typeId = item.value === 'all' ? null : item.value
  529. } else if (this.activeName === 'duration') {
  530. this.yearId = item.value === 'all' ? null : item.value
  531. }
  532. this.list = []
  533. this.onHousePageList()
  534. },
  535. // 弹窗状态变化
  536. change(e) {
  537. console.log('弹窗打开状态:', e);
  538. },
  539. // 获取区域数据
  540. onhouseArea() {
  541. let that = this
  542. houseArea({}).then(response => {
  543. let arr = [
  544. {
  545. label: '全部区域',
  546. value: 'all'
  547. }
  548. ]
  549. response.result.forEach(items => {
  550. let obj = {}
  551. obj.label = items.title;
  552. obj.value = items.id
  553. arr.push(obj)
  554. })
  555. that.region.child = arr
  556. console.info('区域数据', response.result)
  557. }).catch(error => {
  558. })
  559. },
  560. // 获取类型数据
  561. onhouseIconClass() {
  562. let that = this
  563. houseIconClass({}).then(response => {
  564. console.info('类型数据', response.result)
  565. let arr = [
  566. {
  567. label: '全部类型',
  568. value: 'all'
  569. }
  570. ]
  571. response.result.forEach(items => {
  572. let obj = {}
  573. obj.label = items.title;
  574. obj.value = items.id
  575. arr.push(obj)
  576. })
  577. that.type.child = arr
  578. }).catch(error => {
  579. })
  580. },
  581. // 获取价格数据
  582. onhousePrice() {
  583. let that = this
  584. housePrice({}).then(response => {
  585. let arr = [
  586. {
  587. label: '全部价格',
  588. value: 'all'
  589. }
  590. ]
  591. response.result.forEach(items => {
  592. let obj = {}
  593. obj.label = items.title;
  594. obj.value = items.price
  595. arr.push(obj)
  596. })
  597. that.rent.child = arr
  598. }).catch(error => {
  599. })
  600. },
  601. // 获取年限数据
  602. onhouseYear() {
  603. let that = this
  604. houseYear({}).then(response => {
  605. console.info('年限数据', response.result)
  606. let arr = [
  607. {
  608. label: '全部年限',
  609. value: 'all'
  610. }
  611. ]
  612. response.result.forEach(items => {
  613. let obj = {}
  614. obj.label = items.title;
  615. obj.value = items.timeGo
  616. arr.push(obj)
  617. })
  618. that.duration.child = arr
  619. }).catch(error => {
  620. })
  621. },
  622. // 测试加载房源列表
  623. testLoadHouseList() {
  624. console.log('手动触发房源列表加载');
  625. this.pageNo = 1;
  626. this.list = [];
  627. this.onHousePageList();
  628. }
  629. }
  630. }
  631. </script>
  632. <style scoped lang="scss">
  633. .test-button {
  634. position: fixed;
  635. top: 20rpx;
  636. right: 20rpx;
  637. background-color: #1EC77A;
  638. color: white;
  639. padding: 20rpx;
  640. border-radius: 10rpx;
  641. z-index: 999;
  642. font-size: 24rpx;
  643. }
  644. .Locations {
  645. .search-container {
  646. background-color: #fff;
  647. border-bottom: 1rpx solid #f0f0f0;
  648. }
  649. .tabs {
  650. display: flex;
  651. &>view {
  652. flex: 1;
  653. margin: 20rpx 10rpx;
  654. padding: 20rpx 10rpx;
  655. background-color: #e8f7f0;
  656. color: #1EC77A;
  657. border-radius: 40rpx;
  658. font-size: 24rpx;
  659. text-align: center;
  660. }
  661. .act {
  662. background-color: #1EC77A;
  663. color: #fff;
  664. }
  665. }
  666. .Locations-list {
  667. .main {
  668. display: flex;
  669. margin: 20rpx;
  670. .main-image {
  671. width: 150rpx;
  672. height: 150rpx;
  673. border-radius: 20rpx;
  674. }
  675. .info {
  676. margin-left: 20rpx;
  677. .title {
  678. font-size: 30rpx;
  679. font-weight: 900;
  680. }
  681. .tips {
  682. font-size: 24rpx;
  683. color: #999999;
  684. margin-top: 10rpx;
  685. }
  686. }
  687. .controls {
  688. margin-left: auto;
  689. display: flex;
  690. flex-direction: column;
  691. justify-content: center;
  692. align-items: center;
  693. .f {
  694. image {
  695. width: 50rpx;
  696. height: 50rpx;
  697. }
  698. }
  699. }
  700. .btn {
  701. padding: 10rpx;
  702. font-size: 22rpx;
  703. color: #1EC77A;
  704. border: 1rpx solid #1EC77A;
  705. background-color: #e8f7f0;
  706. display: flex;
  707. justify-content: center;
  708. align-items: center;
  709. margin-top: 10rpx;
  710. border-radius: 15rpx;
  711. image {
  712. width: 25rpx;
  713. height: 25rpx;
  714. }
  715. text {
  716. margin: 0 10rpx;
  717. }
  718. }
  719. }
  720. .list {
  721. padding-left: 40rpx;
  722. .main {
  723. align-items: center;
  724. .main-image {
  725. width: 140rpx;
  726. height: 140rpx;
  727. }
  728. .controls {
  729. flex-direction: row;
  730. .f {
  731. margin: 30rpx;
  732. image {
  733. width: 40rpx;
  734. height: 40rpx;
  735. }
  736. }
  737. }
  738. }
  739. }
  740. }
  741. }
  742. </style>