学生资助-问题修复

This commit is contained in:
2026-03-11 11:18:05 +08:00
parent b6337714cc
commit 2c2aa68ce1
6 changed files with 243 additions and 194 deletions

View File

@@ -35,6 +35,15 @@ export function updateApply(data) {
})
}
// 保存助学金申请(第一次保存)
export function saveApply(data) {
return request({
url: '/comprehensive/zxj/apply/save',
method: 'post',
data: data
})
}
// 删除助学金申请
export function delApply(id) {
return request({

View File

@@ -327,15 +327,14 @@
<view class="approval-section">
<view class="section-title">学校意见</view>
<view class="approval-content">
<text v-if="formData.zzdj || formData.xxyj || formData.xxmc || formData.xxyjrq" class="approval-text">已审核</text>
<text v-else class="no-content">暂无审核意见</text>
</view>
<text v-if="formData.zzdj || formData.xxmc || formData.xxyjrq" class="approval-text">已审核</text>
<text v-else class="no-content">暂无审核意见</text>
</view>
<view class="approval-info">
<text v-if="formData.zzdj">确认助学金等级:<text class="difficulty-level">{{ getLevelText(formData.zzdj) }}</text></text>
<text v-if="formData.xxyj">学校意见{{ formData.xxyj }}</text>
<text v-if="formData.xxmc">审核{{ formData.xxmc }}</text>
<text v-if="formData.xxyjrq">审核时间{{ formData.xxyjrq }}</text>
</view>
<text v-if="formData.zzdj">确认助学金等级:<text class="difficulty-level">{{ getLevelText(formData.zzdj) }}</text></text>
<text v-if="formData.xxmc">审核人{{ formData.xxmc }}</text>
<text v-if="formData.xxyjrq">审核时间{{ formData.xxyjrq }}</text>
</view>
</view>
</view>
</view>
@@ -377,7 +376,7 @@
</template>
<script>
import { addApply, updateApply, getApply, getStuInfo, getExtraInfo, getFamilyInfo, getCurrentYear, getAidLevels, getZxjStudentInfo, getOwnStudentInfo, findByXhAndApplyYear } from '@/api/finance/financialaid'
import { addApply, updateApply, saveApply, getApply, getStuInfo, getExtraInfo, getFamilyInfo, getCurrentYear, getAidLevels, getZxjStudentInfo, getOwnStudentInfo, findByXhAndApplyYear } from '@/api/finance/financialaid'
import uploadFile from "@/plugins/upload.js"
import { queryAffixs, getAffixItems, uploadFiles, deleteAffix } from '@/api/affix'
import { getUserProfile } from '@/api/system/user'
@@ -626,13 +625,17 @@
this.formData.sfzhm = stuInfoRes.data.idCard || this.formData.sfzhm || ''
}
// 处理学生扩展信息
if (extraRes.code === 200 && extraRes.data) {
// 补充学生扩展信息
this.formData.mz = extraRes.data.mz || this.formData.mz || ''
this.formData.zzmm = extraRes.data.zzmm || this.formData.zzmm || ''
this.formData.dz = extraRes.data.xxlxdz || this.formData.dz || ''
this.formData.yb = extraRes.data.jtyzbm || this.formData.yb || ''
}
if (extraRes.code === 200 && extraRes.data) {
// 补充学生扩展信息
this.formData.mz = extraRes.data.mz || this.formData.mz || ''
this.formData.zzmm = extraRes.data.zzmm || this.formData.zzmm || ''
this.formData.dz = extraRes.data.xxlxdz || this.formData.dz || ''
this.formData.yb = extraRes.data.jtyzbm || this.formData.yb || ''
// 从 extraInfo 接口回显证件照
if (extraRes.data.whitePhoto) {
this.formData.zp = extraRes.data.whitePhoto
}
}
// 查询贫困申请信息
if (this.formData.xh && this.formData.stuYearId) {
findByXhAndApplyYear({
@@ -924,9 +927,19 @@
// 删除文件
deleteFile(index) {
const deletedFile = this.affixFiles[index];
// 从文件列表中移除
this.affixFiles.splice(index, 1);
if (this.affixFiles.length === 0) {
this.formData.affixId = null;
// 重新生成 affixId确保后端知道文件列表已经发生变化
this.formData.affixId = this.affixFiles.length > 0 ? this.generateUUID() : null;
// 调用后端接口删除文件
if (deletedFile.fileId) {
deleteAffix(deletedFile.fileId).then(res => {
if (res.code === 200) {
console.log('文件删除成功');
}
}).catch(err => {
console.error('文件删除失败:', err);
});
}
uni.showToast({
title: '删除成功',
@@ -954,26 +967,26 @@
})
},
// 保存表单
saveForm() {
if (!this.validateForm()) {
return
}
this.loading = true
const submitData = { ...this.formData }
// 如果有申请ID则更新申请否则新增申请
const request = this.applyId ? updateApply(submitData) : addApply(submitData)
request.then(res => {
if (res.code === 200) {
uni.showToast({ title: '保存成功', icon: 'success' })
// 如果是新增申请保存成功后获取申请ID
if (!this.applyId) {
this.applyId = res.data.id
}
saveForm() {
if (!this.validateForm()) {
return
}
this.loading = true
const submitData = { ...this.formData }
// 如果有申请ID则更新申请否则第一次保存调用save接口
const request = this.applyId ? updateApply(submitData) : saveApply(submitData)
request.then(res => {
if (res.code === 200) {
uni.showToast({ title: '保存成功', icon: 'success' })
// 如果是第一次保存保存成功后获取申请ID
if (!this.applyId) {
this.applyId = res.data.id
}
}).finally(() => {
this.loading = false
})
},
}
}).finally(() => {
this.loading = false
})
},
// 提交申请
submitForm() {
if (!this.validateForm()) {
@@ -1186,6 +1199,7 @@
title: submit ? '申请提交成功' : '表单保存成功',
icon: 'success'
})
this.goBack()
// 如果是提交申请,跳转到列表页面
if (submit) {
uni.redirectTo({
@@ -1208,13 +1222,15 @@
this.loading = false
})
} else {
// 新增申请
addApply(data).then(res => {
// 第一次保存调用save接口提交申请调用add接口
const request = submit ? addApply(data) : saveApply(data)
request.then(res => {
if (res.code === 200) {
uni.showToast({
title: submit ? '申请提交成功' : '表单保存成功',
icon: 'success'
})
this.goBack()
// 如果是提交申请,跳转到列表页面
if (submit) {
uni.redirectTo({
@@ -1231,13 +1247,6 @@
})
}
this.loading = false
}).catch(err => {
console.error('新增申请失败:', err)
uni.showToast({
title: submit ? '申请提交失败' : '表单保存失败',
icon: 'none'
})
this.loading = false
})
}
},

View File

@@ -91,7 +91,7 @@
<view class="card-actions">
<view>
<uni-button type="text" size="mini" @click="detail(item, '修改')"
v-if="item.step == 0 || isRejected(item)">
v-if="item.step == 0">
<uni-icons type="eye-filled" size="14" class="mr-5"></uni-icons>修改
</uni-button>
<uni-button type="text" size="mini" @click="handleRevoke(item)"
@@ -99,7 +99,7 @@
<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">
v-if="item.step == 0 || isRejected(item)">
<uni-icons type="trash" size="14" class="mr-5"></uni-icons>删除
</uni-button>
</view>

View File

@@ -93,19 +93,18 @@
<view class="form-item">
<label class="form-label"><span class="red-tip">*</span>证件照</label>
<!-- 编辑模式显示上传组件 -->
<view class="upload-container" v-if="type !== 'detail'">
<view class="upload-btn" @click="handlePhotoUpload">
<text class="upload-icon">+</text>
<text>上传文件</text>
</view>
<view class="file-list" v-if="photoFiles.length">
<view class="file-item" v-for="(file, index) in photoFiles" :key="index">
<text class="file-name" @click="previewPhoto">{{ file.name }}</text>
<uni-icons type="trash-filled" size="30" @click="deletePhoto" class="delete-btn"></uni-icons>
</view>
</view>
<view class="upload-tip">请上传电子版一寸照支持JPGPNG格式</view>
<view class="example-body" v-if="type !== 'detail'">
<uni-file-picker
@select="handlePhotoUpload"
@delete="deletePhoto"
:auto-upload="false"
limit="1"
:disabled="type === 'detail'"
mode="grid"
:value="filePickerValue"
></uni-file-picker>
</view>
<view class="upload-tip" v-if="type !== 'detail'">支持上传jpg/png格式照片单个文件不超过5MB</view>
<!-- 详情模式显示照片预览 -->
<view class="photo-preview-container" v-if="formData.pic && type === 'detail'">
<image :src="getFullImageUrl(formData.pic)" mode="aspectFill"></image>
@@ -523,93 +522,86 @@ import config from "@/config.js";
},
// 处理证件照上传
handlePhotoUpload() {
handlePhotoUpload(e) {
// 如果是详情模式,不执行上传操作
if (this.type === 'detail') {
return;
}
uni.chooseFile({
count: 1, // 最多选择1个文件
extension: ['jpg', 'jpeg', 'png'], // 限制文件类型
success: async (chooseRes) => {
// 遍历选择的文件,逐个上传
for (const file of chooseRes.tempFiles) {
try {
// 检查文件大小10MB = 10 * 1024 * 1024 bytes
if (file.size > 10 * 1024 * 1024) {
uni.showToast({
title: `文件 ${file.name} 大小超过10MB请重新选择`,
icon: 'none'
});
continue;
}
const tempFiles = e.tempFilePaths || [];
// 检查文件格式
const ext = file.name.split('.').pop().toLowerCase();
const allowedExts = ['jpg', 'jpeg', 'png'];
if (!allowedExts.includes(ext)) {
uni.showToast({
title: `文件 ${file.name} 格式不支持,请选择 JPG、PNG 格式的文件`,
icon: 'none'
});
continue;
}
// 遍历选择的文件,逐个上传
for (const file of e.tempFiles) {
this.uploadFile(file);
}
},
// 上传文件
const uploadRes = await uploadFile('/common/upload', file.path);
const result = typeof uploadRes === 'string' ? JSON.parse(uploadRes) : uploadRes;
// 上传结果校验
if (result && (result.code === 200 || !result.code)) {
// 构造文件信息对象
const fileUrl = result.savePath || result.fileName;
const fullUrl = this.baseUrl + fileUrl;
const fileInfo = {
name: file.name,
path: fileUrl,
url: fullUrl
};
// 更新 formData.pic
this.formData.pic = fileUrl;
// 更新 photoFiles 数组
this.photoFiles = [fileInfo];
uni.showToast({
title: `文件 ${file.name} 上传成功`,
icon: 'success',
duration: 1500
});
} else {
// 上传失败处理
uni.showToast({
title: `文件 ${file.name} 上传失败:${result.message || '未知错误'}`,
icon: 'none',
duration: 2000
});
}
} catch (error) {
// 异常捕获
console.error(`文件 ${file.name} 上传异常:`, error);
uni.showToast({
title: `文件 ${file.name} 上传异常:${error.message || '请检查网络连接'}`,
icon: 'none',
duration: 2000
});
}
}
},
// 取消选择文件的处理
fail: (err) => {
console.error('选择文件失败:', err);
// 上传文件的通用方法
async uploadFile(file) {
try {
// 检查文件大小5MB = 5 * 1024 * 1024 bytes
if (file.size > 5 * 1024 * 1024) {
uni.showToast({
title: '选择文件失败,请重试',
title: `文件 ${file.name} 大小超过5MB请重新选择`,
icon: 'none'
});
return;
}
});
// 检查文件格式
const ext = file.name.split('.').pop().toLowerCase();
const allowedExts = ['jpg', 'jpeg', 'png'];
if (!allowedExts.includes(ext)) {
uni.showToast({
title: `文件 ${file.name} 格式不支持,请选择 JPG、PNG 格式的文件`,
icon: 'none'
});
return;
}
// 上传文件
const uploadRes = await uploadFile('/common/upload', file.path);
const result = typeof uploadRes === 'string' ? JSON.parse(uploadRes) : uploadRes;
// 上传结果校验
if (result && (result.code === 200 || !result.code)) {
// 构造文件信息对象
const fileUrl = result.savePath || result.fileName;
const fullUrl = this.getFullImageUrl(fileUrl);
const fileInfo = {
name: file.name,
path: fileUrl,
url: fullUrl
};
// 更新 formData.pic
this.formData.pic = fileUrl;
// 更新 photoFiles 数组,确保 uni-file-picker 组件能获取预览路径
this.photoFiles = [fileInfo];
uni.showToast({
title: `文件 ${file.name} 上传成功`,
icon: 'success',
duration: 1500
});
} else {
// 上传失败处理
uni.showToast({
title: `文件 ${file.name} 上传失败:${result.message || '未知错误'}`,
icon: 'none',
duration: 2000
});
}
} catch (error) {
// 异常捕获
console.error(`文件 ${file.name} 上传异常:`, error);
uni.showToast({
title: `文件 ${file.name} 上传异常:${error.message || '请检查网络连接'}`,
icon: 'none',
duration: 2000
});
}
},
// 删除证件照
@@ -1487,6 +1479,11 @@ import config from "@/config.js";
line-height: 1.4;
}
/* 证件照上传容器 */
.example-body {
margin-top: 10rpx;
}
/* 照片预览容器 */
.photo-preview-container {
margin-top: 20rpx;

View File

@@ -448,8 +448,9 @@
<script>
import { addApply, updateApply, getApply, infoCheck, getStuByXh, getxh, extraInfo, stuInfoView, getOwnFamily, getCurrentYear, queryByStuNo, getKnrdYear } from '@/api/finance/poverty'
import uploadFile from "@/plugins/upload.js"
import { queryAffixs, getAffixItems } from '@/api/affix'
import uploadFile from "@/plugins/upload.js"
import { queryAffixs, getAffixItems, deleteAffix } from '@/api/affix'
import config from '@/config'
export default {
data() {
return {
@@ -547,7 +548,7 @@
affixFiles: [],
loading: false,
signImg: '',
baseUrl: uni.getStorageSync('baseUrl')
baseUrl: config.baseUrl || ''
}
},
onLoad(option) {
@@ -671,12 +672,13 @@
this.formData.sqrcn = this.formData.sqrcn.toString()
}
// 处理手写签字
if (this.formData.sqrqm) {
// 从sqrqm构造完整的图片URL
this.signImg = this.baseUrl + this.formData.sqrqm
// 处理手写签字支持sqrqm和applySign字段
const signPath = this.formData.sqrqm || this.formData.applySign;
if (signPath) {
// 构造完整的图片URL
this.signImg = this.baseUrl + signPath;
} else {
this.signImg = ''
this.signImg = '';
}
// 处理困难佐证材料
@@ -945,11 +947,7 @@
}
console.log('handleUpload方法被调用');
// 测试点击事件是否正常
uni.showToast({
title: '测试点击事件',
icon: 'none'
});
// 1. 定义affixId生成工具函数确保uuid唯一性
const generateUUID = () => {
@@ -1040,16 +1038,35 @@
});
},
// 删除文件
deleteFile(index) {
async deleteFile(index) {
const deletedFile = this.affixFiles[index];
this.affixFiles.splice(index, 1);
if (this.affixFiles.length === 0) {
this.formData.affixId = null;
if (!deletedFile) return;
try {
// 调用后端删除接口
if (deletedFile.fileId) {
await deleteAffix(deletedFile.fileId);
}
// 从数组中删除文件
this.affixFiles.splice(index, 1);
// 如果没有文件了清空affixId
if (this.affixFiles.length === 0) {
this.formData.affixId = null;
}
uni.showToast({
title: '删除成功',
icon: 'success'
});
} catch (error) {
console.error('删除文件失败:', error);
uni.showToast({
title: '删除失败,请重试',
icon: 'none'
});
}
uni.showToast({
title: '删除成功',
icon: 'success'
});
},
// 预览文件
previewImage(url) {

View File

@@ -262,6 +262,7 @@
<script>
import { addApply, updateApply, getApply, getOwnFamily, getOwnKnrd, getOwnExtraInfo, getOwnInfo, reApply } from '@/api/finance/special';
import uploadFile from "@/plugins/upload.js"
import config from '@/config'
export default {
data() {
@@ -333,7 +334,7 @@ export default {
],
affixFiles: [],
signImg: '',
baseUrl: uni.getStorageSync('baseUrl')
baseUrl: config.baseUrl || ''
};
},
onLoad(option) {
@@ -393,23 +394,27 @@ export default {
} else {
this.signImg = '';
}
// 处理困难佐证材料
if (this.listData.hardFile) {
// 文件路径中提取文件名
const fileName = this.listData.hardFile.split('/').pop();
// 构造文件信息对象
this.affixFiles = [{
attachmentName: fileName,
attachmentUrl: this.listData.hardFile,
serverUrl: this.listData.hardFile,
fileId: '',
fileSize: 0,
fileSuffix: fileName.split('.').pop().toLowerCase(),
savePath: this.listData.hardFile
}];
} else {
this.affixFiles = [];
}
// 处理困难佐证材料(支持多个文件)
if (this.listData.hardFile) {
// 分割文件路径字符串
const filePaths = this.listData.hardFile.split(',');
// 构造文件信息对象数组
this.affixFiles = filePaths.map(filePath => {
// 从文件路径中提取文件名
const fileName = filePath.split('/').pop();
return {
attachmentName: fileName,
attachmentUrl: filePath,
serverUrl: filePath,
fileId: '',
fileSize: 0,
fileSuffix: fileName.split('.').pop().toLowerCase(),
savePath: filePath
};
});
} else {
this.affixFiles = [];
}
} else {
// 否则,调用接口获取申请详情
await this.getApplyDetail();
@@ -693,23 +698,27 @@ export default {
} else {
this.signImg = '';
}
// 处理困难佐证材料
if (data.hardFile) {
// 文件路径中提取文件名
const fileName = data.hardFile.split('/').pop();
// 构造文件信息对象
this.affixFiles = [{
attachmentName: fileName,
attachmentUrl: data.hardFile,
serverUrl: data.hardFile,
fileId: '',
fileSize: 0,
fileSuffix: fileName.split('.').pop().toLowerCase(),
savePath: data.hardFile
}];
} else {
this.affixFiles = [];
}
// 处理困难佐证材料(支持多个文件)
if (data.hardFile) {
// 分割文件路径字符串
const filePaths = data.hardFile.split(',');
// 构造文件信息对象数组
this.affixFiles = filePaths.map(filePath => {
// 从文件路径中提取文件名
const fileName = filePath.split('/').pop();
return {
attachmentName: fileName,
attachmentUrl: filePath,
serverUrl: filePath,
fileId: '',
fileSize: 0,
fileSuffix: fileName.split('.').pop().toLowerCase(),
savePath: filePath
};
});
} else {
this.affixFiles = [];
}
}
} catch (error) {
console.error('获取申请详情失败:', error);
@@ -732,6 +741,14 @@ export default {
applyDate: new Date()
};
// 处理困难佐证材料,将 affixFiles 转换为 hardFile支持多个文件用逗号分隔
if (this.affixFiles.length > 0) {
// 将所有文件的路径用逗号分隔拼接成一个字符串
submitData.hardFile = this.affixFiles.map(file => file.savePath).join(',');
} else {
submitData.hardFile = '';
}
this.loading = true;
try {
let res;