|
|
|
@ -37,12 +37,12 @@
|
|
|
|
|
.transition-custom {
|
|
|
|
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
|
|
}
|
|
|
|
|
/*.scale-hover {*/
|
|
|
|
|
/* transition: transform 0.2s ease-in-out;*/
|
|
|
|
|
/*}*/
|
|
|
|
|
/*.scale-hover:hover {*/
|
|
|
|
|
/* transform: scale(1.02);*/
|
|
|
|
|
/*}*/
|
|
|
|
|
.scale-hover {
|
|
|
|
|
transition: transform 0.2s ease-in-out;
|
|
|
|
|
}
|
|
|
|
|
.scale-hover:hover {
|
|
|
|
|
transform: scale(1.02);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.text-sm {
|
|
|
|
|
font-size: 1.4rem;
|
|
|
|
@ -290,10 +290,61 @@
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</form>
|
|
|
|
|
<h4 class="form-header h4">文件上传</h4>
|
|
|
|
|
<div class="row">
|
|
|
|
|
<h4 class="form-header h4">材料上传</h4>
|
|
|
|
|
|
|
|
|
|
<!-- 新增文件上传区域 -->
|
|
|
|
|
<div class="mt-6">
|
|
|
|
|
<div class="flex items-center justify-between mb-4">
|
|
|
|
|
<h5 class="text-lg font-medium text-gray-800">上传PDF文件</h5>
|
|
|
|
|
<div class="relative">
|
|
|
|
|
<label for="fileUpload" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-primary hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary cursor-pointer transition-colors duration-200">
|
|
|
|
|
<i class="fa-solid fa-upload mr-2"></i> 选择PDF文件
|
|
|
|
|
<input id="fileUpload" type="file" class="sr-only" accept=".pdf" @change="handleFileSelection">
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 上传进度条 -->
|
|
|
|
|
<div v-if="uploadProgress > 0 && uploadProgress < 100" class="mb-4">
|
|
|
|
|
<div class="flex justify-between text-sm mb-1">
|
|
|
|
|
<span class="text-gray-700">上传中: {{ currentFileName }}</span>
|
|
|
|
|
<span class="text-gray-500">{{ uploadProgress }}%</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="w-full bg-gray-200 rounded-full h-2">
|
|
|
|
|
<div class="bg-primary h-2 rounded-full" :style="{ width: uploadProgress + '%' }"></div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 文件列表 -->
|
|
|
|
|
<div class="mt-4">
|
|
|
|
|
<div v-if="uploadedFiles.length === 0" class="py-10 text-center border-2 border-dashed border-gray-300 rounded-lg">
|
|
|
|
|
<i class="fa-solid fa-cloud-upload-alt text-4xl text-gray-400 mb-3"></i>
|
|
|
|
|
<p class="text-gray-500">暂无上传文件</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div v-else class="space-y-3">
|
|
|
|
|
<div v-for="(file, index) in uploadedFiles" :key="index" class="flex items-center p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors duration-200">
|
|
|
|
|
<div class="flex-shrink-0 mr-4">
|
|
|
|
|
<i class="fa-solid fa-file-pdf-o text-2xl text-red-500"></i>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex-grow min-w-0">
|
|
|
|
|
<p class="text-sm font-medium text-gray-900 truncate">{{ file.fileName }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex-shrink-0 ml-4">
|
|
|
|
|
<button @click="downloadFile(file)" class="text-primary hover:text-primary/80 mr-3">
|
|
|
|
|
<i class="fa-solid fa-download"></i>
|
|
|
|
|
</button>
|
|
|
|
|
<button @click="deleteFile(file, index)" class="text-red-500 hover:text-red-700">
|
|
|
|
|
<i class="fa-solid fa-trash"></i>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="row mt-6">
|
|
|
|
|
<div class="col-sm-offset-5 col-sm-10" style="display: flex;">
|
|
|
|
|
<button type="button" class="btn btn-sm btn-primary" onclick="submitHandler()"><i class="fa fa-check"></i>提 交</button>
|
|
|
|
|
<button type="button" class="btn btn-sm btn-primary" @click="submitHandler()"><i class="fa fa-check"></i>提 交</button>
|
|
|
|
|
<button type="button" class="btn btn-sm btn-danger" onclick="closeItem()"><i class="fa fa-reply-all"></i>关 闭
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
@ -331,8 +382,14 @@
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<!-- 上传成功提示 -->
|
|
|
|
|
<div v-if="uploadSuccess" class="fixed bottom-4 right-4 bg-green-500 text-white px-6 py-3 rounded-lg shadow-lg transform transition-all duration-500 translate-y-0 opacity-100">
|
|
|
|
|
<div class="flex items-center">
|
|
|
|
|
<i class="fa-solid fa-check-circle mr-2"></i>
|
|
|
|
|
<span>{{ uploadSuccessMessage }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</main>
|
|
|
|
|
</div>
|
|
|
|
|
<th:block th:include="include :: footer"/>
|
|
|
|
@ -340,12 +397,6 @@
|
|
|
|
|
<th:block th:include="include :: jasny-bootstrap-js"/>
|
|
|
|
|
<script type="text/javascript" th:inline="javascript">
|
|
|
|
|
var prefix = ctx + "system/applyList";
|
|
|
|
|
function submitHandler() {
|
|
|
|
|
if ($.validate.form()) {
|
|
|
|
|
var data = $("#form-apply-edit").serializeArray();
|
|
|
|
|
$.operate.saveTab(prefix + "/edit", data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
new Vue({
|
|
|
|
|
el: '#app',
|
|
|
|
|
data: {
|
|
|
|
@ -367,11 +418,22 @@
|
|
|
|
|
smPost: '',
|
|
|
|
|
smGrade: '',
|
|
|
|
|
photoUrl: '',
|
|
|
|
|
applyId: '',
|
|
|
|
|
},
|
|
|
|
|
selectedFile: null,
|
|
|
|
|
isLoading: false,
|
|
|
|
|
showResult: false,
|
|
|
|
|
pdfUrl: '',
|
|
|
|
|
// 新增文件上传相关数据
|
|
|
|
|
selectedFiles: null,
|
|
|
|
|
currentFileName: '',
|
|
|
|
|
uploadProgress: 0,
|
|
|
|
|
uploadedFiles: [],
|
|
|
|
|
previewModalVisible: false,
|
|
|
|
|
previewingFile: {},
|
|
|
|
|
uploadSuccess: false,
|
|
|
|
|
uploadSuccessMessage: '',
|
|
|
|
|
prefix: ctx + "system/applyList",
|
|
|
|
|
},
|
|
|
|
|
computed: {
|
|
|
|
|
previewUrl() {
|
|
|
|
@ -433,7 +495,7 @@
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 准备表单数据
|
|
|
|
|
const formData = new FormData();
|
|
|
|
|
let formData = new FormData();
|
|
|
|
|
if (this.formData.name) formData.append("name", this.formData.name);
|
|
|
|
|
if (this.formData.sex) formData.append("sex", this.formData.sex);
|
|
|
|
|
if (this.formData.nationa) formData.append("nationa", this.formData.nationa);
|
|
|
|
@ -459,7 +521,7 @@
|
|
|
|
|
})
|
|
|
|
|
.then(response => {
|
|
|
|
|
// 创建下载URL
|
|
|
|
|
const blob = new Blob([response.data], { type: 'application/pdf' });
|
|
|
|
|
let blob = new Blob([response.data], { type: 'application/pdf' });
|
|
|
|
|
this.pdfUrl = window.URL.createObjectURL(blob);
|
|
|
|
|
|
|
|
|
|
// 隐藏加载状态,显示结果
|
|
|
|
@ -471,6 +533,145 @@
|
|
|
|
|
this.isLoading = false;
|
|
|
|
|
alert('生成PDF时出错,请重试');
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
// 新增文件上传相关方法
|
|
|
|
|
handleFileSelection(event) {
|
|
|
|
|
this.selectedFiles = event.target.files;
|
|
|
|
|
if (this.selectedFiles && this.selectedFiles.length > 0) {
|
|
|
|
|
// 只处理第一个文件
|
|
|
|
|
let file = this.selectedFiles[0];
|
|
|
|
|
// 检查文件类型
|
|
|
|
|
if (!file.name.toLowerCase().endsWith('.pdf')) {
|
|
|
|
|
alert('请上传PDF格式的文件');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
this.uploadFile(file);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
uploadFile(file) {
|
|
|
|
|
this.currentFileName = file.name;
|
|
|
|
|
this.uploadProgress = 0;
|
|
|
|
|
|
|
|
|
|
let formData = new FormData();
|
|
|
|
|
formData.append('applyId', this.formData.applyId || '');
|
|
|
|
|
formData.append('filename', file.name);
|
|
|
|
|
formData.append('fileCode', 'bm_user_audit_001');
|
|
|
|
|
formData.append('file', file);
|
|
|
|
|
|
|
|
|
|
axios.post(ctx + 'system/file/upload', formData, {
|
|
|
|
|
onUploadProgress: (progressEvent) => {
|
|
|
|
|
this.uploadProgress = Math.round((progressEvent.loaded * 100) / progressEvent.total);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.then(response => {
|
|
|
|
|
if (response.data.code === web_status.SUCCESS) {
|
|
|
|
|
// 显示上传成功提示
|
|
|
|
|
this.uploadSuccess = true;
|
|
|
|
|
this.uploadSuccessMessage = `文件 "${file.name}" 上传成功`;
|
|
|
|
|
|
|
|
|
|
// 3秒后隐藏提示
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
this.uploadSuccess = false;
|
|
|
|
|
}, 3000);
|
|
|
|
|
|
|
|
|
|
// 更新文件列表
|
|
|
|
|
let fileInfo = {
|
|
|
|
|
id: response.data.data.fileId,
|
|
|
|
|
fileName: file.name,
|
|
|
|
|
fileSize: file.size,
|
|
|
|
|
fileType: 'application/pdf',
|
|
|
|
|
fileUrl: file.filePath,
|
|
|
|
|
uploadTime: new Date().toISOString()
|
|
|
|
|
};
|
|
|
|
|
this.uploadedFiles.push(fileInfo);
|
|
|
|
|
|
|
|
|
|
// 重置选择框
|
|
|
|
|
document.getElementById('fileUpload').value = '';
|
|
|
|
|
} else {
|
|
|
|
|
alert(`上传失败: ${response.data.msg}`);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
console.error('上传错误:', error);
|
|
|
|
|
alert('上传过程中发生错误');
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
downloadFile(file) {
|
|
|
|
|
// 直接通过接口下载
|
|
|
|
|
axios.get(ctx + 'system/file/download',{
|
|
|
|
|
params: { fileId: file.id },
|
|
|
|
|
responseType: 'blob', // 重要:指定响应类型为blob
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.then(response => {
|
|
|
|
|
let url = window.URL.createObjectURL(new Blob([response.data]));
|
|
|
|
|
let link = document.createElement('a');
|
|
|
|
|
link.href = url;
|
|
|
|
|
link.setAttribute('download', file.fileName);
|
|
|
|
|
document.body.appendChild(link);
|
|
|
|
|
link.click();
|
|
|
|
|
document.body.removeChild(link);
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
console.error('下载错误:', error);
|
|
|
|
|
alert('下载文件时出错');
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
submitHandler() {
|
|
|
|
|
if (this.uploadedFiles.length == 0) {
|
|
|
|
|
alert('请上传所需材料');
|
|
|
|
|
return
|
|
|
|
|
}else{
|
|
|
|
|
if(confirm('确认提交吗?')){
|
|
|
|
|
$.operate.saveTab(`${this.prefix}/submit?applyId=${this.formData.appyId}`,);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
deleteFile(file, index) {
|
|
|
|
|
if (confirm(`确定要删除文件 "${file.fileName}" 吗?`)) {
|
|
|
|
|
axios.get(ctx + 'system/file/delFile/' + file.id)
|
|
|
|
|
.then(response => {
|
|
|
|
|
if (response.data.code === web_status.SUCCESS) {
|
|
|
|
|
this.uploadedFiles.splice(index, 1);
|
|
|
|
|
alert('文件已成功删除');
|
|
|
|
|
} else {
|
|
|
|
|
alert(`删除失败: ${response.data.msg}`);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
console.error('删除错误:', error);
|
|
|
|
|
alert('删除文件时出错');
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// 获取已上传文件
|
|
|
|
|
getUploadedFiles() {
|
|
|
|
|
if (!this.formData.applyId) return;
|
|
|
|
|
axios.get(ctx + 'system/file/getFileInfo', {
|
|
|
|
|
params: {
|
|
|
|
|
applyId: this.formData.applyId
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.then(response => {
|
|
|
|
|
if (response.data.code === web_status.SUCCESS) {
|
|
|
|
|
this.uploadedFiles = response.data.data.map((file)=>{
|
|
|
|
|
return {
|
|
|
|
|
id: file.fileId,
|
|
|
|
|
fileName: file.fileName,
|
|
|
|
|
fileSize: file.fileSize,
|
|
|
|
|
fileType: 'application/pdf',
|
|
|
|
|
fileUrl: file.filePath,
|
|
|
|
|
uploadTime: file.createTime
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
console.error('获取文件列表错误:', error);
|
|
|
|
|
alert('获取已上传文件时出错');
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
mounted() {
|
|
|
|
@ -478,16 +679,18 @@
|
|
|
|
|
if ([[${applyInfoList}]]){
|
|
|
|
|
this.formData = {...[[${applyInfoList}]]}
|
|
|
|
|
// 获取图片并转换为 Blob
|
|
|
|
|
fetch(this.formData.photoUrl)
|
|
|
|
|
.then(response => response.blob())
|
|
|
|
|
.then(blob => {
|
|
|
|
|
// 此时已获取二进制文件(Blob)
|
|
|
|
|
console.log('Blob 类型:', blob);
|
|
|
|
|
this.selectedFile = blob;
|
|
|
|
|
})
|
|
|
|
|
.catch(error => console.error('处理图片时出错:', error));
|
|
|
|
|
console.log(this.formData)
|
|
|
|
|
if (this.formData.photoUrl) {
|
|
|
|
|
fetch(this.formData.photoUrl)
|
|
|
|
|
.then(response => response.blob())
|
|
|
|
|
.then(blob => {
|
|
|
|
|
this.selectedFile = blob;
|
|
|
|
|
})
|
|
|
|
|
.catch(error => console.error('处理图片时出错:', error));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取已上传文件
|
|
|
|
|
this.getUploadedFiles();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
//图片上传
|
|
|
|
|