Browse Source

我的培训

ouyj 3 weeks ago
parent
commit
67d8222ef2
6 changed files with 1069 additions and 0 deletions
  1. 45 0
      api/train.js
  2. 21 0
      pages.json
  3. 365 0
      pages/mine/train/trainAssess.vue
  4. 276 0
      pages/mine/train/trainDetail.vue
  5. 351 0
      pages/mine/train/trainList.vue
  6. 11 0
      pages/tabbar-mine/index.vue

+ 45 - 0
api/train.js

@@ -0,0 +1,45 @@
+import request from '@/utils/request.js'
+
+const preUrl = '/clientServices.do?iscrypt=1'
+
+/**
+ * 获取我的培训列表
+ */
+export function getMyTrainList(params) {
+	return request({
+		url: preUrl,
+		method: 'post',
+		data: {
+			serviceId: 'hr_train_myTrainList',
+			params: params
+		}
+	})
+}
+
+/**
+ * 获取我的培训详情
+ */
+export function getMyTrainDetail(params) {
+	return request({
+		url: preUrl,
+		method: 'post',
+		data: {
+			serviceId: 'hr_train_myTrainDetail',
+			params: params
+		}
+	})
+}
+
+/**
+ * 提交培训评估
+ */
+export function submitTrainAssess(params) {
+	return request({
+		url: preUrl,
+		method: 'post',
+		data: {
+			serviceId: 'hr_train_myTrainAssess',
+			params: params
+		}
+	})
+}

+ 21 - 0
pages.json

@@ -244,6 +244,27 @@
 					{
 						"navigationBarTitleText" : "工资详情"
 					}
+				},
+				{
+					"path" : "train/trainList",
+					"style" : 
+					{
+						"navigationBarTitleText" : "我的培训"
+					}
+				},
+				{
+					"path" : "train/trainDetail",
+					"style" : 
+					{
+						"navigationBarTitleText" : "培训详情"
+					}
+				},
+				{
+					"path" : "train/trainAssess",
+					"style" : 
+					{
+						"navigationBarTitleText" : "培训评估"
+					}
 				}
 			]
 		}

+ 365 - 0
pages/mine/train/trainAssess.vue

@@ -0,0 +1,365 @@
+<template>
+	<view class="container">
+		<scroll-view scroll-y class="content">
+			<!-- 培训信息 -->
+			<view class="info-card">
+				<view class="card-title">培训信息</view>
+				<view class="info-item">
+					<text class="label">培训主题:</text>
+					<text class="value">{{ trainName }}</text>
+				</view>
+				<view class="info-item">
+					<text class="label">课程名称:</text>
+					<text class="value">{{ courseName }}</text>
+				</view>
+			</view>
+
+			<!-- 评估表单 -->
+			<view class="form-card">
+				<view class="card-title">培训评估</view>
+				
+				<!-- 项目组织评分 -->
+				<view class="form-item">
+					<view class="form-label">
+						<text class="required">*</text>
+						项目组织评分:
+					</view>
+					<view class="star-rating">
+						<view 
+							v-for="n in 5" 
+							:key="'project_' + n"
+							class="star"
+							:class="{ active: formData.project_org >= n }"
+							@click="selectRating('project_org', n)"
+						>
+							{{ formData.project_org >= n ? '★' : '☆' }}
+						</view>
+					</view>
+				</view>
+
+				<!-- 课程评分 -->
+				<view class="form-item">
+					<view class="form-label">
+						<text class="required">*</text>
+						课程评分:
+					</view>
+					<view class="star-rating">
+						<view 
+							v-for="n in 5" 
+							:key="'course_' + n"
+							class="star"
+							:class="{ active: formData.course_score >= n }"
+							@click="selectRating('course_score', n)"
+						>
+							{{ formData.course_score >= n ? '★' : '☆' }}
+						</view>
+					</view>
+				</view>
+
+				<!-- 讲师评分 -->
+				<view class="form-item">
+					<view class="form-label">
+						<text class="required">*</text>
+						讲师评分:
+					</view>
+					<view class="star-rating">
+						<view 
+							v-for="n in 5" 
+							:key="'teacher_' + n"
+							class="star"
+							:class="{ active: formData.teacher_score >= n }"
+							@click="selectRating('teacher_score', n)"
+						>
+							{{ formData.teacher_score >= n ? '★' : '☆' }}
+						</view>
+					</view>
+				</view>
+
+				<!-- 意见建议 -->
+				<view class="form-item">
+					<view class="form-label">意见建议:</view>
+					<textarea 
+						class="textarea" 
+						v-model="formData.advice"
+						placeholder="请输入您的意见和建议(选填)"
+						maxlength="500"
+					></textarea>
+				</view>
+			</view>
+		</scroll-view>
+
+		<!-- 底部按钮 -->
+		<view class="footer">
+			<button class="btn btn-cancel" @click="goBack">取消</button>
+			<button class="btn btn-submit" @click="submitAssess">提交</button>
+		</view>
+	</view>
+</template>
+
+<script setup>
+import { ref, reactive } from 'vue';
+import { onLoad } from '@dcloudio/uni-app';
+import { getMyTrainDetail, submitTrainAssess } from '@/api/train.js';
+import { useUserStore } from '@/store/user.js';
+
+const userStore = useUserStore();
+
+// 页面参数
+const universalid = ref('');
+const impleId = ref('');
+const courseId = ref('');
+const traineesId = ref('');
+const assessId = ref('');
+const trainName = ref('');
+const courseName = ref('');
+
+// 表单数据
+const formData = reactive({
+	project_org: 0,
+	course_score: 0,
+	teacher_score: 0,
+	advice: ''
+});
+
+onLoad((options) => {
+	universalid.value = options.universalid || '';
+	impleId.value = options.imple_id || '';
+	courseId.value = options.course_id || '';
+	traineesId.value = options.trainees_id || userStore.user.useId;
+	assessId.value = options.assess_id || '';
+	trainName.value = decodeURIComponent(options.train_name || '');
+	courseName.value = decodeURIComponent(options.course_name || '');
+	
+	// 如果有 assess_id,加载已有评估数据
+	if (assessId.value) {
+		loadTrainDetail();
+	}
+});
+
+// 加载培训详情
+async function loadTrainDetail() {
+	try {
+		const res = await getMyTrainDetail({
+			universalid: universalid.value,
+			imple_id: impleId.value,
+			course_id: courseId.value,
+			trainees_id: traineesId.value,
+			assess_id: assessId.value
+		});
+		
+		if (res && res.returnCode === '0' && res.returnParams) {
+			const data = res.returnParams;
+			formData.project_org = data.project_org || 0;
+			formData.course_score = data.course_score || 0;
+			formData.teacher_score = data.teacher_score || 0;
+			formData.advice = data.advice || '';
+		}
+	} catch (error) {
+		console.error('加载培训详情失败:', error);
+	}
+}
+
+// 选择评分
+function selectRating(field, value) {
+	formData[field] = value;
+}
+
+// 提交评估
+async function submitAssess() {
+	// 验证必填项
+	if (!formData.project_org) {
+		uni.showToast({
+			title: '请选择项目组织评分',
+			icon: 'none'
+		});
+		return;
+	}
+	if (!formData.course_score) {
+		uni.showToast({
+			title: '请选择课程评分',
+			icon: 'none'
+		});
+		return;
+	}
+	if (!formData.teacher_score) {
+		uni.showToast({
+			title: '请选择讲师评分',
+			icon: 'none'
+		});
+		return;
+	}
+
+	uni.showLoading({
+		title: '提交中...'
+	});
+
+	try {
+		const res = await submitTrainAssess({
+			universalid: assessId.value,  // 使用 assess_id 作为 universalid
+			imple_id: impleId.value,
+			course_id: courseId.value,
+			trainees_id: traineesId.value,
+			project_org: formData.project_org,
+			course_score: formData.course_score,
+			teacher_score: formData.teacher_score,
+			advice: formData.advice
+		});
+		
+		uni.hideLoading();
+		
+		if (res && res.returnCode === '0') {
+			uni.showToast({
+				title: '评估成功',
+				icon: 'success'
+			});
+			
+			setTimeout(() => {
+				goBack();
+			}, 1500);
+		} else {
+			uni.showToast({
+				title: '评估失败',
+				icon: 'none'
+			});
+		}
+	} catch (error) {
+		uni.hideLoading();
+		uni.showToast({
+			title: '提交失败',
+			icon: 'none'
+		});
+		console.error('提交评估失败:', error);
+	}
+}
+
+// 返回
+function goBack() {
+	uni.navigateBack();
+}
+</script>
+
+<style lang="scss" scoped>
+.container {
+	min-height: 100vh;
+	background-color: #f5f5f5;
+	display: flex;
+	flex-direction: column;
+}
+
+.content {
+	flex: 1;
+	padding: 20rpx;
+}
+
+.info-card, .form-card {
+	background: #fff;
+	border-radius: 12rpx;
+	padding: 30rpx;
+	margin-bottom: 20rpx;
+	
+	.card-title {
+		font-size: 32rpx;
+		font-weight: 600;
+		color: #333;
+		margin-bottom: 24rpx;
+		padding-bottom: 16rpx;
+		border-bottom: 1rpx solid #f0f0f0;
+	}
+}
+
+.info-item {
+	display: flex;
+	align-items: center;
+	font-size: 28rpx;
+	line-height: 1.8;
+	margin-bottom: 12rpx;
+	
+	.label {
+		color: #999;
+		min-width: 160rpx;
+	}
+	
+	.value {
+		color: #333;
+		flex: 1;
+	}
+}
+
+.form-item {
+	margin-bottom: 32rpx;
+	
+	.form-label {
+		font-size: 28rpx;
+		color: #333;
+		margin-bottom: 16rpx;
+		
+		.required {
+			color: #ff4d4f;
+			margin-right: 4rpx;
+		}
+	}
+	
+	.star-rating {
+		display: flex;
+		gap: 16rpx;
+		
+		.star {
+			font-size: 48rpx;
+			color: #d9d9d9;
+			cursor: pointer;
+			transition: all 0.3s;
+			
+			&.active {
+				color: #FF9912;
+			}
+			
+			&:active {
+				transform: scale(1.2);
+			}
+		}
+	}
+	
+	.textarea {
+		width: 100%;
+		min-height: 200rpx;
+		padding: 20rpx;
+		background: #f8f8f8;
+		border-radius: 8rpx;
+		font-size: 28rpx;
+		line-height: 1.6;
+		box-sizing: border-box;
+	}
+}
+
+.footer {
+	display: flex;
+	gap: 20rpx;
+	padding: 20rpx 30rpx;
+	background: #fff;
+	border-top: 1rpx solid #eee;
+	
+	.btn {
+		flex: 1;
+		height: 80rpx;
+		line-height: 80rpx;
+		font-size: 30rpx;
+		border-radius: 8rpx;
+		padding: 0;
+		margin: 0;
+		
+		&::after {
+			border: none;
+		}
+		
+		&.btn-cancel {
+			background: #f5f5f5;
+			color: #666;
+		}
+		
+		&.btn-submit {
+			background: #1890ff;
+			color: #fff;
+		}
+	}
+}
+</style>

+ 276 - 0
pages/mine/train/trainDetail.vue

@@ -0,0 +1,276 @@
+<template>
+	<view class="container">
+		<scroll-view scroll-y class="content">
+			<!-- 培训信息 -->
+			<view class="info-card" v-if="trainDetail">
+				<view class="card-title">培训信息</view>
+				<view class="info-item">
+					<text class="label">培训主题:</text>
+					<text class="value">{{ trainDetail.train_name || '-' }}</text>
+				</view>
+				<view class="info-item">
+					<text class="label">负责人:</text>
+					<text class="value">{{ trainDetail.responsible_people || '-' }}</text>
+				</view>
+				<view class="info-item">
+					<text class="label">学员姓名:</text>
+					<text class="value">{{ trainDetail.user_name || trainDetail.trainees_name || '-' }}</text>
+				</view>
+				<view class="info-item">
+					<text class="label">课程类别:</text>
+					<text class="value">{{ trainDetail.class_name || '-' }}</text>
+				</view>
+				<view class="info-item">
+					<text class="label">课程名称:</text>
+					<text class="value">{{ trainDetail.course_name || '-' }}</text>
+				</view>
+				<view class="info-item">
+					<text class="label">讲师:</text>
+					<text class="value">{{ trainDetail.teacher_name || '-' }}</text>
+				</view>
+				<view class="info-item">
+					<text class="label">培训地点:</text>
+					<text class="value">{{ trainDetail.location_name || '-' }}</text>
+				</view>
+				<view class="info-item">
+					<text class="label">开始时间:</text>
+					<text class="value">{{ formatDateTime(trainDetail.imple_start_time) }}</text>
+				</view>
+				<view class="info-item">
+					<text class="label">结束时间:</text>
+					<text class="value">{{ formatDateTime(trainDetail.imple_end_time) }}</text>
+				</view>
+			</view>
+
+			<!-- 评估信息 -->
+			<view class="info-card" v-if="trainDetail">
+				<view class="card-title">我的评估</view>
+				
+				<view class="info-item">
+					<text class="label">项目组织:</text>
+					<text class="value stars">{{ renderStars(trainDetail.project_org) }}</text>
+				</view>
+				<view class="info-item">
+					<text class="label">课程评分:</text>
+					<text class="value stars">{{ renderStars(trainDetail.course_score) }}</text>
+				</view>
+				<view class="info-item">
+					<text class="label">讲师评分:</text>
+					<text class="value stars">{{ renderStars(trainDetail.teacher_score) }}</text>
+				</view>
+				<view class="info-item" v-if="trainDetail.advice">
+					<text class="label">意见建议:</text>
+					<text class="value advice">{{ trainDetail.advice }}</text>
+				</view>
+				<view class="info-item" v-else>
+					<text class="label">意见建议:</text>
+					<text class="value empty-text">暂无</text>
+				</view>
+			</view>
+
+			<!-- 课程附件 -->
+			<uni-card v-if="trainDetail && fileList && fileList.length > 0">
+				<uni-section titleFontSize="1.3rem" title="课程附件" type="line"></uni-section>
+				<attachment-list :attachments="fileList" :canEdit="false"></attachment-list>
+			</uni-card>
+
+			<view v-if="loading" class="loading">加载中...</view>
+			<view v-else-if="!trainDetail" class="empty">
+				<text>暂无数据</text>
+			</view>
+		</scroll-view>
+
+		<!-- 底部按钮 -->
+<!--		<view class="footer" v-if="trainDetail">
+			<button class="btn btn-assess" @click="goToAssess">去评估</button>
+		</view>-->
+	</view>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+import { onLoad } from '@dcloudio/uni-app';
+import { getMyTrainDetail } from '@/api/train.js';
+import AttachmentList from '@/components/ygoa/attachmentList.vue';
+
+const trainDetail = ref(null);
+const fileList = ref([]);
+const loading = ref(false);
+
+// 页面参数
+const universalid = ref('');
+const impleId = ref('');
+const courseId = ref('');
+const traineesId = ref('');
+const assessId = ref('');
+
+onLoad((options) => {
+	universalid.value = options.universalid || '';
+	impleId.value = options.imple_id || '';
+	courseId.value = options.course_id || '';
+	traineesId.value = options.trainees_id || '';
+	assessId.value = options.assess_id || '';
+	
+	loadTrainDetail();
+});
+
+// 渲染星星评分
+function renderStars(score) {
+	if (!score || score === 0) {
+		return '☆ ☆ ☆ ☆ ☆';
+	}
+	const filledStars = '★ '.repeat(parseInt(score));
+	const emptyStars = '☆ '.repeat(5 - parseInt(score));
+	return filledStars + emptyStars;
+}
+
+// 格式化日期时间
+function formatDateTime(dateStr) {
+	if (!dateStr) return '-';
+	// 如果是字符串格式,直接返回
+	if (typeof dateStr === 'string') {
+		return dateStr;
+	}
+	// 如果是时间戳或 Date 对象,进行格式化
+	const date = new Date(dateStr);
+	const year = date.getFullYear();
+	const month = String(date.getMonth() + 1).padStart(2, '0');
+	const day = String(date.getDate()).padStart(2, '0');
+	const hours = String(date.getHours()).padStart(2, '0');
+	const minutes = String(date.getMinutes()).padStart(2, '0');
+	return `${year}-${month}-${day} ${hours}:${minutes}`;
+}
+
+// 加载培训详情
+async function loadTrainDetail() {
+	loading.value = true;
+	try {
+		const res = await getMyTrainDetail({
+			universalid: universalid.value,
+			imple_id: impleId.value,
+			course_id: courseId.value,
+			trainees_id: traineesId.value,
+			assess_id: assessId.value
+		});
+		
+		if (res && res.returnCode === '0' && res.returnParams) {
+			trainDetail.value = res.returnParams;
+			// 处理附件列表
+			if (res.returnParams.files && Array.isArray(res.returnParams.files)) {
+				fileList.value = res.returnParams.files;
+			}
+		} else {
+			uni.showToast({
+				title: '加载失败',
+				icon: 'none'
+			});
+		}
+	} catch (error) {
+		uni.showToast({
+			title: '加载失败',
+			icon: 'none'
+		});
+		console.error('加载培训详情失败:', error);
+	} finally {
+		loading.value = false;
+	}
+}
+
+// 去评估
+function goToAssess() {
+	uni.navigateTo({
+		url: `/pages/mine/train/trainAssess?universalid=${universalid.value}&imple_id=${impleId.value}&course_id=${courseId.value}&trainees_id=${traineesId.value}`
+	});
+}
+</script>
+
+<style lang="scss" scoped>
+.container {
+	min-height: 100vh;
+	background-color: #f5f5f5;
+	display: flex;
+	flex-direction: column;
+}
+
+.content {
+	flex: 1;
+	padding: 20rpx;
+}
+
+.info-card {
+	background: #fff;
+	border-radius: 12rpx;
+	padding: 30rpx;
+	margin-bottom: 20rpx;
+	
+	.card-title {
+		font-size: 32rpx;
+		font-weight: 600;
+		color: #333;
+		margin-bottom: 24rpx;
+		padding-bottom: 16rpx;
+		border-bottom: 1rpx solid #f0f0f0;
+	}
+}
+
+.info-item {
+	display: flex;
+	align-items: flex-start;
+	font-size: 28rpx;
+	line-height: 1.8;
+	margin-bottom: 16rpx;
+	
+	.label {
+		color: #999;
+		min-width: 160rpx;
+		flex-shrink: 0;
+	}
+	
+	.value {
+		color: #333;
+		flex: 1;
+		
+		&.stars {
+			color: #FF9912;
+			font-size: 26rpx;
+		}
+		
+		&.advice {
+			line-height: 1.6;
+		}
+		
+		&.empty-text {
+			color: #ccc;
+		}
+	}
+}
+
+.loading, .empty {
+	text-align: center;
+	padding: 80rpx 0;
+	color: #999;
+	font-size: 28rpx;
+}
+
+.footer {
+	padding: 20rpx 30rpx;
+	background: #fff;
+	border-top: 1rpx solid #eee;
+	
+	.btn {
+		width: 100%;
+		height: 80rpx;
+		line-height: 80rpx;
+		font-size: 30rpx;
+		border-radius: 8rpx;
+		padding: 0;
+		margin: 0;
+		background: #fa8c16;
+		color: #fff;
+		
+		&::after {
+			border: none;
+		}
+	}
+}
+</style>

+ 351 - 0
pages/mine/train/trainList.vue

@@ -0,0 +1,351 @@
+<template>
+	<view class="container">
+		<!-- 搜索区域 -->
+		<view class="search-box">
+			<input 
+				class="search-input" 
+				v-model="courseName" 
+				placeholder="搜索课程名称"
+				@confirm="searchTrain"
+			/>
+			<button class="search-btn" @click="searchTrain">查询</button>
+		</view>
+
+		<!-- 培训列表 -->
+		<scroll-view scroll-y class="train-list" @scrolltolower="loadMore">
+			<view v-if="loading" class="loading">加载中...</view>
+			
+			<view v-else-if="trainList.length === 0" class="empty">
+				<text>暂无培训记录</text>
+			</view>
+			
+			<view v-else>
+				<view v-for="(item, index) in trainList" :key="index" class="train-item">
+					<view class="card-header">
+						<text class="title">{{ item.train_name || '未命名培训' }}</text>
+					</view>
+					<view class="card-body">
+						<view class="info-line">
+							<text class="label">负责人:</text>
+							<text class="value">{{ item.responsible_people || '-' }}</text>
+						</view>
+						<view class="info-line">
+							<text class="label">课程名称:</text>
+							<text class="value">{{ item.course_name || '-' }}</text>
+						</view>
+						<view class="info-line">
+							<text class="label">讲师:</text>
+							<text class="value">{{ item.teacher_name || '-' }}</text>
+						</view>
+						<view class="info-line">
+							<text class="label">地点:</text>
+							<text class="value">{{ item.location_name || '-' }}</text>
+						</view>
+						
+						<!-- 评分展示 -->
+<!--						<view class="score-section" v-if="item.project_org || item.course_score || item.teacher_score">
+							<view class="score-line">
+								<text class="label">项目组织:</text>
+								<text class="stars">{{ renderStars(item.project_org) }}</text>
+							</view>
+							<view class="score-line">
+								<text class="label">课程评分:</text>
+								<text class="stars">{{ renderStars(item.course_score) }}</text>
+							</view>
+							<view class="score-line">
+								<text class="label">讲师评分:</text>
+								<text class="stars">{{ renderStars(item.teacher_score) }}</text>
+							</view>
+						</view>-->
+						
+						<!-- 操作按钮 -->
+						<view class="action-buttons">
+							<button 
+								class="btn btn-view" 
+								@click="viewDetail(item)"
+							>
+								查看
+							</button>
+							<button 
+								class="btn btn-assess" 
+								@click="assessTrain(item)"
+							>
+								评估
+							</button>
+						</view>
+					</view>
+				</view>
+				
+				<view v-if="hasMore" class="load-more">加载更多...</view>
+				<view v-else-if="trainList.length > 0" class="no-more">没有更多了</view>
+			</view>
+		</scroll-view>
+	</view>
+</template>
+
+<script setup>
+import { ref, onMounted } from 'vue';
+import { onLoad } from '@dcloudio/uni-app';
+import { getMyTrainList } from '@/api/train.js';
+import { useUserStore } from '@/store/user.js';
+
+const userStore = useUserStore();
+const trainList = ref([]);
+const courseName = ref('');
+const loading = ref(false);
+const hasMore = ref(true);
+const pageNum = ref(1);
+const pageSize = ref(20);
+
+onLoad(() => {
+	loadTrainList();
+});
+
+// 渲染星星评分
+function renderStars(score) {
+	if (!score || score === 0) {
+		return '☆ ☆ ☆ ☆ ☆';
+	}
+	const filledStars = '★ '.repeat(parseInt(score));
+	const emptyStars = '☆ '.repeat(5 - parseInt(score));
+	return filledStars + emptyStars;
+}
+
+// 查询培训
+function searchTrain() {
+	pageNum.value = 1;
+	trainList.value = [];
+	hasMore.value = true;
+	loadTrainList();
+}
+
+// 加载培训列表
+async function loadTrainList() {
+	if (loading.value || !hasMore.value) return;
+	
+	loading.value = true;
+	try {
+		const res = await getMyTrainList({
+			userId: userStore.user.useId,
+			course_name: courseName.value,
+			page: pageNum.value,
+			pageSize: pageSize.value
+		});
+		
+		if (res && res.returnCode === '0' && res.returnParams) {
+			const data = res.returnParams;
+			const newList = data.list || [];
+			trainList.value = [...trainList.value, ...newList];
+			
+			// 判断是否还有更多数据
+			if (newList.length < pageSize.value) {
+				hasMore.value = false;
+			} else {
+				pageNum.value++;
+			}
+		}
+	} catch (error) {
+		uni.showToast({
+			title: '加载失败',
+			icon: 'none'
+		});
+		console.error('加载培训列表失败:', error);
+	} finally {
+		loading.value = false;
+	}
+}
+
+// 加载更多
+function loadMore() {
+	if (!loading.value && hasMore.value) {
+		loadTrainList();
+	}
+}
+
+// 查看详情
+function viewDetail(item) {
+	console.log('查看培训详情 - item:', item);
+	console.log('assess_id:', item.assess_id);
+	console.log('universalid:', item.universalid);
+	uni.navigateTo({
+		url: `/pages/mine/train/trainDetail?universalid=${item.universalid || ''}&imple_id=${item.imple_id}&course_id=${item.course_id}&trainees_id=${item.trainees_id}&assess_id=${item.assess_id || ''}`
+	});
+}
+
+// 评估培训
+function assessTrain(item) {
+	uni.navigateTo({
+		url: `/pages/mine/train/trainAssess?universalid=${item.universalid || ''}&imple_id=${item.imple_id}&course_id=${item.course_id}&trainees_id=${item.trainees_id}&assess_id=${item.assess_id || ''}&train_name=${encodeURIComponent(item.train_name || '')}&course_name=${encodeURIComponent(item.course_name || '')}`
+	});
+}
+</script>
+
+<style lang="scss" scoped>
+.container {
+	min-height: 100vh;
+	background-color: #f5f5f5;
+	display: flex;
+	flex-direction: column;
+}
+
+.search-box {
+	background: #fff;
+	padding: 20rpx 30rpx;
+	display: flex;
+	align-items: center;
+	gap: 15rpx;
+	border-bottom: 1rpx solid #eee;
+	
+	.search-input {
+		flex: 1;
+		height: 70rpx;
+		line-height: 70rpx;
+		padding: 0 25rpx;
+		background: #f8f8f8;
+		border-radius: 8rpx;
+		font-size: 28rpx;
+	}
+	
+	.search-btn {
+		width: 150rpx;
+		height: 70rpx;
+		line-height: 70rpx;
+		background: #1890ff;
+		color: #fff;
+		border-radius: 8rpx;
+		font-size: 28rpx;
+		padding: 0;
+		margin: 0;
+		
+		&::after {
+			border: none;
+		}
+	}
+}
+
+.train-list {
+	flex: 1;
+	height: calc(100vh - 150rpx);
+	padding: 20rpx 24rpx;
+	box-sizing: border-box;
+	width: 100%;
+}
+
+.loading, .empty, .load-more, .no-more {
+	text-align: center;
+	padding: 40rpx 0;
+	color: #999;
+	font-size: 28rpx;
+}
+
+.train-item {
+	background: #fff;
+	border-radius: 12rpx;
+	padding: 20rpx;
+	margin-bottom: 16rpx;
+	box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
+	box-sizing: border-box;
+	width: 100%;
+	
+	.card-header {
+		margin-bottom: 16rpx;
+		padding-bottom: 12rpx;
+		border-bottom: 1rpx solid #f0f0f0;
+		
+		.title {
+			font-size: 32rpx;
+			font-weight: 600;
+			color: #333;
+		}
+	}
+	
+	.card-body {
+		.info-line {
+			display: flex;
+			align-items: center;
+			font-size: 26rpx;
+			line-height: 1.8;
+			margin-bottom: 8rpx;
+			
+			.label {
+				color: #999;
+				margin-right: 8rpx;
+				min-width: 140rpx;
+			}
+			
+			.value {
+				color: #333;
+				flex: 1;
+			}
+		}
+		
+		.score-section {
+			margin-top: 12rpx;
+			padding-top: 12rpx;
+			border-top: 1rpx dashed #f0f0f0;
+			
+			.score-line {
+				display: flex;
+				align-items: center;
+				font-size: 26rpx;
+				line-height: 1.8;
+				margin-bottom: 6rpx;
+				
+				.label {
+					color: #999;
+					margin-right: 8rpx;
+					min-width: 140rpx;
+				}
+				
+				.stars {
+					color: #FF9912;
+					font-size: 24rpx;
+				}
+			}
+		}
+		
+		.action-buttons {
+			display: flex;
+			justify-content: flex-end;
+			gap: 16rpx;
+			margin-top: 16rpx;
+			padding-top: 12rpx;
+			border-top: 1rpx solid #f0f0f0;
+			
+			.btn {
+				flex: 0 0 auto;
+				padding: 12rpx 28rpx;
+				font-size: 26rpx;
+				border-radius: 6rpx;
+				min-width: 120rpx;
+				height: auto;
+				line-height: 1.5;
+				
+				&::after {
+					border: none;
+				}
+				
+				&.btn-view {
+					background: #fff;
+					color: #1890ff;
+					border: 1rpx solid #1890ff;
+					
+					&:active {
+						background: #f0f7ff;
+					}
+				}
+				
+				&.btn-assess {
+					background: #1890ff;
+					color: #fff;
+					border: 1rpx solid #1890ff;
+					
+					&:active {
+						background: #096dd9;
+					}
+				}
+			}
+		}
+	}
+}
+</style>

+ 11 - 0
pages/tabbar-mine/index.vue

@@ -63,6 +63,12 @@
 					<text class="title">我的工资</text>
 					<text class="desc"></text>
 				</view>
+							
+				<view class="function-item" @click="myTrain">
+					<text class="ygoa_icon icon-diary"></text>
+					<text class="title">我的培训</text>
+					<text class="desc"></text>
+				</view>
 				
 				<view class="function-item" @click="setting">
 					<text class="ygoa_icon icon-setting"></text>
@@ -137,6 +143,11 @@
 		$tab.navigateTo('/pages/mine/salary/salaryList')
 	}
 	
+	// 我的培训的函数
+	function myTrain() {
+		$tab.navigateTo('/pages/mine/train/trainList')
+	}
+	
 	//头像修改页
 	function toEditAvatar() {
 		// $tab.navigateTo('/pages/mine/avatar/avatarTest/avatarTest')