// 验证码模块封装(王华)
const CaptchaModule = (function(){
let captchaText = '';
function generateCaptchaImage(text) {
const canvas = document.createElement('canvas');
canvas.width = 100;
canvas.height = 40;
const ctx = canvas.getContext('2d');
// 背景
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 绘制文字
ctx.font = '24px Arial';
ctx.textBaseline = 'middle';
for (let i = 0; i < text.length; i++) {
const x = 20 + i * 18;
const y = 20 + (Math.random() * 10 - 5);
ctx.save();
ctx.translate(x, y);
ctx.rotate((Math.random() * 0.5) - 0.25);
ctx.fillStyle = `rgb(${Math.random()*150},${Math.random()*150},${Math.random()*150})`;
ctx.fillText(text[i], 0, 0);
ctx.restore();
}
// 干扰线
for (let i = 0; i < 4; i++) {
ctx.strokeStyle = `rgb(${Math.random()*255},${Math.random()*255},${Math.random()*255})`;
ctx.beginPath();
ctx.moveTo(Math.random()*canvas.width, Math.random()*canvas.height);
ctx.lineTo(Math.random()*canvas.width, Math.random()*canvas.height);
ctx.stroke();
}
return canvas.toDataURL('image/png');
}
function loadCaptcha() {
fetch('https://zhxy.ynsgqfgx.com/yngqfgx/login/getVerCode').then(res => res.json()).then(data => {
captchaText = aesMinDecrypt("ABCDEFGHIJKL_key", "ABCDEFGHIJKLM_iv", data.message.vercode);
document.getElementById('captchaImg').src = generateCaptchaImage(captchaText);
});
}
// 模拟获取底部html返回(王华)
function getMockFooterHtml() {
return `
隐私声明
使用条款
© 2026 诺申科技 · eoasys.com
`;
}
function loadLoginPageFooterHtml() {
const container = document.getElementById('login_page_footer');
if (!container) {
return;
}
// 模拟底部版权信息返回
const USE_MOCK = false;
if (USE_MOCK) {
container.innerHTML = getMockFooterHtml();
return;
}
fetch('https://zhxy.ynsgqfgx.com/yngqfgx/login/getLoginFooterHtml', {
method: 'GET'
})
.then(res => res.json())
.then(res => {
if (res.success && res.data) {
container.innerHTML = res.data;
}
})
.catch(err => {
console.error('加载footer失败', err);
});
}
function validateCaptcha(inputValue) {
return inputValue.toUpperCase() === captchaText.toUpperCase();
}
return {
init: function() {
loadCaptcha();
loadLoginPageFooterHtml();
document.getElementById('captchaImg').addEventListener('click', loadCaptcha);
},
validate: validateCaptcha,
refresh: loadCaptcha
};
})();
$(function(){
//密码不允许输入中文(王华)
$.extend($.fn.validatebox.defaults.rules, {
noChinese: {
validator: function (value) {
return !/[\u4E00-\u9FFF\u3400-\u4DBF\uF900-\uFAFF']/.test(value);
},
message: '密码不允许输入中文'
}
});
$('#password').passwordbox({
onChange: function (newValue) {
let containsChinese = /[\u4E00-\u9FFF\u3400-\u4DBF\uF900-\uFAFF']/.test(newValue);// 检测是否包含中文或反引号
if (containsChinese) {
$(this).passwordbox('validate');
}
}
});
showLoginReason(login_AttentionInfo);
// 显示验证码
$('#vcode').textbox({
label: '
',
labelWidth: 100,
labelPosition: "after",
labelAlign: "right"
});
// 初始化验证码模块
CaptchaModule.init();
$('#username').textbox().next('span').find('input').focus();
})
// (王华)浏览器密码管理器支持:在 EasyUI 完全渲染后,设置内部 input 的 autocomplete
// 确保 Chrome 能检测到这些可见输入框,从而支持保存密码和账号列表
// 注意:只设置 autocomplete 属性,不绑定额外事件,避免干扰 EasyUI 内部值管理
$(window).on('load', function() {
var $unInner = $('#username').textbox('textbox');
var $pwInner = $('#password').passwordbox('textbox');
if ($unInner.length) {
$unInner.attr('autocomplete', 'username');
}
if ($pwInner.length) {
$pwInner.attr('autocomplete', 'current-password');
}
// Chrome 自动填充完成后,轮询检测原生 input 的值变化并同步到 EasyUI
// 使用 detach 方式:在 EasyUI input 上监听 autofill 专用事件
var autofillTimer = setInterval(function() {
var $un = $('#username').textbox('textbox');
var $pw = $('#password').passwordbox('textbox');
var nativeUn = document.getElementById('native_un');
var nativePw = document.getElementById('native_pw');
if (nativeUn && nativeUn.value) {
var easyVal = $('#username').textbox('getValue');
if (nativeUn.value !== easyVal) {
$('#username').textbox('setValue', nativeUn.value);
}
}
if (nativePw && nativePw.value) {
var easyVal = $('#password').passwordbox('getValue');
if (nativePw.value !== easyVal) {
$('#password').passwordbox('setValue', nativePw.value);
}
}
// 检测到表单有值后停止轮询
if ($('#username').textbox('getValue') && $('#password').passwordbox('getValue')) {
clearInterval(autofillTimer);
}
}, 300);
});
// ========== 浏览器密码管理器支持:表单提交 ==========
function handleLogin(event) {
// 将 EasyUI 组件中的值同步到隐藏的原生 input(Chrome 检测密码提交的依据)
var uname = $('#username').textbox('getValue');
var pwd = $('#password').passwordbox('getValue');
$('#native_un').val(uname);
$('#native_pw').val(pwd);
// 执行现有的加密登录逻辑(AJAX)
login();
// 阻止浏览器默认表单提交(登录仍由 AJAX 完成)
event.preventDefault();
return false;
}
function enterFunction(){
login();
}
//验证码输入框(王华)
var inputs;
var timeout;
var suButton;
// 防抖(王华)
function debounce(func, delay) {
clearTimeout(timeout);
timeout = setTimeout(func, delay);
}
// 处理信息加密(王华)
function aesEncrypt(data) {
const key = "ABCDEFGHIJKL_key";
const iv = "ABCDEFGHIJKLM_iv";
const result = {};
for (const prop in data) {
if (data.hasOwnProperty(prop)) {
result[prop] = aesMinEncrypt(key, iv, data[prop]);
}
}
return result;
}
// AES 解密(王华)
function aesMinDecrypt(key, iv, encrypted) {
var _key = CryptoJS.enc.Utf8.parse(key),
_iv = CryptoJS.enc.Utf8.parse(iv);
var decrypted = CryptoJS.AES.decrypt(encrypted, _key, {
iv: _iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
// AES 加密(王华)
function aesMinEncrypt(key, iv, word){
var _word = CryptoJS.enc.Utf8.parse(word),
_key = CryptoJS.enc.Utf8.parse(key),
_iv = CryptoJS.enc.Utf8.parse(iv);
var encrypted = CryptoJS.AES.encrypt(_word, _key, {
iv: _iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
}
// 后端验证登录信息(王华)
function requestLogin(url, data) {
$.ajax({
type: "post",
url: url,
// data: { username: data.username, password: data.password },
data: data,
dataType: "json",
success: function (result) {
if (result.success) {
if (result.smsVerCodeFlag && result.phoneNumber){
$("#phoneNumber").html(result.phoneNumber);
openCodeInput(data)
}else {
if (result.eoatoken) {
// 设置名为 "EOA_TOKEN" 的 Cookie,有效期为 30 天
PCPage.setCookie("EOA_TOKEN", result.eoatoken, 30);
}
location.href = login_RedirectUrl;
}
} else {
showLoginReason(result.message);
CaptchaModule.refresh();
}
},
error: function () {
showLoginReason("登录失败,请重试!");
CaptchaModule.refresh();
}
});
}
// 检测输入手机验证码(王华)
function checkPhoneCode(username, password) {
const isFilled = inputs.toArray().every(input => $(input).val().length > 0);
if (isFilled) {
codeValue = inputs.toArray().map(input => $(input).val()).join('');
showLoginReason("系统正在验证,请稍后......");
$("#inputTips").html('');
// 加密验证码并请求验证
const data = aesEncrypt({ captcha: codeValue });
$.ajax({
type: "post",
url: "https://zhxy.ynsgqfgx.com/yngqfgx/login/checkSMSCode",
data: { loginname: username, password: password, captcha: data.captcha },
dataType: "json",
beforeSend: function() {
$("#inputTips").html('系统正在验证,请稍后......');
},
success: function(result){
if (result.success) {
PCPage.setCookie("EOA_TOKEN", result.eoatoken, 30);
location.href=login_RedirectUrl;
}else if (result.errcode === 1) {
//验证码输入错
$("#inputTips").html(result.message);
inputs.val('');
inputs[0].focus();
showLoginReason(result.message);
}else if (result.errcode === 2) {
//验证码超时
$("#inputTips").html(result.message);
setTimeout(()=>{
inputs.val('');
$('.input_code').fadeOut().css('display', 'none');
},1500)
showLoginReason(result.message);
}else {
//其他错误
inputs.val('');
$('.input_code').fadeOut().css('display', 'none');
showLoginReason(result.message);
}
}
});
} else {
showLoginReason("请输入手机验证码");
}
}
function showLoginReason(info) {
$("#login_error").html(info);
}
//打开手机验证码输入(王华)
function openCodeInput(loginData) {
$('.input_code').fadeIn().css('display','flex');
inputs = $('.verification-code-input input');
suButton = $('#submitButton');
inputs[0].focus();
//聚焦光标顺移
inputs.on('input', function(e) {
const value = $(this).val();
if (value.length === 1) {
if ($(this).index() < inputs.length - 1) {
debounce(() => {
inputs.eq($(this).index() + 1).focus();
}, 10);
} else {
$(this).blur();
}
}
checkPhoneCode(loginData.loginname, loginData.password);
});
//回退删除
inputs.on('keydown', function(e) {
if (e.key === 'Backspace') {
if ($(this).val().length === 0 && $(this).index() > 0) {
inputs.eq($(this).index() - 1).focus();
}
}
checkPhoneCode(loginData.loginname, loginData.password);
});
//复制粘贴
$(document).on('paste', function(e) {
e.preventDefault();
const pastedData = e.originalEvent.clipboardData.getData('text');
const digits = pastedData.match(/\d/g);
if (digits) {
let i = 0;
inputs.each(function() {
if (digits[i]) {
$(this).val(digits[i]);
i++;
}
});
}
checkPhoneCode(loginData.loginname, loginData.password);
});
}
function login(url) {
//接收输入账号密码(必须通过 EasyUI API 取值,原始 input 已被隐藏)
let username = $('#username').textbox('getValue');
let password = $('#password').passwordbox('getValue');
let vcode = $("#vcode").textbox("getValue");
//验证输入
if (Tools.isEmptyString(username)) {
showLoginReason("请输入登录账号!");
return false;
}
if (Tools.isEmptyString(password)) {
showLoginReason("请输入登录密码!");
return false;
}
if (Tools.isEmptyString($("#vcode").textbox("getValue"))) {
showLoginReason("请输入验证码!");
return false;
}
if (!CaptchaModule.validate($("#vcode").textbox("getValue"))) {
showLoginReason("验证码不正确!");
CaptchaModule.refresh();
return false;
}
if(Tools.isEmptyString(url)) {
url = "https://zhxy.ynsgqfgx.com/yngqfgx/login/login?";
} else {
url = url;
}
//开始加密并请求登录
showLoginReason("系统正在验证,请稍后......");
const data = aesEncrypt({ username: username, password: password, captcha: vcode });
requestLogin(url, data)
}