Files
zhxg_app/pages/finance/poverty/index.vue

755 lines
19 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="poverty">
<!-- 头部导航 -->
<!-- <uni-nav-bar left-icon="back" title="贫困认定" :border="false"></uni-nav-bar> -->
<view class="app-container">
<!-- 数据列表滚动容器 -->
<scroll-view class="list-container" id="list-container" scroll-y @scrolltolower="handleLoadMore"
lower-threshold="50" enhanced :show-scrollbar="false">
<!-- 初始加载状态 -->
<uni-load-more :status="loading ? 'loading' : 'done'" v-if="loading" class="loading-wrap"></uni-load-more>
<!-- 空数据状态 -->
<view class="empty-state" v-if="!loading && !hasData">
<uni-icons type="empty" size="80" color="#c0c4cc"></uni-icons>
<text class="empty-text">暂无贫困认定申请数据</text>
<text class="empty-tip" v-if="roleGroup.includes('学生')">点击右下角"+"按钮提交新申请</text>
</view>
<!-- 数据列表 -->
<view class="card-list" v-if="!loading && hasData">
<view class="apply-card" v-for="(item, index) in validDataList" :key="index" hover-class="card-hover"
:hover-stop-propagation="true">
<!-- 卡片头部 -->
<view class="card-header">
<view class="apply-no">
<text class="label-text">学年</text>
<text class="no-text">{{ getSafeValue(item, 'applyYear', '无') }}</text>
</view>
<view class="status-wrap">
<view class="status-label" :class="getStatusClass(item)">
{{ getStatusText(item) }}
</view>
<view class="status-label" :class="getReviewClass(item)">
{{ getReviewText(item) }}
</view>
</view>
</view>
<!-- 卡片主体折叠面板 -->
<uni-collapse accordion v-model="item.activeCollapse">
<uni-collapse-item title="基本信息" name="basic" class="collapse-item">
<view class="info-grid">
<view class="info-item"><text class="label">学号</text><text
class="value">{{ getSafeValue(item, 'xh', '-') }}</text></view>
<view class="info-item"><text class="label">姓名</text><text
class="value">{{ getSafeValue(item, 'xm', '-') }}</text></view>
<view class="info-item"><text class="label">性别</text><text
class="value">{{ getSafeValue(item, 'xb', '-') }}</text></view>
<view class="info-item"><text class="label">民族</text><text
class="value">{{ getSafeValue(item, 'mz', '-') }}</text></view>
<view class="info-item"><text class="label">出生年月</text><text
class="value">{{ parseTime(getSafeValue(item, 'csny')) || '-' }}</text>
</view>
</view>
</uni-collapse-item>
<uni-collapse-item title="申请信息" name="apply" class="collapse-item">
<view class="info-form">
<view class="form-item"><text class="label">家庭总收入</text><text
class="value">{{ getSafeValue(item, 'jtnsr', '-') }} </text></view>
<view class="form-item"><text class="label">家庭人均收入</text><text
class="value">{{ getSafeValue(item, 'rjnsr', '-') }} </text></view>
<view class="form-item"><text class="label">家庭人口数</text><text
class="value">{{ getSafeValue(item, 'rkzs', '-') }} </text></view>
</view>
</uni-collapse-item>
<uni-collapse-item title="审核意见" name="approval" class="collapse-item">
<view class="approval-list">
<view class="approval-item">
<text class="approval-node">辅导员审核意见</text>
<text class="approval-result" :class="getReviewClass(item, 'bjpyyj')">
{{ getReviewDetailText(item, 'bjpyyj') }}
</text>
</view>
<view class="approval-item">
<text class="approval-node">学院审核意见</text>
<text class="approval-result" :class="getReviewClass(item, 'ejxyldqmyj')">
{{ getReviewDetailText(item, 'ejxyldqmyj') }}
</text>
</view>
<view class="approval-item">
<text class="approval-node">学校审核意见</text>
<text class="approval-result" :class="getReviewClass(item, 'xsqmyj')">
{{ getReviewDetailText(item, 'xsqmyj') }}
</text>
</view>
</view>
</uni-collapse-item>
</uni-collapse>
<!-- 卡片操作区 -->
<view class="card-actions">
<view>
<uni-button type="text" size="mini" @click="detail(item, '修改')"
v-if="item.step == 0 || isRejected(item)">
<uni-icons type="eye-filled" size="14" class="mr-5"></uni-icons>修改
</uni-button>
<uni-button type="text" size="mini" @click="handleRevoke(item)"
v-if="(item.bjpyyj == null || item.bjpyyj == '') && (item.step == 1 || item.step == 2)">
<uni-icons type="back" size="14" class="mr-5"></uni-icons>撤回
</uni-button>
<uni-button type="text" size="mini" @click="handleDelete(item)"
v-if="item.step == 0">
<uni-icons type="trash" size="14" class="mr-5"></uni-icons>删除
</uni-button>
</view>
<view>
<uni-button type="text" size="mini" @click="detail(item, '详情')" class="detail-btn"
:disabled="!getSafeValue(item, 'id')">
<uni-icons type="info" size="14" class="mr-5"></uni-icons>查看详情
</uni-button>
</view>
</view>
</view>
</view>
<!-- 加载更多状态 -->
<view class="load-more-wrap" v-if="hasData">
<uni-load-more :status="loadingMore ? 'loading' : (hasMore ? 'more' : 'nomore')"
:content-text="loadMoreText"></uni-load-more>
</view>
</scroll-view>
</view>
<!-- 添加申请按钮 -->
<view class="add" @click="applyPoverty" v-if="roleGroup.includes('学生')">+</view>
</view>
</template>
<script>
import { listOwn, delApply, revoke, getKnrdYear, vaild } from '@/api/finance/poverty';
import { getUserProfile } from '@/api/system/user';
export default {
name: "PovertyApplyList",
data() {
return {
// 加载状态
loading: true,
loadingMore: false,
hasMore: true,
// 总数据量
totalCount: 0,
// 原始数据
povertyApplyList: [],
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 5
},
// 用户角色
roleGroup: '',
user: {},
// 加载更多文本
loadMoreText: {
contentdown: '上拉加载更多',
contentrefresh: '正在加载...',
contentnomore: '没有更多数据了'
},
// 学年信息
yearInfoList: [],
stuYearId: '',
currentYear: ''
};
},
computed: {
// 过滤后的有效数据列表
validDataList() {
return this.povertyApplyList.filter(item => {
return item !== null && item !== undefined && typeof item === 'object';
}).map(item => {
if (!item.hasOwnProperty('activeCollapse')) {
item.activeCollapse = 'basic';
}
return item;
});
},
// 是否有有效数据
hasData() {
return this.validDataList.length > 0;
}
},
onShow() {
this.getUser();
},
methods: {
/** 安全取值方法 */
getSafeValue(obj, key, defaultValue = '') {
if (!obj || typeof obj !== 'object') return defaultValue;
return obj[key] !== undefined && obj[key] !== null ? obj[key] : defaultValue;
},
/** 获取状态样式类 */
getStatusClass(item) {
const status = this.getSafeValue(item, 'step');
const typeMap = {
'0': 'status-info',
'2': 'status-warning',
'3': 'status-warning',
'4': 'status-warning',
'5': 'status-success',
'6': 'status-error',
'7': 'status-error'
};
return typeMap[status] || 'status-default';
},
/** 获取状态文本 */
getStatusText(item) {
const status = this.getSafeValue(item, 'step');
const statusMap = {
'0': '待提交',
'2': '辅导员审核中',
'3': '二级学院审核中',
'4': '学校审核中',
'5': '审核通过',
'6': '已拒绝',
'7': '已驳回'
};
return statusMap[status] || '未知状态';
},
/** 获取审核意见样式类 */
getReviewClass(item, type = 'bjpyyj') {
const reviewResult = this.getSafeValue(item, type);
if (!reviewResult) return 'status-default';
const typeMap = {
'1': 'status-success',
'2': 'status-success',
'3': 'status-success',
'4': 'status-error'
};
return typeMap[reviewResult] || 'status-default';
},
/** 获取审核意见文本 */
getReviewText(item) {
if (this.getSafeValue(item, 'xsqmyj')) {
return this.getReviewDetailText(item, 'xsqmyj');
} else if (this.getSafeValue(item, 'ejxyldqmyj')) {
return this.getReviewDetailText(item, 'ejxyldqmyj');
} else if (this.getSafeValue(item, 'bjpyyj')) {
return this.getReviewDetailText(item, 'bjpyyj');
} else {
return '未审核';
}
},
/** 获取详细审核意见文本 */
getReviewDetailText(item, type = 'bjpyyj') {
const reviewResult = this.getSafeValue(item, type);
if (!reviewResult) return '未审核';
const reviewMap = {
'1': '特别困难',
'2': '比较困难',
'3': '一般困难',
'4': '不困难'
};
return reviewMap[reviewResult] || '未知审核结果';
},
/** 时间格式化 */
parseTime(time, format = '{y}-{m}-{d}') {
if (!time) return '';
try {
const date = new Date(time);
if (isNaN(date.getTime())) return '';
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
return format.replace('{y}', year).replace('{m}', month).replace('{d}', day);
} catch (error) {
return '';
}
},
/** 查询数据 */
getList(isRefresh = false) {
if (isRefresh) {
this.loading = true;
this.hasMore = true;
this.queryParams.pageNum = 1;
this.povertyApplyList = [];
} else {
this.loadingMore = true;
}
listOwn(this.queryParams).then(response => {
const res = response || {};
const newData = Array.isArray(res.rows) ? res.rows : [];
this.totalCount = Number(res.total) || 0;
if (isRefresh) {
this.povertyApplyList = newData;
} else {
this.povertyApplyList = [...this.povertyApplyList, ...newData];
}
// 更新状态
this.loading = false;
this.loadingMore = false;
this.hasMore = this.povertyApplyList.length < this.totalCount;
}).catch((error) => {
console.error('数据加载失败:', error);
this.loading = false;
this.loadingMore = false;
uni.showToast({
title: '数据加载失败',
icon: 'none'
});
});
},
/** 获取用户信息 */
getUser() {
getUserProfile().then(response => {
const res = response || {};
this.user = res.data || {};
this.roleGroup = res.roleGroup || '';
// 获取学年信息
this.getYearInfo();
}).catch((error) => {
console.error('用户信息获取失败:', error);
this.loading = false;
uni.showToast({
title: '用户信息加载失败',
icon: 'none'
});
});
},
/** 获取困难认定学年信息 */
getYearInfo() {
getKnrdYear('KNRD').then(response => {
const res = response || {};
if (res.code === 200 && res.data && res.data.length > 0) {
this.yearInfoList = res.data;
// 默认使用第一个学年
this.stuYearId = res.data[0].id;
this.currentYear = res.data[0].stuYearName;
}
this.getList(true);
}).catch((error) => {
console.error('学年信息获取失败:', error);
this.loading = false;
uni.showToast({
title: '学年信息加载失败',
icon: 'none'
});
});
},
/** 加载更多 */
handleLoadMore() {
if (this.loadingMore || !this.hasMore) return;
this.queryParams.pageNum += 1;
this.getList(false);
},
/** 查看详情 */
detail(item, text) {
const id = this.getSafeValue(item, 'id');
if (!id) {
uni.showToast({
title: '数据异常,无法查看详情',
icon: 'none'
});
return;
}
if (text == '详情') {
uni.navigateTo({
url: `/pages/finance/poverty/apply?id=${id}&type=detail`
});
} else {
uni.navigateTo({
url: `/pages/finance/poverty/apply?id=${id}`
});
}
},
/** 撤回申请 */
handleRevoke(item) {
uni.showModal({
title: '确认撤回',
content: '确定要撤回该申请吗?',
success: (res) => {
if (res.confirm) {
// 直接传递item对象与PC端保持一致
revoke(item).then(response => {
console.log('撤回申请响应:', response);
if (response.code === 200 || response.code === 0) {
uni.showToast({
title: '撤回成功',
icon: 'success'
});
this.getList(true);
} else {
uni.showToast({
title: response.msg || '撤回失败',
icon: 'none'
});
}
}).catch(error => {
console.error('撤回申请失败:', error);
uni.showToast({
title: error.response?.data?.msg || error.message || '撤回失败',
icon: 'none'
});
});
}
}
});
},
/** 删除申请 */
handleDelete(item) {
uni.showModal({
title: '确认删除',
content: '确定要删除该申请吗?',
success: (res) => {
if (res.confirm) {
delApply(item.id).then(() => {
uni.showToast({
title: '删除成功',
icon: 'success'
});
this.getList(true);
}).catch(() => {
uni.showToast({
title: '删除失败',
icon: 'none'
});
});
}
}
});
},
// 跳转到申请页面
applyPoverty() {
// 校验申请资格
uni.showLoading({
title: '校验资格中...'
});
vaild({ stuYearId: this.stuYearId }).then(response => {
const res = response || {};
// 打印完整响应,便于调试
console.log('申请资格校验响应:', res);
uni.hideLoading();
// 处理两种可能的响应格式
let valid = -1;
if (res.valid !== undefined) {
// 后端直接返回 {valid: 1} 格式
valid = parseInt(res.valid);
} else if (res.code === 200) {
// 后端返回完整格式 {code: 200, data: {valid: 1}}
valid = parseInt(res.data?.valid || -1);
}
// 根据valid值判断是否允许申请
if (valid === 0) {
// 本学年已经有申请记录,不能重复申请
uni.showToast({
title: '本学年已经有申请记录,不能重复申请',
icon: 'none'
});
} else if (valid === 1) {
// 校验通过,跳转到申请页面
uni.navigateTo({
url: `/pages/finance/poverty/apply?stuYearId=${this.stuYearId}&yearName=${this.currentYear}`
});
} else {
// 校验失败,显示提示
uni.showToast({
title: res.msg || '申请资格校验失败',
icon: 'none'
});
}
}).catch(error => {
uni.hideLoading();
console.error('申请资格校验失败:', error);
uni.showToast({
title: '申请资格校验失败',
icon: 'none'
});
});
},
// 判断是否被拒绝
isRejected(item) {
return item.step === 6 || item.step === 7;
}
}
}
</script>
<style scoped>
.poverty {
background-color: #F3F4F6;
min-height: 100vh;
}
.app-container {
padding-bottom: 10rpx;
}
.list-container {
width: 100%;
min-height: calc(100vh - 88rpx);
}
.loading-wrap {
padding: 20rpx;
text-align: center;
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
color: #c0c4cc;
}
.empty-text {
margin-top: 20rpx;
font-size: 28rpx;
}
.empty-tip {
margin-top: 10rpx;
font-size: 24rpx;
color: #909399;
}
.card-list {
width: 100%;
padding: 5px 15px 0px;
}
.apply-card {
background-color: white;
margin-bottom: 10px;
border-radius: 10px;
overflow: hidden;
}
.card-hover {
opacity: 0.8;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 24rpx;
border-bottom: 1px solid #f0f0f0;
}
.apply-no {
display: flex;
align-items: center;
}
.label-text {
font-size: 26rpx;
color: #606266;
margin-right: 10rpx;
}
.no-text {
font-size: 28rpx;
color: #303133;
font-weight: 500;
}
.status-wrap {
display: flex;
align-items: center;
gap: 10rpx;
}
.status-label {
padding: 4rpx 12rpx;
border-radius: 10rpx;
font-size: 22rpx;
color: white;
}
.status-info {
background-color: #909399;
}
.status-warning {
background-color: #e6a23c;
}
.status-success {
background-color: #67c23a;
}
.status-error {
background-color: #f56c6c;
}
.status-default {
background-color: #909399;
}
.collapse-item {
padding: 0;
}
.info-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 15rpx;
padding: 20rpx 24rpx;
}
.info-item {
display: flex;
align-items: center;
}
.info-item .label {
font-size: 26rpx;
color: #606266;
width: 100rpx;
}
.info-item .value {
font-size: 26rpx;
color: #303133;
flex: 1;
}
.info-form {
padding: 20rpx 24rpx;
}
.form-item {
display: flex;
align-items: flex-start;
margin-bottom: 15rpx;
}
.form-item .label {
font-size: 26rpx;
color: #606266;
width: 140rpx;
padding-top: 5rpx;
}
.form-item .value {
font-size: 26rpx;
color: #303133;
flex: 1;
word-break: break-word;
}
.split-text {
margin: 0 10rpx;
color: #909399;
}
.approval-list {
padding: 20rpx 24rpx;
}
.approval-item {
margin-bottom: 15rpx;
}
.approval-item:last-child {
margin-bottom: 0;
}
.approval-node {
font-size: 26rpx;
color: #606266;
margin-right: 10rpx;
}
.approval-result {
font-size: 26rpx;
padding: 4rpx 12rpx;
border-radius: 10rpx;
color: white;
}
.approval-time {
font-size: 24rpx;
color: #909399;
margin-left: 10rpx;
}
.approval-remark {
display: block;
font-size: 24rpx;
color: #606266;
margin-top: 5rpx;
margin-left: 100rpx;
}
.empty-approval {
padding: 20rpx 24rpx;
color: #909399;
font-size: 26rpx;
text-align: center;
}
.card-actions {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15rpx 24rpx;
border-top: 1px solid #f0f0f0;
}
.detail-btn {
color: #1890FF;
}
.load-more-wrap {
padding: 20rpx;
text-align: center;
}
.add {
position: fixed;
right: 30rpx;
bottom: 30rpx;
width: 80rpx;
height: 80rpx;
background-color: #1890FF;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 48rpx;
box-shadow: 0 4rpx 20rpx rgba(24, 144, 255, 0.3);
}
</style>