layui.define(['http', 'setter', 'auth', 'form'], function (exports) { var $ = layui.$, layer = layui.layer, http = layui.http, auth = layui.auth, form = layui.form; var _perms = (layui.data('backend').permission) || []; auth.init(_perms); auth.setController('addon'); var isDemo = false; function escapeHtml(s) { return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c]; }); } function priceText(p) { p = Number(p) || 0; return p > 0 ? '¥' + p : '免费'; } function cardHtml(item) { var logo = item.logo ? '' : ''; var action; if (item.installed) { var btns = ''; if (item.upgradable) { btns = '' + btns; } if (Number(item.price) > 0) { btns += ''; } action = '' + btns; } else { var label = (Number(item.price) > 0 ? '¥' + item.price + ' 购买安装' : '安装'); action = ''; } return '
' + '
' + logo + '
' + escapeHtml(item.title) + '
' + escapeHtml(item.author || '') + ' · v' + escapeHtml(item.version || '') + '
' + '
' + escapeHtml(item.intro || '') + '
' + '
' + priceText(item.price) + '' + action + '
' + '
'; } function render(list) { var html = (list || []).map(cardHtml).join(''); $('#marketList').html(html || '
暂无可安装的插件
'); // 权限控制:无安装权限则隐藏安装按钮 if (!auth.has('addon:install') && !auth.has('addon:*')) { $('[data-act="install"]').remove(); } } function load() { http.get('market', {}) .then(function (res) { if (res.code !== 0) { layer.msg(res.message || '获取失败', { icon: 2 }); return; } isDemo = !!res.data.demo; render(res.data.list || []); }) .catch(function () { layer.msg('请求失败', { icon: 2 }); }); } $('#marketList').on('click', '[data-act="install"]', function () { var $btn = $(this); var name = $btn.data('name'); var version = $btn.data('version'); var price = Number($btn.data('price')) || 0; var doInstall = function () { if (isDemo) { layer.msg('演示模式:已安装「' + name + '」', { icon: 1 }); $btn.parent().html(''); return; } var loading = layer.load(); http.post('downloadInstall', { name: name, version: version }) .then(function (res) { layer.close(loading); if (res.code === 0) { layer.msg('安装成功', { icon: 1 }); load(); } else { layer.msg(res.message || '安装失败', { icon: 2 }); } }) .catch(function () { layer.close(loading); layer.msg('请求失败', { icon: 2 }); }); }; if (price > 0) { layer.confirm('该付费插件授权绑定当前站点域名(' + location.host + '),换站点安装将被拒绝。确认在当前站点安装?', { title: '域名授权提示' }, function (idx) { layer.close(idx); doInstall(); }); } else { doInstall(); } }); $('#marketList').on('click', '[data-act="refund"]', function () { var $btn = $(this); var name = $btn.data('name'); layer.confirm('确认对插件「' + name + '」发起退款?退款后授权将被吊销,无法再下载或安装。', function (idx) { layer.close(idx); var loading = layer.load(); http.post('refund', { name: name }) .then(function (res) { layer.close(loading); if (res.code === 0) { layer.msg('退款成功,授权已吊销', { icon: 1 }); load(); } else { layer.msg(res.message || '退款失败', { icon: 2 }); } }) .catch(function () { layer.close(loading); layer.msg('请求失败', { icon: 2 }); }); }); }); $('#marketList').on('click', '[data-act="upgrade"]', function () { var $btn = $(this); var name = $btn.data('name'); var version = $btn.data('version'); var loading = layer.load(); http.post('upgrade', { name: name, version: version }) .then(function (res) { layer.close(loading); if (res.code === 0) { layer.msg('升级成功', { icon: 1 }); load(); } else { layer.msg(res.message || '升级失败', { icon: 2 }); } }) .catch(function () { layer.close(loading); layer.msg('请求失败', { icon: 2 }); }); }); $('#marketList').on('click', '[data-act="manage"]', function () { var name = $(this).data('name'); if (isDemo) { layer.msg('演示:进入「' + name + '」后台', { icon: 0 }); return; } // 真实模式:跳转到插件自己的后台(约定路径,可按实际调整) window.open('/' + name); }); // ===== 发布到本服务器(仅开发模式显示) ===== var isDev = $('#appDebug').val() === '1'; var installedList = []; if (isDev) { $('#btnPublish').show(); } function loadInstalled() { return http.get('index', { page: 1, limit: 9999 }) .then(function (res) { if (res.code === 0 && Array.isArray(res.data)) { installedList = res.data; } return installedList; }) .catch(function () { return []; }); } $('#btnPublish').on('click', function () { loadInstalled().then(function (list) { if (!list.length) { layer.msg('暂无已安装插件可发布', { icon: 2 }); return; } var opts = list.map(function (it) { return ''; }).join(''); var html = '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
'; layer.open({ type: 1, title: '发布到本服务器市场', area: ['520px', 'auto'], content: html }); // 关键:下拉是动态注入到 .layui-form 内的元素,必须显式 render 才会显示选项, // 否则 layui 增强后的 select 会显示为空(表现为「选择插件」没有任何内容)。 form.render('select'); function fillMeta() { var name = $('#pubName').val(); var it = list.filter(function (x) { return x.name === name; })[0] || {}; $('#pubTitle').val(it.title || name); $('#pubAuthor').val(it.author || ''); $('#pubDesc').val(it.description || it.intro || ''); $('#pubPrice').val(it.price != null ? it.price : 0); } fillMeta(); $('#pubName').on('change', fillMeta); $('#pubSubmit').on('click', function () { var data = { name: $('#pubName').val(), title: $('#pubTitle').val(), author: $('#pubAuthor').val(), description: $('#pubDesc').val(), price: $('#pubPrice').val() || 0 }; var loading = layer.load(); http.post('publish', data) .then(function (res) { layer.close(loading); if (res.code === 0) { layer.msg('发布成功', { icon: 1 }); layer.closeAll(); load(); } else { layer.msg(res.message || '发布失败', { icon: 2 }); } }) .catch(function () { layer.close(loading); layer.msg('请求失败', { icon: 2 }); }); }); }); }); // ===== 发布到官方公共市场(需开发者令牌,服务端审核) ===== $('#btnSubmitOfficial').on('click', function () { loadInstalled().then(function (list) { if (!list.length) { layer.msg('暂无已安装插件可发布', { icon: 2 }); return; } var opts = list.map(function (it) { return ''; }).join(''); var html = '
' + '
' + '
' + '
'; layer.open({ type: 1, title: '发布到官方市场(需审核)', area: ['520px', 'auto'], content: html }); form.render('select'); $('#offSubmit').on('click', function () { var loading = layer.load(); http.post('submitOfficial', { name: $('#offName').val() }) .then(function (res) { layer.close(loading); if (res.code === 0) { layer.msg(res.message || '提交成功,等待审核', { icon: 1 }); layer.closeAll(); } else { layer.msg(res.message || '提交失败', { icon: 2 }); } }) .catch(function () { layer.close(loading); layer.msg('请求失败', { icon: 2 }); }); }); }); }); load(); exports('market', {}); });