mobilizeRecord.vue 5.18 KB
<template>
	<view class="record-page">
		<scroll-view
			class="record-scroll"
			:show-scrollbar="false"
			lower-threshold="160"
			scroll-y
			@scrolltolower="loadMore"
		>
			<view class="appList">
				<view class="appItem" v-for="(item, index) in list" :key="item.id || index">
					<!-- 头部:姓名+日期 -->
					<view class="record-header">
						<!-- <view class="avatar">
							<text>{{ (item.personName || '-').charAt(0) }}</text>
						</view> -->
						<view class="header-info">
							<view class="name">{{ item.personName || '-' }}{{ item.personIdcCode || '-' }}</view>
						
						</view>
						<text class="time">{{ formatDate(item.operTime) }}</text>
					</view>

					<!-- 单位信息对比区 -->
					<view class="unit-section">
						<view class="unit-item">
							<view class="unit-label">原单位</view>
							<view class="unit-value">{{ item.sourceMemName || '-' }}</view>
						</view>
						<view class="divider-line">
							<uni-icons type="arrow-right" size="16" color="#999"></uni-icons>
						</view>
						<view class="unit-item target">
							<view class="unit-label">申请单位</view>
							<view class="unit-value">{{ item.targetMemName || '-' }}</view>
						</view>
					</view>
				</view>

				<view class="loading-tip" v-if="loading">加载中...</view>
				<view class="no-more" v-if="!loading && !hasMore && list.length > 0">没有更多了</view>
			</view>
		</scroll-view>

		<view class="nodata" v-if="list.length === 0 && !loading">
			<image mode="aspectFit" :src="config.baseUrl_api + '/fs/static/nodata.png'"></image>
			<text>暂无数据</text>
		</view>
	</view>
</template>

<script setup>
	import * as api from '@/common/api.js'
	import config from '@/config.js'
	import { reactive, ref } from 'vue'
	import { onLoad, onShow } from '@dcloudio/uni-app'

	const app = getApp()
	const list = ref([])
	const loading = ref(false)
	const hasMore = ref(true)
	const hasInited = ref(false)
	const queryParams = reactive({
		pageNum: 1,
		pageSize: 10,
		noAuditProcess: '1'
	})

	onLoad(() => {
		if (app.globalData.isLogin) {
			init()
		} else {
			app.firstLoadCallback = () => {
				init()
			}
		}
	})

	onShow(() => {
		if (hasInited.value) {
			resetList()
		}
	})

	function init() {
		hasInited.value = true
		resetList()
	}

	function resetList() {
		queryParams.pageNum = 1
		list.value = []
		hasMore.value = true
		getList()
	}

	function getList() {
		if (loading.value || !hasMore.value) return
		loading.value = true
		api.logList(queryParams).then(res => {
			const rows = res.rows || []
			if (queryParams.pageNum === 1) {
				list.value = rows
			} else {
				list.value.push(...rows)
			}
			hasMore.value = list.value.length < Number(res.total || 0)
		}).catch(() => {
			uni.showToast({
				title: '加载失败',
				icon: 'none'
			})
			if (queryParams.pageNum > 1) {
				queryParams.pageNum--
			}
		}).finally(() => {
			loading.value = false
		})
	}

	function loadMore() {
		if (loading.value || !hasMore.value) return
		queryParams.pageNum++
		getList()
	}

	function formatDate(dateValue) {
		if (!dateValue) return '-'
		return String(dateValue).substring(0, 10)
	}
</script>

<style scoped lang="scss">
	.record-page {
		height: 100vh;
		background: #f5f7fa;
		position: relative;
	}

	.record-scroll {
		height: 100%;
	}

	.appList {
		// padding: 10rpx;
		box-sizing: border-box;
	}

	.appItem {
		background: #fff;
		border-radius: 16rpx;
		box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
		padding:0 20rpx 20rpx 20rpx;
		margin-bottom: 20rpx;
		transition: all 0.2s ease;

		&:active {
			transform: scale(0.99);
			box-shadow: 0 1rpx 8rpx rgba(0, 0, 0, 0.08);
		}
	}

	.record-header {
		display: flex;
		align-items: center;
		// margin-bottom: 24rpx;
	}

	.avatar {
		width: 64rpx;
		height: 64rpx;
		border-radius: 50%;
		background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
		display: flex;
		align-items: center;
		justify-content: center;
		margin-right: 16rpx;

		text {
			font-size: 28rpx;
			color: #fff;
			font-weight: 500;
		}
	}

	.header-info {
		flex: 1;
	}

	.name {
		font-size: 32rpx;
		font-weight: 600;
		color: #1a1a1a;
		margin-bottom: 6rpx;
	}

	.id-card {
		display: flex;
		align-items: center;

		.label {
			font-size: 24rpx;
			color: #999;
		}

		.value {
			font-size: 24rpx;
			color: #666;
		}
	}

	.time {
		font-size: 24rpx;
		color: #999;
	}

	.unit-section {
		display: flex;
		align-items: center;
		background: #f9fafc;
		border-radius: 12rpx;
		padding: 20rpx 16rpx;
	}

	.unit-item {
		flex: 1;
		padding: 0 12rpx;

		.unit-label {
			font-size: 22rpx;
			color: #999;
			margin-bottom: 8rpx;
		}

		.unit-value {
			font-size: 26rpx;
			color: #333;
			line-height: 1.4;
			word-break: break-all;
		}

		&.target .unit-value {
			color: #C4121B;
		}
	}

	.divider-line {
		display: flex;
		align-items: center;
		justify-content: center;
		padding: 0 8rpx;
	}

	.loading-tip,
	.no-more {
		text-align: center;
		color: #999;
		font-size: 24rpx;
		padding: 20rpx 0;
	}

	.nodata {
		position: absolute;
		top: 180rpx;
		left: 0;
		right: 0;
		display: flex;
		flex-direction: column;
		align-items: center;

		image {
			width: 280rpx;
			height: 280rpx;
			margin-bottom: 16rpx;
		}

		text {
			color: #999;
			font-size: 26rpx;
		}
	}
</style>