'use strict';
layui.use(['table', 'layer', 'util'], function () {
const table = layui.table;
const layer = layui.layer;
const util = layui.util;
const tableId = 'applicationTable';
const columnWidth = {
name: 220,
clientId: 200,
type: 160,
actions: 220
};
table.render({
elem: '#applicationTable',
url: '/Application/Page',
page: true,
limit: 20,
cellMinWidth: 120,
cols: [[
{
field: 'displayName',
title: '显示名称',
minWidth: columnWidth.name
},
{
field: 'clientId',
title: 'ClientId',
minWidth: columnWidth.clientId,
templet: d => util.escape(d.clientId ?? '-')
},
{
field: 'clientType',
title: '应用类型',
width: columnWidth.type,
templet: d => renderTags([d.applicationType])
},
{
field: 'clientType',
title: '客户端类型',
width: columnWidth.type,
templet: d => renderTags([d.clientType])
},
{
field: 'redirectUris',
title: '重定向地址',
minWidth: 260,
templet: d => renderBlockList(d.redirectUris)
},
{
field: 'postLogoutRedirectUri',
title: '登出回调',
minWidth: 220,
templet: d => util.escape(d.postLogoutRedirectUri ?? '-')
},
{
field: 'permissions',
title: '权限',
minWidth: 240,
templet: d => renderTags(d.permissions)
},
{
fixed: 'right',
title: '操作',
width: columnWidth.actions,
toolbar: '#applicationTableActions'
}
]]
});
function renderTags(items) {
if (!Array.isArray(items) || items.length === 0) {
return '<span class="dpz-tag-muted">-</span>';
}
return items
/*.filter(Boolean)*/
.map(item => isNullOrWhiteSpace(item)
? '<span class="dpz-tag-muted">-</span>'
: `<span class="dpz-tag-badge">${util.escape(item)}</span>`)
.join(' ');
}
function isNullOrWhiteSpace(str) {
return str === null || typeof str !== 'string' || str.trim().length === 0;
}
function renderBlockList(items) {
if (!Array.isArray(items) || items.length === 0) {
return '<span class="dpz-tag-muted">-</span>';
}
return items
.map(item => `<div class="layui-text layui-text-sm">${util.escape(item)}</div>`)
.join('');
}
function reloadTable() {
table.reload(tableId, {
page: { curr: 1 },
where: {
keyword: document.getElementById('keyword')?.value?.trim()
}
});
}
document.getElementById('btnSearch')?.addEventListener('click', reloadTable);
document.getElementById('btnClear')?.addEventListener('click', function () {
const keyword = document.getElementById('keyword');
if (keyword) {
keyword.value = '';
}
reloadTable();
});
table.on('tool(applicationTable)', function (obj) {
const data = obj.data;
switch (obj.event) {
case 'edit':
window.location.href = `/Application/Upsert?id=${encodeURIComponent(data.id)}`;
break;
case 'copyId':
copyClientId(data.clientId);
break;
case 'delete':
confirmDelete(data);
break;
default:
break;
}
});
function copyClientId(clientId) {
if (!clientId) {
layer.msg('没有可复制的 ClientId');
return;
}
if (navigator.clipboard?.writeText) {
navigator.clipboard
.writeText(clientId)
.then(() => layer.msg('已复制 ClientId'))
.catch(() => fallbackCopy(clientId));
} else {
fallbackCopy(clientId);
}
}
function fallbackCopy(text) {
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.style.position = 'fixed';
textarea.style.opacity = '0';
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
layer.msg('已复制 ClientId');
} catch (e) {
layer.alert('复制失败,请手动复制');
} finally {
document.body.removeChild(textarea);
}
}
function confirmDelete(data) {
const name = util.escape(data.displayName ?? '');
if (!window.dpz?.openActionDialog) {
layer.alert('对话框组件未加载,请稍后再试');
return;
}
window.dpz.openActionDialog({
title: '删除客户端',
description: `将删除 <strong>${name}</strong> 的所有关联配置,操作不可恢复。`,
confirmText: '确认删除',
cancelText: '取消',
fields: [
{
id: 'pinCode',
type: 'pin',
label: '2FA PIN',
placeholder: '6位验证码',
help: '为安全起见,删除需验证双因素 PIN',
required: true,
validator: value => /^\d{6}$/.test(value) || '请输入 6 位 PIN',
}
],
onConfirm: values =>
submitForm('/Application/Delete', {
id: data.id,
pinCode: values.pinCode
})
});
}
async function submitForm(action, fields) {
const formData = new FormData();
Object.entries(fields).forEach(([key, value]) => formData.append(key, value ?? ''));
try {
const response = await fetch(action, {
method: 'POST',
body: formData
});
const result = await response.json();
if (result.success) {
layer.msg(result.message || '操作成功');
reloadTable();
return true;
}
layer.alert(result.message || '操作失败');
return false;
} catch (e) {
console.warn('application delete fail', e);
layer.alert('请求失败,请稍后再试');
return false;
}
}
});