likeshop/server/application/api/logic/LuckdrawLogic.php
2025-07-27 21:42:34 +08:00

453 lines
14 KiB
PHP
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.

<?php
namespace app\api\logic;
use app\api\model\Coupon;
use app\common\logic\AccountLogLogic;
use app\common\model\AccountLog;
use app\common\model\Luckdraw;
use app\common\model\LuckdrawRecord;
use app\common\model\User;
use app\common\server\ConfigServer;
use app\common\server\UrlServer;
use think\Db;
use think\helper\Time;
class LuckdrawLogic
{
protected static $error; //错误信息
/**
* Notes: 错误错误信息
* @author 张无忌(2021/1/12 16:01)
* @return mixed
*/
public static function getError()
{
return self::$error;
}
/**
* Notes: 获取抽奖的奖品
* @author 张无忌(2021/1/26 15:12)
* @param $user_id
* @return array
*/
public static function getPrize($user_id)
{
$where = [
['is_delete', '=', 0],
['status', '=', 1]
];
// 获取配置信息
$config = [
'need' => ConfigServer::get('luckdraw', 'need', 0),
'limit' => ConfigServer::get('luckdraw', 'limit', 0),
'status' => ConfigServer::get('luckdraw', 'status', ''),
'rule' => ConfigServer::get('luckdraw', 'rule', 0),
'show_win' => ConfigServer::get('luckdraw', 'show_win', 0)
];
// 计算用户剩余抽奖次数
list($startDay, $endDay) = Time::today();
$recordCount = LuckdrawRecord::where([
['user_id', '=', $user_id],
['create_time', '>=', $startDay],
['create_time', '<', $endDay]
])->count('id');
$surplus = $config['limit'] - $recordCount;
$surplus = $surplus <= 0 ? 0 : $surplus;
// 获取历史抽奖记录列表
$record = LuckdrawRecord::order('id', 'desc')
->where('prize_type', '<>', Luckdraw::PRIZE_NOT_WIN)
->with('user')
->append(['prize_name'])
->limit(20)->select();
$recordData = [];
foreach ($record as $item) {
$nickname = self::hideStar($item['user']['nickname']);
$recordData[] = [
'id' => $item['id'],
'text' => '恭喜'.$nickname.'抽中了'.Luckdraw::getPrizeNameDesc($item['prize_type'], $item['number']),
'create_time' => $item['create_time'],
];
}
$model = new Luckdraw();
$lists = $model->field('id,prize_type,name,image,number')
->order(['sort'=>'desc'])
->where($where)->limit(8)
->select();
foreach ($lists as &$item) {
$item['url'] = $item['image'] ? UrlServer::getFileUrl($item['image']) : '';
if ($item['prize_type'] == 1) {
$item['name'] = $item['number'].$item['name'];
}
unset($item['image']);
unset($item['prize_type']);
}
$prizeData = [];
for ($i=0; $i<8; $i++) {
if (!empty($lists[$i])) {
if ($i == 4) {
$prizeData[] = ['name' => self::getPrizeBtn($config['need'])];
}
$prizeData[] = $lists[$i];
} else {
$prizeData[] = json_decode("{}");
}
}
$user = User::findOrEmpty($user_id);
return [
'user_integral' => $user['user_integral'],
'config' => $config,
'surplus' => $surplus,
'record' => $recordData,
'list' => $prizeData
];
}
/**
* Notes: 获取用户抽奖记录
* @param $user_id
* @param $page
* @param $size
* @author 张无忌(2021/1/26 16:13)
* @return array
*/
public static function getUserRecord($user_id, $page, $size)
{
$count = LuckdrawRecord::where(['user_id'=>(int)$user_id])->count();
$record = LuckdrawRecord::order('id', 'desc')
->where(['user_id'=>(int)$user_id])
->order('id', 'desc')
->page($page, $size)
->select();
foreach ($record as &$item) {
$item['prize_image'] = $item['prize_image'] ? UrlServer::getFileUrl($item['prize_image']) : '';
$item['send_tips'] = !$item['is_send'] && $item['prize_type'] != Luckdraw::PRIZE_NOT_WIN ? '自动领取失败,请联系客服人员' : '';
$item['need_tips'] = !empty($item['need_integral']) ? '-'.$item['need_integral'].'积分': '';
}
return [
'list' => $record,
'count' => $count,
'page_no' => $page,
'page_size' => $size,
'more' => is_more($count, $page, $size)
];
}
/**
* Notes: 抽奖逻辑开始
* @author 张无忌(2021/1/26 17:00)
* @param $user_id
* @return array|bool
*/
public static function draw($user_id)
{
Db::startTrans();
try {
// 每次抽奖需要消耗积分
$need = ConfigServer::get('luckdraw', 'need', 0);
// 扣减积分
if ($need > 0) {
User::where(['id' => $user_id])->setDec('user_integral', $need);
AccountLogLogic::AccountRecord(
$user_id, $need, 2,
AccountLog::luck_draw_dec_integral,
AccountLog::getAcccountDesc(AccountLog::luck_draw_dec_integral)
);
}
// 中奖奖品
$inPrize = self::randomLottery();
// 分析奖品类型,如(积分,优惠券,余额等),给用户增加对应获得的奖品
$sendPrizeInfo = self::sendPrize($inPrize, $user_id);
// 记录获得奖品信息
LuckdrawRecord::create([
'user_id' => $user_id,
'prize_id' => $inPrize['id'],
'prize_type' => $inPrize['prize_type'],
'prize_name' => $inPrize['name'],
'prize_image' => $inPrize['image'],
'number' => $inPrize['number'],
'is_send' => $sendPrizeInfo['flag'] ? 1 : 0,
'remark' => $sendPrizeInfo['tips'] ?? '',
'need_integral' => $need,
'create_time' => time(),
]);
Db::commit();
$text = '恭喜您获得' . Luckdraw::getPrizeNameDesc($inPrize['prize_type'], $inPrize['number']);
// 返回抽奖结果
return [
'id' => $inPrize['id'],
'name' => $inPrize['name'],
'image' => UrlServer::getFileUrl($inPrize['image']),
'number' => $inPrize['number'],
'text' => $text,
'create_time' => date('Y-m-d H:i:s', time()),
'error' => $sendPrizeInfo['flag'] ? '' : '自动领取失败,请联系客服'
];
} catch (\Exception $e) {
Db::rollback();
static::$error = $e->getMessage();
return false;
}
}
/**
* Notes: 取出中奖的奖品
* @param $prize_arr
* @author 张无忌(2021/1/26 18:37)
* @return int|mixed
*/
public static function getPrizeRange($prize_arr)
{
$rid = 0; //中奖的产品ID
$weight = 0; //中奖几率 (所有商品累计)
foreach ($prize_arr as $val) {
$weight += $val['probability']; //概率数组的总概率精度
}
shuffle($prize_arr);
foreach ($prize_arr as $key => $value) {
$randNum = mt_rand(1, $weight);
if ($randNum <= $value['probability']) { // 1 2 3 200
$rid = $value['id'];
break;
} else {
$weight -= $value['probability'];
}
}
return $rid; //中奖项
}
// 截取字符串
private static function hideStar($str)
{
if (mb_strlen($str) >= 3) {
return '**' . mb_substr($str, 2);
}
if (mb_strlen($str) == 1) {
return '**' . $str;
}
if (mb_strlen($str) == 2) {
return '**' . mb_substr($str, 1);
}
return $str;
}
/**
* @notes 随机抽奖
* @return array|mixed
* @author 段誉
* @date 2022/2/15 18:11
*/
public static function randomLottery()
{
// 获取正在进行抽奖的商品 (倒叙获取 8个 与api接口保持一致)
$model = new Luckdraw();
$prize = $model->field('id,prize_type,name,image,number,probability')
->order(['sort'=>'desc'])
->where(['is_delete'=>0, 'status'=>1])->limit(8)
->select()->toArray();
// 获得中奖ID
$rid = self::getPrizeRange($prize);
// 根据ID获得中奖信息
$inPrize = [];
foreach ($prize as $item) {
if ($item['id'] == $rid) {
$inPrize = $item;
break;
}
}
return $inPrize;
}
/**
* @notes 发送奖品
* @param $inPrize
* @param $user_id
* @return array
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @author 段誉
* @date 2022/2/15 17:45
*/
public static function sendPrize($inPrize, $user_id)
{
$flag = true;
$tips = '发奖成功';
// 中奖积分
if ($inPrize['prize_type'] == Luckdraw::PRIZE_INTEGRAL) {
User::where(['id' => $user_id])->setInc('user_integral', $inPrize['number']);
AccountLogLogic::AccountRecord(
$user_id, $inPrize['number'], 1,
AccountLog::luck_draw_integral,
AccountLog::getAcccountDesc(AccountLog::luck_draw_integral)
);
}
// 中奖余额
if ($inPrize['prize_type'] == Luckdraw::PRIZE_BALANCE) {
User::where(['id' => $user_id])->setInc('user_money', $inPrize['number']);
AccountLogLogic::AccountRecord(
$user_id, $inPrize['number'], 1,
AccountLog::luck_draw_inc_balance,
AccountLog::getAcccountDesc(AccountLog::luck_draw_inc_balance)
);
}
// 中奖优惠券
if ($inPrize['prize_type'] == Luckdraw::PRIZE_COUPON) {
$coupon = Coupon::findOrEmpty($inPrize['number'])->toArray();
$res = self::sendCoupon($user_id, $coupon);
if (true !== $res) {
$flag = false;
$tips = $res;
}
}
return ['flag' => $flag, 'tips' => $tips];
}
/**
* @notes 发送优惠券奖品
* @param $user_id
* @param $coupon
* @return bool|string
* @author 段誉
* @date 2022/2/15 17:45
*/
public static function sendCoupon($user_id, $coupon)
{
if ($coupon['status'] == 0) {
return '优惠券已失效,不能发放';
}
// send_total_type 发送总量类型1-不限制2-限制张数
if ($coupon['send_total_type'] == 2) {
if ($coupon['send_total'] < 1) {
return '优惠券发放总数量,超出库存数量,不能发放';
} else {
Coupon::update(['send_total' => ['dec', 1]], ['id' => $coupon['id']]);
}
}
// 指定用户发放
Db::name('coupon_list')->insert([
'user_id' => $user_id,
'coupon_id' => $coupon['id'],
'status' => 0,
'coupon_code' => create_coupon_code(),
'create_time' => time(),
]);
return true;
}
/**
* @notes 抽奖按钮
* @param $need_integral
* @return string
* @author 段誉
* @date 2022/2/15 18:47
*/
public static function getPrizeBtn($need_integral)
{
$btn = '开始抽奖';
if ($need_integral > 0) {
$btn = '消耗' . $need_integral . '积分';
}
return $btn;
}
/**
* @notes 中奖列表
* @param $params
* @param $page
* @param $size
* @return array
* @author 段誉
* @date 2022/2/17 15:23
*/
public static function getWinList($page, $size)
{
$where = [
['prize_type', '<>', Luckdraw::PRIZE_NOT_WIN],
];
$count = LuckdrawRecord::where($where)->count();
$lists = LuckdrawRecord::where($where)
->order('id', 'desc')
->page($page, $size)
->select()
->toArray();
foreach ($lists as &$item) {
$item['title'] = self::formatTitleWin($item);
$item['prize_image'] = !empty($item['prize_image']) ? UrlServer::getFileUrl($item['prize_image']) : '';
}
$data = [
'list' => $lists,
'count' => $count,
'page_no' => $page,
'page_size' => $size,
'more' => is_more($count, $page, $size)
];
return $data;
}
/**
* @notes 格式化中奖名单标题
* @param $item
* @return string
* @author 段誉
* @date 2022/2/17 15:23
*/
private static function formatTitleWin($item)
{
$title = "恭喜";
$userName = User::where('id', $item['user_id'])->value('nickname');
// 隐私处理
$userName = '**' . mb_substr($userName, -1 , 1);
$title .= $userName . '抽中了';
if ($item['prize_type'] == Luckdraw::PRIZE_INTEGRAL) {
$title .= $item['number'] . '积分';
}
if ($item['prize_type'] == Luckdraw::PRIZE_COUPON) {
$couponName = Coupon::where('id', $item['number'])->value('name');
$title .= empty($couponName) ? '优惠券' : $couponName;
}
if ($item['prize_type'] == Luckdraw::PRIZE_BALANCE) {
$title .= $item['number'] . '元';
}
return $title;
}
}