mrr.sj.front/pages/shop/workSpace/components/workSpaceCard.vue

456 lines
9.4 KiB
Vue

<template>
<view
class="manHourCard"
:key="index"
@touchstart="touchStart($event, index)"
@touchmove="touchMove"
@touchend="touchEnd"
@mousedown="mouseDown($event, index)"
@mousemove="mouseMove"
@mouseup="mouseUp"
@mouseleave="mouseUp"
>
<!-- 左滑删除按钮 -->
<view
class="delete-btn"
:style="{ transform: `translateX(${info.slideX || 0}rpx)` }"
@click.stop="$emit('deletemanHour',info)"
v-if="info.state == 0"
>
<text>删除</text>
</view>
<!-- 服务内容 -->
<view
class="manHour-content"
:style="{ transform: `translateX(${info.slideX || 0}rpx)` }"
>
<view class="top_info">
<!-- 服务图片 -->
<image
:src="photo && photo[0]"
mode="aspectFill"
class="manHour-image"
/>
<!-- 服务信息 -->
<view class="manHour-info">
<view class="manHourTop">
<view class="manHour-title white-space-nowrap">{{ info.title }}</view>
<view class="manHour-subtitle white-space-nowrap"
>使用场景:{{
info.first_class_title +
" " +
info.second_class_title.join("、")
}}
</view>
</view>
<view class="manHour-price">
<text class="price-symbol">¥</text>
<text class="price-value">{{ price }}</text>
<text class="price-unit">元\10分钟</text>
</view>
</view>
</view>
<!-- 状态标签 -->
<view :class="['status-tag', 'state' + info.state]">
<text class="status-text">{{
info.state == 0
? "草稿"
: info.state == 1
? "审核中"
: info.state == 2
? "已上架"
: info.state == 3
? "下架"
: info.state == 4
? "驳回"
: ""
}}</text>
</view>
<!-- 编辑按钮 -->
<view class="btns">
<view
class="view-btn"
@click="$emit('viewRemove', info)"
v-if="info.state == 2"
>
<text class="view-text">下架</text>
</view>
<view
class="view-btn"
@click="$emit('viewList', info)"
v-if="info.state == 3"
>
<text class="view-text">上架</text>
</view>
<view class="view-btn" @click="$emit('viewEdit', info)">
<text class="view-text">编辑</text>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: "manHourCard",
props: {
info: {
type: Object,
},
index: {
type: Number,
},
},
data() {
return {
currentIndex: "",
};
},
computed: {
photo() {
return JSON.parse(this.info.photo);
},
price() {
return Number(this.info.price);
},
},
methods: {
touchStart(e, index) {
if (this.info.state != 0) return;
// 阻止默认事件和冒泡
e.preventDefault();
e.stopPropagation();
// 获取触摸事件的坐标
if (e.touches && e.touches[0]) {
this.startX = e.touches[0].clientX;
this.currentIndex = index;
}
},
touchMove(e) {
if (this.info.state !== 0) return;
// 阻止默认事件和冒泡
e.preventDefault();
e.stopPropagation();
// 获取触摸事件的坐标
if (e.touches && e.touches[0]) {
this.moveX = e.touches[0].clientX - this.startX;
// 限制只能向左滑动
if (this.moveX > 0) {
this.moveX = 0;
}
// 限制最大滑动距离
if (this.moveX < -160) {
this.moveX = -160;
}
// 更新当前项的滑动状态
this.$emit("changeSlide", {
index: this.currentIndex,
slide: this.moveX,
});
}
},
touchEnd(e) {
if (this.info.state !== 0) return;
// 阻止默认事件和冒泡
e.preventDefault();
e.stopPropagation();
// 如果滑动距离超过一半,则完全展开
if (this.moveX < -80) {
this.$emit("changeSlide", { index: this.currentIndex, slide: -160 });
} else {
// 否则恢复原位
this.$emit("changeSlide", { index: this.currentIndex });
}
this.currentIndex = -1;
},
mouseDown(e, index) {
if (this.info.state !== 0) return;
// 阻止默认事件和冒泡
e.preventDefault();
e.stopPropagation();
this.startX = e.clientX;
this.currentIndex = index;
},
mouseMove(e) {
if (this.info.state !== 0) return;
// 阻止默认事件和冒泡
e.preventDefault();
e.stopPropagation();
this.moveX = e.clientX - this.startX;
// 限制只能向左滑动
if (this.moveX > 0) {
this.moveX = 0;
}
// 限制最大滑动距离
if (this.moveX < -160) {
this.moveX = -160;
}
// 更新当前项的滑动状态
this.$emit("changeSlide", {
index: this.currentIndex,
slide: this.moveX,
});
},
mouseUp(e) {
if (this.info.state !== 0) return;
// 阻止默认事件和冒泡
e.preventDefault();
e.stopPropagation();
// 如果滑动距离超过一半,则完全展开
if (this.moveX < -80) {
this.$emit("changeSlide", {
index: this.currentIndex,
slide: -160,
});
} else {
// 否则恢复原位
this.$emit("changeSlide", {
index: this.currentIndex,
});
}
this.currentIndex = -1;
},
},
};
</script>
<style lang="less" scoped>
.manHourCard {
// height: 248rpx;
position: relative;
background-color: #ffffff;
border-radius: 20rpx;
margin-bottom: 32rpx;
box-sizing: border-box;
overflow: hidden;
touch-action: pan-y pinch-zoom;
}
.manHourCard:last-child {
margin-bottom: 0;
}
.manHour-content {
width: 100%;
height: 100%;
padding: 24rpx;
box-sizing: border-box;
background-color: #ffffff;
transition: transform 0.3s ease;
position: relative;
z-index: 1;
display: flex;
flex-direction: column;
.top_info {
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-items: center;
width: 100%;
height: 100%;
margin-bottom: 30rpx;
border-bottom: 2rpx solid #f6f5f5;
padding-bottom: 24rpx;
}
.btns {
width: 100%;
display: flex;
justify-content: flex-end;
}
}
.delete-btn {
position: absolute;
right: -160rpx;
top: 0;
width: 160rpx;
height: 100%;
background-color: #E8101E;
color: #ffffff;
display: flex;
justify-content: center;
align-items: center;
font-size: 28rpx;
transition: transform 0.3s ease;
z-index: 2;
}
.manHourCard:active .manHour-content,
.manHourCard:active .delete-btn {
transform: none;
}
.manHour-image {
width: 200rpx;
height: 200rpx;
border-radius: 24rpx;
margin-right: 30rpx;
background-color: rgba(0, 0, 0, 0.05);
}
.manHour-info {
height: 200rpx;
width: 350rpx;
display: flex;
flex-flow: column nowrap;
justify-content: space-between;
align-items: flex-start;
}
.manHour-title {
font-size: 30rpx;
line-height: 30rpx;
color: #333333;
font-weight: 500;
padding-right: 20rpx;
margin-bottom: 20rpx;
}
.manHour-subtitle {
font-size: 26rpx;
line-height: 26rpx;
color: #666;
}
.manHour-price {
display: flex;
align-items: baseline;
font-weight: 500;
}
.price-symbol {
font-size: 30rpx;
color: #E8101E;
}
.price-value {
font-size: 30rpx;
color: #E8101E;
}
.price-unit {
font-size: 30rpx;
color: #E8101E;
}
.status-tag {
position: absolute;
top: 0rpx;
right: 0rpx;
border-radius: 0 0 0 20rpx;
line-height: 38rpx;
text-align: center;
box-sizing: border-box;
font-size: 24rpx;
padding: 10rpx 18rpx;
}
/* 已上架 */
.status-tag.state2 {
background-color: rgba(252, 67, 124, 0.15);
}
.status-tag.state2 .status-text {
font-weight: 400;
font-size: 26rpx;
color: #E8101E;
line-height: 37rpx;
text-align: left;
font-style: normal;
}
/* 审核中 */
.status-tag.state1 {
background-color: rgba(40, 209, 137, 0.2);
}
.status-tag.state1 .status-text {
color: #28d189;
}
/* 草稿/撤回 */
.status-tag.state0,
.status-tag.state3,
.status-tag.state4 {
background-color: rgba(209, 15, 19, 0.2);
}
.status-tag.state0 .status-text,
.status-tag.state3 .status-text,
.status-tag.state4 .status-text {
color: #d10f13;
}
.view-btn {
display: flex;
align-items: center;
justify-content: center;
margin-left: 39rpx;
width: 160rpx;
height: 64rpx;
border-radius: 64rpx;
border: 2rpx solid #979797;
}
.view-icon {
width: 32rpx;
height: 32rpx;
margin-right: 8rpx;
}
.view-text {
font-size: 26rpx;
color: #333333;
}
.load-more {
text-align: center;
padding: 20rpx 0;
color: #999999;
font-size: 24rpx;
}
.manHourCard {
cursor: pointer;
user-select: none;
-webkit-user-select: none;
}
.manHour-content,
.delete-btn {
will-change: transform;
}
.add-btn {
height: 140rpx;
}
/* 平台特定样式 */
/* #ifdef H5 */
.manHour-container {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
/* #endif */
/* #ifdef APP-PLUS */
.manHour-image {
border: 1rpx solid #eeeeee;
}
/* #endif */
/* #ifdef MP-WEIXIN */
.manHourCard {
/* 小程序阴影效果 */
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
}
/* #endif */
</style>