You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
759 lines
27 KiB
759 lines
27 KiB
<?php
|
|
|
|
namespace app\logic;
|
|
use app\common\lib\pinyin\PinyinNumber;
|
|
use app\model\AwardsLog;
|
|
use app\model\AwardsRecords;
|
|
use app\model\ConsumptionRecords;
|
|
use app\model\RechargeRecords;
|
|
use app\model\Setting as SettingModel;
|
|
use app\model\User;
|
|
use app\model\ZoneAmountParam;
|
|
use app\model\ZoneGoods;
|
|
use app\model\ZoneGoodsParam;
|
|
use app\model\ZoneGoodsPlay;
|
|
use think\facade\Db;
|
|
|
|
/**
|
|
* 专区逻辑层
|
|
*/
|
|
class ZoneLogic
|
|
{
|
|
|
|
protected static $user_id; // 用户id
|
|
protected static $userData; // 用户数据
|
|
protected static $zone_goods_id; // 刮奖商品id
|
|
protected static $zoneGoodsData; // 刮奖商品数据
|
|
protected static $rechargeAmountId; // 最早一次充值id
|
|
protected static $judgeRateData; // 概率数据
|
|
protected static $play_code; // 玩法编码
|
|
protected static $patterns; // 概率数据组
|
|
protected static $param; // 中奖号码 中奖图案数据组
|
|
protected static $awards_icon_dirname; // 中奖图案目录
|
|
protected static $awards_number_count = 0; // 中奖号码数量
|
|
protected static $direction = 3; // 纵向数量
|
|
protected static $transverse = 4; // 横向数量
|
|
protected static $rate; // 概率
|
|
|
|
/**
|
|
* 刮奖初始化数据
|
|
* @param $user_id
|
|
* @param $zone_goods_id
|
|
* @return bool|string
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
* @throws \think\db\exception\DbException
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
*/
|
|
protected static function ticketingInit($zone_goods_id, $user_id)
|
|
{
|
|
self::$user_id = $user_id;
|
|
self::$zone_goods_id = $zone_goods_id;
|
|
|
|
# 判断余额够不够
|
|
$judgeRes = self::judgeBalance();
|
|
if (!$judgeRes) return '余额不足';
|
|
|
|
$zoneGoods = ZoneGoods::where('id', self::$zone_goods_id)->find();
|
|
if (empty($zoneGoods)) return '刮奖失败';
|
|
|
|
self::$awards_number_count = $zoneGoods['awards_number_count']; // 中奖号码数量
|
|
self::$direction = $zoneGoods['direction_count']; // 纵向数量
|
|
self::$transverse = $zoneGoods['transverse_count']; // 横向数量
|
|
self::$awards_icon_dirname = $zoneGoods['awards_icon_dirname']; // 中奖图案图片地址
|
|
|
|
$playRes = ZoneGoodsPlay::find($zoneGoods['play_id']);
|
|
if (empty($playRes)) return '未设置玩法';
|
|
self::$play_code = $playRes['play_code'];
|
|
|
|
$zoneParamArr = self::getZoneParam(['zone_goods_id' => self::$zone_goods_id]);
|
|
if (empty($zoneParamArr)) return '未设置中奖参数';
|
|
self::$patterns = $zoneParamArr;
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 出奖
|
|
* @param $user_id
|
|
* @param $zone_goods_id
|
|
* @return array
|
|
*/
|
|
public static function ticketing($user_id, $zone_goods_id): array
|
|
{
|
|
# 获取刮奖玩法设定规则参数
|
|
try {
|
|
$initMsg = self::ticketingInit($zone_goods_id, $user_id);
|
|
if ($initMsg !== true) throw new \Exception($initMsg);
|
|
|
|
# 获取刮奖数据
|
|
$resData = self::getTextData();
|
|
|
|
$save_data = $resData['save_data'];
|
|
$prizes_data = $resData['prizes_data'] ?? [];
|
|
$prizes_icon_data = $resData['prizes_icon_data'] ?? [];
|
|
|
|
# 解析是否中奖,组合中奖金额
|
|
$awards_amount = self::calculateAmount($save_data);
|
|
|
|
# 处理数据返回
|
|
$data = self::handleTextData($save_data);
|
|
|
|
# 结算金额
|
|
$settlementRes = self::settlementAmount($awards_amount, $save_data, $prizes_data, $prizes_icon_data);
|
|
if (!$settlementRes['status']) throw new \Exception($settlementRes['msg']);
|
|
|
|
# 返回客户 刮奖数据 、 消费ID 、 code 玩法模板标识
|
|
$returnData = [
|
|
'status' => 1,
|
|
'data' => $data,
|
|
'c_r_id' => $settlementRes['c_r_id'],
|
|
'code' => self::$play_code
|
|
];
|
|
|
|
if (!empty($prizes_data)) $returnData['prizes_data'] = $prizes_data;
|
|
if (!empty($prizes_icon_data)) $returnData['prizes_icon_data'] = $prizes_icon_data;
|
|
|
|
return $returnData;
|
|
} catch (\Exception $e) {
|
|
return ['status' => 0, 'msg' => $e->getMessage()];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取刮奖参数
|
|
* @param $where
|
|
* @return array
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
* @throws \think\db\exception\DbException
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
*/
|
|
protected static function getZoneParam($where = []): array
|
|
{
|
|
$where['status'] = 1;
|
|
$list = ZoneGoodsParam::where($where)
|
|
->field('id,amount,image,probability,awards')
|
|
->order('probability')
|
|
->select()
|
|
->toArray();
|
|
|
|
$ZoneAmountParam = [];
|
|
$sumProbability = 0;
|
|
$sumCount = self::$direction * self::$transverse;
|
|
|
|
$judgeRateData = self::judgeUserRate();
|
|
self::$judgeRateData = $judgeRateData;
|
|
|
|
foreach ($list as &$item) {
|
|
# 判断是否有奖
|
|
$item = self::settingNoPrize($item,$judgeRateData,$sumCount);
|
|
if (!$item['id']) continue;
|
|
|
|
if ($item['image']) $item['image'] = get_image_url($item['image']);
|
|
if ($item['awards'] != 1) {
|
|
# 获取无奖项随机金额
|
|
$res = ZoneAmountParam::getRandAmount($ZoneAmountParam);
|
|
$item['amount'] = $res['amount'];
|
|
$ZoneAmountParam = $res['data'];
|
|
}
|
|
#$item['probability'] = round($item['probability'] / $sumCount,14);
|
|
$sumProbability += $item['probability'];
|
|
}
|
|
|
|
# 概率未补全则自动补全 归1
|
|
if ($sumProbability < 1 && strpos($sumProbability,'.') !== false) {
|
|
for ($i = 1; $i <= 10; $i++) {
|
|
$residueProbability = 1 - $sumProbability;
|
|
$res = ZoneAmountParam::getRandAmount($ZoneAmountParam);
|
|
$list[] = [
|
|
'id' => 0,
|
|
'amount' => $res['amount'],
|
|
'image' => rand_icon('icon',true),
|
|
'probability' => $residueProbability / 10,
|
|
'awards' => 0
|
|
];
|
|
}
|
|
}
|
|
return $list;
|
|
}
|
|
|
|
/**
|
|
* 判断余额是否足够
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
* @throws \think\db\exception\DbException
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
*/
|
|
protected static function judgeBalance(): bool
|
|
{
|
|
$userModel = User::field('id,aid,balance,withdrawal_balance')->find(self::$user_id);
|
|
$balance = $userModel->balance ?: 0;
|
|
self::$userData = $userModel->toArray();
|
|
|
|
$zoneGoodsModel = ZoneGoods::field('zone_id,price,direction_count,transverse_count,play_id')->find(self::$zone_goods_id);
|
|
$price = $zoneGoodsModel->price ?: 0;
|
|
self::$zoneGoodsData = $zoneGoodsModel->toArray();
|
|
|
|
// if ($balance < $price) {
|
|
// $withdrawal_balance = $userModel->withdrawal_balance ?: 0;
|
|
// $balance = bcadd($balance,$withdrawal_balance,2);
|
|
// }
|
|
|
|
if ($balance < $price) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 计算奖金
|
|
* @param $save_data
|
|
* @return int|mixed
|
|
*/
|
|
protected static function calculateAmount(&$save_data)
|
|
{
|
|
$awards_amount = 0;
|
|
foreach ($save_data as $key => $goodsParam) {
|
|
foreach ($goodsParam as $k => $item) {
|
|
$save_data[$key][$k]['is_awards'] = 0;
|
|
if (isset($item['id'])) {
|
|
$awardsAmountRes = ZoneGoodsParam::getAwardsAmount($item['id']);
|
|
if ($awardsAmountRes) {
|
|
$save_data[$key][$k]['is_awards'] = 1;
|
|
$awards_amount += $awardsAmountRes['amount'];
|
|
AwardsLog::createLog(self::$zone_goods_id,self::$user_id,$awardsAmountRes['amount']);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $awards_amount;
|
|
}
|
|
|
|
/**
|
|
* 结算金额
|
|
* @param $awards_amount
|
|
* @param $text_data
|
|
* @param $prizes_data
|
|
* @param $prizes_icon_data
|
|
* @return array
|
|
*/
|
|
protected static function settlementAmount($awards_amount, $text_data, $prizes_data, $prizes_icon_data): array
|
|
{
|
|
# 开启事务
|
|
$connection = Db::connect();
|
|
try {
|
|
|
|
$connection->startTrans();
|
|
|
|
# 扣除余额
|
|
$userData = self::$userData;
|
|
$zoneGoodsData = self::$zoneGoodsData;
|
|
$price = $zoneGoodsData['price'];
|
|
|
|
# 消费金额
|
|
$consumptionBalance = 0; // 余额消费剩余金额
|
|
$balancePrice = 0; // 余额实际支付金额
|
|
$consumptionWithdrawalBalance = 0;// 可提消费剩余金额
|
|
$withdrawalBalancePrice = 0;// 可提余额实际支付金额
|
|
# 余额小于金额 且可提余额能补足
|
|
if ($userData['balance'] < $price) {
|
|
|
|
if ($userData['balance'] > 0) {
|
|
$balancePrice = $userData['balance'];
|
|
$consumptionBalance = User::decrBalance(self::$user_id, $userData['balance']);
|
|
}
|
|
# 剩余余额
|
|
$residue_price = bcsub($price,$userData['balance']);
|
|
$withdrawalBalancePrice = $residue_price;
|
|
$consumptionWithdrawalBalance = User::decrWithdrawalBalance(self::$user_id,$residue_price);
|
|
} else {
|
|
$consumptionBalance = User::decrBalance(self::$user_id, $price);
|
|
$balancePrice = $price;
|
|
}
|
|
|
|
# 判断是否中奖
|
|
$awards_status = 0;
|
|
# 可提余额
|
|
$withdrawal_balance = 0;
|
|
if ($awards_amount > 0) {
|
|
|
|
$awards_status = 1;
|
|
|
|
# 修改用户可提余额
|
|
$withdrawal_balance = User::incrWithdrawalBalance(self::$user_id, $awards_amount);
|
|
}
|
|
|
|
# 消费订单
|
|
$otherData = [
|
|
'prizes_data' => $prizes_data,
|
|
'awards_status' => $awards_status,
|
|
'prizes_icon_data' => $prizes_icon_data
|
|
];
|
|
# 余额消费记录 - 余额大于0
|
|
if ($userData['balance'] > 0) {
|
|
$otherData['actual_type'] = 1;
|
|
$c_r_id = ConsumptionRecords::saveRecords(self::$user_id, self::$zone_goods_id, $price, $balancePrice, $consumptionBalance, $text_data, $otherData);
|
|
}
|
|
# 可提余额消费记录 - 余额小于金额
|
|
if ($userData['balance'] < $price) {
|
|
$otherData['actual_type'] = 2;
|
|
$c_r_id = ConsumptionRecords::saveRecords(self::$user_id, self::$zone_goods_id, $price, $withdrawalBalancePrice, $consumptionWithdrawalBalance, $text_data, $otherData);
|
|
}
|
|
|
|
# 消费返点
|
|
User::addRebateRatioAmount(self::$user_id, $price, 0, $c_r_id);
|
|
|
|
if ($awards_status == 1) {
|
|
# 中奖做记录
|
|
AwardsRecords::createRecords(self::$user_id, $c_r_id, $awards_amount, $withdrawal_balance);
|
|
}
|
|
|
|
# 使用金额增加
|
|
RechargeRecords::incrUsageAmount([['id', '=', self::$rechargeAmountId]],$price);
|
|
|
|
$connection->commit();
|
|
# 消费ID
|
|
return ['status' => 1, 'c_r_id' => $c_r_id];
|
|
} catch (\Exception $e) {
|
|
$connection->rollback();
|
|
return ['status' => 0, 'msg' => '操作失败'];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 选择玩法返回不同刮奖数据
|
|
* @return array
|
|
*/
|
|
protected static function getTextData()
|
|
{
|
|
$returnArr = ['save_data' => []];
|
|
switch (self::$play_code) {
|
|
// 数字 + 中奖号码
|
|
case 'digit_number':
|
|
# 中奖号码
|
|
$prizesFiles = []; # 有奖号码图片
|
|
# 获取数字图片
|
|
$noPrizeFiles = return_image_name('number_icon'); # 无奖号码图片
|
|
# 获取随机中奖数字 踢出所在数组
|
|
for ($i = 1; $i <= self::$awards_number_count; $i++) {
|
|
$rand = rand(0,count($noPrizeFiles)-1);
|
|
$prizesFiles[] = $noPrizeFiles[$rand];
|
|
unset($noPrizeFiles[$rand]);
|
|
sort($noPrizeFiles);
|
|
}
|
|
# 传参给方法使用
|
|
self::$param = ['noPrizeFiles' => $noPrizeFiles,'prizesFiles' => $prizesFiles];
|
|
# 拼接完整连接
|
|
foreach ($prizesFiles as &$file_icon) $file_icon = get_image_url($file_icon);
|
|
$returnArr['save_data'] = self::probabilityAlgorithm('digitNumber');
|
|
$returnArr['prizes_data'] = $prizesFiles;
|
|
break;
|
|
// 数字 + 图标
|
|
case 'digit_icon':
|
|
$noPrizeFiles = return_image_name('number_icon'); # 无奖号码图片
|
|
foreach ($noPrizeFiles as $key => $value) {
|
|
if (in_array($value,['number_icon/06.png','number_icon/07.png'])) unset($noPrizeFiles[$key]);
|
|
}
|
|
sort($noPrizeFiles);
|
|
# 传参给方法使用
|
|
self::$param = ['noPrizeFiles' => $noPrizeFiles];
|
|
$returnArr['save_data'] = self::probabilityAlgorithm('digitIcon');
|
|
break;
|
|
// 数字 + 中奖号码 + 图标
|
|
case 'digit_number_icon':
|
|
# 中奖号码
|
|
$prizesFiles = []; # 有奖号码图片
|
|
# 获取数字图片
|
|
$noPrizeFiles = return_image_name('number_icon'); # 无奖号码图片
|
|
# 获取随机中奖数字 踢出所在数组
|
|
for ($i = 1; $i <= self::$awards_number_count; $i++) {
|
|
$rand = rand(0,count($noPrizeFiles)-1);
|
|
$prizesFiles[] = $noPrizeFiles[$rand];
|
|
unset($noPrizeFiles[$rand]);
|
|
sort($noPrizeFiles);
|
|
}
|
|
# 传参给方法使用
|
|
self::$param = ['noPrizeFiles' => $noPrizeFiles,'prizesFiles' => $prizesFiles];
|
|
$returnArr['save_data'] = self::probabilityAlgorithm('digitNumberIcon');
|
|
# 拼接完整连接
|
|
foreach ($prizesFiles as &$file_icon) $file_icon = get_image_url($file_icon);
|
|
$returnArr['prizes_data'] = $prizesFiles;
|
|
# 获取指定有奖图标
|
|
$awards_icon = return_image_name(self::$awards_icon_dirname);
|
|
$rand_icon = [];
|
|
$randomKeys = array_rand($awards_icon, 4);
|
|
foreach ($randomKeys as $key) $rand_icon[] = get_image_url($awards_icon[$key]);
|
|
$prizes_icon_data = [
|
|
[$rand_icon[0],$rand_icon[1]],
|
|
[$rand_icon[2],$rand_icon[3]]
|
|
];
|
|
$returnArr['prizes_icon_data'] = $prizes_icon_data;
|
|
break;
|
|
// 图标
|
|
case 'icon':
|
|
$returnArr['save_data'] = self::probabilityAlgorithm('icon');
|
|
break;
|
|
default :
|
|
return [];
|
|
}
|
|
return $returnArr;
|
|
}
|
|
|
|
/**
|
|
* 概率算法
|
|
* $patterns = [
|
|
* ['image' => 'prize1.png', 'probability' => 0.3], // 奖项图案,概率为30%
|
|
* ['image' => 'prize2.png', 'probability' => 0.2], // 奖项图案,概率为20%
|
|
* ['image' => 'no_prize1.png', 'probability' => 0.1], // 奖项图案,概率为10%
|
|
* ['image' => 'no_prize2.png', 'probability' => 0.32], // 奖项图案,概率为40%
|
|
* ];
|
|
* @param $function
|
|
* @return array
|
|
*/
|
|
protected static function probabilityAlgorithm($function)
|
|
{
|
|
$patterns = self::$patterns;
|
|
|
|
// 计算概率总和
|
|
$totalProbability = 0;
|
|
foreach ($patterns as $pattern) {
|
|
$totalProbability += $pattern['probability'];
|
|
}
|
|
|
|
// 归一化处理,并计算累积概率
|
|
$accumulatedProbability = 0;
|
|
foreach ($patterns as &$pattern) {
|
|
$pattern['probability'] /= $totalProbability; // 归一化处理
|
|
$accumulatedProbability += $pattern['probability'];
|
|
$pattern['accumulatedProbability'] = $accumulatedProbability; // 累积概率
|
|
}
|
|
unset($pattern);
|
|
|
|
$save_data = [];
|
|
$sumAmount = 0;
|
|
for ($i = 0; $i < self::$direction; $i++) {
|
|
|
|
for ($j = 0; $j < self::$transverse; $j++) { // 每组生成 3 个图案
|
|
|
|
$selectedPattern = null;
|
|
$randomNumber = mt_rand() / mt_getrandmax(); // 生成 0 到 1 之间的随机数
|
|
|
|
foreach ($patterns as $pattern) {
|
|
if ($randomNumber <= $pattern['accumulatedProbability']) {
|
|
$selectedPattern = $pattern;
|
|
break;
|
|
}
|
|
}
|
|
|
|
# 限制奖金
|
|
if ($selectedPattern['id'] > 0) {
|
|
$sumAmount += $selectedPattern['amount'];
|
|
}
|
|
$selectedPattern = self::restrictAmount($selectedPattern,$sumAmount);
|
|
|
|
$save_data[$i][] = self::$function($selectedPattern);
|
|
}
|
|
}
|
|
return $save_data;
|
|
}
|
|
|
|
/**
|
|
* 数字+中奖号码 玩法
|
|
* @param $selectedPattern
|
|
* @return array
|
|
*/
|
|
protected static function digitNumber($selectedPattern)
|
|
{
|
|
$noPrizeFiles = self::$param['noPrizeFiles'];
|
|
$prizesFiles = self::$param['prizesFiles'];
|
|
|
|
$noPrizeCount = count($noPrizeFiles);
|
|
|
|
# 有奖 无奖指定图片
|
|
if ($selectedPattern['awards'] == '1') {
|
|
$tempRand = rand(0,self::$awards_number_count -1);
|
|
$numberImage = $prizesFiles[$tempRand];
|
|
} else {
|
|
$tempRand = rand(0,$noPrizeCount - 1);
|
|
$numberImage = $noPrizeFiles[$tempRand];
|
|
}
|
|
$numberImage = get_image_url($numberImage);
|
|
|
|
# 金额拼音
|
|
$amount = round($selectedPattern['amount']);
|
|
$pinyin = PinyinNumber::getPinyin($amount,true);
|
|
$amount_format = number_format($amount);
|
|
|
|
return [
|
|
'id' => $selectedPattern['id'],
|
|
'amount' => $amount_format,
|
|
'pinyin' => $pinyin,
|
|
'image' => $numberImage
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 数字+图标 玩法
|
|
* @param $selectedPattern // 概率选中数据
|
|
* @return array
|
|
*/
|
|
protected static function digitIcon($selectedPattern)
|
|
{
|
|
$noPrizeFiles = self::$param['noPrizeFiles'];
|
|
$noPrizeCount = count($noPrizeFiles);
|
|
|
|
$numberImage = $selectedPattern['image'];
|
|
|
|
$amount = round($selectedPattern['amount']);
|
|
|
|
# 无奖替换成 数字icon
|
|
if ($selectedPattern['awards'] != '1') {
|
|
$tempRand = rand(0,$noPrizeCount - 1);
|
|
$numberImage = $noPrizeFiles[$tempRand];
|
|
}
|
|
$pinyin = PinyinNumber::getPinyin($amount,true);
|
|
|
|
$numberImage = get_image_url($numberImage);
|
|
$amount_format = number_format($amount);
|
|
$image_url = get_image_url($numberImage);
|
|
|
|
return [
|
|
'id' => $selectedPattern['id'],
|
|
'amount' => $amount_format,
|
|
'pinyin' => $pinyin,
|
|
'image' => $image_url
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 数字+中奖号码+图标 玩法
|
|
* @return array
|
|
*/
|
|
protected static function digitNumberIcon($selectedPattern)
|
|
{
|
|
$param = self::$param;
|
|
|
|
return self::digitNumber($selectedPattern);
|
|
}
|
|
|
|
/**
|
|
* 图标玩法
|
|
* @return array
|
|
*/
|
|
protected static function icon($selectedPattern)
|
|
{
|
|
$amount = round($selectedPattern['amount']);
|
|
$pinyin = PinyinNumber::getPinyin($amount,true);
|
|
$amount_format = number_format($amount);
|
|
$image_url = get_image_url($selectedPattern['image']);
|
|
return [
|
|
'id' => $selectedPattern['id'],
|
|
'amount' => $amount_format,
|
|
'pinyin' => $pinyin,
|
|
'image' => $image_url
|
|
];
|
|
}
|
|
|
|
|
|
/**
|
|
* 刮奖完成
|
|
* @param $user_id
|
|
* @param $c_r_id
|
|
* @return array
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
* @throws \think\db\exception\DbException
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
*/
|
|
public static function endTicketing($user_id,$c_r_id)
|
|
{
|
|
|
|
# 验证
|
|
$queryWhere = ['user_id' => $user_id, 'id' => $c_r_id];
|
|
$ConsumptionRecords = new ConsumptionRecords();
|
|
$query = $ConsumptionRecords->where($queryWhere)->field('text_data,zone_goods_id,status,prizes_data')->find();
|
|
if (!$query) return ['status' => 0, 'msg' => '数据不存在'];
|
|
|
|
# 解密
|
|
$data = unserialize($query['text_data']);
|
|
$prizes_data = unserialize($query['prizes_data']);
|
|
$returnData = self::handleTextData($data);
|
|
|
|
$awards_amount = 0;
|
|
$AwardsRecordsRes = AwardsRecords::where('cr_id',$c_r_id)->find();
|
|
if ($AwardsRecordsRes) $awards_amount = round($AwardsRecordsRes['awards_amount']);
|
|
|
|
# 返回 刮奖数据 、 中奖号码、 中奖总金额、 中奖状态
|
|
return ['status' => 1, 'msg' => '完成', 'data' => $returnData, 'awards_amount' => $awards_amount, 'prizes_data' => $prizes_data];
|
|
}
|
|
|
|
/**
|
|
* 处理刮奖信息数据
|
|
* @param $data
|
|
* @param $is_awards // 1-删除 0-不删
|
|
* @return mixed
|
|
*/
|
|
public static function handleTextData($data,$is_awards = 0)
|
|
{
|
|
foreach ($data as $key => $value) {
|
|
|
|
foreach ($value as $k => $v) {
|
|
|
|
#$data[$key][$k]['amount'] = rtrim($v['amount'],'.00');
|
|
unset($data[$key][$k]['id']);
|
|
if ($is_awards) {
|
|
unset($data[$key][$k]['is_awards']);
|
|
}
|
|
}
|
|
}
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* 判断是否控制出奖金额
|
|
* @return array|int[]
|
|
*/
|
|
protected static function judgeUserRate():array
|
|
{
|
|
$residue_amount = 0;
|
|
$usage_rate = 0;
|
|
try {
|
|
$rate = SettingModel::settingLoad('amount_probability') ?: '0.5';
|
|
self::$rate = $rate;
|
|
|
|
# 最近一次充值金额
|
|
$lastRechargeAmount = RechargeRecords::lastRechargeAmount([['user_id','=',self::$user_id]]);
|
|
self::$rechargeAmountId = $lastRechargeAmount['id'];
|
|
|
|
if ($lastRechargeAmount) {
|
|
|
|
$recharge_time = $lastRechargeAmount['recharge_time']; // 充值时间
|
|
$recharge_amount = $lastRechargeAmount['recharge_amount']; // 充值金额
|
|
$usage_amount = $lastRechargeAmount['usage_amount']; // 充值金额
|
|
$estimate_awards_amount = round($recharge_amount * $rate,2); // 预估中奖金额
|
|
|
|
# 充值后消费金额
|
|
$AwardsRecords = new AwardsRecords();
|
|
$res = $AwardsRecords->where('user_id',self::$user_id)
|
|
->where('create_time','>=',$recharge_time)
|
|
->field('sum(awards_amount) as sum_amount')
|
|
->find();
|
|
$sum_amount = $res->sum_amount ?: 0;
|
|
|
|
# 当前中奖比率
|
|
$residue_amount = round($estimate_awards_amount - $sum_amount,2);
|
|
|
|
if ($residue_amount <= 0) {
|
|
|
|
# 不能中奖了
|
|
|
|
return ['status' => 1];
|
|
}
|
|
if ($usage_amount) {
|
|
$usage_rate = round($usage_amount / $recharge_amount,14);
|
|
}
|
|
// # 使用金额充值金额占比
|
|
// $usage_amount_rate = round($usage_amount / $recharge_amount,4);
|
|
// # 中奖金额小于预估金额 且 使用占比 展示小于 中奖概率时 加码
|
|
// $rateHalf = round($rate / 2,4);
|
|
// if ($sum_amount < $estimate_awards_amount && $usage_amount_rate > $rateHalf && $usage_amount_rate < $rate) {
|
|
// $usage_rate = round($sum_amount / $recharge_amount,4);
|
|
// }
|
|
//
|
|
// # 如果使用金额概率 达到 中奖概率 加码
|
|
// $temp_rate = round($usage_amount_rate/$rate,4);
|
|
// if ($temp_rate >= ($rateHalf + $rate)) {
|
|
// $usage_rate = $temp_rate;
|
|
// }
|
|
}
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
}
|
|
|
|
return [
|
|
'status' => 0,
|
|
'residue_amount' => $residue_amount,
|
|
'usage_rate' => $usage_rate
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 设置无奖场景
|
|
* @param $item
|
|
* @param $judgeRate
|
|
* @param $sumCount
|
|
* @return mixed
|
|
*/
|
|
protected static function settingNoPrize($item,$judgeRate,$sumCount)
|
|
{
|
|
if ($judgeRate['status'] == 1) {
|
|
$item['id'] = 0;
|
|
$item['awards'] = 0;
|
|
} else {
|
|
if ($item['amount'] > $judgeRate['residue_amount']) {
|
|
$item['id'] = 0;
|
|
$item['awards'] = 0;
|
|
} else {
|
|
$zoneGoodsData = self::$zoneGoodsData;
|
|
if ($judgeRate['usage_rate'] < '0.50') {
|
|
$item['probability'] = (float) number_format(($zoneGoodsData['price'] * self::$rate) / ($item['amount'] / self::$rate) / $sumCount * self::$rate, 14, '.', '');
|
|
} else {
|
|
$item['probability'] = (float) number_format(($zoneGoodsData['price'] * self::$rate) / ($item['amount'] / self::$rate) / $sumCount * (2* self::$rate), 14, '.', '');
|
|
}
|
|
}
|
|
}
|
|
return $item;
|
|
}
|
|
|
|
/**
|
|
* 限制奖金
|
|
* @param $selectedPattern
|
|
* @param $sumAmount
|
|
* @return mixed
|
|
*/
|
|
protected static function restrictAmount($selectedPattern,$sumAmount)
|
|
{
|
|
$judgeRateData = self::$judgeRateData;
|
|
if (!$judgeRateData['status'] && $sumAmount > $judgeRateData['residue_amount']) {
|
|
$selectedPattern['id'] = 0;
|
|
$selectedPattern['awards'] = 0;
|
|
}
|
|
return $selectedPattern;
|
|
}
|
|
|
|
/**
|
|
* 自动刮奖测试机
|
|
* @param int $user_id
|
|
* @param int $zone_goods_id
|
|
* @param int $count
|
|
* @return string|void
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
* @throws \think\db\exception\DbException
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
*/
|
|
public static function auto(int $user_id = 1,int $zone_goods_id = 1,int $count = 500)
|
|
{
|
|
# 验证
|
|
$user = User::find($user_id);
|
|
if (!$user) return '用户不存在';
|
|
$zoneGoods = ZoneGoods::find($zone_goods_id);
|
|
if (!$zoneGoods) return '刮奖商品不存在';
|
|
$zoneGoodsParam = ZoneGoodsParam::where('zone_goods_id',$zone_goods_id)->where('status',1)->find();
|
|
if (!$zoneGoodsParam) return '刮奖奖项不存在';
|
|
$balance = $user->balance ?: 0;
|
|
// if ($user->withdrawal_balance) {
|
|
// $balance += $user->withdrawal_balance;
|
|
// }
|
|
$sumPrice = $count * $zoneGoods['price'];
|
|
if ($balance < $sumPrice) return '用户余额不足';
|
|
|
|
# 开始执行
|
|
$limit = 1;
|
|
while ($limit <= $count) {
|
|
|
|
$result = self::ticketing($user_id,$zone_goods_id);
|
|
if (!$result['status']) return $result['msg'];
|
|
# 循环执行
|
|
$limit++;
|
|
}
|
|
return '完成';
|
|
}
|
|
}
|