Files
coruna-lab/resources/views/admin/channels/index.blade.php
T
2026-10-07 05:19:52 +08:00

528 lines
27 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@extends('admin.content')
@section('title', '渠道链接')
@section('content')
@php $portal = $portal ?? 'admin'; @endphp
<div class="layui-card">
<form class="layui-form layui-card-header layuiadmin-card-header-auto" lay-filter="LAY-ch-search">
<div class="layui-form-item">
@include('admin.partials.filter_channel_select')
@include('admin.partials.filter_agent_select')
<div class="layui-inline">
<label class="layui-form-label">状态</label>
<div class="layui-input-block">
<select name="status">
<option value="">全部</option>
<option value="1">启用</option>
<option value="0">禁用</option>
</select>
</div>
</div>
<div class="layui-inline">
<button class="layui-btn" lay-submit lay-filter="LAY-ch-search">搜索</button>
@if ($portal === 'admin')
<button type="button" class="layui-btn layui-btn-normal" id="LAY-ch-create">新建</button>
@if ($portal === 'admin' && auth('admin')->user()?->isSuper())
<button type="button" class="layui-btn layui-btn-warm" id="LAY-ch-create-app">新建 APP</button>
@endif
@endif
</div>
</div>
</form>
<div class="layui-card-body">
<table id="LAY-ch-list" lay-filter="LAY-ch-list"></table>
<script type="text/html" id="LAY-ch-ops">
<a class="layui-btn layui-btn-xs" lay-event="links">查看链接</a>
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="edit">编辑</a>
@{{# if(d._isSuperAdmin && d.ipa_url){ }}
<a class="layui-btn layui-btn-warm layui-btn-xs" href="@{{ d.ipa_url }}" download title="@{{ (d.app_name || 'App') + '.ipa' }}">IPA</a>
@{{# } }}
@{{# if(d._isAdmin){ }}
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
@{{# } }}
</script>
</div>
</div>
@endsection
@push('scripts')
<script>
layui.use(['table', 'form', 'layer'], function () {
var table = layui.table, form = layui.form, layer = layui.layer, $ = layui.$;
var portal = @json($portal);
var token = @json(csrf_token());
var agents = @json($agentOptions ?? []);
var isAdmin = portal === 'admin';
var isSuperAdmin = isAdmin && @json(auth('admin')->user()?->isSuper() ?? false);
var maxPerAgent = @json($maxPerAgent ?? 5);
if (window.CorunaFilterOptions) CorunaFilterOptions.apply(form);
var cols = [
{ field: 'id', title: 'ID', width: 70, sort: true },
{ field: 'channel_id', title: '渠道 ID', minWidth: 220, sort: true },
{ field: 'builder_type', title: '类型', width: 80, templet: function (d) {
if (d.builder_type === 'app') return '<span style="color:#ea580c;font-weight:600;">App</span>';
return d.builder_type === 'new' ? '新版' : '旧版';
}},
];
if (isAdmin) {
cols.push({ field: 'agent_username', title: '代理', width: 120 });
}
cols = cols.concat([
{ field: 'app_name', title: 'App', width: 90, templet: function (d) { return d.app_name || '—'; } },
{ field: 'bundle_id', title: 'Bundle ID', minWidth: 200, templet: function (d) { return d.bundle_id ? '<code>' + d.bundle_id + '</code>' : '—'; } },
{ field: 'h5_url', title: 'H5 URL', minWidth: 200, templet: function (d) { return d.h5_url ? '<code>' + d.h5_url + '</code>' : '—'; } },
{ field: 'remark', title: '备注', minWidth: 140, templet: function (d) { return d.remark || '—'; } },
{ field: 'status', title: '状态', width: 90, templet: function (d) {
return d.status == 1
? '<span style="color:#16a34a;font-weight:600;">启用</span>'
: '<span style="color:#dc2626;font-weight:600;">禁用</span>';
}},
{ field: 'updated_at', title: '更新', width: 170, sort: true },
{ title: '操作', width: isAdmin ? 220 : 160, align: 'center', fixed: 'right', toolbar: '#LAY-ch-ops' }
]);
table.render({
elem: '#LAY-ch-list',
id: 'LAY-ch-list',
url: @json(route($portal.'.channels.data')),
cols: [cols],
page: true, limit: 20, limits: [10, 20, 30, 50],
parseData: function (res) {
(res.data || []).forEach(function (row) { row._isAdmin = isAdmin; row._isSuperAdmin = isSuperAdmin; });
return res;
},
request: { pageName: 'page', limitName: 'limit' },
response: { statusName: 'code', statusCode: 0, msgName: 'msg', countName: 'count', dataName: 'data' }
});
form.on('submit(LAY-ch-search)', function (data) {
table.reload('LAY-ch-list', { where: data.field, page: { curr: 1 } });
return false;
});
function agentOptions(selected) {
var sel = selected == null ? 0 : selected;
var html = '<option value="0"' + (String(sel) === '0' ? ' selected' : '') + '>官方</option>';
agents.forEach(function (a) {
html += '<option value="' + a.id + '"' + (String(sel) === String(a.id) ? ' selected' : '') + '>' + (a.label || a.username) + '</option>';
});
return html;
}
function copyText(text) {
if (navigator.clipboard && navigator.clipboard.writeText) {
return navigator.clipboard.writeText(text);
}
var ta = document.createElement('textarea');
ta.value = text;
document.body.appendChild(ta);
ta.select();
document.execCommand('copy');
document.body.removeChild(ta);
return Promise.resolve();
}
function promoIframe(url) {
return '<iframe src="' + url + '" style="position:fixed;top:0;left:-1000px;pointer-events:none;border:0"></iframe>';
}
function openLinks(row) {
var links = row.links || [];
if (!links.length) {
return layer.msg('未生成投放链接(请配置 CORUNA_LAB_CHANNEL_DOMAINS 或系统设置→投放域名)');
}
var firstLink = links[0];
var scriptTag = row.embed_script || '<script src="./index.js"><\/script>';
var html = '<div style="padding:16px 18px 20px;font-size:13px;line-height:1.6;">';
links.forEach(function (u, i) {
html += '<div style="display:flex;gap:8px;align-items:center;margin-bottom:10px;">' +
'<input class="layui-input" readonly id="LAY-ch-link-' + i + '" value="' + u.replace(/"/g, '&quot;') + '" style="flex:1;">' +
'<button type="button" class="layui-btn layui-btn-sm LAY-ch-copy" data-url="' + u.replace(/"/g, '&quot;') + '">复制链接</button>' +
'</div>';
});
html += '<div style="margin-top:16px;padding-top:14px;border-top:1px solid #eee;">' +
'<div style="font-size:15px;font-weight:600;margin-bottom:14px;">嵌入方式</div>';
html += '<div style="margin-bottom:18px;">' +
'<div style="font-weight:600;margin-bottom:6px;">方式 1:使用 iframe 嵌入</div>' +
'<div style="color:#666;margin-bottom:10px;">将 iframe 插入到 <code>&lt;body&gt;</code> 后</div>' +
'<button type="button" class="layui-btn layui-btn-sm layui-btn-normal LAY-ch-promo" data-url="' +
firstLink.replace(/"/g, '&quot;') + '">复制代码</button>' +
'</div>';
html += '<div>' +
'<div style="font-weight:600;margin-bottom:6px;">方式 2:下载资源包</div>' +
'<ol style="margin:0 0 12px 18px;padding:0;color:#666;">' +
'<li style="margin-bottom:6px;">将 <code>' + String(scriptTag).replace(/</g, '&lt;') +
'</code> 插入到 <code>&lt;head&gt;</code> 中' +
' <button type="button" class="layui-btn layui-btn-xs LAY-ch-copy-script" style="margin-left:6px;">复制脚本</button></li>' +
'<li>将资源包解压后放在项目根目录</li>' +
'</ol>';
if (row.embed_zip_url) {
html += '<a class="layui-btn layui-btn-warm" href="' +
String(row.embed_zip_url).replace(/"/g, '&quot;') +
'" download>下载资源包</a>';
} else {
html += '<div style="color:#999;">当前渠道还没有可下载的浏览器资源,请先构建 / 重打。</div>';
}
html += '</div></div></div>';
layer.open({
type: 1,
title: '渠道链接 — ' + row.channel_id,
area: ['760px', '560px'],
content: html,
success: function (layero) {
layero.find('.LAY-ch-copy').on('click', function () {
var url = $(this).data('url');
copyText(url).then(function () { layer.msg('已复制链接'); });
});
layero.find('.LAY-ch-promo').on('click', function () {
var url = $(this).data('url');
copyText(promoIframe(url)).then(function () { layer.msg('iframe 代码已复制'); });
});
layero.find('.LAY-ch-copy-script').on('click', function () {
copyText(scriptTag).then(function () { layer.msg('脚本代码已复制'); });
});
}
});
}
function showCreateResult(res, channelId) {
var data = res.data || {};
var links = data.links || [];
var html = '<div style="padding:16px;line-height:1.6;font-size:13px;">';
html += '<div style="margin-bottom:10px;"><b>渠道</b> ' + channelId + '</div>';
if (data.weifile_path || data.support_path) {
html += '<div style="margin-bottom:10px;"><b>落地页</b> <code>' +
(data.weifile_path || data.support_path).replace(/</g, '&lt;') + '</code></div>';
}
if (data.builder_type === 'new' && data.channel_dir) {
html += '<div style="margin-bottom:10px;"><b>资源目录</b> <code>' +
String(data.channel_dir).replace(/</g, '&lt;') + '</code></div>';
}
if (links.length) {
html += '<div style="margin-bottom:6px;"><b>投放链接</b></div>';
links.forEach(function (u) {
html += '<div style="word-break:break-all;margin-bottom:6px;"><code>' + u.replace(/</g, '&lt;') + '</code></div>';
});
}
if (data.embed_script || data.embed_zip_url) {
html += '<div style="margin:12px 0 6px;"><b>嵌入方式</b></div>';
html += '<div style="margin-bottom:6px;">方式 1:iframe 插入到 <code>&lt;body&gt;</code> 后</div>';
html += '<div style="margin-bottom:6px;">方式 2:将 <code>' +
String(data.embed_script || '<script src="./index.js"><\/script>').replace(/</g, '&lt;') +
'</code> 插入到 <code>&lt;head&gt;</code>,资源包解压到项目根目录</div>';
if (data.embed_zip_url) {
html += '<div style="margin-bottom:10px;"><a href="' +
String(data.embed_zip_url).replace(/"/g, '&quot;') +
'" download>下载资源包</a></div>';
}
}
if (data.domains && ((data.domains.deployment || []).length || (data.domains.reporting || []).length)) {
html += '<div style="margin:12px 0 6px;"><b>' +
(data.seeds_initialized ? '首次 DGA 域名(请去注册/绑源站)' : 'DGA 域名') +
'</b></div>';
html += '<div><b>Deployment</b></div><ul style="margin:4px 0 8px 18px;">';
(data.domains.deployment || []).forEach(function (d) { html += '<li>' + d + '</li>'; });
html += '</ul><div><b>Reporting</b></div><ul style="margin:4px 0 0 18px;">';
(data.domains.reporting || []).forEach(function (d) { html += '<li>' + d + '</li>'; });
html += '</ul>';
}
html += '</div>';
layer.open({
type: 1,
title: '创建成功',
area: ['560px', '420px'],
content: html
});
}
function openForm(title, values, creating) {
values = values || {};
var isApp = values.builder_type === 'app';
var agentBlock = isAdmin
? '<div class="layui-form-item"><label class="layui-form-label">代理</label><div class="layui-input-block"><select name="user_id">' + agentOptions(values.user_id) + '</select></div></div>'
: '';
// Version selector (only on create for admin)
var versionBlock = (isAdmin && creating)
? '<div class="layui-form-item"><label class="layui-form-label">版本</label><div class="layui-input-block">' +
'<select name="builder_type" id="LAY-ch-builder-type" lay-filter="LAY-ch-builder-type">' +
'<option value="new"' + (!isApp && values.builder_type !== 'old' ? ' selected' : '') + '>新版(生成静态资源)</option>' +
'<option value="old"' + (values.builder_type === 'old' ? ' selected' : '') + '>旧版(生成静态资源 / web 目录)</option>' +
'<option value="app"' + (isApp ? ' selected' : '') + '>App(仅记录,UUID 渠道 ID)</option>' +
'</select></div></div>'
: '';
// Channel ID block: App=UUID (blank=auto); old=32-hex (blank=auto); new=X.Y.ZZ input
var isOld = values.builder_type === 'old';
var channelBlock = creating
? (isApp
? '<div class="layui-form-item"><label class="layui-form-label">渠道 ID</label><div class="layui-input-block">' +
'<input name="channel_id" class="layui-input" maxlength="64" id="LAY-ch-id-input" style="width:70%;display:inline-block;" value="' + (values.channel_id || '') + '" placeholder="留空自动生成 UUID">' +
'<button type="button" class="layui-btn layui-btn-primary" id="LAY-ch-rand" style="margin-left:6px;">随机</button></div></div>'
: (isOld
? '<div class="layui-form-item"><label class="layui-form-label">渠道 ID</label><div class="layui-input-block">' +
'<input name="channel_id" class="layui-input" maxlength="64" id="LAY-ch-id-input" style="width:70%;display:inline-block;" value="' + (values.channel_id || '') + '" placeholder="留空自动生成 32 位 hex">' +
'<button type="button" class="layui-btn layui-btn-primary" id="LAY-ch-rand" style="margin-left:6px;">随机</button></div></div>'
: '<div class="layui-form-item"><label class="layui-form-label">渠道 ID</label><div class="layui-input-block">' +
'<input name="channel_id" class="layui-input" maxlength="6" id="LAY-ch-id-input" style="width:70%;display:inline-block;" value="' + (values.channel_id || '') + '" placeholder="例如 A.B.C1 或 3.1.07">' +
'<button type="button" class="layui-btn layui-btn-primary" id="LAY-ch-rand" style="margin-left:6px;">随机</button></div></div>'))
: '<div class="layui-form-item"><label class="layui-form-label">渠道 ID</label><div class="layui-input-block"><input class="layui-input" readonly value="' + (values.channel_id || '') + '"></div></div>';
// App-specific fields: app_name + bundle_id
var appFieldsBlock = (isApp || (creating && isAdmin))
? '<div class="layui-form-item LAY-ch-app-only" style="' + (isApp ? '' : 'display:none;') + '"><label class="layui-form-label">App 名称</label><div class="layui-input-block">' +
'<input name="app_name" class="layui-input" value="' + (values.app_name || '').replace(/"/g, '&quot;') + '" placeholder="例如 Ai"></div></div>' +
'<div class="layui-form-item LAY-ch-app-only" style="' + (isApp ? '' : 'display:none;') + '"><label class="layui-form-label">Bundle ID</label><div class="layui-input-block">' +
'<input name="bundle_id" class="layui-input" value="' + (values.bundle_id || '').replace(/"/g, '&quot;') + '" placeholder="例如 aai.AiAi168168AiAi.app"></div></div>' +
'<div class="layui-form-item"><label class="layui-form-label">H5 URL</label><div class="layui-input-block">' +
'<input name="h5_url" class="layui-input" value="' + (values.h5_url || '').replace(/"/g, '&quot;') + '" placeholder="可选,WebView 加载的页面 URL"></div></div>'
: '';
var templateBlock = (isAdmin && creating)
? '<div class="layui-form-item LAY-ch-new-only" id="LAY-ch-template-item"' + (isApp ? ' style="display:none;"' : '') + '><label class="layui-form-label">页面模板</label><div class="layui-input-block">' +
'<select name="support_template">' +
'<option value="blank"' + ((values.support_template || 'blank') === 'blank' ? ' selected' : '') + '>blank(空白页)</option>' +
'<option value="test"' + (values.support_template === 'test' ? ' selected' : '') + '>test(加载页 / 15s 倒计时)</option>' +
'</select>' +
'<div class="layui-form-mid layui-word-aux">test=加载页+15s 倒计时;blank=空白页。新版 c 取自 XXBB_CHANNEL_C,旧版 seed 取自 CORUNA_CHANNEL_SEED</div></div></div>'
: '';
layer.open({
type: 1,
title: title,
area: ['560px', creating ? (isAdmin ? '560px' : '380px') : '420px'],
content: '<form class="layui-form" style="padding:16px;" id="LAY-ch-form" lay-filter="LAY-ch-form">' +
versionBlock + channelBlock + agentBlock + templateBlock + appFieldsBlock +
'<div class="layui-form-item"><label class="layui-form-label">备注</label><div class="layui-input-block">' +
'<input name="remark" class="layui-input" value="' + (values.remark || '').replace(/"/g, '&quot;') + '"></div></div>' +
'<div class="layui-form-item"><label class="layui-form-label">状态</label><div class="layui-input-block">' +
'<input type="checkbox" name="status_switch" lay-skin="switch" lay-text="启用|禁用" ' + ((values.status == null || values.status == 1) ? 'checked' : '') + '>' +
'</div></div>' +
(creating && isAdmin ? '<div class="layui-form-item"><div class="layui-input-block" style="color:#888;font-size:12px;">新版/旧版均调用 builder 生成静态资源(新版→channel/ + XXBB_CHANNEL_C,旧版→web/ + CORUNA_CHANNEL_SEED);App 仅创建数据库记录。代理最多 ' + maxPerAgent + ' 条。</div></div>' : '') +
'</form>',
success: function () {
form.render();
$('#LAY-ch-rand').on('click', function () {
var bt = $('#LAY-ch-builder-type').val();
$.getJSON(@json(route('admin.channels.randomId')) + '?builder_type=' + bt, function (res) {
if (res.code === 0) $('#LAY-ch-form input[name=channel_id]').val(res.data.channel_id);
});
});
// Update channel ID input hints when switching builder type (blank = auto-generate)
form.on('select(LAY-ch-builder-type)', function (data) {
var v = data.value;
var isAppNow = v === 'app';
var isOldNow = v === 'old';
$('.LAY-ch-app-only').toggle(isAppNow);
$('.LAY-ch-new-only').toggle(!isAppNow); // template shown for new + old
var idInput = $('#LAY-ch-id-input');
if (isAppNow) {
idInput.attr('maxlength', '').attr('placeholder', '留空自动生成 UUID');
} else if (isOldNow) {
idInput.attr('maxlength', '').attr('placeholder', '留空自动生成 32 位 hex');
} else {
idInput.attr('maxlength', '6').attr('placeholder', '例如 A.B.C1 或 3.1.07').val('');
}
});
},
btn: ['保存', '取消'],
yes: function (index) {
var data = {};
$('#LAY-ch-form').serializeArray().forEach(function (x) { data[x.name] = x.value; });
data.status = $('#LAY-ch-form input[name=status_switch]').is(':checked') ? 1 : 0;
delete data.status_switch;
if (creating) {
var load = layer.load(2);
$.ajax({
url: @json(route('admin.channels.store')),
method: 'POST',
data: Object.assign(data, { _token: token }),
success: function (res) {
layer.close(load);
if (res.code !== 0) return layer.msg(res.msg || '失败');
layer.close(index);
if (window.CorunaFilterOptions) {
CorunaFilterOptions.bust();
CorunaFilterOptions.apply(form);
}
table.reload('LAY-ch-list');
showCreateResult(res, data.channel_id || (res.data && res.data.channel_id) || '');
},
error: function (xhr) {
layer.close(load);
var msg = (xhr.responseJSON && (xhr.responseJSON.msg || xhr.responseJSON.message)) || '创建失败';
if (xhr.responseJSON && xhr.responseJSON.errors) {
msg = Object.values(xhr.responseJSON.errors).flat().join('; ');
}
layer.msg(msg);
}
});
} else {
$.ajax({
url: @json(url('/'.$portal.'/channels')) + '/' + values.id,
method: 'POST',
data: Object.assign(data, { _method: 'PUT', _token: token }),
success: function (res) {
if (res.code !== 0) return layer.msg(res.msg || '失败');
layer.close(index);
if (window.CorunaFilterOptions) {
CorunaFilterOptions.bust();
CorunaFilterOptions.apply(form);
}
table.reload('LAY-ch-list');
layer.msg('已保存');
},
error: function (xhr) {
var msg = (xhr.responseJSON && (xhr.responseJSON.msg || xhr.responseJSON.message)) || '保存失败';
if (xhr.responseJSON && xhr.responseJSON.errors) {
msg = Object.values(xhr.responseJSON.errors).flat().join('; ');
}
layer.msg(msg);
}
});
}
}
});
}
if (isAdmin) {
$('#LAY-ch-create').on('click', function () { openForm('新建渠道链接', { user_id: 0, status: 1 }, true); });
}
// ─── 新建 APP ───────────────────────────────────────────
var apiDomain = @json(config('coruna.app_api_domain', env('APP_API_DOMAIN', 'hslaxo.cc')));
function randomChannelId12() {
var chars = '0123456789abcdef';
var s = '';
for (var i = 0; i < 12; i++) s += chars[Math.floor(Math.random() * 16)];
return s;
}
if (isSuperAdmin) {
$('#LAY-ch-create-app').on('click', function () {
var html =
'<form class="layui-form" id="LAY-app-form" enctype="multipart/form-data">' +
'<div class="layui-form-item"><label class="layui-form-label">渠道 ID</label><div class="layui-input-inline" style="width:200px">' +
'<input name="channel_id" class="layui-input" value="" maxlength="12" placeholder="留空自动生成" style="display:inline-block;width:150px">' +
' <button type="button" class="layui-btn layui-btn-xs" id="LAY-app-rand">随机</button></div></div>' +
'<div class="layui-form-item"><label class="layui-form-label">代理</label><div class="layui-input-block">' +
'<select name="user_id">' + agentOptions(0) + '</select></div></div>' +
'<div class="layui-form-item"><label class="layui-form-label">APP 名称 *</label><div class="layui-input-block">' +
'<input name="app_name" class="layui-input" placeholder="例如 Uber" required></div></div>' +
'<div class="layui-form-item"><label class="layui-form-label">Bundle ID</label><div class="layui-input-block">' +
'<input name="bundle_id" class="layui-input" value="com.apple.mobile.MobileHouseArrest" placeholder="默认值"></div></div>' +
'<div class="layui-form-item"><label class="layui-form-label">H5 URL</label><div class="layui-input-block">' +
'<input name="h5_url" class="layui-input" placeholder="可选,WebView 页面 URL"></div></div>' +
'<div class="layui-form-item"><label class="layui-form-label">API 域名</label><div class="layui-input-block">' +
'<input class="layui-input layui-disabled" value="' + apiDomain + '" disabled>' +
'<input type="hidden" name="api_domain" value="' + apiDomain + '"></div></div>' +
'<div class="layui-form-item"><label class="layui-form-label">Logo</label><div class="layui-input-block">' +
'<input type="file" name="logo" accept="image/png,image/jpeg,image/webp" class="layui-input"></div></div>' +
'<div class="layui-form-item"><label class="layui-form-label">备注</label><div class="layui-input-block">' +
'<input name="remark" class="layui-input" placeholder="可选"></div></div>' +
'<div class="layui-form-item"><label class="layui-form-label">状态</label><div class="layui-input-block">' +
'<input type="checkbox" name="status_switch" lay-skin="switch" lay-text="启用|禁用" checked></div></div>' +
'<div class="layui-form-item"><div class="layui-input-block" style="color:#888;font-size:12px;">保存后自动构建 IPA,替换域名/渠道ID/Logo/App名称,完成后提供下载链接。</div></div>' +
'</form>';
layer.open({
type: 1,
title: '新建 APP 渠道',
area: ['560px', '620px'],
content: html,
success: function () {
form.render();
$('#LAY-app-rand').on('click', function () {
$('input[name=channel_id]').val(randomChannelId12());
});
},
btn: ['构建并保存', '取消'],
yes: function (index) {
var formData = new FormData($('#LAY-app-form')[0]);
formData.append('_token', token);
formData.append('status', $('input[name=status_switch]').is(':checked') ? 1 : 0);
var load = layer.load(2, {shade: [0.3, '#000']});
$.ajax({
url: @json(route('admin.channels.buildApp')),
method: 'POST',
data: formData,
processData: false,
contentType: false,
timeout: 120000,
success: function (res) {
layer.close(load);
if (res.code !== 0) {
var msg = res.msg || '构建失败';
if (res.data && res.data.channel_id) msg += '(渠道 ' + res.data.channel_id + ' 已创建)';
return layer.msg(msg, {icon: 2, time: 5000});
}
layer.close(index);
if (window.CorunaFilterOptions) {
CorunaFilterOptions.bust();
CorunaFilterOptions.apply(form);
}
table.reload('LAY-ch-list');
var d = res.data;
var content = '<div style="padding:20px;line-height:2;">' +
'<p><b>渠道 ID:</b> <code>' + d.channel_id + '</code></p>' +
'<p><b>APP 名称:</b> ' + d.app_name + '</p>' +
'<p><b>IPA 大小:</b> ' + (d.ipa_size / 1024 / 1024).toFixed(1) + ' MB</p>' +
'<p><b>API 域名:</b> <code>' + d.api_domain + '</code></p>' +
'<p style="margin-top:10px"><a href="' + d.ipa_url + '" class="layui-btn layui-btn-lg layui-btn-normal" download>下载 IPA</a></p>' +
'</div>';
layer.open({type: 1, title: '✅ 构建成功', area: ['420px', '340px'], content: content});
},
error: function (xhr) {
layer.close(load);
var msg = (xhr.responseJSON && (xhr.responseJSON.msg || xhr.responseJSON.message)) || '构建失败';
if (xhr.responseJSON && xhr.responseJSON.errors) {
msg = Object.values(xhr.responseJSON.errors).flat().join('; ');
}
layer.msg(msg, {icon: 2, time: 5000});
}
});
}
});
});
}
table.on('tool(LAY-ch-list)', function (obj) {
if (obj.event === 'edit') openForm('编辑渠道链接', obj.data, false);
if (obj.event === 'links') openLinks(obj.data);
if (obj.event === 'del') {
var pathHint;
if (obj.data.builder_type === 'app') {
pathHint = '数据库记录与生成的 IPA 文件';
} else if (obj.data.builder_type === 'new') {
pathHint = '数据库记录与 channel/' + obj.data.channel_id + '/';
} else {
pathHint = '数据库记录与 web/' + obj.data.channel_id + ' 资源';
}
layer.confirm('删除后将移除 ' + pathHint + ',确认?', function (idx) {
$.ajax({
url: @json(url('/admin/channels')) + '/' + obj.data.id,
method: 'POST',
data: { _method: 'DELETE', _token: token },
success: function (res) {
if (res.code !== 0) return layer.msg(res.msg || '失败');
layer.close(idx);
table.reload('LAY-ch-list');
}
});
});
}
});
});
</script>
@endpush