| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907 |
- <%@ 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>
|