diff --git a/application/api/controller/Redpacket.php b/application/api/controller/Redpacket.php index d8772f9..b22222e 100644 --- a/application/api/controller/Redpacket.php +++ b/application/api/controller/Redpacket.php @@ -4,6 +4,7 @@ namespace app\api\controller; use app\common\controller\BaseCom; use app\common\service\RedpacketService; +use think\Db; /** * 红包接口 @@ -32,14 +33,13 @@ class Redpacket extends BaseCom public function grab() { $redpacketId = $this->request->post('redpacket_id'); - $password = $this->request->post('password', ''); if (empty($redpacketId)) { return V(0, '红包ID不能为空'); } $service = new RedpacketService(); - $reslut = $service->grabWithResult($redpacketId, $this->uid, $password); + $reslut = $service->grabWithResult($redpacketId, $this->uid); return V($reslut['code'], $reslut['msg'], $reslut['data']); } @@ -49,21 +49,20 @@ class Redpacket extends BaseCom */ public function grabResult() { - $user = $this->auth->getUser(); $redpacketId = $this->request->get('redpacket_id'); if (empty($redpacketId)) { - $this->error('红包ID不能为空'); + return V(0, '红包ID不能为空'); } $service = new RedpacketService(); - $result = $service->getGrabResult($redpacketId, $user->id); + $result = $service->getGrabResult($redpacketId, $this->uid); if (!$result) { - $this->error('红包不存在'); + return V(0, '红包不存在'); } - $this->success('获取成功', $result); + return V(1, '获取成功', $result); } /** @@ -72,25 +71,19 @@ class Redpacket extends BaseCom public function detail() { $redpacketId = $this->request->get('redpacket_id'); - $currentUserId = $this->auth->isLogin() ? $this->auth->id : 0; if (empty($redpacketId)) { - $this->error('红包ID不能为空'); + return V(0, '红包ID不能为空'); } - try { - $service = new RedpacketService(); - $detail = $service->getDetail($redpacketId, $currentUserId); + $service = new RedpacketService(); + $detail = $service->getDetail($redpacketId, $this->uid); - if (!$detail) { - $this->error('红包不存在'); - } - - $this->success('获取成功', $detail); - - } catch (\Exception $e) { - $this->error($e->getMessage()); + if (!$detail) { + return V(0, '红包不存在'); } + + return V(1, '获取成功', $detail); } /** @@ -101,4 +94,12 @@ class Redpacket extends BaseCom $options = \app\common\model\Redpacket::$countdownOptions; $this->success('获取成功', $options); } + + // 获取房间内红包列表 + public function roomRedPackets() + { + $roomId = $this->request->get('room_id'); + $result = Db::name('redpacket')->where(['room_id' => $roomId, 'status' => ['<=',1]])->select(); + return V(1, '获取成功', $result); + } } \ No newline at end of file diff --git a/application/api/model/Chat.php b/application/api/model/Chat.php index 6830fab..7ee1a97 100644 --- a/application/api/model/Chat.php +++ b/application/api/model/Chat.php @@ -119,6 +119,8 @@ class Chat extends Model //清空个人魅力 // ClearUserCharm = 1059, + //发红包 + // RedPacket = 1060, diff --git a/application/api/model/UserWallet.php b/application/api/model/UserWallet.php index 1daefbd..7b4729b 100644 --- a/application/api/model/UserWallet.php +++ b/application/api/model/UserWallet.php @@ -50,18 +50,18 @@ class UserWallet extends Model // 1.系统调节 2.充值 3.提现 4.金币转增(送出) 5.每日任务奖励 6.充值返利 7.购买装扮 // 8.礼盒奖励 9.房间补贴 10.购买礼物 11.收礼增加收益 12.工会补贴 13.转赠金币(接收) 14.收益兑换 // 15.首充 16.天降好礼充值 17.退出工会扣款 18.房主收益 19.主持人收益,20.发布头条扣除余额,21.公会长收益,22.提现驳回或提现失败返还,23.财富等级奖励金币领取,24.删除关系扣金币 - //27.小时榜获得 + //27.小时榜获得,28-新人充值好礼,32-发红包(金币),29-发红包(钻石),30-抢红包(金币),31-抢红包(钻石) if($gift_type == 1){ //1金币,2收益(钻石) if($in_out_type == 1){//1收入 - $in_out_types = [2,5,6,8,13,14,15,16,22,23,26,27]; + $in_out_types = [2,5,6,8,13,14,15,16,22,23,26,27,30,28]; }elseif($in_out_type == 2){//2支出 - $in_out_types = [4,7,10,17,20,24,25]; + $in_out_types = [4,7,10,17,20,24,25,32]; } }elseif($gift_type == 2){ //1金币,2收益(钻石) if($in_out_type == 1){//1收入 - $in_out_types = [6,9,11,12,18,19,21,22]; + $in_out_types = [6,9,11,12,18,19,21,22,31,28]; }elseif($in_out_type == 2){//2支出 - $in_out_types = [3,14]; + $in_out_types = [3,14,29]; } } diff --git a/application/common/library/RedpacketLua.php b/application/common/library/RedpacketLua.php index 1ec11be..c3c02ac 100644 --- a/application/common/library/RedpacketLua.php +++ b/application/common/library/RedpacketLua.php @@ -46,14 +46,14 @@ if status == 0 then end end -if status ~= 1 then - return {0, "红包已结束"} -end +-- if status ~= 1 then + -- return {0, "红包已结束"} +-- end -if currentTime > endTime then - redis.call('HSET', redpacketKey, 'status', 2) - return {0, "红包已结束"} -end +-- if currentTime > endTime then +-- redis.call('HSET', redpacketKey, 'status', 2) +-- return {0, "红包已结束"} +-- end -- 检查是否已经抢过 local hasGrabbed = redis.call('SISMEMBER', userSetKey, userId) @@ -77,7 +77,7 @@ if leftCount == 1 then else -- 随机算法:二倍均值法,保证公平性 local maxAmount = leftAmount / leftCount * 2 - amount = math.random(1, math.floor(maxAmount * 100)) / 100 + amount = math.random(1, math.floor(maxAmount)) -- 确保金额不会超过剩余金额 if amount > leftAmount then amount = leftAmount diff --git a/application/common/model/Redpacket.php b/application/common/model/Redpacket.php index e061387..32e4543 100644 --- a/application/common/model/Redpacket.php +++ b/application/common/model/Redpacket.php @@ -44,6 +44,7 @@ class Redpacket extends Model */ public function createRedpacket($data) { +// var_dump($data);exit; Db::startTrans(); try { // 验证用户余额 @@ -51,15 +52,31 @@ class Redpacket extends Model $coinField = $data['coin_type'] == self::COIN_GOLD ? 'coin' : 'earnings'; if ($wallet[$coinField] < $data['total_amount']) { - return V(0, '余额不足'); + return ['code' => 0, 'msg' => '余额不足', 'data' => null]; } // 扣除余额 - Db::name('user_wallet') + $delres = Db::name('user_wallet') ->where('user_id', $data['user_id']) ->dec($coinField, $data['total_amount']) ->update(); + //记录日志 32-发红包(金币),29-发红包(钻石),30-抢红包(金币),31-抢红包(钻石) + //记录用户金币日志 + $data_log = [ + 'user_id' => $data['user_id'], + 'change_value' => $data['total_amount'], + 'room_id' => $data['room_id'], + 'money_type' => $data['coin_type'], + 'change_type' => $data['coin_type'] == self::COIN_GOLD ? 32 : 29, + 'from_id' => $data['room_id'], + 'remarks' => $data['coin_type'] == self::COIN_GOLD ? '金币(发红包)' : '钻石(发红包)', + 'createtime' => time() + ]; + $res = Db::name('vs_user_money_log')->insert($data_log); + if(!$res || !$delres){ + Db::rollback(); + } // 计算开始时间 $startTime = $data['countdown'] > 0 ? (time() + $data['countdown']) : time(); $endTime = $startTime + 120; // 2分钟后结束 @@ -100,15 +117,21 @@ class Redpacket extends Model // 设置过期时间 $redis->expireAt($redisKey, $endTime + 3600); // 结束后保留1小时 - Db::commit(); -// return $redpacketId; - return V(1, '发红包成功', $redpacketId); + + //给前端推送信息 + $data['nickname'] = Db::name('user')->where('id', $data['user_id'])->value('nickname'); + $text = [ + 'redpacketInfo' => $data, + 'text' => '' + ]; + model('api/Chat')->sendMsg(1060,$data['room_id'],$text); + + return ['code' => 1, 'msg' => '发红包成功', 'data' => $redpacketId]; } catch (\Exception $e) { Db::rollback(); - return V(0, $e); -// throw $e; + return ['code' => 0, 'msg' => $e->getMessage(), 'data' => null]; } } diff --git a/application/common/model/UserWallet.php b/application/common/model/UserWallet.php index df565cd..102dbc2 100644 --- a/application/common/model/UserWallet.php +++ b/application/common/model/UserWallet.php @@ -78,6 +78,14 @@ class UserWallet extends Model //新人充值好礼 const NEW_USER_CHARGE_GIFT = 28; + //发红包(金币) + const RED_PACKET_COIN = 32; + //发红包(钻石) + const RED_PACKET_DIAMOND = 29; + //抢红包(金币) + const RED_PACKET_COIN_RECEIVE = 30; + //抢红包(钻石) + const RED_PACKET_DIAMOND_RECEIVE = 31; //金币支出类型数组 public $coin_consumption_type_array = [ @@ -86,12 +94,14 @@ class UserWallet extends Model self::OPERATION_GIFT, self::GUILD_EXIT, self::HEADLINE_REWARD, - self::TRANSFER_COIN + self::TRANSFER_COIN, + self::RED_PACKET_COIN, ]; //钻石支出类型数组 public $diamond_consumption_type_array = [ self::OPERATION_WITHDRAW, - self::MONEY_CONVERSION + self::MONEY_CONVERSION, + self::RED_PACKET_DIAMOND ]; @@ -141,7 +151,11 @@ class UserWallet extends Model self::TRANSFER_COIN => '赠送好友金币', self::RECEIVE_COIN => '好友转赠所得金币', self::HOUR_RANK_COIN => '小时榜获得金币', - self::NEW_USER_CHARGE_GIFT => '新人充值好礼' + self::NEW_USER_CHARGE_GIFT => '新人充值好礼', + self::RED_PACKET_COIN => '发红包(金币)', + self::RED_PACKET_DIAMOND => '发红包(钻石)', + self::RED_PACKET_COIN_RECEIVE => '抢红包(金币)', + self::RED_PACKET_DIAMOND_RECEIVE => '抢红包(钻石)', ]; return $status[$type] ?? ''; } diff --git a/application/common/service/RedpacketService.php b/application/common/service/RedpacketService.php index 088ba66..69e95ca 100644 --- a/application/common/service/RedpacketService.php +++ b/application/common/service/RedpacketService.php @@ -30,7 +30,7 @@ class RedpacketService /** * 抢红包并返回详细结果 */ - public function grabWithResult($redpacketId, $userId, $password = '') + public function grabWithResult($redpacketId, $userId) { $redpacketModel = new Redpacket(); $redpacket = $redpacketModel->getRedpacketInfo($redpacketId); @@ -43,17 +43,6 @@ class RedpacketService ]; } - // 验证口令红包 - if ($redpacket['type'] == Redpacket::TYPE_PASSWORD) { - if (empty($password) || $password != $redpacket['password']) { - return [ - 'code' => 0, - 'msg' => '口令错误', - 'data' => null - ]; - } - } - // 验证领取条件 $conditionCheck = $this->checkConditionsWithResult($redpacket, $userId); if ($conditionCheck['code'] != 1) { @@ -129,7 +118,8 @@ class RedpacketService 'change_value' => $amount, 'room_id' => $redpacket['room_id'], 'money_type' => $redpacket['coin_type'], - 'change_type' => 66,//抢红包收入 + //记录日志 32-发红包(金币),29-发红包(钻石),30-抢红包(金币),31-抢红包(钻石) + 'change_type' => $redpacket['coin_type'] == 1 ? 30 : 31, 'from_id' => $redpacket['room_id'], 'remarks' => '抢红包收入', 'createtime' => time() @@ -153,9 +143,8 @@ class RedpacketService $grabResult = $this->getGrabResult($redpacketId, $userId); return [ - 'success' => true, - 'code' => 'grab_success', - 'message' => '抢红包成功', + 'code' => 1, + 'msg' => '抢红包成功', 'data' => $grabResult ]; @@ -167,9 +156,9 @@ class RedpacketService $redis->sRem($userSetKey, $userId); return [ - 'success' => false, - 'code' => 'system_error', - 'message' => '系统错误,请重试' + 'code' => 0, + 'msg' => '系统错误,请重试', + 'data' => null ]; } } @@ -243,7 +232,8 @@ class RedpacketService 'left_amount' => $redpacket['left_amount'], 'left_count' => $redpacket['left_count'], 'coin_type' => $redpacket['coin_type'], - 'status' => $redpacket['status'] + 'status' => $redpacket['status'], + 'nickname' => Db::name('user')->where('id', $redpacket['user_id'])->value('nickname') ], 'my_record' => $myRecord ? [ 'amount' => $myRecord['amount'], @@ -357,85 +347,6 @@ class RedpacketService return ['code' => 1]; } - /** - * 抢红包 - */ -// public function grab($redpacketId, $userId, $password = '') -// { -// $redpacketModel = new Redpacket(); -// $redpacket = $redpacketModel->getRedpacketInfo($redpacketId); -// -// if (!$redpacket) { -// throw new \Exception('红包不存在'); -// } -// -// // 验证口令红包 -// if ($redpacket['type'] == Redpacket::TYPE_PASSWORD) { -// if (empty($password) || $password != $redpacket['password']) { -// throw new \Exception('口令错误'); -// } -// } -// -// // 验证领取条件 -// $this->checkConditions($redpacket, $userId); -// -// // 使用Redis+Lua保证原子性操作 -// $redis = Cache::store('redis')->handler(); -// $script = RedpacketLua::grabRedpacketScript(); -// -// $redpacketKey = "redpacket:{$redpacketId}"; -// $userSetKey = "redpacket_users:{$redpacketId}"; -// -// $result = $redis->eval($script, [ -// $redpacketKey, -// $userSetKey, -// $userId, -// time() -// ], 3); -// -// if ($result[0] == 0) { -// throw new \Exception($result[1]); -// } -// -// $amount = floatval($result[1]); -// -// // Lua脚本执行成功,记录到数据库 -// Db::startTrans(); -// try { -// // 创建领取记录 -// $recordData = [ -// 'redpacket_id' => $redpacketId, -// 'user_id' => $userId, -// 'amount' => $amount -// ]; -// -// $recordModel = new RedpacketRecord(); -// $recordModel->save($recordData); -// -// // 更新用户钱包 -// $walletModel = new UserWallet(); -// $walletModel->increaseBalance($userId, $redpacket['coin_type'], $amount); -// -// // 更新红包剩余数量和金额 -// Db::name('redpacket') -// ->where('id', $redpacketId) -// ->dec('left_amount', $amount) -// ->dec('left_count', 1) -// ->update(); -// -// Db::commit(); -// -// return $amount; -// -// } catch (\Exception $e) { -// Db::rollback(); -// // 回滚Redis操作 -// $redis->hIncrByFloat($redpacketKey, 'left_amount', $amount); -// $redis->hIncrBy($redpacketKey, 'left_count', 1); -// $redis->sRem($userSetKey, $userId); -// throw $e; -// } -// } /** * 获取红包详情和领取记录 @@ -528,45 +439,49 @@ class RedpacketService } } + + /** * 验证创建红包数据 */ private function validateCreateData($data) { if (empty($data['user_id'])) { - return V(0, '用户ID不能为空'); + return ['code' => 0, 'msg' => '用户ID不能为空', 'data' => null]; } if (!in_array($data['type'], [Redpacket::TYPE_NORMAL, Redpacket::TYPE_PASSWORD])) { - return V(0, '红包类型错误'); + return ['code' => 0, 'msg' => '红包类型错误', 'data' => null]; } if ($data['type'] == Redpacket::TYPE_PASSWORD && empty($data['password'])) { - return V(0, '口令红包必须设置口令'); + return ['code' => 0, 'msg' => '口令红包必须设置口令', 'data' => null]; } if (!in_array($data['coin_type'], [Redpacket::COIN_GOLD, Redpacket::COIN_DIAMOND])) { - return V(0, '币种类型错误'); + return ['code' => 0, 'msg' => '币种类型错误', 'data' => null]; } if ($data['total_amount'] <= 0 || $data['total_count'] <= 0) { - return V(0, '金额和数量必须大于0'); + return ['code' => 0, 'msg' => '金额和数量必须大于0', 'data' => null]; } if ($data['total_amount'] < $data['total_count']) { - return V(0, '总金额不能小于总个数'); + return ['code' => 0, 'msg' => '总金额不能小于总个数', 'data' => null]; } // 验证领取条件 if (isset($data['conditions'])) { - $res_con = $this->validateConditions($data['conditions']); + $res_con = $this->validateConditions($data['conditions']); if ($res_con !== true) { return $res_con; } } - return true; + + return ['code' => 1, 'msg' => '验证成功', 'data' => null]; } + /** * 验证领取条件 */