学生资助-修复图片文件预览问题

This commit is contained in:
2026-03-05 14:37:37 +08:00
parent 6fb7c809cb
commit b6337714cc
4 changed files with 309 additions and 83 deletions

View File

@@ -96,19 +96,25 @@
<input v-model="formData.sfzhm" placeholder="请输入身份证号码" class="form-input" :disabled="detailMode"></input> <input v-model="formData.sfzhm" placeholder="请输入身份证号码" class="form-input" :disabled="detailMode"></input>
</view> </view>
<view class="form-item"> <view class="form-item">
<label class="form-label"><span class="red-tip">*</span>电子版一寸照</label> <label class="form-label"><span class="red-tip">*</span>电子版一寸照</label>
<view class="example-body"> <!-- 编辑模式显示上传组件 -->
<uni-file-picker <view class="example-body" v-if="!detailMode">
@select="handlePhotoUpload" <uni-file-picker
@delete="deletePhoto" @select="handlePhotoUpload"
:auto-upload="false" @delete="deletePhoto"
limit="1" :auto-upload="false"
:disabled="detailMode" limit="1"
mode="grid" :disabled="detailMode"
></uni-file-picker> mode="grid"
</view> :value="filePickerValue"
<view class="upload-tip" v-if="!detailMode">支持上传jpg/png格式照片单个文件不超过5MB</view> ></uni-file-picker>
</view> </view>
<view class="upload-tip" v-if="!detailMode">支持上传jpg/png格式照片单个文件不超过5MB</view>
<!-- 详情模式显示照片预览 -->
<view class="photo-preview-container" v-if="formData.zp && detailMode">
<image :src="getFullImageUrl(formData.zp)" mode="aspectFill"></image>
</view>
</view>
<view class="form-item"> <view class="form-item">
<label class="form-label"><span class="red-tip">*</span>二级学院</label> <label class="form-label"><span class="red-tip">*</span>二级学院</label>
<input v-model="formData.xy" placeholder="请输入二级学院" class="form-input" :disabled="detailMode"></input> <input v-model="formData.xy" placeholder="请输入二级学院" class="form-input" :disabled="detailMode"></input>
@@ -375,6 +381,7 @@
import uploadFile from "@/plugins/upload.js" import uploadFile from "@/plugins/upload.js"
import { queryAffixs, getAffixItems, uploadFiles, deleteAffix } from '@/api/affix' import { queryAffixs, getAffixItems, uploadFiles, deleteAffix } from '@/api/affix'
import { getUserProfile } from '@/api/system/user' import { getUserProfile } from '@/api/system/user'
import config from '@/config'
export default { export default {
data() { data() {
return { return {
@@ -402,33 +409,33 @@
yb: '', yb: '',
zzls: '', zzls: '',
gyhd: '', gyhd: '',
rkzs: '', rkzs: '',
rjnsr: '', rjnsr: '',
srly: '', srly: '',
dz: '', dz: '',
kndj: '', kndj: '',
knlx: '', knlx: '',
bankCard: '', bankCard: '',
bankAddr: '', bankAddr: '',
jtcyObj: [ jtcyObj: [
{ {
xm: '', xm: '',
nl: '', nl: '',
gx: '', gx: '',
dw: '', dw: '',
lxdh: '', lxdh: '',
zy: '', zy: '',
nsr: '', nsr: '',
jkzk: '' jkzk: ''
} }
], ],
sqly: '', sqly: '',
affixId: null, affixId: null,
bjyj: '', bjyj: '',
bjyjdj: '', bjyjdj: '',
ejxyyj: '', ejxyyj: '',
ejxyyjdj: '' ejxyyjdj: ''
}, },
genderOptions: [ genderOptions: [
{ value: '男', text: '男' }, { value: '男', text: '男' },
{ value: '女', text: '女' } { value: '女', text: '女' }
@@ -438,7 +445,19 @@
affixFiles: [], affixFiles: [],
loading: false, loading: false,
signImg: '', signImg: '',
baseUrl: uni.getStorageSync('baseUrl') || '' baseUrl: config.baseUrl || ''
}
},
computed: {
filePickerValue() {
if (this.formData.zp) {
return [{
url: this.getFullImageUrl(this.formData.zp),
name: '证件照',
size: 0
}];
}
return [];
} }
}, },
onLoad(option) { onLoad(option) {
@@ -524,6 +543,12 @@
if (this.formData.xsqm) { if (this.formData.xsqm) {
this.signImg = this.baseUrl + this.formData.xsqm; this.signImg = this.baseUrl + this.formData.xsqm;
} }
// 处理证件照回显
if (this.formData.zp) {
console.log('证件照路径:', this.formData.zp);
console.log('baseUrl:', this.baseUrl);
console.log('完整URL:', this.getFullImageUrl(this.formData.zp));
}
} }
}).finally(() => { }).finally(() => {
this.loading = false this.loading = false
@@ -884,8 +909,8 @@
if (path.startsWith('http://') || path.startsWith('https://')) { if (path.startsWith('http://') || path.startsWith('https://')) {
return path; return path;
} }
// 直接从存储中获取最新的baseUrl // 使用配置文件中的baseUrl
const currentBaseUrl = uni.getStorageSync('baseUrl') || ''; const currentBaseUrl = config.baseUrl || '';
console.log('当前baseUrl:', currentBaseUrl); console.log('当前baseUrl:', currentBaseUrl);
// 处理baseUrl确保结尾没有斜杠 // 处理baseUrl确保结尾没有斜杠
const baseUrlClean = currentBaseUrl.replace(/\/$/, ''); const baseUrlClean = currentBaseUrl.replace(/\/$/, '');
@@ -1501,9 +1526,22 @@
cursor: pointer; cursor: pointer;
} }
.sign-disabled { .sign-disabled {
opacity: 0.5; opacity: 0.5;
cursor: not-allowed; cursor: not-allowed;
} }
/* 证件照预览容器样式 */
.photo-preview-container {
margin-top: 20rpx;
border-radius: 8rpx;
overflow: hidden;
}
.photo-preview-container image {
width: 200rpx;
height: 200rpx;
border-radius: 8rpx;
}
.submit-container { .submit-container {
position: fixed; position: fixed;
bottom: 0; bottom: 0;

View File

@@ -82,20 +82,28 @@
<label class="form-label"><span class="red-tip">*</span>入学时间</label> <label class="form-label"><span class="red-tip">*</span>入学时间</label>
<input v-model="formData.inTime" placeholder="请输入入学时间" class="form-input" :disabled="type === 'detail'" ></input> <input v-model="formData.inTime" placeholder="请输入入学时间" class="form-input" :disabled="type === 'detail'" ></input>
</view> </view>
<!-- <view class="form-item"> <view class="form-item">
<label class="form-label"><span class="red-tip">*</span>证件照</label> <label class="form-label"><span class="red-tip">*</span>证件照</label>
<view class="example-body"> <!-- 编辑模式显示上传组件 -->
<uni-file-picker <view class="example-body" v-if="type !== 'detail'">
@select="handlePhotoUpload" <uni-file-picker
@delete="deletePhoto" @select="handlePhotoUpload"
:auto-upload="false" @delete="deletePhoto"
limit="1" :auto-upload="false"
:disabled="type === 'detail'" limit="1"
mode="grid" :disabled="type === 'detail'"
></uni-file-picker> mode="grid"
:value="filePickerValue"
preview-full-image
image-mode="aspectFill"
></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>
</view>
</view> </view>
<view class="upload-tip" v-if="type !== 'detail'">支持上传jpg/png格式照片单个文件不超过5MB</view>
</view> -->
<view class="form-item"> <view class="form-item">
<label class="form-label">曾获资助/奖励</label> <label class="form-label">曾获资助/奖励</label>
<textarea v-model="formData.helpHis" placeholder="请输入曾获资助或奖励情况" class="form-textarea" rows="3" :disabled="type === 'detail'" ></textarea> <textarea v-model="formData.helpHis" placeholder="请输入曾获资助或奖励情况" class="form-textarea" rows="3" :disabled="type === 'detail'" ></textarea>
@@ -289,6 +297,7 @@
import { getOwnSign } from '@/api/workStudy/post'; import { getOwnSign } from '@/api/workStudy/post';
import { getOwnKnrd, getOwnExtraInfo, getOwnInfo as getOwnStuInfo } from '@/api/finance/special'; import { getOwnKnrd, getOwnExtraInfo, getOwnInfo as getOwnStuInfo } from '@/api/finance/special';
import uploadFile from "@/plugins/upload.js" import uploadFile from "@/plugins/upload.js"
import config from '@/config'
export default { export default {
data() { data() {
return { return {
@@ -354,7 +363,7 @@
}, },
affixFiles: [], affixFiles: [],
signImg: '', signImg: '',
baseUrl: uni.getStorageSync('baseUrl') baseUrl: config.baseUrl || ''
}; };
}, },
onLoad(option) { onLoad(option) {
@@ -382,6 +391,18 @@
onShow() { onShow() {
this.calculateFormHeight(); this.calculateFormHeight();
}, },
computed: {
filePickerValue() {
if (this.formData.pic) {
return [{
url: this.getFullImageUrl(this.formData.pic),
name: '证件照',
size: 0
}];
}
return [];
}
},
methods: { methods: {
// 计算表单滚动区域高度 // 计算表单滚动区域高度
calculateFormHeight() { calculateFormHeight() {
@@ -639,6 +660,22 @@
}; };
}); });
} }
// 处理证件照
if (this.formData.pic) {
// 从文件路径中提取文件名
const fileName = this.formData.pic.split('/').pop();
// 构造完整的图片URL
const fullUrl = this.getFullImageUrl(this.formData.pic);
// 更新 photoFiles 数组,使 uni-file-picker 组件能够预览图片
this.photoFiles = [{
name: fileName,
path: this.formData.pic,
url: fullUrl
}];
console.log('处理证件照formData.pic:', this.formData.pic);
console.log('fullUrl:', fullUrl);
console.log('photoFiles:', this.photoFiles);
}
}).catch(error => { }).catch(error => {
console.error('获取详情失败:', error); console.error('获取详情失败:', error);
uni.showToast({ uni.showToast({
@@ -951,7 +988,18 @@
// 处理证件照上传 // 处理证件照上传
handlePhotoUpload(e) { handlePhotoUpload(e) {
const file = e.tempFile; // 检查事件参数格式
console.log('handlePhotoUpload 事件参数:', e);
// 从事件参数中获取文件信息
const file = e.tempFiles ? e.tempFiles[0] : e.tempFile;
if (!file) {
uni.showToast({
title: '获取文件信息失败',
icon: 'none'
});
return;
}
// 检查文件大小 // 检查文件大小
if (file.size > 5 * 1024 * 1024) { if (file.size > 5 * 1024 * 1024) {
@@ -974,11 +1022,33 @@
uni.showLoading({ title: '上传中...' }); uni.showLoading({ title: '上传中...' });
uploadFile('/common/upload', file.path).then((res) => { // 获取文件路径
const filePath = file.path || file.tempFilePath;
if (!filePath) {
uni.showToast({
title: '获取文件路径失败',
icon: 'none'
});
return;
}
uploadFile('/common/upload', filePath).then((res) => {
uni.hideLoading(); uni.hideLoading();
const result = typeof res === 'string' ? JSON.parse(res) : res; const result = typeof res === 'string' ? JSON.parse(res) : res;
if (result && result.code === 200) { if (result && result.code === 200) {
this.formData.pic = result.fileName || result.savePath; this.formData.pic = result.fileName || result.savePath;
// 构造完整的图片URL
const fullUrl = this.getFullImageUrl(this.formData.pic);
// 更新 photoFiles 数组,使 uni-file-picker 组件能够预览图片
this.photoFiles = [{
name: file.name,
path: filePath,
url: fullUrl
}];
console.log('上传成功formData.pic:', this.formData.pic);
console.log('fullUrl:', fullUrl);
console.log('filePickerValue:', this.filePickerValue);
console.log('photoFiles:', this.photoFiles);
uni.showToast({ uni.showToast({
title: '证件照上传成功', title: '证件照上传成功',
icon: 'success' icon: 'success'
@@ -1006,6 +1076,27 @@
title: '证件照已删除', title: '证件照已删除',
icon: 'success' icon: 'success'
}); });
},
// 获取完整图片URL
getFullImageUrl(path) {
if (!path) return '';
// 调试信息
console.log('getFullImageUrl调用path:', path);
// 如果已经是完整URL则直接返回
if (path.startsWith('http://') || path.startsWith('https://')) {
return path;
}
// 使用配置文件中的baseUrl
const currentBaseUrl = config.baseUrl || '';
console.log('当前baseUrl:', currentBaseUrl);
// 处理baseUrl确保结尾没有斜杠
const baseUrlClean = currentBaseUrl.replace(/\/$/, '');
// 处理path确保开头没有斜杠
const pathClean = path.replace(/^\//, '');
// 拼接URL
const fullUrl = `${baseUrlClean}/${pathClean}`;
console.log('拼接后的完整URL:', fullUrl);
return fullUrl;
} }
} }
}; };
@@ -1231,8 +1322,19 @@
} }
.example-body { .example-body {
margin-top: 10rpx; margin-top: 10rpx;
} }
.photo-preview-container {
margin-top: 20rpx;
border-radius: 8rpx;
overflow: hidden;
}
.photo-preview-container image {
width: 200rpx;
height: 200rpx;
border-radius: 8rpx;
}
.sign { .sign {
width: 200px; width: 200px;

View File

@@ -228,15 +228,15 @@
<textarea v-model="formData.applyReasonExtra" placeholder="请详细描述申请理由" class="form-textarea" rows="4" :disabled="detailMode"></textarea> <textarea v-model="formData.applyReasonExtra" placeholder="请详细描述申请理由" class="form-textarea" rows="4" :disabled="detailMode"></textarea>
</view> </view>
<view class="form-item"> <view class="form-item">
<label class="form-label"><span class="red-tip">*</span>申请人签名</label> <label class="form-label"><span class="red-tip">*</span>申请人签名</label>
<view class="sign-img" v-if="signImg"> <view class="sign-img" v-if="signImg">
<image :src="signImg" mode="aspectFit" style="width: 200px; height: 50px; cursor: pointer;"></image> <image :src="signImg" mode="aspectFit" style="width: 200px; height: 50px; cursor: pointer;" @tap="previewSign"></image>
<text @tap="signToggle" class="re-sign-text">重新签名</text> <text @tap="signToggle" class="re-sign-text" v-if="!detailMode">重新签名</text>
</view>
<view v-else class="sign" @tap="signToggle" :class="{ 'sign-disabled': detailMode }">
点击签名
</view>
</view> </view>
<view v-else class="sign" @tap="signToggle" :class="{ 'sign-disabled': detailMode }">
点击签名
</view>
</view>
<view class="form-item"> <view class="form-item">
<label class="form-label"><span class="red-tip">*</span>中职毕业证</label> <label class="form-label"><span class="red-tip">*</span>中职毕业证</label>
<view class="upload-btn" @click="handleDiplomaUpload" :class="{ 'upload-disabled': detailMode }"> <view class="upload-btn" @click="handleDiplomaUpload" :class="{ 'upload-disabled': detailMode }">
@@ -316,6 +316,7 @@
<script> <script>
import { add, update, reApply, getOwnSign, getOwnFamily, getStudentInfo, getExtraInfo } from '@/api/finance/knzzZsg'; import { add, update, reApply, getOwnSign, getOwnFamily, getStudentInfo, getExtraInfo } from '@/api/finance/knzzZsg';
import uploadFile from "@/plugins/upload.js" import uploadFile from "@/plugins/upload.js"
import config from '@/config'
export default { export default {
data() { data() {
@@ -324,7 +325,7 @@ export default {
detailMode: false, detailMode: false,
formScrollHeight: '', formScrollHeight: '',
signImg: '', signImg: '',
baseUrl: uni.getStorageSync('baseUrl'), baseUrl: config.baseUrl || '',
diplomaFiles: [], diplomaFiles: [],
diplomaAffixId: '', diplomaAffixId: '',
genderOptions: [ genderOptions: [
@@ -575,9 +576,12 @@ export default {
this.formData.applyReasonExtra = item.applyExtraReason || ''; this.formData.applyReasonExtra = item.applyExtraReason || '';
// 签名和文件信息 // 签名和文件信息
this.formData.applySign = item.applySign || ''; this.formData.applySign = item.applySign || '';
this.formData.diplomaFile = item.diplomaCertificate || ''; this.formData.diplomaFile = item.diplomaCertificate || '';
this.signImg = item.applySign || ''; // 构造完整的签名图片URL
this.signImg = item.applySign ? this.getFullImageUrl(item.applySign) : '';
console.log('处理签名图片item.applySign:', item.applySign);
console.log('signImg:', this.signImg);
// 审核意见 // 审核意见
this.formData.fdyCmt = item.fdyCmt || ''; this.formData.fdyCmt = item.fdyCmt || '';
@@ -806,9 +810,38 @@ export default {
uploadFile('/common/upload', e).then((res) => { uploadFile('/common/upload', e).then((res) => {
const data = JSON.parse(res); const data = JSON.parse(res);
this.formData.applySign = data.fileName; this.formData.applySign = data.fileName;
this.signImg = data.url || (this.baseUrl + data.fileName); this.signImg = data.url || this.getFullImageUrl(data.fileName);
}) })
}, },
// 获取完整图片URL
getFullImageUrl(path) {
if (!path) return '';
// 调试信息
console.log('getFullImageUrl调用path:', path);
// 如果已经是完整URL则直接返回
if (path.startsWith('http://') || path.startsWith('https://')) {
return path;
}
// 使用配置文件中的baseUrl
const currentBaseUrl = config.baseUrl || '';
console.log('当前baseUrl:', currentBaseUrl);
// 处理baseUrl确保结尾没有斜杠
const baseUrlClean = currentBaseUrl.replace(/\/$/, '');
// 处理path确保开头没有斜杠
const pathClean = path.replace(/^\//, '');
// 拼接URL
const fullUrl = `${baseUrlClean}/${pathClean}`;
console.log('拼接后的完整URL:', fullUrl);
return fullUrl;
},
// 预览签名图片
previewSign() {
if (this.signImg) {
uni.previewImage({
urls: [this.signImg]
});
}
},
// 处理中职毕业证上传 // 处理中职毕业证上传
handleDiplomaUpload() { handleDiplomaUpload() {
if (this.detailMode) { if (this.detailMode) {

View File

@@ -92,19 +92,24 @@
</view> </view>
<view class="form-item"> <view class="form-item">
<label class="form-label"><span class="red-tip">*</span>证件照</label> <label class="form-label"><span class="red-tip">*</span>证件照</label>
<view class="upload-container"> <!-- 编辑模式显示上传组件 -->
<view class="upload-btn" @click="handlePhotoUpload" :class="{ 'upload-disabled': type === 'detail' }"> <view class="upload-container" v-if="type !== 'detail'">
<view class="upload-btn" @click="handlePhotoUpload">
<text class="upload-icon">+</text> <text class="upload-icon">+</text>
<text>{{ type === 'detail' ? '已上传证件照' : '上传文件' }}</text> <text>上传文件</text>
</view> </view>
<view class="file-list" v-if="photoFiles.length"> <view class="file-list" v-if="photoFiles.length">
<view class="file-item" v-for="(file, index) in photoFiles" :key="index"> <view class="file-item" v-for="(file, index) in photoFiles" :key="index">
<text class="file-name" @click="previewPhoto">{{ file.name }}</text> <text class="file-name" @click="previewPhoto">{{ file.name }}</text>
<uni-icons type="trash-filled" size="30" @click="deletePhoto" v-if="type !== 'detail'" class="delete-btn"></uni-icons> <uni-icons type="trash-filled" size="30" @click="deletePhoto" class="delete-btn"></uni-icons>
</view> </view>
</view> </view>
<view class="upload-tip">请上传电子版一寸照支持JPGPNG格式</view> <view class="upload-tip">请上传电子版一寸照支持JPGPNG格式</view>
</view> </view>
<!-- 详情模式显示照片预览 -->
<view class="photo-preview-container" v-if="formData.pic && type === 'detail'">
<image :src="getFullImageUrl(formData.pic)" mode="aspectFill"></image>
</view>
</view> </view>
</view> </view>
</view> </view>
@@ -306,7 +311,7 @@ import config from "@/config.js";
// 签名图片 // 签名图片
signImg: '', signImg: '',
// 基础URL // 基础URL
baseUrl: uni.getStorageSync('baseUrl'), baseUrl: config.baseUrl || '',
// 选项卡状态 // 选项卡状态
activeTab: 0, activeTab: 0,
// 表单滚动高度 // 表单滚动高度
@@ -346,6 +351,18 @@ import config from "@/config.js";
onResize() { onResize() {
this.calculateFormHeight(); this.calculateFormHeight();
}, },
computed: {
filePickerValue() {
if (this.formData.pic) {
return [{
url: this.getFullImageUrl(this.formData.pic),
name: '证件照',
size: 0
}];
}
return [];
}
},
methods: { methods: {
// 计算表单高度 // 计算表单高度
calculateFormHeight() { calculateFormHeight() {
@@ -464,13 +481,16 @@ import config from "@/config.js";
// 从文件路径中提取文件名 // 从文件路径中提取文件名
const fileName = data.pic.split('/').pop(); const fileName = data.pic.split('/').pop();
// 构造完整的URL // 构造完整的URL
const fullUrl = this.baseUrl + data.pic; const fullUrl = this.getFullImageUrl(data.pic);
// 更新 photoFiles 数组,使 uni-file-picker 组件显示已有的证件照 // 更新 photoFiles 数组,使编辑模式下能够预览图片
this.photoFiles = [{ this.photoFiles = [{
name: fileName, name: fileName,
path: data.pic, path: data.pic,
url: fullUrl url: fullUrl
}]; }];
console.log('处理证件照formData.pic:', this.formData.pic);
console.log('fullUrl:', fullUrl);
console.log('photoFiles:', this.photoFiles);
} }
// 处理证明材料 // 处理证明材料
@@ -601,6 +621,27 @@ import config from "@/config.js";
icon: 'success' icon: 'success'
}); });
}, },
// 获取完整图片URL
getFullImageUrl(path) {
if (!path) return '';
// 调试信息
console.log('getFullImageUrl调用path:', path);
// 如果已经是完整URL则直接返回
if (path.startsWith('http://') || path.startsWith('https://')) {
return path;
}
// 使用配置文件中的baseUrl
const currentBaseUrl = config.baseUrl || '';
console.log('当前baseUrl:', currentBaseUrl);
// 处理baseUrl确保结尾没有斜杠
const baseUrlClean = currentBaseUrl.replace(/\/$/, '');
// 处理path确保开头没有斜杠
const pathClean = path.replace(/^\//, '');
// 拼接URL
const fullUrl = `${baseUrlClean}/${pathClean}`;
console.log('拼接后的完整URL:', fullUrl);
return fullUrl;
},
// 预览证件照 // 预览证件照
previewPhoto() { previewPhoto() {
@@ -1445,4 +1486,16 @@ import config from "@/config.js";
margin-top: 10rpx; margin-top: 10rpx;
line-height: 1.4; line-height: 1.4;
} }
/* 照片预览容器 */
.photo-preview-container {
margin-top: 20rpx;
border-radius: 8rpx;
overflow: hidden;
}
.photo-preview-container image {
width: 200rpx;
height: 200rpx;
border-radius: 8rpx;
}
</style> </style>