HanvonAttendanceService/device-api-dump/add_member.html

1416 lines
51 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<link href="resources/plugins/bootstrap-3.3.0/css/bootstrap.min.css" rel="stylesheet"/>
<link href="resources/plugins/material-design-iconic-font-2.2.0/css/material-design-iconic-font.min.css" rel="stylesheet"/>
<link href="resources/plugins/bootstrap-table-1.17.0/bootstrap-table.min.css" rel="stylesheet"/>
<link href="resources/plugins/waves-0.7.5/waves.min.css" rel="stylesheet"/>
<link href="resources/plugins/jquery-confirm/jquery-confirm.min.css" rel="stylesheet"/>
<link href="resources/css/common.css" rel="stylesheet"/>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
margin: 0;
}
.AdduserDialog {
height: 100vh;
overflow-y: auto;
display: flex;
flex-direction: column;
flex-grow: 1;
max-width: 100%;
width: 800px;
padding: 2rem;
border: 1px solid #ccc;
border-radius: 5px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
#imagePreview {
width: 240px;
object-fit: cover;
padding-bottom: 20px;
}
#imagePreview::before {
content: '';
display: block;
width: 240px;
padding-top: 100%;
background-color: lightgray;
}
@media (max-width: 768px) {
.AdduserDialog {
overflow-y: auto;
}
.col-md-4 {
flex-basis: 100%;
margin-bottom: 1rem;
}
#imagePreview {
margin: 0 auto;
width: 360px;
}
#imagePreview::before {
content: '';
display: block;
width: 360px;
padding-top: 100%;
background-color: lightgray;
}
}
.custom-checkbox {
width: 1.5em; /* 增加复选框的宽度 */
height: 1.5em; /* 增加复选框的高度 */
}
.checkbox-inline {
text-align: left; /* 文本靠左对齐 */
}
.checkbox-inline label {
display: flex;
align-items: center;
justify-content: flex-start;
}
.btn-gap {
margin-bottom: 1rem !important;
}
</style>
</head>
<body>
<!-- createDialog -->
<div id="main-container">
<div class="modal fade" id="FloorSelectionModal" tabindex="-1" role="dialog" aria-labelledby="FloorSelectionModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title lang" id="FloorSelectionModalLabel" key="UISTR_FLOOR_AUTHORIZATION">Select Floors</h4>
</div>
<div class="modal-body">
<div id="FloorDialog" class="crudDialog">
<form>
<div class="form-group text-center mb-3">
<h5 id="show_message"></h5>
</div>
<!-- 楼层选择区域 -->
<div id="floorSelectionContainer"></div>
</form>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary lang" key="UISTR_SELECT_ALL" onclick="Floor_selectall()">Select All</button>
<button type="button" class="btn btn-primary lang" key="UISTR_DESELECT_ALL" onclick="Floor_deselectall()">Deselect All</button>
<button type="button" class="btn btn-primary lang" key="UISTR_SUBMIT" onclick="Floor_submit()">submit</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="RegFingerModal" tabindex="-1" role="dialog" aria-labelledby="RegFingerModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="cancelFingerprintRegistration()"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="RegFingerModalLabel"></h4>
</div>
<div class="modal-body">
<div id="FingerDialog" class="crudDialog">
<form>
<div class="form-group text-center mb-3">
<h5 id="show_message"></h5>
</div>
<div class="form-group text-center">
<img src="resources/images/fingerprint.jpg" alt="User Image Preview" id="FingerPreview" class="img-fluid">
</div>
</form>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default lang" key="UISTR_CANCEL_ESC" data-dismiss="modal" onclick="cancelFingerprintRegistration()">CANCEL</button>
</div>
</div>
</div>
</div>
<div class="AdduserDialog" style="width: 1000px;">
<form>
<div class="row align-items-start g-3">
<div class="col-md-4">
<div>
<label class="lang" key="UISTR_ENROLL_ID">ID</label>
<input id="inputid" class="form-control" type="text" onblur="checkIdUniqueness()" oninput="validateEnrollid(this)">
</div>
<div>
<label class="lang" key="UISTR_UserName">Name</label>
<input id="inputname" type="text" class="form-control" maxlength="48">
</div>
<div>
<label class="lang" key="UISTR_Department">Dept.</label>
<input id="inputdepartment" type="text" class="form-control" maxlength="48">
</div>
<div id="finger_div" class="mb-3 d-flex align-items-center" style="flex-wrap: nowrap;">
<label for="inputfinger" class="lang" key="UISTR_FINGER_ENROLL" style="margin-right: 10px;">fingerprint</label>
<div class="d-flex">
<input id="inputfinger" value="0" type="number" readonly style="width: 50px;">
<button id="btn_add_finger" type="button" class="btn btn-primary lang" key="UISTR_ADD_ON_DEVICE" onclick="addFingerprint()">Add on device</button>
<button id="btn_delete_finger" type="button" class="btn btn-primary lang" key="UISTR_ENROLL_DELETE" onclick="removeFingerprint()">delete</button>
</div>
</div>
<div id="palm_div" class="mb-3 d-flex align-items-center" style="flex-wrap: nowrap;">
<label for="inputpalm" class="lang" key="UISTR_PALM_ENROLL" style="margin-right: 10px;">palm</label>
<div class="d-flex">
<input id="inputpalm" value="0" type="number" readonly style="width: 50px;">
<button id="btn_add_palm" type="button" class="btn btn-primary lang" key="UISTR_ADD_ON_DEVICE" onclick="addPalm()">Add on device</button>
<button id="btn_delete_palm" type="button" class="btn btn-primary lang" key="UISTR_ENROLL_DELETE" onclick="removePalm()">delete</button>
</div>
</div>
<div class="mb-3 d-flex align-items-center" style="flex-wrap: nowrap;">
<label for="inputcard" class="lang" key="UISTR_CARD_ENROLL" style="margin-right: 10px;" >Card</label>
<div class="d-flex">
<input id="inputcard" value="0" type="text" style="width: 100px;">
<button type="button" class="btn btn-primary lang" key="UISTR_ADD_ON_DEVICE" onclick="addCard()">Add on device</button>
</div>
</div>
<div>
<label class="lang" key="UISTR_PASSWORD_ENROLL">Password</label>
<input id="inputpassword" type="text" class="form-control" oninput="validateNumericAndMaxLength(this, 99999999, 8)">
</div>
<div>
<label class="lang" key="UISTR_Privilege">Privilege</label>
<select id="inputadmin" class="form-control">
<option value="0" class="lang" key="UISTR_USER">User</option>
<option value="1" class="lang" key="UISTR_ENROLL_MANAGER">Admin</option>
<option value="2" class="lang" key="UISTR_ENROLL_SUPER_USER">Sup.User</option>
</select>
</div>
</div>
<div class="col-md-4">
<div>
<label class="lang" key="UISTR_UserShift">Shift</label>
<input id="inputshift" class="form-control" type="number" oninput="validateNumericAndMaxLength(this, 8, 1)">
</div>
<div>
<label class="lang" key="UISTR_MAINMENU_PASSTIMEID">T.Zone</label>
<input id="inputweekzone" class="form-control" type="number" oninput="validateNumericAndMaxLength(this, 8, 1)">
</div>
<div>
<label class="lang" id="group_lable" key="UISTR_MAINMENU_GROUPID">GRP</label>
<input id="inputgroup" class="form-control" type="number" oninput="validateNumericAndMaxLength(this, 99999999, 8)">
</div>
<div>
<label class="lang" id="access_times_lable" key="UISTR_ACCESS_TIMES">Access times</label>
<input id="inputaccess_times" class="form-control" type="number" value="0" max="65535" min="0" step="1" oninput="validateNumericAndMaxLength(this, 65535, 5)">
</div>
<div>
<label class="lang" key="UISTR_PERSON_VERIFY_MODE">Personal Verify Mode</label>
<select class="form-control" id="verifymode">
</select>
</div>
<div>
<label class="lang" key="UISTR_BIRTHDAY">Birthday</label>
<input id="inputbirthday" type="text" class="form-control">
</div>
<div>
<label class="lang" key="UISTR_START">Start:</label>
<input id="inputstarttime" type="text" class="form-control" maxlength="48">
</div>
<div>
<label class="lang" key="UISTR_END">End:</label>
<input id="inputendtime" type="text" class="form-control" maxlength="48">
</div>
</div>
<div class="col-md-4 d-flex flex-column justify-content-between">
<img src="resources/images/face.jpg" alt="User Image Preview" id="imagePreview" class="img-fluid mb-3">
<div class="d-flex flex-wrap gap-3">
<button type="button" class="btn btn-primary btn-gap lang" key="UISTR_SELECTFILE" onclick="loadFaceImage()">select face image</button>
<button type="button" class="btn btn-primary btn-gap lang" key="UISTR_ADD_ON_DEVICE" onclick="addface()">Add on device</button>
<button id="btn_delete_face" type="button" class="btn btn-primary btn-gap lang" key="UISTR_ENROLL_DELETE" onclick="removeFace()">delete</button>
</div>
</div>
</div>
<!-- Add the User Profile div here -->
<div class="row align-items-start g-3">
<div class="col-md-8">
<div>
<label class="lang" key="UISTR_USER_PROFILE">User Profile</label>
<textarea id="inputuserprofile" class="form-control" rows="5" cols="40"></textarea>
</div>
</div>
<!-- Submit button is now placed in a separate row below the User Profile -->
</div>
<div class="row align-items-center g-3">
<div class="col-md-auto d-flex justify-content-between">
<button type="button" class="btn btn-primary lang" key="UISTR_SENDTODEVICE" style="margin-top: 20px;" onclick="submitedituser()">Send to Device</button>
<button type="button" id="floorAuthorizationButton" class="btn btn-primary lang" key="UISTR_FLOOR_AUTHORIZATION" style="margin-left: 100px; margin-top: 20px;" onclick="select_floors()">Floor Authorization</button>
</div>
</div>
</form>
</div>
</div>
<script src="resources/plugins/jquery.1.12.4.min.js"></script>
<script src="resources/plugins/bootstrap-3.3.0/js/bootstrap.min.js"></script>
<script src="resources/plugins/bootstrap-table-1.17.0/bootstrap-table.min.js"></script>
<script src="resources/plugins/waves-0.7.5/waves.min.js"></script>
<script src="resources/plugins/jquery-confirm/jquery-confirm.min.js"></script>
<script src="resources/plugins/jquery.cookie.js"></script>
<script src="resources/js/notify.js"></script>
<script src="resources/js/lang.js"></script>
<script src="resources/js/common.js"></script>
<script src="resources/js/admin.js"></script>
<script>
let pollInterval;
var urlParams = new URLSearchParams(window.location.search);
var idStr = urlParams.get('id');
var userid = idStr;
var base64String=null;
let isAlertShown = false;
let DI_CARD_DISP_FORMAT = parseInt($.cookie("CARD_DISP_FORMAT")) || 0;
let DI_DATE_FORMAT = parseInt($.cookie("DATE_FORMAT")) || 0;
let DI_USERID_FORMAT = parseInt($.cookie("USERID_FORMAT")) || 0;
let hasFpsize = $.cookie("fpsize") !== undefined && $.cookie("fpsize") !== "0";
let hasPalmsize = $.cookie("palmsize") !== undefined && $.cookie("palmsize") !== "0";
let hasFacesize = $.cookie("facesize") !== undefined && $.cookie("facesize") !== "0";
let hasElevator = $.cookie("elevator_control") !== undefined && $.cookie("elevator_control") !== "0";
let floors = $.cookie("floors") || "1";
let naccess_times = $.cookie("acces_stimes") || "";
let basefloor = $.cookie("base_floor") || "1";
let gfloor = $.cookie("have_g_floor") !== undefined && $.cookie("have_g_floor") !== "0";
check_permission();
document.getElementById("inputaccess_times").value = naccess_times;
if (!hasFpsize) {
let finger_Div = document.getElementById('finger_div');
finger_Div.parentNode.removeChild(finger_Div);
}
if (!hasPalmsize) {
let palm_Div = document.getElementById('palm_div');
palm_Div.parentNode.removeChild(palm_Div);
}
if(!hasElevator)
{
$('#floorAuthorizationButton').hide();
}
lang_load().then(() => {
verifymodeSelect(); // 先生成选项
resetFormDirty();
if (hasElevator) {
$('#group_lable').text(lang.UISTR_DIRECT_FLOOR);
}
if (idStr) {
get_userinfo(); // 在选项生成后执行赋值
} else {
get_unusedid();
if (hasFpsize)
document.getElementById('btn_delete_finger').style.display = 'none';
if (hasPalmsize)
document.getElementById('btn_delete_palm').style.display = 'none';
}
}).catch(error => {});
function convertEnrollId(strid) {
if (typeof strid === 'number') {
return strid > 0xFFFFFFFF ? strid.toString() : strid;
}
if (typeof strid === 'string' && /^\d+$/.test(strid) && DI_USERID_FORMAT != 2) {
const num = Number(strid);
return Number.isSafeInteger(num) ? num : strid;
}
return strid;
}
function formatCard(card, dispFormat) {
if (card === null || card === undefined || card === "") {
return "";
}
const dispCard = BigInt(card);
const bits = dispCard.toString(2).length;
const byteLen = Math.ceil(bits / 8);
if (dispFormat === 1) {
if (byteLen <= 3 || byteLen === 4) {
if (byteLen <3) {
const number = dispCard & 0xFFFFFn;
return `0,${number.toString().padStart(5, '0')}`;
} else {
const area = (dispCard >> 16n) & 0xFFFFn;
const number = dispCard & 0xFFFFn;
return `${area},${number.toString().padStart(5, '0')}`;
}
} else {
return dispCard.toString();
}
} else if (dispFormat === 2) {
return `0x${dispCard.toString(16).toUpperCase()}`;
} else {
return dispCard.toString();
}
}
function parseCardInput(input) {
if (!input) return 0;
const str = input.trim().toUpperCase();
if (!str) return 0; // 默认返回0Number类型
try {
let value;
if (str.includes(',')) {
const [areaStr, numberStr] = str.split(',');
const area = BigInt(areaStr);
const number = BigInt(numberStr);
value = (area << 16n) + number;
}
else if (str.startsWith('0X')) {
value = BigInt(`0x${str.slice(2)}`);
}
else {
value = BigInt(str);
}
const MAX_SAFE = BigInt(Number.MAX_SAFE_INTEGER);
const MIN_SAFE = BigInt(Number.MIN_SAFE_INTEGER);
if (value >= MIN_SAFE && value <= MAX_SAFE) {
return Number(value);
} else {
return value.toString();
}
} catch (e) {
return 0; // 解析失败返回0
}
}
function formatDateTimeByType(dateStr, dateType) {
if (!dateStr) return "";
const [datePart, timePart] = dateStr.split(' ');
const [year, month, day] = datePart.split('-');
let formattedDate;
switch (dateType) {
case 1: // MDY格式月/日/年)
formattedDate = `${month.padStart(2, '0')}/${day}/${year}`;
break;
case 2: // DMY格式日/月/年)
formattedDate = `${day}/${month.padStart(2, '0')}/${year}`;
break;
default: // YMD格式年/月/日)
formattedDate = `${year}/${month.padStart(2, '0')}/${day}`;
}
return `${formattedDate} ${timePart}`;
}
function formatMonthDay(dateStr, dateType = 0) {
if (!dateStr) return "";
if (!/^\d{1,2}-\d{1,2}\**$/.test(dateStr)) {
return "";
}
const [datePart, asterisk = ""] = dateStr.split(/(\d{1,2}-\d{1,2})/).filter(Boolean);
const [inputMonth, inputDay] = datePart.split('-');
const month = inputMonth.padStart(2, '0');
const day = inputDay.padStart(2, '0');
switch (dateType) {
case 1: // MDY月/日)
return `${month}/${day}${asterisk.replace(/[^*]/g, '')}`;
case 2: // DMY日/月)
return `${day}/${month}${asterisk.replace(/[^*]/g, '')}`;
default: // 默认保持原格式
return `${month}/${day}${asterisk.replace(/[^*]/g, '')}`;
}
}
function parseFormattedDate(formattedDate, dateType = 1) {
if (!formattedDate) return "";
const match = formattedDate.match(/^(\d{1,2}[\/\-]\d{1,2})\**$/);
if (!match) return "";
const [_, datePart] = match;
const separator = /[\/\-]/;
let monthIndex, dayIndex;
switch (dateType) {
case 2:
[monthIndex, dayIndex] = [1, 0];
break;
default:
[monthIndex, dayIndex] = [0, 1];
}
const parts = datePart.split(separator);
if (parts.length !== 2) return ""; // 避免无效输入(如 "3-8-9"
const month = parts[monthIndex].padStart(2, '0');
const day = parts[dayIndex].padStart(2, '0');
return `${month}-${day}`;
}
function parseFormattedDateTime(str, dateType, isEnd = false) {
if (!str) return "";
const [datePart, timePart] = str.includes(' ') ? str.split(' ') : [str, ''];
const dateComponents = datePart.split(/[/-]/);
let day, month, year;
switch(dateType) {
case 1: // MDY (月/日/年)
[month, day, year] = dateComponents;
break;
case 2: // DMY (日/月/年)
[day, month, year] = dateComponents;
break;
default: // YMD (年/月/日)
[year, month, day] = dateComponents;
}
const padZero = num => String(num).padStart(2, '0');
month = padZero(month);
day = padZero(day);
let time = '00:00:00';
if (timePart) {
const [hours, minutes, seconds = '00'] = timePart.split(':').slice(0, 3);
time = `${padZero(hours)}:${padZero(minutes)}:${padZero(seconds)}`;
} else {
time = isEnd ? '23:59:59' : '00:00:00';
}
return `${year}-${month}-${day} ${time}`;
}
function checkIdUniqueness() {
if (isAlertShown) return;
const inputId = document.getElementById('inputid');
const inputValue = inputId.value.trim();
if (/^(0|[1-9]\d*)$/.test(inputValue)===false&&DI_USERID_FORMAT!=2)
{
return;
}
let sendData = {
"password": $.cookie("pwd"),
"cmd": 'checkuserid',
"enrollid": convertEnrollId(inputValue)
};
$.ajax({
url: debugserver+'/api',
type: 'POST',
contentType: "application/json",
dataType: "json",
data: JSON.stringify(sendData),
beforeSend: function() {},
success: function(json) {
if (json.exists) {
isAlertShown = true;
alert(lang.UISTR_INVALID_ENROLL_ID);
inputId.focus();
}
},
error: function(error) {
console.log("error::::", error);
}
});
}
function validateNumericAndMaxLength(inputElement, maxValue, maxLength) {
inputElement.value = inputElement.value.replace(/\D/g, '');
var intValue = parseInt(inputElement.value, 10);
isAlertShown = false;
if (inputElement.value.length > maxLength) {
inputElement.value = inputElement.value.slice(0, maxLength);
}
if (!isNaN(intValue) && intValue > maxValue) {
inputElement.value = maxValue.toString();
}
}
function validateEnrollid(inputElement) {
let maxValue, maxLength;
switch(DI_USERID_FORMAT) {
case 0:
inputElement.value = inputElement.value.replace(/\D/g, '');
maxValue = 99999999;
maxLength = 8;
break;
case 1:
inputElement.value = inputElement.value.replace(/[^0-9]/g, '');
maxValue = '9223372036854775807';
maxLength = 19;
break;
case 2:
maxLength = 32;
break;
}
if (inputElement.value.length > maxLength) {
inputElement.value = inputElement.value.slice(0, maxLength);
}
if (DI_USERID_FORMAT !== 2) {
const numericValue = DI_USERID_FORMAT === 1 ?
BigInt(inputElement.value || 0) :
parseInt(inputElement.value || 0, 10);
if (numericValue > maxValue) {
inputElement.value = maxValue.toString();
}
}
}
function get_unusedid() {
let send = new Object()
send["password"] = $.cookie("pwd")
send["cmd"] = 'getunuserdid'
console.log(send)
$.ajax({
url: debugserver+'/api',
type: 'POST',
contentType:"application/json",
dataType: "json",
data: JSON.stringify(send),
beforeSend: function() {
},
success: function(json){
console.log("done", json)
if (json.result) {
document.getElementById('inputid').value = json.enrollid;
} else {
console.log("", json);
}
},
error: function(error){
console.log("error::::",error);
}
});
}
function formatUserprofileContent(userprofile) {
if (userprofile === null || userprofile === undefined || userprofile === "") return "";
if (typeof userprofile === 'object') {
return Object.entries(userprofile)
.map(([key, value]) => `${key}:${value}`)
.join(',');
}
return String(userprofile);
}
function get_userinfo() {
let send = new Object()
send["password"] = $.cookie("pwd")
send["cmd"] = 'getuserinfo'
send["enrollid"] = convertEnrollId(userid)
console.log(send)
$.ajax({
url: debugserver+'/api',
type: 'POST',
contentType:"application/json",
dataType: "json",
data: JSON.stringify(send),
beforeSend: function() {
},
success: function(json){
console.log("done", json)
if (json.result) {
document.getElementById('inputid').value = json.enrollid;
document.getElementById('inputid').readOnly = true;
document.getElementById('inputname').value = json.name || "";
document.getElementById('inputdepartment').value = json.department || "";
document.getElementById('inputshift').value = json.shiftid || "";
const selectElementadmin = document.getElementById('inputadmin');
if (json.admin !== undefined && json.admin >= 0 && json.admin < selectElementadmin.options.length) {
selectElementadmin.selectedIndex = json.admin;
} else {
selectElementadmin.selectedIndex = -1;
}
document.getElementById('inputpassword').value = json.pwd || "";
document.getElementById('inputcard').value = formatCard(json.card,DI_CARD_DISP_FORMAT);
if (hasFpsize)
document.getElementById('inputfinger').value = json.fpcnt || "0";
if(hasPalmsize)
document.getElementById('inputpalm').value = json.palmcnt || "0";
document.getElementById('inputweekzone').value = json.zoneid || "";
document.getElementById('inputgroup').value = json.groupid || "";
document.getElementById('inputaccess_times').value = json.access_times || "";
document.getElementById('verifymode').value =json.verifymode||0;
document.getElementById('inputbirthday').value = formatMonthDay(json.birthday,DI_DATE_FORMAT);
document.getElementById('inputstarttime').value = formatDateTimeByType(json.starttime, DI_DATE_FORMAT);
document.getElementById('inputendtime').value = formatDateTimeByType(json.endtime, DI_DATE_FORMAT);
document.getElementById('inputuserprofile').value =formatUserprofileContent(json.userprofile);
if(json.photourl)
document.getElementById('imagePreview').src = debugserver+json.photourl+'?t=' + new Date().getTime();
if (hasFpsize)
{
if(json.fpcnt>=2)
{
document.getElementById('btn_add_finger').style.display = 'none';
}
else if(json.fpcnt==0)
{
document.getElementById('btn_delete_finger').style.display = 'none';
}
else
{
document.getElementById('btn_add_finger').style.display = '';
document.getElementById('btn_delete_finger').style.display = '';
}
}
if(hasPalmsize)
{
if(json.palmcnt>=2)
{
document.getElementById('btn_add_palm').style.display = 'none';
}
else if(json.palmcnt==0)
{
document.getElementById('btn_delete_palm').style.display = 'none';
}
else
{
document.getElementById('btn_add_palm').style.display = '';
document.getElementById('btn_delete_palm').style.display = '';
}
}
} else {
console.log("error", json);
}
},
error: function(error){
console.log("error::::",error);
}
});
}
function set_userinfo(isshowmsg=true) {
let enrollid;
let send = new Object()
send["password"] = $.cookie("pwd");
send["cmd"] = 'setuserinfo';
if(document.getElementById('inputid').value) {
const inputId = document.getElementById('inputid');
const inputValue = inputId.value.trim();
enrollid=convertEnrollId(inputValue);
send["enrollid"] = enrollid;
}
if(document.getElementById('inputname').value) {
send["name"] = document.getElementById('inputname').value;
}
else
send["name"]='';
if(document.getElementById('inputdepartment').value) {
send["department"] = document.getElementById('inputdepartment').value;
}
else
send["department"]='';
if(document.getElementById('inputshift').value) {
send["shiftid"] = parseInt(document.getElementById('inputshift').value, 10);
}
else
send["shiftid"]=0;
if(document.getElementById('inputadmin').value) {
send["admin"] = parseInt(document.getElementById('inputadmin').value, 10);
}
else
send["admin"]=0;
if(document.getElementById('inputpassword').value) {
send["pwd"] = parseInt(document.getElementById('inputpassword').value, 10);
}
else
send["pwd"]=0;
if(document.getElementById('inputcard').value) {
send["card"] = parseCardInput(document.getElementById('inputcard').value);
}
else
send["card"]=0;
if(document.getElementById('inputweekzone').value) {
send["zoneid"] = parseInt(document.getElementById('inputweekzone').value, 10);
}
else
send["zoneid"]=0;
if(document.getElementById('inputgroup').value) {
send["groupid"] = parseInt(document.getElementById('inputgroup').value, 10);
}
else
send["groupid"]=0;
if(document.getElementById('inputaccess_times').value) {
send["access_times"] = parseInt(document.getElementById('inputaccess_times').value, 10);
}
else
send["access_times"]=0;
if(document.getElementById('verifymode').value) {
send["verifymode"] = parseInt(document.getElementById('verifymode').value, 10);
}
else
send["verifymode"]=0;
if(document.getElementById('inputbirthday').value) {
send["birthday"] = parseFormattedDate(document.getElementById('inputbirthday').value, DI_DATE_FORMAT);
}
else
{
send["birthday"] ='';
}
if(document.getElementById('inputstarttime').value) {
send["starttime"] = parseFormattedDateTime(document.getElementById('inputstarttime').value,DI_DATE_FORMAT,false);
}
else
{
send["starttime"] ='';
}
if(document.getElementById('inputendtime').value) {
send["endtime"] = parseFormattedDateTime(document.getElementById('inputendtime').value,DI_DATE_FORMAT,true);
}
else
{
send["endtime"] ='';
}
if(document.getElementById('inputuserprofile').value) {
send["userprofile"] = document.getElementById('inputuserprofile').value;
}
else
{
send["userprofile"] ='';
}
if(base64String) {
send["face"] = base64String;
}
console.log(send)
$.ajax({
url: debugserver+'/api',
type: 'POST',
contentType:"application/json",
dataType: "json",
data: JSON.stringify(send),
beforeSend: function() {
},
success: function(json){
console.log("done", json)
if(json.ret=="setuserinfo" && json.result==true)
{
if(isshowmsg)
alert(lang.UISTR_UPLOAD_OK);
onSaveSuccess(enrollid);
onUploadSuccess();
}
else
{
if(isshowmsg)
alert(lang.UISTR_UPLOAD_FAIL+ json.msg);
}
},
error: function(error){
console.log("error::::",error);
}
});
}
function verifymodeSelect() {
const selectElement = document.getElementById('verifymode');
const LOG_ALLVERIFY = 0;
const LOG_FPVERIFY = 1; // Fingerprint Verify
const LOG_PASSVERIFY = 2; // Password Verify
const LOG_CARDVERIFY = 3; // Card Verify
const LOG_FPPASSVERIFY = 4; // Password + Fingerprint Verify
const LOG_FPCARDVERIFY = 5; // Card + Fingerprint Verify
const LOG_PASSFPVERIFY = 6; // Password + Fingerprint Verify
const LOG_CARDFPVERIFY = 7; // Card + Fingerprint Verify
const LOG_FACEVERIFY = 8; // Face Verify
const LOG_FACEPASSVERIFY = 9; // Face + Password Verify
const LOG_CARDFACEVERIFY = 10; // Face + Card Verify
const LOG_CARDPASSVERIFY = 11; // Card + Password Verify
const LOG_FPFACEVERIFY = 12; // Fingerprint + Face Verify
const LOG_QRCODEVERIFY = 13; // QR Code Verify
const LOG_FACE_CARDORPWD_VERIFY = 14;
const LOG_SFZVERIFY = 15; // SFZ (Chinese ID Card) Verify
const LOG_PALMVERIFY = 16; // Palm Verify
const LOG_1N1VERIFY = 19;
const LOG_PERSON_ALLVERIFY = 20;
const LOG_PALMANDFACE = 21;
const LOG_FPANDPALM = 22;
const LOG_CARDANDPALM = 23;
const LOG_PALMANDPWD = 24;
selectElement.innerHTML = '';
addOption(LOG_ALLVERIFY, lang.UISTR_DEVICE_VERIFY_MODE);
addOption(LOG_PERSON_ALLVERIFY, lang.UISTR_ANY);
addOption(LOG_CARDFACEVERIFY, lang.UISTR_VERIFY_CARD_ADD_FACE);
addOption(LOG_FACEPASSVERIFY, lang.UISTR_VERIFY_FACE_ADD_PWD);
addOption(LOG_FACE_CARDORPWD_VERIFY, lang.UISTR_VERIFY_FACE_ADD_CARD_PWD);
addOption(LOG_FACEVERIFY, lang.UISTR_FACE_ONLY);
if (hasPalmsize) {
addOption(LOG_PALMANDFACE, lang.UISTR_PALMANDFACE);
if (hasFpsize)
addOption(LOG_FPANDPALM, lang.UISTR_FPANDPALM);
addOption(LOG_CARDANDPALM, lang.UISTR_CARDANDPALM);
addOption(LOG_PALMANDPWD, lang.UISTR_PALMANDPWD);
addOption(LOG_PALMVERIFY, lang.UISTR_ONLYPALM);
}
if (hasFpsize) {
addOption(LOG_FPFACEVERIFY, lang.UISTR_VERIFY_FP_ADD_FACE);
addOption(LOG_FPCARDVERIFY, lang.UISTR_VERIFY_FP_ADD_CARD);
addOption(LOG_FPPASSVERIFY, lang.UISTR_SET_LIST_FP);
addOption(LOG_FPVERIFY, lang.UISTR_FINGER_ONLY);
}
addOption(LOG_CARDPASSVERIFY, lang.UISTR_SET_LIST_CP);
addOption(LOG_CARDVERIFY, lang.UISTR_CARD_ONLY);
addOption(LOG_PASSVERIFY, lang.UISTR_PASSWORD_ONLY);
selectElement.selectedIndex = -1;
function addOption(value, textContent) {
const option = document.createElement('option');
option.value = value;
option.textContent = textContent;
selectElement.appendChild(option);
}
}
function showTitle(message) {
const messageElement = $('#RegFingerModalLabel');
messageElement.text(message);
}
function showMessage(message) {
const messageElement = $('#show_message');
messageElement.text(message);
}
function changeModalSize(sizeClass) {
const currentSizeClass = $('#RegFingerModal .modal-dialog').attr('class').match(/modal-(sm|lg)/);
if (currentSizeClass) {
$('#RegFingerModal .modal-dialog').removeClass(currentSizeClass[0]);
}
$('#RegFingerModal .modal-dialog').addClass(sizeClass);
}
function addFingerprint() {
var backupnumber = parseInt(document.getElementById('inputfinger').value, 10);
setImagePreview("resources/images/fingerprint.jpg");
changeModalSize('modal-sm');
$('#RegFingerModal').modal('show');
$('#RegFingerModal').on('shown.bs.modal', function () {
showTitle(lang.UISTR_FINGER_ENROLL);
});
StartRegFingerprint(backupnumber);
}
function removeFingerprint(){
let send = new Object()
send["password"] = $.cookie("pwd");
send["cmd"] = 'deleteuserfp';
if(document.getElementById('inputid').value) {
const inputId = document.getElementById('inputid');
const inputValue = inputId.value.trim();
send["enrollid"] = convertEnrollId(inputValue);
}
console.log(send)
$.ajax({
url: debugserver+'/api',
type: 'POST',
contentType:"application/json",
dataType: "json",
data: JSON.stringify(send),
beforeSend: function() {
},
success: function(json){
console.log("done", json)
if(json.ret=="deleteuserfp" && json.result==true)
{
alert(lang.UISTR_DELETE_OK);
onUploadSuccess();
if (hasFpsize)
{
document.getElementById('inputfinger').value =0;
document.getElementById('btn_add_finger').style.display = '';
}
if(hasPalmsize)
document.getElementById('btn_delete_finger').style.display = 'none';
}
else
{
alert(lang.UISTR_ERRNONESUCCESS+ json.msg);
}
},
error: function(error){
console.log("error::::",error);
}
});
}
function addPalm() {
var backupnumber = parseInt(document.getElementById('inputpalm').value, 10)+40;
setImagePreview("resources/images/palm.jpg");
changeModalSize('modal-lg');
$('#RegFingerModal').modal('show');
$('#RegFingerModal').on('shown.bs.modal', function () {
showTitle(lang.UISTR_PALM_ENROLL);
});
StartRegFingerprint(backupnumber);
}
function removePalm(){
let send = new Object()
send["password"] = $.cookie("pwd");
send["cmd"] = 'deleteuserpalm';
if(document.getElementById('inputid').value) {
const inputId = document.getElementById('inputid');
const inputValue = inputId.value.trim();
send["enrollid"] = convertEnrollId(inputValue);
}
console.log(send)
$.ajax({
url: debugserver+'/api',
type: 'POST',
contentType:"application/json",
dataType: "json",
data: JSON.stringify(send),
beforeSend: function() {
},
success: function(json){
console.log("done", json)
if(json.ret=="deleteuserpalm" && json.result==true)
{
alert(lang.UISTR_DELETE_OK);
onUploadSuccess();
document.getElementById('inputpalm').value =0;
document.getElementById('btn_add_palm').style.display = '';
document.getElementById('btn_delete_palm').style.display = 'none';
}
else
{
alert(lang.UISTR_ERRNONESUCCESS+ json.msg);
}
},
error: function(error){
console.log("error::::",error);
}
});
}
function addface() {
setImagePreview("resources/images/face.jpg");
changeModalSize('modal-lg');
$('#RegFingerModal').modal('show');
$('#RegFingerModal').on('shown.bs.modal', function () {
showTitle(lang.UISTR_FACE_ENROLL);
});
StartRegFingerprint(50);
}
function removeFace(){
let send = new Object()
send["password"] = $.cookie("pwd");
send["cmd"] = 'deleteuserface';
if(document.getElementById('inputid').value) {
const inputId = document.getElementById('inputid');
const inputValue = inputId.value.trim();
send["enrollid"] = convertEnrollId(inputValue);
}
console.log(send)
$.ajax({
url: debugserver+'/api',
type: 'POST',
contentType:"application/json",
dataType: "json",
data: JSON.stringify(send),
beforeSend: function() {
},
success: function(json){
console.log("done", json)
if(json.ret=="deleteuserface" && json.result==true)
{
alert(lang.UISTR_DELETE_OK);
onUploadSuccess();
document.getElementById('btn_delete_face').style.display = 'none';
document.getElementById('imagePreview').src = "resources/images/face.jpg";
}
else
{
alert(lang.UISTR_ERRNONESUCCESS+ json.msg);
}
},
error: function(error){
console.log("error::::",error);
}
});
}
function addCard() {
setImagePreview("resources/images/card.jpg");
changeModalSize('modal-sm');
$('#RegFingerModal').modal('show');
$('#RegFingerModal').on('shown.bs.modal', function () {
showTitle(lang.UISTR_CARD_ENROLL);
});
StartRegFingerprint(11);
}
function cancelFingerprintRegistration() {
clearInterval(pollInterval);
pollInterval=null;
setTimeout(get_userinfo, 1000);
let send = new Object()
send["password"] = $.cookie("pwd");
send["cmd"] = 'adduser';
send["cancel"] =true;
$.ajax({
url: debugserver+'/api',
type: 'POST',
async: true,
contentType: "application/json",
data: JSON.stringify(send),
success: function (response) {
console.log(response);
},
error: function (error) {
console.log("Error starting fingerprint capture:", error);
}
});
}
function StartRegFingerprint(backupnum) {
set_userinfo(false);
let send = new Object();
send["password"] = $.cookie("pwd");
send["cmd"] = 'adduser';
send["flag"] = 2;
if(document.getElementById('inputid').value) {
const inputId = document.getElementById('inputid');
const inputValue = inputId.value.trim();
userid=convertEnrollId(inputValue);
send["enrollid"] = userid;
}
var inputname = document.getElementById('inputname');
if (inputname && inputname.value.trim() !== "") {
send["name"] = inputname.value.trim();
}
send["backupnum"] = backupnum;
$.ajax({
url: debugserver + '/api',
type: 'POST',
async: true,
contentType: "application/json",
data: JSON.stringify(send),
success: function (response) {
console.log(response);
if (response.result) {
pollForRegistrationStatus(1);
} else {
showMessage(lang.UISTR_ERRNONESUCCESS);
}
},
error: function (error) {
console.log("Error starting fingerprint capture:", error);
showMessage(lang.UISTR_ERRNONESUCCESS);
}
});
}
function pollForRegistrationStatus(attempt) {
$.ajax({
url: debugserver + '/api',
type: 'POST',
async: true,
contentType: "application/json",
data: JSON.stringify({
"password": $.cookie("pwd"),
"cmd": 'checkregstatus'
}),
success: function (response) {
console.log(response);
if (response.result) {
if (response.status === 100) {
if (response.msg) {
showMessage(response.msg);
}
if (response.image) {
updateImagePreview(response.image);
}
setTimeout(() => {
clearInterval(pollInterval); // 3秒后清除定时器
pollInterval = null;
get_userinfo();
onUploadSuccess();
$('#RegFingerModal').modal('hide');
}, 3000); // 3000毫秒 = 3秒
} else if (response.status >= 0 && response.status < 100) {
if (response.msg) {
showMessage(response.msg);
}
if (response.image) {
updateImagePreview(response.image);
}
if (!pollInterval) {
pollInterval = setInterval(function () {
pollForRegistrationStatus(attempt + 1);
}, 500); // 每 2 秒轮询一次
}
} else {
showMessage(lang.UISTR_ERRNONESUCCESS);
clearInterval(pollInterval); // 清除定时器
}
} else {
showMessage(lang.UISTR_ERRNONESUCCESS);
clearInterval(pollInterval); // 清除定时器
}
},
error: function (error) {
console.log("Error checking registration status:", error);
showMessage(lang.UISTR_ERRNONESUCCESS);
clearInterval(pollInterval); // 清除定时器
}
});
}
function updateImagePreview(imageData) {
$('#FingerPreview').attr('src', 'data:image/jpeg;base64,' + imageData);
}
function setImagePreview(path) {
$('#FingerPreview').attr('src', path + '?t=' + new Date().getTime());
}
function closeDialog() {
$.alert().close();
}
let userInfoFormDirty = false;
function bindInputListeners() {
const fieldIds = [
'inputname', 'inputdepartment', 'inputshift',
'inputadmin', 'inputpassword', 'inputcard', 'inputweekzone',
'inputgroup', 'inputaccess_times', 'verifymode', 'inputbirthday',
'inputstarttime', 'inputendtime', 'inputuserprofile'
];
fieldIds.forEach(id => {
const field = document.getElementById(id);
if (field) {
field.addEventListener('input', () => {
userInfoFormDirty = true;
});
}
});
}
function resetFormDirty() {
userInfoFormDirty = false;
}
if (document.readyState === 'complete') {
bindInputListeners();
} else {
document.addEventListener('DOMContentLoaded', bindInputListeners);
}
function submitedituser() {
if (typeof bindInputListeners === 'function' &&
!document.getElementById('inputname').hasEventListener) {
bindInputListeners();
document.getElementById('inputname').hasEventListener = true;
}
if (!userInfoFormDirty) {
alert(lang.UISTR_NO_MODIFY);
return;
}
const fieldIds = [
'inputname', 'inputdepartment', 'inputshift',
'inputadmin', 'inputpassword', 'inputcard', 'inputweekzone',
'inputgroup', 'inputaccess_times', 'verifymode', 'inputbirthday',
'inputstarttime', 'inputendtime', 'inputuserprofile'
];
let allEmpty = true;
for (const id of fieldIds) {
const field = document.getElementById(id);
if (field) {
let value;
value = field.value;
if (typeof value === 'string') {
value = value.trim();
}
if (value !== '' && value !== 0 && value !== '0') {
allEmpty = false;
break;
}
}
}
if (allEmpty) {
alert(lang.UISTR_NO_MODIFY);
return;
}
set_userinfo();
resetFormDirty();
}
function select_floors(){
$('#FloorSelectionModal').modal('show');
$('#FloorSelectionModal').on('shown.bs.modal', function () {
let userProfileValue = $('#inputuserprofile').val();
generateFloorSelection(floors, basefloor, gfloor,userProfileValue);
});
}
function generateFloorSelection(floors, basefloor, gfloor, userprofile) {
let floorSelectionContainer = $('#floorSelectionContainer');
floorSelectionContainer.empty();
floors = parseInt(floors, 10);
const basefloorMap = {
0: 1,
1: -1,
2: -2,
3: -3,
4: -4,
5: -5,
6: -6,
7: -7,
8: -8,
9: -9
};
basefloor = basefloorMap[parseInt(basefloor, 10)] || 1;
let selectedFloors = userprofile ? userprofile.split(',').map(Number) : [];
let currentRow = $('<div class="row" style="margin-bottom: 20px;"></div>');
let columnIndex = 0;
for (let i = basefloor; i <= floors; i++) {
let floorNumber;
if (gfloor && i === 0) {
floorNumber = 'G';
} else if (i === 0) {
continue;
} else {
floorNumber = i > 0 ? i : `-${Math.abs(i)}`;
}
let isChecked = selectedFloors.includes(i);
let col = $(`<div class="col-md-2 d-flex align-items-center"></div>`);
col.append(`<label class="d-block checkbox-inline"><input type="checkbox" name="floor-${i}" value="${i}" class="custom-checkbox"${isChecked ? ' checked' : ''}>${floorNumber}</label>`);
currentRow.append(col);
columnIndex++;
if (columnIndex % 5 === 0) {
floorSelectionContainer.append(currentRow);
currentRow = $('<div class="row" style="margin-bottom: 20px;"></div>');
columnIndex = 0;
}
}
if (columnIndex > 0) {
floorSelectionContainer.append(currentRow);
}
}
function loadFaceImage() {
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = 'image/jpeg, image/png, image/bmp';
fileInput.onchange = function(event) {
const file = event.target.files[0];
if (file) {
const allowedTypes = ['image/jpeg', 'image/png', 'image/bmp'];
if (!allowedTypes.includes(file.type)) {
alert(lang.UISTR_FILE_ERROR);
return;
}
if (file.size > 500 * 1024) {
alert(lang.UISTR_FILE_ERROR);
return;
}
const img = new Image();
img.onload = function() {
if (this.width > 1024 || this.height > 1024) {
alert(lang.UISTR_FILE_ERROR);
return;
}
const reader = new FileReader();
reader.onload = function(e) {
document.getElementById('imagePreview').src = e.target.result;
base64String = e.target.result.split(',')[1];
console.log('Base64 String:', base64String);
};
reader.readAsDataURL(file);
};
img.onerror = function() {
alert(lang.UISTR_FILE_ERROR);
};
img.src = URL.createObjectURL(file);
}
};
fileInput.click();
}
function Floor_selectall() {
// 选择所有的复选框
$('input[name^="floor-"]').prop('checked', true);
}
function Floor_deselectall() {
// 取消选择所有的复选框
$('input[name^="floor-"]').prop('checked', false);
}
function Floor_submit() {
let selectedFloors = [];
$('input[name^="floor-"]:checked').each(function() {
selectedFloors.push($(this).val());
});
// 将选中的楼层转换为指定格式的字符串
let selectedFloorsStr = selectedFloors.map(floor => {
return floor === '0' ? 'G' : floor;
}).join(',');
// 将字符串赋值给inputuserprofile
$('#inputuserprofile').val(selectedFloorsStr);
// 关闭模态框
$('#FloorSelectionModal').modal('hide');
}
// 在模态框关闭时清除定时器
$('#RegFingerModal').on('hidden.bs.modal', function () {
clearInterval(pollInterval);
});
function onSaveSuccess(enrollid) {
const channel = new BroadcastChannel('userlist_channel');
channel.postMessage({
action:idStr?'update':'add',
id:enrollid
});
channel.close(); // 可选关闭频道
}
function onUploadSuccess() {
const homeChannel = new BroadcastChannel('home_refresh_channel');
homeChannel.postMessage({type: 'refresh_home'});
homeChannel.close();
}
// 初始化上一次合法值
let lastValidValue = document.getElementById('inputcard').value;
const validateInput = () => {
const input = document.getElementById('inputcard');
const format = DI_CARD_DISP_FORMAT;
const value = input.value;
if (value.trim() === '') {
lastValidValue = '';
return;
}
let isValid = false;
switch (format) {
case 0: // 十进制
isValid = /^\d+$/.test(value);
break;
case 1: // 韦根格式
isValid = /^\d{1,5},\d{1,5}$/.test(value);
break;
case 2: // 十六进制
isValid = /^0x[0-9A-Fa-f]+$/.test(value);
break;
}
// 处理验证结果
if (isValid) {
lastValidValue = value; // 更新合法值缓存
} else {
input.value = lastValidValue; // 恢复至上次合法值
alert(getFormatDescription(format));
}
};
document.getElementById('inputcard').addEventListener('blur', validateInput);
// 获取格式描述文本(用于警告信息)
function getFormatDescription(format) {
return [
lang.UISTR_DIGITAL+"(123456)",
lang.UISTR_WIEGAND+"(123,45678)",
lang.UISTR_HEX+"(0x12AB)"
][format];
}
</script>
</body>
</html>