You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
625 lines
16 KiB
625 lines
16 KiB
<!--教练服务详情页-->
|
|
<template>
|
|
<view class="container">
|
|
<!-- 如果没有指定ID,显示服务列表 -->
|
|
<view class="content" v-if="!id">
|
|
<view class="service-list">
|
|
<view class="section-title">我的服务列表</view>
|
|
<view class="empty-list" v-if="serviceList.length === 0">
|
|
<text>暂无服务记录</text>
|
|
</view>
|
|
<view class="service-item" v-for="(item, index) in serviceList" :key="index" @click="viewServiceDetail(item.id)">
|
|
<view class="service-header">
|
|
<view class="user-info">
|
|
<image class="user-avatar" src="/static/icon-img/avatar.png"></image>
|
|
<text class="user-name">{{item.service_id}} {{item.resource_id}}</text>
|
|
</view>
|
|
</view>
|
|
<view class="service-content">
|
|
<view class="info-row">
|
|
<text class="info-label">所属校区:</text>
|
|
<text class="info-value">{{item.campus || '总部校区'}}</text>
|
|
</view>
|
|
<view class="info-row">
|
|
<text class="info-label">来源:</text>
|
|
<text class="info-value">{{item.source || '线上'}}</text>
|
|
</view>
|
|
<view class="info-row">
|
|
<text class="info-label">来源渠道:</text>
|
|
<text class="info-value">{{item.channel || '地推'}}</text>
|
|
</view>
|
|
</view>
|
|
<view class="service-footer">
|
|
<text class="contact-status">暂未联系</text>
|
|
<view class="effective-status" :class="{'status-yes': item.status === 1}">
|
|
是否有效: {{item.status === 1 ? '有效' : '无效'}}
|
|
<view class="status-dot" :class="{'dot-yes': item.status === 1}"></view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 如果指定了ID,显示服务详情 -->
|
|
<view class="content detail-content" v-else-if="serviceInfo">
|
|
<view class="service-detail-card">
|
|
<view class="detail-header">
|
|
<view class="user-info">
|
|
<image class="user-avatar" src="/static/icon-img/avatar.png"></image>
|
|
<text class="user-name">{{serviceInfo.service_id}}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="detail-content">
|
|
<view class="card-section">
|
|
<view class="section-title">基本信息</view>
|
|
<view class="info-card">
|
|
<view class="info-item">
|
|
<text class="item-label">服务内容</text>
|
|
<text class="item-value">{{serviceInfo.id}}</text>
|
|
</view>
|
|
<view class="info-item">
|
|
<text class="item-label">学员姓名</text>
|
|
<text class="item-value">{{serviceInfo.resource_id}}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="card-section">
|
|
<view class="section-title">服务详情</view>
|
|
<view class="info-card">
|
|
<view class="info-item">
|
|
<text class="item-label">服务备注</text>
|
|
<text class="item-value">{{serviceInfo.service_remark || '暂无备注'}}</text>
|
|
</view>
|
|
<view class="info-item">
|
|
<text class="item-label">服务状态</text>
|
|
<text class="item-value" :class="{'status-completed': serviceInfo.status === 1}">
|
|
{{serviceInfo.status === 1 ? '已完成服务' : '待完成服务'}}
|
|
</text>
|
|
</view>
|
|
<view class="info-item">
|
|
<text class="item-label">服务人员ID</text>
|
|
<text class="item-value">{{serviceInfo.staff_id}}</text>
|
|
</view>
|
|
<view class="info-item">
|
|
<text class="item-label">评分</text>
|
|
<view class="score-box">
|
|
<view class="star-box">
|
|
<uni-icons v-for="i in 5" :key="i" :type="i <= serviceInfo.score ? 'star-filled' : 'star'" size="18" color="#FFB800"></uni-icons>
|
|
</view>
|
|
<text class="score-value">{{serviceInfo.score}}分</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="card-section">
|
|
<view class="section-title">用户反馈</view>
|
|
<view class="info-card">
|
|
<view class="feedback-content" v-if="serviceInfo.feedback">
|
|
<text>{{serviceInfo.feedback}}</text>
|
|
</view>
|
|
<view class="empty-feedback" v-else>
|
|
<text>暂无用户反馈</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="card-section">
|
|
<view class="section-title">时间信息</view>
|
|
<view class="info-card">
|
|
<view class="info-item">
|
|
<text class="item-label">创建时间</text>
|
|
<text class="item-value">{{formatTime(serviceInfo.created_at)}}</text>
|
|
</view>
|
|
<view class="info-item">
|
|
<text class="item-label">反馈时间</text>
|
|
<text class="item-value">{{formatTime(serviceInfo.feedback_time)}}</text>
|
|
</view>
|
|
<view class="info-item">
|
|
<text class="item-label">更新时间</text>
|
|
<text class="item-value">{{formatTime(serviceInfo.updated_at)}}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="detail-footer" v-if="serviceInfo.status !== 1">
|
|
<button class="btn primary" @click="completeService">完成服务</button>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view v-else class="loading-box">
|
|
<text>加载中...</text>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import apiRoute from '@/api/apiRoute.js';
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
id: null,
|
|
serviceInfo: null,
|
|
serviceList: []
|
|
}
|
|
},
|
|
onLoad(options) {
|
|
if (options.id) {
|
|
this.id = options.id;
|
|
this.getServiceDetail();
|
|
} else {
|
|
this.getServiceList();
|
|
}
|
|
},
|
|
methods: {
|
|
navigateBack() {
|
|
uni.navigateBack();
|
|
},
|
|
async getServiceList() {
|
|
try {
|
|
// 接口未开发,使用模拟数据
|
|
// const res = await apiRoute.getServiceList();
|
|
// if(res.code == 1) {
|
|
// this.serviceList = res.data || [];
|
|
// } else {
|
|
// uni.showToast({
|
|
// title: res.msg || '获取服务列表失败',
|
|
// icon: 'none'
|
|
// });
|
|
// }
|
|
|
|
// 使用模拟数据
|
|
setTimeout(() => {
|
|
this.serviceList = [
|
|
{
|
|
id: '1',
|
|
resource_id: '美团用户1',
|
|
course_id: '2001',
|
|
service_id: '18645873651',
|
|
service_remark: '针对学员英语口语发音进行专项辅导',
|
|
status: 1,
|
|
staff_id: '3001',
|
|
score: 4,
|
|
feedback: '老师很耐心,讲解很清楚,孩子进步很大',
|
|
created_at: '2023-10-15 14:30:00',
|
|
feedback_time: '2023-10-16 18:20:00',
|
|
updated_at: '2023-10-16 18:20:00',
|
|
campus: '总部校区',
|
|
source: '线上',
|
|
channel: '地推'
|
|
},
|
|
{
|
|
id: '2',
|
|
resource_id: '李柏辉',
|
|
course_id: '2002',
|
|
service_id: '13876337043',
|
|
service_remark: '解答家长关于课程安排的问题',
|
|
status: 0,
|
|
staff_id: '3001',
|
|
score: 0,
|
|
feedback: '',
|
|
created_at: '2023-10-18 09:15:00',
|
|
feedback_time: '',
|
|
updated_at: '2023-10-18 09:15:00',
|
|
campus: '西区校区',
|
|
source: '地推',
|
|
channel: ''
|
|
},
|
|
{
|
|
id: '3',
|
|
resource_id: '张小明',
|
|
course_id: '2003',
|
|
service_id: '13912345678',
|
|
service_remark: '为学员制定个性化学习计划',
|
|
status: 0,
|
|
staff_id: '3001',
|
|
score: 0,
|
|
feedback: '',
|
|
created_at: '2023-10-20 16:45:00',
|
|
feedback_time: '',
|
|
updated_at: '2023-10-20 16:45:00',
|
|
campus: '东区校区',
|
|
source: '线下',
|
|
channel: '朋友介绍'
|
|
}
|
|
];
|
|
}, 500);
|
|
} catch(error) {
|
|
console.error('获取服务列表失败:', error);
|
|
uni.showToast({
|
|
title: '获取服务列表失败',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
},
|
|
async getServiceDetail() {
|
|
try {
|
|
// 接口未开发,使用模拟数据
|
|
const res = await apiRoute.getServiceDetail({id: this.id});
|
|
if(res.code == 1) {
|
|
this.serviceInfo = res.data || null;
|
|
} else {
|
|
uni.showToast({
|
|
title: res.msg || '获取服务详情失败',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
|
|
// 使用模拟数据
|
|
// setTimeout(() => {
|
|
// // 模拟数据库
|
|
// const mockServices = {
|
|
// '1': {
|
|
// id: '1',
|
|
// resource_id: '美团用户1',
|
|
// course_id: '2001',
|
|
// service_id: '18645873651',
|
|
// service_remark: '针对学员英语口语发音进行专项辅导',
|
|
// status: 1,
|
|
// staff_id: '3001',
|
|
// score: 4,
|
|
// feedback: '老师很耐心,讲解很清楚,孩子进步很大',
|
|
// created_at: '2023-10-15 14:30:00',
|
|
// feedback_time: '2023-10-16 18:20:00',
|
|
// updated_at: '2023-10-16 18:20:00',
|
|
// campus: '总部校区',
|
|
// source: '线上',
|
|
// channel: '地推'
|
|
// },
|
|
// '2': {
|
|
// id: '2',
|
|
// resource_id: '李柏辉',
|
|
// course_id: '2002',
|
|
// service_id: '13876337043',
|
|
// service_remark: '解答家长关于课程安排的问题',
|
|
// status: 0,
|
|
// staff_id: '3001',
|
|
// score: 0,
|
|
// feedback: '',
|
|
// created_at: '2023-10-18 09:15:00',
|
|
// feedback_time: '',
|
|
// updated_at: '2023-10-18 09:15:00',
|
|
// campus: '西区校区',
|
|
// source: '地推',
|
|
// channel: ''
|
|
// },
|
|
// '3': {
|
|
// id: '3',
|
|
// resource_id: '张小明',
|
|
// course_id: '2003',
|
|
// service_id: '13912345678',
|
|
// service_remark: '为学员制定个性化学习计划',
|
|
// status: 0,
|
|
// staff_id: '3001',
|
|
// score: 0,
|
|
// feedback: '',
|
|
// created_at: '2023-10-20 16:45:00',
|
|
// feedback_time: '',
|
|
// updated_at: '2023-10-20 16:45:00',
|
|
// campus: '东区校区',
|
|
// source: '线下',
|
|
// channel: '朋友介绍'
|
|
// }
|
|
// };
|
|
|
|
// 根据ID获取对应服务详情
|
|
// this.serviceInfo = mockServices[this.id] || null;
|
|
|
|
if (!this.serviceInfo) {
|
|
uni.showToast({
|
|
title: '未找到服务详情',
|
|
icon: 'none'
|
|
});
|
|
setTimeout(() => {
|
|
this.navigateBack();
|
|
}, 1500);
|
|
}
|
|
// }, 500);
|
|
} catch(error) {
|
|
console.error('获取服务详情失败:', error);
|
|
uni.showToast({
|
|
title: '获取服务详情失败',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
},
|
|
formatTime(timeStr) {
|
|
if (!timeStr) return '暂无';
|
|
return timeStr;
|
|
},
|
|
viewServiceDetail(id) {
|
|
uni.navigateTo({
|
|
url: `/pages/coach/my/service_detail?id=${id}`
|
|
});
|
|
},
|
|
async completeService() {
|
|
uni.showModal({
|
|
title: '确认完成',
|
|
content: '确定要将此服务标记为已完成吗?',
|
|
success: async (res) => {
|
|
if (res.confirm) {
|
|
try {
|
|
// 接口未开发,使用模拟数据
|
|
// const result = await apiRoute.completeService({id: this.id});
|
|
// if(result.code == 1) {
|
|
// this.serviceInfo.status = 1;
|
|
// uni.showToast({
|
|
// title: '服务已完成',
|
|
// icon: 'success'
|
|
// });
|
|
// } else {
|
|
// uni.showToast({
|
|
// title: result.msg || '操作失败',
|
|
// icon: 'none'
|
|
// });
|
|
// }
|
|
|
|
// 模拟API调用
|
|
setTimeout(() => {
|
|
this.serviceInfo.status = 1;
|
|
uni.showToast({
|
|
title: '服务已完成',
|
|
icon: 'success'
|
|
});
|
|
}, 500);
|
|
} catch(error) {
|
|
console.error('完成服务失败:', error);
|
|
uni.showToast({
|
|
title: '操作失败',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.container {
|
|
min-height: 100vh;
|
|
height: 100vh;
|
|
background-color: #292929;
|
|
padding-bottom: 120rpx;
|
|
position: relative;
|
|
box-sizing: border-box;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.content {
|
|
padding: 20rpx;
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.detail-content {
|
|
padding: 0;
|
|
}
|
|
|
|
.section-title {
|
|
font-size: 30rpx;
|
|
font-weight: bold;
|
|
color: #FFFFFF;
|
|
margin-bottom: 20rpx;
|
|
padding-left: 10rpx;
|
|
}
|
|
|
|
.service-list {
|
|
padding-bottom: 30rpx;
|
|
}
|
|
|
|
.service-item {
|
|
background-color: #333;
|
|
border-radius: 12rpx;
|
|
padding: 20rpx;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.service-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.user-info {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.user-avatar {
|
|
width: 60rpx;
|
|
height: 60rpx;
|
|
border-radius: 50%;
|
|
margin-right: 15rpx;
|
|
background-color: #29D3B4;
|
|
}
|
|
|
|
.user-name {
|
|
color: #fff;
|
|
font-size: 30rpx;
|
|
}
|
|
|
|
.service-content {
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.info-row {
|
|
display: flex;
|
|
margin-bottom: 10rpx;
|
|
font-size: 28rpx;
|
|
color: #ccc;
|
|
}
|
|
|
|
.info-label {
|
|
color: #999;
|
|
margin-right: 10rpx;
|
|
}
|
|
|
|
.info-value {
|
|
color: #fff;
|
|
}
|
|
|
|
.service-footer {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
border-top: 1px solid #444;
|
|
padding-top: 15rpx;
|
|
font-size: 26rpx;
|
|
}
|
|
|
|
.contact-status {
|
|
color: #999;
|
|
}
|
|
|
|
.effective-status {
|
|
color: #ff6b6b;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.status-yes {
|
|
color: #29D3B4;
|
|
}
|
|
|
|
.status-dot {
|
|
width: 16rpx;
|
|
height: 16rpx;
|
|
border-radius: 50%;
|
|
background-color: #ff6b6b;
|
|
margin-left: 10rpx;
|
|
}
|
|
|
|
.dot-yes {
|
|
background-color: #29D3B4;
|
|
}
|
|
|
|
.service-detail-card {
|
|
background-color: #333;
|
|
margin: 20rpx;
|
|
border-radius: 12rpx;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.detail-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 30rpx 20rpx;
|
|
border-bottom: 1px solid #444;
|
|
}
|
|
|
|
.detail-content {
|
|
padding: 30rpx 20rpx;
|
|
}
|
|
|
|
.card-section {
|
|
margin-bottom: 30rpx;
|
|
}
|
|
|
|
.info-card {
|
|
background-color: #3a3a3a;
|
|
border-radius: 12rpx;
|
|
padding: 20rpx;
|
|
}
|
|
|
|
.info-item {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 20rpx 10rpx;
|
|
border-bottom: 1rpx solid #444;
|
|
}
|
|
|
|
.info-item:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.item-label {
|
|
color: #999;
|
|
font-size: 28rpx;
|
|
}
|
|
|
|
.item-value {
|
|
color: #fff;
|
|
font-size: 28rpx;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.score-box {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.star-box {
|
|
display: flex;
|
|
margin-right: 10rpx;
|
|
}
|
|
|
|
.score-value {
|
|
color: #FFB800;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.feedback-content {
|
|
padding: 20rpx 10rpx;
|
|
font-size: 28rpx;
|
|
color: #fff;
|
|
line-height: 1.6;
|
|
}
|
|
|
|
.empty-feedback {
|
|
padding: 40rpx 0;
|
|
text-align: center;
|
|
color: #999;
|
|
font-size: 28rpx;
|
|
}
|
|
|
|
.detail-footer {
|
|
padding: 20rpx;
|
|
border-top: 1px solid #444;
|
|
}
|
|
|
|
.btn {
|
|
height: 80rpx;
|
|
line-height: 80rpx;
|
|
border-radius: 40rpx;
|
|
font-size: 30rpx;
|
|
margin-bottom: 20rpx;
|
|
background-color: transparent;
|
|
}
|
|
|
|
.primary {
|
|
background-color: #29D3B4;
|
|
color: #FFFFFF;
|
|
}
|
|
|
|
.loading-box {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
height: 300rpx;
|
|
color: #999;
|
|
}
|
|
|
|
.empty-list {
|
|
padding: 60rpx 0;
|
|
text-align: center;
|
|
color: #999;
|
|
font-size: 28rpx;
|
|
background-color: #333;
|
|
border-radius: 12rpx;
|
|
}
|
|
|
|
.status-completed {
|
|
color: #29D3B4;
|
|
}
|
|
</style>
|