manghe/app/admin/view/Goods/goods.html
2025-04-23 15:15:49 +08:00

778 lines
33 KiB
HTML
Executable File
Raw Permalink 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.

{include file="Public:header3"/}
<body>
<div class="layui-fluid" style="padding-top: 15px;">
<div class=" layui-card">
<div class="layui-form layui-card-header layuiadmin-card-header-auto" style="height: 84px;">
<div class="layui-form-item">
<div class="layui-inline">
<div class="layui-input-inline" style="width: 300px;margin-left: 0px">
<input type="text" name="title" id="title" placeholder="请输入盒子标题" autocomplete="off"
class="layui-input">
</div>
</div>
<div class="layui-inline">
<div class="layui-input-inline" style="width: 180px;margin-left: 0px">
<select name="status" id="status" style="width:100%">
<option value="">--请选择状态--</option>
<option value="1">上架</option>
<option value="2">下架</option>
<option value="3">售罄</option>
</select>
</div>
</div>
<div class="layui-inline">
<div class="layui-input-inline" style="width: 180px;margin-left: 0px">
<select name="type" id="goodsType" style="width:100%">
<option value="">--盒子类型--</option>
<!-- 盒子类型由JS动态加载 -->
</select>
</div>
</div>
<div class="layui-inline">
<button class="layui-btn layuiadmin-btn-useradmin" id="searchBtn">
<i class="layui-icon layui-icon-search layuiadmin-button-btn"></i>
</button>
<button class="layui-btn" id="addGoodsBtn">添加盒子</button>
<button class="layui-btn layui-btn-normal" id="offshelfLogBtn">自动下架日志
<span class="layui-badge layui-hide" id="offshelfLogCount"></span>
</button>
</div>
<div class="layui-inline">
默认不显示福利屋数据,查看福利屋盒子,请在盒子类型选择福利屋单独查看。
</div>
</div>
</div>
<div class="layui-card-body">
<table id="goodsTable" lay-filter="goodsTable"></table>
</div>
</div>
</div>
<!-- 盒子类型模板 -->
<script type="text/html" id="typeTpl">
{{#
var typeNames = {};
layui.each(window.goodsTypes || [], function(index, item) {
typeNames[item.value] = item.fl_name;
});
var typeName = typeNames[d.type] || ('未知类型' + d.type);
}}
<button class="layui-btn layui-btn-normal layui-btn-radius layui-btn-sm">{{typeName}}</button>
</script>
<!-- 盒子状态模板 -->
<script type="text/html" id="statusTpl">
{{# if(d.status == 1){ }}
<button data-id="{{d.id}}" data-status="2" data-name="下架" class="goods-status layui-btn layui-btn-danger layui-btn-xs">
<i class="layui-icon">&#xe61a;</i>
</button>
{{# } else if(d.status == 2){ }}
<button data-id="{{d.id}}" data-status="1" data-name="上架" class="goods-status layui-btn layui-btn-info layui-btn-xs">
<i class="layui-icon">&#xe619;</i>
</button>
{{# } else if(d.status == 3){ }}
<button class="layui-btn layui-btn-disabled layui-btn-radius layui-btn-sm">售罄</button>
{{# } }}
</script>
<!-- 自动下架模板 -->
<script type="text/html" id="autoOffshelfTpl">
{{# if(d.is_auto_xiajia == 1){ }}
<button class="layui-btn layui-btn-warm layui-btn-radius layui-btn-sm">已开启</button>
<br>
<button class="layui-btn layui-btn-warm layui-btn-sm">利润值{{d.xiajia_lirun}}%</button>
<br>
{{# if(d.xiajia_jine > 0){ }}
<button class="layui-btn layui-btn-warm layui-btn-sm">下架金额{{d.xiajia_jine}}</button>
<br>
{{# } }}
<button class="layui-btn layui-btn-warm layui-btn-sm">阈值{{d.xiajia_auto_coushu}}</button>
{{# } else { }}
<button class="layui-btn layui-btn-danger layui-btn-radius layui-btn-sm">未开启</button>
{{# } }}
</script>
<!-- 首页显示模板 -->
<script type="text/html" id="showIsTpl">
{{# if(d.show_is == 1){ }}
<button class="layui-btn layui-btn-danger layui-btn-radius layui-btn-sm"></button>
{{# } }}
</script>
<!-- 锁箱模式模板 -->
<script type="text/html" id="lockIsTpl">
{{# if(d.lock_is == 1){ }}
<button class="layui-btn layui-btn-warm layui-btn-sm">状态开启</button>
<br>
<button class="layui-btn layui-btn-warm layui-btn-sm">时间{{d.lock_time}}</button>
{{# } }}
</script>
<!-- 盒子支付信息模板 -->
<script type="text/html" id="payInfoTpl">
<div class="pay-info-container">
{{# var hasExtend = false; }}
{{# var goodsExtend = d.goods_extend || {}; }}
{{# if(goodsExtend && (goodsExtend.pay_wechat !== undefined || goodsExtend.pay_balance !== undefined ||
goodsExtend.pay_currency !== undefined || goodsExtend.pay_currency2 !== undefined ||
goodsExtend.pay_coupon !== undefined)) { }}
{{# hasExtend = true; }}
<div>
{{# if(goodsExtend.pay_wechat == 1) { }}
<span class="layui-badge layui-bg-green">微信</span>
{{# } }}
{{# if(goodsExtend.pay_balance == 1) { }}
<span class="layui-badge layui-bg-blue">{$app_setting.balance_name}</span>
{{# } }}
{{# if(goodsExtend.pay_currency == 1) { }}
<span class="layui-badge layui-bg-orange">{$app_setting.currency1_name}</span>
{{# } }}
{{# if(goodsExtend.pay_currency2 == 1) { }}
<span class="layui-badge layui-bg-cyan">{$app_setting.currency2_name}</span>
{{# } }}
{{# if(goodsExtend.pay_coupon == 1) { }}
<span class="layui-badge layui-bg-purple">优惠券</span>
{{# } }}
</div>
<div style="margin-top:5px;">
{{# if(goodsExtend.is_deduction == 1) { }}
<span class="layui-badge layui-bg-red">抵扣</span>
{{# } else { }}
<span class="layui-badge layui-bg-gray">支付</span>
{{# } }}
</div>
{{# } else { }}
<span class="layui-badge layui-bg-gray">默认设置</span>
{{# } }}
</div>
</script>
<!-- 盒子价格和套数模板 -->
<script type="text/html" id="priceStockTpl">
<div><b>价格</b>{{d.price}}</div>
<div><b>套数</b>{{d.stock}}</div>
</script>
<!-- 盒子限购等信息模板 -->
<script type="text/html" id="limitInfoTpl">
<div><b>是否首抽5折</b>{{d.is_shou_zhe==0?'':''}}</div>
<div><b>限购次数</b>{{d.quanju_xiangou}}</div>
<div><b>每日限购</b>{{d.daily_xiangou}}</div>
<div><b>解锁金额</b><span class="layui-badge layui-bg-orange">{{d.unlock_amount}}</span></div>
<div><b>抽奖门槛</b>{{d.choujiang_xianzhi}}</div>
</script>
<!-- 首页显示和锁箱模式模板 -->
<script type="text/html" id="showLockTpl">
{{# if(d.show_is == 1) { }}
<div><b>首页显示</b><span class="layui-badge layui-bg-danger"></span></div>
{{# } }}
{{# if(d.lock_is == 1) { }}
<div><b>锁箱模式</b></div>
<div><b>锁箱时间</b>{{d.lock_time}}</div>
{{# } }}
</script>
<!-- 操作栏模板 -->
<script type="text/html" id="toolbarTpl">
<div class="user-extra-info">
<div>
<a style="text-decoration:none" title="编辑" lay-event="edit" class="layui-btn layui-btn-normal layui-btn-xs">
<i class="layui-icon layui-icon-edit"></i>
</a>
<a style="text-decoration:none" lay-event="goodslist" class="layui-btn layui-btn-warm layui-btn-xs">
<i class="layui-icon layui-icon-cart-simple"></i>
</a>
</div>
<div>
<a style="text-decoration:none" lay-event="copy" class="layui-btn layui-btn-normal layui-btn-xs">
<i class="layui-icon layui-icon-template"></i>
</a>
<a style="text-decoration:none" lay-event="sync" class="layui-btn layui-btn-normal layui-btn-xs">
<i class="layui-icon layui-icon-sync"></i>
</a>
</div>
<div>
<a style="text-decoration:none" lay-event="extend" class="layui-btn layui-btn-normal layui-btn-xs">
<i class="layui-icon layui-icon-set"></i>
</a>
<a style="text-decoration:none" lay-event="extend_del" class="layui-btn layui-btn-danger layui-btn-xs">
<i class="layui-icon layui-icon-delete"></i>
</a>
</div>
<div>
<a style="text-decoration:none" lay-event="clear" class="layui-btn layui-btn-danger layui-btn-xs">
<i class="layui-icon layui-icon-delete"></i>
</a>
<a style="text-decoration:none" lay-event="delete" class="layui-btn layui-btn-danger layui-btn-xs">
<i class="layui-icon layui-icon-delete"></i>
</a>
</div>
</div>
</script>
<!-- 同步弹窗模板 -->
<script type="text/html" id="syncDialogTpl">
<div class="layui-form" style="padding: 20px;">
<div class="layui-form-item">
<label class="layui-form-label">选择同步目标</label>
<div class="layui-input-block">
<input type="checkbox" name="syncAll" title="全选" lay-filter="syncAllFilter">
{{# layui.each(d.syncAddresses, function(index, item){ }}
<input type="checkbox" name="syncTargets" value="{{ item.sync_address }}" title="{{ item.name }}" lay-skin="primary">
{{# }); }}
</div>
</div>
</div>
</script>
{include file="Public:footer3"/}
<script type="text/javascript">
var table;
var form;
var layer;
var laytpl;
layui.use(['layer', 'table', 'form', 'laytpl'], function () {
var $ = layui.$;
table = layui.table;
form = layui.form;
layer = layui.layer;
laytpl = layui.laytpl;
// 加载未读下架日志数量
loadUnreadOffshelfLogCount();
// 定时刷新未读数量每60秒
setInterval(loadUnreadOffshelfLogCount, 60000);
// 加载盒子类型数据
$.ajax({
url: '{:url("/admin/api/goods/types")}',
type: 'GET',
success: function (res) {
if (res.code === 0) {
// 保存类型数据到全局变量
window.goodsTypes = res.data;
var html = '<option value="">--盒子类型--</option>';
$.each(res.data, function (index, item) {
html += '<option value="' + item.value + '" title="' + item.remark + '">' + item.fl_name + '</option>';
});
$('#goodsType').html(html);
form.render('select');
}
}
});
// 初始化表格
var tableIns = table.render({
elem: '#goodsTable',
url: '{:url("/admin/api/goods/list")}',
page: true,
limit: 20,
lineStyle: 'height:150px',
height: 'full-120',
cols: [[
{ field: 'id', type: 'numbers', title: '序号',width:60 },
{
field: 'id', title: '盒子ID', width: 80, templet: function (d) {
if (d.type == 1 || d.type == 11) {
return '<div style="cursor:pointer;" class="goodsextend-btn" data-id="' + d.id + '" data-title="' + d.title + '">' + d.id + '</div>';
} else {
return d.id;
}
}
},
{ field: 'type', title: '盒子类型', width: 120, templet: '#typeTpl' },
{ field: 'title', title: '盒子名称', width: 180 },
{
field: 'price_stock', title: '价格/套数', width: 140, templet: '#priceStockTpl'
},
{
field: 'imgurl', title: '盒子图片', width: 90, templet: function (d) {
return '<img src="' + d.imgurl + '" style="width:60px;height:60px;" class="layui-admin-img" onclick="previewImg(this)">';
}
},
{
field: 'imgurl_detail', title: '详情图片', width: 90, templet: function (d) {
return d.imgurl_detail ? '<img src="' + d.imgurl_detail + '" style="width:60px;height:60px;" class="layui-admin-img" onclick="previewImg(this)">' : '';
}
},
{ field: 'limit_info', title: '限购信息', width: 160, templet: '#limitInfoTpl' },
{ field: 'pay_info', title: '支付信息', width: 150, templet: '#payInfoTpl' },
{ field: 'is_auto_xiajia', title: '自动下架', width: 150, templet: '#autoOffshelfTpl' },
{ field: 'sort', title: '排序', width: 100, edit: 'text' },
{
field: 'is_flw', title: '福利屋信息', width: 200, templet: function (d) {
if (d.type == 15) {
var startTime = d.flw_start_time ? new Date(d.flw_start_time * 1000).toLocaleString() : '未设置';
var endTime = d.flw_end_time ? new Date(d.flw_end_time * 1000).toLocaleString() : '未设置';
var openTime = d.open_time ? new Date(d.open_time * 1000).toLocaleString() : '未设置';
var isOpen = d.is_open == 1 ? '<span class="layui-badge layui-bg-green">已开奖</span>' : '<span class="layui-badge layui-bg-gray">未开奖</span>';
return '<div><b>开始:</b> ' + startTime + '</div>' +
'<div><b>结束:</b> ' + endTime + '</div>' +
'<div><b>开奖:</b> ' + openTime + '</div>' +
'<div><b>状态:</b> ' + isOpen + '</div>';
} else {
return '';
}
}
},
{ field: 'show_lock', title: '显示/锁箱', width: 150, templet: '#showLockTpl' },
{
field: 'addtime', title: '添加/修改时间', width: 180, templet: function (d) {
if (d.update_time) {
return '<div><b>添加:</b> ' + d.addtime_text + '</div><div><b>修改:</b> ' + new Date(d.update_time * 1000).toLocaleString() + '</div>';
} else {
return '<div>' + d.addtime_text + '</div>';
}
}
},
{ fixed: 'right', field: 'status', title: '状态', width: 100, templet: '#statusTpl' },
{ fixed: 'right', title: '操作', width: 200, toolbar: '#toolbarTpl' }
]],
done: function () {
// 绑定状态切换事件
$('.goods-status').on('click', function () {
var id = $(this).data('id');
var type = $(this).data('status');
var type_name = $(this).data('name');
del(id, type, type_name);
});
// 绑定扩展奖品点击事件
$('.goodsextend-btn').on('click', function () {
var goods_id = $(this).data('id');
var title = $(this).data('title');
goodsextendlist_edit(goods_id, title);
});
}
});
// 搜索按钮点击事件
$('#searchBtn').on('click', function () {
tableIns.reload({
where: {
title: $('#title').val(),
status: $('#status').val(),
type: $('#goodsType').val()
},
page: {
curr: 1
}
});
});
// 添加盒子按钮点击事件
$('#addGoodsBtn').on('click', function () {
goods_add();
});
// 自动下架日志按钮点击事件
$('#offshelfLogBtn').on('click', function () {
offshelf_log();
});
// 监听工具条事件
table.on('tool(goodsTable)', function (obj) {
var data = obj.data;
var layEvent = obj.event;
if (layEvent === 'edit') {
// 编辑盒子
goods_edit(data.id);
} else if (layEvent === 'goodslist') {
// 查看奖品
goodslist(data.id, data.title);
} else if (layEvent === 'sync') {
// 同步盒子
goods_sync(data.id, data.async_code);
} else if (layEvent === 'copy') {
// 复制盒子
copy_goods(data.id);
} else if (layEvent === 'clear') {
// 清空抽奖数据
clear_goods_data(data.id);
} else if (layEvent === 'delete') {
// 删除盒子
del(data.id, 3, '删除');
} else if (layEvent === 'extend') {
// 盒子扩展设置
goods_extend(data.id, data.title);
} else if (layEvent === 'extend_del') {
// 删除盒子扩展
goods_extend_del(data.id);
}
});
// 监听单元格编辑
table.on('edit(goodsTable)', function (obj) {
var value = obj.value, // 得到修改后的值
data = obj.data, // 得到所在行所有键值
field = obj.field; // 得到字段
// 排序字段修改
if (field === 'sort') {
var loadIndex = layer.load(2);
// 发送请求保存修改
$.ajax({
url: '{:url("/admin/update_goods_sort")}',
type: 'POST',
data: {
id: data.id,
sort: value
},
success: function (res) {
layer.close(loadIndex);
if (res.status === 1) {
layer.msg('排序修改成功', { icon: 1, time: 1000 });
} else {
layer.msg(res.msg || '修改失败', { icon: 2, anim: 6, time: 2000 });
// 重载表格以恢复原值
table.reload('goodsTable');
}
},
error: function () {
layer.close(loadIndex);
layer.msg('网络错误,请稍后重试', { icon: 2, anim: 6, time: 2000 });
// 重载表格以恢复原值
table.reload('goodsTable');
}
});
}
});
});
//添加盒子
function goods_add() {
var url = "{:url('/admin/goods_add')}";
layer.open({
type: 2,
title: '添加盒子',
shadeClose: false,
shade: 0.3,
area: ['90%', '90%'],
content: url,
});
}
//查看自动下架日志
function offshelf_log() {
var url = "{:url('/admin/offshelf_log')}";
layer.open({
type: 2,
title: '盒子自动下架日志',
shadeClose: false,
shade: 0.3,
area: ['90%', '90%'],
content: url,
end: function() {
// 日志页面关闭后刷新未读数量
loadUnreadOffshelfLogCount();
}
});
}
//编辑奖品
function goodsextendlist_edit(goods_id, title) {
var url = "{:url('/admin/goodsextendlist')}?goods_id=" + goods_id;
layer.open({
type: 2,
title: title + '奖品配置',
shadeClose: false,
shade: 0.3,
area: ['90%', '90%'],
content: url,
});
}
//编辑盒子
function goods_edit(id) {
var url = "{:url('/admin/goods_edit')}?id=" + id;
layer.open({
type: 2,
title: '编辑盒子',
shadeClose: false,
shade: 0.3,
area: ['90%', '90%'],
content: url,
});
}
//盒子奖品
function goodslist(goods_id, title) {
var url = "{:url('/admin/goodslist')}?goods_id=" + goods_id;
layer.open({
type: 2,
title: title + ' 盒子奖品',
shadeClose: false,
shade: 0.3,
area: ['95%', '95%'],
content: url,
});
}
//上下架
function del(id, type, type_name) {
layer.confirm('确认要执行' + type_name + '操作吗?', function () {
var url = "{:url('/admin/goods_del')}";
var load = layer.load(2);
var $ = layui.$;
$.post(url, { "id": id, 'type': type }, function (data) {
if (data.status == 1) {
layer.close(load);
layer.msg('操作成功', { icon: 1, time: 1000 }, function () {
table.reload('goodsTable');
});
} else {
layer.msg(data.msg, { icon: 2, anim: 6, time: 1000 }, function () {
layer.close(load);
});
}
})
});
}
//盒子奖品
function goods_sync(goods_id, async_code) {
layui.use(['table', 'form', 'layer', 'laytpl'], function () {
var table = layui.table, form = layui.form, layer = layui.layer, laytpl = layui.laytpl;
var $ = layui.$;
// 同步操作
var confirmMsg = async_code
? '警告:该盒子已经同步过,再次同步将会覆盖目标系统中的盒子数据!确定要继续吗?'
: '确定要同步该盒子吗?';
layer.confirm(confirmMsg, {
btn: ['确定', '取消'],
title: '同步确认',
skin: async_code ? 'layui-layer-danger' : ''
}, function (index) {
// 获取同步地址
$.get('{:url("/admin/get_sync_addresses")}', function (res) {
if (res.status === 1 && res.data.length > 0) {
// 渲染同步地址选择弹窗
layer.open({
type: 1,
title: '选择同步目标',
area: ['500px', '350px'],
content: laytpl($('#syncDialogTpl').html()).render({ syncAddresses: res.data }),
btn: ['开始同步', '取消'],
success: function () {
form.render(); // 重新渲染表单
// 监听全选
form.on('checkbox(syncAllFilter)', function (data) {
var syncTargets = $('input[name="syncTargets"]');
syncTargets.prop('checked', data.elem.checked);
form.render('checkbox');
});
},
yes: function (index, layero) {
var selectedTargets = [];
$('input[name="syncTargets"]:checked').each(function () {
selectedTargets.push($(this).val());
});
if (selectedTargets.length === 0) {
layer.msg('请至少选择一个同步目标', { icon: 2 });
return;
}
// 调用同步接口
layer.close(index);
var loadIndex = layer.load(2);
$.post('{:url("/admin/sync_goods")}', {
goods_id: goods_id,
targets: selectedTargets
}, function (res) {
layer.close(loadIndex);
if (res.status === 1) {
layer.msg('同步成功', { icon: 1 });
table.reload('goodsTable');
} else {
layer.msg(res.msg || '同步失败', { icon: 2 });
}
});
}
});
} else {
layer.msg('没有可用的同步目标,请先在系统设置中配置', { icon: 2 });
}
});
layer.close(index);
});
});
}
// 清空盒子抽奖数据
function clear_goods_data(id) {
layer.confirm('警告:清空抽奖数据将删除该盒子所有订单记录,且无法恢复!确定要继续吗?', {
btn: ['确定', '取消'],
title: '危险操作确认',
skin: 'layui-layer-danger'
}, function (index) {
var url = "{:url('/admin/clear_goods_data')}";
var load = layer.load(2);
var $ = layui.$;
$.post(url, { "id": id }, function (data) {
layer.close(load);
if (data.status == 1) {
layer.msg(data.msg, { icon: 1, time: 2000 }, function () {
table.reload('goodsTable');
});
} else {
layer.msg(data.msg, { icon: 2, anim: 6, time: 2000 }, function () {
layer.close(load);
});
}
});
layer.close(index);
});
}
// 复制盒子
function copy_goods(id) {
layer.confirm('确定要复制此盒子及其所有奖品吗?', {
btn: ['确定', '取消'],
title: '复制确认'
}, function (index) {
var url = "{:url('/admin/copy_goods')}";
var load = layer.load(2);
var $ = layui.$;
$.post(url, { "id": id }, function (data) {
layer.close(load);
if (data.status == 1) {
layer.msg(data.msg, { icon: 1, time: 2000 }, function () {
table.reload('goodsTable');
});
} else {
layer.msg(data.msg, { icon: 2, anim: 6, time: 2000 }, function () {
layer.close(load);
});
}
});
layer.close(index);
});
}
// 盒子扩展设置
function goods_extend(goods_id, title) {
var url = "{:url('/admin/goods_extend')}?goods_id=" + goods_id;
layer.open({
type: 2,
title: title + ' - 盒子扩展设置',
shadeClose: false,
shade: 0.3,
area: ['550px', '450px'],
content: url,
});
}
// 删除盒子扩展
function goods_extend_del(goods_id) {
layer.confirm('确定要删除该盒子的扩展设置吗?删除后将恢复默认支付方式。', {
btn: ['确定', '取消'],
title: '删除确认'
}, function (index) {
var url = "{:url('/admin/goods_extend_del')}";
var load = layer.load(2);
var $ = layui.$;
$.post(url, { "goods_id": goods_id }, function (data) {
layer.close(load);
if (data.status == 1) {
layer.msg(data.msg, { icon: 1, time: 2000 }, function () {
table.reload('goodsTable');
});
} else {
layer.msg(data.msg, { icon: 2, anim: 6, time: 2000 });
}
});
layer.close(index);
});
}
// 图片预览功能
function previewImg(obj) {
var img = new Image();
img.src = obj.src;
layer.open({
type: 1,
title: false,
closeBtn: 1,
shadeClose: true,
area: [img.width > 800 ? '800px' : img.width + 'px', ''],
content: '<div style="text-align: center;"><img src="' + obj.src + '" style="max-width: 100%;" /></div>'
});
}
// 加载未读下架日志数量
function loadUnreadOffshelfLogCount() {
var $ = layui.$;
$.ajax({
url: '{:url("/admin/goods_offshelf_unread_count")}',
type: 'GET',
success: function(res) {
if (res.status === 1) {
if (res.count > 0) {
$('#offshelfLogCount').text(res.count).removeClass('layui-hide');
} else {
$('#offshelfLogCount').addClass('layui-hide');
}
}
}
});
}
</script>
<style>
.combined-values div {
margin: 0;
padding: 0px 0;
}
/* 图片放大样式 */
.layui-admin-img {
cursor: pointer;
transition: all 0.3s;
}
.layui-admin-img:hover {
transform: scale(1.1);
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}
/* 支付信息容器样式 */
.pay-info-container {
padding: 5px 0;
}
/* 徽章样式 */
.layui-badge {
margin: 2px;
}
</style>
</body>
</html>