HaniBlindBox/server/php/public/js/reward-component.js
2026-01-01 20:46:07 +08:00

469 lines
19 KiB
JavaScript
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.

/**
* 奖励信息组件
* 用于创建和管理奖励信息表单元素
*/
// 存储所有实例的映射
var rewardInstances = {};
/**
* 初始化奖励信息区域
* @param {string} containerId - 容器ID
* @param {Array|string} existingRewards - 已存在的奖励数据数组或reward_id
* @param {string} fieldName - 自定义字段名默认为reward_id
* @returns {string} - 返回实例ID用于后续操作
*/
function initRewardInfo(containerId, existingRewards = null, fieldName = 'reward_id') {
var $ = layui.$;
var form = layui.form;
// 创建实例ID
var instanceId = containerId + '_' + new Date().getTime();
// 奖励类型选项
var rewardTypes = [
{ value: '1', text: '钻石' },
{ value: '2', text: 'UU币' },
{ value: '3', text: '达达卷' },
{ value: '4', text: '优惠券' }
];
// 存储优惠券数据
var couponsData = [];
// 创建奖励信息卡片 - 使用实例化ID
var cardHtml = '<div class="layui-card">' +
'<div class="layui-card-header">' +
'<button type="button" class="layui-btn layui-btn-sm layui-btn-normal" id="' + instanceId + '_addReward">' +
'<i class="layui-icon">&#xe654;</i>添加奖励' +
'</button>' +
'</div>' +
'<div class="layui-card-body">' +
'<div id="' + instanceId + '_rewardContainer">' +
'<!-- 动态添加的奖励项将显示在这里 -->' +
'</div>' +
'</div>' +
'</div>';
// 只有在不存在同名字段时添加隐藏字段
if ($('#' + containerId + ' input[name="' + fieldName + '"]').length == 0 &&
$('input[name="' + fieldName + '"]').length == 0) {
cardHtml += '<input type="hidden" name="' + fieldName + '" value="">';
}
// 渲染奖励信息卡片
$('#' + containerId).html(cardHtml);
// 请求优惠券数据
function fetchCoupons(callback) {
var load = layer.load(2);
$.ajax({
url: '/admin/get_coupons',
type: 'GET',
dataType: 'json',
success: function (res) {
layer.close(load);
if (res.code == 0) {
couponsData = res.data;
if (typeof callback === 'function') {
callback(couponsData);
}
} else {
layer.msg(res.msg || '获取优惠券失败', { icon: 2, anim: 6, time: 1500 });
}
},
error: function () {
layer.close(load);
layer.msg('网络错误,请稍后重试', { icon: 2, anim: 6, time: 1500 });
}
});
}
// 生成唯一ID
function generateUniqueId() {
return instanceId + '_item_' + new Date().getTime() + '_' + Math.floor(Math.random() * 1000);
}
// 添加奖励项
function addRewardItem(rewardData = null) {
var uniqueId = generateUniqueId();
var html = '<div class="layui-form-item ' + instanceId + '-reward-item" id="' + uniqueId + '">' +
'<div class="layui-inline">' +
'<select class="' + instanceId + '-reward-type-select" lay-filter="' + instanceId + 'RewardTypeFilter">' +
'<option value="">请选择奖励类型</option>';
// 添加奖励类型选项
for (var i = 0; i < rewardTypes.length; i++) {
var selected = rewardData && rewardData.reward_type == rewardTypes[i].value ? 'selected' : '';
html += '<option value="' + rewardTypes[i].value + '" ' + selected + '>' + rewardTypes[i].text + '</option>';
}
html += '</select>' +
'</div>';
// 根据奖励类型决定显示哪个输入区域
var rewardValueDisplay = (!rewardData || rewardData.reward_type != '4') ? '' : 'style="display:none;"';
var couponDisplay = (!rewardData || rewardData.reward_type != '4') ? 'style="display:none;"' : '';
var rewardValue = rewardData ? rewardData.reward_value : '';
html += '<div class="layui-inline ' + instanceId + '-reward-value-container" ' + rewardValueDisplay + '>' +
'<input type="text" placeholder="请输入奖励数值" class="layui-input ' + instanceId + '-reward-value-input" value="' + rewardValue + '">' +
'</div>' +
'<div class="layui-inline ' + instanceId + '-coupon-container" ' + couponDisplay + '>' +
'<select class="' + instanceId + '-coupon-select">' +
'<option value="">请选择优惠券</option>' +
'<option value="loading" disabled>加载中...</option>' +
'</select>' +
'</div>' +
'<div class="layui-inline">' +
'<button type="button" class="layui-btn layui-btn-danger layui-btn-sm ' + instanceId + '-remove-reward" data-id="' + uniqueId + '">' +
'<i class="layui-icon">&#xe640;</i>删除' +
'</button>' +
'</div>' +
'</div>';
$('#' + instanceId + '_rewardContainer').append(html);
form.render('select'); // 重新渲染表单
// 绑定删除按钮事件
$('.' + instanceId + '-remove-reward[data-id="' + uniqueId + '"]').click(function () {
var id = $(this).data('id');
$('#' + id).remove();
});
// 如果是优惠券类型,需要加载优惠券数据
if (rewardData && rewardData.reward_type == '4') {
var $item = $('#' + uniqueId);
var $couponSelect = $item.find('.' + instanceId + '-coupon-select');
// 获取优惠券数据并选中指定的优惠券
if (couponsData.length > 0) {
fillCouponOptions($couponSelect, couponsData, rewardData.reward_extend);
} else {
fetchCoupons(function (coupons) {
fillCouponOptions($couponSelect, coupons, rewardData.reward_extend);
});
}
}
return uniqueId;
}
// 添加奖励按钮点击事件
$('#' + instanceId + '_addReward').click(function () {
addRewardItem();
});
// 监听奖励类型选择
form.on('select(' + instanceId + 'RewardTypeFilter)', function (data) {
var $item = $(data.elem).closest('.' + instanceId + '-reward-item');
var value = data.value;
if (value == '4') { // 选择了优惠券
$item.find('.' + instanceId + '-reward-value-container').hide();
$item.find('.' + instanceId + '-coupon-container').show();
$item.find('.' + instanceId + '-reward-value-input').val(''); // 清空奖励数值
// 获取当前选择框的优惠券选择框
var $couponSelect = $item.find('.' + instanceId + '-coupon-select');
// 如果优惠券数据已加载,直接填充
if (couponsData.length > 0) {
fillCouponOptions($couponSelect, couponsData);
} else {
// 否则请求加载
fetchCoupons(function (coupons) {
fillCouponOptions($couponSelect, coupons);
});
}
} else {
$item.find('.' + instanceId + '-reward-value-container').show();
$item.find('.' + instanceId + '-coupon-container').hide();
$item.find('.' + instanceId + '-coupon-select').val(''); // 清空优惠券选择
form.render('select');
}
});
// 填充优惠券选项
function fillCouponOptions($select, coupons, selectedCouponId = null) {
// 清空现有选项,保留第一个"请选择"
$select.find('option:not(:first)').remove();
// 添加优惠券选项
for (var i = 0; i < coupons.length; i++) {
var coupon = coupons[i];
var selected = selectedCouponId && coupon.id == selectedCouponId ? 'selected' : '';
$select.append('<option value="' + coupon.id + '" ' + selected + '>' +
coupon.title + ' (满' + coupon.man_price + '减' + coupon.price + ')</option>');
}
// 重新渲染表单
form.render('select');
}
// 处理初始化奖励数据
if (existingRewards) {
// 如果传入的是字符串reward_id则通过接口获取奖励数据
if (typeof existingRewards === 'string' && existingRewards.trim() !== '') {
var rewardId = existingRewards;
// 通过API获取奖励数据
var loadingIndex = layer.load(1, { shade: [0.1, '#fff'] });
$.ajax({
url: '/admin/get_rewards_by_id',
type: 'GET',
data: { reward_id: rewardId },
dataType: 'json',
success: function (res) {
layer.close(loadingIndex);
if (res.status === 1 && res.data && res.data.length > 0) {
// 先获取优惠券数据,再初始化奖励表单
if ($('input[name="' + fieldName + '"]').length > 0) {
$('input[name="' + fieldName + '"]').val(rewardId);
}
fetchCoupons(function () {
// 遍历奖励数据,添加奖励项
for (var i = 0; i < res.data.length; i++) {
var rewardItem = {
reward_type: res.data[i].reward_type.toString(),
reward_value: res.data[i].reward_value || '',
reward_extend: res.data[i].reward_extend || ''
};
addRewardItem(rewardItem);
}
});
} else {
// layer.msg('没有找到奖励数据或获取失败', { icon: 2, time: 2000 });
}
},
error: function () {
layer.close(loadingIndex);
layer.msg('网络错误,无法获取奖励数据', { icon: 2, time: 2000 });
}
});
}
// 如果传入的是数组,直接使用
else if (Array.isArray(existingRewards) && existingRewards.length > 0) {
// 先获取优惠券数据,再初始化奖励表单
fetchCoupons(function () {
for (var i = 0; i < existingRewards.length; i++) {
addRewardItem(existingRewards[i]);
}
});
}
} else {
// 预加载优惠券数据,以便后续使用
fetchCoupons();
}
// 存储实例相关数据
rewardInstances[instanceId] = {
containerId: containerId,
fieldName: fieldName,
validateRewardInfo: function () {
var hasRewardType = false;
$('.' + instanceId + '-reward-type-select').each(function () {
if ($(this).val()) {
hasRewardType = true;
var $item = $(this).closest('.' + instanceId + '-reward-item');
var rewardType = $(this).val();
// 如果不是优惠券类型,检查奖励数值
if (rewardType != '4' && !$item.find('.' + instanceId + '-reward-value-input').val()) {
layer.msg('请输入奖励数值', { icon: 2, anim: 6, time: 1500 });
hasRewardType = false;
return false;
}
// 如果是优惠券类型,检查是否选择了优惠券
if (rewardType == '4' && !$item.find('.' + instanceId + '-coupon-select').val()) {
layer.msg('请选择优惠券', { icon: 2, anim: 6, time: 1500 });
hasRewardType = false;
return false;
}
}
});
if (!hasRewardType) {
layer.msg('请至少添加一项奖励信息', { icon: 2, anim: 6, time: 1500 });
return false;
}
// 验证通过后,处理奖励数据
this.processRewardData();
return true;
},
processRewardData: function () {
var rewardData = [];
// 收集所有奖励项的数据
$('.' + instanceId + '-reward-item').each(function () {
var $item = $(this);
var rewardType = $item.find('.' + instanceId + '-reward-type-select').val();
if (rewardType) {
var rewardObj = {
reward_type: rewardType,
reward_value: '',
coupon_id: ''
};
// 根据奖励类型设置相应的值
if (rewardType == '4') { // 优惠券类型
rewardObj.coupon_id = $item.find('.' + instanceId + '-coupon-select').val() || '';
} else { // 其他类型
rewardObj.reward_value = $item.find('.' + instanceId + '-reward-value-input').val() || '';
}
rewardData.push(rewardObj);
}
});
// 将奖励数据转换为JSON字符串
var rewardJson = JSON.stringify(rewardData);
// 创建或更新reward字段名
var rewardDataFieldName = 'reward_' + fieldName.replace('_id', '');
if ($('input[name="' + rewardDataFieldName + '"]').length > 0) {
$('input[name="' + rewardDataFieldName + '"]').val(rewardJson);
} else {
$('form').append('<input type="hidden" name="' + rewardDataFieldName + '" value=\'' + rewardJson + '\'>');
}
},
processRewardIdData: async function (pre, reward_id = '') {
var rewardData = [];
var $ = layui.$; // 确保在异步函数内部重新获取jQuery引用
// 收集所有奖励项的数据
$('.' + instanceId + '-reward-item').each(function () {
var $item = $(this);
var rewardType = $item.find('.' + instanceId + '-reward-type-select').val();
if (rewardType) {
var rewardObj = {
reward_type: rewardType,
reward_value: '',
coupon_id: ''
};
// 根据奖励类型设置相应的值
if (rewardType == '4') { // 优惠券类型
rewardObj.coupon_id = $item.find('.' + instanceId + '-coupon-select').val() || '';
} else { // 其他类型
rewardObj.reward_value = $item.find('.' + instanceId + '-reward-value-input').val() || '';
}
rewardData.push(rewardObj);
}
});
if (reward_id === '') {
if ($('input[name="' + fieldName + '"]').length > 0) {
reward_id = $('input[name="' + fieldName + '"]').val();
}
}
if (reward_id == '' && rewardData.length == 0) {
layer.msg('请至少添加一项奖励信息', { icon: 2, anim: 6, time: 1500 });
return false;
}
// 将奖励数据转换为JSON字符串
var rewardJson = JSON.stringify(rewardData);
var url = "/admin/reward_add_json.html";
var load = layer.load(2);
try {
let l = await $.post(url, {
reward: rewardJson,
reward_id: reward_id,
reward_id_pre: pre
});
layer.close(load);
console.log(l);
if (l && l.status === 1) {
reward_id = l.data.reward_id;
// 更新reward_id字段
if ($('input[name="' + fieldName + '"]').length > 0) {
$('input[name="' + fieldName + '"]').val(reward_id);
} else {
$('form').append('<input type="hidden" name="' + fieldName + '" value="' + reward_id + '">');
}
return reward_id;
}
return false;
} catch (error) {
layer.close(load);
layer.msg('网络错误,请稍后重试', { icon: 2, anim: 6, time: 1500 });
return false;
}
}
};
return instanceId;
}
/**
* 验证奖励信息 (兼容旧版本调用)
* @param {string} instanceId - 实例ID为空时使用最后一个实例
* @returns {boolean} - 验证结果
*/
function validateRewardInfo(instanceId = null) {
// 如果没有指定实例ID使用最后创建的实例
if (!instanceId) {
var instances = Object.keys(rewardInstances);
if (instances.length === 0) return false;
instanceId = instances[instances.length - 1];
}
// 如果指定的实例不存在返回false
if (!rewardInstances[instanceId]) return false;
// 调用实例的验证方法
return rewardInstances[instanceId].validateRewardInfo();
}
/**
* 处理奖励数据 (兼容旧版本调用)
* @param {string} instanceId - 实例ID为空时使用最后一个实例
*/
function processRewardData(instanceId = null) {
// 如果没有指定实例ID使用最后创建的实例
if (!instanceId) {
var instances = Object.keys(rewardInstances);
if (instances.length === 0) return;
instanceId = instances[instances.length - 1];
}
// 如果指定的实例不存在,直接返回
if (!rewardInstances[instanceId]) return;
// 调用实例的数据处理方法
rewardInstances[instanceId].processRewardData();
}
/**
* 处理奖励数据将其转换为JSON格式并添加到隐藏字段 (兼容旧版本调用)
* @param {string} pre - 前缀
* @param {string} reward_id - 奖励ID
* @param {string} instanceId - 实例ID为空时使用最后一个实例
* @returns {Promise<string|boolean>} - 返回reward_id或false
*/
async function processRewardIdData(pre, reward_id = '', instanceId = null) {
// 如果没有指定实例ID使用最后创建的实例
if (!instanceId) {
var instances = Object.keys(rewardInstances);
if (instances.length === 0) return false;
instanceId = instances[instances.length - 1];
}
// 如果指定的实例不存在返回false
if (!rewardInstances[instanceId]) return false;
// 调用实例的数据处理方法
return await rewardInstances[instanceId].processRewardIdData(pre, reward_id);
}