302 lines
11 KiB
HTML
302 lines
11 KiB
HTML
<!DOCTYPE HTML>
|
||
<html lang="zh-cn">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>log view</title>
|
||
|
||
<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>
|
||
.img-max-height-lg {
|
||
max-height: 240px !important;
|
||
}
|
||
.img-max-height-sm {
|
||
max-height: 320px !important;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div id="main">
|
||
<div id="toolbar">
|
||
</div>
|
||
<table id="table"></table>
|
||
</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 poithide = $.cookie("manufacturer") !== undefined && $.cookie("manufacturer")==="Piot Robotics";
|
||
check_permission();
|
||
lang_load().then(() => {
|
||
fetchLogs();
|
||
changetitle('time', lang.UISTR_TIME_SETTING);
|
||
changetitle('id', lang.UISTR_ENROLL_ID);
|
||
changetitle('name', lang.UISTR_UserName);
|
||
changetitle('mode', lang.UISTR_VERIFY_mode);
|
||
changetitle('event', lang.UISTR_EVENT);
|
||
changetitle('note',lang.UISTR_NOTE||'note');
|
||
changetitle('inout',lang.UISTR_INOUT||'inout');
|
||
changetitle('photo',lang.UISTR_Photo||'Photo');
|
||
changetitle('photouri',lang.UISTR_Photo_Url||'Photo');
|
||
changeSearchPlaceholder();
|
||
}).catch(error => {
|
||
console.error("Language loading failed:", error);
|
||
});
|
||
function formatNoteContent(note) {
|
||
if (note === null || note === undefined || note === "") return "";
|
||
if (typeof note === 'object') {
|
||
return Object.entries(note)
|
||
.map(([key, value]) => `${key}:${value}`)
|
||
.join(',');
|
||
}
|
||
if (typeof note === 'string') {
|
||
try {
|
||
const parsed = JSON.parse(note);
|
||
return Object.entries(parsed)
|
||
.map(([key, value]) => `${key}:${value}`)
|
||
.join(',');
|
||
} catch (e) {
|
||
return note;
|
||
}
|
||
}
|
||
return String(note);
|
||
}
|
||
function get_rtlog(index = 0) {
|
||
let send = new Object();
|
||
send["password"] = $.cookie("pwd");
|
||
send["cmd"] = 'getrtlog';
|
||
send["index"] = index;
|
||
console.log(send);
|
||
|
||
return new Promise((resolve, reject) => {
|
||
$.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.count&&json.count>0)
|
||
{
|
||
let records = json.record;
|
||
let transformedData = [];
|
||
for (let record of records) {
|
||
let transformedRecord = {
|
||
id: record.enrollid,
|
||
name: record.name || "",
|
||
time: record.time || "",
|
||
mode: record.mode || "",
|
||
inout: record.inout || "",
|
||
event: record.event || "",
|
||
note: formatNoteContent(record.note),
|
||
photo: record.photourl ? 1 : 0,
|
||
photouri: record.photourl || ""
|
||
};
|
||
transformedData.push(transformedRecord);
|
||
}
|
||
$table.bootstrapTable('append', transformedData);
|
||
}
|
||
if (json.count > json.to) {
|
||
var nindex = json.to + 1;
|
||
get_rtlog(nindex).then(resolve); // 继续处理下一个分包
|
||
} else {
|
||
resolve(); // 所有分包处理完毕
|
||
}
|
||
},
|
||
error: function(error) {
|
||
console.log("error::::", error);
|
||
reject(error);
|
||
}
|
||
});
|
||
});
|
||
}
|
||
let isFetching = false;
|
||
function fetchLogs() {
|
||
if (!isFetching) {
|
||
isFetching = true;
|
||
get_rtlog().then(() => {
|
||
isFetching = false;
|
||
setTimeout(fetchLogs, 3000); // 每3秒更新一次
|
||
}).catch(error => {
|
||
console.error("Failed to fetch logs:", error);
|
||
isFetching = false;
|
||
setTimeout(fetchLogs, 3000); // 如果请求失败,3秒后重试
|
||
});
|
||
}
|
||
}
|
||
var $table = $('#table');
|
||
$(function() {
|
||
$(document).on('focus', 'input[type="text"]', function() {
|
||
$(this).parent().find('label').addClass('active');
|
||
}).on('blur', 'input[type="text"]', function() {
|
||
if ($(this).val() == '') {
|
||
$(this).parent().find('label').removeClass('active');
|
||
}
|
||
});
|
||
// bootstrap table初始化
|
||
// http://bootstrap-table.wenzhixin.net.cn/zh-cn/documentation/
|
||
$table.bootstrapTable({
|
||
data:[],
|
||
height: getHeight(),
|
||
striped: true,
|
||
search: true,
|
||
searchOnEnterKey: true,
|
||
showRefresh: false,
|
||
//showToggle: true,
|
||
showColumns: true,
|
||
minimumCountColumns: 2,
|
||
//showPaginationSwitch: true,
|
||
clickToSelect: true,
|
||
detailView: true,
|
||
detailFormatter: 'detailFormatter',
|
||
pagination: true,
|
||
pageSize: 15,
|
||
pageList: [10, 15, 30, 50, 100],
|
||
paginationLoop: false,
|
||
classes: 'table table-hover table-no-bordered',
|
||
//sidePagination: 'server',
|
||
//silentSort: false,
|
||
smartDisplay: false,
|
||
idField: 'time',
|
||
sortName: 'time',
|
||
sortOrder: 'desc',
|
||
escape: true,
|
||
searchOnEnterKey: true,
|
||
maintainSelected: true,
|
||
toolbar: '#toolbar',
|
||
columns: [
|
||
{field: 'time', title: 'date time', sortable: true, halign: 'center', width: '15%',align: 'center'},
|
||
{field: 'id', title: 'user id', sortable: true, halign: 'center', width: '15%',align: 'center'},
|
||
{field: 'name', title: 'name', sortable: true, halign: 'center', width: '15%',align: 'center'},
|
||
{field: 'mode', title: 'verify mode', sortable: true, halign: 'center', width: '10%',align: 'center'},
|
||
{field: 'inout', title: 'inout', sortable: true, halign: 'center', width: '10%',align: 'center'},
|
||
{field: 'event', title: 'event', sortable: true, halign: 'center', width: '10%',align: 'center'},
|
||
{field: 'note', title: 'not', sortable: true, halign: 'center', width: '20%',align: 'center'},
|
||
{field: 'photo', title: 'photo', sortable: true, halign: 'center', width: '10%',align: 'center', formatter: 'actionfaceFormatter'},
|
||
{field: 'photouri', title: 'image', visible: false}
|
||
]
|
||
}).on('all.bs.table', function (e, name, args) {
|
||
$('[data-toggle="tooltip"]').tooltip();
|
||
$('[data-toggle="popover"]').popover();
|
||
});
|
||
});
|
||
|
||
$table.on('refresh.bs.table', function () {
|
||
$table.bootstrapTable('removeAll');
|
||
get_rtlog();
|
||
});
|
||
|
||
function changetitle(field, newTitle) {
|
||
var columns = $table.bootstrapTable('getOptions').columns[0];
|
||
for (var i = 0; i < columns.length; i++) {
|
||
if (columns[i].field === field) {
|
||
columns[i].title = newTitle;
|
||
break;
|
||
}
|
||
}
|
||
$table.bootstrapTable('refreshOptions', {columns: columns});
|
||
}
|
||
function changeSearchPlaceholder() {
|
||
const options = $table.bootstrapTable('getOptions');
|
||
options.formatSearch = () => lang.UISTR_USER_FIND || 'Search...';
|
||
options.formatRefresh = () => lang.UISTR_Refresh || 'Refresh';
|
||
options.formatRefreshButton = (icon, text) =>
|
||
`<i class="${icon}"></i> ${text || lang.UISTR_Refresh || 'Refresh'}`;
|
||
options.formatColumns = () => lang.UISTR_Columns || 'Columns'; // [4](@ref)
|
||
options.formatColumnsButton = (icon, text) =>
|
||
`<i class="${icon}"></i> ${text || lang.UISTR_Columns || 'Columns'}`;
|
||
options.formatToggle = () => lang.UISTR_Toggle || 'Toggle'; // 悬浮提示(Tooltip)
|
||
options.formatToggleButton = (icon, text) =>
|
||
`<i class="${icon}"></i> ${text || lang.UISTR_Toggle || 'Toggle'}`; // 按钮文本
|
||
options.formatNoMatches = () => lang.UISTR_NoMatches || 'No matching records found';
|
||
options.formatShowingRows = (from, to, total) => {
|
||
const template = lang.UISTR_ShowingRows
|
||
|| 'Showing #1 to #2 of #3 rows';
|
||
return template
|
||
.replace(/#1/g, from)
|
||
.replace(/#2/g, to)
|
||
.replace(/#3/g, total);
|
||
};
|
||
options.formatRecordsPerPage = (pageSize) => {
|
||
const template = lang.UISTR_RecordsPerPage
|
||
|| '#3 rows per page';
|
||
return template.replace(/#3/g, pageSize);
|
||
};
|
||
|
||
// 强制刷新配置
|
||
$table.bootstrapTable('refreshOptions', options);
|
||
}
|
||
function actionfaceFormatter(value, row, index) {
|
||
return value ? `<i class="glyphicon glyphicon-picture"></i>` : '';
|
||
}
|
||
function detailFormatter(index, row) {
|
||
var html = [];
|
||
var detailsHtml = [];
|
||
// Manually add the information you want to display
|
||
detailsHtml.push('<p><b>'+lang.UISTR_ENROLL_ID+':</b>' + row.id + '</p>');
|
||
detailsHtml.push('<p><b>'+lang.UISTR_UserName+':</b>' + row.name + '</p>');
|
||
detailsHtml.push('<p><b>'+lang.UISTR_TIME_SETTING+':</b>' + row.time + '</p>');
|
||
detailsHtml.push('<p><b>'+lang.UISTR_VERIFY_mode+':</b>' + row.mode + '</p>');
|
||
if(!poithide)
|
||
{
|
||
detailsHtml.push('<p><b>inout:</b>' + row.inout + '</p>');
|
||
detailsHtml.push('<p><b>'+lang.UISTR_EVENT+':</b>' + row.event + '</p>');
|
||
detailsHtml.push('<p><b>note:</b>' + row.note + '</p>');
|
||
}
|
||
|
||
var imageUrl = '';
|
||
if(row.photouri)
|
||
imageUrl = debugserver+row.photouri;
|
||
|
||
// Use Flexbox for responsive alignment
|
||
html.push('<div class="row d-flex flex-column flex-sm-row">'); // Use flex-column for stacking on small screens, and flex-row for larger screens
|
||
|
||
html.push(' <div class="col-12 col-sm-8">'); // Adjusted width for the first column
|
||
html.push(' ' + detailsHtml.join(''));
|
||
html.push(' </div>');
|
||
|
||
if (imageUrl && imageUrl.trim()) {
|
||
// Ensure the image is always on the left on small screens
|
||
html.push(' <div class="col-12 col-sm-4 order-first order-sm-0">'); // Use order-first for small screens, and remove it for larger screens
|
||
html.push(' <a href="' + imageUrl+'?t=' + new Date().getTime() + '" target="_blank">'); // Added link to open image in new tab
|
||
html.push(' <img src="' + imageUrl+'?t=' + new Date().getTime() + '" alt="User Image" class="img-max-height-lg img-max-height-sm">');
|
||
html.push(' </a>');
|
||
html.push(' </div>');
|
||
}
|
||
|
||
|
||
|
||
html.push('</div>');
|
||
|
||
return html.join('');
|
||
}
|
||
$(document).ready(function() {
|
||
if(poithide)
|
||
{
|
||
const hideColumns = ['inout', 'event', 'note', 'photo', 'photouri'];
|
||
hideColumns.forEach(col => {
|
||
$table.bootstrapTable('hideColumn', col);
|
||
});
|
||
}
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|