mrr.sj.front/pages/shop/userorder-detail.vue

1714 lines
41 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="detail-page" :class="{ 'no-bottom-buttons': !haveButton }">
<!-- 顶部导航栏 -->
<custom-navbar title="订单详情" :show-back="true" title-color="#333333" :backgroundColor="backgroundColor"
borderBottom="none"></custom-navbar>
<view class="content-part">
<!-- 订单状态 -->
<view class="status-section">
<image class="status-section-image" mode="widthFix" :src="stateItem.icon" />
<text class="status-text">{{ stateItem.text }}
<text v-if="orderInfo.team_buy_order_state">{{
` (${getGroupType(orderInfo.team_buy_order_state)})`
}}</text></text>
</view>
<!-- 到店订单客户信息 -->
<view class="kh-card" v-if=" serviceType == '2' && orderInfo.order_kind==2">
<view class="kh-card-footer flex-row-center-between">
<view class="kh-card-footer-left flex-row-center">
<image class="kh-card-footer-left-img" :src="orderInfo.order_headphoto"></image>
<view class="kh-card-footer-left-text">
{{ `${orderInfo.order_username} ${orderInfo.phone_user}` }}
</view>
</view>
<image class="kh-card-footer-right" @click="contactService(orderInfo.phone_user)"
src="/static/images/icons/phone.png"></image>
</view>
</view>
<!-- 上门订单 客户以及手艺人信息 -->
<view class="service-card" v-if="reservation_address_arr && reservation_address_arr.name">
<view class="card_title">顾客信息</view>
<view class="location-info">
<view class="name-phone">
<view>
<text class="name">{{ reservation_address_arr.name }}</text>
<text class="phone">{{
reservation_address_arr.call_phone
}}</text>
</view>
<view class="info_Btn" @click="contactService(reservation_address_arr.call_phone)">
<image class="btn-phone"
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/fffa5408-df61-40c1-8dea-78325f75f3ab.png"
mode="aspectFit"></image>
<text>联系客户</text>
</view>
</view>
<view class="address-info">
<image @click="openMap()"
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/8a503a74-a809-4dc4-b3e0-3a257530ff10.png"
class="location-icon"></image>
<text class="address">上门地址:{{ reservation_address_arr.server_address
}}{{ reservation_address_arr.house_number }}</text>
</view>
</view>
</view>
<!-- 店铺信息 -->
<!-- <view class="shop_card"
v-if=" serviceType !== '2' && orderInfo.order_kind !== 3 && user_sj && user_sj.name">
<view class="shop_info_box">
<view class="shop_info_row">
<view class="shop_info_left">
<image class="shop_photo" :src="user_sj.head_photo" mode="aspectFill"></image>
<view class="shop_info_right">
<text class="shop_name">{{ user_sj.name }}</text>
</view>
</view>
<view class="shop_info_actions">
<view class="shop_action_item" @click="openShopMap">
<image class="action_icon_map"
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/306b7f20-8b5a-4585-baf5-962bf4c07d8c.png"
mode="aspectFit"></image>
<view class="action_text">地址</view>
</view>
<view class="shop_action_item" @click="contactService(user_sj.phone || user_sj.account)">
<image class="action_icon_phone"
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/5e6bb10e-9f14-4349-8021-7e79078a8da7.png"
mode="aspectFit"></image>
<view class="action_text">电话</view>
</view>
</view>
</view>
<view class="shop_details">
<text class="shop_phone"
v-if="user_sj.phone || user_sj.account">商家电话:{{ user_sj.phone || user_sj.account }}</text>
<text class="shop_address" v-if="user_sj.address">地址:{{ user_sj.address }}</text>
</view>
</view>
</view> -->
<!-- 用户信息 -->
<!-- <view class="shop_card" v-if="orderInfo.order_kind==2">
<view class="userinfo">
<view class="" v-if="orderInfo.user_yh.head_photo">
<image :src="orderInfo.user_yh.head_photo" mode="widthFix"
style="width: 70rpx;border-radius: 50%;"></image>
</view>
<view class="" style="margin-left: 20rpx;margin-top: 15rpx;">{{orderInfo.user_yh.username}}</view>
<view class="" style="margin-left: 12rpx;margin-top: 15rpx;">{{orderInfo.user_yh.account}}</view>
<view class="" style="margin-left: auto;" @click="contactService(orderInfo.user_yh.account)">
<image
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/1cd9338d-f5b3-421b-8757-92578387e05d.png"
mode="widthFix" style="width: 40rpx;margin-top: 15rpx;"></image>
</view>
</view>
</view> -->
<!-- 服务时段 -->
<view class="time_card" v-if="orderInfo.order_kind == 3">
<view class="card_title">服务时段</view>
<view class="card_time mb-20">
预约开始时间: <text
style="color: #333333;">{{ formatDateAndAddMinutes(orderInfo.reservation_time).original }}</text>
</view>
<view class="card_time">
预约结束时间: <text
style="color: #333333;">{{ formatDateAndAddMinutes(orderInfo.reservation_time,orderInfo.server_time).afterAddingMinutes }}</text>
</view>
</view>
<!-- 预约信息 -->
<view class="booking-card">
<view class="card_title">预约信息</view>
<view class="service-item">
<image :src="orderInfo.server_photo[0]"
v-if="orderInfo.server_photo && orderInfo.server_photo.length != 0" mode="aspectFill"
class="service-image"></image>
<view class="service-info">
<view class="service-name">{{ orderInfo.server_title }}
<view class="service-name-num">×1</view>
</view>
<view v-if="orderInfo.team_buy_id" class="group-price">
<!-- <view class="service-price">原价¥{{ orderInfo.cost_money }}</view> -->
<view class="service-price2">团购价:¥<text style="font-size: 36rpx">{{
orderInfo.order_money
}}</text></view>
</view>
<text class="service-price2" style="color: #333" v-else>¥
<text style="font-size: 36rpx">{{ orderInfo.order_money }}</text>
</text>
</view>
</view>
<view class="service-item1">
<view class="serverinfo">
<view class="serverinfo-l">服务售价</view>
<view class="serverinfo-r">
<view class="serverinfo-r-o" v-if="orderInfo.cost_money!=orderInfo.line_money">
¥{{orderInfo.line_money}}</view>
<view class="serverinfo-r-t">¥{{orderInfo.cost_money}}</view>
</view>
</view>
</view>
<view class="service-item1">
<view class="payinfo">
<view class="payinfo-l">用户实付</view>
<view class="payinfo-r">¥{{orderInfo.pay_money}}</view>
</view>
</view>
<view class="service-item1" v-if="orderInfo.butie_zonge && orderInfo.butie_zonge!=0">
<view class="btinfo">
<view class="btinfo-l">平台补贴</view>
<view class="btinfo-r">¥{{orderInfo.butie_zonge}}</view>
</view>
</view>
<view class="service-real">
<text class="real-lable">商家结算基数</text>
<view class="real-price">
<text class="icon">¥</text>
<text>{{ orderInfo.jiesuan_jine_yiju?orderInfo.jiesuan_jine_yiju:0 }}</text>
</view>
</view>
</view>
<view class="syr-card" v-if="orderInfo.order_shopphone_other">
<view class="syr-card-header">
预约手艺人信息
</view>
<view class="syr-card-footer flex-row-center-between">
<view class="syr-card-footer-left flex-row-center">
<image class="syr-card-footer-left-img" :src="orderInfo.order_shopheadphoto_other"></image>
<view class="syr-card-footer-left-text">
{{ `${orderInfo.order_shop_other} ${orderInfo.order_shopphone_other}` }}
</view>
</view>
<image class="syr-card-footer-right" @click="contactService(orderInfo.order_shopphone_other)"
src="/static/images/icons/phone.png"></image>
</view>
</view>
<!-- 订单信息 -->
<view class="order-card">
<text class="card-title">订单信息</text>
<view class="info-item">
<text class="label">订单编号</text>
<text class="value">{{orderInfo.number}}</text>
</view>
<view class="info-item" v-if="orderInfo.order_kind == 1">
<text class="label">到家时间</text>
<text class="value">{{orderInfo.reservation_time}}</text>
</view>
<view class="info-item">
<text class="label">下单时间</text>
<text class="value">{{orderInfo.add_time}}</text>
</view>
<view class="info-item" v-if="orderInfo.server_time">
<text class="label">服务时长</text>
<text class="value">{{orderInfo.server_time}}分钟</text>
</view>
<view class="info-item" v-if="orderInfo.state != 1 && orderInfo.pay_kind">
<text class="label">支付方式</text>
<text
class="value">{{orderInfo.pay_kind == 1 ? '账户余额' : orderInfo.pay_kind == 2 ? '微信支付' : orderInfo.pay_kind == 3 ? '支付宝支付' : ''}}</text>
</view>
<view class="info-item" v-if="orderInfo.state != 1 &&orderInfo.pay_time">
<text class="label">支付时间</text>
<text class="value">{{orderInfo.pay_time}}</text>
</view>
<view class="info-item" v-if="orderInfo.state >= 3 && orderInfo.get_time">
<text class="label">接单时间</text>
<text class="value">{{ orderInfo.get_time }}</text>
</view>
<view class="info-item" v-if="orderInfo.state >= 4 && orderInfo.server_start_time">
<text class="label">开始服务时间</text>
<text class="value">{{ orderInfo.server_start_time }}</text>
</view>
<view class="info-item" v-if="orderInfo.state >= 5 && orderInfo.server_end_time">
<text class="label">完成服务时间</text>
<text class="value">{{ orderInfo.server_end_time }}</text>
</view>
</view>
<!-- 订单信息 -->
<view class="order-card" v-if="orderInfo.team_buy_id">
<text class="card-title">团购活动</text>
<view class="info-item">
<text class="label" v-if="orderInfo.team_buy_number">活动编号</text>
<text class="value">{{orderInfo.team_buy_number}}</text>
</view>
<view class="info-item">
<text class="label">活动名称</text>
<text class="value">{{orderInfo.team_buy_title}}</text>
</view>
<view class="info-item" v-if="orderInfo.team_buy_order_number">
<text class="label">团单编号</text>
<text class="value">{{orderInfo.team_buy_order_number}}</text>
</view>
</view>
<view class="order-card" v-if="Object.keys(orderInfo.coupon_info).length>0">
<text class="card-title">优惠券信息</text>
<view class="coupon-item">
<view class="info-item">
<text class="label">优惠券</text>
<text class="value">{{orderInfo.coupon_info.title}}</text>
</view>
<view class="info-item">
<text class="label">券码</text>
<text class="value">{{orderInfo.coupon_info.code_num}}</text>
</view>
<view class="info-item">
<text class="label">优惠金额</text>
<text class="value">{{orderInfo.coupon_info.reduce_money}}元</text>
</view>
</view>
</view>
</view>
<!-- 底部按钮 -->
<view class="bottom-buttons"
v-if="haveButton && (orderInfo.state == 2) || orderInfo.state == 3 || orderInfo.state == 4">
<!-- <view class="contact-button" @click="contactService(orderInfo.phone_user)">
<image src="/static/images/tell_icon.png" class="tell-icon"></image>
<text class="contact-text">联系TA</text>
</view> -->
<view class="handel-button btn-border" v-if="orderInfo.state == 2 || orderInfo.state == 3"
@click.stop="cancelOrder($event, orderInfo)">
<text class="button-text">取消订单</text>
</view>
<view class="handel-button btn-bg" v-if="orderInfo.state == 3" @click.stop="startOrder($event, orderInfo)">
<text class="button-text">开始服务</text>
</view>
<view class="handel-button btn-bg" v-if="orderInfo.state == 4" @click.stop="endOrder($event, orderInfo)">
<text class="button-text">服务完成</text>
</view>
</view>
<serviceCodeInput :show="showInput" @close="showInput = false" @confirm="onConfirm" />
<!-- 获取权限提示匡内容 -->
<view class="permission" :class="{ transform: isShowPer }">
<view class="per-tit">美融融plus 对拨打电话权限申请说明</view>
<view class="per-cont">当您需要联系商家或平台客服的时候,需要获取拨打电话权限。</view>
</view>
<!-- 定位权限提示匡内容 -->
<view class="permission" :class="{ transform: isShowLocationPer }">
<view class="per-tit">美融融plus 对位置权限申请说明</view>
<view class="per-cont">当您需要查看商家位置或打开地图时,需要获取您的位置权限。</view>
</view>
</view>
</template>
<script>
import request from '../../utils/request'
import _public from '../../utils/public'
import serviceCodeInput from '../../components/service-code-input/service-code-input.vue';
import locationService from '../../utils/locationService';
import permissionUtils from '../../utils/per'
export default {
components: {
serviceCodeInput
},
data() {
return {
serviceType: 1, //订单类型1普通2自营
urls: {
1: {
weChatRefund: "/sj/yhwechatrefund",
aliRefund: "/sj/yhalirefund",
startOrder: "/sj/startserver",
endOrder: "/sj/endserver",
detail: "/sj/yhorderdetail",
},
2: {
weChatRefund: "/sj/orderSelf/weChatRefund",
aliRefund: "/sj/orderSelf/aliRefund",
startOrder: "/sj/orderSelf/start",
endOrder: "/sj/orderSelf/end",
detail: "/sj/orderSelf/details",
}
},
clickType: false, //点击状态,防止连续点击
isShowPer: false,
isShowLocationPer: false, // 控制定位权限说明视图显示
id: '',
staffInfo: {
avatar: '/static/images/staff.jpg',
name: '中医理疗谢飞',
rating: 5
},
showInput: false,
userInfo: {},
orderInfo: {},
reservation_address_arr: {},
user_sj: {}, // 店铺信息
distance: "", // 距离
scrollTop: 0,
haveButton: true,
}
},
async onLoad(options) {
this.id = options.order_id
if (options.serviceType) {
this.serviceType = options.serviceType
}
//推送消息订单传入后判断是否是自营
if (options.order_type) {
this.serviceType = options.order_type == 6 ? 2 : 1
}
//信息读取
if (options.push_id) {
this.messageRead(options.push_id)
}
// 添加调试日志
console.log('serviceType 值:', this.serviceType, '类型:', typeof this.serviceType)
console.log('options.serviceType:', options.serviceType)
if (options.order_id) {
// 请求订单详情
const userInfo = await request.post('/user/getuser', {
type: 3
});
this.userInfo = userInfo.data;
this.getOrderDetail();
}
if (options.order_kind == 3) {
this.haveButton = false
}
},
onPageScroll(e) {
this.scrollTop = e.scrollTop;
},
computed: {
backgroundColor() {
if (this.scrollTop > 10) {
return `rgba(255, 255, 255, ${Math.min(0.02 * this.scrollTop, 1)})`;
}
return "transparent";
},
stateItem() {
const list = [{
text: "待支付",
icon: "/static/images/icons/pay.png",
state: "1"
},
{
text: "待接单",
icon: "/static/images/icons/pending.png",
state: "2",
},
{
text: "待开始",
icon: "/static/images/icons/daikaishi.png",
state: "3",
},
{
text: "待完成",
icon: "/static/images/icons/pendingService.png",
state: "4",
},
{
text: "已完成",
icon: "/static/images/icons/payOk.png",
state: "5"
},
{
text: "待评价",
icon: "/static/images/icons/pending.png",
state: "6",
},
{
text: "已取消",
icon: "/static/images/evaluate/cancel.png",
state: "7"
},
];
const item = list.find((it) => it.state == this.orderInfo.state) || {};
return item;
},
},
methods: {
//消息列表跳转阅读
messageRead(id) {
request.post("/sj/push/messageRead", {
id: id
}).then(res => {
console.log("messageRead:", res)
this.messageUpudateNum()
})
},
//获取拼团状态文字
getGroupType(id) {
let list = [{
id: 1,
text: "拼团中",
},
{
id: 2,
text: "已成团",
},
{
id: 3,
text: "拼团失败",
},
];
let name = list.find((it) => it.id == id)?.text;
return name;
},
// 用于标准格式的方法
formatDateTime(dateStr, includeSeconds = true) {
if (!dateStr) {
return '';
}
// 处理日期字符串,兼容不同格式
const originalDate = new Date(dateStr.replace(/-/g, '/'));
// 格式化为 YYYY-MM-DD HH:mm:ss
const year = originalDate.getFullYear();
const month = String(originalDate.getMonth() + 1).padStart(2, "0");
const day = String(originalDate.getDate()).padStart(2, "0");
const hours = String(originalDate.getHours()).padStart(2, "0");
const minutes = String(originalDate.getMinutes()).padStart(2, "0");
const seconds = String(originalDate.getSeconds()).padStart(2, "0");
if (includeSeconds) {
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
} else {
return `${year}-${month}-${day} ${hours}:${minutes}`;
}
},
formatDateAndAddMinutes(dateStr, addMinutes = 0) {
// 解析原始日期
if (!dateStr) {
return {
original: '',
afterAddingMinutes: '',
};
}
const originalDate = new Date(dateStr.replace(/-/g, '/'));
// 格式化日期的辅助函数
function format(date) {
const year = date.getFullYear();
// 月份和日期需要补零
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
return `${year}年${month}月${day}日 ${hours}:${minutes}`;
}
// 格式化原始日期
const formattedOriginal = format(originalDate);
// 计算加上指定分钟后的日期
const newDate = new Date(originalDate);
newDate.setMinutes(newDate.getMinutes() + addMinutes);
// 格式化新日期
const formattedNew = format(newDate);
return {
original: formattedOriginal,
afterAddingMinutes: formattedNew,
};
},
getOrderDetail() {
request.post(this.urls[this.serviceType].detail, {
id: this.id,
sjid: this.userInfo.id
}).then(res => {
this.orderInfo = res.data;
this.reservation_address_arr = res.data.reservation_address_arr;
// 添加店铺信息(如果有的话)
if (res.data.user_sj) {
this.user_sj = res.data.user_sj;
this.calculateDistance(); // 计算距离
}
console.log(this.orderInfo)
})
},
// 打开店铺地图
openShopMap() {
if (!this.user_sj.latitude || !this.user_sj.longitude) {
uni.showToast({
title: '暂无店铺位置信息',
icon: 'none'
});
return;
}
// #ifdef MP-WEIXIN
uni.openLocation({
latitude: parseFloat(this.user_sj.latitude),
longitude: parseFloat(this.user_sj.longitude),
name: this.user_sj.name || '店铺位置',
address: this.user_sj.address || '',
success: () => console.log('打开系统位置地图成功'),
fail: (error) => console.log(error),
});
// #endif
// #ifdef APP-PLUS
_public.goMap({
latitude: parseFloat(this.user_sj.latitude),
longitude: parseFloat(this.user_sj.longitude),
name: this.user_sj.name || '店铺位置',
address: this.user_sj.address || '',
});
// #endif
},
// 计算距离
calculateDistance() {
if (this.user_sj.latitude && this.user_sj.longitude) {
// 使用公共方法计算距离
this.distance = _public.calcDistance(
parseFloat(this.user_sj.latitude),
parseFloat(this.user_sj.longitude),
getApp().globalData.latitude || 0,
getApp().globalData.longitude || 0
);
}
},
// 取消订单
cancelOrder(e, order) {
// app阻止事件冒泡
// #ifdef APP-PLUS
e.preventDefault();
e.stopPropagation();
// #endif
uni.showModal({
title: '取消订单',
content: '确定要取消该订单吗?(订单取消后,支付金额将原路退回)',
success: (res) => {
if (res.confirm) {
// TODO: 取消订单
let data = {
orderNo: order.number,
amount: order.pay_money,
sjid: this.userInfo.id
}
let url = '';
if (order.pay_kind == 1) {
url = ''
} else if (order.pay_kind == 2) {
url = this.urls[this.serviceType].weChatRefund
} else if (order.pay_kind == 3) {
url = this.urls[this.serviceType].aliRefund
}
console.log(data, url)
if (this.clickType) {
return
}
this.clickType = true
request.post(url, data).then(res => {
if (res.state == 1) {
uni.showToast({
title: '取消成功!',
icon: 'none'
})
this.getOrderDetail();
// 修改上一页页面信息
const pages = getCurrentPages();
const prevPage = pages[pages.length - 2];
if (prevPage) {
prevPage.$vm.getOrderNumber();
prevPage.$vm.getOrderList();
}
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
}).catch(err => {
console.log(err)
}).finally(() => {
this.clickType = false
})
}
}
})
},
// 开始服务
startOrder(e, order) {
// app阻止事件冒泡
if (order.team_buy_order_state == 1) {
uni.showToast({
title: "订单当前处于拼团中,服务将在拼团完成后才开启~",
icon: "none",
});
return
}
this.showInput = true
},
// 输入完成
onConfirm(code) {
this.showInput = false
if (this.clickType) {
return
}
this.clickType = true
request.post(this.urls[this.serviceType].startOrder, {
id: this.orderInfo.id,
server_code: code,
sjid: this.userInfo.id
}).then(res => {
console.log(res)
if (res.state == 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
this.getOrderDetail();
// 修改上一页页面信息
const pages = getCurrentPages();
const prevPage = pages[pages.length - 2];
if (prevPage) {
prevPage.$vm.getOrderNumber();
prevPage.$vm.getOrderList();
}
} else if (res.state == 2) {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
this.handelOrder = {};
}).finally(() => {
this.clickType = false
})
},
// 完成服务
endOrder(e, order) {
// app阻止事件冒泡
// #ifdef APP-PLUS
e.preventDefault();
e.stopPropagation();
// #endif
if (this.clickType) {
return
}
this.clickType = true
request.post(this.urls[this.serviceType].endOrder, {
id: order.id,
sjid: this.userInfo.id
}).then(res => {
if (res.state == 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
this.getOrderDetail();
// 修改上一页页面信息
const pages = getCurrentPages();
const prevPage = pages[pages.length - 2];
if (prevPage) {
prevPage.$vm.getOrderNumber();
prevPage.$vm.getOrderList();
}
}
}).finally(() => {
this.clickType = false
})
},
// 显示权限说明弹窗
showPermissionDialog(title, content) {
return new Promise((resolve) => {
uni.showModal({
title,
content,
confirmText: '去开启',
success(res) {
resolve(res.confirm);
}
});
});
},
// 联系用户
async contactService(phone) {
// TODO: 实现联系客服功能
// uni.navigateTo({
// url: '/pages/contact/contact?phone='+phone
// })
const systemInfo = uni.getSystemInfoSync()
if (systemInfo.platform === 'ios') {
uni.makePhoneCall({
phoneNumber: phone //仅为示例
})
} else {
let permission = '';
if (systemInfo.platform === 'ios') {
permission = 'phone'
} else {
permission = 'android.permission.CALL_PHONE'
}
this.isShowPer = true;
const firstRequest = !plus.storage.getItem(`perm_${permission}`)
if (firstRequest) {
this.isShowPer = true;
}
// 1. 检查权限
const {
granted
} = await permissionUtils.checkPermission('phone', '需要拨打电话权限,方便您联系商家或平台');
if (granted) {
this.isShowPer = false;
uni.makePhoneCall({
phoneNumber: phone //仅为示例
})
return;
}
this.isShowPer = false;
// 2. 显示权限说明弹窗
const confirm = await this.showPermissionDialog(
'拨打电话权限申请',
'我们需要拨打电话权限,方便您联系商家或平台'
);
if (!confirm) return;
// 3. 请求权限
const result = await permissionUtils.requestPermission('phone', '需要拨打电话权限,方便您联系商家或平台');
console.log('result', result)
if (result) {
uni.makePhoneCall({
phoneNumber: phone //仅为示例
})
return;
} else {
locationService.openAppSettings();
return;
// uni.showToast({ title: '相机权限被拒绝', icon: 'none' });
}
}
},
// 打开上门地址地图
async openMap() {
const systemInfo = uni.getSystemInfoSync();
if (systemInfo.platform === "ios") {
this._openLocation(this.reservation_address_arr);
} else {
this.isShowLocationPer = true;
const {
granted
} = await permissionUtils.checkPermission(
"location",
"需要位置权限以打开地图"
);
if (granted) {
this.isShowLocationPer = false;
this._openLocation(this.reservation_address_arr);
return;
}
this.isShowLocationPer = false;
const confirm = await this.showPermissionDialog(
"位置权限申请",
"我们需要您的位置权限,以便在地图上显示位置"
);
if (!confirm) return;
const result = await permissionUtils.requestPermission(
"location",
"需要位置权限以打开地图"
);
if (result) {
this._openLocation(this.reservation_address_arr);
} else {
locationService.openAppSettings();
}
}
},
// 打开店铺地图
async openShopMap() {
if (!this.user_sj.latitude || !this.user_sj.longitude) {
uni.showToast({
title: '暂无店铺位置信息',
icon: 'none'
});
return;
}
const systemInfo = uni.getSystemInfoSync();
if (systemInfo.platform === "ios") {
this._openLocation(this.user_sj);
} else {
this.isShowLocationPer = true;
const {
granted
} = await permissionUtils.checkPermission(
"location",
"需要位置权限以打开地图"
);
if (granted) {
this.isShowLocationPer = false;
this._openLocation(this.user_sj);
return;
}
this.isShowLocationPer = false;
const confirm = await this.showPermissionDialog(
"位置权限申请",
"我们需要您的位置权限,以便在地图上显示店铺位置"
);
if (!confirm) return;
const result = await permissionUtils.requestPermission(
"location",
"需要位置权限以打开地图"
);
if (result) {
this._openLocation(this.user_sj);
} else {
locationService.openAppSettings();
}
}
},
// 实际打开地图的方法(抽离)
_openLocation(obj) {
// #ifdef MP-WEIXIN
uni.openLocation({
latitude: parseFloat(obj.latitude),
longitude: parseFloat(obj.longitude),
name: obj.name || obj.house_number || '位置',
address: obj.address || obj.server_address || '',
success: () => console.log('打开地图成功'),
fail: (err) => console.error('打开地图失败', err)
});
// #endif
// #ifdef APP-PLUS
_public.goMap({
latitude: parseFloat(obj.latitude),
longitude: parseFloat(obj.longitude),
name: obj.name || obj.house_number || '位置',
address: obj.address || obj.server_address || ''
});
// #endif
},
}
}
</script>
<style lang="less">
page {
position: relative;
background-color: #fff;
}
.detail-page::before {
content: "";
position: fixed;
top: 0;
left: 0;
right: 0;
height: 1200rpx !important;
background-image: url("/static/images/bg.png");
background-size: cover;
background-position: center top;
background-repeat: no-repeat;
z-index: 1;
}
.detail-page.no-bottom-buttons {
padding-bottom: 20rpx !important;
}
.content-part {
position: relative;
left: 0;
right: 0;
z-index: 9;
}
/* 导航栏样式 */
.custom-nav {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 88rpx;
background-color: transparent;
display: flex;
align-items: center;
padding: 0 32rpx;
z-index: 100;
/* #ifdef H5 */
padding-top: 0;
/* #endif */
/* #ifdef APP-PLUS || MP-WEIXIN */
padding-top: var(--status-bar-height);
/* #endif */
}
.nav-back {
width: 48rpx;
height: 48rpx;
display: flex;
align-items: center;
justify-content: center;
}
.back-icon {
width: 32rpx;
height: 32rpx;
}
.nav-title {
flex: 1;
text-align: center;
font-size: 36rpx;
font-weight: 500;
color: #ffffff;
}
/* 状态区域 */
.status-section {
/* background: linear-gradient(135deg, #FF6B9D 0%, #FF4D6B 100%); */
/* height: 160rpx; */
display: flex;
align-items: center;
justify-content: center;
gap: 20rpx;
padding-top: 55rpx;
padding-bottom: 50rpx;
/* padding-top: 88rpx; */
/* #ifdef APP-PLUS || MP-WEIXIN */
/* padding-top: calc(88rpx + var(--status-bar-height)); */
/* #endif */
.status-section-image {
width: 52rpx;
height: 48rpx;
}
}
.status-text {
font-size: 44rpx;
color: #333333;
font-weight: 600;
}
/* 服务人员卡片 */
.service-card {
margin: 0 30rpx 20rpx;
background-color: #ffffff;
border-radius: 20rpx;
padding: 30rpx 20rpx;
box-shadow: 0 4rpx 16rpx 0 rgba(210, 213, 224, 0.5);
.card_title {
font-weight: 500;
font-size: 32rpx;
color: #333333;
padding-bottom: 16rpx;
}
}
.location-info {
display: flex;
flex-direction: column;
gap: 24rpx;
// flex-direction: column;
// flex-flow: row nowrap;
// justify-content: flex-start;
// align-items: center;
}
.location-icon {
width: 44rpx;
height: 44rpx;
margin-right: 10rpx;
flex-shrink: 0;
}
.address-info {
display: flex;
align-items: center;
flex: 1;
}
.name-phone {
display: flex;
align-items: center;
flex-wrap: nowrap;
justify-content: space-between;
}
.name {
font-size: 30rpx;
color: #333333;
font-weight: 500;
margin-right: 20rpx;
}
.phone {
font-weight: 500;
font-size: 30rpx;
color: #333333;
line-height: 42rpx;
}
.address {
font-size: 26rpx;
color: #333333;
margin-top: 8rpx;
}
.info_Btn {
width: 155rpx;
height: 42rpx;
border-radius: 13rpx;
border: 1rpx solid #bbbbbb;
display: flex;
align-items: center;
justify-content: center;
gap: 11rpx;
color: #999999;
font-size: 24rpx;
.btn-phone {
width: 20rpx;
height: 22rpx;
}
}
/* 店铺信息卡片 */
.shop_card {
margin: 30rpx 30rpx 20rpx;
background-color: #ffffff;
border-radius: 16rpx;
padding: 24rpx 20rpx 24rpx;
box-shadow: 0 4rpx 16rpx 0 rgba(210, 213, 224, 0.5);
.card_title {
font-weight: 500;
font-size: 32rpx;
color: #333333;
}
.shop_info_box {
// margin-top: 30rpx;
}
.shop_info_row {
display: flex;
align-items: center;
padding-bottom: 24rpx;
border-bottom: 3rpx solid #f6f5f5;
}
.shop_info_left {
display: flex;
align-items: center;
flex: 1;
}
.shop_photo {
width: 96rpx;
height: 96rpx;
border-radius: 12rpx;
margin-right: 20rpx;
}
.shop_name {
font-size: 32rpx;
color: #333333;
font-weight: 600;
}
.shop_distance {
display: flex;
align-items: center;
margin-top: 10rpx;
}
.distance_icon {
width: 24rpx;
height: 24rpx;
margin-right: 4rpx;
}
.distance_text {
font-size: 26rpx;
color: #666666;
}
.shop_info_actions {
display: flex;
align-items: center;
gap: 30rpx;
}
.shop_action_item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.action_icon_map,
.action_icon_phone {
width: 40rpx;
height: 40rpx;
}
.action_text {
font-size: 20rpx;
color: #8b8b8b;
margin-top: 2rpx;
}
.shop_details {
margin-top: 24rpx;
}
.shop_time {
display: block;
font-size: 28rpx;
color: #333333;
font-weight: 500;
padding-bottom: 10rpx;
margin-bottom: 20rpx;
border-bottom: 1rpx solid #f6f5f5;
}
.shop_phone {
display: block;
font-size: 28rpx;
color: #666666;
margin-bottom: 10rpx;
}
.shop_address {
display: block;
font-size: 28rpx;
color: #666666;
}
}
/* 预约信息卡片 */
.booking-card {
margin: 0rpx 30rpx 20rpx;
background-color: #ffffff;
border-radius: 20rpx;
padding: 24rpx 30rpx 20rpx 20rpx;
box-shadow: 0 4rpx 16rpx 0 rgba(210, 213, 224, 0.5);
.card_title {
font-weight: 500;
font-size: 32rpx;
color: #333333;
margin-bottom: 40rpx;
line-height: 34rpx;
}
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
}
.card-title {
font-size: 32rpx;
color: #3d3d3d;
font-weight: 500;
}
.update-time {
font-size: 28rpx;
color: #333333;
padding-right: 4rpx;
}
.update-change {
font-size: 28rpx;
color: #666666;
}
.service-item {
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-items: center;
margin-bottom: 32rpx;
}
.service-image {
width: 160rpx;
height: 160rpx;
border-radius: 16rpx;
margin-right: 24rpx;
background-color: #e2e2e2;
}
.service-info {
flex: 1;
height: 160rpx;
display: flex;
flex-flow: column nowrap;
justify-content: space-between;
align-items: flex-start;
margin-right: 24rpx;
}
.service-name {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
font-weight: 500;
font-size: 30rpx;
color: #333333;
line-height: 34rpx;
text-align: left;
font-style: normal;
.service-name-num {
font-weight: 500;
font-size: 26rpx;
color: #999999;
line-height: 34rpx;
}
}
.service-price {
font-family: DINPro, DINPro;
font-weight: 400;
font-size: 24rpx;
color: #bbbbbb;
line-height: 34rpx;
text-align: left;
font-style: normal;
margin-bottom: 7rpx;
}
.service-price2 {
font-family: DINPro, DINPro;
font-weight: 500;
font-size: 24rpx;
color: #E8101E;
line-height: 34rpx;
text-align: left;
font-style: normal;
}
.service-count {
font-weight: 500;
font-size: 26rpx;
color: #999999;
line-height: 34rpx;
text-align: left;
font-style: normal;
}
.service-real {
display: flex;
flex-flow: row nowrap;
justify-content: flex-end;
align-items: baseline;
padding-top: 24rpx;
border-top: 1rpx solid rgba(0, 0, 0, 0.05);
}
.real-lable {
font-size: 30rpx;
color: #333333;
}
.real-price {
font-family: DINPro, DINPro;
font-size: 32rpx;
font-weight: 500;
color: #E8101E;
.icon {
font-size: 20rpx;
}
}
/* 订单信息卡片 */
.order-card {
margin: 20rpx 30rpx 30rpx 30rpx;
background-color: #ffffff;
border-radius: 16rpx;
padding: 36rpx 20rpx 40rpx;
box-shadow: 0 4rpx 16rpx 0 rgba(210, 213, 224, 0.5);
.card_title {
font-weight: 500;
font-size: 32rpx;
color: #333333;
padding-bottom: 10rpx;
}
}
.time_card {
margin: 30rpx;
background-color: #ffffff;
border-radius: 16rpx;
padding: 30rpx 20rpx;
box-shadow: 0 4rpx 16rpx 0 rgba(210, 213, 224, 0.5);
.card_title {
font-weight: 500;
font-size: 32rpx;
color: #333333;
padding-bottom: 16rpx;
}
.card_time {
font-weight: 400;
font-size: 28rpx;
color: #999999;
line-height: 34rpx;
text-align: left;
font-style: normal;
}
}
.info-item {
display: flex;
justify-content: space-between;
margin-top: 30rpx;
}
.label {
font-size: 28rpx;
color: #999999;
}
.value {
font-size: 28rpx;
color: #333333;
}
/* 底部按钮 */
.bottom-buttons {
position: fixed;
left: 0;
right: 0;
bottom: 0;
height: 128rpx;
background-color: #ffffff;
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: flex-end;
box-shadow: 0 -2rpx 8rpx rgba(0, 0, 0, 0.05);
padding: 0 24rpx 0 78rpx;
/* #ifdef H5 */
padding-bottom: env(safe-area-inset-bottom);
/* #endif */
z-index: 999;
}
.contact-button {
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
}
.contact-text {
font-size: 24rpx;
color: #666666;
}
.tell-icon {
width: 36rpx;
height: 36rpx;
margin-right: 8rpx;
}
.handel-button {
width: 186rpx;
height: 72rpx;
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
border-radius: 36rpx;
margin-left: 30rpx;
}
.btn-border {
border: 2rpx solid #979797;
background-color: #fff;
box-sizing: border-box;
margin-left: 60rpx;
}
.btn-bg {
background-color: #E8101E;
}
.button-text {
font-size: 28rpx;
font-weight: 400;
color: #ffffff;
}
.btn-border .button-text {
font-size: 28rpx;
font-weight: 400;
color: #333333;
}
/* APP适配 */
/* #ifdef APP-PLUS */
.permission.transform {
top: calc(var(--status-bar-height) + 88rpx + 20rpx);
opacity: 1;
visibility: visible;
}
.detail-page {
padding-bottom: calc(120rpx + env(safe-area-inset-bottom));
}
/* #endif */
/* 平台适配 */
/* #ifdef H5 */
.detail-page {
padding-bottom: calc(120rpx + env(safe-area-inset-bottom));
}
/* #endif */
/* #ifdef MP-WEIXIN */
.custom-nav {
padding-top: calc(var(--status-bar-height) + constant(safe-area-inset-top));
padding-top: calc(var(--status-bar-height) + env(safe-area-inset-top));
}
/* #endif */
.syr-card {
margin: 30rpx;
background-color: #ffffff;
padding: 30rpx 20rpx;
border-radius: 16rpx;
.syr-card-header {
font-weight: 500;
font-size: 32rpx;
color: #333333;
line-height: 45rpx;
text-align: left;
font-style: normal;
margin-bottom: 40rpx;
}
.syr-card-footer {
.syr-card-footer-left {
.syr-card-footer-left-img {
width: 70rpx;
height: 70rpx;
border-radius: 50%;
margin-right: 20rpx;
}
.syr-card-footer-left-text {
font-weight: 400;
font-size: 28rpx;
color: #333333;
line-height: 40rpx;
text-align: left;
font-style: normal;
}
}
.syr-card-footer-right {
width: 40rpx;
height: 40rpx;
}
}
}
// 客户卡片样式
.kh-card {
margin: 30rpx;
background-color: #ffffff;
padding: 30rpx 20rpx;
border-radius: 16rpx;
.kh-card-header {
font-weight: 500;
font-size: 32rpx;
color: #333333;
line-height: 45rpx;
text-align: left;
font-style: normal;
margin-bottom: 40rpx;
}
.kh-card-footer {
.kh-card-footer-left {
.kh-card-footer-left-img {
width: 70rpx;
height: 70rpx;
border-radius: 50%;
margin-right: 20rpx;
}
.kh-card-footer-left-text {
font-weight: 400;
font-size: 28rpx;
color: #333333;
line-height: 40rpx;
text-align: left;
font-style: normal;
}
}
.kh-card-footer-right {
width: 40rpx;
height: 40rpx;
}
}
}
.userinfo {
display: flex;
}
.serverinfo {
display: flex;
justify-content: space-between;
}
.serverinfo-l {
width: 120rpx;
height: 42rpx;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 30rpx;
color: #333333;
line-height: 42rpx;
text-align: left;
font-style: normal;
}
.serverinfo-r {
display: flex;
}
.serverinfo-r-o {
height: 40rpx;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 26rpx;
color: #999999;
line-height: 40rpx;
text-align: left;
font-style: normal;
// margin-left: 350rpx;
text-decoration: line-through;
}
.serverinfo-r-t {
height: 40rpx;
font-family: DINPro, DINPro;
font-weight: 500;
font-size: 32rpx;
color: #333333;
line-height: 40rpx;
text-align: left;
font-style: normal;
margin-left: 17rpx;
}
.service-item1 {
margin-bottom: 32rpx;
}
.payinfo {
display: flex;
justify-content: space-between;
}
.payinfo-l {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 26rpx;
color: #666666;
line-height: 37rpx;
text-align: left;
font-style: normal;
}
.payinfo-r {
font-family: DINPro, DINPro;
font-weight: 500;
font-size: 32rpx;
color: #333333;
line-height: 41rpx;
text-align: left;
font-style: normal;
}
.btinfo {
display: flex;
justify-content: space-between;
}
.btinfo-l {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 26rpx;
color: #666666;
line-height: 37rpx;
text-align: left;
font-style: normal;
}
.btinfo-r {
font-family: DINPro, DINPro;
font-weight: 500;
font-size: 30rpx;
color: #333333;
line-height: 38rpx;
text-align: left;
font-style: normal;
}
.coupon-title{
width: 160rpx;
height: 40rpx;
font-family: PingFangSC, PingFang SC;
font-weight: 500;
font-size: 32rpx;
color: #3D3D3D;
line-height: 39rpx;
text-align: left;
font-style: normal;
}
.coupon-item {}
</style>