Browse Source

优化刮奖逻辑

master
wanghongjun 3 years ago
parent
commit
932c5a6be7
  1. 8
      app/controller/Zone.php
  2. 348
      app/logic/Zone.php
  3. 34
      app/model/ConsumptionRecords.php
  4. BIN
      public/storage/number_icon/01.png
  5. BIN
      public/storage/number_icon/02.png
  6. BIN
      public/storage/number_icon/03.png
  7. BIN
      public/storage/number_icon/04.png
  8. BIN
      public/storage/number_icon/05.png
  9. BIN
      public/storage/number_icon/06.png
  10. BIN
      public/storage/number_icon/07.png
  11. BIN
      public/storage/number_icon/08.png
  12. BIN
      public/storage/number_icon/09.png
  13. BIN
      public/storage/number_icon/10.png
  14. BIN
      public/storage/number_icon/11.png
  15. BIN
      public/storage/number_icon/12.png
  16. BIN
      public/storage/number_icon/13.png
  17. BIN
      public/storage/number_icon/14.png
  18. BIN
      public/storage/number_icon/15.png
  19. BIN
      public/storage/number_icon/16.png
  20. BIN
      public/storage/number_icon/17.png
  21. BIN
      public/storage/number_icon/18.png
  22. BIN
      public/storage/number_icon/19.png
  23. BIN
      public/storage/number_icon/20.png
  24. BIN
      public/storage/number_icon/21.png
  25. BIN
      public/storage/number_icon/22.png
  26. BIN
      public/storage/number_icon/23.png
  27. BIN
      public/storage/number_icon/24.png
  28. BIN
      public/storage/number_icon/25.png
  29. BIN
      public/storage/number_icon/26.png
  30. BIN
      public/storage/number_icon/27.png
  31. BIN
      public/storage/number_icon/28.png
  32. BIN
      public/storage/number_icon/29.png
  33. BIN
      public/storage/number_icon/30.png

8
app/controller/Zone.php

@ -80,10 +80,10 @@ class Zone extends BaseController
if (!$judgeRes) return $this->renderError('余额不足');
# 获取刮奖图片
$data = ZoneLogic::createOrder($userData['id'],$zoneGoodsId);
$data = ZoneLogic::ticketing($userData['id'],$zoneGoodsId,2);
if (!$data['status']) $this->renderError($data['msg']);
return $this->renderSuccess('开始刮奖',['list' => $data['data'], 'c_r_id' => $data['c_r_id']]);
return $this->renderSuccess('开始刮奖',['list' => $data['data'], 'c_r_id' => $data['c_r_id'],'prizes_data' => $data['prizes_data']]);
}
/**
@ -99,13 +99,13 @@ class Zone extends BaseController
$c_r_id = $param['c_r_id'];
$userData = $this->request->userInfo;
$res = ZoneLogic::endOrder($userData['id'],$c_r_id);
$res = ZoneLogic::endTicketing($userData['id'],$c_r_id);
if (!$res['status']) return $this->renderError($res['msg']);
return $this->renderSuccess(
$res['awards_amount'] > 0 ? '恭喜你中奖了' : '未中奖',
['awards_amount' => $res['awards_amount'],'list' => $res['data']]
['awards_amount' => $res['awards_amount'],'list' => $res['data'],'prizes_data' => $res['prizes_data']]
);
}

348
app/logic/Zone.php

@ -34,6 +34,123 @@ class Zone
return true;
}
/**
* 出奖
* @param $user_id
* @param $zone_goods_id
* @param $type
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException、
*/
public static function ticketing($user_id,$zone_goods_id,$type = 1)
{
# 获取奖项个参数
$zoneParamArr = ZoneGoodsParam::getList(['zone_goods_id' => $zone_goods_id]);
if (empty($zoneParamArr)) return ['status' => 0, 'msg' => '刮奖失败'];
# 获取刮刮乐信息
if ($type == 1) {
$resData = self::getWinningPrize($zoneParamArr);
} else {
$resData = self::getWinningPrizeRandNumber($zoneParamArr);
}
$save_data = $resData['save_data'];
$prizes_data = $resData['prizes_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'];
}
}
}
}
# 处理数据返回
$data = self::handleTextData($save_data,1);
# 开启事务
$connection = Db::connect();
try {
$connection->startTrans();
# 扣除余额
$zoneGoodsModel = ZoneGoods::field('price')->find($zone_goods_id);
$price = $zoneGoodsModel['price'];
$balance = User::decrBalance($user_id,$price);
# 判断是否中奖
$awards_status = 0;
if ($awards_amount > 0) {
$awards_status = 1;
# 修改用户余额
$balance = User::incrWithdrawalBalance($user_id,$awards_amount);
}
# 消费订单
$c_r_id = ConsumptionRecords::saveRecords($user_id,$zone_goods_id,$price,$price,$balance,$save_data,$prizes_data,$awards_status);
if ($awards_status == 1) {
# 中奖做记录
AwardsRecords::createRecords($user_id,$c_r_id,$awards_amount,$balance);
}
$connection->commit();
# 返回 刮奖数据 、 消费ID
return ['status' => 1, 'data' => $data, 'c_r_id' => $c_r_id, 'prizes_data' => $prizes_data];
} catch (\Exception $e) {
$connection->rollback();
return ['status' => 0, 'msg' => '操作失败'];
}
}
/**
* 刮奖完成
* @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 $user_id
@ -169,9 +286,10 @@ class Zone
/**
* 处理刮奖信息数据
* @param $data
* @param $is_awards // 1-删除 0-不删
* @return mixed
*/
public static function handleTextData($data)
public static function handleTextData($data,$is_awards = 0)
{
foreach ($data as $key => $value) {
@ -179,13 +297,16 @@ class Zone
#$data[$key][$k]['amount'] = rtrim($v['amount'],'.00');
unset($data[$key][$k]['id']);
if ($is_awards) {
unset($data[$key][$k]['is_awards']);
}
}
}
return $data;
}
/**
* 获取刮刮乐信息(概率算法)
* 获取刮刮乐信息(概率算法 - 自定义中奖图片 - 获取随机无奖图片
* @param array $patterns // 数据 和 占比
* @param int $direction // 纵向数量
* @param int $transverse // 横向数量
@ -256,6 +377,100 @@ class Zone
];
}
/**
* 获取刮刮乐信息(概率算法 - 随机中奖数字图片 随机无奖数字图片)
* @param array $patterns // 数据 和 占比
* @param int $direction // 纵向数量
* @param int $transverse // 横向数量
* @param int $randNum // 中奖号码数量
* @return array[]
*/
public static function getWinningPrizeRandNumber(array $patterns,int $direction = 3,int $transverse = 4, int $randNum = 3)
{
# 中奖号码
$prizesFiles = []; # 有奖号码图片
# 获取数字图片
$noPrizeFiles = return_image_name('number_icon'); # 无奖号码图片
# 获取随机中奖数字 踢出所在数组
for ($i = 1; $i <= $randNum; $i++) {
$rand = rand(0,count($noPrizeFiles)-1);
$prizesFiles[] = $noPrizeFiles[$rand];
unset($noPrizeFiles[$rand]);
sort($noPrizeFiles);
}
$noPrizeCount = count($noPrizeFiles);
// 计算概率总和
$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);
$data = [];
$save_data = [];
for ($i = 0; $i < $direction; $i++) {
for ($j = 0; $j < $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['awards'] == '1') {
$tempRand = rand(0,$randNum -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(100000,true);
# 返回给用户数据
$data[$i][] = [
'amount' => $amount,
'pinyin' => $pinyin,
'image' => $numberImage
];
# 保存到系统数据
$save_data[$i][] = [
'id' => $selectedPattern['id'],
'amount' => $amount,
'pinyin' => $pinyin,
'image' => $numberImage
];
}
}
# 返回中奖图片地址
foreach ($prizesFiles as &$valFiles) {
$valFiles = get_image_url($valFiles);
}
return [
'data' => $data,
'save_data' => $save_data,
'prizes_data' => $prizesFiles
];
}
/**
* 自动刮奖测试机
* @param $user_id
@ -283,69 +498,72 @@ class Zone
$limit = 1;
while ($limit <= $count) {
# 获取奖项个参数
$zoneParamArr = ZoneGoodsParam::getList(['zone_goods_id' => $zone_goods_id]);
if (empty($zoneParamArr)) return '奖项不存在';
# 获取刮刮乐信息
$resData = Zone::getWinningPrize($zoneParamArr);
$data = $resData['data'];
$save_data = $resData['save_data'];
# 开启事务
$connection = Db::connect();
try {
$connection->startTrans();
# 扣除余额
$zoneGoodsModel = ZoneGoods::field('price')->find($zone_goods_id);
$price = $zoneGoodsModel['price'];
$balance = User::decrBalance($user_id,$price);
# 消费记录
$c_r_id = ConsumptionRecords::createRecords($user_id,$zone_goods_id,$price,$price,$balance,$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 += $item['amount'];
}
}
}
}
$ConsumptionRecords = new ConsumptionRecords();
$ConsumptionRecords::awardsData($save_data,$c_r_id);
# 判断是否中奖
if ($awards_amount > 0) {
# 修改用户余额
$balance = User::incrWithdrawalBalance($user_id,$awards_amount);
# 中奖做记录
AwardsRecords::createRecords($user_id,$c_r_id,$awards_amount,$balance);
}
# 完成订单
ConsumptionRecords::endOrder($c_r_id,$awards_amount);
$connection->commit();
# 返回刮刮乐图标、金额、订单id
} catch (\Exception $e) {
$connection->rollback();
return $e->getMessage();
}
$result = self::ticketing($user_id,$zone_goods_id,2);
if (!$result['status']) return $result['msg'];
// # 获取奖项个参数
// $zoneParamArr = ZoneGoodsParam::getList(['zone_goods_id' => $zone_goods_id]);
// if (empty($zoneParamArr)) return '奖项不存在';
//
// # 获取刮刮乐信息
// $resData = Zone::getWinningPrize($zoneParamArr);
// #$data = $resData['data'];
// $save_data = $resData['save_data'];
//
// # 开启事务
// $connection = Db::connect();
// try {
//
// $connection->startTrans();
//
// # 扣除余额
// $zoneGoodsModel = ZoneGoods::field('price')->find($zone_goods_id);
// $price = $zoneGoodsModel['price'];
// $balance = User::decrBalance($user_id,$price);
//
// # 消费记录
// $c_r_id = ConsumptionRecords::createRecords($user_id,$zone_goods_id,$price,$price,$balance,$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 += $item['amount'];
// }
// }
// }
// }
//
// $ConsumptionRecords = new ConsumptionRecords();
//
// $ConsumptionRecords::awardsData($save_data,$c_r_id);
//
// # 判断是否中奖
// if ($awards_amount > 0) {
//
// # 修改用户余额
// $balance = User::incrWithdrawalBalance($user_id,$awards_amount);
//
// # 中奖做记录
// AwardsRecords::createRecords($user_id,$c_r_id,$awards_amount,$balance);
// }
//
// # 完成订单
// ConsumptionRecords::endOrder($c_r_id,$awards_amount);
//
// $connection->commit();
//
// # 返回刮刮乐图标、金额、订单id
// } catch (\Exception $e) {
//
// $connection->rollback();
// return $e->getMessage();
// }
# 循环执行
$limit++;
}

34
app/model/ConsumptionRecords.php

@ -30,6 +30,40 @@ class ConsumptionRecords extends Model
return $records->id;
}
/**
* 保存消费记录
* @param $user_id // 用户id
* @param $z_g_id // 专区商品id
* @param $price // 原价
* @param $actual_price // 实际支付金额
* @param $residue_amount // 剩余余额
* @param $data // 剩余余额
* @param $prizes_data // 有奖区
* @param $awards_status // 中奖状态
* @return mixed
*/
public static function saveRecords($user_id,$z_g_id,$price,$actual_price,$residue_amount,$data,$prizes_data = [],$awards_status = 0)
{
$records = new ConsumptionRecords();
$records->user_id = $user_id;
$records->zone_goods_id = $z_g_id;
$records->price = $price;
$records->text_data = serialize($data);
$records->actual_price = $actual_price;
$records->residue_amount = $residue_amount;
$records->create_time = date("Y-m-d H:i:s",time());
$records->status = 1;
if (!empty($prizes_data)) {
$records->prizes_data = serialize($prizes_data);
}
$records->complete_time = date("Y-m-d H:i:s",time());
$records->awards_status = $awards_status;
$records->save();
return $records->id;
}
/**
* 完成订单
* @param $c_r_id

BIN
public/storage/number_icon/01.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
public/storage/number_icon/02.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
public/storage/number_icon/03.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
public/storage/number_icon/04.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
public/storage/number_icon/05.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
public/storage/number_icon/06.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
public/storage/number_icon/07.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
public/storage/number_icon/08.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
public/storage/number_icon/09.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
public/storage/number_icon/10.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
public/storage/number_icon/11.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
public/storage/number_icon/12.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
public/storage/number_icon/13.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
public/storage/number_icon/14.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
public/storage/number_icon/15.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
public/storage/number_icon/16.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
public/storage/number_icon/17.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
public/storage/number_icon/18.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
public/storage/number_icon/19.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
public/storage/number_icon/20.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
public/storage/number_icon/21.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
public/storage/number_icon/22.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
public/storage/number_icon/23.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
public/storage/number_icon/24.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
public/storage/number_icon/25.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
public/storage/number_icon/26.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
public/storage/number_icon/27.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
public/storage/number_icon/28.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
public/storage/number_icon/29.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
public/storage/number_icon/30.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Loading…
Cancel
Save