First Commit

This commit is contained in:
Administrator
2025-05-12 12:04:42 +08:00
commit 6a5e13974c
1248 changed files with 366157 additions and 0 deletions

View File

@@ -0,0 +1,116 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{admin/v1/include::head}">
</head>
<style>
.layui-elem-quote-warning {
border-left: 5px solid #d8a900;
}
.layui-form-mid {
float: none;
}
</style>
<body>
<ul th:replace="~{admin/v1/include::nav}"></ul>
<div class="manage-body">
<div>
<h1 class="manage-title">
<b>指标配置</b>
<a href="#" class="help"><i class="layui-icon layui-icon-help"></i></a>
<a href="javascript:openUpdateForm()" class="operate">更新</a>
</h1>
</div>
<div>
<table class="layui-table" id="indexInfos" lay-filter="indexInfos">
</table>
</div>
</div>
<script type="text/html" id="operationTpl">
<div class="layui-btn-group">
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="detail">详情</a>
</div>
</script>
<div th:replace="~{admin/v1/include::feet}"></div>
<th:block th:replace="~{admin/v1/include::head-script}"></th:block>
<script>
layui.use(function(){
const form = layui.form, layer = layui.layer, table = layui.table;
const help = document.querySelector('.help');
help.addEventListener('click', (e) => {
e.preventDefault();
layer.open({
title: '帮助',
shadeClose: !0,
content:
[
'益盟操盘手指标配置,一般需要从 APK 包中获取 <span>config_ind_online.json</span> 文件',
'该界面提供可视化查看指标信息的功能,并允许用户从云端拉取、编辑配置文件',
'此处的指标配置决定了任务能够更新的指标和细节,包括指标参数限制、数据粒度限制等'
].join('<br/>')
})
})
document.querySelectorAll('[lay-skin="switch"]').forEach(check => {
form.on(`switch(${check.getAttribute('lay-filter')})`, (data) => {
var el = data.elem;
el.value = !!el.checked;
});
})
table.render({
elem: '#indexInfos',
url: '/admin/v1/manage/indexInfo/configIndOnline',
skin: 'line',
cols: [ [
{field: 'indexCode', title: '指标代码'},
{field: 'indexName', title: '指标名称'},
{field: 'isCalc', title: '是否传统算法', templet: (d) => {
return d.isCalc ?
'<i class="op-green fa-solid fa-circle-check"></i>' :
'<i class="op-red fa-solid fa-circle-exclamation"></i>';
}},
{field:'operation', title: '操作', toolbar: '#operationTpl'}
]],
where: {
fields: 'configIndOnline'
},
headers: {
'Content-Type': 'application/json'
},
parseData: (json) => {
console.log(json)
const jo = json.data, indMap = jo.indMap;
const data = [];
Object.keys(indMap).forEach(key => {
const indInfo = indMap[key];
const row = {
indexCode: key,
indexName: jo.indIdNameConfig[key],
isCalc: indInfo.isCalc,
indInfo: indInfo
};
data.push(row)
})
return {
code: json.ok ? 0 : 1,
msg: json.message,
data: data,
count: data.length
}
}
})
table.on('tool(indexInfos)', (obj) => {
if (obj.event == 'detail') {
}
})
})
</script>
<th:block th:replace="~{admin/v1/manage/indexInfo/updateForm::indexInfoUpdateForm}"></th:block>
</body>
</html>

View File

@@ -0,0 +1,164 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<th:block th:fragment="indexInfoUpdateForm">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.2/codemirror.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.2/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.2/mode/javascript/javascript.min.js"></script>
<!-- JSON通常用JavaScript模式 -->
<script id="index-info-update-form" type="text/html">
<style>
.layui-layer>#updateFormLayer.layui-layer-content {
overflow: auto !important;
}
.CodeMirror {
border: 1px solid #eee;
border-radius: 2px;
}
</style>
<div class="layui-form" style="margin:10px 15px" id="editPlanForm" lay-filter="editPlanForm">
<div class="layui-form-item with-inline-btn">
<label class="layui-form-label">配置文件 URL</label>
<div class="layui-inline">
<input type="text" name="configIndOnlineUrl" placeholder="" autocomplete="off" class="layui-input"/>
</div>
<div class="layui-inline">
<button class="layui-btn" id="pull-online-file">拉取</button>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">配置文件</label>
<div class="layui-input-block" id="editor-wrapper">
<textarea id="config-editor" class="layui-textarea"></textarea>
</div>
</div>
<div style="display:none" class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit="*" lay-filter="submitIndexConfigFile">提交</button>
</div>
</div>
</div>
</script>
<script type="text/javascript">
async function openUpdateForm() {
// 获取必要项
const base = '/admin/v1/manage/indexInfo';
const res = await fetch(
`${base}/getFields?fields=${['configIndOnlineUrl', 'configIndOnlineStr'].join(',')}`
);
const result = await res.json();
if (!res.ok) {
Dog.error({msg: result.message || '获取配置失败'});
return
}
window.updateConfigLayer = layui.layer.open({
id: 'updateFormLayer',
type: 1,
title: '更新配置文件',
btn: ['提交', '关闭'],
yes: function (index, layero) {
const submitBtn = document.querySelector('[lay-filter="submitIndexConfigFile"]');
submitBtn.click();
const formData = new FormData(document.getElementById(editPlanForm));
console.log(formData)
//layero.find('[lay-filter="submitIndexConfigFile"]').click()
},
area: ['800px', '540px'],
shadeClose: !0,
content: document.getElementById('index-info-update-form').innerHTML,
success: function (layero, layerIndex) {
const textarea = document.getElementById("config-editor");
const urlInput = document.querySelector('[name="configIndOnlineUrl"]');
const data = result.data;
urlInput.value = data.configIndOnlineUrl;
textarea.textContent = data.configIndOnlineStr;
document.getElementById('pull-online-file').addEventListener('click', async function (e) {
const load = layui.layer.load(2);
const resJson =
await (await fetch(`${base}/getConfigIndOnlineByUrl?url=${urlInput.value}`)).json();
try {
if (!resJson.ok) {
Dog.error({msg: resJson.message || '拉取失败'});
return
}
Dog.success({msg: '拉取成功'});
editor.setValue(textarea.textContent = resJson.data)
}
finally {
layui.layer.close(load)
}
});
const editor = CodeMirror.fromTextArea(textarea, {
mode: {name: "javascript", json: true}, // 使用JavaScript模式来高亮JSON
lineNumbers: true,
indentUnit: 4, // 每一级缩进为 4 个空格
indentWithTabs: false, // 不使用 tab 字符,使用空格缩进
extraKeys: {
Tab: function (cm) {
if (cm.somethingSelected()) {
cm.indentSelection("add");
} else {
const cursor = cm.getCursor();
const line = cm.getLine(cursor.line);
const beforeCursor = line.slice(0, cursor.ch);
const col = CodeMirror.countColumn(beforeCursor, null, cm.getOption("tabSize"));
const indentSize = cm.getOption("indentUnit");
const spacesToInsert = indentSize - (col % indentSize);
const spaces = " ".repeat(spacesToInsert);
cm.replaceSelection(spaces, "end", "+input");
}
},
"Shift-Tab": function (cm) {
cm.indentSelection("subtract");
}
}
});
enableCodeMirrorResize(editor, document.getElementById("editor-wrapper"))
}
})
}
function enableCodeMirrorResize(editor, wrapperElement, minHeight = 100) {
// 创建拖动手柄
const handle = document.createElement("div");
handle.className = "cm-resize-handle";
wrapperElement.appendChild(handle);
Object.assign(handle.style, {
height: "8px",
background: "#ccc",
cursor: "ns-resize",
position: "absolute",
bottom: "-8px",
left: "0",
right: "0",
zIndex: "10"
});
// 添加 wrapper 相对定位
wrapperElement.style.position = "relative";
let isDragging = false;
handle.addEventListener("mousedown", (e) => {
isDragging = true;
document.body.style.cursor = "ns-resize";
e.preventDefault();
});
document.addEventListener("mousemove", (e) => {
if (!isDragging) return;
const wrapperTop = wrapperElement.getBoundingClientRect().top;
const newHeight = e.clientY - wrapperTop;
if (newHeight > minHeight) {
editor.setSize(null, newHeight + "px");
}
});
document.addEventListener("mouseup", () => {
isDragging = false;
document.body.style.cursor = "default";
});
}
</script>
</th:block>

View File

@@ -0,0 +1,289 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<div th:fragment="planExtra">
<script id="addPlan" type="text/html">
<style>.layui-form-select dl{max-height: 160px}</style>
<div class="layui-form" style="margin:10px 15px" id="editPlanForm" lay-filter="editPlanForm">
<div class="layui-form-item">
<input type="hidden" name="planId"/>
<label class="layui-form-label">计划名称<span>*</span></label>
<div class="layui-input-block">
<input type="text" lay-verify="required" name="planName" placeholder="" autocomplete="off" class="layui-input"/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">计划表达式<span>*</span></label>
<div class="layui-input-block">
<input type="text" lay-verify="required" name="cronExpression" placeholder="" autocomplete="off" class="layui-input"/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">更新指标<span>*</span></label>
<div class="layui-input-block">
<div class="layui-inline">
<select name="indexCode" lay-filter="indexCodeFilter" lay-search>
<option value="">选择更新指标</option>
</select>
</div>
</div>
</div>
<div id="params">
</div>
<div id="periods">
</div>
<div class="layui-form-item">
<label class="layui-form-label">启用<span>*</span></label>
<div class="layui-input-block">
<input type="checkbox"
name="enabled" lay-skin="switch" lay-filter="enabled" lay-text="ON|OFF">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">交易日校验<span>*</span></label>
<div class="layui-input-block">
<input type="checkbox"
name="openDayCheck" lay-skin="switch" lay-filter="openDayCheck" lay-text="ON|OFF">
</div>
</div>
<div style="display:none" class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit="*" lay-filter="submitPlan">提交</button>
</div>
</div>
</div>
</script>
<script type="text/html" id="periodsTemplet">
<div class="layui-form-item">
<label class="layui-form-label">更新粒度<span>*</span></label>
<div class="layui-input-block">
<div id="period-xm-select" style="width: 100%" class="layui-inline"></div>
</div>
</div>
</script>
<script type="text/html" id="paramTemplet">
<div class="layui-form-item">
<label class="layui-form-label">{{d.pName}}<span>*</span></label>
<div class="layui-input-block">
<input type="number"
min="{{d.pMin}}" max="{{d.pMax}}"
name="params.{{d.pName}}"
lay-verify="required|min:{{d.pMin}}|max:{{d.pMax}}|number"
placeholder="范围:{{d.pMin}} ~ {{d.pMax}}"
value="{{d.pValue}}" autocomplete="off" class="layui-input"/>
</div>
</div>
</script>
<script type="text/javascript">
layui.form.on('submit(submitPlan)', function (obj) {
var field = obj.field, data = {params: {}}
Object.keys(field).forEach(key => {
if (key.indexOf('params') == 0) {
data.params[key.substr(7)] = field[key]
}
else if (key == 'periods') {
data.periods = field.periods.split(',')
}
else {
data[key] = field[key]
}
})
$.ajax({
url: '/admin/v1/manage/plan/save',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify(data),
success: function (r) {
layer.msg('操作成功', {
offset: '15px',
icon: 1,
time: 1000
},
function () {
if (window.editLayer) {
layui.layer.close(window.editLayer);
}
layui.table.reload('plans', {
page: {
curr: $(".layui-laypage-em").next().html() //当前页码值
}
});
}
)
}
})
})
function openEditForm(r) {
if (r && r.ok) {
window.editLayer = layui.layer.open({
type: 1,
title: `${r.data.planId ? '编辑' : '新增'}计划任务`,
btn: ['提交', '关闭'],
yes: function (index, layero) {
layero.find('[lay-filter="submitPlan"]').click()
},
skin: "layui-anim layui-anim-rl layui-layer-adminRight",
area: '500px',
anim: -1,
shadeClose: !0,
closeBtn: !1,
move: !1,
offset: 'r',
content: $('#addPlan').html(),
success: async function (layero, layerIndex) {
var el = $(layero);
['planId', 'planName', 'cronExpression', 'indexCode'].forEach(x => {
const fieldEl = el[0].querySelector(`[name="${x}"]`);
if (!fieldEl) return;
fieldEl.value = r.data[x];
});
['enabled', 'openDayCheck'].forEach(x => {
const fieldEl = el[0].querySelector(`[name="${x}"]`);
if (!fieldEl) return;
fieldEl.checked = r.data[x];
fieldEl.value = r.data[x];
layui.form.on('switch(' + x + ')', obj => obj.elem.value = obj.elem.checked)
});
layui.cron.render({
elem: '[name="cronExpression"]',
btns: ['confirm'],
cssPath: '/admin/v1/static/css/cron.css'
});
layui.form.on('select(indexCodeFilter)', async function (obj) {
const paramsEl = document.getElementById('params');
const periodsEl = document.getElementById('periods');
paramsEl.textContent = periodsEl.textContent = '';
const indInfo =
JSON.parse(obj.elem.querySelector(`[value="${obj.value}"]`).dataset.indInfo);
const paramTemplet = document.getElementById('paramTemplet');
const periodsTemplet = document.getElementById('periodsTemplet');
if (indInfo.indParam) {
var tpl = layui.laytpl(paramTemplet.textContent);
for (var i = 0; i < indInfo.indParam.pName.length; i++) {
var d = {
pName: indInfo.indParam.pName[i],
pMin: indInfo.indParam.min[i],
pMax: indInfo.indParam.max[i],
pValue: indInfo.indParam.value[i]
}
if (obj.params && obj.params[d.pName]) {
d.pValue = obj.params[d.pName]
}
paramsEl.insertAdjacentHTML('beforeend', tpl.render(d));
}
}
var periods = Helper.allEmoneyPeriods;
if (indInfo.supportPeriod) periods = indInfo.supportPeriod;
periodsEl.insertAdjacentHTML('beforeend', periodsTemplet.textContent);
var data = [];
for (var i = 0; i < periods.length; i++) {
var period = periods[i];
data.push({
name: Helper.emoneyPeriodToName(period),
value: period,
selected: r.data.periods.indexOf(period + '') != -1
})
}
layui.xmSelect.render({
name: 'periods',
el: '#period-xm-select',
language: 'zn',
data: data,
autoRow: !0
})
layui.form.render()
})
const loadConfigLayer = layui.layer.load(2);
const json = await (await fetch('/admin/v1/manage/indexInfo/configIndOnline')).json();
if (json.ok) {
const indexNameSelectEl = document.querySelector('[name="indexCode"]');
const jo = json.data, indMap = jo.indMap;
let selected = undefined;
const optionsFragment = document.createDocumentFragment();
Object.keys(indMap).forEach(key => {
const indInfo = indMap[key];
if (indInfo.isCalc) return;
if (r.data.indexCode == key) selected = key;
const option = document.createElement('option');
option.value = key;
option.textContent = `${key} ${jo.indIdNameConfig[key]}`;
option.selected = r.data.indexCode == key;
option.dataset.indInfo = JSON.stringify(indInfo);
optionsFragment.appendChild(option);
})
indexNameSelectEl.appendChild(optionsFragment);
if (selected)
// 如果有选择内容, 手动触发指标选择下拉框,并附带参数
layui.event.call(this, 'form', 'select(indexCodeFilter)', {
elem: indexNameSelectEl,
value: selected,
params: r.data.params
});
layui.form.render();
}
else {
Dog.error({
msg: json.data || '获取指标配置错误'
});
layui.layer.close(window.editLayer);
}
layui.form.render();
layui.layer.close(loadConfigLayer);
}
})
}
else Dog.error({
msg: r && r.data || '服务器错误'
});
}
async function openNewForm(planId) {
const json = await (await fetch((() => {
const url = '/admin/v1/manage/plan/getOne';
if (planId) return url + '?planId=' + planId;
return url
})())).json();
if (json.ok) {
openEditForm(json)
}
else {
window.toastModule.errorLayer({
msg: json.data || '服务器错误'
});
}
}
layui.table.on('tool(plans)', async function (obj) {
if (obj.event == 'edit') {
openNewForm(obj.data.planId)
}
else if (obj.event == 'del') {
layui.layer.confirm('确定删除该计划任务吗?', function (index) {
layui.layer.close(index);
$.ajax({
url: '/admin/v1/manage/plan/delete',
method: 'POST',
data: {planId: obj.data.planId},
success: function (data) {
layui.table.reload('plans', {
page: {
curr: $(".layui-laypage-em").next().html() //当前页码值
}
});
layer.msg('删除成功', {offset: '15px', icon: 1, time: 1000})
},
error: function (res) {
var r = res.responseJSON;
layer.msg(r && r.data || '服务器错误',
{offset: '15px', icon: 2, time: 2000});
return
}
})
})
}
})
</script>
</div>
</html>

View File

@@ -0,0 +1,168 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:insert="~{admin/v1/include::head}"
th:with="title=${'计划任务管理'}">
</head>
<body>
<ul th:replace="~{admin/v1/include::nav}"></ul>
<div class="manage-body">
<div>
<h1 class="manage-title">
<b>计划任务列表</b><a href="javascript:openNewForm()" class="operate">新增</a>
</h1>
</div>
<button class="layui-btn layui-btn-sm operdown">
<span>选中项<i
class="layui-icon layui-icon-sm layui-icon-triangle-d"></i></span>
</button>
<div>
<table class="layui-table" id="plans" lay-filter="plans">
</table>
</div>
</div>
<div th:replace="~{admin/v1/include::feet}"></div>
<script type="text/html" id="operationTpl">
<div class="layui-btn-group">
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
</div>
</script>
<th:block th:replace="~{admin/v1/include::head-script}"></th:block>
<script th:inline="javascript">
layui
.extend({
xmSelect: '/admin/v1/static/layuiadmin/lib/xm-select',
cron: '/admin/v1/static/layuiadmin/lib/cron'
})
.use(['table', 'form', 'dropdown', 'layer', 'xmSelect', 'cron'], function(){
var dropdown = layui.dropdown, table = layui.table, form = layui.form;
function switchTemplet(d) {
var fieldName = d.LAY_COL.field;
return `<input type="checkbox" lay-skin="switch" lay-text="|"
data-field="${fieldName}" data-id="${d.planId}"
${d[fieldName] ? 'checked' : ''} lay-filter="switchFilter">`;
}
table.render({
elem: '#plans',
url:'/admin/v1/manage/plan/list',
page:true, skin:'line',
cols: [ [
{type:'checkbox'},
{field:'enabled', title: '启用', width: 95, templet: switchTemplet},
{field:'openDayCheck', title: '交易日校验', width: 95, templet: switchTemplet},
{field:'planId', hide: true, width: 60, title: 'ID'},
{field:'planName', title: '计划名称'},
{field:'cronExpression', title: '计划表达式'},
{field:'indexCode', title: '指标代码'},
{field:'params', title: '请求参数',templet: function(d) {
if (typeof d.params === 'object' && d.params !== null) {
return Object.entries(d.params).map(([key, value]) => `${key}=${value}`).join(', ');
}
return d.params || '无';
}},
{field:'periods', title: '更新粒度', templet: function(d) {
if (typeof d.periods === 'object' && d.periods !== null) {
return d.periods.map(x => Helper.emoneyPeriodToName(x)).join(', ')
}
return d.periods || '无';
}},
{field:'operation', title: '操作', toolbar: '#operationTpl'}
]]
});
form.on('switch(switchFilter)', function(obj) {
console.log(obj);
console.log(obj.elem.checked);
$.ajax({
url: '/admin/v1/manage/plan/updateBool',
method: 'POST',
data: {
planId: obj.elem.dataset.id,
field: obj.elem.dataset.field,
value: obj.elem.checked
},
success: function () {
layer.msg('操作成功', {
offset: '15px',
icon: 1,
time: 1000
},
function() {}
)
},
error: function (res) {
var r = res.responseJSON;
layer.msg(r && r.data || '服务器错误', {
offset: '15px',
icon: 2,
time: 1000
});
// 恢复 enabled 状态
obj.elem.checked = !obj.elem.checked;
layui.form.render('checkbox')
return
}
})
});
dropdown.render({
elem: '.operdown',
data: [
{title: '删除'},
{title: '启用', op: 'enable'},
{title: '停用', op: 'disable'},
{title: '开启交易日校验', op: 'enableOpenDayCheck'},
{title: '关闭交易日校验', op: 'disableOpenDayCheck'}],
click: function (data, othis){
var checked = layui.table.checkStatus('plans'), planIds = [];
if (!checked.data.length) {
layui.layer.msg('未选中任何项', {time: 1000});
return;
}
$.each(checked.data, function (i, plan){
planIds.push(plan.planId);
});
data = $.extend(data, {ids: planIds});
var op = function() {
$.ajax({
url: '/admin/v1/manage/plan/batchOp',
method: 'POST',
data: data,
success: function () {
layer.msg('批量操作成功', {
offset: '15px',
icon: 1,
time: 1000
},
function() {
layui.table.reload('plans', {
page: {
curr: $(".layui-laypage-em").next().html() //当前页码值
}
});
}
)
},
error: function (res) {
var r = res.responseJSON;
layer.msg(r&&r.data||'服务器错误', {
offset: '15px',
icon: 2,
time: 1000
});
return
}
})
}
data.op ? op() : layer.confirm('确认批量删除吗?该操作不可恢复', function(){
op();
})
}
});
})
</script>
<th:block th:replace="~{admin/v1/manage/plan/include::planExtra}"></th:block>
</body>
</html>

View File

@@ -0,0 +1,128 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<div th:fragment="protocolMatchExtra">
<script id="addProtocolMatch" type="text/html">
<style>.layui-form-select dl{max-height: 160px}</style>
<div class="layui-form" style="margin:10px 15px" id="editPlanForm" lay-filter="editPlanForm">
<div class="layui-form-item">
<label class="layui-form-label">Protocol ID<span>*</span></label>
<div class="layui-input-block">
<input type="text" lay-verify="required|number" name="protocolId" placeholder="" autocomplete="off" class="layui-input"/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">类名</label>
<div class="layui-input-block">
<input type="text" name="className" placeholder="" autocomplete="off" class="layui-input"/>
</div>
</div>
<div style="display:none" class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit="*" lay-filter="submitProtocolMatch">提交</button>
</div>
</div>
</div>
</script>
<script type="text/javascript">
layui.form.on('submit(submitProtocolMatch)', function(obj){
var field = obj.field, data = {params: {}}
Object.keys(field).forEach(key => {
data[key] = field[key]
});
$.ajax({
url: '/admin/v1/manage/protocolMatch/save',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify(data),
success: function (r) {
layer.msg('操作成功', {
offset: '15px',
icon: 1,
time: 1000
},
function() {
if (window.editLayer) {
layui.layer.close(window.editLayer);
}
layui.table.reload('protocolMatches',{
page: {
curr: $(".layui-laypage-em").next().html() //当前页码值
}
});
}
)
}
})
})
function openEditForm(r) {
if (r && r.ok) {
window.editLayer = layui.layer.open({
type: 1,
title: `${r.data.planId ? '编辑' : '新增'}Protocol`,
btn: ['提交', '关闭'],
yes: function(index, layero) {
layero.find('[lay-filter="submitProtocolMatch"]').click()
},
skin: "layui-anim layui-anim-rl layui-layer-adminRight",
area: '500px',
anim: -1,
shadeClose: !0,
closeBtn: !1,
move: !1,
offset: 'r',
content: $('#addProtocolMatch').html(),
success: function(layero, layerIndex) {
var el = $(layero);
['protocolId', 'className'].forEach(x => {
el.find(`[name="${x}"]`).val(r.data[x])
});
}
})
}
else layer.msg(r && r.data || '服务器错误', {offset: '15px', icon: 2, time: 1000})
}
function openNewForm(protocolId) {
$.ajax({
url: '/admin/v1/manage/protocolMatch/getOne',
data: {protocolId: protocolId},
success: function(r) {
openEditForm(r)
},
error: function(xhr) {
var r = xhr.responseJSON;
layer.msg(r && r.data || '服务器错误', {offset: '15px', icon: 2, time: 100})
}
})
}
layui.table.on('tool(protocolMatches)', function(obj) {
if (obj.event == 'edit') {
openNewForm(obj.data.protocolId)
}
else if (obj.event == 'del') {
layui.layer.confirm('确定删除该映射吗?', function (index) {
layui.layer.close(index);
$.ajax({
url: '/admin/v1/manage/protocolMatch/delete',
method: 'POST',
data: {planId: obj.data.protocolId},
success: function (data) {
layui.table.reload('protocolMatches',{
page: {
curr: $(".layui-laypage-em").next().html() //当前页码值
}
});
layer.msg('删除成功', {offset: '15px', icon: 1, time: 1000})
},
error: function (res) {
var r = res.responseJSON;
layer.msg(r&&r.data||'服务器错误',
{offset: '15px', icon: 2, time: 2000});
return
}
})
})
}
})
</script>
</div>
</html>

View File

@@ -0,0 +1,134 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:insert="~{admin/v1/include::head}"
th:with="title=${'Protocol 管理'}">
</head>
<body>
<ul th:replace="~{admin/v1/include::nav}"></ul>
<div class="manage-body">
<div>
<h1 class="manage-title">
<b>Protocol ID 映射表</b>
<a href="#" class="help"><i class="layui-icon layui-icon-help"></i></a>
<a href="javascript:openUploadForm()" class="operate">上传</a>
<a href="javascript:openNewForm()" class="operate">新增</a>
</h1>
</div>
<button class="layui-btn layui-btn-sm operdown">
<span>选中项<i
class="layui-icon layui-icon-sm layui-icon-triangle-d"></i></span>
</button>
<div>
<table class="layui-table" id="protocolMatches" lay-filter="protocolMatches">
</table>
</div>
</div>
<div th:replace="~{admin/v1/include::feet}"></div>
<script type="text/html" id="operationTpl">
<div class="layui-btn-group">
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
</div>
</script>
<th:block th:replace="~{admin/v1/include::head-script}"></th:block>
<script th:inline="javascript">
layui
.extend({
xmSelect: '/admin/v1/static/layuiadmin/lib/xm-select',
cron: '/admin/v1/static/layuiadmin/lib/cron'
})
.use(['table', 'form', 'dropdown', 'layer', 'xmSelect', 'cron'], function(){
var dropdown = layui.dropdown, table = layui.table, form = layui.form;
$('.help').on('click', function (e) {
e.preventDefault();
layer.open({
title: '帮助',
content:
'益盟操盘手 Protocol-Id 设置,用来映射 Id 与解析类的关系。<br>'+
'一般需要从 APK 包中获取 nano 包下的文件以及 ProtocolIDs.java 文件'
})
})
function switchTemplet(d) {
var fieldName = d.LAY_COL.field;
return `<input type="checkbox" lay-skin="switch" lay-text="|"
data-field="${fieldName}" data-id="${d.planId}"
${d[fieldName] ? 'checked' : ''} lay-filter="switchFilter">`;
}
table.render({
elem: '#protocolMatches',
url:'/admin/v1/manage/protocolMatch/list',
page:true, skin:'line',
cols: [ [
{type:'checkbox'},
{field:'protocolId', width: 100, title: 'ID'},
{field:'className', title: '类名'},
{field:'operation', title: '操作', width: 150, toolbar: '#operationTpl'}
]]
});
dropdown.render({
elem: '.operdown',
data: [
{title: '删除'},
{title: '启用', op: 'enable'},
{title: '停用', op: 'disable'},
{title: '开启交易日校验', op: 'enableOpenDayCheck'},
{title: '关闭交易日校验', op: 'disableOpenDayCheck'}],
click: function (data, othis){
var checked = layui.table.checkStatus('protocolMatches'), planIds = [];
if (!checked.data.length) {
layui.layer.msg('未选中任何项', {time: 1000});
return;
}
$.each(checked.data, function (i, plan){
planIds.push(plan.planId);
});
data = $.extend(data, {ids: planIds});
var op = function() {
$.ajax({
url: '/admin/v1/manage/plan/batchOp',
method: 'POST',
data: data,
success: function () {
layer.msg('批量操作成功', {
offset: '15px',
icon: 1,
time: 1000
},
function() {
layui.table.reload('protocolMatches', {
page: {
curr: $(".layui-laypage-em").next().html() //当前页码值
}
});
}
)
},
error: function (res) {
var r = res.responseJSON;
layer.msg(r&&r.data||'服务器错误', {
offset: '15px',
icon: 2,
time: 1000
});
return
}
})
}
data.op ? op() : layer.confirm('确认批量删除吗?该操作不可恢复', function(){
op();
})
}
});
})
</script>
<th:block th:replace="~{admin/v1/manage/protocolMatch/include::protocolMatchExtra}"></th:block>
</body>
</html>