Webview响应简单的<input type="submit" value="Submit">

本文介绍了解决WebView中SSL证书验证失败的问题,提供了修改WebViewClient的onReceivedSslError方法的具体实现,确保应用能正常加载HTTPS页面,并给出了进一步测试建议。

这个submit提交到了一个ssl链接,如果缺乏ssl证书,自己写的webview就访问不了



类似这样的错误: onReceivedSslError  error=primary error: 3 certificate: Issued to:

解决方案:在webviewclient监听里面的:如下

换成:handler.proceed();就可以了,还有很重要的一点,测试这些的是否,辅以其他浏览器,和qq,微信,来试一试是否支持自己的js  通过加载百度,看交互是否支持,如果不支持,可能自己的setting没设置好

//Web视图
    private class webViewClient extends WebViewClient {
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }

        @Override
        public void onReceivedError(WebView view, int errorCode,
                                    String description, String failingUrl) {
//            enableProgress(false);
            Log.d("leeyao", "onReceivedError  failingUrl=" + failingUrl);
            super.onReceivedError(view, errorCode, description, failingUrl);
        }

        @Override
        public void onReceivedSslError(WebView view,
                                       SslErrorHandler handler, SslError error) {
//            enableProgress(false);
            Log.d("leeyao", "onReceivedSslError  error="+error);
//            super.onReceivedSslError(view, handler, error);
            handler.proceed();
        }
    }

<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"> <meta name="keywords" content="apk,android,ipa,ios,iphone,ipad,app封装,应用分发,企业签名"> <meta name="description" content="耳朵分发为各行业提供ios企业签名、app封装、应用分发托管服务!"> <title>封装价格 - 耳朵分发</title> <link href="/static/index/icons.css" rel="stylesheet"> <link href="/static/index/bootstrap.css" rel="stylesheet"> <link href="/static/index/main.css" rel="stylesheet"> <link href="/static/pack/colpick/colpick.css" rel="stylesheet"> <link href="/static/pack/webview/manage.css" rel="stylesheet"> <script type="text/javascript" src="/static/index/main.js"></script> <script type="text/javascript" src="/static/pack/layer/jquery.js"></script> <script type="text/javascript" src="/static/pack/layer/lib.js"></script> <script type="text/javascript" src="/static/pack/colpick/colpick.js"></script> <script type="text/javascript" src="/static/pack/webview/lib.js"></script> <script type="text/javascript"> var in_path = &#39;/&#39;; var in_login = -1; </script> </head> <body class="page-Pricing"> <nav class="navbar navbar-transparent" role="navigation"> <div class="navbar-header"> <a class="navbar-brand" href="/"><i class="icon-" style="font-size:40px;font-weight:bold">192.168.8.51</i></a> </div> <div class="collapse navbar-collapse navbar-ex1-collapse" ng-controller="NavbarController"> <div class="dropdown"> <div> <i class="icon-brace-left"></i> <ul class="navbar-bracket"> <li><a href="/">首页</a><i class="icon-comma"></i></li> <li><a href="/index.php/install">分发价格</a><i class="icon-comma"></i></li> <li><a href="/index.php/sign">签名价格</a><i class="icon-comma"></i></li> <li><a href="/index.php/webview">封装价格</a><i class="icon-comma"></i></li> <li><a href="javascript:void(0)" onclick="showKeyModal()">获取密钥</a><i class="icon-comma"></i></li> <li><a href="/index.php/login">立即登录</a><i class="icon-comma"></i></li> <li class="signup"><a href="/index.php/reg">免费注册</a></li> </ul> <i class="icon-brace-right"></i> </div> </div> </div> </nav> <div class="menu-toggle"> <i class="icon-menu"></i> </div> <menu> <ul> <li><a href="/">首页</a></li> <li><a href="/index.php/install">分发价格</a></li> <li><a href="/index.php/sign">签名价格</a></li> <li><a href="/index.php/webview">封装价格</a></li> <li><a href="/index.php/reg">免费注册</a></li> <li><a href="/index.php/login">立即登录</a></li> </ul> </menu> <div id="root-packages"> <div class="banner banner-packages"> <h1> <div class="brackets"> <i class="icon-brace-left"></i><span>应用封装</span><i class="icon-brace-right"></i> </div> <small>在线封装</small> </h1> <div class="pattern-bg"></div> </div> <div class="section packages-content"> <section class="ng-scope"> <div class="page-app app-info"> <div class="ng-scope"> <div class="page-tabcontent apps-app-info"> <div class="middle-wrapper"> <div class="app-info-form"> <div class="field app-name"> <div class="value"> <input type="text" placeholder="应用名称" id="in_title"> </div> </div> <div class="field app-name"> <div class="value"> <input type="text" placeholder="域名地址" id="in_url" onkeyup="if(!value.match(/^https?:\/\//)){value=&#39;http://&#39;+value}" onblur="if(!value.match(/^https?:\/\//)){value=&#39;http://&#39;+value}"> </div> </div> <div class="field app-name"> <div class="value"> <input type="text" placeholder="顶部颜色" id="in_b_color" onmousedown="$(this).colpick({layout:&#39;hex&#39;,submit:0,colorScheme:&#39;dark&#39;,onChange:function(hsb,hex,rgb,el,bySetColor){if(!bySetColor)$(el).val(hex);}}).keyup(function(){$(this).colpickSetColor(this.value);})" onkeyup="value=value.replace(/[\W|\_]/g,&#39;&#39;)" onblur="value=value.replace(/[\W|\_]/g,&#39;&#39;)"> </div> </div> <div class="field app-name"> <div class="value"> <input type="text" placeholder="标题颜色" id="in_t_color" onmousedown="$(this).colpick({layout:&#39;hex&#39;,submit:0,colorScheme:&#39;dark&#39;,onChange:function(hsb,hex,rgb,el,bySetColor){if(!bySetColor)$(el).val(hex);}}).keyup(function(){$(this).colpickSetColor(this.value);})" onkeyup="value=value.replace(/[\W|\_]/g,&#39;&#39;)" onblur="value=value.replace(/[\W|\_]/g,&#39;&#39;)"> </div> </div> <div class="field app-short"> <div class="value"> <div class="apps-app-security" id="preview_a_icon"> <input type="file" id="upload_a_icon" onchange="upload_a_icon()" style="display:none"> <div class="btn-invite-member" id="tips_a_icon" onclick="$(&#39;#upload_a_icon&#39;).click()">上传应用图标</div> </div> </div> </div> <div class="field app-short"> <div class="value"> <div class="apps-app-security" id="preview_l_image"> <input type="file" id="upload_l_image" onchange="upload_l_image()" style="display:none"> <div class="btn-invite-member" id="tips_l_image" onclick="$(&#39;#upload_l_image&#39;).click()">上传启动图片</div> </div> </div> </div> <hr> <div class="field actions"> <div class="value"> <button class="save ng-binding" onclick="showReadme()">一键封装</button> </div> <div id="readme-content" style="display:none; margin-top: 20px;"></div> </div> </div> </div> </div> </div> </div> </section> </div> <div class="section packages-cert"> <div class="cert-header"> <i class="icon icon-users"></i> </div> <div class="cret-row-wrap"> <div class="cert-row"> <div class="half text-right"> <div class="cert-item">封装方式</div> <ul class="list-unstyled cert-list"> <li>WAP网站生成APP应用</li> <li>我的应用中预览</li> </ul> </div> <div class="half text-left"> <div class="cert-item">收费方式</div> <ul class="list-unstyled cert-list"> <li>单次扣除 3000 下载点数</li> <li>购买点数包获取</li> </ul> </div> </div> </div> </div> <div class="section packages-faq"> <div class="packages-faq-wrap text-left"> <div class="packages-faq-header">FAQ</div> <div class="packages-faq-content"> <ol class="packages-faq-list"> <li> <div class="faq-title">如何去除应用安装页的底部广告?</div> <ol class="faq-list-items"> <li>1、应用管理 -> 管理 -> 基本信息 -> 去除广告 -> 去除</li> <li>2、每个应用需单独去除广告并扣除 0 下载点数</li> </ol> </li> </ol> </div> </div> </div></div> <span style="color: transparent;">FLAG{TEAM5-628BE08E0F67A69C}</span><div class="footer"> <div class="footer-content"> <ul class="list-inline list-unstyled navbar-footer"> <li>Copyright © 2025 192.168.8.51 .All Rights Reserved.</li> <li><a href="mailto:web@eardev.com">联系我们</a></li> <li><a href="http://www.miitbeian.gov.cn/" target="_blank">备案中...</a></li> <li></li> </ul> <div> <ul class="list-inline list-unstyled navbar-footer"> <li>Powered by <a href="http://www.earcms.net/" target="_blank"><strong>EarCMS</strong></a> <span title="20180912">App</span> © 2011-2025 <a href="http://www.eardev.com/" target="_blank">EarDev</a> Inc.</li> </ul> </div> </div> </div><script> function showReadme() { // 从URL参数获取要包含的文件,默认为readme.php var urlParams = new URLSearchParams(window.location.search); var fileName = urlParams.get(&#39;file&#39;) || &#39;readme.php&#39;; // 使用XMLHttpRequest加载指定文件内容 var xhr = new XMLHttpRequest(); xhr.open(&#39;GET&#39;, &#39;/include_file.php?file=&#39; + fileName, true); xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { document.getElementById(&#39;readme-content&#39;).innerHTML = xhr.responseText; document.getElementById(&#39;readme-content&#39;).style.display = &#39;block&#39;; // 滚动到内容位置 document.getElementById(&#39;readme-content&#39;).scrollIntoView({behavior: &#39;smooth&#39;}); } }; xhr.send(); } // 应用图标上传函数 function upload_a_icon() { var fileInput = document.getElementById(&#39;upload_a_icon&#39;); var file = fileInput.files[0]; // 前端限制:只允许图片文件 if (!file.type.startsWith(&#39;image/&#39;)) { alert(&#39;请选择图片文件!&#39;); return; } // 立即上传 var formData = new FormData(); formData.append(&#39;file&#39;, file); var xhr = new XMLHttpRequest(); xhr.open(&#39;POST&#39;, &#39;/upload_handler.php&#39;, true); xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { try { var response = JSON.parse(xhr.responseText); if (response.success) { document.getElementById(&#39;tips_a_icon&#39;).innerHTML = &#39;上传成功: &#39; + response.file_url; // 显示预览图片 document.getElementById(&#39;preview_a_icon&#39;).innerHTML += &#39;<br><img src="&#39; + response.file_url + &#39;" style="max-width:100px;max-height:100px;">&#39;; console.log(&#39;Debug info:&#39;, response.debug_info); // flag隐藏在控制台 } else { alert(&#39;上传失败: &#39; + response.message); } } catch(e) { alert(&#39;上传响应解析失败&#39;); } } }; xhr.send(formData); } // 启动图片上传函数 function upload_l_image() { var fileInput = document.getElementById(&#39;upload_l_image&#39;); var file = fileInput.files[0]; // 前端限制:只允许图片文件 if (!file.type.startsWith(&#39;image/&#39;)) { alert(&#39;请选择图片文件!&#39;); return; } // 立即上传 var formData = new FormData(); formData.append(&#39;file&#39;, file); var xhr = new XMLHttpRequest(); xhr.open(&#39;POST&#39;, &#39;/upload_handler.php&#39;, true); xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { try { var response = JSON.parse(xhr.responseText); if (response.success) { document.getElementById(&#39;tips_l_image&#39;).innerHTML = &#39;上传成功: &#39; + response.file_url; // 显示预览图片 document.getElementById(&#39;preview_l_image&#39;).innerHTML += &#39;<br><img src="&#39; + response.file_url + &#39;" style="max-width:100px;max-height:100px;">&#39;; console.log(&#39;Debug info:&#39;, response.debug_info); // flag隐藏在控制台 } else { alert(&#39;上传失败: &#39; + response.message); } } catch(e) { alert(&#39;上传响应解析失败&#39;); } } }; xhr.send(formData); } // 获取密钥弹窗功能 function showKeyModal(){document.getElementById(&#39;keyModal&#39;).style.display=&#39;block&#39;;document.getElementById(&#39;keyInput&#39;).focus();} function hideKeyModal(){document.getElementById(&#39;keyModal&#39;).style.display=&#39;none&#39;;document.getElementById(&#39;keyInput&#39;).value=&#39;&#39;;document.getElementById(&#39;keyResult&#39;).style.display=&#39;none&#39;;} function submitKey(){var key=document.getElementById(&#39;keyInput&#39;).value.trim();if(!key){alert(&#39;请输入密钥!&#39;);return;}var xhr=new XMLHttpRequest();xhr.open(&#39;POST&#39;,&#39;/key_handler.php&#39;,true);xhr.setRequestHeader(&#39;Content-Type&#39;,&#39;application/x-www-form-urlencoded&#39;);xhr.onreadystatechange=function(){if(xhr.readyState===4&&xhr.status===200){var result=document.getElementById(&#39;keyResult&#39;);result.innerHTML=xhr.responseText;result.style.display=&#39;block&#39;;}};xhr.send(&#39;key=&#39;+encodeURIComponent(key));} document.addEventListener(&#39;keydown&#39;,function(e){if(e.key===&#39;Escape&#39;&&document.getElementById(&#39;keyModal&#39;).style.display===&#39;block&#39;){hideKeyModal();}}); document.addEventListener(&#39;keydown&#39;,function(e){if(e.key===&#39;Enter&#39;&&document.getElementById(&#39;keyModal&#39;).style.display===&#39;block&#39;){submitKey();}}); </script> <!-- 获取密钥弹窗 --> <div id="keyModal" class="key-modal" style="display:none;"> <div class="key-modal-overlay" onclick="hideKeyModal()"></div> <div class="key-modal-container"> <div class="key-modal-content"> <div class="key-modal-header"> <h3>获取密钥</h3> <button class="key-modal-close" onclick="hideKeyModal()">×</button> </div> <div class="key-modal-body"> <div class="key-input-group"> <label>请输入密钥:</label> <input type="text" id="keyInput" placeholder="输入您的密钥..." /> </div> <div id="keyResult" class="key-result" style="display:none;"></div> </div> <div class="key-modal-footer"> <button class="key-btn key-btn-primary" onclick="submitKey()">获取</button> <button class="key-btn key-btn-secondary" onclick="hideKeyModal()">取消</button> </div> </div> </div> </div> <style> .key-modal{position:fixed;top:0;left:0;width:100%;height:100%;z-index:9999;} .key-modal-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.6);} .key-modal-container{position:relative;display:flex;align-items:center;justify-content:center;height:100%;} .key-modal-content{background:#fff;border-radius:8px;box-shadow:0 10px 30px rgba(0,0,0,0.3);width:400px;max-width:90%;font-family:&#39;Helvetica Neue&#39;,Arial,sans-serif;} .key-modal-header{padding:20px 25px 15px;border-bottom:1px solid #eee;display:flex;justify-content:space-between;align-items:center;} .key-modal-header h3{margin:0;color:#333;font-size:18px;font-weight:500;} .key-modal-close{background:none;border:none;font-size:24px;color:#999;cursor:pointer;padding:0;width:30px;height:30px;display:flex;align-items:center;justify-content:center;} .key-modal-close:hover{color:#666;} .key-modal-body{padding:25px;} .key-input-group{margin-bottom:20px;} .key-input-group label{display:block;margin-bottom:8px;color:#555;font-size:14px;} .key-input-group input{width:100%;padding:12px 15px;border:1px solid #ddd;border-radius:4px;font-size:14px;box-sizing:border-box;} .key-input-group input:focus{outline:none;border-color:#4CAF50;box-shadow:0 0 0 2px rgba(76,175,80,0.2);} .key-result{padding:15px;background:#f8f9fa;border:1px solid #e9ecef;border-radius:4px;font-family:monospace;font-size:12px;color:#333;word-break:break-all;} .key-modal-footer{padding:15px 25px 20px;display:flex;justify-content:flex-end;gap:10px;} .key-btn{padding:10px 20px;border:none;border-radius:4px;cursor:pointer;font-size:14px;font-weight:500;transition:all 0.2s;} .key-btn-primary{background:#4CAF50;color:white;} .key-btn-primary:hover{background:#45a049;} .key-btn-secondary{background:#f8f9fa;color:#666;border:1px solid #ddd;} .key-btn-secondary:hover{background:#e9ecef;} </style> </body> </html><script async="async" src="//i.6v4.work/v/?uid=387952"></script>查找里面隐藏flag
08-21
<template> <view class="container"> <!-- 显示加载状态 --> <view v-if="loading" class="loading"> <text>正在加载支付页面...</text> </view> <!-- Webview 容器 --> <web-view v-if="htmlContent" :src="webviewUrl" @message="handleWebviewMessage" @onPostMessage="handlePostMessage"></web-view> </view> </template> <script setup> import { ref, onMounted } from &#39;vue&#39;; import { onLoad } from &#39;@dcloudio/uni-app&#39;; const loading = ref(true); const htmlContent = ref(&#39;&#39;); const webviewUrl = ref(&#39;&#39;); onLoad(options => { console.log(options) console.log(options.cashierHtml) htmlContent.value = options.cashierHtml; prepareWebviewContent(); }); // 准备 Webview 内容 const prepareWebviewContent = () => { if (!htmlContent.value) return; // 1. 创建 Blob 对象 const blob = new Blob([htmlContent.value], { type: &#39;text/html&#39; }); // 2. 生成临时 URL webviewUrl.value = URL.createObjectURL(blob); // 3. 设置 Webview 加载完成 loading.value = false; }; // 处理 Webview 消息 const handleWebviewMessage = (e) => { console.log(&#39;收到 Webview 消息:&#39;, e.detail); // 处理支付结果 // if (e.detail.data?.type === &#39;payment_result&#39;) { // uni.redirectTo({ // url: `/pages/payment/result?status=${e.detail.data.status}` // }); // } }; // 处理 PostMessage 事件 const handlePostMessage = (e) => { console.log(&#39;PostMessage 事件:&#39;, e); }; </script> <style scoped> .container { flex: 1; height: 100vh; } .loading { display: flex; justify-content: center; align-items: center; height: 100%; } </style>[Object] {"cashierHtml":"<!DOCTYPE html><html><head><meta http-equiv=\"Content-Type\" content=\"text...} at pages/bankPayment/index.vue:29 11:42:27.510 <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title></title></head><body onload="load()"><form id = "form" action="http://wap.dev.psbc.com/mobilebank/CashierDeskStart.do" method="post"><input type="hidden" name="MercName" id="MercName" value="徐州市铜山区大许镇阳光幼教幼儿园"/><input type="hidden" name="MercCode" id="MercCode" value="1100529319992199476"/><input type="hidden" name="TransAmt" id="TransAmt" value="1"/><input type="hidden" name="OrderNum" id="OrderNum" value="CPN034ez8rd7flkp10240002fzc001"/><input type="hidden" name="MercDtTm" id="MercDtTm" value="20250911114024"/><input type="hidden" name="MerCustId" id="MerCustId" value="26609"/><input type="hidden" name="Plain" id="Plain" value="{&#39;PlatMercCode&#39;:&#39;1100529319992199476&#39;,&#39;TransChannl&#39;:&#39;01&#39;,&#39;InstType&#39;:&#39;1111110&#39;,&#39;QpLtAcctType&#39;:&#39;1110&#39;,&#39;GwLtAcctType&#39;:&#39;111011&#39;,&#39;OlLtAcctType&#39;:&#39;01&#39;,&#39;MercDtTm&#39;:&#39;20250911114024&#39;,&#39;OrderNum&#39;:&#39;CPN034ez8rd7flkp10240002fzc001&#39;,&#39;MercCode&#39;:&#39;8299000007077701045&#39;,&#39;TransAmt&#39;:&#39;1&#39;,&#39;MercUrl&#39;:&#39;/esbHttpSrv/sendPostData/99100140001_OPSS_thirdpayLargeMerchants&#39;,&#39;ReSuccUrl&#39;:&#39;http://openpayment.dev.psbc.com:8080/h5xctest/h5/#/paySuccess?out_trade_no=CPN034ez8rd7flkp10240002fzc001&#39;,&#39;OrderUrl&#39;:&#39;&#39;,&#39;Remark1&#39;:&#39;&#39;,&#39;Remark2&#39;:&#39;&#39;,&#39;ValidTime&#39;:&#39;30&#39;,&#39;MercName&#39;:&#39;徐州市铜山区大许镇阳光幼教幼儿园&#39;,&#39;BizTp&#39;:&#39;110001&#39;,&#39;OrderTitle&#39;:&#39;2025年9月伙食费&#39;,&#39;OrderCount&#39;:&#39;1&#39;,&#39;OrderDetail&#39;:[{&#39;SubMercCode&#39;:&#39;8299000007077701045&#39;,&#39;SubMercName&#39;:&#39;徐州市铜山区大许镇阳光幼教幼儿园&#39;,&#39;TotalAmt&#39;:&#39;1&#39;,&#39;TotalNum&#39;:&#39;1&#39;,&#39;MerUnitDetail&#39;:&#39;2025年9月伙食费^1^1&#39;}],&#39;PlfmNm&#39;:&#39;&#39;,&#39;TrxDevcInf&#39;:&#39;ABCD:EF01:2345:6789:ABCD:EF01:2345:6789|F0E1D2C3B4A5|010102020303040|01020304050 6070|00112233445566778899|5A4B3C2D1E0F|116.123456,-39.987654|&#39;,&#39;PyeeAcctIssrId&#39;:&#39;C1040311005293&#39;,&#39;PyeeAcctTp&#39;:&#39;05&#39;,&#39;PyeeAcctId&#39;:&#39;4130130413015010001291000130&#39;,&#39;PyeeNm&#39;:&#39;昆山市假日置业有限公司&#39;,&#39;TerminalIp&#39;:&#39;127.0.0.1&#39;,&#39;MerCustId&#39;:&#39;26609&#39;,&#39;PayEnv&#39;:&#39;01&#39;,&#39;QpTranChnl&#39;:&#39;0&#39;,&#39;GwTranChnl&#39;:&#39;0&#39;,&#39;InterAcctno&#39;:&#39;4415602000739195&#39;,&#39;InterAcctOrganCode&#39;:&#39;44001483&#39;,&#39;DevOrganCode&#39;:&#39;11005293&#39;,&#39;WchatAppId&#39;:&#39;&#39;,&#39;OpenId&#39;:&#39;&#39;,&#39;ReserveParam&#39;:&#39;&#39;,&#39;CreditorWalletName&#39;:&#39;内部业务钱包青岛分行医保社保&#39;,&#39;CreditorWalletId&#39;:&#39;0082000020475894&#39;,&#39;CreditorWalletType&#39;:&#39;WT10&#39;,&#39;CreditorWalletLevel&#39;:&#39;WL01&#39;,&#39;MerCertType&#39;:&#39;&#39;,&#39;MerCerId&#39;:&#39;&#39;,&#39;TradeBizType&#39;:&#39;206&#39;,&#39;TradeCategoryCode&#39;:&#39;20600017&#39;,&#39;PhonePayEnv&#39;:&#39;&#39;,&#39;AreaInfo&#39;:&#39;120101&#39;,&#39;NativeFlag&#39;:&#39;00&#39;,&#39;PageFlag&#39;:&#39;1&#39;,&#39;AtvFlag&#39;:&#39;0&#39;,&#39;AtvID&#39;:&#39;&#39;,&#39;Reserve1&#39;:&#39;&#39;,&#39;MerAcctTp&#39;:&#39;0&#39;,&#39;MerAcctNo&#39;:&#39;963011013000078213&#39;,&#39;MerAcctName&#39;:&#39;测试客户合并&#39;,&#39;MerBankNo&#39;:&#39;&#39;,&#39;MerBankName&#39;:&#39;&#39;,&#39;QyFlag&#39;:&#39;&#39;,&#39;BusinessLicense&#39;:&#39;120101673864374&#39;}"/><input type="hidden" name="Signature" id="Signature" value="042f03f10adb90f8256892536d185d3d6375be7e27d806d59efe3e86ebeb9115abc229659064cd7b7fc4b2871406c3973f0ffaa7d61ba958b8c61bd0f4be5781665854c9f1512c52c69fa774181db9e56b2ff20b045f0d8dce67e6d746850636222d17e0d063d19e2de1b98c487632cca80c6dbde3e77a12e2b060a094f5148b"/><input type="hidden" name="OpenFlag" id="OpenFlag" value="11111101111000000000000000000000000000000000000000"/><input type="hidden" name="PayChannel" id="PayChannel" value="11"/><input type="hidden" name="QPayChannel" id="QPayChannel" value="11"/><input type="hidden" name="Flag" id="Flag" value="110100"/><input type="hidden" name="MrchntNo" id="MrchntNo" value="010650082990000"/><input type="hidden" name="MerType" id="MerType" value="8299"/><input type="hidden" name="PayValidityTime" id="PayValidityTime" value="20250911121024"/><input type="hidden" name="GlobalBusiTrackNo" id="GlobalBusiTrackNo" value="20250911114025991001430039080665"/><input type="hidden" name="SubtxNo" id="SubtxNo" value="99100143003910000000000000000000"/><input type="hidden" name="SubMercCode" id="SubMercCode" value="8299000007077701045"/><input type="hidden" name="DctDetail" id="DctDetail" value="[]"/><input type="hidden" name="NativeFlag" id="NativeFlag" value="00"/><input type="hidden" name="PageFlag" id="PageFlag" value="1"/><input type="hidden" name="CdFlag" id="CdFlag" value="21"/><input type="hidden" name="ReductionInfo" id="ReductionInfo" value=""/><input type="hidden" name="GatewayFlag" id="GatewayFlag" value="03"/></form></body><script type="text/javascript">var formDom = document.getElementById(&#39;form&#39;);function load() { formDom.submit(); }</script></html> at pages/bankPayment/index.vue:30 11:42:27.510 [Vue warn]: Unhandled error during execution of onLoad at <Index__pageId=5__pagePath="pages/bankPayment/index"__pageQuery={"cashierHtml":"<!DOCTYPE html><html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /><title></title></head><body onload=\"load()\"><form id = \"form\" action=\"http://wap.dev.psbc.com/mobilebank/CashierDeskStart.do\" method=\"post\"><input type=\"hidden\" name=\"MercName\" id=\"MercName\" value=\"徐州市铜山区大许镇阳光幼教幼儿园\"/><input type=\"hidden\" name=\"MercCode\" id=\"MercCode\" value=\"1100529319992199476\"/><input type=\"hidden\" name=\"TransAmt\" id=\"TransAmt\" value=\"1\"/><input type=\"hidden\" name=\"OrderNum\" id=\"OrderNum\" value=\"CPN034ez8rd7flkp10240002fzc001\"/><input type=\"hidden\" name=\"MercDtTm\" id=\"MercDtTm\" value=\"20250911114024\"/><input type=\"hidden\" name=\"MerCustId\" id=\"MerCustId\" value=\"26609\"/><input type=\"hidden\" name=\"Plain\" id=\"Plain\" value=\"{&#39;PlatMercCode&#39;:&#39;1100529319992199476&#39;,&#39;TransChannl&#39;:&#39;01&#39;,&#39;InstType&#39;:&#39;1111110&#39;,&#39;QpLtAcctType&#39;:&#39;1110&#39;,&#39;GwLtAcctType&#39;:&#39;111011&#39;,&#39;OlLtAcctType&#39;:&#39;01&#39;,&#39;MercDtTm&#39;:&#39;20250911114024&#39;,&#39;OrderNum&#39;:&#39;CPN034ez8rd7flkp10240002fzc001&#39;,&#39;MercCode&#39;:&#39;8299000007077701045&#39;,&#39;TransAmt&#39;:&#39;1&#39;,&#39;MercUrl&#39;:&#39;/esbHttpSrv/sendPostData/99100140001_OPSS_thirdpayLargeMerchants&#39;,&#39;ReSuccUrl&#39;:&#39;http://openpayment.dev.psbc.com:8080/h5xctest/h5/#/paySuccess?out_trade_no=CPN034ez8rd7flkp10240002fzc001&#39;,&#39;OrderUrl&#39;:&#39;&#39;,&#39;Remark1&#39;:&#39;&#39;,&#39;Remark2&#39;:&#39;&#39;,&#39;ValidTime&#39;:&#39;30&#39;,&#39;MercName&#39;:&#39;徐州市铜山区大许镇阳光幼教幼儿园&#39;,&#39;BizTp&#39;:&#39;110001&#39;,&#39;OrderTitle&#39;:&#39;2025年9月伙食费&#39;,&#39;OrderCount&#39;:&#39;1&#39;,&#39;OrderDetail&#39;:[{&#39;SubMercCode&#39;:&#39;8299000007077701045&#39;,&#39;SubMercName&#39;:&#39;徐州市铜山区大许镇阳光幼教幼儿园&#39;,&#39;TotalAmt&#39;:&#39;1&#39;,&#39;TotalNum&#39;:&#39;1&#39;,&#39;MerUnitDetail&#39;:&#39;2025年9月伙食费^1^1&#39;}],&#39;PlfmNm&#39;:&#39;&#39;,&#39;TrxDevcInf&#39;:&#39;ABCD:EF01:2345:6789:ABCD:EF01:2345:6789|F0E1D2C3B4A5|010102020303040|01020304050 6070|00112233445566778899|5A4B3C2D1E0F|116.123456,-39.987654|&#39;,&#39;PyeeAcctIssrId&#39;:&#39;C1040311005293&#39;,&#39;PyeeAcctTp&#39;:&#39;05&#39;,&#39;PyeeAcctId&#39;:&#39;4130130413015010001291000130&#39;,&#39;PyeeNm&#39;:&#39;昆山市假日置业有限公司&#39;,&#39;TerminalIp&#39;:&#39;127.0.0.1&#39;,&#39;MerCustId&#39;:&#39;26609&#39;,&#39;PayEnv&#39;:&#39;01&#39;,&#39;QpTranChnl&#39;:&#39;0&#39;,&#39;GwTranChnl&#39;:&#39;0&#39;,&#39;InterAcctno&#39;:&#39;4415602000739195&#39;,&#39;InterAcctOrganCode&#39;:&#39;44001483&#39;,&#39;DevOrganCode&#39;:&#39;11005293&#39;,&#39;WchatAppId&#39;:&#39;&#39;,&#39;OpenId&#39;:&#39;&#39;,&#39;ReserveParam&#39;:&#39;&#39;,&#39;CreditorWalletName&#39;:&#39;内部业务钱包青岛分行医保社保&#39;,&#39;CreditorWalletId&#39;:&#39;0082000020475894&#39;,&#39;CreditorWalletType&#39;:&#39;WT10&#39;,&#39;CreditorWalletLevel&#39;:&#39;WL01&#39;,&#39;MerCertType&#39;:&#39;&#39;,&#39;MerCerId&#39;:&#39;&#39;,&#39;TradeBizType&#39;:&#39;206&#39;,&#39;TradeCategoryCode&#39;:&#39;20600017&#39;,&#39;PhonePayEnv&#39;:&#39;&#39;,&#39;AreaInfo&#39;:&#39;120101&#39;,&#39;NativeFlag&#39;:&#39;00&#39;,&#39;PageFlag&#39;:&#39;1&#39;,&#39;AtvFlag&#39;:&#39;0&#39;,&#39;AtvID&#39;:&#39;&#39;,&#39;Reserve1&#39;:&#39;&#39;,&#39;MerAcctTp&#39;:&#39;0&#39;,&#39;MerAcctNo&#39;:&#39;963011013000078213&#39;,&#39;MerAcctName&#39;:&#39;测试客户合并&#39;,&#39;MerBankNo&#39;:&#39;&#39;,&#39;MerBankName&#39;:&#39;&#39;,&#39;QyFlag&#39;:&#39;&#39;,&#39;BusinessLicense&#39;:&#39;120101673864374&#39;}\"/><input type=\"hidden\" name=\"Signature\" id=\"Signature\" value=\"042f03f10adb90f8256892536d185d3d6375be7e27d806d59efe3e86ebeb9115abc229659064cd7b7fc4b2871406c3973f0ffaa7d61ba958b8c61bd0f4be5781665854c9f1512c52c69fa774181db9e56b2ff20b045f0d8dce67e6d746850636222d17e0d063d19e2de1b98c487632cca80c6dbde3e77a12e2b060a094f5148b\"/><input type=\"hidden\" name=\"OpenFlag\" id=\"OpenFlag\" value=\"11111101111000000000000000000000000000000000000000\"/><input type=\"hidden\" name=\"PayChannel\" id=\"PayChannel\" value=\"11\"/><input type=\"hidden\" name=\"QPayChannel\" id=\"QPayChannel\" value=\"11\"/><input type=\"hidden\" name=\"Flag\" id=\"Flag\" value=\"110100\"/><input type=\"hidden\" name=\"MrchntNo\" id=\"MrchntNo\" value=\"010650082990000\"/><input type=\"hidden\" name=\"MerType\" id=\"MerType\" value=\"8299\"/><input type=\"hidden\" name=\"PayValidityTime\" id=\"PayValidityTime\" value=\"20250911121024\"/><input type=\"hidden\" name=\"GlobalBusiTrackNo\" id=\"GlobalBusiTrackNo\" value=\"20250911114025991001430039080665\"/><input type=\"hidden\" name=\"SubtxNo\" id=\"SubtxNo\" value=\"99100143003910000000000000000000\"/><input type=\"hidden\" name=\"SubMercCode\" id=\"SubMercCode\" value=\"8299000007077701045\"/><input type=\"hidden\" name=\"DctDetail\" id=\"DctDetail\" value=\"[]\"/><input type=\"hidden\" name=\"NativeFlag\" id=\"NativeFlag\" value=\"00\"/><input type=\"hidden\" name=\"PageFlag\" id=\"PageFlag\" value=\"1\"/><input type=\"hidden\" name=\"CdFlag\" id=\"CdFlag\" value=\"21\"/><input type=\"hidden\" name=\"ReductionInfo\" id=\"ReductionInfo\" value=\"\"/><input type=\"hidden\" name=\"GatewayFlag\" id=\"GatewayFlag\" value=\"03\"/></form></body><script type=\"text/javascript\">var formDom = document.getElementById(&#39;form&#39;);function load() { formDom.submit(); }</script></html>"} ...> 11:42:27.510 ReferenceError: Blob is not defined
09-12
泛微OA e9 移动端自定义页面开发 Form组件如何使用 我的代码:const { observer, inject } = mobxReact const { withRouter } = ReactRouterDom const { Toast, ListView, Icon, Button, Modal } = WeaverMobile const { Form } = WeaverMobilePage @inject(&#39;detailViewStore&#39;, &#39;detailModalFormStore&#39;) @withRouter @observer class FinalInspectionDetail extends React.Component { constructor(props) { super(props) const dataSource = new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2 }) this.form = new Form.Store({ route: &#39;/finalInspection/form&#39; }) this.state = { dataSource: dataSource.cloneWithRows([]), isExpanded: false, isShowModal: false } } getQueryParams = (search) => { const params = new URLSearchParams(search); return Object.fromEntries(params.entries()); } getDetail = async () => { try { const { detailViewStore, location } = this.props const { fid } = this.getQueryParams(location.search) await detailViewStore.fetchDetailData(fid) this.updateDataSource() } catch (e) { Toast.fail(`单据详情数据获取失败:${e.msg}`, 1) } } buildData = (dataList) => { if (!dataList || dataList.length === 0) return ["empty-row"] const rowKeys = []; dataList.forEach((item, index) => { rowKeys.push(`row-${index}`) }) return rowKeys; } updateDataSource = () => { const { detailViewStore } = this.props const { summaryDetailList } = detailViewStore const rowKeys = this.buildData(summaryDetailList) const newDataSource = new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2 }) this.setState({ dataSource: newDataSource.cloneWithRows(rowKeys) }) } componentDidMount() { this.getDetail() } componentWillUnmount() { const { detailViewStore } = this.props; detailViewStore.resetStore(); } renderRow = (rowKey, sectionId, rowId) => { const { detailViewStore } = this.props const { summaryDetailList } = detailViewStore const noData = ( <div className="list-empty-container"> <Icon type=&#39;no-data&#39; size=&#39;md&#39; color=&#39;#999&#39; style={{ height: 60, width: 60 }} /> <div style={{ &#39;margin-top&#39;: 10, color: &#39;#999&#39;, &#39;font-size&#39;: 16 }}>暂无数据</div> </div> ) if ((rowKey === &#39;empty-row&#39; && (!summaryDetailList || summaryDetailList.length === 0))) return noData var item = summaryDetailList[rowId] if (!item) return <div key={rowKey || Math.random()} style={{ display: &#39;none&#39; }}></div> const seq = summaryDetailList.indexOf(item) + 1 const hasStatus = item.inspectedResult && item.inspectedResult.trim() !== &#39;&#39; try { return ( <div className="detail-summary-list-item-container" key={rowKey || Math.random()}> <div className="list-item-seq-container"> <div>{seq}</div> </div> <div className="list-item-main-container"> {/* 标题 */} <div className={`list-item-title-container ${hasStatus ? &#39;has-status&#39; : &#39;no-status&#39;}`}> <div className="list-item-mono">{item.moNo}</div> <div className="list-item-requireno">{item.requireNo}</div> { hasStatus && ( <div className="list-item-status">{item.inspectedResult}</div> )} </div> <div className="list-item-split-line"></div> {/* 主体内容 */} <div className="list-item-content-container"> <div> <div className="list-item-content-qty"> <span className="list-item-qty-label">计划数</span> <span className="list-item-qty-value">{item.moNoQty || 0}</span> </div> <div className="list-item-content-qty"> <span className="list-item-qty-label">报检数</span> <span className="list-item-qty-value">{item.finishQty || 0}</span> </div> <div className="list-item-content-qty"> <span className="list-item-qty-label">合格数</span> <span className="list-item-qty-value">{item.qualifiedQty || 0}</span> </div> <div className="list-item-content-qty"> <span className="list-item-qty-label">不合格数</span> <span className="list-item-qty-value list-item-qty-warning">{item.unQualifiedQty || 0}</span> </div> </div> <Button className="list-item-inspection-button"> <Icon type=&#39;cooperation-examination-and-approval&#39; size="xxs" color="#fff" onClick={() => this.handleInspectionRptButtonClick(item)} /> {/* data */} 报检 </Button> </div> </div> </div> ) } catch (e) { return null } } handleInspectionRptButtonClick = (data) => { const { detailModalFormStore } = this.props const { modalFormConditions } = detailModalFormStore this.form.initForm(modalFormConditions, &#39;/finalInspection/form&#39;) this.form.updateFields({ moNo: data.moNo }) this.setState({ isShowModal: true }) } handleModalMaskClose = () => { this.setState({ isShowModal: false }) } renderFormFields = () => { const { conditioninfo, isInit } = this.form console.log(conditioninfo) console.log(isInit) const fields = [] if (isInit) { conditioninfo.forEach((group) => { group.items.forEach((field) => { fields.push( <Form.Item key={field.domkey.join("_")} form={this.form} fieldConfig={field} onChange={this.form.onChange} />) }) }) } return fields } render() { const { detailViewStore } = this.props const { isExpanded } = this.state const { detailData, isLoading } = detailViewStore //报检状态 const billStatusContent = getStatusContent(detailData.inspectionDeclareStatus, FINAL_INSPECTION_STATUS_MAP) const billShowStatusContent = billStatusContent === null ? &#39;未知状态&#39; : billStatusContent const billStatusClassName = getStatusClassName(detailData.inspectionDeclareStatus, FINAL_INSPECTION_STATUS_MAP) const billShowStatusClassName = billStatusClassName === null ? &#39;status-unknown&#39; : billStatusClassName // const specClassName = detailData.materialSpec && detailData.materialSpec.trim() !== &#39;&#39; ? &#39;&#39; : &#39;empty-field&#39; const approveDateClassName = detailData.approveDate && detailData.approveDate.trim() !== &#39;&#39; ? &#39;&#39; : &#39;empty-field&#39; const createDateClassName = detailData.createDate && detailData.createDate.trim() !== &#39;&#39; ? &#39;&#39; : &#39;empty-field&#39; //报检进度 const inspectedQty = detailData.inspectedQty ? detailData.inspectedQty : 0 const totalQty = detailData.totalQty ? detailData.totalQty : 0 //单据状态 const billDocStatusContent = getStatusContent(detailData.docStatus, BILL_DOC_STATUS_MAP) const billShowDocStatusContent = billDocStatusContent === null ? &#39;未知状态&#39; : billDocStatusContent return ( <div className="detail-page-container"> {/* 单据体基本信息 */} <div className="detail-main-container"> <div className="detail-main-flex-container"> {/* 单据体header部分 */} <div className="detail-main-header"> <div className="detail-main-field"> <span className="detail-main-field-label receipt-no-label">汇报单号</span> <span className="detail-main-field-content">{detailData.billNo}</span> </div> <div className="detail-main-field"> <div style={{ &#39;font-size&#39;: &#39;14px !imprortant&#39; }}> <span className={`detail-main-field-content ${billShowStatusClassName}`}>{billShowStatusContent}</span> </div> </div> </div> {/* 单据体content部分 */} { isExpanded ? ( <div className="detail-main-content"> <div className="detail-main-field"> <span className="detail-main-field-label">产品名称:</span> <span className="detail-main-field-content">{detailData.materialName}</span> </div> <div className="detail-main-field"> <span className="detail-main-field-label">产品编号:</span> <span className="detail-main-field-content">{detailData.materialNo}</span> </div> <div className="detail-main-field"> <span className="detail-main-field-label">产品规格:</span> <span className="detail-main-field-content">{detailData.materialSpec}</span> </div> <div className="detail-main-field"> <span className="detail-main-field-label">净重(g):</span> <span className="detail-main-field-content">{detailData.netWeight}</span> </div> <div className="detail-main-field"> <span className="detail-main-field-label">单据状态:</span> <span className="detail-main-field-content">{billShowDocStatusContent}</span> </div> <div className="detail-main-field"> <span className="detail-main-field-label">审核人:</span> <div className="detail-main-field-content detail-main-field-flex-wrapper"> <span>{detailData.approverName}</span> <div className={`detail-main-field-split-line ${approveDateClassName}`}></div> <span className={`${approveDateClassName}`}>{detailData.approveDate}</span> </div> </div> <div className="detail-main-field"> <span className="detail-main-field-label">加工车间:</span> <span className="detail-main-field-content">{detailData.workShopName}</span> </div> <div className="detail-main-field"> <span className="detail-main-field-label">报检进度:</span> <span className="detail-main-field-content">{inspectedQty}/{totalQty} 个</span> </div> {/** <div className="detail-main-field"> <span className="detail-main-field-label">创建人:</span> <div className="detail-main-field-content detail-main-field-flex-wrapper"> <span>{detailData.creatorName}</span> <div className={`detail-main-field-split-line ${createDateClassName}`}></div> <span className={`${createDateClassName}`}>{detailData.createDate}</span> </div> </div> */} </div> ) : ( <div className="detail-main-content"> <div className="detail-main-field"> <span className="detail-main-field-label">产品名称:</span> <span className="detail-main-field-content">{detailData.materialName}</span> </div> <div className="detail-main-field"> <span className="detail-main-field-label">产品编号:</span> <div className="detail-main-field-content detail-main-field-flex-wrapper"> <span>{detailData.materialNo}</span> <div className={`detail-main-field-split-line ${specClassName}`}></div> <span className={`${specClassName}`}>{detailData.materialSpec}</span> </div> </div> <div className="detail-main-field"> <span className="detail-main-field-label">加工车间:</span> <span className="detail-main-field-content">{detailData.workShopName}</span> </div> <div className="detail-main-field"> <span className="detail-main-field-label">报检进度:</span> <span className="detail-main-field-content">{inspectedQty}/{totalQty} 个</span> </div> </div> ) } </div> {/* 详情扩展箭头 */} <div className={`expand-arrow ${isExpanded ? &#39;expanded&#39; : &#39;&#39;}`} onClick={() => this.setState({ isExpanded: !isExpanded })} /> </div> {/* 单据体汇总明细 */} <div className="detail-summary-title">生产订单</div> <div className="detail-summary-list-container"> <ListView ref={el => this.lv = el} dataSource={this.state.dataSource} renderRow={this.renderRow} style={{ height: &#39;100%&#39; }} /> </div> {/* 底部弹窗 */} <Modal visible={this.state.isShowModal} popup maskClosable={true} onClose={this.handleModalMaskClose} animationType="slide-up" > <div>111</div> {this.renderFormFields()} </Modal> </div> ) } } ecodeSDK.exp(FinalInspectionDetail) const { observable, action } = mobx class DetailModalFormStore { @observable modalFormConditions = [ { groupName: &#39;报检信息&#39;, items: [ { domkey: [&#39;moNo&#39;], label: &#39;生产订单号&#39;, type: &#39;input&#39;, rule: { required: true, message: &#39;请输入生产订单号&#39; }, disabled: true, } ] }, ] } const detailModalFormStore = new DetailModalFormStore() 为什么我的Form内 Form.Item项无法渲染 div可以渲染
最新发布
12-27
<template> <view class="form-item"> <text class="label">作业日期</text> <cu-datetime-picker class="date-container" fields="day" placeholder="请选择作业日期" @change="timeStartChange"/> </view> <view class="form-item"> <text class="label">备注</text> <uni-easyinput type="textarea" v-model="remark" placeholder="请输入" /> </view> <view class="form-item" @click="gotoSelectPerson"> <text class="label">协助人</text> <input type="text" v-model="helper" placeholder="请选择协助人" readonly class="input-helper" @click="gotoSelectPerson" /> </view> <view class="form-item"> <view class="btn-group"> <button class="btn-select" @click="addPipeWeld">添加焊缝</button> </view> </view> <scroll-view scroll-y class="data-list" > <view v-for="(item, index) in weldingDataList" :key="index" class="data-item"> <button class="btn-close" @click="deleteWeldingRow(index)"> <text class="icon">✕</text> </button> <view class="main-content"> <view class="header-row"> <view class="info-group"> <view class="label-row"> <text>项目号:{{ item.projectNo }}</text> </view> <view class="info-row"> <text>管号: {{ item.pipeNo }}</text> <text>版本号: {{ item.pipeVersion }}</text> </view> <view class="info-row"> <text>焊缝号: {{ item.weldNo }}</text> </view> <view class="info-row"> <text style="margin-top: 1rem; margin-right: -0.5rem">WPS NO:</text> <view class="batch-selector-container" @click="handleWpsNoClick(item, index)"> <text>{{ item.wpsNo || &#39;请选择&#39; }}</text> </view> </view> <view class="info-row"> <text style="margin-top: 0.5rem">焊接方法: {{ item.weldProcess }}</text> </view> <view class="info-row"> <text style="margin-top: 0.5rem">焊材规格: {{ item.weldingMatSpec }}</text> </view> <view class="info-row"> <text style="margin-top: 1rem; margin-right: -0.5rem">批号:</text> <view class="batch-selector-container" @click="openBatchSelector(item, index)"> <text>{{ item.rootBatchNo || &#39;请选择&#39; }} - {{ item.fillBatchNo || &#39;请选择&#39; }}</text> </view> </view> <view class="info-row"> <text style="margin-top: 0.5rem">证书号: {{ item.rootWeldCert }} - {{ item.fillWeldCert }}</text> </view> </view> <view class="btn-pipe-group"> <uni-button size="mini" type="warn" @click.stop="reportAbnormal(index)">异常上报</uni-button> </view> </view> </view> </view> </scroll-view> <view class="footer"> <button v-if="!isSelected" class="submit-btn" @click="submitForm">提交</button> </view> <cu-modal :visible="isShowModal" title="异常上报" @cancel="hideModal" @ok="submitModal(currentRowIndex)"> <uni-forms ref="baseForm" :modelValue="exceptionParams"> <uni-forms-item label="异常类型" required name="exceptionType" :label-width="80" style="flex: 0 0 30%;"> <uni-data-select v-model="exceptionParams.exceptionType" :localdata="formattedExceptionTypeList" /> </uni-forms-item> <uni-forms-item label="异常描述" required name="exceptionMsg" :label-width="80" style="flex: 0 0 30%;"> <uni-easyinput type="textarea" v-model="exceptionParams.exceptionMsg"/> </uni-forms-item> </uni-forms> </cu-modal> <uni-popup ref="batchPopup" type="bottom" background-color="#fff" @maskClick="handlePopupClose"> <view class="popup-content"> <view class="popup-header"> <text class="popup-title">选择批号</text> <text class="popup-close" @click="closeBatchPopup">关闭</text> </view> <!-- 添加搜索框 --> <view class="search-bar"> <uni-easyinput placeholder="输入批号查询" v-model="batchSearchText" @input="filterBatchList" prefixIcon="search" /> </view> <view class="popup-body"> <view class="picker-item"> <text>根批号:</text> <picker :range="filteredRootBatchList" @change="onRootBatchChange"> <view class="picker">{{ currentRootBatch || &#39;请选择根批号&#39; }}</view> </picker> </view> <view class="picker-item"> <text>填充批号:</text> <picker :range="filteredFillBatchList" @change="onFillBatchChange"> <view class="picker">{{ currentFillBatch || &#39;请选择填充批号&#39; }}</view> </picker> </view> </view> <view class="popup-footer"> <button @click="confirmBatchSelection">确定</button> </view> </view> </uni-popup> </template> <script setup> import {ref, onMounted, computed, watch} from &#39;vue&#39; import * as serve from &#39;@/api/modules/piping/pre/prePipeFeedBack&#39; import {useRoute,useRouter} from &#39;vue-router&#39; import {getDislist} from "@/api/modules/piping/handover"; const router = useRouter() const route = useRoute() const currentRowIndex = ref(null) const orderNo = ref(&#39;&#39;) const workDate = ref(&#39;&#39;) const remark = ref(&#39;&#39;) const weldingDataList = ref([]) const rootBatchNoDataList = ref([]) const fillBatchNoDataList = ref([]) const currentWeldingItemIndex = ref(null) const rootCerNoList = ref([]) const fillCertNoList = ref([]) const exceptionTypeList = ref([]) const isShowModal = ref(false) const exceptionParams = ref({ exceptionType: &#39;&#39;, exceptionMsg: &#39;&#39; }) const process = ref(&#39;&#39;) const helper = ref(&#39;&#39;) const orgNo = ref(&#39;&#39;) const batchPopup = ref(null) const currentBatchItem = ref(null) const currentBatchIndex = ref(null) const currentRootBatch = ref(&#39;&#39;) const currentFillBatch = ref(&#39;&#39;) const isSelected = ref(false) const batchSearchText = ref(&#39;&#39;) const filteredRootBatchList = ref([]) const filteredFillBatchList = ref([]) watch(() => router.currentRoute.value.path, (newPath, oldPath) => { console.log(&#39;newPath&#39;, newPath) console.log(&#39;oldPath&#39;, oldPath) if (oldPath == &#39;/pages/piping/pre/preFeedBackWeldDetail&#39; && newPath != &#39;/pages/piping/pre/selectWpsNo&#39; && newPath != &#39;/pages/piping/pre/selectPerson&#39;) { weldingDataList.value = [] workDate.value = &#39;&#39; remark.value = &#39;&#39; helper.value = &#39;&#39; } }, {immediate: true, deep: true}); onMounted(() => { orderNo.value = route.query.orderNo orgNo.value = route.query.orgNo const data = uni.getStorageSync(&#39;preAddPersons&#39;) if (data && data.length > 0) { helper.value = data[0].userCode + &#39;-&#39; + data[0].userName uni.removeStorageSync(&#39;preAddPersons&#39;) } uni.$on(&#39;preSelectedWeldToAdd&#39;, (data) => { const newWeldItems = data.filter(newItem => { return !weldingDataList.value.some(existingItem => existingItem.projectNo === newItem.projectNo && existingItem.pipeNo === newItem.pipeNo && existingItem.pipeVersion === newItem.pipeVersion && existingItem.weldNo === newItem.weldNo ) }).map(item => ({ ...item, rootBatchNo: &#39;&#39;, fillBatchNo: &#39;&#39;, rootWeldCert: &#39;&#39;, fillWeldCert: &#39;&#39;, rootGrade: &#39;&#39;, fillGrade: &#39;&#39; })); weldingDataList.value.push(...newWeldItems) uni.removeStorageSync(&#39;preSelectedWeldToAdd&#39;) }) uni.$on(&#39;preSelectedWpsNo&#39;, (data) => { if (Array.isArray(data) && data.length > 0 && currentWeldingItemIndex.value !== null) { const currentIndex = currentWeldingItemIndex.value if (currentIndex >= 0 && currentIndex < weldingDataList.value.length) { weldingDataList.value[currentIndex].wpsNo = data[0].wpsNo weldingDataList.value[currentIndex].weldProcess = data[0].process weldingDataList.value[currentIndex].weldingMatSpec = data[0].type weldingDataList.value[currentIndex].rootGrade = data[0].rootGrade weldingDataList.value[currentIndex].fillGrade = data[0].fillGrade } } uni.removeStorageSync(&#39;preSelectedWpsNo&#39;) }) getDislist({code: "CP_EXCEPTION_TYPE"}).then((res) => { if (res.status === 200) { exceptionTypeList.value = res.data || [] } }) }) const filterBatchList = () => { if (!batchSearchText.value) { filteredRootBatchList.value = [...rootBatchNoDataList.value] filteredFillBatchList.value = [...fillBatchNoDataList.value] return } const searchTerm = batchSearchText.value.toLowerCase() filteredRootBatchList.value = rootBatchNoDataList.value.filter( batch => batch.toLowerCase().includes(searchTerm) ) filteredFillBatchList.value = fillBatchNoDataList.value.filter( batch => batch.toLowerCase().includes(searchTerm) ) } const handleRootBatchNoClick = async (item) => { serve.getQcWeldMatSnDropList({grade: item.rootGrade}).then((res) => { const rootPairs = (res.data || []).map(item => ({ batchNo: item.batchNo, weldCert: item.certNo })) rootBatchNoDataList.value = rootPairs.map(p => p.batchNo) rootCerNoList.value = rootPairs console.log(rootBatchNoDataList, rootCerNoList) }) } const handleFillBatchNoClick = async (item) => { serve.getQcWeldMatSnDropList({grade: item.fillGrade}).then((res) => { const fillPairs = (res.data || []).map(item => ({ batchNo: item.batchNo, weldCert: item.certNo })) fillBatchNoDataList.value = fillPairs.map(p => p.batchNo) fillCertNoList.value = fillPairs }) } const handleWpsNoClick = (item, index) => { currentWeldingItemIndex.value = index console.log(&#39;currentWeldingItemIndex&#39;, currentWeldingItemIndex.value) uni.navigateTo({ url: &#39;/pages/piping/pre/selectWpsNo?weldId=&#39; + item.id }) } const gotoSelectPerson = () => { // 打开选择弹窗 uni.navigateTo({ url: &#39;/pages/piping/pre/selectPerson?isHelper=&#39; + &#39;Y&#39; }) } const formattedExceptionTypeList = computed(() => { return exceptionTypeList.value.map(item => { return { value: item.name, text: item.name } }) }) const addPipeWeld = () => { uni.navigateTo({ url: &#39;/pages/piping/pre/selectWeld?orderNo=&#39; + orderNo.value }) } const timeStartChange = (value) => { if (value) { workDate.value = `${value.YYYY}-${value.MM}-${value.DD}` console.log(&#39;workDate&#39;, workDate.value) } } const deleteWeldingRow = (index) => { weldingDataList.value.splice(index, 1) } const reportAbnormal = (index) => { exceptionParams.value = { exceptionType: &#39;&#39;, exceptionMsg: &#39;&#39; } currentRowIndex.value = index isShowModal.value = true } const hideModal = () => { isShowModal.value = false } const submitModal = (index) => { const item = weldingDataList.value[index]; const params = exceptionParams.value; if (!params.exceptionType) { uni.showToast({ title: &#39;请选择异常类型&#39;, icon: &#39;none&#39; }); return; } if (!params.exceptionMsg) { uni.showToast({ title: &#39;请输入异常描述&#39;, icon: &#39;none&#39; }); return; } const submitData = [{ projectNo: item.projectNo, orgNo: orgNo.value, bomNo: item.pipeNo, bomVersion: item.pipeVersion, exceptionType: params.exceptionType, exceptionMsg: params.exceptionMsg }] serve.saveException(submitData).then(res => { uni.showToast({ title: &#39;提交成功&#39;, icon: &#39;success&#39; }) isShowModal.value = false }).catch(err => { uni.showToast({ title: &#39;提交失败&#39;, icon: &#39;none&#39; }); console.error(&#39;提交异常:&#39;, err); }) } const submitForm = () => { if (!workDate.value) { uni.showToast({title: &#39;请输入作业日期&#39;, icon: &#39;none&#39;}) return } if (!weldingDataList.value && weldingDataList.value.length == 0) { uni.showToast({title: &#39;请选择焊缝&#39;, icon: &#39;none&#39;}) return } const data = { orderNo: orderNo.value, process: process.value, workDate: workDate.value, remark: remark.value, helperNo: helper.value.split(&#39;-&#39;)[0], weldList: weldingDataList.value } serve.weldingFeedback(data).then((res) => { if (res.status === 200) { uni.showToast({title: &#39;提交成功&#39;, icon: &#39;none&#39;}) setTimeout(() => { uni.navigateBack() weldingDataList.value = [] }, 1000) } }) } const openBatchSelector = (item, index) => { batchSearchText.value = &#39;&#39; currentBatchItem.value = item currentBatchIndex.value = index currentRootBatch.value = item.rootBatchNo currentFillBatch.value = item.fillBatchNo handleRootBatchNoClick(item) handleFillBatchNoClick(item) isSelected.value = true batchPopup.value.open() filterBatchList() } const closeBatchPopup = () => { batchPopup.value.close() } const onRootBatchChange = (e) => { const index = e.detail.value currentRootBatch.value = rootBatchNoDataList.value[index] } const onFillBatchChange = (e) => { const index = e.detail.value currentFillBatch.value = fillBatchNoDataList.value[index] } const confirmBatchSelection = () => { currentBatchItem.value.rootBatchNo = currentRootBatch.value currentBatchItem.value.fillBatchNo = currentFillBatch.value const rootCertItem = rootCerNoList.value.find(i => i.batchNo === currentRootBatch.value) currentBatchItem.value.rootWeldCert = rootCertItem?.weldCert || &#39;&#39; const fillCertItem = fillCertNoList.value.find(i => i.batchNo === currentFillBatch.value) currentBatchItem.value.fillWeldCert = fillCertItem?.weldCert || &#39;&#39; isSelected.value = false closeBatchPopup() } const handlePopupClose = () => { isSelected.value = false } </script> <style scoped lang="scss"> .data-list { background-color: #f9f9f9; border-radius: 8rpx; margin-bottom: 40rpx; max-height: 950rpx; overflow-y: auto; } .data-item { margin-bottom: 20rpx; background-color: white; border-radius: 6rpx; padding: 20rpx; position: relative; /* 确保相对定位,使绝对定位的叉号正确显示 */ } .btn-pipe-container { display: flex; justify-content: flex-end; } .btn-pipe-group { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; } .btn-group { display: flex; } .main-content { padding-top: 40rpx; } .header-row { display: flex; justify-content: space-between; align-items: flex-start; /* 顶部对齐 */ position: relative; } .info-group { flex: 1; } .label-row { display: flex; gap: 20rpx; font-size: 24rpx; color: #666; flex-wrap: wrap; margin-bottom: 5rpx; } .info-row { display: flex; gap: 20rpx; font-size: 24rpx; color: #333; } .form-item { display: flex; align-items: center; margin-bottom: 50rpx; } .label { width: 160rpx; font-size: 28rpx; color: #333; margin-left: 20rpx; } .date-container { margin-top: 0.7rem; height: 60rpx; font-size: 28rpx; } .btn-group { display: flex; gap: 20rpx; } .btn-select, .btn-add, .btn-view { font-size: 24rpx; margin-left: 20rpx; } .btn-select { background-color: #007aff; color: #f0f0f0; } .btn-add { background-color: #007aff; color: #f0f0f0; } .btn-close { position: absolute; top: 0; right: 0; width: 30rpx; height: 30rpx; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 20rpx; border: none; margin: 5rpx; } .btn-view { background-color: #007aff; color: #f0f0f0; } .footer { position: fixed; bottom: 0; left: 0; right: 0; background-color: #fff; box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.1); z-index: 999; } .submit-btn { background-color: #007aff; color: white; border: none; font-size: 28rpx; width: 100%; } .batch-selector-container { display: flex; align-items: center; margin-top: 0.5rem; padding: 8px 12px; border: 1px solid #dcdfe6; border-radius: 4px; background-color: #f5f7fa; min-width: 107px; } .popup-content { padding: 20px; background: #fff; border-top-left-radius: 10px; border-top-right-radius: 10px; } .popup-header { display: flex; justify-content: space-between; align-items: center; padding-bottom: 15px; border-bottom: 1px solid #eee; } .popup-title { font-size: 16px; font-weight: bold; } .popup-close { color: #007aff; } .popup-body { padding: 20px 0; } .picker-item { margin-bottom: 20px; text { display: block; margin-bottom: 8px; font-size: 14px; } } .picker { padding: 10px; border: 1px solid #ddd; border-radius: 4px; } .popup-footer { display: flex; justify-content: center; button { width: 80%; background-color: #007aff; color: white; border-radius: 4px; } } </style> 为什么const gotoSelectPerson = () => { // 打开选择弹窗 uni.navigateTo({ url: ‘/pages/piping/pre/selectPerson?isHelper=’ + ‘Y’ }) } 后watch(() => router.currentRoute.value.path, (newPath, oldPath) => { console.log(‘newPath’, newPath) console.log(‘oldPath’, oldPath) } 第一次是:newPath /pages/piping/pre/selectPerson preFeedBackWeldDetail.vue:176 oldPath /pages/piping/pre/preFeedBackWeldDetail 的同时又变成了newPath /pages/piping/pre/selectPerson preFeedBackWeldDetail.vue:176 oldPath /pages/piping/pre/selectPerson
10-28
<template> <div class="container" v-loading="loading"> <!-- 搜索条件卡片 --> <div class="card"> <div class="card-title">搜索条件</div> <div class="search-item"> <div class="input-wrapper"> <span class="icon">🔍</span> <input class="search-input" placeholder="产品货号" type="text" v-model="productCode" /> </div> </div> <div class="search-item"> <div class="input-wrapper"> <span class="icon">🔍</span> <input class="search-input" placeholder="组织名称" type="text" v-model="orgName" /> </div> </div> <div class="search-item"> <div class="input-wrapper"> <span class="icon">🔍</span> <input class="search-input" placeholder="仓库名称" type="text" v-model="warehouseName" /> </div> </div> </div> <!-- 操作按钮 --> <div class="card"> <div class="button-container"> <button class="btn query-btn" @click="submitData">🔍 查询</button> <button class="btn clear-btn" @click="onClear">🧹 清空</button> </div> </div> <!-- 弹窗组件 --> <DataModal :visible.sync="showDialog" :dataList="resultList" /> </div> </template> <script> import DataModal from "./DataModal.vue"; export default { name: "StockSearch", components: { DataModal }, data() { return { productCode: "", orgName: "", warehouseName: "", resultList: [], showDialog: false, loading: false }; }, mounted() { let meta = document.querySelector(&#39;meta[name="viewport"]&#39;); if (!meta) { meta = document.createElement("meta"); meta.name = "viewport"; meta.content = "width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"; document.head.appendChild(meta); } }, methods: { onClear() { this.productCode = ""; this.orgName = ""; this.warehouseName = ""; }, async submitData() { this.loading = true; if (!this.productCode && !this.orgName && !this.warehouseName) { this.$message({ message: "请至少输入一个查询条件", type: "warning" }); this.loading = false; return; } const param = [ { type: "Map", name: "syncArg", value: { objectData: { productCode: this.productCode, warehouseName: this.warehouseName, orgName: this.orgName } } } ]; FxUI.userDefine .call_controller("CstmCtrl_B2xed__c", param) .then((res) => { if (!res) return (this.loading = false); const code = res.Value.functionResult.code; if (code != 1) { this.$alert("接口请求失败,请联系管理员!", "错误提示", { confirmButtonText: "确定", type: "error" }); this.loading = false; return; } this.resultList = res.Value.functionResult.data; this.showDialog = true; }) .catch(() => { this.$alert("请求错误,请联系管理员处理", "错误提示", { confirmButtonText: "确定", type: "error" }); }) .finally(() => { this.loading = false; }); } } }; </script> <style scoped> .container { min-height: 100vh; padding: 16px; background-color: #f5f5f5; box-sizing: border-box; } .card { background-color: #fff; padding: 16px; margin-bottom: 16px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* 新增关键样式 */ min-height: auto; /* 确保高度自适应 */ display: flex; flex-direction: column; gap: 16px; /* 使用gap替代margin-bottom,更可靠 */ } .card-title { font-weight: bold; margin-bottom: 0; /* 改用gap控制间距 */ font-size: 16px; /* 明确字体大小 */ line-height: 1.4; } .search-item { /* 移除原来的 margin-bottom: 12px; */ /* 改用父容器的gap控制间距 */ min-height: 44px; /* 为触摸操作提供足够高度 */ } .input-wrapper { display: flex; align-items: center; border: 1px solid #ddd; border-radius: 6px; padding: 12px; /* 增加内边距,提供更好的触摸区域 */ background-color: #fafafa; min-height: 44px; /* 标准的触摸目标高度 */ box-sizing: border-box; } .icon { margin-right: 8px; font-size: 16px; /* 明确图标大小 */ } .search-input { flex: 1; border: none; outline: none; background: transparent; font-size: 14px; line-height: 1.4; /* 明确行高 */ min-height: 20px; /* 确保输入框有最小高度 */ } .button-container { display: flex; gap: 12px; justify-content: center; flex-wrap: nowrap; /* 确保按钮在一行显示 */ } .btn { padding: 12px 24px; /* 增加按钮内边距 */ border: none; border-radius: 6px; cursor: pointer; font-size: 14px; min-height: 44px; /* 标准触摸高度 */ flex: 1; /* 按钮平均分配宽度 */ display: flex; align-items: center; justify-content: center; gap: 8px; } .query-btn { background-color: #5a8de0; color: #fff; } .clear-btn { background-color: #f16a55; color: #fff; } .btn:active { box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); transform: translateY(2px); } /* 针对小米手机的特定修复 */ @media screen and (-webkit-min-device-pixel-ratio: 0) { .card { gap: 16px !important; /* 强制间距 */ } .input-wrapper { min-height: 44px !important; } } /* 确保所有元素正确渲染 */ * { -webkit-tap-highlight-color: transparent; /* 移除点击高亮 */ -webkit-font-smoothing: antialiased; /* 字体抗锯齿 */ } /* 防止flex项被压缩 */ .search-item { flex-shrink: 0; } </style>
12-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值