mrr.sj.front/pages/syr/shoporder-detail.vue

1054 lines
24 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">
<!-- 顶部导航栏 -->
<custom-navbar title="订单详情" :show-back="true" title-color="#333333"
:backgroundColor="backgroundColor"></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>
</view>
<!-- 到家订单 客户以及手艺人信息 -->
<view class="service-card">
<view class="location-info">
<view class="name-phone">
<view>
<text class="name">{{ reservation_address_arr.name }}</text>
<text class="phone">{{ reservation_address_arr.account }}</text>
</view>
<image class="btn-phone" src="/static/images/order_phone.png" mode="aspectFit"
@click="contactService(reservation_address_arr.account)"></image>
</view>
<view class="address-info">
<image @click="openMap()" src="/static/images/icons/position.png" class="location-icon"></image>
<text class="address">到家地址:{{ reservation_address_arr.dependency
}}{{ reservation_address_arr.address }}</text>
<!-- <image
class="btn-map"
src="/static/images/map_icon.png"
mode="aspectFit"
@click="openMap()"
></image>
<image
class="btn-phone"
src="/static/images/order_phone.png"
mode="aspectFit"
@click="contactService(reservation_address_arr.call_phone)"
></image> -->
</view>
</view>
</view>
<!-- 服务时段 -->
<view class="time_card">
<view class="card_title">服务时段</view>
<view class="card_time">预约开始时间{{
formatDateAndAddMinutes(orderInfo.reservation_time).original
}}
</view>
<view class="card_time">预约结束时间{{
formatDateAndAddMinutes(
orderInfo.reservation_time,
orderInfo.server_time
).afterAddingMinutes
}}
</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-box">
<text class="service-name text-overflow">{{
orderInfo.server_title
}}</text>
<text class="service-count">×1</text>
</view>
<view class="service-price">
<text class="icon">¥</text>
<text>{{ orderInfo.order_money }}</text>
</view>
</view>
</view>
<view class="service-real">
<text class="real-lable">实付金额:</text>
<view class="real-price">
<text class="icon">¥</text>
<text>{{ orderInfo.pay_money }}</text>
</view>
</view>
</view>
<!-- 订单信息 -->
<view class="order-card">
<view class="card_title">订单信息</view>
<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">
<text class="label">服务时长</text>
<text class="value">{{ orderInfo.server_time || 0 }}分钟</text>
</view>
<view class="info-item" v-if="orderInfo.state != 1">
<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">
<text class="label">支付时间</text>
<text class="value">{{ orderInfo.pay_time }}</text>
</view>
<view class="info-item" v-if="
orderInfo.state != 1 && orderInfo.state != 2 && orderInfo.state != 3
">
<text class="label">开始服务时间</text>
<text class="value">{{ orderInfo.server_start_time }}</text>
</view>
<view class="info-item" v-if="
orderInfo.state != 1 &&
orderInfo.state != 2 &&
orderInfo.state != 3 &&
orderInfo.state != 4
">
<text class="label">服务完成时间</text>
<text class="value">{{ orderInfo.server_end_time }}</text>
</view>
</view>
</view>
<!-- 底部按钮 -->
<view class="bottom-buttons">
<!-- <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 == 2"
@click.stop="confirmOrder($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>
</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 {
clickType: false, //点击状态,防止连续点击
isShowPer: false,
id: "",
staffInfo: {
avatar: "/static/images/staff.jpg",
name: "中医理疗谢飞",
rating: 5,
},
showInput: false,
userInfo: {},
orderInfo: {},
reservation_address_arr: {},
user_syr: {},
scrollTop: 0,
};
},
async onLoad(options) {
this.id = options.id;
if (options.id) {
// 请求订单详情
const {
data
} = await request.post("/user/getuser", {
type: 2
});
this.userInfo = data;
this.getOrderDetail();
}
},
// 页面滚动时触发
onPageScroll(e) {
// e.scrollTop 为页面滚动的距离单位px
this.scrollTop = e.scrollTop;
},
computed: {
backgroundColor() {
if (this.scrollTop > 10) {
return `rgba(255, 255, 255, ${0.02 * this.scrollTop});`;
}
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/pendingService.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: {
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("/syr/sjorderdetail", {
id: this.id,
syrid: this.userInfo.id
})
.then((res) => {
this.orderInfo = res.data;
this.reservation_address_arr = res.data.reservation_address_arr;
console.log(this.orderInfo);
});
},
// 取消订单
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,
syrid: this.userInfo.id,
};
let url = "";
if (order.pay_kind == 1) {
url = "";
} else if (order.pay_kind == 2) {
url = "/syr/sjwechatrefund";
} else if (order.pay_kind == 3) {
url = "/syr/sjalirefund";
}
console.log(data, url);
if (this.clickType) {
return
}
this.clickType = true
request
.post(url, data)
.then((res) => {
if (res.state == 1 || res.code == 1 || res.code == 200) {
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
});
}
},
});
},
// 确认接单
confirmOrder(e, order) {
// app阻止事件冒泡
// #ifdef APP-PLUS
e.preventDefault();
e.stopPropagation();
// #endif
if (this.clickType) {
return
}
this.clickType = true
request
.post("/syr/sjordersure", {
id: order.id,
syrid: this.userInfo.id
})
.then((res) => {
uni.showToast({
title: "已接单",
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
});
},
// 开始服务
startOrder(e, order) {
// app阻止事件冒泡
// #ifdef APP-PLUS
e.preventDefault();
e.stopPropagation();
// #endif
this.showInput = true;
},
// 输入完成
onConfirm(code) {
this.showInput = false;
if (this.clickType) {
return
}
this.clickType = true
request
.post("/syr/sjstartserver", {
id: this.orderInfo.id,
server_code: code,
syrid: 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("/syr/sjendserver", {
id: order.id,
syrid: 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' });
}
}
},
// 打开手机已有地图
openMap() {
let that = this;
// #ifdef MP-WEIXIN
uni.openLocation({
success: function(res) {
console.log("打开系统位置地图成功");
},
fail: function(error) {
console.log(error);
},
});
// #endif
// #ifdef APP-PLUS
_public.goMap({
latitude: parseFloat(that.reservation_address_arr.latitude),
longitude: parseFloat(that.reservation_address_arr.longitude),
name: that.reservation_address_arr.name,
address: that.reservation_address_arr.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;
}
.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;
}
}
.status-text {
font-size: 44rpx;
color: #333333;
font-weight: 600;
}
/* 服务人员卡片 */
.service-card {
margin: 0 30rpx 20rpx;
background-color: #ffffff;
border-radius: 20rpx;
padding: 30rpx;
box-shadow: 0 4rpx 16rpx 0 rgba(210, 213, 224, 0.5);
// display: flex;
// flex-direction: column;
// flex-flow: row nowrap;
// justify-content: space-between;
// align-items: center;
}
.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: 30rpx;
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: 28rpx;
color: #666666;
margin-top: 8rpx;
}
.btn-map,
.btn-phone {
width: 64rpx;
height: 64rpx;
flex-shrink: 0;
}
.btn-map {
margin: 0 28rpx;
}
/* 预约信息卡片 */
.booking-card {
margin: 0rpx 30rpx 20rpx;
background-color: #ffffff;
border-radius: 20rpx;
padding: 34rpx 30rpx 40rpx 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;
}
}
.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-box {
width: 100%;
gap: 8rpx;
display: flex;
justify-content: space-between;
.service-count {
flex-shrink: 0;
}
.service-name {
flex: 1;
}
}
}
.service-name {
font-size: 30rpx;
color: #333333;
font-weight: 500;
}
.service-price {
font-size: 34rpx;
color: #333333;
font-weight: 500;
.icon {
font-size: 20rpx;
font-weight: 500;
}
}
.service-count {
font-size: 26rpx;
color: #999999;
font-weight: 500;
}
.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-size: 32rpx;
font-weight: 500;
color: #FF4767;
.icon {
font-size: 20rpx;
}
}
/* 订单信息卡片 */
.order-card {
margin: 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: 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: 16rpx;
}
.card_time {
font-size: 30rpx;
line-height: 30rpx;
color: #333333;
margin-top: 18rpx;
}
}
.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: 60rpx;
}
.btn-border {
border: 2rpx solid #FF4767;
background-color: #fff;
box-sizing: border-box;
margin-left: 60rpx;
}
.btn-bg {
background-color: #FF4767;
}
.button-text {
font-size: 28rpx;
font-weight: 400;
color: #ffffff;
}
.btn-border .button-text {
font-size: 28rpx;
font-weight: 400;
color: #FF4767;
}
/* 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 */
</style>