LicenseManger/web/static/js/licenses.js

343 lines
13 KiB
JavaScript

layui.use(['table', 'form', 'layer'], function(){
var table = layui.table;
var form = layui.form;
var layer = layui.layer;
var $ = layui.$;
// 自定义验证规则
form.verify({
min1: function(value) {
if (value < 1) {
return '必须大于0';
}
}
});
// 初始化表格
table.render({
elem: '#license-table',
url: '/api/licenses',
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token')
},
toolbar: '#tableToolbar',
defaultToolbar: ['filter', 'exports', 'print'],
cols: [[
{type: 'checkbox'},
{field: 'code', title: '授权码', width: 320, templet: function(d){
return '<div class="layui-table-cell laytable-cell-1-code">' +
d.code +
'<a class="layui-btn layui-btn-xs layui-btn-normal" lay-event="copy" style="margin-left:5px;">复制</a>' +
'</div>';
}},
{field: 'license_type', title: '授权类型', width: 100, templet: function(d){
var types = {
'time': '时间授权',
'count': '次数授权',
'permanent': '永久授权'
};
return types[d.license_type.toLowerCase()] || d.license_type;
}},
{field: 'duration', title: '有效期', width: 150, templet: function(d){
if(d.license_type.toLowerCase() === 'time') {
let minutes = d.duration;
if (minutes >= 525600) {
return Math.floor(minutes / 525600) + '年';
} else if (minutes >= 43200) {
return Math.floor(minutes / 43200) + '月';
} else if (minutes >= 1440) {
return Math.floor(minutes / 1440) + '天';
} else if (minutes >= 60) {
return Math.floor(minutes / 60) + '小时';
} else {
return minutes + '分钟';
}
}
return '-';
}},
{field: 'max_uses', title: '使用次数', width: 100, templet: function(d){
if(d.license_type.toLowerCase() === 'count') {
return d.max_uses || 0;
}
return '-';
}},
{field: 'status', title: '状态', width: 100, templet: function(d){
var status = d.status.toLowerCase();
if(status === 'unused') return '<span class="layui-badge layui-bg-green">未使用</span>';
if(status === 'used') return '<span class="layui-badge layui-bg-gray">已使用</span>';
if(status === 'expired') return '<span class="layui-badge layui-bg-orange">已过期</span>';
if(status === 'revoked') return '<span class="layui-badge layui-bg-red">已撤销</span>';
return '<span class="layui-badge layui-bg-black">未知</span>';
}},
{field: 'used_by', title: '使用设备', width: 180},
{field: 'used_at', title: '使用时间', width: 160, templet: function(d){
return d.used_at ? new Date(d.used_at).toLocaleString() : '-';
}},
{field: 'batch_no', title: '批次号', width: 160},
{field: 'remark', title: '备注'},
{field: 'bind_count', title: '可绑定次数', width: 100, templet: function(d){
if(d.bind_count === -1) return '<span class="layui-badge layui-bg-blue">无限制</span>';
if(d.bind_count === 0) return '<span class="layui-badge layui-bg-gray">已用完</span>';
return d.bind_count;
}},
{fixed: 'right', title: '操作', toolbar: '#tableRowBar', width: 180, templet: function(d){
var btns = [
'<a class="layui-btn layui-btn-xs" lay-event="view">查看</a>',
'<a class="layui-btn layui-btn-xs layui-btn-warm" lay-event="logs">日志</a>'
];
// 只有未过期且未撤销的授权码才能撤销
if(d.status.toLowerCase() !== 'expired' && d.status.toLowerCase() !== 'revoked') {
btns.push('<a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="revoke">撤销</a>');
}
return btns.join('');
}}
]],
page: true,
parseData: function(res) {
if (res.code === 401) {
window.location.href = '/login';
return;
}
return {
"code": res.code,
"msg": res.msg,
"count": res.count,
"data": res.data
};
}
});
// 表格工具栏事件
table.on('toolbar(license-table)', function(obj){
var checkStatus = table.checkStatus(obj.config.id);
switch(obj.event){
case 'refresh':
table.reload('license-table');
break;
case 'copySelected':
var data = checkStatus.data;
if(data.length === 0){
layer.msg('请选择要复制的授权码');
return;
}
// 提取授权码并按格式组织
var codes = data.map(item => item.code);
var copyText = '';
// 弹出选择框
layer.confirm('请选择复制格式', {
btn: ['换行分隔', '逗号分隔']
}, function(index){
// 换行分隔
copyText = codes.join('\n');
copyToClipboard(copyText);
layer.close(index);
}, function(index){
// 逗号分隔
copyText = codes.join(',');
copyToClipboard(copyText);
layer.close(index);
});
break;
case 'batchDel':
var data = checkStatus.data;
if(data.length === 0){
layer.msg('请选择要删除的授权码');
return;
}
layer.confirm('确定撤销选中的授权码吗?', function(index){
var codes = data.map(item => item.code);
fetch('/api/licenses/batch/revoke', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
credentials: 'include',
body: JSON.stringify({codes: codes})
})
.then(response => response.json())
.then(result => {
if(result.error) {
layer.msg(result.error);
return;
}
layer.msg('批量撤销成功');
table.reload('license-table');
})
.catch(error => {
layer.msg('批量撤销失败:' + error.message);
});
layer.close(index);
});
break;
}
});
// 添加复制到剪贴板的函数
function copyToClipboard(text) {
// 创建临时文本区域
var textarea = document.createElement('textarea');
textarea.value = text;
document.body.appendChild(textarea);
// 选择文本
textarea.select();
textarea.setSelectionRange(0, 99999); // 兼容移动设备
try {
// 执行复制
var successful = document.execCommand('copy');
if (successful) {
layer.msg('复制成功');
} else {
layer.msg('复制失败,请手动复制');
}
} catch (err) {
layer.msg('复制失败:' + err.message);
}
// 移除临时文本区域
document.body.removeChild(textarea);
}
// 行工具栏事件
table.on('tool(license-table)', function(obj){
var data = obj.data;
switch(obj.event){
case 'view':
layer.alert(JSON.stringify(data, null, 2), {
title: '授权码详情'
});
break;
case 'logs':
layer.open({
type: 2,
title: '使用日志',
area: ['800px', '600px'],
content: '/admin/license-logs?id=' + data.id + '&token=' + localStorage.getItem('token')
});
break;
case 'revoke':
layer.confirm('确定撤销该授权码吗?', function(index){
fetch('/api/licenses/' + data.code + '/revoke', {
method: 'POST',
credentials: 'include'
})
.then(response => response.json())
.then(result => {
if (result.error) {
layer.msg(result.error);
return;
}
layer.msg('撤销成功');
table.reload('license-table');
})
.catch(error => {
layer.msg('撤销失败:' + error.message);
});
layer.close(index);
});
break;
case 'copy':
copyToClipboard(data.code);
break;
}
});
// 搜索表单提交
form.on('submit(search)', function(data){
// 转换所有字段为小写
Object.keys(data.field).forEach(key => {
if(data.field[key]) {
data.field[key] = data.field[key].toLowerCase();
}
});
table.reload('license-table', {
where: data.field,
page: {
curr: 1
}
});
return false;
});
// 创建授权码按钮点击事件
$('#create-license').on('click', function(){
layer.open({
type: 1,
title: '生成授权码',
area: ['500px', '400px'],
content: $('#createLicenseTpl').html(),
success: function(){
form.render();
}
});
});
// 监听授权类型切换
form.on('select(licenseType)', function(data){
if(data.value === 'time'){
$('#durationItem').show();
$('#maxUsesItem').hide();
} else if(data.value === 'count'){
$('#durationItem').hide();
$('#maxUsesItem').show();
} else {
$('#durationItem').hide();
$('#maxUsesItem').hide();
}
});
// 创建授权码表单提交
form.on('submit(licenseSubmit)', function(data){
var field = data.field;
// 构造请求数据,确保数值类型正确
const submitData = {
license_type: field.license_type.toLowerCase(),
count: parseInt(field.count),
remark: field.remark
};
// 根据授权类型处理参数
if(field.license_type.toLowerCase() === 'time'){
submitData.duration = parseInt(field.duration) * parseInt(field.duration_unit);
delete field.max_uses;
} else if(field.license_type.toLowerCase() === 'count'){
submitData.max_uses = parseInt(field.max_uses);
delete field.duration;
} else {
delete field.duration;
delete field.max_uses;
}
fetch('/api/licenses', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + localStorage.getItem('token')
},
credentials: 'include',
body: JSON.stringify(submitData)
})
.then(response => response.json())
.then(result => {
if (result.error) {
layer.msg(result.error);
return;
}
layer.closeAll('page');
layer.msg('授权码生成成功');
table.reload('license-table');
})
.catch(error => {
layer.msg('生成失败:' + error.message);
});
return false;
});
});