智慧教务系统UniApp前端项目(使用中2025-0517)
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

<!--教练服务详情页-->
<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>