From c207301225726725572e5e9d7d9ad87722069244 Mon Sep 17 00:00:00 2001
From: dshclm <3321914460@qq.com>
Date: Wed, 28 May 2025 10:42:15 +0800
Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../system/newdev/leaveAudit/leaveAudit.html  | 796 +++++++++++++++++-
 1 file changed, 792 insertions(+), 4 deletions(-)

diff --git a/ruoyi-admin/src/main/resources/templates/system/newdev/leaveAudit/leaveAudit.html b/ruoyi-admin/src/main/resources/templates/system/newdev/leaveAudit/leaveAudit.html
index 566549bd..19e5eb92 100644
--- a/ruoyi-admin/src/main/resources/templates/system/newdev/leaveAudit/leaveAudit.html
+++ b/ruoyi-admin/src/main/resources/templates/system/newdev/leaveAudit/leaveAudit.html
@@ -1,10 +1,798 @@
 <!DOCTYPE html>
-<html lang="en">
+<html lang="zh" xmlns:th="http://www.thymeleaf.org">
 <head>
-    <meta charset="UTF-8">
-    <title>Title</title>
+    <th:block th:include="include :: header('材料上传')"/>
+    <th:block th:include="include :: select2-css"/>
+    <th:block th:include="include :: jasny-bootstrap-css"/>
+    <th:block th:include="include :: element-css"/>
+    <link href="/file/pdf/test.css" rel="stylesheet">
+    <script src="/file/pdf/tailwindcss.js"></script>
+    <!-- Tailwind配置 -->
+    <script>
+        tailwind.config = {
+            theme: {
+                extend: {
+                    colors: {
+                        primary: '#3b82f6',
+                        secondary: '#64748b',
+                        accent: '#0ea5e9',
+                        neutral: '#f1f5f9',
+                        'neutral-dark': '#334155',
+                    },
+                    fontFamily: {
+                        sans: ['Inter', 'system-ui', 'sans-serif'],
+                    },
+                }
+            }
+        }
+    </script>
+
+    <style type="text/tailwindcss">
+        @layer utilities {
+            .content-auto {
+                content-visibility: auto;
+            }
+            .shadow-soft {
+                box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
+            }
+            .transition-custom {
+                transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+            }
+        }
+        .text-sm {
+            font-size: 1.4rem;
+        }
+        .text-base {
+            font-size: 1.4rem;
+        }
+        .text-xs {
+            font-size: 0.85rem;
+        }
+        .py-2 {
+            padding-top: 0.8rem;
+            padding-bottom: 0.8rem;
+        }
+        .space-y-3{
+            margin-bottom: 1.5rem;
+        }
+    </style>
 </head>
-<body>
+<body class="bg-gray-50 font-sans">
+<div class="main-content min-h-screen flex flex-col" id="app">
+    <main class="flex-grow container mx-auto px-4 py-8" style="max-width: 100%;">
+        <div class="max-w-10xl mx-auto" style="width: 100%;">
+            <div  class="bg-white rounded-xl shadow-soft p-6 mb-8 scale-hover">
+                <form class="form-horizontal space-y-6" id="form-apply-edit" th:object="${applyInfoList}">
+                    <input name="applyId" type="hidden" th:field="*{applyId}"/>
+                    <h4 class="form-header h4">基本信息</h4>
+                    <!-- 文本字段 -->
+                    <div class="grid md:grid-cols-3 gap-6">
+                        <!-- 第一行前两列:姓名、性别 -->
+                        <div class="md:col-span-1 space-y-3">
+                            <!-- 姓名 -->
+                            <div class="space-y-3">
+                                <label for="name" class="block text-sm font-medium text-gray-700">姓名</label>
+                                <div class="relative">
+                                <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
+                                    <i class="fa-solid fa-user"></i>
+                                </span>
+                                    <input disabled type="text" id="name" v-model="formData.name" class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg" placeholder="请输入姓名">
+                                </div>
+                            </div>
+
+                            <!-- 性别 -->
+                            <div class="space-y-3">
+                                <label for="sex" class="block text-sm font-medium text-gray-700">性别</label>
+                                <div class="relative">
+                                <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
+                                    <i class="fa-solid fa-venus-mars"></i>
+                                </span>
+                                    <input disabled type="text" id="sex" v-model="formData.sex" class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg" placeholder="请输入性别">
+                                </div>
+                            </div>
+                        </div>
+                        <!-- 第二行前两列:国籍、曾用名 -->
+                        <div class="md:col-span-1 space-y-3">
+                            <!-- 国籍 -->
+                            <div class="space-y-3">
+                                <label for="nationa" class="block text-sm font-medium text-gray-700">国籍</label>
+                                <div class="relative">
+                                <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
+                                    <i class="fa-solid fa-globe"></i>
+                                </span>
+                                    <input disabled type="text" id="nationa" v-model="formData.nationa" class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg" placeholder="请输入国籍">
+                                </div>
+                            </div>
+
+                            <!-- 曾用名 -->
+                            <div class="space-y-3">
+                                <label for="formerName" class="block text-sm font-medium text-gray-700">曾用名</label>
+                                <div class="relative">
+                                <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
+                                    <i class="fa-solid fa-user-tag"></i>
+                                </span>
+                                    <input disabled type="text" id="formerName" v-model="formData.formerName" class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg" placeholder="请输入曾用名">
+                                </div>
+                            </div>
+                        </div>
+                        <!-- 第一行第三列:图片上传区域(固定位置,跨两行) -->
+                        <div class="md:col-span-1 md:row-span-2 space-y-3 relative">
+                            <label class="block text-sm font-medium text-gray-700">一寸照片</label>
+                            <div class="mt-1 h-64 border-2 border-gray-300 rounded-lg shadow-soft transition-all duration-200" style="width: 141px;height: 195px">
+                                <!-- 上传区域(未选中时显示) -->
+                                <div v-if="!selectedFile" class="h-full flex justify-center items-center border-dashed cursor-pointer hover:border-primary">
+                                    <div class="text-center">
+                                        <i class="fa-solid fa-cloud-upload text-4xl text-gray-400 mb-2"></i>
+                                        <label for="photo" class="cursor-pointer bg-white rounded-md font-medium text-primary hover:text-primary/80">
+                                            <span>上传照片</span>
+                                            <input disabled id="photo" name="photo" type="file" accept="image/jpeg,image/png" class="sr-only" @change="handleFileUpload">
+                                        </label>
+                                        <p class="text-xs text-gray-500">
+                                            JPG, PNG (最大 2MB)
+                                        </p>
+                                    </div>
+                                </div>
+                                <!-- 预览区域(选中后显示) -->
+                                <div v-else class="h-full flex flex-col items-center justify-center p-3">
+                                    <img :src="previewUrl" alt="预览图" class="max-h-full max-w-full object-cover rounded-lg mb-2" style="max-height: 200px;">
+                                    <!--                                    <button type="button" @click="clearFile" class="text-xs text-red-500 hover:text-red-700">-->
+                                    <!--                                        <i class="fa-solid fa-times-circle mr-1"></i> 移除-->
+                                    <!--                                    </button>-->
+                                </div>
+                            </div>
+                        </div>
+                        <div class="space-y-3">
+                            <label for="nationality" class="block text-sm font-medium text-gray-700">民族</label>
+                            <div class="relative">
+                                    <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
+                                        <i class="fa-solid fa-people-group"></i>
+                                    </span>
+                                <input disabled type="text" id="nationality" v-model="formData.nationality"
+                                       class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary/50 focus:border-primary transition-colors duration-200"
+                                       placeholder="请输入民族">
+                            </div>
+                        </div>
+                        <div class="space-y-3">
+                            <label for="maritalStatus" class="block text-sm font-medium text-gray-700">婚姻状况</label>
+                            <div class="relative">
+                                    <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
+                                        <i class="fa-solid fa-ring"></i>
+                                    </span>
+                                <input disabled type="text" id="maritalStatus" v-model="formData.maritalStatus"
+                                       class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary/50 focus:border-primary transition-colors duration-200"
+                                       placeholder="请输入婚姻状况">
+
+                            </div>
+                        </div>
+                        <div class="space-y-3">
+                            <label for="political" class="block text-sm font-medium text-gray-700">政治面貌</label>
+                            <div class="relative">
+                                    <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
+                                        <i class="fa-solid fa-user-tie"></i>
+                                    </span>
+                                <input disabled type="text" id="political" v-model="formData.political"
+                                       class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary/50 focus:border-primary transition-colors duration-200"
+                                       placeholder="请输入政治面貌">
+                            </div>
+                        </div>
+                        <div class="space-y-3">
+                            <label for="phone" class="block text-sm font-medium text-gray-700">联系方式</label>
+                            <div class="relative">
+                                    <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
+                                        <i class="fa-solid fa-phone"></i>
+                                    </span>
+                                <input disabled type="text" id="phone" v-model="formData.phone"
+                                       class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary/50 focus:border-primary transition-colors duration-200"
+                                       placeholder="请输入联系方式">
+                            </div>
+                        </div>
+                        <div class="space-y-3">
+                            <label for="cerno" class="block text-sm font-medium text-gray-700">身份证号</label>
+                            <div class="relative">
+                                    <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
+                                        <i class="fa-solid fa-id-card"></i>
+                                    </span>
+                                <input disabled type="text" id="cerno" v-model="formData.cerno"
+                                       class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary/50 focus:border-primary transition-colors duration-200"
+                                       placeholder="请输入身份证号">
+                            </div>
+                        </div>
+                        <div class="space-y-3">
+                            <label for="address" class="block text-sm font-medium text-gray-700">户籍地址</label>
+                            <div class="relative">
+                                    <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
+                                        <i class="fa-solid fa-house-chimney"></i>
+                                    </span>
+                                <input disabled type="text" id="address" v-model="formData.address"
+                                       class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary/50 focus:border-primary transition-colors duration-200"
+                                       placeholder="请输入户籍地址">
+                            </div>
+                        </div>
+                        <div class="space-y-3">
+                            <label for="registeredAuthority" class="block text-sm font-medium text-gray-700">户籍地公安机关</label>
+                            <div class="relative">
+                                    <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
+                                        <i class="fa-solid fa-badge-shield"></i>
+                                    </span>
+                                <input disabled type="text" id="registeredAuthority" v-model="formData.registeredAuthority"
+                                       class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary/50 focus:border-primary transition-colors duration-200"
+                                       placeholder="请输入户籍地公安机关">
+                            </div>
+                        </div>
+                        <div class="space-y-3">
+                            <label for="permanentAddress" class="block text-sm font-medium text-gray-700">常住地址</label>
+                            <div class="relative">
+                                    <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
+                                        <i class="fa-solid fa-house"></i>
+                                    </span>
+                                <input disabled type="text" id="permanentAddress" v-model="formData.permanentAddress"
+                                       class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary/50 focus:border-primary transition-colors duration-200"
+                                       placeholder="请输入常住地址">
+                            </div>
+                        </div>
+                        <div class="space-y-3">
+                            <label for="residentBureau" class="block text-sm font-medium text-gray-700">常住地公安机关</label>
+                            <div class="relative">
+                                    <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
+                                        <i class="fa-solid fa-badge-shield"></i>
+                                    </span>
+                                <input disabled type="text" id="residentBureau" v-model="formData.residentBureau"
+                                       class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary/50 focus:border-primary transition-colors duration-200"
+                                       placeholder="请输入常住地公安机关">
+                            </div>
+                        </div>
+                        <div class="space-y-3">
+                            <label for="positionCapacity" class="block text-sm font-medium text-gray-700">单位及职务职称</label>
+                            <div class="relative">
+                                    <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
+                                        <i class="fa-solid fa-building-user"></i>
+                                    </span>
+                                <input disabled type="text" id="positionCapacity" v-model="formData.positionCapacity"
+                                       class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary/50 focus:border-primary transition-colors duration-200"
+                                       placeholder="请输入单位及职务职称">
+                            </div>
+                        </div>
+                        <div class="space-y-3">
+                            <label for="smPost" class="block text-sm font-medium text-gray-700">已(拟)任涉密岗位</label>
+                            <div class="relative">
+                                    <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
+                                        <i class="fa-solid fa-shield-halved"></i>
+                                    </span>
+                                <input disabled type="text" id="smPost" v-model="formData.smPost"
+                                       class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary/50 focus:border-primary transition-colors duration-200"
+                                       placeholder="请输入已(拟)任涉密岗位">
+                            </div>
+                        </div>
+                        <div class="space-y-3">
+                            <label for="smGrade" class="block text-sm font-medium text-gray-700">涉密等级</label>
+                            <div class="relative">
+                                    <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
+                                        <i class="fa-solid fa-lock"></i>
+                                    </span>
+                                <input disabled type="text" id="smGrade" v-model="formData.smGrade"
+                                       class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary/50 focus:border-primary transition-colors duration-200"
+                                       placeholder="请输入涉密等级">
+                            </div>
+                        </div>
+                    </div>
+                    <h4 class="form-header h4">材料上传</h4>
+                    <!-- 材料上传区域 - 使用循环生成 -->
+                    <div class="mt-6" style=" display: flex;flex-wrap: wrap;justify-content: space-around;">
+                        <div v-for="(material, index) in materials" :key="index" class="border border-gray-200 rounded-lg p-4 mb-6" style="width: 50%;">
+                            <div class="flex items-center justify-between mb-3">
+                                <span class="text-sm text-gray-600">{{ material.description }}</span>
+                                <div class="relative">
+                                    <label :for="'fileUpload' + index" class="inline-flex items-center px-3 py-1.5 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> 选择文件
+                                        <input :id="'fileUpload' + index" type="file" class="sr-only" :accept="material.accept" @change="handleFileSelection(index)">
+                                    </label>
+                                    <a v-if="material.code ==='bm_user_lpromise_012'" :href="material.templateUrl" :download="material.downloadName" class="inline-flex items-center px-3 py-1.5 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 transition-colors duration-200">
+                                        <i class="fa-solid fa-download mr-1"></i> 下载模版
+                                    </a>
+                                </div>
+                            </div>
+
+                            <!-- 上传进度条 -->
+                            <div v-if="uploadProgress[index] > 0 && uploadProgress[index] < 100" class="mb-3">
+                                <div class="flex justify-between text-sm mb-1">
+                                    <span class="text-gray-700">上传中: {{ currentFileName[index] }}</span>
+                                    <span class="text-gray-500">{{ uploadProgress[index] }}%</span>
+                                </div>
+                                <div class="w-full bg-gray-200 rounded-full h-2">
+                                    <div class="bg-primary h-2 rounded-full" :style="{ width: uploadProgress[index] + '%' }"></div>
+                                </div>
+                            </div>
+
+                            <!-- 文件列表 -->
+                            <div class="mt-3">
+                                <div v-if="uploadedFiles[index].length === 0" class="py-6 text-center border-2 border-dashed border-gray-300 rounded-lg">
+                                    <i class="fa-solid fa-cloud-upload-alt text-3xl text-gray-400 mb-2"></i>
+                                    <p class="text-gray-500">未上传文件</p>
+                                </div>
+                                <div v-else class="space-y-2">
+                                    <div v-for="(file, fileIndex) in uploadedFiles[index]" :key="fileIndex" class="flex items-center p-2 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors duration-200">
+                                        <div class="flex-shrink-0 mr-3">
+                                            <i :class="getFileIcon(file.fileName)" class="text-xl"></i>
+                                        </div>
+                                        <div class="flex-grow min-w-0">
+                                            <p style="height: 100%;line-height: 20px" class="text-sm font-medium text-gray-900 truncate">{{ file.fileName }}</p>
+                                        </div>
+                                        <div class="flex-shrink-0 ml-3">
+                                            <button v-if="isImageFile(file.fileName)" @click="previewFile(file)" class="text-primary hover:text-primary/80 mr-2">
+                                                <i class="fa-solid fa-eye"></i>
+                                            </button>
+                                            <button @click="downloadFile(file, index)" class="text-primary hover:text-primary/80 mr-2">
+                                                <i class="fa-solid fa-download"></i>
+                                            </button>
+<!--                                            <button @click.stop="deleteFile(file, index, fileIndex)" class="text-red-500 hover:text-red-700">-->
+<!--                                                <i class="fa-solid fa-trash"></i>-->
+<!--                                            </button>-->
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </form>
+
+                <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" @click="approveApplication"><i class="fa fa-check"></i>通 过</button>&nbsp;
+                        <button type="button" class="btn btn-sm btn-danger" @click="showRejectDialog"><i class="fa fa-undo"></i>退 回</button>&nbsp;
+                        <button type="button" class="btn btn-sm btn-danger" onclick="closeItem()"><i class="fa fa-reply-all"></i>关 闭
+                        </button>
+                    </div>
+                </div>
+            </div>
+            <!-- 退回意见对话框 -->
+            <div v-if="rejectDialogVisible" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
+                <div class="bg-white rounded-lg max-w-md w-full p-6 transform transition-all">
+                    <h3 class="text-lg font-medium text-gray-900 mb-4">退回申请</h3>
+                    <div class="mb-4">
+                        <label for="rejectReason" class="block text-sm font-medium text-gray-700 mb-1">退回原因</label>
+                        <textarea
+                                id="rejectReason"
+                                v-model="rejectReason"
+                                rows="4"
+                                class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"
+                                placeholder="请输入退回原因..."
+                        ></textarea>
+                    </div>
+                    <div class="flex justify-end space-x-3">
+                        <button @click="rejectDialogVisible = false" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50">
+                            取消
+                        </button>
+                        <button @click="rejectApplication" class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90">
+                            确认退回
+                        </button>
+                    </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 v-if="previewModalVisible" class="fixed inset-0 bg-black bg-opacity-90 flex items-center justify-center z-50">
+                <div class="bg-white rounded-lg max-w-4xl w-full max-h-[90vh] overflow-auto">
+                    <div class="p-4 flex justify-between items-center border-b">
+                        <h3 class="text-lg font-medium text-gray-900">{{ previewingFile.fileName }}</h3>
+                        <button @click="closePreviewModal" class="text-gray-500 hover:text-gray-700">
+                            <i class="fa-solid fa-times"></i>
+                        </button>
+                    </div>
+                    <div class="p-4 flex justify-center">
+                        <img :src="getPreviewUrl(previewingFile)" alt="预览图" class="max-w-full max-h-[70vh] object-contain">
+                    </div>
+                    <div class="p-4 border-t flex justify-end">
+                        <button @click="closePreviewModal" class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md shadow-sm text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary transition-colors duration-200">
+                            <i class="fa-solid fa-times mr-2"></i> 关闭
+                        </button>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </main>
+</div>
+<th:block th:include="include :: footer"/>
+<th:block th:include="include :: select2-js"/>
+<th:block th:include="include :: jasny-bootstrap-js"/>
+<th:block th:include="include :: element-js"/>
+<script type="text/javascript" th:inline="javascript">
+    var prefix = ctx + "system/leaveAuditList";
+    new Vue({
+        el: '#app',
+        data: {
+            formData: {
+                name: '',
+                sex: '',
+                nationa: '',
+                formerName: '',
+                nationality: '',
+                maritalStatus: '',
+                political: '',
+                phone: '',
+                cerno: '',
+                address: '',
+                registeredAuthority: '',
+                permanentAddress: '',
+                residentBureau: '',
+                positionCapacity: '',
+                smPost: '',
+                smGrade: '',
+                photoUrl: '',
+                applyId: '',
+            },
+            selectedFile: null,
+            // 材料配置 - 定义六个材料的信息
+            materials: [
+                {
+                    name: '涉密人员离职离岗保密审批表',
+                    code: 'bm_user_userleav_011',
+                    templateUrl: '/file/pdfFiles/涉密人员离职离岗保密审批表.pdf',
+                    downloadName: '涉密人员离职离岗保密审批表.pdf',
+                    description: '涉密人员离职离岗保密审批表',
+                    accept: '.pdf, .doc, .docx, .jpg, .jpeg, .png, .gif, .bmp'
+                },
+                {
+                    name: '涉密人员离职离岗保密承诺书',
+                    code: 'bm_user_lpromise_012',
+                    templateUrl: '/file/pdfFiles/涉密人员离职离岗保密承诺书.pdf',
+                    downloadName: '涉密人员离职离岗保密承诺书.pdf',
+                    description: '涉密人员离职离岗保密承诺书',
+                    accept: '.pdf, .doc, .docx, .jpg, .jpeg, .png, .gif, .bmp'
+                },
+            ],
+            // 文件上传相关数据
+            selectedFiles: Array(2).fill(null),
+            currentFileName: Array(2).fill(''),
+            uploadProgress: Array(2).fill(0),
+            uploadedFiles: Array(2).fill([]).map(() => []),
+            previewModalVisible: false,
+            previewingFile: {},
+            uploadSuccess: false,
+            uploadSuccessMessage: '',
+            prefix: ctx + "system/leaveAuditList",
+            isLoading: false,
+            showResult: false,
+            pdfUrl:'',
+            rejectDialogVisible: false,
+            rejectReason: '',
+        },
+        computed: {
+            previewUrl() {
+                return this.selectedFile ? window.URL.createObjectURL(this.selectedFile) : '';
+            }
+        },
+        methods: {
+            handleFileUpload(event) {
+                let file = event.target.files[0];
+                if (file) {
+                    // 检查文件类型和大小
+                    let fileSize = file.size / 1024 / 1024; // MB
+                    if (fileSize > 2) {
+                        this.$message.error('文件大小不能超过2MB');
+                        return;
+                    }
+                    let fileType = file.type;
+                    if (!fileType.startsWith('image/')) {
+                        this.$message.error('请上传图片文件');
+                        return;
+                    }
+                    // 验证图片格式
+                    let validFormats = ['image/jpeg', 'image/png'];
+                    if (!validFormats.includes(fileType)) {
+                        this.$message.error('请上传JPG或PNG格式的图片');
+                        return;
+                    }
+                    // 验证图片尺寸是否接近一寸照片 (2.5cm x 3.5cm, 约295x413像素)
+                    let img = new Image();
+                    img.src = window.URL.createObjectURL(file);
+                    img.onload = () => {
+                        let width = img.naturalWidth;
+                        let height = img.naturalHeight;
+                        let ratio = width / height;
+                        // 检查宽高比是否接近一寸照片的比例 (约0.714)
+                        if (Math.abs(ratio - 0.714) > 0.1) {
+                            this.$message({
+                                message: '建议上传一寸照片尺寸 (约295x413像素)',
+                                type: 'warning'
+                            });
+                        }
+                        this.selectedFile = file;
+                    };
+                    img.onerror = () => {
+                        this.$message.error('无法加载图片,请重新选择');
+                    };
+                }
+            },
+            clearFile() {
+                this.selectedFile = null;
+                document.getElementById('photo').value = '';
+            },
+            // 文件上传处理
+            handleFileSelection(index) {
+                this.selectedFiles[index] = event.target.files[0];
+                if (this.selectedFiles[index]) {
+                    let file = this.selectedFiles[index];
+                    let fileExtension = file.name.split('.').pop().toLowerCase();
+
+                    // 根据材料类型验证文件格式
+                    let validExtensions = this.materials[index].accept.split(',').map(ext => ext.trim().replace('.', ''));
+
+                    if (!validExtensions.includes(fileExtension)) {
+                        this.$message.error(`请上传${this.materials[index].description.split(':')[1]}`);
+                        document.getElementById(`fileUpload${index}`).value = ''; // 清空选择
+                        return;
+                    }
+
+                    this.uploadFile(file, index);
+                }
+            },
+// 新增通过申请方法
+            approveApplication() {
+                if (this.uploadedFiles.length === 0) {
+                    alert('请上传所需材料');
+                    return;
+                }
+                this.$confirm('确认提交吗?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    $.operate.saveTab(`${this.prefix}/leaveAudit`,{applyId:this.formData.applyId});
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: '已取消'
+                    });
+                });
+            },
+            // 新增显示退回对话框方法
+            showRejectDialog() {
+                if (this.uploadedFiles.length === 0) {
+                    alert('请上传所需材料');
+                    return;
+                }
+
+                this.rejectDialogVisible = true;
+                this.rejectReason = '';
+            },
+            // 新增退回申请方法
+            rejectApplication() {
+                if (!this.rejectReason.trim()) {
+                    alert('请输入退回原因');
+                    return;
+                }
+
+                $.operate.saveTab(`${this.prefix}/goBackLeave`,{
+                    applyId:this.formData.applyId,
+                    leaveMsg:this.rejectReason
+                });
+            },
+            uploadFile(file, index) {
+                this.currentFileName[index] = file.name;
+                this.uploadProgress[index] = 0;
+
+                let formData = new FormData();
+                formData.append('applyId', this.formData.applyId || '');
+                formData.append('filename', file.name);
+                formData.append('fileCode', this.materials[index].code);
+                formData.append('file', file);
+
+                axios.post(ctx + 'system/file/upload', formData, {
+                    onUploadProgress: (progressEvent) => {
+                        this.uploadProgress[index] = 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: file.type,
+                                fileUrl: response.data.data.filePath,
+                                uploadTime: new Date().toISOString()
+                            };
+                            this.$set(this.uploadedFiles, index, [...this.uploadedFiles[index], fileInfo]);
+                            // 重置选择框
+                            document.getElementById(`fileUpload${index}`).value = '';
+                        } else {
+                            this.$message.error(`上传失败: ${response.data.msg}`);
+                        }
+                    })
+                    .catch(error => {
+                        console.error('上传错误:', error);
+                        this.$message.error('上传过程中发生错误');
+                    });
+            },
+            downloadFile(file, index) {
+                // 直接通过接口下载
+                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);
+                        this.$message.error('下载文件时出错');
+                    });
+            },
+
+
+            deleteFile(file, materialIndex, fileIndex) {
+                let event = window.event;
+                if (event) {
+                    event.preventDefault();
+                }
+                this.$confirm(`确定要删除文件 "${file.fileName}" 吗?`, '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    axios.get(ctx + 'system/file/delFile/' + file.id)
+                        .then(response => {
+                            if (response.data.code === web_status.SUCCESS) {
+                                this.uploadedFiles[materialIndex].splice(fileIndex, 1);
+                                this.$message.success('文件已成功删除');
+                            } else {
+                                this.$message.error(`删除失败: ${response.data.msg}`);
+                            }
+                        })
+                        .catch(error => {
+                            console.error('删除错误:', error);
+                            this.$message.error('删除文件时出错');
+                        });
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: '已取消删除'
+                    });
+                });
+            },
+            submitHandler() {
+                if (this.uploadedFiles.length == 0) {
+                    this.$message.warning('请上传所需材料');
+                    return;
+                }
+
+                this.$confirm('确认提交吗?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    $.operate.saveTab(`${this.prefix}/submitLeave?applyId=${this.formData.applyId}`);
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: '已取消'
+                    });
+                });
+            },
+            // 获取已上传文件
+            getUploadedFiles() {
+                if (!this.formData.applyId) return;
+
+                // 使用forEach确保每个请求有自己的作用域
+                this.materials.forEach((material, index) => {
+                    axios.get(ctx + 'system/file/getFileInfo', {
+                        params: {
+                            applyId: this.formData.applyId,
+                            fileCode: material.code,
+                        }
+                    })
+                        .then(response => {
+                            if (response.data.code === web_status.SUCCESS) {
+                                // 使用Vue.set确保响应式更新
+                                this.$set(this.uploadedFiles, index, response.data.data.map((file) => {
+                                    return {
+                                        id: file.fileId,
+                                        fileName: file.fileName,
+                                        fileSize: file.fileSize,
+                                        fileType: file.fileType,
+                                        fileUrl: file.filePath,
+                                        uploadTime: file.createTime
+                                    }
+                                }));
+                            } else {
+                                console.error(`获取${material.name}文件列表失败:`, response.data.msg);
+                                this.$message.error(`获取${material.name}已上传文件失败: ${response.data.msg}`);
+                            }
+                        })
+                        .catch(error => {
+                            console.error(`获取${material.name}文件列表错误:`, error);
+                            this.$message.error(`获取${material.name}已上传文件时出错`);
+                        });
+                });
+            },
+
+            // 图片预览相关方法
+            isImageFile(fileName) {
+                const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp','pdf'];
+                const extension = fileName.split('.').pop().toLowerCase();
+                return imageExtensions.includes(extension);
+            },
+
+            getFileIcon(fileName) {
+                const extension = fileName.split('.').pop().toLowerCase();
+                if (extension === 'pdf') return 'fa-solid fa-file-pdf text-red-500';
+                if (['doc', 'docx'].includes(extension)) return 'fa-solid fa-file-word text-blue-500';
+                if (['jpg', 'jpeg', 'png', 'gif', 'bmp'].includes(extension)) return 'fa-solid fa-file-image text-green-500';
+                return 'fa-solid fa-file text-gray-500';
+            },
+
+            previewFile(file) {
+                let extension = file.fileName.split('.').pop().toLowerCase();
+                if (extension === 'pdf') {
+                    // 使用preventDefault阻止默认行为,避免影响当前页面状态
+                    let event = window.event;
+                    if (event) {
+                        event.preventDefault();
+                    }
+                    window.open(file.fileUrl, '_blank');
+                    return
+                }
+                this.previewingFile = file;
+                this.previewModalVisible = true;
+            },
+
+            closePreviewModal() {
+                this.previewModalVisible = false;
+                this.previewingFile = {};
+            },
+
+            getPreviewUrl(file) {
+                // 如果是图片,直接返回URL
+                if (this.isImageFile(file.fileName)) {
+                    return ctx + 'system/file/download?fileId=' + file.id;
+                }
+                return '';
+            }
+        },
+        mounted() {
+            // 从后端获取转义后的 JSON 字符串
+            if ([[${applyInfoList}]]){
+                this.formData = {...[[${applyInfoList}]]}
+                // 获取图片并转换为 Blob
+                if (this.formData.photoUrl) {
+                    fetch(this.formData.photoUrl)
+                        .then(response => response.blob())
+                        .then(blob => {
+                            this.selectedFile = blob;
+                        })
+                        .catch(error => console.error('处理图片时出错:', error));
+                }
+            }
+            // 获取已上传文件
+            this.getUploadedFiles();
+        }
+    });
 
+</script>
 </body>
 </html>
\ No newline at end of file