studentList.vue 6.0 KB
<template>
	<view class="internship_box" :style="vuex_theme">
		<view class="internship" v-if="hasLogin">

			<view class="search_box">
				<view class="search">
					<u-search placeholder="请输入学生姓名/学号/手机号" placeholderColor="#C1C1C9" searchIconSize="36" height="64rpx"
						bgColor="#F4F4F4" :showAction="false" shape="square" v-model="keyword" @search="handelSearch">
					</u-search>
				</view>
			</view>

			<view class="list_box" v-if="list.length > 0">
				<view class="item" v-for="(item, i) in list" :key="i" @click="handelDetail(item)">

					<view class="info">
						<view class="avatar">{{getNameLastTwo(item.studentName)}}</view>
						<view class="student_info">
							<view class="name">
								<text>{{overflowHide(item.studentName, 4)}}</text>
								<text>({{item.studentNumber}})</text>
							</view>
							<view class="mobile">
								<text>{{item.studentPhone}}</text>
							</view>
						</view>
					</view>

				</view>
				<c-loading :loading="loading"></c-loading>
			</view>
			<view v-else class="no_data">
				<c-no-data></c-no-data>
			</view>

		</view>
		<view class="no_login" v-else>
			<view class="image">
				<u-image :style="{margin:'0 auto'}" :src="vuex_baseImgUrl+'internship_bg.png'" width="480rpx"
					height="480rpx"></u-image>
			</view>
			<view class="btn">
				<text>登录后可查看待办事项</text>
				<u-button type="primary" text="登录" color="var(--primary-color)" :customStyle="{width:'340rpx'}" @click="handelLOgin">
				</u-button>
			</view>
		</view>
	</view>
</template>

<script>
	import {
		mapGetters,
		mapState,
		mapActions
	} from 'vuex'

	import listMixin from "@/common/mixins/list-mixin.js";

	import {
		getStudentListApi,
	} from '@/config/api.js';

	export default {
		mixins: [listMixin],
		data() {
			return {
				classInfoId: '',
				keyword: '',
				list: [],
				search: {
					keySearch: "",
				},
			}
		},

		onLoad(option) {
			this.classInfoId = option.classInfoId

			this.search.keySearch = '';

			this.finished = false;
			this.loading = "loadmore";
			this.page = 0;
			this.list = [];
			this._getList();
		},

		onShow() {

		},

		computed: {
			...mapState({
				hasLogin: 'hasLogin',
				vuex_user: 'vuex_user',
				teacher: (state) => state.vuex_user.teacher,
			}),


		},

		methods: {
			getNameLastTwo(value) {
				if (value && value.length > 3) {
					return value.substring(value.length - 3)
				} else {
					return value;
				}
			},

			overflowHide(value, num = 4) {
				if (value && value.length > num) {
					return `${value.slice(0, num)}...`
				} else {
					return value;
				}
			},

			timeFormat(timestamp, format = 'yyyy-mm-dd') {
				return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--'
			},

			handelSearch(value) {
				this.finished = false;
				this.loading = "loadmore";
				this.page = 0;
				this.list = [];
				this._getList();
			},

			// scroll-view到底部加载更多
			onreachBottom() {},
			// 搜索
			searchSubmit() {
				// 调用混合搜索
				this._searchData();
			},
			// 模拟后端分页
			async getData(requestParams) {
				const {
					search = {}
				} = requestParams;

				let params = {};
				params.pageNumber = requestParams.page + 1;
				params.pageSize = 10;

				if (this.classInfoId) {
					params.classInfoId = this.classInfoId
				}

				if (this.keyword) {
					params.keySearch = this.keyword
				}

				return await getStudentListApi(params);
			},
			// 数据请求(没错就是这么少的代码)
			async _getList() {
				if (this.page == 0) {
					this.list = [];
				}

				// 根据实际情况修改自己修改key
				let result = await this.getData({
					page: this.page, // 传入页码
					size: this.size, // 传入每页条数
					search: this.search, // 传入搜索的对象
				});

				this.total = result.total;
				this.list = this.list.concat(result.records)
				
				// 判断是否全部加载完成
				if (this.total == this.list.length) {
					this.finished = true;
					this.loading = 'nomore';
				} else {
					this.loading = 'loadmore';
				}
			},
			
			handelDetail(record) {
				this.$u.route({
					url: `pages/main/internship/traineeDetail/traineeDetail?studentId=${record.studentId}`
				})
			},

		}
	}
</script>

<style lang="scss" scoped>
	.internship_box {
		background-color: #F7F7F7;
		min-height: 100%;
		height: auto;

		.internship {
			width: 100%;
			margin: 0 auto;

			.search_box {
				padding: 36rpx 0;
				background-color: #FFFFFF;

				.search {
					width: 690rpx;
					margin: 0 auto;
				}

			}

			.list_box {
				padding: 0 0 50rpx 0;

				.item {
					position: relative;
					width: 630rpx;
					margin: 30rpx auto;
					padding: 30rpx;
					border-radius: 12rpx;
					background-color: #FFFFFF;

					.info {
						display: flex;
						flex-flow: row nowrap;
						align-items: center;
						margin: 0 0 30rpx 0;

						.avatar {
							width: 94rpx;
							height: 94rpx;
							border-radius: 4rpx;
							background-color: var(--primary-color);
							font-size: 24rpx;
							line-height: 94rpx;
							color: #FFFFFF;
							text-align: center;
						}

						.student_info {
							.name {
								font-size: 32rpx;
								line-height: 32rpx;
								color: #121212;
								font-weight: 500;
								margin: 0 20rpx;

								text:last-child {
									font-size: 26rpx;
									color: #26292F;
									padding: 0 0 0 20rpx;
								}
							}

							.mobile {
								padding: 20rpx 0 0 20rpx;
								font-size: 26rpx;
								line-height: 36rpx;
								color: #26292F;
							}
						}
					}
				}
			}
		}

		.no_login {
			padding: 180rpx 0 0 0;
			text-align: center;

			.image {
				width: 480rpx;
				margin: 0 auto;
			}

			.btn {
				position: relative;
				top: -80rpx;

				text {
					font-size: 24rpx;
					line-height: 52rpx;
					color: #909097;

				}
			}
		}

	}
</style>