|
|
- <template>
- <view class="home">
-
- <view class="home-top">
- <view class="search">
-
- <view @click="showSelectArea" class="left-area">
- <image src="@/static/home/address-icon.png"></image>
- <view class="area">{{ area }}</view>
- <image src="../../static/home/arrow-icon.png" mode="aspectFit"></image>
- <view class="parting-line">|</view>
- </view>
-
- <view class="center-area">
- <image src="@/static/home/search-icon.png"></image>
- <van-field @click="searchAddress" v-model="queryParams.title" center placeholder="请选择地区" />
- </view>
-
- <view class="right-area">
- <view @click="searchAddress" class="search-button">
- 搜索
- </view>
- </view>
-
- </view>
- </view>
-
- <view class="home-content">
-
- <view class="banner b-relative">
- <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
- <van-swipe-item v-for="item in bannerList" :key="item.id">
- <image class="banner-image" :src="item.image" mode="widthFix"></image>
- </van-swipe-item>
- </van-swipe>
- </view>
-
- <view v-if="projectList.length > 0" class="server-list">
- <van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" ref="list"
- @load="onLoad">
- <view v-for="item in projectList" class="server-item" @click="toServiceDetail(item.id)">
-
- <view class="img-box">
- <image :src="item.image" mode="aspectFill"></image>
- </view>
-
- <view class="server-info">
- <view class="server-title">{{ item.title }}</view>
- <view class="time-coupon">
- <image src="@/static/home/time-icon.png"></image>
- <view class="time">{{ item.times }}分钟</view>
- <!-- <view class="coupon">{{ item.subTitle }}</view> -->
- </view>
- <view class="price">
- <view class="current-price">
- <text class="unit">¥</text>{{ item.price }}
- </view>
- <view class="original-price">
- <text class="unit">¥</text>{{ item.oldPrice }}
- </view>
- </view>
- <view class="sales-volume">
- <image src="@/static/icons/icon1.png"></image>
- <view class="desc">已售出{{ item.payNum }}+单</view>
- </view>
- </view>
-
- <view class="selective-technician">
- <view @click.stop="selectTechnician(item.id)" class="btn">
- 选择技师
- </view>
- </view>
-
- </view>
- </van-list>
- </view>
-
- <van-empty v-else image="/static/empty/data.png" image-size="400rpx" description="暂无项目" />
-
- </view>
-
- <selectArea :show="showAeraPro" @close="closeAreaPro" @select="selectArea"></selectArea>
-
- </view>
- </template>
-
- <script>
- import selectArea from '../../components/selectArea.vue';
- import Position from '@/utils/position.js'
-
- export default {
- components: {
- selectArea
- },
- data() {
- return {
- bannerList: [],
- projectList: [],
- queryParams: {
- pageNo: 1,
- pageSize: 10,
- title: ''
- },
- loading: false,
- finished: false,
- technicianList: [],
- showAeraPro: false,
- area: ''
- }
- },
- onShow() {
- this.getBanner()
- this.getProject()
- this.getLocation()
- },
- methods: {
- //list列表滑动到底部自动新增数据列表
- onLoad() {
- this.queryParams.pageSize += 10;
- this.getProject()
- },
-
- //获取banner
- getBanner() {
- this.$api('getBanner', {}, res => {
- this.bannerList = res.result;
- })
- },
-
- //获取项目列表
- getProject() {
- this.$api('getProjectList', this.queryParams, res => {
- if (res.code == 200) {
- this.projectList = res.result.records;
- } else {
- this.finished = true
- }
- if (this.queryParams.pageSize > res.result.total) {
- this.finished = true
- }
- this.loading = false
- })
- },
-
- //获取技师详情
- selectTechnician(id) {
- this.$api('getProjectDetail', {
- id
- }, res => {
- if (res.code == 200) {
- uni.navigateTo({
- url: `/pages/technician/selectTechnician?serviceId=${id}`
- })
- sessionStorage.setItem('technicianList', JSON.stringify(res.result.tenPageList))
- }
- })
- },
-
- //跳转技师详情
- toServiceDetail(id) {
- uni.navigateTo({
- url: '/pages/technician/subscribeService?id=' + id
- })
- },
-
- //显示选择地区
- showSelectArea() {
- this.showAeraPro = true;
- },
-
- //关闭选择地区
- closeAreaPro() {
- this.showAeraPro = false;
- },
-
- //选择了地区信息
- selectArea(area) {
- this.area = area;
- this.showAeraPro = false;
-
- //后端逻辑
- this.updateSessionPositon(area)
- },
-
- //搜索地址
- searchAddress() {
- Position.getLocation(res => {
- Position.selectAddress(res.longitude, res.latitude, success => {
- let address = this.extractProvinceAndCity(success)
- this.queryParams.title = address.city
- })
- })
- },
-
- //提取用户选择的地址信息(省市县信息)
- extractProvinceAndCity(res) { //提取用户选择的地址信息(省市)
- if (!res.address && res.name) { //用户直接选择城市的逻辑
- return {
- province: '',
- city: res.name
- };
- }
-
- if (res.address) { //用户选择了详细地址,要从详细地址中提取出省市县信息
- // 使用正则表达式匹配省市县
- const regex = /(?<province>[\u4e00-\u9fa5]+?省)(?<city>[\u4e00-\u9fa5]+?(?:市|自治州|盟|地区))/;
- const match = res.address.match(regex);
- if (match) { // 如果匹配成功,则返回省和市的信息
- return {
- province: match.groups.province,
- city: match.groups.city
- };
- }
- }
-
- return { //用户没选择地址就点了确定按钮
- province: '',
- city: ''
- }
- },
-
- //获取用户详细地址(省市县)
- getLocation() {
- Position.getLocationDetail().then(res => {
- sessionStorage.setItem("position", JSON.stringify(res))
- this.area = res.addressDetail.district
- })
- },
-
- //初始化用户所在地区
- initUserArea() {
- if (!sessionStorage.getItem('position')) return this.getLocation()
- let positionInfo = JSON.parse(sessionStorage.getItem('position'))
- this.area = positionInfo.addressDetail.district
- },
-
- //更新用户所在区域(更新区县信息)
- updateSessionPositon(area) {
- if (sessionStorage.getItem('position')) {
- let position = JSON.parse(sessionStorage.getItem('position'))
- position.addressDetail.district = area
- sessionStorage.setItem('position', JSON.stringify(position))
- }
- }
- }
- }
- </script>
-
- <style lang="scss" scoped>
- .home {
- width: 750rpx;
- background: #F5F5F5;
- margin: 0 auto;
-
- .home-top {
- height: 350rpx;
- background: linear-gradient(38deg, #4899A6, #60BDA2);
- padding-top: 60rpx;
-
- .search {
- height: 82rpx;
- width: 710rpx;
- background: #FFFFFF;
- margin: 0px auto;
- border-radius: 41rpx;
- box-sizing: border-box;
- padding: 0 15rpx;
-
- display: flex;
- align-items: center;
- justify-content: space-between;
-
- .left-area,
- .center-area {
- display: flex;
- align-items: center;
- }
-
- .left-area {
- max-width: 160rpx;
-
- image {
- flex-shrink: 0;
- width: 26rpx;
- height: 26rpx;
- }
-
- .area {
- font-size: 24rpx;
- display: -webkit-box;
- -webkit-line-clamp: 2;
- /* 限制显示两行 */
- -webkit-box-orient: vertical;
- overflow: hidden;
- text-overflow: ellipsis;
- color: #292929;
- }
-
- .parting-line {
- flex-shrink: 0;
- font-size: 26rpx;
- color: #ccc;
- margin: 0rpx 5rpx;
- }
- }
-
- .center-area {
- display: flex;
- flex-wrap: nowrap;
- align-items: center;
- width: calc(100% - 290rpx);
-
- image {
- width: 26rpx;
- height: 26rpx;
- }
-
- .van-field {
- background-color: transparent;
- box-sizing: border-box;
- height: 82rpx;
- line-height: 82rpx;
- width: calc(100% - 30rpx);
- padding: 0rpx 10rpx 0rpx 0rpx;
-
- input {
- height: 82rpx;
- font-size: 60rpx;
- }
- }
- }
-
- .right-area {
- .search-button {
- background: #60BDA2;
- height: 60rpx;
- width: 130rpx;
- font-size: 26rpx;
- border-radius: 35rpx;
- color: white;
-
- display: flex;
- align-items: center;
- justify-content: center;
- }
- }
-
- }
- }
-
- .home-content {
- width: calc(100% - 40rpx);
- margin: -240rpx 20rpx 0rpx 20rpx;
-
- .banner {
- box-sizing: border-box;
-
- .my-swipe {
- width: 100%;
- margin: 0px auto;
- border-radius: 20rpx;
- height: 334rpx;
- overflow: hidden;
-
- .van-swipe-item {
- width: 100%;
-
- .banner-image {
- width: 100%;
-
- image {
- width: 100%;
- }
- }
- }
- }
- }
-
- .server-list {
- padding-bottom: 80rpx;
-
- .server-item {
- display: flex;
- flex-wrap: wrap;
- justify-content: space-between;
- background: white;
- border-radius: 15rpx;
- box-sizing: border-box;
- padding: 15rpx;
- margin: 20rpx 0rpx;
-
- .img-box {
- width: 150rpx;
- height: 150rpx;
- border-radius: 10rpx;
- overflow: hidden;
-
- image {
- width: 100%;
- height: 100%;
- }
- }
-
- .server-info {
- display: flex;
- flex-direction: column;
- justify-content: space-around;
- width: calc(100% - 330rpx);
- box-sizing: border-box;
- padding: 0 10rpx;
-
- .server-title {}
-
- .time-coupon,
- .price {
- display: flex;
- flex-wrap: wrap;
- align-items: center;
- }
-
- .time-coupon {
- font-size: 26rpx;
-
- image {
- width: 22rpx;
- height: 22rpx;
- }
-
- .time {
- color: #B8B8B8;
- margin-left: 6rpx;
- }
-
- .coupon {
- display: flex;
- justify-content: center;
- align-items: center;
- background: #F29E45;
- color: white;
- width: 140rpx;
- height: 45rpx;
- border-radius: 10rpx;
- margin-left: 10rpx;
- }
- }
-
- .price {
- display: flex;
- align-items: center;
- color: #B8B8B8;
-
- .current-price {
- font-size: 30rpx;
- font-weight: 600;
- color: #D34430;
- margin-right: 5rpx;
- }
-
- .unit {
- font-size: 20rpx;
- }
- }
-
- .sales-volume {
- display: flex;
- align-items: center;
- color: #B8B8B8;
- font-size: 26rpx;
-
- image {
- width: 23rpx;
- height: 23rpx;
- }
-
- }
-
- }
-
- .selective-technician {
- display: flex;
- flex-wrap: wrap;
- align-items: center;
- width: 170rpx;
-
- .btn {
- display: flex;
- align-items: center;
- justify-content: center;
- height: 60rpx;
- width: 170rpx;
- border-radius: 40rpx;
- color: white;
- background: linear-gradient(170deg, #53CEAC, #5AC796);
- }
- }
- }
- }
- }
- }
- </style>
|