mrr.sj.front/pages/shop/components/orderCard.vue

432 lines
9.6 KiB
Vue
Raw Permalink 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="order-card">
<!-- 订单编号 -->
<view class="orderNumBox">
<view class="order-id white-space-nowrap">订单编号{{ dataItem.number }}</view>
</view>
<!-- 服务信息区域 -->
<view class="service-container" @click="$emit('goOrderDetail', dataItem)"
:class="{ noFotter: (!dataItem.reservation_time && !dataItem.reserve_end_time) || haveButton }">
<image class="service-img" :src="dataItem.order_photo ? dataItem.order_photo[0] : JSON.parse(dataItem.photo)[0]
" mode="aspectFill"></image>
<view class="service-info">
<view>
<view class="service-type">
<view class="service-name-type" v-if="dataItem.team_buy_id">
{{ getGroupType }}
</view>
<text class="service-name-text">
{{ dataItem.server_title }}
</text>
</view>
<view class="service-time" v-if="dataItem.add_time && dataItem.state != 7">下单时间:
{{ dataItem.add_time }}</view>
</view>
<view class="service-price">
<text v-if="dataItem.team_buy_id">{{ `团购价: ` }}</text>¥<text style="font-size: 34rpx;">{{
dataItem.order_money }}</text>
<text class="service-price-line">{{ dataItem.line_money }}</text>
</view>
</view>
</view>
<!-- 时间信息 -->
<view class="time-info" v-if="dataItem.reservation_time || dataItem.reserve_end_time">
<image class="time-info-img" :src="dataItem.order_shopheadphoto_other"></image>
<text class="time-info-name">{{ dataItem.order_shop_other }}</text>
<text class="time-info-text1">服务时段:</text>
<text class="time-info-text2">{{ useTime }}</text>
</view>
<!-- 操作按钮 -->
<view class="button-group" v-if="haveButton">
<view class="btn cancel-btn" v-if="dataItem.state == 2 || dataItem.state == 3" @click.stop="emitCancel">取消订单
</view>
<!-- <view class="btn accept-btn" @click.stop="emitAccept" v-if="dataItem.state == 2">接单</view> -->
<view class="btn accept-btn" @click.stop="emitStart" v-if="dataItem.state == 3">开始服务</view>
<view class="btn accept-btn" @click.stop="emitDone" v-if="dataItem.state == 4">服务完成</view>
</view>
</view>
</template>
<script>
export default {
name: "OrderCard",
props: {
dataItem: {
type: Object,
},
typeId: {
type: Number,
},
showState: {
type: Boolean,
default: true,
},
haveButton: {
type: Boolean,
default: true,
},
},
computed: {
useTime() {
const start = this.dataItem.reservation_time;
const server_time = this.dataItem.server_time || 0;
// 格式化时间范围:输出 2025年05月29 12:30-13:30 格式
function formatTimeRange(startTimeStr, serviceMinutes) {
// 1. 空值兜底:避免无开始时间时报错
if (!startTimeStr) return "";
// 2. 兼容低版本iOSiOS不识别 "-" 分隔的日期,必须替换为 "/"
const iosSafeTimeStr = startTimeStr.replace(/-/g, "/");
const startTime = new Date(iosSafeTimeStr);
// 校验时间有效性
if (isNaN(startTime.getTime())) {
console.error("无效的开始时间格式:", startTimeStr);
return "";
}
// 3. 计算结束时间(开始时间 + 服务分钟数)
const endTime = new Date(startTime.getTime() + serviceMinutes * 60 * 1000);
// 格式化年份YYYY年
const formatYear = (date) => {
return date.getFullYear() + '年';
};
// 格式化月份和日期MM月DD补零
const formatMonthDay = (date) => {
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
return `${month}月${day}`;
};
// 格式化时间部分HH:MM补零
const formatTimePart = (date) => {
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
return `${hours}:${minutes}`;
};
// 4. 判断是否同一天
const isSameDay = startTime.getFullYear() === endTime.getFullYear() &&
startTime.getMonth() === endTime.getMonth() &&
startTime.getDate() === endTime.getDate();
// 5. 拼接最终格式
if (isSameDay) {
// 同一天2025年05月29 12:30-13:30
return `${formatYear(startTime)}${formatMonthDay(startTime)} ${formatTimePart(startTime)}-${formatTimePart(endTime)}`;
} else {
// 跨天2025年05月29 12:30-2025年05月30 13:30
return `${formatYear(startTime)}${formatMonthDay(startTime)} ${formatTimePart(startTime)}-${formatYear(endTime)}${formatMonthDay(endTime)} ${formatTimePart(endTime)}`;
}
}
// 兜底如果start为空返回空字符串避免报错
return start ? formatTimeRange(start, server_time) : "";
},
stateText() {
const textList = [
"",
"待支付",
"待接单",
"待开始",
"待完成",
"已完成",
"已评价",
"已取消",
];
return textList[this.dataItem.state];
},
//获取拼团状态文字
getGroupType() {
let list = [{
id: 1,
text: "团购中",
},
{
id: 2,
text: "已成团",
},
{
id: 3,
text: "拼团失败",
},
];
let name = list.find((it) => it.id == this.dataItem.team_buy_order_state)?.text;
return name;
},
},
methods: {
// 触发取消事件
emitCancel() {
this.$emit("cancel");
},
// 触发接单事件
emitAccept() {
this.$emit("accept");
},
emitStart() {
this.$emit("start");
},
emitDone() {
this.$emit("done");
},
},
};
</script>
<style scoped lang="less">
.order-card {
padding: 20rpx 30rpx 10rpx 30rpx;
margin: 0rpx 30rpx 20rpx 30rpx;
background-color: #fff;
border-radius: 12px;
/* box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); */
position: relative;
}
/* 订单编号 */
.order-id {
width: 630rpx;
font-size: 28rpx;
color: #333333;
}
.orderNumBox {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 40rpx;
.stateText {
font-weight: 400;
font-size: 26rpx;
color: #FF4767;
text-align: left;
font-style: normal;
position: absolute;
right: 0;
top: 0;
background-image: url("/static/images/icons/tabBj.png");
background-size: 100% auto;
background-position: center top;
background-repeat: no-repeat;
width: 128rpx;
height: 49rpx;
display: flex;
align-items: center;
justify-content: center;
}
.stateText2 {
background-image: url("/static/images/icons/tabBj2.png");
color: #333;
}
.stateText3 {
background-image: url("/static/images/icons/tabBj2.png");
color: #999999 !important;
}
.rightArrow {
width: 12rpx;
height: 24rpx;
}
}
/* 服务信息容器 */
.service-container {
display: flex;
padding-bottom: 24rpx;
border-bottom: 1px solid #f6f5f5;
}
.noFotter {
border-bottom: none;
padding-bottom: 0rpx;
}
/* 服务图片 */
.service-img {
width: 172rpx;
height: 168rpx;
border-radius: 24rpx;
margin-right: 30rpx;
flex-shrink: 0;
}
/* 服务信息 */
.service-info {
display: flex;
flex-direction: column;
justify-content: space-between;
}
.service-price {
font-family: DINPro, DINPro;
font-weight: 500;
font-size: 24rpx;
color: #FF4767;
line-height: 34rpx;
text-align: left;
font-style: normal;
.service-price-line {
font-weight: 400;
font-size: 24rpx;
color: #999999;
line-height: 34rpx;
margin-left: 10rpx;
text-decoration: line-through;
}
}
.service-type {
width: 400rpx;
font-weight: 500;
font-size: 30rpx;
color: #333333;
line-height: 34rpx;
text-align: left;
font-style: normal;
display: flex;
align-items: center;
margin-bottom: 22rpx;
.service-name-type {
/* #ifdef APP-PLUS */
font-family: 'shuHeiTi';
/* #endif */
font-size: 24rpx;
color: #FFFFFF;
line-height: 27rpx;
letter-spacing: 2px;
text-align: left;
font-style: normal;
background: linear-gradient(166deg, #FC5E72 0%, #FF4767 100%);
border-radius: 6rpx;
padding: 4rpx 4rpx 4rpx 8rpx;
margin-right: 13rpx;
letter-spacing: 2rpx;
}
.service-name-text {
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.service-time {
font-weight: 400;
font-size: 26rpx;
color: #999999;
line-height: 33rpx;
text-align: left;
font-style: normal;
}
/* 时间信息 */
.time-info {
font-size: 30rpx;
color: #333;
margin-bottom: 10rpx;
margin-top: 28rpx;
display: flex;
align-items: center;
.time-info-img {
width: 40rpx;
height: 40rpx;
margin-right: 10rpx;
border-radius: 50%;
}
.time-info-name {
font-weight: 400;
font-size: 26rpx;
color: #333333;
line-height: 34rpx;
text-align: left;
font-style: normal;
margin-right: 20rpx;
max-width: 110rpx;
overflow: hidden;
word-break: break-all;
/* break-all(允许在单词内换行) */
text-overflow: ellipsis;
/* 超出部分省略号 */
display: -webkit-box;
/** 对象作为伸缩盒子模型显示 **/
-webkit-box-orient: vertical;
/** 设置或检索伸缩盒对象的子元素的排列方式 **/
-webkit-line-clamp: 1;
/** 显示的行数 **/
}
.time-info-text1 {
font-weight: 400;
font-size: 26rpx;
color: #999999;
line-height: 34rpx;
text-align: left;
font-style: normal;
// margin-right: 20rpx;
white-space: nowrap;
}
.time-info-text2 {
font-weight: 400;
font-size: 26rpx;
color: #333333;
line-height: 34rpx;
text-align: left;
font-style: normal;
}
}
/* 按钮组 */
.button-group {
display: flex;
justify-content: flex-end;
gap: 30rpx;
margin-bottom: 20rpx;
}
/* 通用按钮样式 */
.btn {
// width: 80rpx;
height: 32rpx;
border-radius: 64rpx;
font-size: 26rpx;
background-color: #fff;
white-space: nowrap;
margin-top: 40rpx;
}
/* 取消按钮 */
.cancel-btn {
border: 2rpx solid #979797;
color: #333333;
}
/* 接单按钮 */
.accept-btn {
border: 2rpx solid #FF4767;
color: #FF4767;
}
</style>