140 lines
4.2 KiB
PHP
140 lines
4.2 KiB
PHP
<?php
|
|
// +----------------------------------------------------------------------
|
|
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
|
// +----------------------------------------------------------------------
|
|
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
|
// +----------------------------------------------------------------------
|
|
// | Author: ywxapp<admin@ywxapp.cn>
|
|
// +----------------------------------------------------------------------
|
|
declare (strict_types = 1);
|
|
|
|
namespace addon\wxchat\controller\api;
|
|
|
|
use addon\wxchat\model\WxchatLotteryPrize;
|
|
use addon\wxchat\model\WxchatLotteryRecord;
|
|
use think\facade\Db;
|
|
use think\facade\Request;
|
|
use ywxapp\controller\FrontendBase;
|
|
use ywxapp\service\WalletService;
|
|
|
|
/**
|
|
* Lottery 类
|
|
*
|
|
* @author ywxapp <admin@ywxapp.cn>
|
|
*/
|
|
class Lottery extends FrontendBase
|
|
{
|
|
protected $noNeedLogin = [];
|
|
protected $noNeedVerify = ['*'];
|
|
|
|
// 每次抽奖消耗金币
|
|
protected $cost = 10;
|
|
// 每日免费次数
|
|
protected $freeDaily = 1;
|
|
|
|
|
|
protected function initialize()
|
|
{
|
|
if ($this->auth->isLogin) {
|
|
$this->uid = $this->auth->model->uid;
|
|
}
|
|
}
|
|
|
|
private $uid = 0;
|
|
|
|
/**
|
|
* 抽奖配置(奖品列表 + 我的金币 + 剩余免费次数)
|
|
*/
|
|
public function config()
|
|
{
|
|
$uid = $this->uid;
|
|
$prizes = WxchatLotteryPrize::where('status', 1)
|
|
->order('sort', 'asc')
|
|
->field('id,name,type,value,probability')
|
|
->select();
|
|
$freeUsed = WxchatLotteryRecord::where('uid', $uid)
|
|
->where('is_free', 1)
|
|
->where('create_at', '>=', strtotime('today'))
|
|
->count();
|
|
$this->success([
|
|
'coins' => WalletService::getCoins($uid),
|
|
'cost' => $this->cost,
|
|
'free_daily' => $this->freeDaily,
|
|
'free_left' => max(0, $this->freeDaily - $freeUsed),
|
|
'prizes' => $prizes,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 抽奖(金币或免费)
|
|
*/
|
|
public function draw()
|
|
{
|
|
$uid = $this->uid;
|
|
|
|
// 是否使用免费次数
|
|
$freeUsed = WxchatLotteryRecord::where('uid', $uid)
|
|
->where('is_free', 1)
|
|
->where('create_at', '>=', strtotime('today'))
|
|
->count();
|
|
$useFree = Request::post('use_free', 0) && $freeUsed < $this->freeDaily;
|
|
|
|
if (! $useFree) {
|
|
try {
|
|
WalletService::decCoins($uid, $this->cost, '抽奖消耗');
|
|
} catch (\Throwable $e) {
|
|
$this->error($e->getMessage());
|
|
}
|
|
}
|
|
|
|
$prize = $this->pickPrize();
|
|
$record = new WxchatLotteryRecord();
|
|
$record->uid = $uid;
|
|
$record->prize_id = $prize ? $prize->id : 0;
|
|
$record->prize_name = $prize ? $prize->name : '谢谢参与';
|
|
$record->prize_type = $prize ? $prize->type : 3;
|
|
$record->prize_value = $prize ? $prize->value : 0;
|
|
$record->is_free = $useFree ? 1 : 0;
|
|
$record->save();
|
|
|
|
// 金币奖品发放
|
|
if ($prize && $prize->type == 1 && $prize->value > 0) {
|
|
WalletService::incCoins($uid, (int) $prize->value, "抽奖中奖:{$prize->name}");
|
|
}
|
|
|
|
$this->success([
|
|
'prize' => $record->prize_name,
|
|
'prize_type' => $record->prize_type,
|
|
'prize_value'=> $record->prize_value,
|
|
'coins_left' => WalletService::getCoins($uid),
|
|
], '抽奖完成');
|
|
}
|
|
|
|
/**
|
|
* 按概率加权抽取奖品(无命中返回 null)
|
|
*/
|
|
private function pickPrize()
|
|
{
|
|
$prizes = WxchatLotteryPrize::where('status', 1)
|
|
->where('stock', '<>', 0)
|
|
->order('sort', 'asc')
|
|
->select();
|
|
if ($prizes->isEmpty()) {
|
|
return null;
|
|
}
|
|
$rand = mt_rand(1, 10000) / 10000; // 0-1
|
|
$acc = 0.0;
|
|
foreach ($prizes as $p) {
|
|
$acc += (float) $p->probability;
|
|
if ($rand <= $acc) {
|
|
// 扣库存
|
|
if ($p->stock > 0) {
|
|
Db::name('wxchat_lottery_prizes')->where('id', $p->id)->dec('stock')->update(['update_at' => time()]);
|
|
}
|
|
return $p;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
}
|