Ver código fonte

导出前提交 20260402

ruhuxu 12 horas atrás
pai
commit
c0030ddb19

Diferenças do arquivo suprimidas por serem muito extensas
+ 635 - 151
js/vue/ss-components.js


+ 15 - 9
page/biz/grcz_grczAdd.ss.jsp

@@ -41,9 +41,11 @@
 					}
 				%>
 			</td>
-		
+		</tr>
+		<tr>
 			<th>班级/亲属</th>
-			<td  style="display: flex;align-items: center;">
+			<td style="display: flex;align-items: center;border: none;
+    border-right: 1px solid #e2e4ec;">
 				<objp.ss name="bjid" cb="bj" inp="true" width="200px"/>
 				<onoff.ss name="rylbm" mode="edit" rad="false" null="false" val="1100" />
 				<input name="rylbm" value="职工亲属" ssVal="1000" />
@@ -66,21 +68,20 @@
 
 				<objp.ss name="ryid" cb="ryByBjOrRylb" inp="true" onChange="selBaseInfoByRyid" filterField="bjid,rylbm" />
 			</td>
-		
+		</tr>
+		<tr>
 			<th>部门/班级</th>
 			<td id='bmbj'></td>
 		</tr>
 		<tr>
 			<th>姓名</th>
 			<td id='xm'></td>
-		
-			<th>人员号</th>
-			<td id='ryh'></td>
 		</tr>
 		<tr>
-			<th>消费余额</th>
-			<td  colspan="3"><input name="xfye"/></td>
+			<th>人员号</th>
+			<td id='ryh'></td>
 		</tr>
+		
 		<tr>
 			<th>金额</th>
 			<td>
@@ -90,7 +91,12 @@
 				</script>
 				<ss-inp v-model="je" name="je" placeholder="请输入金额"></ss-inp>
 			</td>
-		
+		</tr>
+		<tr>
+			<th>消费余额</th>
+			<td ><input name="xfye"/></td>
+		</tr>
+		<tr>
 			<th>描述</th>
 			<td>
 				<script>

+ 16 - 14
page/biz/grcz_grtfAdd.ss.jsp

@@ -11,11 +11,7 @@
 	  .form-container .content-box {
 		  height: calc(100% - 80px) !important;
 	  }
-	  td{
-		display: flex;
-		align-items: center;
-		justify-content: flex-start;
-		}
+
 	</style>
 
 </head>
@@ -45,9 +41,11 @@
 						}
 					%>
 				</td>
-			
+			</tr>
+			<tr>
 				<th>班级/亲属</th>
-				<td  style="display: flex;align-items: center;">
+				<td style="display: flex;align-items: center;border: none;
+    border-right: 1px solid #e2e4ec;">
 					<objp.ss name="bjid" cb="bj" inp="true" width="200px"/>
 					<onoff.ss name="rylbm" mode="edit" rad="false" null="false" val="1100" />
 					<input name="rylbm" value="职工亲属" ssVal="1000" />
@@ -70,21 +68,20 @@
 
 					<objp.ss name="ryid" cb="ryByBjOrRylb" inp="true" onChange="selBaseInfoByRyid" filterField="bjid,rylbm" />
 				</td>
-			
+			</tr>
+			<tr>
 				<th>部门/班级</th>
 				<td id='bmbj'></td>
 			</tr>
 			<tr>
 				<th>姓名</th>
 				<td id='xm'></td>
-			
-				<th>人员号</th>
-				<td id='ryh'></td>
 			</tr>
 			<tr>
-				<th>消费余额</th>
-				<td  colspan="3"><input name="xfye"/></td>
+				<th>人员号</th>
+				<td id='ryh'></td>
 			</tr>
+			
 			<tr>
 				<th>金额</th>
 				<td>
@@ -94,7 +91,12 @@
 					</script>
 					<ss-inp v-model="je" name="je" placeholder="请输入金额"></ss-inp>
 				</td>
-			
+			</tr>
+			<tr>
+				<th>消费余额</th>
+				<td ><input name="xfye"/></td>
+			</tr>
+			<tr>
 				<th>描述</th>
 				<td>
 					<script>

+ 662 - 0
page/biz/ws_inp.ss.jsp

@@ -0,0 +1,662 @@
+<!-- 引入必要的JavaScript库 -->
+<js.ss file="/ss/jquery/jquery1.11.3.min.js"/>
+<js.ss file="/ss/jquery/jquery.form.min.js"/>
+<js.ss file="/ss/js/upload.js"/>
+
+<div class='content-div' ssFith="true">
+    <table class='form'>
+        <tr>
+            <th>上传原件</th>
+            <td>
+                <!-- 上传按钮 - upload.js会绑定点击事件 -->
+                <input type="button" id="scyjEdit" class="content-button" value="选择文件..."/>
+                <!-- 文件信息显示区域 - upload.js必需的元素 -->
+                <span id="scyjBaseName" class="file-info"></span>
+                <!-- 操作按钮区域 - upload.js控制显示/隐藏 -->
+                <span class="file-action">
+					<button id="checkScyj" style="display:none;" onclick="checkFile('scyj')">查看</button>
+					<button id="qxScyj" style="display:none;" onclick="uploadFileClean('scyj')">删除</button>
+				</span>
+            </td>
+            <th>上传后路径</th>
+            <td>
+                <!-- upload.js上传成功后会将路径填充到这里 -->
+                <input mc="mc" name="scyjwj" id="scyjpath" value="" style="width: 300px;"/>
+                <!-- 隐藏的文件名输入框,upload.js需要 -->
+                <input type="hidden" name="scyjBaseName" value=""/>
+            </td>
+            <td>
+                <input id="path" name='uploadPath' style="width: 200px;"/>
+            </td>
+        </tr>
+
+        <!-- 新增:生成原件行 -->
+        <tr>
+            <th>生成原件</th>
+            <td colspan="4">
+                <input type="button" id="generateDocumentBtn" class="content-button" value="生成原件"
+                       onclick="generateOfficialDocument()"
+                       style="background-color: #1890ff; color: white; border: 1px solid #1890ff;"/>
+                <span id="generateStatus" style="margin-left: 10px; color: #666; font-size: 12px;"></span>
+            </td>
+        </tr>
+
+        <tr>
+            <th>文书类别</th>
+            <td><input type="text" name="wslbm" style="width: 200px;"/></td>
+            <th>密级</th>
+            <td><input name="wsmjm" style="width: 200px;"/></td>
+        </tr>
+
+        <tr>
+            <th>范围</th>
+            <td><input type="text" name="wsfwm" style="width: 200px;"/></td>
+            <th>管理类别</th>
+            <td><input name="gllbm" style="width: 200px;"/></td>
+        </tr>
+
+        <tr>
+            <th>标题</th>
+            <td colspan="3"><input name="bt" style="width: 100%;"/></td>
+        </tr>
+
+        <tr>
+            <th>摘要</th>
+            <td colspan="3"><input name="zy" style="width: 100%;"/></td>
+        </tr>
+        <tr>
+            <th>正文</th>
+            <td colspan="3">
+                <input name="zwwj" ssBtn="{desc:'附件',name:'fjid',val:'${ws.fjid}'}" width="700px" height="420px"/>
+            </td>
+        </tr>
+        <tr>
+            <th>拟稿人员</th>
+            <td><input name="ngryid" style="width: 170px;"/></td>
+            <th>拟稿部门</th>
+            <td><input name="ngbmid" style="width: 170px;"/></td>
+        </tr>
+    </table>
+</div>
+
+<!-- 将所有JavaScript函数和初始化代码集中放在这里 -->
+<script>
+    // 全局变量定义
+    var wd = window.wd || {};
+    wd.app = wd.app || {name: 'defaultApp'};
+
+    // 生成原件按钮状态
+    var isGenerating = false;
+
+    // 获取账户信息函数
+    function getAccountInfo() {
+        return {
+            xmmc: 'defaultProject'
+        };
+    }
+
+    // 查看文件函数
+    function checkFile(fileId) {
+        var filePath = $('input[name="' + fileId + 'wj"]').val();
+        if (!filePath) {
+            alert('请先上传文件');
+            return;
+        }
+        alert('文件路径:' + filePath + '\n点击确定后将尝试打开文件');
+        window.open(filePath, '_blank');
+    }
+
+    // upload.js 需要的清理文件函数
+    function uploadFileClean(id) {
+        $('#' + id + 'Name').html('');
+        $('input[name="' + id + 'wj"]').val('');
+        $('#' + id + 'Edit_File').val('');
+        $('#' + id + 'path').val('');
+        $("#qx" + id).hide();
+        $("#check" + id).hide();
+
+        // 同时清空文件名显示
+        $('#' + id + 'BaseName').html('');
+        $('input[name="' + id + 'BaseName"]').val('');
+    };
+
+    // 生成原件函数
+    function generateOfficialDocument() {
+        console.log('生成原件按钮被点击');
+
+        if (isGenerating) {
+            console.log('正在生成中,请等待...');
+            return; // 防止重复点击
+        }
+
+        // 验证必填字段
+        // var title = $('input[name="bt"]').val();
+        var title ="1233333";
+      /*  if (!title || title.trim() === '') {
+            alert('请填写标题');
+            $('input[name="bt"]').focus();
+            return;
+        }*/
+
+        // 获取HTML内容(从正文控件获取)
+        var htmlContent = '';
+        var editorElement = document.querySelector('ss-editor[name="zwwj"]');
+        if (editorElement && editorElement.__vue__) {
+            var vueInstance = editorElement.__vue__;
+            if (vueInstance.editorContent !== undefined) {
+                htmlContent = vueInstance.editorContent;
+                console.log('从editorContent获取到HTML内容,长度:', htmlContent.length);
+            } else {
+                // 尝试其他获取方式
+                try {
+                    var editor = $(editorElement).find('.ql-editor');
+                    if (editor.length) {
+                        htmlContent = editor.html();
+                        console.log('从.ql-editor获取到HTML内容,长度:', htmlContent.length);
+                    } else {
+                        console.warn('无法找到富文本编辑器内容');
+                    }
+                } catch (e) {
+                    console.warn('获取编辑器内容失败:', e);
+                }
+            }
+        } else {
+            console.warn('未找到富文本编辑器元素或Vue实例');
+        }
+
+        if (!htmlContent || htmlContent.trim() === '') {
+            if (!confirm('正文内容为空,确定要生成空白公文吗?')) {
+                return;
+            }
+        }
+
+        // 收集生成参数
+        var params = {
+            institutionName: '广州工商学院', // 可以从配置获取或输入框获取
+            documentNumber: '数教函〔2026〕2号', // 可以从输入框获取,这里用示例
+            documentTitle: title,
+            htmlContent: htmlContent,
+            sender: '数字教育与装备中心', // 可以从用户信息或输入框获取
+            receiver: '各学院、各部门:',
+            hasAttachment: false,
+            attachmentInfo: '',
+            sealImagePath: 'D:\\tmp\\seal\\yz2.png', // 可以从配置获取
+            enableSeal: true
+        };
+
+        console.log('生成参数:', params);
+
+        // 开始生成
+        generateAndUploadDocument(params);
+    }
+
+    // 生成并上传公文
+    function generateAndUploadDocument(params) {
+        isGenerating = true;
+        $('#generateStatus').html('正在生成公文...').css('color', '#1890ff');
+        $('#generateDocumentBtn').prop('disabled', true).css('opacity', 0.7);
+
+        // 使用XMLHttpRequest来获取二进制数据
+        var xhr = new XMLHttpRequest();
+        xhr.open('POST', "<serv.ss name='ws_zh_schtwj'/>", true);
+        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
+        xhr.responseType = 'arraybuffer'; // 重要:指定响应类型为arraybuffer
+
+        // 构建请求参数
+        var formData = new URLSearchParams();
+        formData.append('institutionName', params.institutionName);
+        formData.append('documentNumber', params.documentNumber);
+        formData.append('documentTitle', params.documentTitle);
+        formData.append('htmlContent', params.htmlContent);
+        formData.append('sealImagePath', params.sealImagePath);
+        formData.append('sender', params.sender);
+        formData.append('receiver', params.receiver);
+        formData.append('hasAttachment', params.hasAttachment);
+        formData.append('attachmentInfo', params.attachmentInfo);
+        formData.append('enableSeal', params.enableSeal);
+
+        // 监听进度事件
+        xhr.addEventListener('progress', function(e) {
+            if (e.lengthComputable) {
+                var percentComplete = (e.loaded / e.total) * 100;
+                $('#generateStatus').html('生成中... ' + Math.round(percentComplete) + '%');
+            }
+        }, false);
+
+        xhr.onload = function() {
+            if (xhr.status === 200) {
+                console.log('收到服务器响应,状态码:', xhr.status);
+
+                // 检查响应类型
+                var contentType = xhr.getResponseHeader('Content-Type');
+                console.log('响应类型:', contentType);
+
+                if (contentType && contentType.indexOf('application/pdf') !== -1) {
+                    console.log('返回的是PDF文件流');
+
+                    // 获取ArrayBuffer
+                    var arrayBuffer = xhr.response;
+                    console.log('PDF文件大小:', arrayBuffer ? arrayBuffer.byteLength : 0);
+
+                    if (!arrayBuffer || arrayBuffer.byteLength === 0) {
+                        console.error('PDF文件流为空');
+                        $('#generateStatus').html('PDF文件流为空').css('color', '#ff4d4f');
+                        alert('生成的PDF文件为空,请检查服务器端');
+                        return;
+                    }
+
+                    // 创建Blob
+                    var blob = new Blob([arrayBuffer], { type: 'application/pdf' });
+                    var fileName = params.documentTitle.replace(/[^\u4e00-\u9fa5a-zA-Z0-9]/g, '_') + '.pdf';
+
+                    console.log('生成的PDF文件名:', fileName, '文件大小:', blob.size);
+
+                    if (blob.size === 0) {
+                        console.error('Blob对象为空');
+                        $('#generateStatus').html('Blob对象为空').css('color', '#ff4d4f');
+                        alert('生成的PDF文件为空,请检查服务器端');
+                        return;
+                    }
+
+                    // 上传生成的PDF文件
+                    uploadGeneratedPdf(blob, fileName, function(uploadResult) {
+                        if (uploadResult && uploadResult.fileList && uploadResult.fileList.length > 0) {
+                            var filePath = uploadResult.fileList[0].path;
+                            var fileName = uploadResult.fileList[0].fileName;
+
+                            console.log('文件上传成功,路径:', filePath, '文件名:', fileName);
+
+                            // 构建完整的文件路径
+                            var fullFilePath = filePath;
+
+                            // 回填到上传路径输入框
+                            $('#scyjpath').val(fullFilePath);
+                            $('input[name="scyjwj"]').val(fullFilePath);
+                            $('input[name="uploadPath"]').val(fullFilePath);
+                            $('#scyjBaseName').text(fileName);
+                            $('input[name="scyjBaseName"]').val(fileName);
+                            $('#checkScyj').show();
+                            $('#qxScyj').show();
+
+                            $('#generateStatus').html('生成并上传成功!').css('color', '#52c41a');
+                            alert('公文生成并上传成功!文件路径:' + fullFilePath);
+                        } else {
+                            console.error('上传失败,返回结果:', uploadResult);
+                            $('#generateStatus').html('上传失败').css('color', '#ff4d4f');
+                            alert('上传失败,请重试');
+                        }
+                    });
+                } else {
+                    console.log('返回的不是PDF,尝试解析JSON响应');
+                    try {
+                        // 尝试将响应解析为JSON
+                        var decoder = new TextDecoder('utf-8');
+                        var text = decoder.decode(new Uint8Array(xhr.response));
+                        var result = JSON.parse(text);
+                        console.log('解析后的JSON结果:', result);
+
+                        if (result.success === false) {
+                            $('#generateStatus').html('生成失败:' + (result.message || '未知错误')).css('color', '#ff4d4f');
+                            alert('生成失败:' + (result.message || '未知错误'));
+                        } else {
+                            $('#generateStatus').html('未知响应格式').css('color', '#ff4d4f');
+                            alert('未知响应格式,请检查接口');
+                        }
+                    } catch (e) {
+                        console.error('响应解析失败:', e);
+                        $('#generateStatus').html('响应解析失败').css('color', '#ff4d4f');
+                        alert('服务器响应异常:' + e.message);
+                    }
+                }
+            } else {
+                console.error('HTTP请求失败,状态码:', xhr.status);
+                $('#generateStatus').html('生成失败,状态码:' + xhr.status).css('color', '#ff4d4f');
+                alert('生成失败,HTTP状态码:' + xhr.status);
+            }
+        };
+
+        xhr.onerror = function() {
+            console.error('网络错误');
+            $('#generateStatus').html('生成失败:网络错误').css('color', '#ff4d4f');
+            alert('生成失败:网络错误,请检查网络连接');
+        };
+
+        xhr.onloadend = function() {
+            console.log('生成请求完成');
+            isGenerating = false;
+            $('#generateDocumentBtn').prop('disabled', false).css('opacity', 1);
+        };
+
+        console.log('开始生成公文,发送请求到服务器...');
+        xhr.send(formData.toString());
+    }
+    // 上传生成的PDF文件
+    function uploadGeneratedPdf(blob, fileName, callback) {
+        console.log('开始上传生成的PDF文件:', fileName, '大小:', blob.size);
+        $('#generateStatus').html('正在上传文件...').css('color', '#1890ff');
+
+        if (blob.size === 0) {
+            console.error('要上传的文件大小为0');
+            alert('要上传的文件为空,无法上传');
+            callback(null);
+            return;
+        }
+
+        // 创建FormData
+        var formData = new FormData();
+        formData.append('file', blob, fileName);
+        formData.append('name', fileName);
+        formData.append('type', 'document');
+        formData.append('app', wd.app ? wd.app.name : getAccountInfo().xmmc);
+
+        console.log('FormData创建完成,开始上传...');
+
+        // 使用原有的上传接口
+        $.ajax({
+            url: "/service?ssServ=ulByHttp&type=document",
+            type: 'POST',
+            data: formData,
+            processData: false,
+            contentType: false,
+            xhr: function() {
+                var xhr = new XMLHttpRequest();
+                xhr.upload.addEventListener('progress', function(e) {
+                    if (e.lengthComputable) {
+                        var percentComplete = (e.loaded / e.total) * 100;
+                        $('#generateStatus').html('上传中... ' + Math.round(percentComplete) + '%');
+                    }
+                }, false);
+                return xhr;
+            },
+            beforeSend: function() {
+                console.log('开始上传文件到服务器...');
+            },
+            success: function(result) {
+                console.log('文件上传成功,返回结果:', result);
+                try {
+                    if (typeof result === 'string') {
+                        result = JSON.parse(result);
+                    }
+                    // 这里不再检查success字段,只检查是否有fileList
+                    if (result && result.fileList && result.fileList.length > 0) {
+                        callback(result);
+                    } else {
+                        // 如果返回结果中没有fileList,但确实有有效数据,也可以认为是成功
+                        callback(result);
+                    }
+                } catch (e) {
+                    console.error('解析上传响应失败:', e, '原始结果:', result);
+                    callback(null);
+                }
+            },
+            error: function(xhr, status, error) {
+                console.error('文件上传失败:', error, '状态:', status, 'XHR:', xhr);
+                alert('文件上传失败:' + error);
+                callback(null);
+            }
+        });
+    }
+    // 页面加载完成后初始化上传功能
+    $(document).ready(function () {
+        console.log('文档加载完成,开始初始化上传功能...');
+
+        // 检查upload.js是否已加载
+        if (typeof $.fn.uploadFile === 'undefined') {
+            console.error('upload.js 未正确加载,请检查路径:/ss/js/upload.js');
+            alert('文件上传插件加载失败,请联系管理员');
+            return;
+        }
+
+        console.log('upload.js 已加载,开始初始化上传插件...');
+
+        // 调试:检查按钮是否存在
+        console.log('上传按钮是否存在:', $('#scyjEdit').length > 0);
+
+        // 初始化上传插件
+        try {
+            console.log('开始初始化uploadFile插件...');
+
+            // 使用upload.js插件
+            $('#scyjEdit').uploadFile({
+                name: 'scyj', // 必须与页面中的元素ID前缀一致
+                type: 'document', // 上传类型,可根据需要设置
+                validation: 'jpg,jpeg,png,pdf,doc,docx,xls,xlsx,ppt,pptx,txt,zip,rar', // 允许上传的文件类型
+                size: 10240, // 文件大小限制,单位KB(10MB)
+                app: wd.app ? wd.app.name : getAccountInfo().xmmc, // 应用名称
+                action: "/service?ssServ=ulByHttp&type=document", // 明确指定action
+                beforeClick: function () {
+                    // 点击前的验证逻辑,返回false可阻止上传
+                    console.log('开始选择文件...');
+                    return true;
+                },
+                onchange: function (settings) {
+                    // 文件选择后的回调
+                    console.log('已选择文件,准备上传...');
+                },
+                callback: function (result) {
+                    // 上传成功后的回调函数
+                    console.log('文件上传成功:', result);
+
+                    // 可以在这里添加额外的处理逻辑
+                    if (result && result.fileList && result.fileList.length > 0) {
+                        // 显示成功消息
+                        var fileName = result.fileList[0].fileName;
+                        alert('文件 "' + fileName + '" 上传成功!');
+
+                        // 自动填充上传路径输入框
+                        var filePath = result.fileList[0].path;
+                        if (filePath) {
+                            $('input[name="uploadPath"]').val(filePath);
+                        }
+
+                        // 文件上传成功之后, 获取对应的文件 , 并且将pdf文件解析出正文内容
+                        // 获取文件路径, 然后调用后端代码
+                        // if (filePath && filePath.toLowerCase().endsWith('.pdf')) {
+                        if (filePath ) {
+                            $.ajax({
+                                url: "<serv.ss name='ws_zh_pdf2html'/>",
+                                type: 'post',
+                                data: {
+                                    path: filePath,
+                                    fileName: fileName
+                                },
+                                success: function (result) {
+                                    // 提取成功后, 将正文内容传输到正文控件中
+                                    var parse = JSON.parse(result);
+                                    console.log(parse.data);
+
+                                    // 获取组件实例
+                                    var editorElement = document.querySelector('ss-editor[name="zwwj"]');
+                                    if (editorElement && editorElement.__vue__) {
+                                        var vueInstance = editorElement.__vue__;
+
+                                        // 尝试设置editorContent变量
+                                        if (vueInstance.editorContent !== undefined) {
+                                            vueInstance.editorContent = parse.data;
+                                            console.log('通过editorContent变量设置成功');
+                                        }
+
+                                        // 触发change事件
+                                        var changeEvent = new Event('change', { bubbles: true });
+                                        editorElement.dispatchEvent(changeEvent);
+                                    }
+                                },
+                                error: function(xhr, status, error) {
+                                    console.warn('PDF解析失败:', error);
+                                }
+                            });
+                        }
+                    }
+                }
+            });
+
+            console.log('uploadFile插件初始化成功');
+
+        } catch (error) {
+            console.error('上传插件初始化失败:', error);
+            alert('上传插件初始化失败: ' + error.message);
+
+            // 如果upload.js插件失败,使用简单方法
+            $('#scyjEdit').off('click.simple').on('click.simple', function () {
+                // 创建一个临时的文件input
+                var fileInput = $('#scyjEdit_File');
+                if (fileInput.length === 0) {
+                    $('body').append('<input type="file" id="scyjEdit_File" style="display:none;">');
+                    fileInput = $('#scyjEdit_File');
+                }
+
+                fileInput.off('change').on('change', function () {
+                    if (this.files.length > 0) {
+                        var fileName = this.files[0].name;
+                        $('#scyjBaseName').text(fileName);
+                        $('input[name="scyjBaseName"]').val(fileName);
+                        $('#checkScyj').show();
+                        $('#qxScyj').show();
+                        alert('已选择文件: ' + fileName);
+                    }
+                });
+
+                fileInput.click();
+            });
+        }
+
+        // 添加上传路径输入框的点击事件
+        $('#scyjpath').click(function () {
+            var currentPath = $(this).val();
+            if (currentPath) {
+                $(this).select();
+            }
+        });
+
+        // 为删除按钮添加确认提示
+        $('body').on('click', '#qxScyj', function (e) {
+            if (!confirm('确定要删除已上传的文件吗?')) {
+                e.preventDefault();
+                return false;
+            }
+        });
+
+        // 初始化页面时检查是否有已上传的文件
+        var existingFile = $('input[name="scyjwj"]').val();
+        if (existingFile) {
+            var fileName = existingFile.split('/').pop();
+            $('#scyjBaseName').text(fileName);
+            $('input[name="scyjBaseName"]').val(fileName);
+            $('#checkScyj').show();
+            $('#qxScyj').show();
+            $('input[name="uploadPath"]').val(existingFile);
+        }
+
+        console.log('文件上传功能初始化完成');
+    });
+
+    // 表单提交前的验证函数
+    function validateForm() {
+        var filePath = $('input[name="scyjwj"]').val();
+        var title = $('input[name="bt"]').val();
+
+        if (!title || title.trim() === '') {
+            alert('请填写标题');
+            $('input[name="bt"]').focus();
+            return false;
+        }
+
+        if (!filePath || filePath.trim() === '') {
+            if (!confirm('您尚未上传原件,确定要继续提交吗?')) {
+                $('#scyjEdit').focus();
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    // 修复uploadFile插件的问题
+    function fixUploadPlugin() {
+        // 检查是否有必要的CSS样式
+        if (!$('.content-button').length) {
+            $('#scyjEdit').addClass('content-button');
+        }
+
+        // 确保文件输入框存在
+        if (!$('#scyjEdit_File').length) {
+            $('body').append('<input type="file" id="scyjEdit_File" name="fileEdit" style="display:none;">');
+        }
+
+        // 手动绑定点击事件
+        $('#scyjEdit').off('click.manual').on('click.manual', function () {
+            console.log('手动触发文件选择对话框');
+            $('#scyjEdit_File').click();
+        });
+
+        // 监听文件选择
+        $('#scyjEdit_File').off('change').on('change', function (e) {
+            console.log('文件已选择:', this.files);
+            if (this.files && this.files.length > 0) {
+                var fileName = this.files[0].name;
+                var fileSize = this.files[0].size;
+                var fileType = this.files[0].type;
+
+                console.log('文件名:', fileName, '大小:', fileSize, '类型:', fileType);
+
+                // 显示文件信息
+                $('#scyjBaseName').text(fileName);
+                $('input[name="scyjBaseName"]').val(fileName);
+
+                // 模拟上传
+                simulateUpload(fileName, fileSize);
+            }
+        });
+    }
+
+    // 模拟文件上传
+    function simulateUpload(fileName, fileSize) {
+        console.log('开始模拟上传文件:', fileName);
+
+        // 显示进度条
+        $('#scyjBaseName').html('<div class="progress"><div class="bar"></div><div class="percent">0%</div></div>');
+
+        // 模拟上传进度
+        var progress = 0;
+        var interval = setInterval(function () {
+            progress += 10;
+            if (progress <= 100) {
+                $('.bar').width(progress + '%');
+                $('.percent').text(progress + '%');
+
+                if (progress === 100) {
+                    clearInterval(interval);
+
+                    // 模拟上传完成
+                    setTimeout(function () {
+                        // 生成模拟文件路径
+                        var timestamp = new Date().getTime();
+                        var filePath = '/uploads/' + timestamp + '_' + fileName;
+
+                        // 更新页面
+                        $('#scyjBaseName').text(fileName);
+                        $('input[name="scyjwj"]').val(filePath);
+                        $('input[name="uploadPath"]').val(filePath);
+                        $('#checkScyj').show();
+                        $('#qxScyj').show();
+
+                        alert('文件 "' + fileName + '" 上传成功!');
+                    }, 500);
+                }
+            }
+        }, 200);
+    }
+
+    // 页面完全加载后修复插件
+    $(window).on('load', function () {
+        console.log('页面完全加载完成,检查上传功能...');
+
+        // 如果upload.js插件没有正常工作,使用修复方法
+        setTimeout(function () {
+            if ($('#scyjEdit').length && !$('#scyjEdit').data('upload-initialized')) {
+                console.log('使用备用上传方案');
+                fixUploadPlugin();
+            }
+        }, 1000);
+    });
+</script>

+ 39 - 0
page/biz/xy_baseInfo.ss.jsp

@@ -0,0 +1,39 @@
+<div class="content-div" ssFith="true">
+	<table class="form">
+		<tr>
+			<th rowspan="2" style="width:160px;">相片</th>
+			<td rowspan="2">
+				<input name="zjzwj" placeholder="default-photo.png" class="id-photo"/>
+				<input name="yszwj" placeholder="default-personalPhoto.png" class="life-photo"/>
+			</td>
+			<th style="width:160px;">姓名</th>
+			<td><input name="xm" width="108px"/></td>
+		</tr>
+		<tr>
+			<th>性别</th>
+			<td><input name="xbm" width="90px"/></td>
+		</tr>
+		<tr>
+			<th>民族</th>
+			<td colspan="3"><input name="mzm" width="117px"/></td>
+		</tr>
+		<tr>
+			<th>学号</th>
+			<td><input name="ryh" width="117px"/></td>
+			<th>班级</th>
+			<td><input name="bjid" width="117px"/></td>
+		</tr>
+		<tr>
+			<th>消费余额</th>
+			<td><input name="xfye" width="117px"/></td>
+			<th>就读方式</th>
+			<td><input name="jdfsm" width="117px"/></td>
+		</tr>
+		<tr>
+			<th>是否坐校车</th>
+			<td><input name="sfzxc" width="117px"/></td>
+			<th>是否晚自修</th>
+			<td><input name="sfwzx" width="117px"/></td>
+		</tr>
+	</table>
+</div>

+ 5 - 5
page/biz/xy_inp.ss.jsp

@@ -1,10 +1,10 @@
 <div class="content-div" ssFith="true">
 	<table class="form">
 		<tr>
-			<th rowspan="4" style="width:160px;">相片</th>
-			<td rowspan="4" style="width:260px;">
-				<input name="zjzwj" placeholder="default-photo.png" class="photo"/>
-				<input name="yszwj" style="margin-top:42px; margin-left:13px;" placeholder="default-personalPhoto.png" class="personalPhoto photo"/>
+			<th rowspan="2" style="width:160px;">相片</th>
+			<td rowspan="2" >
+				<input name="zjzwj" placeholder="default-photo.png" class="id-photo"/>
+				<input name="yszwj"  placeholder="default-personalPhoto.png" class="life-photo" />
 			</td>
 			<th style="width:160px;">姓名</th>
 			<td><input name="xm" width="108px"/></td>
@@ -15,7 +15,7 @@
 		</tr>
 		<tr>
 			<th>民族</th>
-			<td><input name="mzm" width="117px"/></td>
+			<td colspan="3"><input name="mzm" width="117px"/></td>
 		</tr>
 		<tr>
 			<th>家庭困难程度</th>

+ 20 - 7
page/env/objInp.jsp

@@ -262,9 +262,19 @@
 	};
 
 	const data = {};
+	console.log('[objInp] formElemConfig:', window.SS.dom.formElemConfig);
 	if (window.SS.dom.formElemConfig) {
 		Object.entries(window.SS.dom.formElemConfig).forEach(([key, config]) => {
-			data[key] = config.val;
+			// 如果 config 有 val 属性,使用 val;否则如果 config 本身是数组/对象,直接使用 config
+			// 这支持 zwwjCustomButtons 这样的直接数组配置
+			if (config && typeof config === 'object' && 'val' in config) {
+				data[key] = config.val;
+			} else {
+				data[key] = config;
+			}
+			if (key === 'zwwjCustomButtons') {
+				console.log('[objInp] zwwjCustomButtons 处理:', config, '->', data[key]);
+			}
 			// 处理 objPicker
 			if (config.type === window.SS.dom.TYPE.OBJPICKER) {
 				data[key + "ObjPicker"] = true;
@@ -278,10 +288,14 @@
 			    data[key + "Mode"] = config.mode
 			    console.log(data[key + "Mode"]);
 			}
-			// 处理富文本编辑器
-			if (config.type === window.SS.dom.TYPE.RICHTEXT) {
+			// 处理富文本编辑器(RICHTEXT 和 HTML 类型)
+			if (config.type === window.SS.dom.TYPE.RICHTEXT || config.type === window.SS.dom.TYPE.HTML) {
 				data[key + "Url"] = config.val;
 				data[key + "editor"] = config.val;
+				// 处理编辑器自定义按钮配置(同台字段)by xu 20250331
+				if (config.customButtons && Array.isArray(config.customButtons)) {
+					data[key + "CustomButtons"] = config.customButtons;
+				}
 			}
 			// 处理onoff
 			if (config.type === window.SS.dom.TYPE.ONOFFBTN) {
@@ -313,13 +327,11 @@
 
 			}
 
-		
-
-
 		// 在这里直接初始化,不需要等待 load 事件
 		window.SS.dom.initializeFormApp({
 			el: "#app",
 			data(){
+				console.log('[objInp] Vue data() 返回:', data, 'zwwjCustomButtons:', data.zwwjCustomButtons);
 				return data;
 			},
 			methods: {
@@ -392,9 +404,10 @@
 
 				});
 			}
-		})
+		});
 	});
 
+
 </script>
 <%--<script type="text/javascript">--%>
 <%--	tokenCleanser("<ss:serv name='clearPageToken'/>", {tokenList:"<%= pageContext.getAttribute(ss.page.PageC.PAGE_tokenList)%>"});--%>

+ 25 - 15
page/grcz_grczAdd.jsp

@@ -19,6 +19,8 @@
 			height: calc(100% - 80px) !important;
 		}
 
+
+
 	</style>
 
 </head>
@@ -62,9 +64,11 @@ onchange="handleGrczlbmChange"
 					}
 				%>
 			</td>
-		
+		</tr>
+		<tr>
 			<th>班级/亲属</th>
-			<td style="display: flex;align-items: center;">
+			<td style="display: flex;align-items: center;    border: none;
+    border-right: 1px solid #e2e4ec;">
 				
 <script>
 ss.dom.formElemConfig.bjid={val:null,type:window.ss.dom.TYPE.OBJP};
@@ -133,14 +137,16 @@ onChange="selBaseInfoByRyid"
 ></ss-objp>
 
 			</td>
-		
+		</tr>
+		<tr>
 			<th>部门/班级</th>
 			<td id='bmbj'></td>
 		</tr>
 		<tr>
 			<th>姓名</th>
 			<td id='xm'></td>
-		
+		</tr>
+		<tr>
 			<th>人员号</th>
 			<td id='ryh'></td>
 		</tr>
@@ -157,7 +163,12 @@ onChange="selBaseInfoByRyid"
 	placeholder="请输入金额"
 				></ss-inp>
 			</td>
-		
+		</tr>
+		<tr>
+			<th>消费余额</th>
+			<td id='xfye'></td>
+		</tr>
+		<tr>
 			<th>描述</th>
 			<td>
 				<script>
@@ -171,16 +182,19 @@ onChange="selBaseInfoByRyid"
 				></ss-inp>
 			</td>
 		</tr>
-		<tr>
-			<th>消费余额</th>
-			<td id='xfye' colspan="3"></td>
-		</tr>
+		
 		
 	</table>
 </div>
 
 
-	<div class='bottom-div'>
+	
+
+
+<input name='wdComponentID' type='hidden' value='grcz_grczAdd'/>
+
+</div>
+<div class='bottom-div'>
 
 		<ss-bottom-button
 				id="saveAndCommit"
@@ -197,11 +211,7 @@ onChange="selBaseInfoByRyid"
 		></ss-bottom-button>
 
 	</div>
-
-
-<input name='wdComponentID' type='hidden' value='grcz_grczAdd'/>
-
-</div></form>
+</form>
 <script type="text/javascript">var wdRecordValue='${wdRecordValue}';</script>
 <script type="text/javascript" src="/ss/js/wdRecord.js"></script>
 <script type="text/javascript">(function(){wdRecord("grcz_grczAdd");})();</script>

+ 21 - 11
page/grcz_grtfAdd.jsp

@@ -64,8 +64,11 @@ onchange="handleGrczlbmChange"
 					%>
 				</td>
 			
+			</tr>
+			<tr>
 				<th style="width: 120px">班级/亲属</th>
-				<td style="display: flex;align-items: center;">
+				<td style="display: flex;align-items: center;border: none;
+    border-right: 1px solid #e2e4ec;">
 					
 <script>
 ss.dom.formElemConfig.bjid={val:null,type:window.ss.dom.TYPE.OBJP};
@@ -134,14 +137,16 @@ onChange="selBaseInfoByRyid"
 ></ss-objp>
 
 				</td>
-			
+			</tr>
+			<tr>
 				<th>部门/班级</th>
 				<td id='bmbj'></td>
 			</tr>
 			<tr>
 				<th>姓名</th>
 				<td id='xm'></td>
-			
+			</tr>
+			<tr>
 				<th>人员号</th>
 				<td id='ryh'></td>
 			</tr>
@@ -158,7 +163,12 @@ onChange="selBaseInfoByRyid"
 	placeholder="请输入金额"
 					></ss-inp>
 				</td>
-			
+			</tr>
+			<tr>
+				<th>消费余额</th>
+				<td id='xfye'></td>
+			</tr>
+			<tr>
 				<th>描述</th>
 				<td>
 					<script>
@@ -172,15 +182,16 @@ onChange="selBaseInfoByRyid"
 					></ss-inp>
 				</td>
 			</tr>
-			<tr>
-				<th>消费余额</th>
-				<td id='xfye' colspan="3"></td>
-			</tr>
+			
 		</table>
 	</div>
 
 
-	<div class='bottom-div'>
+	
+
+
+<input name='wdComponentID' type='hidden' value='grcz_grtfAdd'/></div>
+<div class='bottom-div'>
 
 		<ss-bottom-button
 				id="saveAndCommit"
@@ -198,8 +209,7 @@ onChange="selBaseInfoByRyid"
 
 	</div>
 
-
-<input name='wdComponentID' type='hidden' value='grcz_grtfAdd'/></div></form>
+</form>
 <script type="text/javascript">var wdRecordValue='${wdRecordValue}';</script>
 <script type="text/javascript" src="/ss/js/wdRecord.js"></script>
 <script type="text/javascript">(function(){wdRecord("grcz_grtfAdd");})();</script>

+ 1032 - 0
page/ws_inp.jsp

@@ -0,0 +1,1032 @@
+<%@ page language="java" pageEncoding="UTF-8" isELIgnored="false" %>
+<%@ taglib uri="/ssTag" prefix="ss"%>
+
+<% pageContext.setAttribute(ss.page.PageC.PAGE_objName,"ws");%>
+<%pageContext.setAttribute("wdpageinformation","{'hastab':'0'}");%>
+<!DOCTYPE html>
+<!-- 引入必要的JavaScript库 -->
+<script type="text/javascript" src="/ss/jquery/jquery1.11.3.min.js"></script>
+<script type="text/javascript" src="/ss/jquery/jquery.form.min.js"></script>
+<script type="text/javascript" src="/ss/js/upload.js"></script>
+
+<div class='content-div' ssFith="true">
+    <table class='form'>
+        <tr>
+            <th>上传原件</th>
+            <td>
+                <!-- 上传按钮 - upload.js会绑定点击事件 -->
+                <input type="button" id="scyjEdit" class="content-button" value="选择文件..."/>
+                <!-- 文件信息显示区域 - upload.js必需的元素 -->
+                <span id="scyjBaseName" class="file-info"></span>
+                <!-- 操作按钮区域 - upload.js控制显示/隐藏 -->
+                <span class="file-action">
+					<button id="checkScyj" style="display:none;" onclick="checkFile('scyj')">查看</button>
+					<button id="qxScyj" style="display:none;" onclick="uploadFileClean('scyj')">删除</button>
+				</span>
+            </td>
+            <th>上传后路径</th>
+            <td>
+                <!-- upload.js上传成功后会将路径填充到这里 -->
+                <input mc="mc" name="scyjwj" id="scyjpath" value="" style="width: 300px;"/>
+                <!-- 隐藏的文件名输入框,upload.js需要 -->
+                <input type="hidden" name="scyjBaseName" value=""/>
+            </td>
+            <td>
+                <input id="path" name='uploadPath' style="width: 200px;"/>
+            </td>
+        </tr>
+
+        <!-- 新增:生成原件行 -->
+        <tr>
+            <th>生成原件</th>
+            <td colspan="4">
+                <input type="button" id="generateDocumentBtn" class="content-button" value="生成原件"
+                       onclick="generateOfficialDocument()"
+                       style="background-color: #1890ff; color: white; border: 1px solid #1890ff;"/>
+                <span id="generateStatus" style="margin-left: 10px; color: #666; font-size: 12px;"></span>
+            </td>
+        </tr>
+
+        <!-- Vue 桥接 API 测试按钮(可删除) -->
+        <tr>
+            <th>桥接API测试</th>
+            <td colspan="4">
+                <b>编辑器操作:</b><br/>
+                <input type="button" class="content-button" value="读取内容"
+                       onclick="readEditorContent()"
+                       style="margin: 2px 5px 2px 0;"/>
+                <input type="button" class="content-button" value="写入示例"
+                       onclick="writeEditorContent()"
+                       style="margin: 2px 5px 2px 0;"/>
+                <input type="button" class="content-button" value="清空编辑器"
+                       onclick="clearEditorWithConfirm()"
+                       style="margin: 2px 5px 2px 0;"/>
+                <br/>
+                <b>普通字段:</b><br/>
+                <input type="button" class="content-button" value="读取标题"
+                       onclick="alert('标题: ' + (readFormTitle() || '未填写'))"
+                       style="margin: 2px 5px 2px 0;"/>
+                <input type="button" class="content-button" value="设置标题"
+                       onclick="setFormTitle()"
+                       style="margin: 2px 5px 2px 0;"/>
+                <br/>
+                <b>下拉框操作:</b><br/>
+                <input type="button" class="content-button" value="读取文书类别"
+                       onclick="readDocumentType()"
+                       style="margin: 2px 5px 2px 0;"/>
+                <input type="button" class="content-button" value="随机设置文书类别"
+                       onclick="setDocumentType()"
+                       style="margin: 2px 5px 2px 0;"/>
+                <input type="button" class="content-button" value="自动匹配文书类别"
+                       onclick="autoSelectDocumentType()"
+                       style="margin: 2px 5px 2px 0;"/>
+                <br/>
+                <b>批量操作:</b><br/>
+                <input type="button" class="content-button" value="读取所有下拉框"
+                       onclick="readAllDropdowns()"
+                       style="margin: 2px 5px 2px 0;"/>
+                <input type="button" class="content-button" value="批量设置数据"
+                       onclick="batchSetFormData()"
+                       style="margin: 2px 5px 2px 0;"/>
+                <input type="button" class="content-button" value="读取完整表单"
+                       onclick="readFullFormData()"
+                       style="margin: 2px 5px 2px 0;"/>
+                <br/>
+                <span style="color: #999; font-size: 12px;">详见函数定义及 /docs/普通JS读写Vue数据方法.md</span>
+            </td>
+        </tr>
+
+        <tr>
+            <th>文书类别</th>
+            <td>
+<script>
+ss.dom.formElemConfig.wslbm={val:'${ws.wslbm}',type:window.ss.dom.TYPE.OBJP};
+</script>
+<ss-objp
+:opt="wslbmOption"
+placeholder="请选择文书类别"
+:inp="false"
+url="<ss:serv name='loadObjpOpt' parm='{"objectpickerdropdown1":"1"}' />"
+cb="wslb"
+v-model="wslbm"
+name="wslbm"
+:readonly="false"
+style="width: 200px;"
+>
+
+</ss-objp>
+</td>
+            <th>密级</th>
+            <td>
+<script>
+ss.dom.formElemConfig.wsmjm={val:'${ws.wsmjm}',type:window.ss.dom.TYPE.OBJP};
+</script>
+<ss-objp
+:opt="wsmjmOption"
+placeholder="请选择文书密级"
+:inp="false"
+url="<ss:serv name='loadObjpOpt' parm='{"objectpickerdropdown1":"1"}' />"
+cb="wsmj"
+v-model="wsmjm"
+name="wsmjm"
+:readonly="false"
+style="width: 200px;"
+>
+
+</ss-objp>
+</td>
+        </tr>
+
+        <tr>
+            <th>范围</th>
+            <td>
+<script>
+ss.dom.formElemConfig.wsfwm={val:'${ws.wsfwm}',type:window.ss.dom.TYPE.OBJP};
+</script>
+<ss-objp
+:opt="wsfwmOption"
+placeholder="请选择文书范围"
+:inp="false"
+url="<ss:serv name='loadObjpOpt' parm='{"objectpickerdropdown1":"1"}' />"
+cb="wsfw"
+v-model="wsfwm"
+name="wsfwm"
+:readonly="false"
+style="width: 200px;"
+>
+
+</ss-objp>
+</td>
+            <th>管理类别</th>
+            <td>
+<script>
+ss.dom.formElemConfig.gllbm={val:'${ws.gllbm}',type:window.ss.dom.TYPE.OBJP};
+</script>
+<ss-objp
+:opt="gllbmOption"
+placeholder="请选择管理类别"
+:inp="false"
+url="<ss:serv name='loadObjpOpt' parm='{"objectpickerdropdown1":"1"}' />"
+cb="gllb"
+v-model="gllbm"
+name="gllbm"
+:readonly="false"
+style="width: 200px;"
+>
+
+</ss-objp>
+</td>
+        </tr>
+
+        <tr>
+            <th>标题</th>
+            <td colspan="3">
+<%--自动生成:ws.bt--%>
+<script>
+ss.dom.formElemConfig.bt={val:'<ss:txt val='${ws.bt}'/>',type:window.ss.dom.TYPE.INPUT};
+</script>
+<ss-inp
+placeholder="请输入标题"
+v-model="bt"
+name="bt"
+:readonly="false"
+style="width: 100%;"
+>
+
+</ss-inp>
+</td>
+        </tr>
+
+        <tr>
+            <th>摘要</th>
+            <td colspan="3">
+<%--自动生成:ws.zy--%>
+<script>
+ss.dom.formElemConfig.zy={val:'<ss:txt val='${ws.zy}'/>',type:window.ss.dom.TYPE.INPUT};
+</script>
+<ss-inp
+placeholder="请输入摘要"
+v-model="zy"
+name="zy"
+:readonly="false"
+style="width: 100%;"
+>
+
+</ss-inp>
+</td>
+        </tr>
+        <tr>
+            <th>正文</th>
+            <td colspan="3">
+                
+<script>
+// 处理函数定义
+window.handleInsertTemplate = function(context) {
+    var templateHtml = '<div style="border: 1px solid #ccc; padding: 20px; margin: 10px 0; background: #f5f5f5;">' +
+        '<h3 style="text-align: center;">公文模板</h3>' +
+        '<p>  请输入正文内容...</p>' +
+        '<p style="text-align: right;">(此段落为模板示例)</p>' +
+        '</div>';
+    var currentContent = context.getValue() || '';
+    context.setValue(currentContent + templateHtml);
+    if (context.editor && context.editor.insertHTML) {
+        context.editor.insertHTML(templateHtml);
+    }
+    alert('已插入公文模板!');
+};
+
+window.handleClearEditor = function(context) {
+    if (confirm('确定要清空正文内容吗?')) {
+        context.setValue('');
+        if (window.ss && window.ss.dom && window.ss.dom.set) {
+            window.ss.dom.set('zwwjHtml', '');
+        }
+        alert('正文内容已清空!');
+    }
+};
+
+// zwwj 配置(按钮移到 param 中)
+ss.dom.formElemConfig.zwwj = {
+    val: '${ws.zwwj}',
+    type: window.ss.dom.TYPE.HTML
+};
+ss.dom.formElemConfig.zwwjHtml = {val: '', type: window.ss.dom.TYPE.INPUT};
+</script>
+<ss-editor
+:height="420"
+url="<ss:serv name='loadEditorBody' />"
+:param="{'mode':'${dataType=='change'?'change':'edit'}','button':[{'desc':'附件','name':'fjid','val':'${ws.fjid}','cmsUpdUrl':'<ss:serv name='regCms' dest='cmsHome' />','cmsAddUrl':'<ss:serv name='makeAttCms' />'},{'desc':'插入模板','name':'insertTemplate','icon':'editor-icon-file','func':'window.handleInsertTemplate'},{'desc':'清空','name':'clearContent','icon':'editor-icon-eraser','func':'window.handleClearEditor'}],'obj':'ws','jlztm':'${ws.jlztm}'}"
+v-model="zwwj"
+:html="zwwjHtml"
+name="zwwj"
+:readonly="false"
+width="700px"
+>
+
+</ss-editor>
+
+            </td>
+        </tr>
+        <tr>
+            <th>拟稿人员</th>
+            <td>
+<script>
+ss.dom.formElemConfig.ngryid={val:'${ws.ngryid}',type:window.ss.dom.TYPE.OBJP};
+</script>
+<ss-objp
+:opt="ngryidOption"
+placeholder="请选择拟稿人员"
+:inp="false"
+url="<ss:serv name='loadObjpOpt' parm='{"objectpickerdropdown1":"1"}' />"
+cb="ry"
+v-model="ngryid"
+name="ngryid"
+:readonly="false"
+style="width: 170px;"
+>
+
+</ss-objp>
+</td>
+            <th>拟稿部门</th>
+            <td>
+<script>
+ss.dom.formElemConfig.ngbmid={val:'${ws.ngbmid}',type:window.ss.dom.TYPE.OBJP};
+</script>
+<ss-objp
+:opt="ngbmidOption"
+placeholder="请选择拟稿部门"
+:inp="false"
+url="<ss:serv name='loadObjpOpt' parm='{"objectpickerdropdown1":"1"}' />"
+cb="bm"
+v-model="ngbmid"
+name="ngbmid"
+:readonly="false"
+style="width: 170px;"
+>
+
+</ss-objp>
+</td>
+        </tr>
+    </table>
+</div>
+
+<!-- 将所有JavaScript函数和初始化代码集中放在这里 -->
+<script>
+    // 全局变量定义
+    var wd = window.wd || {};
+    wd.app = wd.app || {name: 'defaultApp'};
+
+    // 生成原件按钮状态
+    var isGenerating = false;
+
+    // 获取账户信息函数
+    function getAccountInfo() {
+        return {
+            xmmc: 'defaultProject'
+        };
+    }
+
+
+    function checkFile(fileId) {
+        var filePath = $('input[name="' + fileId + 'wj"]').val();
+        if (!filePath) {
+            alert('请先上传文件');
+            return;
+        }
+        alert('文件路径:' + filePath + '\n点击确定后将尝试打开文件');
+        window.open(filePath, '_blank');
+    }
+
+    // upload.js 需要的清理文件函数
+    function uploadFileClean(id) {
+        $('#' + id + 'Name').html('');
+        $('input[name="' + id + 'wj"]').val('');
+        $('#' + id + 'Edit_File').val('');
+        $('#' + id + 'path').val('');
+        $("#qx" + id).hide();
+        $("#check" + id).hide();
+
+        // 同时清空文件名显示
+        $('#' + id + 'BaseName').html('');
+        $('input[name="' + id + 'BaseName"]').val('');
+    };
+
+    // 生成原件函数
+    function generateOfficialDocument() {
+        if (isGenerating) {
+            return; // 防止重复点击
+        }
+
+        var title = "1233333";
+
+        // 使用桥接 API 读取 Vue 数据(方式2:从 zwwjHtml 读取编辑器内容)
+        // 文档:/docs/普通JS读写Vue数据方法.md
+        var htmlContent = window.ss.dom.get('zwwjHtml') || '';
+
+        if (!htmlContent || htmlContent.trim() === '') {
+            if (!confirm('正文内容为空,确定要生成空白公文吗?')) {
+                return;
+            }
+        }
+
+        // 收集生成参数
+        var params = {
+            institutionName: '广州工商学院',
+            documentNumber: '数教函〔2026〕2号',
+            documentTitle: title,
+            htmlContent: htmlContent,
+            sender: '数字教育与装备中心',
+            receiver: '各学院、各部门:',
+            hasAttachment: false,
+            attachmentInfo: '',
+            sealImagePath: 'D:\\tmp\\seal\\yz2.png',
+            enableSeal: true
+        };
+
+        // 开始生成
+        generateAndUploadDocument(params);
+    }
+
+    // 生成并上传公文
+    function generateAndUploadDocument(params) {
+        isGenerating = true;
+        $('#generateStatus').html('正在生成公文...').css('color', '#1890ff');
+        $('#generateDocumentBtn').prop('disabled', true).css('opacity', 0.7);
+
+        // 使用XMLHttpRequest来获取二进制数据
+        var xhr = new XMLHttpRequest();
+        xhr.open('POST', "<ss:serv name='ws_zh_schtwj'/>", true);
+        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
+        xhr.responseType = 'arraybuffer';
+
+        // 构建请求参数
+        var formData = new URLSearchParams();
+        formData.append('institutionName', params.institutionName);
+        formData.append('documentNumber', params.documentNumber);
+        formData.append('documentTitle', params.documentTitle);
+        formData.append('htmlContent', params.htmlContent);
+        formData.append('sealImagePath', params.sealImagePath);
+        formData.append('sender', params.sender);
+        formData.append('receiver', params.receiver);
+        formData.append('hasAttachment', params.hasAttachment);
+        formData.append('attachmentInfo', params.attachmentInfo);
+        formData.append('enableSeal', params.enableSeal);
+
+        // 监听进度事件
+        xhr.addEventListener('progress', function(e) {
+            if (e.lengthComputable) {
+                var percentComplete = (e.loaded / e.total) * 100;
+                $('#generateStatus').html('生成中... ' + Math.round(percentComplete) + '%');
+            }
+        }, false);
+
+        xhr.onload = function() {
+            if (xhr.status === 200) {
+                // 检查响应类型
+                var contentType = xhr.getResponseHeader('Content-Type');
+
+                if (contentType && contentType.indexOf('application/pdf') !== -1) {
+                    // 获取ArrayBuffer
+                    var arrayBuffer = xhr.response;
+
+                    if (!arrayBuffer || arrayBuffer.byteLength === 0) {
+                        $('#generateStatus').html('PDF文件流为空').css('color', '#ff4d4f');
+                        alert('生成的PDF文件为空,请检查服务器端');
+                        return;
+                    }
+
+                    // 创建Blob
+                    var blob = new Blob([arrayBuffer], { type: 'application/pdf' });
+                    var fileName = params.documentTitle.replace(/[^\u4e00-\u9fa5a-zA-Z0-9]/g, '_') + '.pdf';
+
+                    if (blob.size === 0) {
+                        $('#generateStatus').html('Blob对象为空').css('color', '#ff4d4f');
+                        alert('生成的PDF文件为空,请检查服务器端');
+                        return;
+                    }
+
+                    // 上传生成的PDF文件
+                    uploadGeneratedPdf(blob, fileName, function(uploadResult) {
+                        if (uploadResult && uploadResult.fileList && uploadResult.fileList.length > 0) {
+                            var filePath = uploadResult.fileList[0].path;
+                            var fileName = uploadResult.fileList[0].fileName;
+
+                            // 回填到上传路径输入框
+                            var fullFilePath = filePath;
+                            $('#scyjpath').val(fullFilePath);
+                            $('input[name="scyjwj"]').val(fullFilePath);
+                            $('input[name="uploadPath"]').val(fullFilePath);
+                            $('#scyjBaseName').text(fileName);
+                            $('input[name="scyjBaseName"]').val(fileName);
+                            $('#checkScyj').show();
+                            $('#qxScyj').show();
+
+                            $('#generateStatus').html('生成并上传成功!').css('color', '#52c41a');
+                            alert('公文生成并上传成功!文件路径:' + fullFilePath);
+                        } else {
+                            $('#generateStatus').html('上传失败').css('color', '#ff4d4f');
+                            alert('上传失败,请重试');
+                        }
+                    });
+                } else {
+                    // 尝试将响应解析为JSON
+                    try {
+                        var decoder = new TextDecoder('utf-8');
+                        var text = decoder.decode(new Uint8Array(xhr.response));
+                        var result = JSON.parse(text);
+
+                        if (result.success === false) {
+                            $('#generateStatus').html('生成失败:' + (result.message || '未知错误')).css('color', '#ff4d4f');
+                            alert('生成失败:' + (result.message || '未知错误'));
+                        } else {
+                            $('#generateStatus').html('未知响应格式').css('color', '#ff4d4f');
+                            alert('未知响应格式,请检查接口');
+                        }
+                    } catch (e) {
+                        $('#generateStatus').html('响应解析失败').css('color', '#ff4d4f');
+                        alert('服务器响应异常:' + e.message);
+                    }
+                }
+            } else {
+                $('#generateStatus').html('生成失败,状态码:' + xhr.status).css('color', '#ff4d4f');
+                alert('生成失败,HTTP状态码:' + xhr.status);
+            }
+        };
+
+        xhr.onerror = function() {
+            $('#generateStatus').html('生成失败:网络错误').css('color', '#ff4d4f');
+            alert('生成失败:网络错误,请检查网络连接');
+        };
+
+        xhr.onloadend = function() {
+            isGenerating = false;
+            $('#generateDocumentBtn').prop('disabled', false).css('opacity', 1);
+        };
+
+        xhr.send(formData.toString());
+    }
+    // 上传生成的PDF文件
+    function uploadGeneratedPdf(blob, fileName, callback) {
+        $('#generateStatus').html('正在上传文件...').css('color', '#1890ff');
+
+        if (blob.size === 0) {
+            alert('要上传的文件为空,无法上传');
+            callback(null);
+            return;
+        }
+
+        // 创建FormData
+        var formData = new FormData();
+        formData.append('file', blob, fileName);
+        formData.append('name', fileName);
+        formData.append('type', 'document');
+        formData.append('app', wd.app ? wd.app.name : getAccountInfo().xmmc);
+
+        // 使用原有的上传接口
+        $.ajax({
+            url: "/service?ssServ=ulByHttp&type=document",
+            type: 'POST',
+            data: formData,
+            processData: false,
+            contentType: false,
+            xhr: function() {
+                var xhr = new XMLHttpRequest();
+                xhr.upload.addEventListener('progress', function(e) {
+                    if (e.lengthComputable) {
+                        var percentComplete = (e.loaded / e.total) * 100;
+                        $('#generateStatus').html('上传中... ' + Math.round(percentComplete) + '%');
+                    }
+                }, false);
+                return xhr;
+            },
+            beforeSend: function() {
+            },
+            success: function(result) {
+                try {
+                    if (typeof result === 'string') {
+                        result = JSON.parse(result);
+                    }
+                    if (result && result.fileList && result.fileList.length > 0) {
+                        callback(result);
+                    } else {
+                        callback(result);
+                    }
+                } catch (e) {
+                    console.error('解析上传响应失败:', e);
+                    callback(null);
+                }
+            },
+            error: function(xhr, status, error) {
+                console.error('文件上传失败:', error);
+                alert('文件上传失败:' + error);
+                callback(null);
+            }
+        });
+    }
+    // 页面加载完成后初始化上传功能
+    $(document).ready(function () {
+
+        // 检查upload.js是否已加载
+        if (typeof $.fn.uploadFile === 'undefined') {
+            console.error('upload.js 未正确加载');
+            alert('文件上传插件加载失败,请联系管理员');
+            return;
+        }
+
+
+        // 调试:检查按钮是否存在
+
+        // 初始化上传插件
+        try {
+
+            // 使用upload.js插件
+            $('#scyjEdit').uploadFile({
+                name: 'scyj', // 必须与页面中的元素ID前缀一致
+                type: 'document', // 上传类型,可根据需要设置
+                validation: 'jpg,jpeg,png,pdf,doc,docx,xls,xlsx,ppt,pptx,txt,zip,rar', // 允许上传的文件类型
+                size: 10240, // 文件大小限制,单位KB(10MB)
+                app: wd.app ? wd.app.name : getAccountInfo().xmmc, // 应用名称
+                action: "/service?ssServ=ulByHttp&type=document", // 明确指定action
+                beforeClick: function () {
+                    return true;
+                },
+                onchange: function (settings) {
+                },
+                callback: function (result) {
+                    if (result && result.fileList && result.fileList.length > 0) {
+                        // 显示成功消息
+                        var fileName = result.fileList[0].fileName;
+                        alert('文件 "' + fileName + '" 上传成功!');
+
+                        // 自动填充上传路径输入框
+                        var filePath = result.fileList[0].path;
+                        if (filePath) {
+                            $('input[name="uploadPath"]').val(filePath);
+                        }
+
+                        // 文件上传成功之后, 获取对应的文件 , 并且将pdf文件解析出正文内容
+                        // 获取文件路径, 然后调用后端代码
+                        // if (filePath && filePath.toLowerCase().endsWith('.pdf')) {
+                        if (filePath) {
+                            $.ajax({
+                                url: "<ss:serv name='ws_zh_pdf2html'/>",
+                                type: 'post',
+                                data: {
+                                    path: filePath,
+                                    fileName: fileName
+                                },
+                                success: function (result) {
+                                    // 提取成功后, 将正文内容传输到正文控件中
+                                    try {
+                                        var parse = typeof result === 'string' ? JSON.parse(result) : result;
+                                        // 使用桥接 API 写入 Vue 数据(推荐方式)
+                                        // 文档:/docs/普通JS读写Vue数据方法.md
+                                        // 这会自动更新编辑器内容
+                                        window.ss.dom.set('zwwjHtml', parse.data || '');
+                                    } catch (e) {
+                                        console.warn('PDF解析结果处理失败:', e);
+                                    }
+                                },
+                                error: function(xhr, status, error) {
+                                }
+                            });
+                        }
+                    }
+                }
+            });
+
+
+        } catch (error) {
+            alert('上传插件初始化失败: ' + error.message);
+
+            // 如果upload.js插件失败,使用简单方法
+            $('#scyjEdit').off('click.simple').on('click.simple', function () {
+                // 创建一个临时的文件input
+                var fileInput = $('#scyjEdit_File');
+                if (fileInput.length === 0) {
+                    $('body').append('<input type="file" id="scyjEdit_File" style="display:none;">');
+                    fileInput = $('#scyjEdit_File');
+                }
+
+                fileInput.off('change').on('change', function () {
+                    if (this.files.length > 0) {
+                        var fileName = this.files[0].name;
+                        $('#scyjBaseName').text(fileName);
+                        $('input[name="scyjBaseName"]').val(fileName);
+                        $('#checkScyj').show();
+                        $('#qxScyj').show();
+                        alert('已选择文件: ' + fileName);
+                    }
+                });
+
+                fileInput.click();
+            });
+        }
+
+        // 添加上传路径输入框的点击事件
+        $('#scyjpath').click(function () {
+            var currentPath = $(this).val();
+            if (currentPath) {
+                $(this).select();
+            }
+        });
+
+        // 为删除按钮添加确认提示
+        $('body').on('click', '#qxScyj', function (e) {
+            if (!confirm('确定要删除已上传的文件吗?')) {
+                e.preventDefault();
+                return false;
+            }
+        });
+
+        // 初始化页面时检查是否有已上传的文件
+        var existingFile = $('input[name="scyjwj"]').val();
+        if (existingFile) {
+            var fileName = existingFile.split('/').pop();
+            $('#scyjBaseName').text(fileName);
+            $('input[name="scyjBaseName"]').val(fileName);
+            $('#checkScyj').show();
+            $('#qxScyj').show();
+            $('input[name="uploadPath"]').val(existingFile);
+        }
+
+    });
+
+    // 表单提交前的验证函数
+    function validateForm() {
+        var filePath = $('input[name="scyjwj"]').val();
+        var title = $('input[name="bt"]').val();
+
+        if (!title || title.trim() === '') {
+            alert('请填写标题');
+            $('input[name="bt"]').focus();
+            return false;
+        }
+
+        if (!filePath || filePath.trim() === '') {
+            if (!confirm('您尚未上传原件,确定要继续提交吗?')) {
+                $('#scyjEdit').focus();
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    // ==================== Vue 桥接 API 使用示例 ====================
+    // 文档:/docs/普通JS读写Vue数据方法.md
+
+    /**
+     * 示例1:读取编辑器内容
+     * 使用 window.ss.dom.get() 从 Vue 实例读取数据
+     */
+    function readEditorContent() {
+        // 方式1:通过桥接 API 读取(推荐)
+        var htmlContent = window.ss.dom.get('zwwjHtml') || '';
+        console.log('读取到编辑器内容,长度:', htmlContent.length);
+        alert('编辑器内容长度: ' + htmlContent.length + '\n前100字: ' + htmlContent.substring(0, 100));
+        return htmlContent;
+    }
+
+    /**
+     * 示例2:写入编辑器内容
+     * 使用 window.ss.dom.set() 向 Vue 实例写入数据
+     */
+    function writeEditorContent() {
+        var sampleHtml = '<p style="color: blue;">这是通过桥接 API 插入的内容</p>' +
+            '<p>当前时间: ' + new Date().toLocaleString() + '</p>';
+
+        // 通过桥接 API 设置 Vue 数据,编辑器会自动更新
+        window.ss.dom.set('zwwjHtml', sampleHtml);
+        console.log('已写入编辑器内容');
+        alert('已向编辑器写入示例内容');
+    }
+
+    /**
+     * 示例3:读取和设置表单标题
+     * 演示如何读写普通输入字段
+     */
+    function readFormTitle() {
+        // 读取标题字段
+        var title = window.ss.dom.get('bt') || '';
+        console.log('当前标题:', title);
+        return title;
+    }
+
+    /**
+     * 示例3b:设置表单标题
+     */
+    function setFormTitle() {
+        var newTitle = '新标题_' + new Date().getTime();
+        window.ss.dom.set('bt', newTitle);
+        console.log('已设置标题:', newTitle);
+        alert('标题已设置为: ' + newTitle);
+    }
+
+    /**
+     * 示例4:读取和设置下拉框(文书类别)
+     * 演示如何操作下拉选择框(ss-objp 组件)
+     */
+    function readDocumentType() {
+        // 读取文书类别代码
+        var typeCode = window.ss.dom.get('wslbm') || '';
+
+        // 定义选项映射
+        var typeMap = {
+            "1": "函",
+            "11": "通知",
+            "21": "请示",
+            "31": "批复",
+            "41": "报告",
+            "81": "个人书信",
+            "91": "其他"
+        };
+
+        var typeName = typeMap[typeCode] || '未选择';
+
+        console.log('文书类别代码:', typeCode, '名称:', typeName);
+        alert('当前文书类别:\n代码: ' + typeCode + '\n名称: ' + typeName);
+
+        return { code: typeCode, name: typeName };
+    }
+
+    /**
+     * 示例4b:设置下拉框值(文书类别)
+     * 注意:下拉框通过 v-model 绑定,设置 code 即可
+     */
+    function setDocumentType() {
+        // 定义选项
+        var typeOptions = [
+            { code: '1', name: '函' },
+            { code: '11', name: '通知' },
+            { code: '21', name: '请示' },
+            { code: '31', name: '批复' },
+            { code: '41', name: '报告' },
+            { code: '81', name: '个人书信' },
+            { code: '91', name: '其他' }
+        ];
+
+        // 随机选择一个(实际应用中是用户选择)
+        var randomType = typeOptions[Math.floor(Math.random() * typeOptions.length)];
+
+        // 设置下拉框的值(设置 code,组件自动显示对应文本)
+        window.ss.dom.set('wslbm', randomType.code);
+
+        console.log('已设置文书类别:', randomType);
+        alert('已设置文书类别为: ' + randomType.name + ' (代码: ' + randomType.code + ')');
+    }
+
+    /**
+     * 示例4d:读取所有下拉框值
+     * 批量读取多个下拉框字段
+     */
+    function readAllDropdowns() {
+        // 读取各个下拉框的值
+        var values = {
+            wslbm: window.ss.dom.get('wslbm') || '',  // 文书类别
+            wsmjm: window.ss.dom.get('wsmjm') || '',  // 密级
+            wsfwm: window.ss.dom.get('wsfwm') || '',  // 范围
+            gllbm: window.ss.dom.get('gllbm') || ''   // 管理类别
+        };
+
+        // 定义映射表
+        var maps = {
+            wslbm: { "1": "函", "11": "通知", "21": "请示", "31": "批复", "41": "报告", "81": "个人书信", "91": "其他" },
+            wsmjm: { "1": "公开", "2": "内部", "3": "秘密", "4": "机密", "5": "绝密" },
+            wsfwm: { "1": "全局", "2": "部门", "3": "个人" },
+            gllbm: { "1": "行政", "2": "人事", "3": "财务", "4": "业务" }
+        };
+
+        var result = '下拉框取值:\n';
+        for (var key in values) {
+            var code = values[key];
+            var name = maps[key] && maps[key][code] ? maps[key][code] : code;
+            result += key + ': ' + name + ' (代码: ' + code + ')\n';
+        }
+
+        alert(result);
+        return values;
+    }
+
+    /**
+     * 示例5:批量设置表单数据
+     * 实际应用场景:快速填充表单
+     */
+    function batchSetFormData() {
+        // 批量设置多个字段
+        window.ss.dom.set('bt', '关于2026年度工作总结的通知');
+        window.ss.dom.set('zy', '本文总结了2026年度的工作情况...');
+        window.ss.dom.set('wslbm', '11');  // 通知
+        window.ss.dom.set('wsmjm', '2');   // 内部
+
+        alert('已批量设置:\n标题、摘要、文书类别(通知)、密级(内部)');
+    }
+
+    /**
+     * 示例6:读取完整表单数据
+     * 用于提交前预览或生成文档
+     */
+    function readFullFormData() {
+        var formData = {
+            // 基本信息
+            title: window.ss.dom.get('bt') || '',
+            summary: window.ss.dom.get('zy') || '',
+
+            // 下拉框
+            docType: window.ss.dom.get('wslbm') || '',
+            secretLevel: window.ss.dom.get('wsmjm') || '',
+            scope: window.ss.dom.get('wsfwm') || '',
+            manageType: window.ss.dom.get('gllbm') || '',
+
+            // 编辑器内容
+            content: window.ss.dom.get('zwwjHtml') || '',
+
+            // 人员部门
+            draftPerson: window.ss.dom.get('ngryid') || '',
+            draftDept: window.ss.dom.get('ngbmid') || ''
+        };
+
+        console.log('完整表单数据:', formData);
+
+        // 生成预览文本
+        var preview = '表单数据预览:\n' +
+            '标题: ' + formData.title + '\n' +
+            '文书类别: ' + formData.docType + '\n' +
+            '密级: ' + formData.secretLevel + '\n' +
+            '内容长度: ' + formData.content.length + ' 字符\n';
+
+        alert(preview);
+        return formData;
+    }
+
+    /**
+     * 示例4:清空编辑器并显示提示
+     * 结合读写操作
+     */
+    function clearEditorWithConfirm() {
+        // 先读取当前内容
+        var currentContent = window.ss.dom.get('zwwjHtml') || '';
+
+        if (currentContent.length === 0) {
+            alert('编辑器已经是空的');
+            return;
+        }
+
+        if (confirm('确定要清空编辑器内容吗?当前有 ' + currentContent.length + ' 个字符')) {
+            // 清空内容
+            window.ss.dom.set('zwwjHtml', '');
+            alert('已清空');
+        }
+    }
+
+    /**
+     * 示例5:生成公文时读取编辑器内容
+     * 实际应用场景
+     */
+    function generateDocWithContent() {
+        // 从 Vue 读取编辑器内容
+        var htmlContent = window.ss.dom.get('zwwjHtml') || '';
+        var title = window.ss.dom.get('bt') || '未命名';
+
+        if (!htmlContent || htmlContent.trim() === '') {
+            if (!confirm('正文内容为空,确定要生成空白公文吗?')) {
+                return;
+            }
+        }
+
+        console.log('准备生成公文:', {
+            title: title,
+            contentLength: htmlContent.length
+        });
+
+        // 这里调用生成公文的接口...
+        alert('标题: ' + title + '\n内容长度: ' + htmlContent.length + '\n\n可以在这里调用生成接口');
+    }
+
+    // ==================== 示例结束 ====================
+
+    // 修复uploadFile插件的问题
+    function fixUploadPlugin() {
+        // 检查是否有必要的CSS样式
+        if (!$('.content-button').length) {
+            $('#scyjEdit').addClass('content-button');
+        }
+
+        // 确保文件输入框存在
+        if (!$('#scyjEdit_File').length) {
+            $('body').append('<input type="file" id="scyjEdit_File" name="fileEdit" style="display:none;">');
+        }
+
+        // 手动绑定点击事件
+        $('#scyjEdit').off('click.manual').on('click.manual', function () {
+            $('#scyjEdit_File').click();
+        });
+
+        // 监听文件选择
+        $('#scyjEdit_File').off('change').on('change', function (e) {
+            if (this.files && this.files.length > 0) {
+                var fileName = this.files[0].name;
+                var fileSize = this.files[0].size;
+                var fileType = this.files[0].type;
+
+                // 显示文件信息
+                $('#scyjBaseName').text(fileName);
+                $('input[name="scyjBaseName"]').val(fileName);
+
+                // 模拟上传
+                simulateUpload(fileName, fileSize);
+            }
+        });
+    }
+
+    // 模拟文件上传
+    function simulateUpload(fileName, fileSize) {
+
+        // 显示进度条
+        $('#scyjBaseName').html('<div class="progress"><div class="bar"></div><div class="percent">0%</div></div>');
+
+        // 模拟上传进度
+        var progress = 0;
+        var interval = setInterval(function () {
+            progress += 10;
+            if (progress <= 100) {
+                $('.bar').width(progress + '%');
+                $('.percent').text(progress + '%');
+
+                if (progress === 100) {
+                    clearInterval(interval);
+
+                    // 模拟上传完成
+                    setTimeout(function () {
+                        // 生成模拟文件路径
+                        var timestamp = new Date().getTime();
+                        var filePath = '/uploads/' + timestamp + '_' + fileName;
+
+                        // 更新页面
+                        $('#scyjBaseName').text(fileName);
+                        $('input[name="scyjwj"]').val(filePath);
+                        $('input[name="uploadPath"]').val(filePath);
+                        $('#checkScyj').show();
+                        $('#qxScyj').show();
+
+                        alert('文件 "' + fileName + '" 上传成功!');
+                    }, 500);
+                }
+            }
+        }, 200);
+    }
+
+    // 页面完全加载后修复插件
+    $(window).on('load', function () {
+
+        // 如果upload.js插件没有正常工作,使用修复方法
+        setTimeout(function () {
+            if ($('#scyjEdit').length && !$('#scyjEdit').data('upload-initialized')) {
+                fixUploadPlugin();
+            }
+        }, 1000);
+    });
+</script>
+
+<ss:ichk name='ws_inp'/>
+<script> addRemoveToken('<%= pageContext.getAttribute(ss.page.PageC.PAGE_tokenList)%>');</script>

+ 130 - 0
page/xyZjz_excelAdd copy.jsp

@@ -0,0 +1,130 @@
+<!DOCTYPE html>
+<%@ page language="java" pageEncoding="UTF-8" isELIgnored="false" %>
+<%@ taglib uri="/ssTag" prefix="ss"%>
+
+<% pageContext.setAttribute(ss.page.PageC.PAGE_objName,"xy");%>
+<%pageContext.setAttribute("wdpageinformation","{'hastab':'0'}");%>
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="pragma" content="no-cache">
+<meta http-equiv="cache-control" content="no-cache">
+<meta http-equiv="expires" content="0">
+<script>window.loginStatus="${empty sessionScope['ssUser']?'0':'1'}"</script>
+<ss:skin file='main.css'/>
+<script type="text/javascript" src="/ss/jquery/jquery.js"></script>
+<script type="text/javascript" src="/ss/artdialog/artDialogUtil.js"></script>
+<script type="text/javascript" src="/ss/js/base.js"></script>
+<script> if(!window.wd) var wd={}; if(!wd.display) wd.display={}; wd.display.wdDialogId="xyZjz_excelAdd"; if(!wd.app) wd.app={};  wd.app.name='pms';</script>
+<script type="text/javascript" src="/ss/js/masklayer.js"></script>
+<script type="text/javascript" src="/ss/js/wdDialogInit.js"></script>
+<script type="text/javascript" src="/ss/js/common.js"></script>
+<script type="text/javascript" src="/ss/js/display.js"></script>
+<script type="text/javascript" src="/ss/js/edit.js"></script>
+<script type="text/javascript" src="/ss/nicescroll/jquery.nicescroll.js"></script>
+<script type="text/javascript" src="/ss/nicescroll/jquery.nicescroll.iframehelper.min.js"></script>
+<link rel="stylesheet" type="text/css" href="/ss/window/theme/dhtmlxwindows.css">
+<link rel="stylesheet" type="text/css" href="/ss/window/theme/dhx_blue/dhtmlxwindows_dhx_blue.css">
+<script type="text/javascript" src="/ss/window/dhtmlxcommon.js"></script>
+<script type="text/javascript" src="/ss/window/dhtmlxwindows.js"></script>
+<script type="text/javascript" src="/ss/window/dhtmlxcontainer.js"></script>
+<script type="text/javascript" src="/ss/js/common.js"></script>
+<script type="text/javascript" src="/ss/js/display.js"></script>
+<%-- 改。Lin
+<@script type="text/javascript" src="/${sessionScope['XMMC']}/js/yx/yx_zjz.js"></script> --%>
+<script type="text/javascript" src="/ss/yx/yx_zjz.js"></script>
+<%-- 改,去掉 /wd/js/ueditor/dialogs/wdimage/upload.js,改用 /wd/js/upload.js。Lin
+<script type="text/javascript" src="/wd/js/ueditor/dialogs/wdimage/upload.js"></script>
+--%><script type="text/javascript" src="/ss/js/upload.js"></script>
+<style type="text/css">
+	#sfzImg{
+		margin: 0 auto;
+		width: 381px;
+		height: 491.6px !important;
+		border:1px solid #999;
+	}
+/*	#video{width:100% !important;height:100% !important}*/
+	#video{width:800px!important;height:719px!important}
+</style>
+</head>
+<body>
+<div class="content-div" ssFith="true">
+	<table class='form' style="table-layout: fixed;">
+		<tr>
+			<th width="130px">姓名</th>
+<%-- 改,暂时指定为 bjcyList[0] -- 等小许。Lin
+			<td>${ry.xm}</td> --%>
+			<td>${bjcyList[0].xm}</td>
+			<th width="130px">身份证号码</th>
+			<td >${ry.sfzh}</td>
+		</tr>
+		<tr>
+			<th width="130px">班级</th>
+			<td colspan="3">
+				<%--<wd:translate name="bmxy_bjcx" value="${bmxy.bjid}" filter="bmxyid:'${bmxy.bmxyid}'" />--%>
+				<ss:cbTrans cb='bj' val='${bjid}'/>
+			</td>
+		</tr>
+	</table>
+<%-- 改,去掉部件 yx_info,改用 info -- 不是摊位,没有摊位的 "下一步" 操作。Lin
+	<@form action="@service{name:'yx_zjz_bc',dest:'yx_info'}@"  method="post"> --%>
+	<form action="<ss:serv name='xyZjz_excelSureAdd' parm='{"wdConfirmationCaptchaService":"0"}' dest='info'/>" method="post">
+<%-- 改,暂时指定为 bjcyList[0] -- 等小许。Lin
+		<@input name="ryid" value="$@{ry.ryid}" type="hidden"/>
+		<input name="zjzwj" value="${ry.zjzwj}" type="hidden">
+--%>
+		<input name="ryid" value="${bjcyList[0].ryid}" type="hidden"/>
+		<input name="zjzwj" value="${bjcyList[0].zjzwj}" type="hidden">
+
+		<label  style="display:none;" for="videoSource">视频来源: </label>
+		<select style="display:none;" id="videoSource"></select>
+		<div style="width:100%;display: flex;height: 413px;">
+			<div id="sfzImg" class="photo">
+				<input type="file" style="display:none;" id="file">
+				<img style="max-height: 100%;max-width: 100%; width:100%;height:100%;"  id="image"
+<%-- 改,暂时指定为 bjcyList[0] -- 等小许。Lin
+						src="@service{name:'getData',param:{path:'${ry.zjzwj}'}}@"
+--%>				src="<ss:serv name='dlByHttp' parm='{"wdConfirmationCaptchaService":"0","path":"${bjcyList[0].zpwj}","type":"img"}'/>"
+						onerror="this.src='/image/files.png'"/> <%-- ='${sessionScope['XMMC']}/image/files.png'"。Lin --%>
+				<video autoplay muted playsinline style="display:none" id="video"></video>
+				<canvas id="canvas" style="display:none"></canvas>
+			</div>
+		</div>
+		<div style="text-align: center; margin-top: 88px;margin-bottom: 46px;">
+			<input class="content-button" type="button" value="拍照" id="btn">
+		</div>
+		<div class='bottom-div'>
+			<div class="bottom-down-div border-top">
+				<input class="bottom-button" type="submit" value="提交" >
+				<input class="bottom-button" type="button" onclick="wd.display.closeDialog();" value="取消">
+			</div>
+		</div>
+	<input name='wdComponentID' type='hidden' value='xyZjz_excelAdd'/></form>
+</div>
+<script type="text/javascript">var wdRecordValue='${wdRecordValue}';</script>
+<script type="text/javascript" src="/ss/js/wdRecord.js"></script>
+<script type="text/javascript">(function(){wdRecord("xyZjz_excelAdd");})();</script>
+<script type="text/javascript" src="/ss/js/wdFitHeight.js"></script>
+<script type="text/javascript">initWdFitHeight(0)</script>
+<script type="text/javascript">initWdFitHeightFunction=function(){initWdFitHeight(0);};</script>
+<ss:equal val="${empty resizeComponent}" val2="false">
+<script>{var iframe=wd.display.getFrameOfWindow();
+if(iframe&&iframe.contentWindow==window)
+wd.display.resizeComponent(${resizeComponent.width}, ${resizeComponent.height}, ${empty resizeComponent.minHeight?'null':resizeComponent.minHeight}, ${empty resizeComponent.maxHeight?'null':resizeComponent.maxHeight});}</script>
+</ss:equal>
+<ss:help/>
+</body>
+<script type="text/javascript">
+try{wd.display.showMsgPopup('${msg}');
+}catch(err){console.error(err);}
+</script>
+<ss:equal val="${empty wdclosewindowparam}" val2="false">
+<script type="text/javascript">
+try{wd.display.setCloseWindowParam('${wdclosewindowparam}');
+}catch(err){console.error(err);}
+</script>
+</ss:equal>
+</html>
+<script type="text/javascript">
+tokenCleanser("<ss:serv name='ss.clearPageToken'/>", {tokenList:"<%= pageContext.getAttribute(ss.page.PageC.PAGE_tokenList)%>"});
+</script>

+ 907 - 0
page/xyZjz_excelAdd.jsp

@@ -0,0 +1,907 @@
+<%@ page import="java.util.List" %>
+<%@ page language="java" pageEncoding="UTF-8" isELIgnored="false" %>
+<%@ taglib uri="/ssTag" prefix="ss"%>
+
+<% pageContext.setAttribute(ss.page.PageC.PAGE_objName,"xy");%>
+<%pageContext.setAttribute("wdpageinformation","{'hastab':'0'}");%>
+<!DOCTYPE html>
+<html>
+<head>
+<%@ include file="/page/clip/header.jsp" %>
+<script>window.loginStatus="${empty sessionScope['ssUser']?'0':'1'}"</script>
+<link rel="stylesheet" type="text/css" href="/ss/window/theme/dhtmlxwindows.css">
+<link rel="stylesheet" type="text/css" href="/ss/window/theme/dhx_blue/dhtmlxwindows_dhx_blue.css">
+<script type="text/javascript" src="/ss/window/dhtmlxcommon.js"></script>
+<script type="text/javascript" src="/ss/window/dhtmlxwindows.js"></script>
+<script type="text/javascript" src="/ss/window/dhtmlxcontainer.js"></script>
+<script type="text/javascript" src="/ss/js/display.js"></script>
+<%-- 改。Lin
+<@script type="text/javascript" src="/${sessionScope['XMMC']}/js/yx/yx_zjz.js"></script> --%>
+<%-- 页面拍照逻辑内联处理,不再依赖 /ss/yx/yx_zjz.js。 --%>
+<%-- 改,去掉 /wd/js/ueditor/dialogs/wdimage/upload.js,改用 /wd/js/upload.js。Lin
+<script type="text/javascript" src="/wd/js/ueditor/dialogs/wdimage/upload.js"></script>
+--%><script type="text/javascript" src="/ss/js/upload.js"></script>
+<style type="text/css">
+	body{
+		background: #f5f7fb;
+	}
+	
+	#app.form-container{
+		height: 100%;
+	}
+	.form-container .content-box{
+		height: 100% !important;
+		padding: 0 !important;
+	}
+	.xy-zjz-page{
+		height: 100%;
+		padding: 0;
+		box-sizing: border-box;
+	}
+	.xy-zjz-layout{
+		height: 100%;
+		display: flex;
+		gap: 0;
+	}
+	.xy-zjz-left{
+		flex: 0 0 61%;
+		min-width: 0;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		background: #ffffff;
+		border-radius: 4px;
+		padding: 30px 46px;
+		box-sizing: border-box;
+		border-right: 1px solid #e2e4ec;
+	}
+	.xy-zjz-right{
+		flex: 0 0 39%;
+		min-width: 320px;
+		display: flex;
+		flex-direction: column;
+		background: #f7f7f7;
+	}
+	.xy-zjz-info-wrapper{
+		height: 234px;
+		padding: 30px 35px 35px;
+		box-sizing: border-box;
+	}
+	.xy-zjz-camera-toolbar{
+		display: none;
+	}
+	.xy-zjz-preview-shell{
+		width: 100%;
+		flex: 1;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+	}
+	#sfzImg.xy-zjz-preview{
+		position: relative;
+		width: min(100%, 498px);
+		height: auto;
+		aspect-ratio: 498/756;
+		max-height: 756px;
+		background: #8e8e8e;
+		overflow: hidden;
+		box-sizing: border-box;
+		border: none;
+	}
+	#sfzImg.xy-zjz-preview.is-live{
+		border: 1px solid #3f3f3f;
+	}
+	#sfzImg.xy-zjz-preview img,
+	#sfzImg.xy-zjz-preview video{
+		position: absolute;
+		inset: 0;
+		width: 100% !important;
+		height: 100% !important;
+		object-fit: cover;
+		display: none;
+	}
+	#canvas,
+	#file{
+		display: none;
+	}
+	.xy-zjz-camera-placeholder{
+		position: absolute;
+		inset: 0;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		padding: 0 32px;
+		text-align: center;
+		font-size: 18px;
+		line-height: 28px;
+		color: rgba(255,255,255,0.88);
+		background: linear-gradient(180deg, rgba(0,0,0,0.08), rgba(0,0,0,0.16));
+	}
+	.xy-zjz-camera-placeholder::before{
+		content: "";
+		position: absolute;
+		width: 70%;
+		height: 70%;
+		background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 240'%3E%3Cpath fill='rgba(255,255,255,0.25)' d='M100 20c-25 0-45 20-45 45 0 15 7 28 18 36-20 10-35 30-40 55-2 10-3 20-3 30h140c0-10-1-20-3-30-5-25-20-45-40-55 11-8 18-21 18-36 0-25-20-45-45-45z'/%3E%3C/svg%3E") center/contain no-repeat;
+		opacity: 0.8;
+	}
+	.xy-zjz-action-stack{
+		width: min(100%, 360px);
+		padding-top: 20px;
+	}
+	.xy-zjz-action-stack.bottom-div{
+		position: static;
+		display: block;
+		height: auto;
+		padding: 20px 0 0;
+		border-top: none;
+		background: transparent !important;
+		width: min(100%, 360px);
+	}
+	.xy-zjz-action-stack.bottom-div ss-bottom-button{
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		gap: 8px;
+		font-size: 16px;
+		min-width: 140px;
+		padding: 10px 24px;
+		border-radius: 4px;
+		border: 1px solid #d9d9d9;
+		background: #fff;
+		color: #666;
+		cursor: pointer;
+		transition: all 0.2s;
+	}
+	.xy-zjz-action-stack.bottom-div ss-bottom-button:hover{
+		border-color: #409eff;
+		color: #409eff;
+	}
+	.xy-zjz-action-stack.bottom-div ss-bottom-button::before{
+		content: "📷";
+		font-size: 18px;
+	}
+	.xy-zjz-action-bar{
+		display: flex;
+		justify-content: center;
+		gap: 12px;
+		width: 100%;
+	}
+	.xy-zjz-action-bar ss-bottom-button,
+	.xy-zjz-action-bar #photoConnectBtn,
+	.xy-zjz-action-bar #photoCaptureBtn,
+	.xy-zjz-action-bar #photoRetakeBtn,
+	.xy-zjz-action-bar #photoSubmitBtn{
+		min-width: 140px;
+	}
+
+	.xy-zjz-card,
+	.xy-zjz-list-card{
+		background: #fff;
+		border: 1px solid #e3e7f0;
+		border-radius: 4px;
+		box-sizing: border-box;
+	}
+	.xy-zjz-card{
+		width: 100%;
+		height: 100%;
+		box-sizing: border-box;
+		background: #ffffff;
+		border: 1px solid #dddfe6;
+		border-radius: 4px;
+		padding: 18px 20px;
+	}
+	.xy-zjz-info-name{
+		font-size: 20px;
+		line-height: 1;
+		font-weight: 500;
+		color: #010101;
+		margin-bottom: 18px;
+	}
+	.xy-zjz-info-body{
+		display: flex;
+		gap: 0;
+		align-items: flex-end;
+	}
+	.xy-zjz-info-avatar{
+		width: 68px;
+		height: 100px;
+		border: 1px solid #dddfe6;
+		background: #f2f3f4;
+		overflow: hidden;
+		flex: 0 0 68px;
+		border-radius: 4px;
+	}
+	.xy-zjz-info-avatar.has-image{
+		border: none;
+	}
+	.xy-zjz-info-avatar img{
+		width: 100%;
+		height: 100%;
+		object-fit: cover;
+		display: block;
+	}
+	.xy-zjz-info-lines{
+		flex: 1;
+		padding-left: 20px;
+		min-width: 0;
+		display: flex;
+		flex-direction: column;
+		justify-content: flex-end;
+	}
+	.xy-zjz-info-line{
+		font-size: 18px;
+		line-height: 28px;
+		color: #666;
+		white-space: nowrap;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		line-height: 1.4;
+	}
+	.xy-zjz-info-line:last-child{
+		color: #000;
+	}
+	.xy-zjz-info-line strong{
+		font-weight: normal;
+		color: inherit;
+	}
+	.xy-zjz-right-divider{
+		width: 100%;
+		height: 1px;
+		background: #e2e4ec;
+		flex-shrink: 0;
+	}
+	.xy-zjz-list-card{
+		flex: 1;
+		padding: 16px 14px 12px;
+		display: flex;
+		flex-direction: column;
+		min-height: 0;
+		max-height: none;
+		background: #f7f7f7;
+	}
+	.xy-zjz-filter-row{
+		display: flex;
+		gap: 10px;
+		margin-bottom: 10px;
+		align-items: center;
+	}
+	.xy-zjz-filter-class{
+		font-size: 16px;
+		font-weight: 500;
+		color: #333;
+		margin-right: auto;
+	}
+	.xy-zjz-filter-progress{
+		font-size: 14px;
+		color: #666;
+		margin-right: 12px;
+	}
+	.xy-zjz-filter-input{
+		width: 120px;
+		height: 32px;
+		border: 1px solid #d9d9d9;
+		border-radius: 4px;
+		background: #fff;
+		padding: 0 12px;
+		font-size: 14px;
+		color: #333;
+		box-sizing: border-box;
+		transition: border-color 0.2s;
+	}
+	.xy-zjz-filter-input:focus{
+		outline: none;
+		border-color: #409eff;
+	}
+	.xy-zjz-filter-input::placeholder{
+		color: #999;
+	}
+	.xy-zjz-filter-select{
+		display: none;
+	}
+	.xy-zjz-filter-summary{
+		display: flex;
+		justify-content: flex-end;
+		align-items: center;
+		padding: 0 2px 10px;
+	}
+	.xy-zjz-class-count{
+		font-size: 16px;
+		line-height: 24px;
+		color: #5f6b80;
+	}
+	.xy-zjz-student-list{
+		flex: 1;
+		min-height: 0;
+		overflow-y: auto;
+		padding-top: 2px;
+		border-top: 1px solid #e8e8e8;
+	}
+	.xy-zjz-student-row{
+		display: grid;
+		grid-template-columns: 32px 1fr 1.5fr;
+		align-items: center;
+		gap: 12px;
+		height: 40px;
+		padding: 0 8px;
+		font-size: 14px;
+		color: #333;
+		border-radius: 4px;
+		box-sizing: border-box;
+		cursor: pointer;
+		transition: background 0.15s;
+	}
+	.xy-zjz-student-row:hover{
+		background: #f5f7fa;
+	}
+	.xy-zjz-student-row + .xy-zjz-student-row{
+		margin-top: 2px;
+	}
+	.xy-zjz-student-row.is-active{
+		background: #e8eaed;
+	}
+	.xy-zjz-student-row.is-active .xy-zjz-student-index{
+		color: #666;
+	}
+	.xy-zjz-student-index{
+		text-align: center;
+		color: #999;
+		font-size: 13px;
+	}
+	.xy-zjz-student-name{
+		white-space: nowrap;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		font-weight: 500;
+		color: #333;
+	}
+	.xy-zjz-student-id{
+		white-space: nowrap;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		color: #666;
+		font-size: 13px;
+	}
+	.xy-zjz-empty{
+		padding: 32px 0;
+		text-align: center;
+		font-size: 14px;
+		color: #999;
+	}
+</style>
+</head>
+<body class="env-input-body">
+<form id="app" class="form-container" action="<ss:serv name='xyZjz_excelSureAdd' parm='{"wdConfirmationCaptchaService":"0"}' dest='info'/>" method="post">
+<div class="content-box fit-height-content">
+<div class="content-div xy-zjz-page" ssFith="true">
+<%
+	List bjcyList = (List)request.getAttribute("bjcyList");
+	int bjcyCount = bjcyList == null ? 0 : bjcyList.size();
+	Object firstStudent = bjcyCount > 0 ? bjcyList.get(0) : null;
+	pageContext.setAttribute("bjcyCount", Integer.valueOf(bjcyCount));
+	pageContext.setAttribute("firstStudent", firstStudent);
+%>
+	<input name="ryid" value="${firstStudent.ryid}" type="hidden"/>
+	<input name="zjzwj" value="${firstStudent.zjzwj}" type="hidden">
+	<input name='wdComponentID' type='hidden' value='xyZjz_excelAdd'/>
+	<input type="file" id="file">
+	<select id="videoSource" style="display:none;"></select>
+	<div class="xy-zjz-layout">
+		<div class="xy-zjz-left">
+			<div class="xy-zjz-camera-toolbar"></div>
+			<div class="xy-zjz-preview-shell">
+				<div id="sfzImg" class="photo xy-zjz-preview">
+					<div class="xy-zjz-camera-placeholder" id="cameraPlaceholder">点击“连接摄像头”后由浏览器弹出设备/权限选择</div>
+					<img id="image"
+						src="<ss:serv name='dlByHttp' parm='{"wdConfirmationCaptchaService":"0","path":"${firstStudent.zpwj}","type":"img"}'/>"
+						onerror="this.src='data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'100\' height=\'100\'%3E%3Crect width=\'100\' height=\'100\' fill=\'%23f0f0f0\'/%3E%3Ctext x=\'50\' y=\'55\' font-size=\'12\' fill=\'%23999\' text-anchor=\'middle\'%3E无照片%3C/text%3E%3C/svg%3E'"
+					<video autoplay muted playsinline id="video"></video>
+					<canvas id="canvas"></canvas>
+				</div>
+			</div>
+			<div class="xy-zjz-action-stack bottom-div">
+
+				<div class="xy-zjz-action-bar" id="cameraConnectActions">
+					<ss-bottom-button
+						id="photoConnectBtn"
+						text="连接摄像头"
+						@click='xyZjzCameraPage.connectCamera()'
+						icon-class="bottom-div-save"
+					></ss-bottom-button>
+				</div>
+				<div class="xy-zjz-action-bar" id="cameraCaptureActions" style="display:none;">
+					<ss-bottom-button
+						id="photoCaptureBtn"
+						text="拍照"
+						@click='xyZjzCameraPage.capturePhoto()'
+						icon-class="bottom-div-save"
+					></ss-bottom-button>
+				</div>
+				<div class="xy-zjz-action-bar" id="cameraReviewActions" style="display:none;">
+					<ss-bottom-button
+						id="photoRetakeBtn"
+						text="重拍"
+						@click='xyZjzCameraPage.retakePhoto()'
+						icon-class="bottom-div-close"
+					></ss-bottom-button>
+					<ss-bottom-button
+						id="photoSubmitBtn"
+						text="保存并提交"
+						@click='xyZjzCameraPage.submitPhotoForm()'
+						icon-class="bottom-div-save"
+					></ss-bottom-button>
+				</div>
+			</div>
+		</div>
+		<div class="xy-zjz-right">
+			<div class="xy-zjz-info-wrapper">
+				<div class="xy-zjz-card">
+					<template v-if="currentStudent">
+						<div class="xy-zjz-info-name">{{currentStudent.xm}}</div>
+						<div class="xy-zjz-info-body">
+							<div class="xy-zjz-info-avatar">
+								<img :src="currentStudent.zpwj ? '/service?ssServ=dlByHttp&type=img&path=' + currentStudent.zpwj : 'data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'68\' height=\'100\'%3E%3Crect width=\'68\' height=\'100\' fill=\'%23f2f3f4\'/%3E%3Ctext x=\'34\' y=\'55\' font-size=\'11\' fill=\'%23999\' text-anchor=\'middle\'%3E无照片%3C/text%3E%3C/svg%3E'"/>
+							</div>
+							<div class="xy-zjz-info-lines">
+								<div v-if="currentStudent.xbmc" class="xy-zjz-info-line"><strong>性别:</strong>{{currentStudent.xbmc}}</div>
+								<div v-if="currentStudent.jyfsmc" class="xy-zjz-info-line"><strong>就读方式:</strong>{{currentStudent.jyfsmc}}</div>
+								<div v-if="bjmc" class="xy-zjz-info-line"><strong>班级:</strong>{{bjmc}}</div>
+								<div v-if="currentStudent.ryh" class="xy-zjz-info-line"><strong>学号:</strong>{{currentStudent.ryh}}</div>
+							</div>
+						</div>
+					</template>
+					<div v-else class="xy-zjz-info-empty">
+						<div class="xy-zjz-info-name">--</div>
+					</div>
+				</div>
+			</div>
+			<div class="xy-zjz-right-divider"></div>
+			<div class="xy-zjz-list-card">
+				<div class="xy-zjz-filter-row">
+					<select class="xy-zjz-filter-select">
+						<option>年级</option>
+					</select>
+					<select class="xy-zjz-filter-select">
+						<option>班级</option>
+					</select>
+					<span class="xy-zjz-filter-class"><ss:cbTrans cb='bj' val='${bjid}'/></span>
+					<span class="xy-zjz-filter-progress">{{currentIndex + 1}}/{{bjcyCount}}</span>
+					<input class="xy-zjz-filter-input" type="text" placeholder="姓名"/>
+				</div>
+				<div class="xy-zjz-student-list">
+				<div v-for="(item, index) in studentList" :key="index" 
+					 :class="['xy-zjz-student-row', currentIndex === index ? 'is-active' : '']"
+					 @click="selectStudent(index, item)">
+					<div class="xy-zjz-student-index">{{index + 1}}</div>
+					<div class="xy-zjz-student-name">{{item.xm}}</div>
+					<div class="xy-zjz-student-id">{{item.sfzh}}</div>
+				</div>
+			</div>
+			</div>
+		</div>
+	</div>
+</div>
+</div>
+</form>
+<script type="text/javascript">
+(function(){
+	var settings = {
+		width: 1000,
+		height: 1292,
+		action: "/service?ssServ=ulByHttp&type=img"
+	};
+	var state = {
+		stream: null,
+		mode: "disconnected",
+		enumerated: false
+	};
+	var elements = {};
+
+	function $(id){
+		return document.getElementById(id);
+	}
+
+	function ensureElements(){
+		elements.preview = $("sfzImg");
+		elements.video = $("video");
+		elements.image = $("image");
+		elements.canvas = $("canvas");
+		elements.file = $("file");
+		elements.videoSource = $("videoSource");
+		elements.placeholder = $("cameraPlaceholder");
+		elements.connectActions = $("cameraConnectActions");
+		elements.captureActions = $("cameraCaptureActions");
+		elements.reviewActions = $("cameraReviewActions");
+		return !!(elements.preview && elements.video && elements.image && elements.canvas && elements.file && elements.videoSource && elements.placeholder && elements.connectActions && elements.captureActions && elements.reviewActions);
+	}
+
+	function stopTracks(stream){
+		if (!stream || !stream.getTracks) {
+			return;
+		}
+		stream.getTracks().forEach(function(track){
+			track.stop();
+		});
+	}
+
+	function setPlaceholder(text){
+		if (!ensureElements() || !elements.placeholder) {
+			return;
+		}
+		elements.placeholder.textContent = text || "";
+		elements.placeholder.style.display = "flex";
+	}
+
+	function hidePlaceholder(){
+		if (!ensureElements()) {
+			return;
+		}
+		elements.placeholder.style.display = "none";
+	}
+
+	function clearStream(){
+		stopTracks(state.stream);
+		state.stream = null;
+		if (elements.video) {
+			elements.video.pause();
+			elements.video.srcObject = null;
+		}
+	}
+
+	function renderCameraOptions(deviceInfos){
+		if (!ensureElements() || !elements.videoSource) {
+			return false;
+		}
+		while (elements.videoSource.options.length > 0) {
+			elements.videoSource.remove(0);
+		}
+		var videoDevices = deviceInfos.filter(function(item){
+			return item.kind === "videoinput";
+		});
+		if (!videoDevices.length) {
+			var emptyOption = document.createElement("option");
+			emptyOption.value = "";
+			emptyOption.text = "未检测到摄像头";
+			elements.videoSource.appendChild(emptyOption);
+			elements.videoSource.disabled = true;
+			return false;
+		}
+		elements.videoSource.disabled = false;
+		videoDevices.forEach(function(device, index){
+			var option = document.createElement("option");
+			option.value = device.deviceId;
+			option.text = device.label || ("摄像头" + (index + 1));
+			elements.videoSource.appendChild(option);
+		});
+		if (elements.videoSource.options.length > 0) {
+			elements.videoSource.selectedIndex = 0;
+		}
+		return true;
+	}
+
+	async function ensureCameraOptions(){
+		if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
+			alert("当前浏览器不支持摄像头访问");
+			return false;
+		}
+		if (!ensureElements()) {
+			return false;
+		}
+		if (state.enumerated && elements.videoSource.options.length > 0 && elements.videoSource.options[0].value !== "") {
+			return true;
+		}
+		var permissionStream = null;
+		try {
+			permissionStream = await navigator.mediaDevices.getUserMedia({video: true, audio: false});
+			var deviceInfos = await navigator.mediaDevices.enumerateDevices();
+			state.enumerated = renderCameraOptions(deviceInfos);
+			return state.enumerated;
+		} catch (error) {
+			handleCameraError(error);
+			return false;
+		} finally {
+			stopTracks(permissionStream);
+		}
+	}
+
+	async function startPreview(deviceId){
+		if (!ensureElements()) {
+			return false;
+		}
+		clearStream();
+		var constraints = {
+			video: deviceId ? {deviceId: {exact: deviceId}} : true,
+			audio: false
+		};
+		try {
+			var stream = await navigator.mediaDevices.getUserMedia(constraints);
+			state.stream = stream;
+			elements.video.srcObject = stream;
+			await elements.video.play();
+			elements.video.style.display = "block";
+			elements.image.style.display = "none";
+			hidePlaceholder();
+			return true;
+		} catch (error) {
+			if (deviceId) {
+				var fallbackStream = await navigator.mediaDevices.getUserMedia({video: true, audio: false});
+				state.stream = fallbackStream;
+				elements.video.srcObject = fallbackStream;
+				await elements.video.play();
+				elements.video.style.display = "block";
+				elements.image.style.display = "none";
+				hidePlaceholder();
+				return true;
+			}
+			handleCameraError(error);
+			return false;
+		}
+	}
+
+	function setActionMode(mode){
+		if (!ensureElements()) {
+			return;
+		}
+		state.mode = mode;
+		elements.connectActions.style.display = mode === "disconnected" ? "flex" : "none";
+		elements.captureActions.style.display = mode === "live" ? "flex" : "none";
+		elements.reviewActions.style.display = mode === "captured" ? "flex" : "none";
+		if (mode === "live") {
+			elements.preview.classList.add("is-live");
+		} else {
+			elements.preview.classList.remove("is-live");
+		}
+		if (mode === "disconnected") {
+			clearStream();
+			elements.video.style.display = "none";
+			elements.image.style.display = "none";
+			setPlaceholder("点击连接摄像头后由浏览器弹出设备/权限选择");
+		}
+	}
+
+	function handleCameraError(error){
+		console.error("Error: ", error);
+		clearStream();
+		if (elements.video) {
+			elements.video.style.display = "none";
+		}
+		setPlaceholder("摄像头连接失败,请检查权限后重试");
+		alert("摄像头连接失败,请检查设备权限后重试");
+	}
+
+	async function connectCamera(){
+		if (!ensureElements()) {
+			return false;
+		}
+		setPlaceholder("正在请求浏览器摄像头权限...");
+		var canUseCamera = await ensureCameraOptions();
+		if (!canUseCamera) {
+			return false;
+		}
+		var connected = await startPreview(elements.videoSource.value);
+		if (connected) {
+			setActionMode("live");
+		}
+		return connected;
+	}
+
+	function capturePhoto(){
+		if (!ensureElements()) {
+			return;
+		}
+		if (!state.stream) {
+			connectCamera();
+			return;
+		}
+		var width = elements.video.videoWidth || elements.preview.clientWidth;
+		var height = elements.video.videoHeight || elements.preview.clientHeight;
+		elements.canvas.width = width;
+		elements.canvas.height = height;
+		var context = elements.canvas.getContext("2d");
+		context.clearRect(0, 0, width, height);
+		context.drawImage(elements.video, 0, 0, width, height);
+		var imgdataBase64 = elements.canvas.toDataURL("image/png");
+		initCropper1(elements.file, settings, cropConfirm, convertBase64UrlToBlob(imgdataBase64));
+	}
+
+	function cropConfirm(result){
+		if (!ensureElements()) {
+			return;
+		}
+		clearStream();
+		var path = result.fileList[0].path;
+		var url = "/service?ssServ=dlByHttp&type=img&path=" + path;
+		elements.image.src = url;
+		elements.image.style.display = "block";
+		elements.video.style.display = "none";
+		hidePlaceholder();
+		document.querySelector("input[name='zjzwj']").value = path;
+		setActionMode("captured");
+	}
+
+	function retakePhoto(){
+		if (!ensureElements()) {
+			return;
+		}
+		elements.image.style.display = "none";
+		connectCamera();
+	}
+
+	function submitPhotoForm(){
+		var formEl = document.getElementById("app") || document.getElementById("xyZjzPhotoForm");
+		if (!formEl) {
+			alert("表单不存在");
+			return false;
+		}
+		if (!document.querySelector("input[name='zjzwj']").value) {
+			alert("请先拍照");
+			return false;
+		}
+		formEl.submit();
+		return true;
+	}
+
+	function convertBase64UrlToBlob(urlData) {
+		var bytes = window.atob(urlData.split(",")[1]);
+		var ab = new ArrayBuffer(bytes.length);
+		var ia = new Uint8Array(ab);
+		for (var i = 0; i < bytes.length; i++) {
+			ia[i] = bytes.charCodeAt(i);
+		}
+		return new Blob([ab], {
+			type: "image/jpeg"
+		});
+	}
+
+	window.xyZjzCameraPage = {
+		connectCamera: connectCamera,
+		capturePhoto: capturePhoto,
+		retakePhoto: retakePhoto,
+		submitPhotoForm: submitPhotoForm
+	};
+
+	function initPage(){
+		if (!ensureElements()) {
+			return;
+		}
+		setActionMode("disconnected");
+	}
+
+	if (document.readyState === "loading") {
+		document.addEventListener("DOMContentLoaded", initPage);
+	} else {
+		initPage();
+	}
+})();
+
+var file = {};
+function initCropper1(fileEle, settings, cropConfirm, fileDate) {
+	file["name"] = new Date().getTime() + ".png";
+	initWdCropper();
+	wdCropper.topWin = wd.topWindow;
+	wdCropper.thisWindow = window;
+	wdCropper.settings = settings;
+	wdCropper.fileEle = fileEle;
+	wdCropper.cropConfirm = cropConfirm;
+	wdCropper.cropper.fileName = file.name;
+	wdCropper.fileObj = fileDate;
+	var uploadedImageURL = URL.createObjectURL(fileDate);
+	var img = new Image();
+	img.onload = function() {
+		wdCropper.layer.show({
+			width: img.width,
+			height: img.height
+		});
+		wdCropper.cropper.init();
+		wdCropper.cropper.replace(uploadedImageURL);
+	};
+	img.src = uploadedImageURL;
+}
+</script>
+
+<script type="text/javascript">var wdRecordValue='${wdRecordValue}';</script>
+<script type="text/javascript" src="/ss/js/wdRecord.js"></script>
+<script type="text/javascript">(function(){wdRecord("xyZjz_excelAdd");})();</script>
+<script type="text/javascript" src="/ss/js/wdFitHeight.js"></script>
+<script type="text/javascript">initWdFitHeight(0)</script>
+<script type="text/javascript">initWdFitHeightFunction=function(){initWdFitHeight(0);};</script>
+<ss:equal val="${empty resizeComponent}" val2="false">
+<script>{var iframe=wd.display.getFrameOfWindow();
+if(iframe&&iframe.contentWindow==window)
+wd.display.resizeComponent(${resizeComponent.width}, ${resizeComponent.height}, ${empty resizeComponent.minHeight?'null':resizeComponent.minHeight}, ${empty resizeComponent.maxHeight?'null':resizeComponent.maxHeight});}</script>
+</ss:equal>
+<ss:help/>
+</body>
+<script type="text/javascript">
+try{wd.display.showMsgPopup('${msg}');
+}catch(err){console.error(err);}
+</script>
+<ss:equal val="${empty wdclosewindowparam}" val2="false">
+<script type="text/javascript">
+try{wd.display.setCloseWindowParam('${wdclosewindowparam}');
+}catch(err){console.error(err);}
+</script>
+</ss:equal>
+</html>
+<%@ include file="/page/clip/footer.jsp" %>
+<script>
+
+</script>
+<script>
+	// 写死测试数据,先调UI
+	// 策略:劫持 SS.dom.initializeFormApp,在创建 Vue 时自动注入数据
+	(function() {
+		const studentList = [
+			{xm: '张三', xbmc: '男', jyfsmc: '走读', ryh: '2024001', zpwj: '', zjzwj: '', ryid: '1001', sfzh: '110101200001011234'},
+			{xm: '李四', xbmc: '女', jyfsmc: '寄宿', ryh: '2024002', zpwj: '', zjzwj: '', ryid: '1002', sfzh: '110101200002021245'},
+			{xm: '王五', xbmc: '男', jyfsmc: '走读', ryh: '2024003', zpwj: '', zjzwj: '', ryid: '1003', sfzh: '110101200003031256'},
+			{xm: '赵六', xbmc: '女', jyfsmc: '寄宿', ryh: '2024004', zpwj: '', zjzwj: '', ryid: '1004', sfzh: '110101200004041267'},
+			{xm: '钱七', xbmc: '男', jyfsmc: '走读', ryh: '2024005', zpwj: '', zjzwj: '', ryid: '1005', sfzh: '110101200005051278'},
+		];
+		
+		const firstStudent = studentList[0];
+		
+		// 等待 SS.ready 后劫持 initializeFormApp
+		function setupHijack() {
+			if (!window.SS || !window.SS.dom || !window.SS.dom.initializeFormApp) {
+				setTimeout(setupHijack, 50);
+				return;
+			}
+			
+			const originalInit = window.SS.dom.initializeFormApp;
+			
+			window.SS.dom.initializeFormApp = function(options) {
+				// 合并数据到 options
+				if (!options.data) {
+					options.data = function() { return {}; };
+				}
+				
+				const originalDataFn = options.data;
+				options.data = function() {
+					const originalData = originalDataFn.call(this);
+					return {
+						...originalData,
+						currentStudent: { ...firstStudent },
+						bjmc: '一年级1班',
+						bjcyCount: studentList.length,
+						currentIndex: 0,
+						studentList: studentList,
+						stream: null,
+						mode: 'disconnected'
+					};
+				};
+				
+				// 合并方法
+				if (!options.methods) {
+					options.methods = {};
+				}
+				options.methods.selectStudent = function(index, student) {
+					this.currentIndex = index;
+					this.currentStudent = { ...student };
+					const ryidInput = document.querySelector("input[name='ryid']");
+					const zjzwjInput = document.querySelector("input[name='zjzwj']");
+					if (ryidInput) ryidInput.value = student.ryid || '';
+					if (zjzwjInput) zjzwjInput.value = student.zjzwj || '';
+					const img = document.getElementById("image");
+					if (img && student.zpwj) {
+						img.src = "/service?ssServ=dlByHttp&type=img&path=" + student.zpwj;
+					} else if (img) {
+						img.src = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100'%3E%3Crect width='100' height='100' fill='%23f0f0f0'/%3E%3Ctext x='50' y='55' font-size='12' fill='%23999' text-anchor='middle'%3E无照片%3C/text%3E%3C/svg%3E";
+					}
+				};
+				
+				console.log('[Vue] 数据已合并到初始化选项');
+				return originalInit.call(this, options);
+			};
+			
+			console.log('[Vue] initializeFormApp 已劫持');
+		}
+		
+		// 如果 SS 还没准备好,等它
+		if (typeof SS !== 'undefined' && SS.ready) {
+			SS.ready(setupHijack);
+		} else {
+			setTimeout(setupHijack, 100);
+		}
+	})();
+</script>

+ 206 - 0
page/xy_baseInfo.jsp

@@ -0,0 +1,206 @@
+<%@ page language="java" pageEncoding="UTF-8" isELIgnored="false" %>
+<%@ taglib uri="/ssTag" prefix="ss"%>
+
+<% pageContext.setAttribute(ss.page.PageC.PAGE_objName,"xy");%>
+<%pageContext.setAttribute("wdpageinformation","{'hastab':'0'}");%>
+<!DOCTYPE html>
+<html>
+<head>
+<%@ include file="/page/clip/header.jsp" %>
+</head>
+<body> <%-- 新UI把原来body标签样式 style="padding-left:7px;padding-top:13px;padding-bottom:0px;" 去掉 Ben(20251217) --%>
+<div id="app" class="form-container">
+    <div class="content-box fit-height-content"><%-- 这和上一层代码,是新UI加的div结构 Ben(20251213) --%>
+<%--  <script type="text/javascript">wd.display.fitHeightbqgd(13)</script>  纵向已经没标签了,注释掉 Ben(20251213) --%> <%-- bqgd = 标签高度。Lin --%>
+<div class="content-div" ssFith="true">
+	<table class="form">
+		<tr>
+			<th rowspan="2" style="width:160px;">相片</th>
+			<td rowspan="2">
+				<ss:auth field='zjzwj'>
+<div id="zjzwjDiv" class=" id-photo" ><ss:equal val='${empty xy.zjzwj}' val2='false'><img src="<ss:serv name='dlByHttp' parm='{"path":"${xy.zjzwj}","type":"img"}'/>" id="zjzimg" onerror_="this.src='${sessionScope['ssUser'].skinDir}image/default-photo.png'" /></ss:equal><ss:equal val='${empty xy.zjzwj}' val2='true'><img src="${sessionScope['ssUser'].skinDir}image/default-photo.png" id="zjzimg" onerror_="this.src='${sessionScope['ssUser'].skinDir}image/default-photo.png'" /></ss:equal></div><script type="text/javascript">
+$("#zjzwjDiv").click(function(){
+var url ="<ss:serv name='dlByHttp' parm='{"path":"${xy.zjzwj}","type":"img"}'/>";
+var errorPhoto='${sessionScope['ssUser'].skinDir}image/default-photo.png'; 
+wd.display.previewPicture(url,errorPhoto);
+	})
+</script>
+
+</ss:auth>
+				<ss:auth field='yszwj'>
+<div id="yszwjDiv" class="life-photo"  style="margin-top:42px; margin-left:13px;"><ss:equal val='${empty xy.yszwj}' val2='false'><img src="<ss:serv name='dlByHttp' parm='{"path":"${xy.yszwj}","type":"img"}'/>" id="yszimg1" onerror_="this.src='${sessionScope['ssUser'].skinDir}image/null'" /></ss:equal><ss:equal val='${empty xy.yszwj}' val2='true'><img src="${sessionScope['ssUser'].skinDir}image/null" id="yszimg2" onerror_="this.src='${sessionScope['ssUser'].skinDir}image/null'" /></ss:equal></div><script type="text/javascript">
+$("#yszwjDiv").click(function(){
+var url ="<ss:serv name='dlByHttp' parm='{"path":"${xy.yszwj}","type":"img"}'/>";
+var errorPhoto='${sessionScope['ssUser'].skinDir}image/null'; 
+wd.display.previewPicture(url,errorPhoto);
+	})
+</script>
+
+</ss:auth>
+			</td>
+			<th style="width:160px;">姓名</th>
+			<td><ss:auth field="xm">
+
+<%--自动生成:xy.xm--%><div id="xm"  width="108px" ><ss:txt val='${xy.xm}'/></div><script type="text/javascript" charset="utf-8" src="/ss/js/growHeight.js"></script>
+<script type="text/javascript" charset="utf-8" src="/ss/js/display.js"></script>
+<script type="text/javascript" charset="utf-8">
+wd.display.initGrowHigh('xm','null',{},null,false);
+
+</script>
+
+</ss:auth></td>
+		</tr>
+		<tr>
+			<th>性别</th>
+			<td><ss:auth field="xbm">
+
+<%--自动生成:xy.xbm--%><div id="xbm"  width="90px" ><ss:cbTrans cb="xb" val="${xy.xbm}" filter=""/></div><script type="text/javascript" charset="utf-8" src="/ss/js/growHeight.js"></script>
+<script type="text/javascript" charset="utf-8" src="/ss/js/display.js"></script>
+<script type="text/javascript" charset="utf-8">
+wd.display.initGrowHigh('xbm','null',{},null,false);
+
+</script>
+
+</ss:auth></td>
+		</tr>
+		<tr>
+			<th>民族</th>
+			<td colspan="3"><ss:auth field="mzm">
+
+<%--自动生成:xy.mzm--%><div id="mzm"  width="117px" ><ss:cbTrans cb="mz" val="${xy.mzm}" filter=""/></div><script type="text/javascript" charset="utf-8" src="/ss/js/growHeight.js"></script>
+<script type="text/javascript" charset="utf-8" src="/ss/js/display.js"></script>
+<script type="text/javascript" charset="utf-8">
+wd.display.initGrowHigh('mzm','null',{},null,false);
+
+</script>
+
+</ss:auth></td>
+		</tr>
+		<tr>
+			<th>学号</th>
+			<td><ss:auth field="ryh">
+
+<%--自动生成:xy.ryh--%><div id="ryh"  width="117px" ><ss:txt val='${xy.ryh}'/></div><script type="text/javascript" charset="utf-8" src="/ss/js/growHeight.js"></script>
+<script type="text/javascript" charset="utf-8" src="/ss/js/display.js"></script>
+<script type="text/javascript" charset="utf-8">
+wd.display.initGrowHigh('ryh','null',{},null,false);
+
+</script>
+
+</ss:auth></td>
+			<th>班级</th>
+			<td><ss:auth field="bjid">
+
+<%--自动生成:xy.bjid--%><div id="bjid"  width="117px" ><ss:cbTrans cb="bj" val="${xy.bjid}" filter=""/></div><script type="text/javascript" charset="utf-8" src="/ss/js/growHeight.js"></script>
+<script type="text/javascript" charset="utf-8" src="/ss/js/display.js"></script>
+<script type="text/javascript" charset="utf-8">
+wd.display.initGrowHigh('bjid','null',{},null,false);
+
+</script>
+
+</ss:auth></td>
+		</tr>
+		<tr>
+			<th>消费余额</th>
+			<td><ss:auth field="xfye">
+
+<%--自动生成:xy.xfye--%><div id="xfye"  width="117px" ><ss:txt val='${xy.xfye}'/></div><script type="text/javascript" charset="utf-8" src="/ss/js/growHeight.js"></script>
+<script type="text/javascript" charset="utf-8" src="/ss/js/display.js"></script>
+<script type="text/javascript" charset="utf-8">
+wd.display.initGrowHigh('xfye','null',{},null,false);
+
+</script>
+
+</ss:auth></td>
+			<th>就读方式</th>
+			<td><ss:auth field="jdfsm">
+
+<%--自动生成:xy.jdfsm--%><div id="jdfsm"  width="117px" ><ss:cbTrans cb="jdfs" val="${xy.jdfsm}" filter=""/></div><script type="text/javascript" charset="utf-8" src="/ss/js/growHeight.js"></script>
+<script type="text/javascript" charset="utf-8" src="/ss/js/display.js"></script>
+<script type="text/javascript" charset="utf-8">
+wd.display.initGrowHigh('jdfsm','null',{},null,false);
+
+</script>
+
+</ss:auth></td>
+		</tr>
+		<tr>
+			<th>是否坐校车</th>
+			<td><ss:auth field="sfzxc">
+
+<script>
+ss.dom.formElemConfig.sfzxc={val:'${xy.sfzxc}',type:window.ss.dom.TYPE.ONOFFBTN};
+</script>
+<ss-onoff
+v-model="sfzxc"
+name="sfzxc"
+label="是"
+value="1"
+:multiple="false"
+:readonly="false"
+></ss-onoff>
+<ss-onoff
+v-model="sfzxc"
+name="sfzxc"
+label="否"
+value="0"
+:multiple="false"
+:readonly="false"
+></ss-onoff>
+
+</ss:auth></td>
+			<th>是否晚自修</th>
+			<td><ss:auth field="sfwzx">
+
+<script>
+ss.dom.formElemConfig.sfwzx={val:'${xy.sfwzx}',type:window.ss.dom.TYPE.ONOFFBTN};
+</script>
+<ss-onoff
+v-model="sfwzx"
+name="sfwzx"
+label="是"
+value="1"
+:multiple="false"
+:readonly="false"
+></ss-onoff>
+<ss-onoff
+v-model="sfwzx"
+name="sfwzx"
+label="否"
+value="0"
+:multiple="false"
+:readonly="false"
+></ss-onoff>
+
+</ss:auth></td>
+		</tr>
+	</table>
+</div>
+
+    </div>
+</div>
+<script type="text/javascript">var wdRecordValue='${wdRecordValue}';</script>
+<script type="text/javascript" src="/ss/js/wdRecord.js"></script>
+<script type="text/javascript">(function(){wdRecord("xy_baseInfo");})();</script>
+<script type="text/javascript" src="/ss/js/wdFitHeight.js"></script>
+<script type="text/javascript">initWdFitHeight(0)</script>
+<script type="text/javascript">initWdFitHeightFunction=function(){initWdFitHeight(0);};</script>
+<ss:equal val="${empty resizeComponent}" val2="false">
+<script>{var iframe=wd.display.getFrameOfWindow();
+if(iframe&&iframe.contentWindow==window)
+wd.display.resizeComponent(${resizeComponent.width}, ${resizeComponent.height}, ${empty resizeComponent.minHeight?'null':resizeComponent.minHeight}, ${empty resizeComponent.maxHeight?'null':resizeComponent.maxHeight});}</script>
+</ss:equal>
+<ss:help/>
+</body>
+<script type="text/javascript">
+try{wd.display.showMsgPopup('${msg}');
+}catch(err){console.error(err);}
+</script>
+<ss:equal val="${empty wdclosewindowparam}" val2="false">
+<script type="text/javascript">
+try{wd.display.setCloseWindowParam('${wdclosewindowparam}');
+}catch(err){console.error(err);}
+</script>
+</ss:equal>
+</html>
+<%@ include file="/page/clip/footer.jsp" %>

+ 4 - 0
skin/easy/css/base.css

@@ -44,6 +44,7 @@
   position: relative;
   float: left;
   margin-top: 5px !important;
+  margin-left: 14px;
 }
 .life-photo::before {
   content: "\e605";
@@ -59,6 +60,9 @@
 }
 .life-photo img{
   border-radius: 50%;
+  width: 100%;
+  position: relative;
+  z-index: 1;
 }
 
 /* 仅临时兼容 */

+ 40 - 44
ss/clip/miniInfo.jsp

@@ -2,8 +2,8 @@
 <div class="longCardList-div" style="box-sizing: border-box;">
 	<table class="scrollbar" style="max-height: 100%;width: 100%;">
 		<tbody style="width: 100%;padding: 0px 16px 0px 11px;box-sizing: border-box;"> <%-- 去掉 id="wdTbody0",好像没用到。Lin --%>
-		<ss:rpt name='objectList' id='item'>
-			<tr
+		<ss:rpt name='objectList' id='item'>
+			<tr
 					<ss:equal val='${item.rauth}' val2='0'>
 						class="xxxfilter"
 <%-- 再改为 WebC.REQ_objName、WebC.REQ_objId,避免与数据表里的 对象名、对象ID 字段重名。Lin
@@ -14,10 +14,10 @@
 				<td class="hLine"
 						<ss:equal val='${empty item.play}' val2='false'>
 							titlexxx="${item.play.title}"
-							onclick='wd.display.showComponent({show:["wdDialog"],url:"<ss:serv name='${item.play.servName}' dest='${item.play.dest}' parm='${item.play.parm}'/>",title:"${item.play.title}",width:"${item.play.width}",height:"${item.play.height}",minHeight:"${item.play.minHeight}",maxHeight:"${item.play.maxHeight}"});'
+							onclick='wd.display.showComponent({show:["wdDialog"],url:"<ss:serv name='${item.play.servName}' dest='${item.play.dest}' parm='${item.play.parm}'/>",title:"${item.play.title}",width:"${item.play.width}",height:"${item.play.height}",minHeight:"${item.play.minHeight}",maxHeight:"${item.play.maxHeight}"});'
 						</ss:equal>
 					>
-					<ss:equal val='${empty item.thn}' val2='false'>
+					<ss:equal val='${empty item.thn}' val2='false'>
 						<div class="longCardList-thumbnail" style="margin-right: 18px;margin-bottom: 2px;">
 <%-- 再增加 type="img"。Lin
 							<img src="<ss@serv name='dlByHttp' parm='{"wdConfirmationCaptchaService":"0","path":"${item.thn}"}'/>"/> --%>
@@ -30,32 +30,30 @@
 								<ss:equal val='${empty item.title}' val2='false'>
 									<%--不带codebook--%>
 									<ss:equal val='${empty item.title.cbName}' val2='true'>
-										<ss:txt val='${empty item.title.value?item.title.val:item.title.value}' fmt='${item.title.fmt}'/>
+										<ss:txt val='${empty item.title.value?item.title.val:item.title.value}' fmt='${item.title.fmt}'/>
 									</ss:equal>
 									<%--带codebook--%>
 									<ss:equal val='${empty item.title.cbName}' val2='false'>
-										<ss:cbTrans cb='${item.title.cbName}' val='${empty item.title.value?item.title.val:item.title.value}'/>
+										<ss:cbTrans cb='${item.title.cbName}' val='${empty item.title.value?item.title.val:item.title.value}'/>
 									</ss:equal>
 								</ss:equal>
-								<%--缺标题显示属性start--%>
-								<ss:equal val='${empty item.title && not empty item.catList}' val2='true'>
-									<ss:rpt name='${item.catList}' id='itemList'>
-										<ss:rpt name='${itemList}' id='item2'>
-											<span>
-												${item2.desc}:
-												<%--不带codebook--%>
-												<ss:equal val='${empty item2.cbName}' val2='true'>
-													<ss:txt val='${item2.value}' fmt='${item2.fmt}' miniDate='false'/>
-												</ss:equal>
-												<%--带codebook--%>
-												<ss:equal val='${empty item2.field.cbName}' val2='false'>
-													<ss:cbTrans cb='${item2.cbName}' val='${item2.value}'/>
-												</ss:equal>
-											</span>
-										</ss:rpt>
-									</ss:rpt>
-								</ss:equal>
-								<%--缺标题显示属性end--%>
+								<%--缺标题显示属性start--%>
+								<ss:equal val='${empty item.title && not empty item.catList}' val2='true'>
+									<ss:rpt name='${item.catList}' id='item2'>
+										<span>
+											${item2.desc}:
+											<%--不带codebook--%>
+											<ss:equal val='${empty item2.cbName}' val2='true'>
+												<ss:txt val='${item2.val}' fmt='${item2.fmt}' miniDate='false'/>
+											</ss:equal>
+											<%--带codebook--%>
+											<ss:equal val='${empty item2.cbName}' val2='false'>
+												<ss:cbTrans cb='${item2.cbName}' val='${item2.val}'/>
+											</ss:equal>
+										</span>
+									</ss:rpt>
+								</ss:equal>
+								<%--缺标题显示属性end--%>
 							</a>
 						</span>
 						<ss:equal val='${empty item.second}' val2='false'>
@@ -63,25 +61,23 @@
 									${item.abs}
 							</div>
 						</ss:equal>
-						<ss:equal val='${empty item.title && not empty item.catList}' val2='false'>
-							<ss:rpt name='${item.catList}' id='itemList'>
-								<div id="cardList-category${item.index}-0" class="longCardList growHeightDiv">
-									<ss:rpt name='${itemList}' id='item2'>
-										<span>
-											${item2.desc}:
-											<%--不带codebook--%>
-											<ss:equal val='${empty item2.cbName}' val2='true'>
-												<ss:txt val='${item2.value}' fmt='${item2.fmt}' miniDate='false'/>
-											</ss:equal>
-											<%--带codebook--%>
-											<ss:equal val='${empty item2.cbName}' val2='false'>
-												<ss:cbTrans cb='${item2.cbName}' val='${item2.value}'/>
-											</ss:equal>
-										</span>
-									</ss:rpt>
-								</div>
-							</ss:rpt>
-						</ss:equal>
+						<ss:equal val='${empty item.title && not empty item.catList}' val2='false'>
+							<div id="cardList-category${item.index}-0" class="longCardList growHeightDiv">
+								<ss:rpt name='${item.catList}' id='item2'>
+									<span>
+										${item2.desc}:
+										<%--不带codebook--%>
+										<ss:equal val='${empty item2.cbName}' val2='true'>
+											<ss:txt val='${item2.val}' fmt='${item2.fmt}' miniDate='false'/>
+										</ss:equal>
+										<%--带codebook--%>
+										<ss:equal val='${empty item2.cbName}' val2='false'>
+											<ss:cbTrans cb='${item2.cbName}' val='${item2.val}'/>
+										</ss:equal>
+									</span>
+								</ss:rpt>
+							</div>
+						</ss:equal>
 					</div>
 					<%-- <ss:equal val='${empty item.service.change}' val2='false'>
 						<a class="button-${'change'==item.service.change.function.name?'change':'enable'}"

+ 23 - 19
ss/js/growHeight.js

@@ -193,28 +193,32 @@ GrowHeight.prototype.updateContainerHeight = function () {
     this.container.style.height = h + "px";
 }
 GrowHeight.prototype.hide = function () {
+    try{
+        $(this.wrapper).removeClass("input-div-selected");
+        $(this.wrapper).addClass("input-s");
+        $(this.wrapper).find(".smallScrollbar").getNiceScroll().remove();
+        if (this.shadow) {
+            if (this.shadow.parentNode != this.wrapper.parentNode)
+                this.shadow.parentNode.insertBefore(this.wrapper, this.shadow);
+            this.shadow.parentNode.removeChild(this.shadow);
+            this.shadow = null;
+        }
 
-    $(this.wrapper).removeClass("input-div-selected");
-    $(this.wrapper).addClass("input-s");
-    $(this.wrapper).find(".smallScrollbar").getNiceScroll().remove();
-    if (this.shadow) {
-        if (this.shadow.parentNode != this.wrapper.parentNode)
-            this.shadow.parentNode.insertBefore(this.wrapper, this.shadow);
-        this.shadow.parentNode.removeChild(this.shadow);
-        this.shadow = null;
-    }
+        var ori = this.oriInfo;
+        if (ori) {
+            this.wrapper.style.cssText = ori.wrapper;
+            this.container.style.cssText = ori.container;
+            this.wrapper.parentNode.style.cssText = ori.parent_;
+            this.oriInfo = null;
+        }
 
-    var ori = this.oriInfo;
-    if (ori) {
-        this.wrapper.style.cssText = ori.wrapper;
-        this.container.style.cssText = ori.container;
-        this.wrapper.parentNode.style.cssText = ori.parent_;
-        this.oriInfo = null;
+        if (this.cmsBtn) {
+            //更新CMS按钮的位置
+            this.cmsBtn.updateButtonSize();
+        }
     }
-
-    if (this.cmsBtn) {
-        //更新CMS按钮的位置
-        this.cmsBtn.updateButtonSize();
+    catch(e){
+        console.log(e)
     }
 
 }

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff