796 lines
18 KiB
Vue
Raw Normal View History

2025-04-01 09:03:51 +08:00
<template>
<view class="box flex flex-column align-items">
<view class="first flex align-items">
<image :src="avatar" mode="" style="width: 120rpx;height: 120rpx;border-radius: 50%;"></image>
<view class="flex flex-column" style="margin-left: 18rpx;">
<span class="nick"> {{nickNmae}}</span>
<span class="name">姓名{{name}}</span>
<span class="tel">联系电话{{tel}}</span>
</view>
</view>
<view class="header flex align-items">
<view class=" left flex align-items">
<image :src="header.detail.headimage" mode="" style="width: 200rpx; height: 140rpx;"></image>
<view class="flex flex-column justify-center" style="margin-left: 24rpx;align-items: left;">
<span class="title white-space">{{header.detail.title}}</span>
<span class="shengyu hui" style="margin: 13rpx 0 8rpx 0;">剩余课时
{{header.detail.sub_num}}/{{header.detail.classes_num}}</span>
<span class="yuyue hui">预约课时 {{header.detail.use_num}}</span>
</view>
</view>
<view class="right flex flex-column align-items justify-center" @click="openShow()">
<image src="../../static/my/add.png" mode="" style="width: 64rpx; height: 64rpx;"></image>
<span>加入课程</span>
</view>
</view>
<view class="center flex flex-column align-items">
<view class="centerBox flex align-items space-around" v-for="(item,index) in list" :key="index"
@click="selectItem(index,item)" :class="{ selected: selectedIndex === index }">
<view class="left">
<image
:src="selectedIndex === index ? '../../static/my/selected.png' : '../../static/my/select.png'"
mode="" style="width: 42rpx;height: 42rpx;"></image>
</view>
<view class="right flex flex-column">
<span class="title white-space">{{item.detail.title}}</span>
<span class="number">订单编号:{{item.order_no}}</span>
<span class="number" style="margin: 8rpx 0;">预约时间:{{item.reservation_time_text}}</span>
<span class="number">上课时间:{{item.start_time_text}}</span>
<span class="line-row"></span>
<view class="center-footer">
<span class="edit flex justify-center align-items" @click="edit(item.order_no)">修改</span>
<span class="del flex justify-center align-items" @click="del(item.order_no)">删除</span>
</view>
</view>
</view>
</view>
<view class="footer flex justify-center align-items">
<span class="flex justify-center align-items" @click="confirm()">确认核销</span>
</view>
<!-- 课程时间 -->
<u-popup :show="show" mode="bottom" :round="10" :zIndex="99999" :custom-style="popupStyle" @close="close"
@open="open">
<view class="popupBox flex justify-start align-items flex-column">
<view class="pop-header flex align-items" style="justify-content: space-between;">
<span class="selectTime">选择时间</span>
<span class="quxiao" @click="cancel">取消选择</span>
</view>
<!-- <span class="line"></span> -->
<view class="times flex align-items justify-center" style="flex-wrap: wrap;">
<span class="selectTime flex justify-center align-items" v-for="(item,index) in timeList"
:key="index" :class="{ selected: timeSelected(item) }" @click="selectTime(item)">
{{item.name}}</span>
</view>
<view class="pos flex justify-center align-items">
<span class="flex justify-center align-items" @click="addTime()" v-if="type == 0">添加课时</span>
<span class="flex justify-center align-items" @click="editTime()" v-if="type == 1">修改课时</span>
</view>
</view>
</u-popup>
</view>
</template>
<script>
export default {
data() {
return {
scanResult: '',
header: {},
list: [],
nickNmae:'',
name:'',
tel:'',
avatar:'',
page: 1,
limit: 10,
status: '-1,0',
selectedIndex: 0, // 默认选中第一个
popupStyle: {
// bottom: '166rpx',
width: '100%',
margin: '0 auto', // 水平居中
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
},
timeList: [],
listOrder_no:'',
order_no: '',
type: 0,
classes_lib_spec_id: '',
show: false,
selectedTime: null
};
},
onLoad(options) {
// 从 options 中获取传递的参数
if (options.res) {
this.scanResult = this.parseQuery(decodeURIComponent(options.res));
console.log('接收到的扫码结果:', this.scanResult);
this.getHeader(this.scanResult.vcode)
}
this.nickNmae = uni.getStorageSync('niName')
this.name = uni.getStorageSync('userInfo').realname
this.tel = uni.getStorageSync('userInfo').mobile
this.avatar = uni.getStorageSync('userInfo').avatar
},
methods: {
selectItem(index,item) {
this.selectedIndex = index;
this.listOrder_no = item.order_no
console.log(this.listOrder_no)
},
// 取消选择
cancel() {
this.selectedTime = null
},
// 删除
del(order_no){
uni.$u.http.post('/api/school/worker/hour_order/cancel', {
order_no : order_no
}).then(res => {
if (res.code == 1) {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
this.getHeader(this.scanResult.vcode)
this.getList()
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
}
}).catch(error => {
uni.showToast({
title: '请求失败,请稍后再试',
icon: 'none',
duration: 2000
});
});
},
// 确认核销
confirm(){
if (this.listOrder_no) {
uni.$u.http.post('/api/school/worker/hour_order/verification', {
order_no : this.listOrder_no
}).then(res => {
if (res.code == 1) {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
this.getList()
this.getHeader(this.scanResult.vcode)
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
}
}).catch(error => {
uni.showToast({
title: '请求失败,请稍后再试',
icon: 'none',
duration: 2000
});
});
} else{
uni.showToast({
title: '请选择课时',
icon: 'none',
duration: 2000
});
}
},
// 获取课时规格
getTime() {
this.show = true
uni.$u.http.get('/api/school/classes/spec', {
params: {
id: this.header.classes_lib_id,
}
}).then(res => {
if (res.code == 1) {
this.timeList = res.data.spec;
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
}
}).catch(error => {
uni.showToast({
title: '请求失败,请稍后再试',
icon: 'none',
duration: 2000
});
});
},
selectTime(time) {
this.selectedTime = time;
this.classes_lib_spec_id = time.id
},
// 修改课时
edit(order_no){
this.type = 1
this.getTime()
},
// 弹窗
openShow(){
this.type = 0
this.getTime()
},
// 修改课时
editTime(){
uni.$u.http.post('/api/school/worker/hour_order/update_spec', {
classes_lib_spec_id: this.classes_lib_spec_id,
order_no: this.listOrder_no,
}).then(res => {
if (res.code == 1) {
this.show = false
uni.showToast({
title: '修改成功',
icon: 'none',
duration: 2000
})
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
// _this.$api.toast(res.msg);
}
}).catch(error => {
});
},
// 添加课时
addTime(){
uni.$u.http.post('/api/school/worker/hour_order/confirm', {
classes_order_id: this.header.detail.classes_order_id,
classes_lib_spec_id: this.classes_lib_spec_id,
order_no: '',
is_compute: 1
}).then(res => {
if (res.code == 1) {
this.timeCreat(res.data.order_no)
this.getHeader(this.scanResult.vcode)
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
// _this.$api.toast(res.msg);
}
}).catch(error => {
});
},
// 预约下单
timeCreat(order_no) {
uni.$u.http.post('/api/school/worker/hour_order/create', {
order_no: order_no,
}).then(res => {
if (res.code == 1) {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
this.show = false
this.order_no = ''
this.getList()
this.getHeader(this.scanResult.vcode)
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
}
}).catch(error => {
});
},
timeSelected(time) {
return this.selectedTime === time;
},
open() {
},
close() {
this.type = 0
this.selectedTime = null
this.show = false
},
// 数据转换
parseQuery(queryString) {
const query = {};
const pairs = queryString.split('&');
for (let pair of pairs) {
const [key, value] = pair.split('=');
query[key] = value;
}
return query;
},
// 获取头部信息
getHeader(vcode) {
uni.$u.http.get('/api/school/worker/order/detail', {
params: {
id: vcode,
}
}).then(res => {
if (res.code == 1) {
this.header = res.data.detail
this.order_no = res.data.detail.order_no
if (res.data.detail) {
this.getList()
}
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000,
complete: function() {
setTimeout(function() {
uni.navigateBack(1)
}, 2000);
}
});
}
}).catch(error => {
uni.showToast({
title: '请求失败,请稍后再试',
icon: 'none',
duration: 2000
});
});
},
// 获取列表
getList() {
uni.$u.http.get('/api/school/worker/hour_order/order_list', {
params: {
classes_order_id: this.header.detail.classes_order_id,
page: this.page,
limit: this.limit,
status: this.status
}
}).then(res => {
if (res.code == 1) {
this.list = res.data.list
this.listOrder_no = res.data.list[0]?.order_no
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
}
}).catch(error => {
uni.showToast({
title: '请求失败,请稍后再试',
icon: 'none',
duration: 2000
});
});
}
},
}
</script>
<style lang="scss" scoped>
.w-100 {
width: 100%;
}
.flex {
display: flex;
}
.justify-center {
justify-content: center;
}
.space-between {
justify-content: space-between;
}
.align-items {
align-items: center;
}
.space-around {
justify-content: space-around;
}
.flex-column {
flex-flow: column;
}
.justify-start {
justify-content: start;
}
.mar-top-30 {
margin-top: 30rpx;
}
.white-space {
overflow: hidden;
/* 确保超出容器的文本被隐藏 */
white-space: nowrap;
/* 确保文本在一行内显示 */
text-overflow: ellipsis;
/* 使用省略号表示被截断的文本 */
width: 100%;
}
.box {
background-color: #F1F2F8;
height: 100vh;
}
.hui {
font-family: PingFang SC, PingFang SC;
font-weight: 500;
font-size: 24rpx;
color: #7A7A7A;
}
.first{
width: 696rpx;
height: 196rpx;
background: #FFFFFF;
padding: 0 26rpx 0 30rpx;
border-bottom: 1rpx solid #D9D9D9;;
.nick{
font-family: PingFang SC, PingFang SC;
font-weight: 800;
font-size: 34rpx;
color: #181818;
}
.name{
font-family: PingFang SC, PingFang SC;
font-weight: 500;
font-size: 24rpx;
color: #7A7A7A;
margin: 12rpx 0 8rpx 0;
}
.tel{
font-family: PingFang SC, PingFang SC;
font-weight: 500;
font-size: 24rpx;
color: #7A7A7A;
}
}
.header {
width: 696rpx;
height: 196rpx;
background: #FFFFFF;
justify-content: space-between;
padding: 0 26rpx 0 30rpx;
.left {
.title {
width: 192rpx;
height: 32rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 800;
font-size: 32rpx;
color: #343434;
line-height: 32rpx;
}
}
.right {
span {
font-family: PingFang SC, PingFang SC;
font-weight: 500;
font-size: 24rpx;
color: #9E9E9E;
}
}
}
.center {
width: 750rpx;
.centerBox {
background-color: #FFFFFF;
width: 690rpx;
height: 261rpx;
margin-top: 24rpx;
.right {
.title {
width: 256rpx;
height: 32rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 800;
font-size: 32rpx;
color: #7A7A7A;
line-height: 32rpx;
margin-bottom: 14rpx;
}
.number {
height: 32rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
font-size: 26rpx;
color: #7A7A7A;
}
.line-row {
width: 570rpx;
height: 1rpx;
background: #D9D9D9;
margin: 8rpx 0 12rpx 0;
}
.center-footer {
display: flex;
align-items: center;
justify-content: flex-end;
.edit {
width: 100rpx;
height: 48rpx;
border-radius: 12rpx 12rpx 12rpx 12rpx;
border: 2rpx solid #008CFF;
font-family: PingFang SC, PingFang SC;
font-weight: 800;
font-size: 24rpx;
color: #008CFF;
margin-right: 24rpx;
}
.del {
width: 100rpx;
height: 48rpx;
background: #008CFF;
border-radius: 12rpx 12rpx 12rpx 12rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 800;
font-size: 24rpx;
color: #FFFFFF;
}
}
}
}
}
.footer {
width: 750rpx;
height: 122rpx;
background: #F1F2F8;
position: fixed;
bottom: 0;
span {
width: 642rpx;
height: 80rpx;
background: #008CFF;
border-radius: 401rpx 401rpx 401rpx 401rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 800;
font-size: 34rpx;
color: #FFFFFF;
line-height: 32rpx;
letter-spacing: 14px;
}
}
.center .centerBox:last-child {
margin-bottom: 122rpx;
}
.popupBox {
height: 572rpx;
width: 750rpx;
position: relative;
.pos {
position: absolute;
bottom: 0;
width: 750rpx;
height: 122rpx;
background: #FFFFFF;
box-shadow: 0rpx -6rpx 12rpx 0rpx rgba(111, 190, 255, 0.1);
position: fixed;
bottom: 0;
span {
width: 642rpx;
height: 80rpx;
background: #008CFF;
border-radius: 401rpx 401rpx 401rpx 401rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 800;
font-size: 34rpx;
color: #FFFFFF;
line-height: 32rpx;
letter-spacing: 14px;
}
}
.pop-header {
width: 93%;
padding-top: 32rpx;
padding-bottom: 17rpx;
border-bottom: 2rpx solid #D9D9D9;
.selectTime{
width: 168rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 800;
font-size: 42rpx;
color: #008CFF;
}
.quxiao{
font-family: PingFang SC, PingFang SC;
font-weight: 400;
font-size: 20rpx;
color: #343434;
}
}
.popup {
display: flex;
align-items: self-start;
justify-content: center;
padding-top: 21rpx;
.popur-right {
align-items: self-start;
margin-left: 24rpx;
width: 418rpx;
.name {
font-family: PingFang SC, PingFang SC;
font-weight: 800;
font-size: 28rpx;
color: #343434;
}
.address {
font-family: PingFang SC, PingFang SC;
font-weight: 500;
font-size: 24rpx;
color: #7A7A7A;
line-height: 32rpx;
margin: 16rpx 0 12rpx 0;
overflow: hidden;
/* 确保超出容器的文本被隐藏 */
white-space: nowrap;
/* 确保文本在一行内显示 */
text-overflow: ellipsis;
/* 使用省略号表示被截断的文本 */
width: 100%;
}
.date {
font-family: PingFang SC, PingFang SC;
font-weight: 500;
font-size: 24rpx;
color: #7A7A7A;
line-height: 32rpx;
}
.time {
margin: 12rpx 0 73rpx 0;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
font-size: 24rpx;
color: #7A7A7A;
line-height: 32rpx;
}
.line-row {
width: 418rpx;
height: 1rpx;
background: #008CFF;
border-radius: 0rpx 0rpx 0rpx 0rpx;
}
.price {
font-family: PingFang SC, PingFang SC;
font-weight: 500;
font-size: 24rpx;
color: #7A7A7A;
line-height: 32rpx;
margin-top: 23rpx;
align-self: flex-end;
span {
font-family: PingFang SC, PingFang SC;
font-weight: 800;
font-size: 36rpx;
color: #FF2323;
line-height: 32rpx;
}
}
}
}
.line {
width: 642rpx;
height: 1rpx;
background: #D9D9D9;
box-shadow: 1rpx 1rpx 0rpx 0rpx rgba(102, 102, 102, 0.25);
border-radius: 0rpx 0rpx 0rpx 0rpx;
}
.times {
width: 93%;
.selectTime {
width: 288rpx;
height: 50rpx;
background: #FFFFFF;
border-radius: 12rpx 12rpx 12rpx 12rpx;
border: 1rpx solid #D9D9D9;
color: #4B4B4B;
font-family: 'PingFang SC', 'PingFang SC';
font-weight: 500;
font-size: 24rpx;
padding-left: 15rpx;
cursor: pointer;
margin: 24rpx 32rpx 0 0;
white-space: nowrap;
/* 防止文本换行 */
text-overflow: ellipsis;
/* 超出部分显示省略号 */
overflow: hidden;
/* 隐藏超出部分 */
text-align: left;
/* 文字靠左对齐 */
line-height: 50rpx;
/* 垂直居中对齐 */
box-sizing: border-box;
/* 确保 padding 和 border 不影响宽度和高度 */
display: inline-block;
/* 确保容器内文字正确对齐 */
}
}
.selectTime.selected {
width: 288rpx;
height: 50rpx;
border-radius: 12rpx 12rpx 12rpx 12rpx;
background: #008CFF;
font-family: PingFang SC, PingFang SC;
font-weight: 800;
font-size: 24rpx;
color: #FFFFFF;
cursor: pointer;
margin: 24rpx 32rpx 0 0;
}
}
</style>