diff --git a/app/admin/controller/Goods.php b/app/admin/controller/Goods.php index f1ba70d..0527789 100755 --- a/app/admin/controller/Goods.php +++ b/app/admin/controller/Goods.php @@ -13,6 +13,8 @@ use app\common\model\AdminGoodsLog; use think\facade\Db; use app\common\model\Shang; use app\common\model\Reward; +use app\common\model\GoodsExtend; + class Goods extends Base { /** @@ -54,7 +56,7 @@ class Goods extends Base // 获取盒子ID集合 $goodsIds = array_column($list, 'id'); - + // 获取盒子扩展信息 $goodsExtendList = []; if (!empty($goodsIds)) { @@ -72,12 +74,12 @@ class Goods extends Base } // 添加格式化时间 $item['addtime_text'] = date('Y-m-d H:i', $item['addtime']); - + // 添加扩展信息 $item['goods_extend'] = isset($goodsExtendList[$item['id']]) ? $goodsExtendList[$item['id']] : null; - + // 修改时间处理 - if(isset($item['update_time']) && $item['update_time']){ + if (isset($item['update_time']) && $item['update_time']) { $item['update_time_text'] = date('Y-m-d H:i', $item['update_time']); } } @@ -410,7 +412,7 @@ class Goods extends Base } $data['prize_num'] = 0; $data['category_id'] = 0; - } elseif ($type == 2 || $type == 16 || $type == 17) { + } elseif ($type == 2 || $type == 16 || $type == 17) { $data['stock'] = 0; $data['lock_is'] = 0; $data['lock_time'] = 0; @@ -732,10 +734,10 @@ class Goods extends Base } if ($info['type'] == 1 || $info['type'] == 5 || $info['type'] == 10 || $info['type'] == 11 || $info['type'] == 6) { $shang = Shang::where('id', '<=', 33)->where('id', '<>', 5)->select()->toArray(); - if( $goods_list_id){ + if ($goods_list_id) { $shang = Shang::where('id', '<=', 33)->where('id', '>', 5)->select()->toArray(); } - } elseif ($info['type'] == 2 || $info['type'] == 8 || $info['type'] == 9 || $info['type'] == 16 || $info['type'] == 17 ) { + } elseif ($info['type'] == 2 || $info['type'] == 8 || $info['type'] == 9 || $info['type'] == 16 || $info['type'] == 17) { $shang = Shang::where('id', 'between', [34, 38])->select()->toArray(); } elseif ($info['type'] == 3) { $shang = Shang::where('id', 'between', [4, 33])->select()->toArray(); @@ -857,9 +859,8 @@ class Goods extends Base $prize_code = getPrizeCode() . '_' . time(); $data['prize_code'] = $prize_code; $data['surplus_stock'] = $data['stock']; - - } - else { + + } else { return $this->err('请求参数错误'); } if (RegZero($data['sort'])) { @@ -910,10 +911,10 @@ class Goods extends Base } if ($info['type'] == 1 || $info['type'] == 5 || $info['type'] == 6 || $info['type'] == 10 | $info['type'] == 11) { $shang = Shang::where('id', '<=', 33)->where('id', '<>', 5)->select()->toArray(); - if( $goods_list_id){ + if ($goods_list_id) { $shang = Shang::where('id', '<=', 33)->where('id', '>', 5)->select()->toArray(); } - } elseif ($info['type'] == 2 || $info['type'] == 8 || $info['type'] == 9 || $info['type'] == 16 || $info['type'] == 17 ) { + } elseif ($info['type'] == 2 || $info['type'] == 8 || $info['type'] == 9 || $info['type'] == 16 || $info['type'] == 17) { $shang = Shang::where('id', 'between', [34, 38])->select()->toArray(); } elseif ($info['type'] == 15) { $shang = Shang::where('id', '>=', 114)->select()->toArray(); @@ -1396,9 +1397,9 @@ class Goods extends Base ->where($whe) ->order('id desc') ->paginate([ - 'list_rows' => $this->page, - 'query' => request()->param(), - ]); + 'list_rows' => $this->page, + 'query' => request()->param(), + ]); // 获取所有相关的盒子信息 $goodsIds = array_column($list->items(), 'goods_id'); @@ -1436,71 +1437,108 @@ class Goods extends Base /** * 同步盒子数据 */ - public function sync_goods() + public function sync_goods(Request $request) { - $goods_id = $this->request->post('goods_id/d', 0); - $targets = $this->request->post('targets/a', []); - - if (empty($goods_id)) { - return $this->renderError('盒子ID不能为空'); + if (!$request->isPost()) { + return $this->renderError('请求方式错误'); } - if (empty($targets)) { - return $this->renderError('同步目标不能为空'); + $id = $request->post('id/d'); + $url = $request->post('url/s'); + + // 验证URL格式 + if (!filter_var($url, FILTER_VALIDATE_URL)) { + return $this->renderError('URL格式不正确'); } - # 获取盒子数据 - $goods = \app\common\model\Goods::find($goods_id); + // 确保URL以/结尾 + if (substr($url, -1) !== '/') { + $url .= '/'; + } + + $url .= 'api/goods/receive_sync'; + + // 获取盒子数据 + $goods = GoodsModel::where(['id' => $id])->find(); if (!$goods) { return $this->renderError('盒子不存在'); } - # 检查是否有async_code,没有则生成 - if (empty($goods['async_code'])) { - $async_code = $this->generateUUID(); - $goods->async_code = $async_code; - $goods->async_date = date('Y-m-d H:i:s'); - $goods->save(); - } else { - $async_code = $goods['async_code']; + // 生成或获取同步代码 + $async_code = $goods['async_code']; + if (empty($async_code)) { + $async_code = 'MHHZ' . date('YmdHis') . mt_rand(1000, 9999); + $goods->save(['async_code' => $async_code]); } - # 获取盒子奖品数据 - $goodsList = \app\common\model\GoodsList::where('goods_id', $goods_id)->select()->toArray(); - - # 准备同步数据 - $syncData = [ - 'goods' => $goods->toArray(), - 'goodsList' => $goodsList, - 'async_code' => $async_code, - 'sync_time' => time() - ]; - - # 发送到所有目标 - $successCount = 0; - $failCount = 0; - $errorMessages = []; - - foreach ($targets as $target) { - $result = $this->sendSyncData($target, $syncData); - if ($result['success']) { - $successCount++; - } else { - $failCount++; - $errorMessages[] = $target . ': ' . $result['message']; + // 获取盒子奖品数据 + $goodsLists = GoodsList::where(['goods_id' => $id])->select()->toArray(); + + // 获取盒子扩展配置 + $goodsExtend = GoodsExtend::where(['goods_id' => $id])->find(); + + // 收集所有奖励ID + $rewardIds = []; + foreach ($goodsLists as $item) { + if (!empty($item['reward_id'])) { + $rewardIds[] = $item['reward_id']; } } + + // 获取奖励数据 + $rewards = []; + if (!empty($rewardIds)) { + $rewards = Db::name('reward')->whereIn('reward_id', $rewardIds)->select()->toArray(); + } - # 更新同步状态 - $goods->async_date = date('Y-m-d H:i:s'); - $goods->save(); + // 准备发送的数据 + $postData = [ + 'goods' => $goods->toArray(), + 'goodsList' => $goodsLists, + 'async_code' => $async_code, + 'rewards' => $rewards + ]; + + if ($goodsExtend) { + $postData['goodsExtend'] = $goodsExtend->toArray(); + } - if ($failCount == 0) { - return $this->renderSuccess("同步成功,已成功同步到 {$successCount} 个目标"); - } else if ($successCount > 0) { - return $this->renderSuccess("部分同步成功:{$successCount} 个成功,{$failCount} 个失败。\n失败信息:" . implode("\n", $errorMessages)); - } else { - return $this->renderError("同步失败:" . implode("\n", $errorMessages)); + // 发送同步请求 + try { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData)); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Content-Type: application/json', + 'Content-Length: ' . strlen(json_encode($postData)) + ]); + + $response = curl_exec($ch); + $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + if ($status !== 200) { + return $this->renderError('同步失败,服务器返回状态码: ' . $status); + } + + $responseData = json_decode($response, true); + if (!$responseData || $responseData['code'] !== 1) { + $errorMsg = isset($responseData['msg']) ? $responseData['msg'] : '服务器未返回预期响应'; + return $this->renderError('同步失败: ' . $errorMsg); + } + + // 更新同步状态 + $goods->save([ + 'sync_status' => 1, + 'sync_url' => $url, + 'sync_time' => date('Y-m-d H:i:s') + ]); + + return $this->renderSuccess('同步成功'); + } catch (\Exception $e) { + return $this->renderError('同步失败: ' . $e->getMessage()); } } @@ -1571,17 +1609,33 @@ class Goods extends Base $newGoods->save($goodsData); $newGoodsId = $newGoods->id; + // 复制盒子扩展配置 + $goodsExtend = GoodsExtend::where('goods_id', $id)->find(); + if ($goodsExtend) { + $extendData = $goodsExtend->toArray(); + unset($extendData['id']); + $extendData['goods_id'] = $newGoodsId; + $newExtend = new GoodsExtend(); + $newExtend->save($extendData); + } + + // 创建ID映射表,用于处理子奖品关联 + $idMapping = []; + // 复制盒子奖品 - $goodsLists = GoodsList::where(['goods_id' => $id])->select(); + $goodsLists = GoodsList::where(['goods_id' => $id, 'goods_list_id' => 0])->select(); foreach ($goodsLists as $item) { $listData = $item->toArray(); + $oldId = $item['id']; // 保存原始ID,用于建立映射 unset($listData['id']); $listData['goods_id'] = $newGoodsId; $listData['addtime'] = time(); $listData['surplus_stock'] = $listData['stock']; + + // 处理奖励ID if ($listData['reward_id'] && $listData['reward_id'] != '') { $reward = Reward::where(['reward_id' => $listData['reward_id']])->select(); - $listData['reward_id'] = 'MHHZ' . date('YmdHis') . mt_rand(1000, 9999);//$this->generateUUID(); + $listData['reward_id'] = 'MHHZ' . date('YmdHis') . mt_rand(1000, 9999); if ($reward) { $rewards = $reward->toArray(); foreach ($rewards as $item2) { @@ -1591,29 +1645,51 @@ class Goods extends Base $item2['update_time'] = time(); Reward::insert($item2); } - } } + // 插入新奖品 $newGoodsList = new GoodsList(); $newGoodsList->save($listData); + + // 记录ID映射关系 + $idMapping[$oldId] = $newGoodsList->id; + } - // 如果有扩展奖品,也进行复制 - if ($goods['type'] == 1 || $goods['type'] == 11) { - $goodsExtends = Db::name('goods_extend_list') - ->where(['goods_list_id' => $item['id']]) - ->select() - ->toArray(); + // 复制子奖品(宝箱类型的子奖品) + $childItems = GoodsList::where(['goods_id' => $id])->where('goods_list_id', '>', 0)->select(); + foreach ($childItems as $childItem) { + $childData = $childItem->toArray(); + $originalParentId = $childData['goods_list_id']; + unset($childData['id']); + $childData['goods_id'] = $newGoodsId; + $childData['addtime'] = time(); + $childData['surplus_stock'] = $childData['stock']; - foreach ($goodsExtends as $extend) { - unset($extend['id']); - $extend['goods_id'] = $newGoodsId; - $extend['goods_list_id'] = $newGoodsList->id; - $extend['addtime'] = time(); + // 更新goods_list_id为新系统中的ID + if (isset($idMapping[$originalParentId])) { + $childData['goods_list_id'] = $idMapping[$originalParentId]; + } - Db::name('goods_extend_list')->insert($extend); + // 处理奖励ID + if ($childData['reward_id'] && $childData['reward_id'] != '') { + $reward = Reward::where(['reward_id' => $childData['reward_id']])->select(); + $childData['reward_id'] = 'MHHZ' . date('YmdHis') . mt_rand(1000, 9999); + if ($reward) { + $rewards = $reward->toArray(); + foreach ($rewards as $item2) { + unset($item2['id']); + $item2['reward_id'] = $childData['reward_id']; + $item2['create_time'] = time(); + $item2['update_time'] = time(); + Reward::insert($item2); + } } } + + // 插入子奖品 + $newChildList = new GoodsList(); + $newChildList->save($childData); } Db::commit(); @@ -1711,7 +1787,7 @@ class Goods extends Base if ($request->isPost()) { $data = $request->post(); - + // 验证参数 $data['goods_id'] = $goods_id; $data['pay_wechat'] = isset($data['pay_wechat']) ? 1 : 0; @@ -1720,10 +1796,10 @@ class Goods extends Base $data['pay_currency2'] = isset($data['pay_currency2']) ? 1 : 0; $data['pay_coupon'] = isset($data['pay_coupon']) ? 1 : 0; $data['is_deduction'] = isset($data['is_deduction']) ? 1 : 0; - + // 查询是否已存在 $exist = \app\common\model\GoodsExtend::getByGoodsId($goods_id); - + Db::startTrans(); try { if ($exist) { @@ -1743,14 +1819,14 @@ class Goods extends Base // 获取扩展设置 $extend = \app\common\model\GoodsExtend::getByGoodsId($goods_id); - + if (!$extend) { // 从goods_type表获取默认值 $goodsType = Db::name('goods_type') ->field('pay_wechat, pay_balance, pay_currency, pay_currency2, pay_coupon, is_deduction') ->where('value', $goods['type']) ->find(); - + if ($goodsType) { // 如果找到了盒子类型的默认配置 $extend = [ @@ -1813,22 +1889,22 @@ class Goods extends Base { $id = $request->post('id/d'); $sort = $request->post('sort/d'); - + if (empty($id)) { return json(['status' => 0, 'msg' => '参数错误']); } - + // 验证排序值 if (!is_numeric($sort) || $sort < 0) { return json(['status' => 0, 'msg' => '排序值必须是非负整数']); } - + // 获取盒子信息 $goods = GoodsModel::where('id', $id)->find(); if (!$goods) { return json(['status' => 0, 'msg' => '盒子不存在']); } - + // 更新排序值 $result = GoodsModel::where('id', $id)->update(['sort' => $sort]); if ($result) { @@ -1845,22 +1921,22 @@ class Goods extends Base { $id = $request->post('id/d'); $sort = $request->post('sort/d'); - + if (empty($id)) { return json(['status' => 0, 'msg' => '参数错误']); } - + // 验证排序值 if (!is_numeric($sort) || $sort < 0) { return json(['status' => 0, 'msg' => '排序值必须是非负整数']); } - + // 获取奖品信息 $goodsList = GoodsList::where('id', $id)->find(); if (!$goodsList) { return json(['status' => 0, 'msg' => '奖品不存在']); } - + // 更新排序值 $result = GoodsList::where('id', $id)->update(['sort' => $sort]); if ($result) { diff --git a/app/api/controller/Goods.php b/app/api/controller/Goods.php index ec730f5..09412a1 100755 --- a/app/api/controller/Goods.php +++ b/app/api/controller/Goods.php @@ -676,255 +676,38 @@ class Goods extends Base if (!$goods) { return $this->renderError("盒子不存在"); } - if ($goods['status'] != 1) { return $this->renderError("盒子已下架"); } - $goods['imgurl_detail'] = imageUrl($goods['imgurl_detail']); - if (RegInt($num)) { - return $this->renderError("箱号选择错误"); + + // 获取服务实例 + $calculator = new \app\common\service\PaymentCalculator(); + + // 验证抽奖限制 + $validationResult = $calculator->validateDrawRestrictions($user, $goods, $prize_num); + if ($validationResult['status'] == 0) { + return $this->renderError($validationResult['msg']); } - # 获取盒子类型配置 - $goods_type = $goods['type']; - $goods_extend = GoodsExtend::getGoodsExtendByGoodsId($goods_id, $goods_type); - if (!$goods_extend) { - return $this->renderError("盒子类型配置不存在"); + + // 计算订单金额 + $result = $calculator->calculateOrderAmount( + $user, + $goods_id, + $prize_num, + $use_money_is, + $use_integral_is, + $use_money2_is, + $coupon_id, + $goods + ); + + if ($result['status'] == 0) { + return $this->renderError($result['msg']); } - if ($goods['quanju_xiangou'] > 0) { - //限购 - $user_toDay_count = OrderList::field('id')->where('goods_id', '=', $goods_id) - ->where('user_id', '=', $user['id']) - ->where('parent_goods_list_id', '=', 0) - ->count(); - //已经达到限购先上限 - if ($goods['quanju_xiangou'] <= $user_toDay_count) { - return $this->renderError('当前限购' . $goods['quanju_xiangou'] . '次'); - } - $now_prize_num = $prize_num + $user_toDay_count; - if ($now_prize_num > $goods['quanju_xiangou']) { - return $this->renderError('购买超出限制,还允许购买' . ($goods['quanju_xiangou'] - $user_toDay_count) . '次'); - } - } - if ($goods['daily_xiangou'] > 0) { - //获取今天凌晨时间 - $todayMidnight = strtotime('today'); - //限购 - $user_toDay_count = OrderList::field('id') - ->where('goods_id', '=', $goods_id) - ->where('user_id', '=', $user['id']) - ->where('parent_goods_list_id', '=', 0) - ->where('addtime', '>=', $todayMidnight) - ->count(); - //已经达到限购先上限 - if ($user_toDay_count >= $goods['daily_xiangou']) { - return $this->renderError('今日限购' . $goods['daily_xiangou'] . '次'); - } - $now_prize_num = $prize_num + $user_toDay_count; - if ($now_prize_num > $goods['daily_xiangou']) { - return $this->renderError('购买超出限制,今日还允许购买' . ($goods['daily_xiangou'] - $user_toDay_count) . '次'); - } - } - - if ($goods['type'] == 6 && $goods['quanju_xiangou'] > 0) { - //限购 - $user_xiangou_count = OrderList::field('id')->where('goods_id', '=', $goods_id) - ->where('num', '=', $num) - ->where('shang_id', 'between', self::$shang_count_id) - ->where('order_type', '=', $goods['type']) - ->where('user_id', '=', $user['id']) - ->count(); - //已经达到限购先上限 - if ($goods['quanju_xiangou'] <= $user_xiangou_count) { - return $this->renderError('当前箱子限购' . $goods['quanju_xiangou'] . '次'); - } - } elseif ($goods['type'] == 15 && $goods['quanju_xiangou'] > 0) { - //限购 - $user_xiangou_count = OrderList::field('id')->where('goods_id', '=', $goods_id) - ->where('user_id', '=', $user['id']) - ->count(); - //已经达到限购先上限 - if ($goods['quanju_xiangou'] <= $user_xiangou_count) { - return $this->renderError('当前活动限购' . $goods['quanju_xiangou'] . '次'); - } - } - if ($goods['type'] != 15) { - #奖品信息 - $goodslist = GoodsList::field('sum(`stock`) as stock, sum(`surplus_stock`) as surplus_stock') - ->where('goods_id', '=', $goods_id) - ->where('num', '=', $num) - ->where('shang_id', 'between', self::$shang_prize_id) - ->find(); - if (!$goodslist) { - return $this->renderError('暂无奖品信息'); - } - $surplus_stock = $goodslist['surplus_stock']; - if ($surplus_stock <= 0) { - return $this->renderError('库存剩余不足,请刷新重试'); - } - #判断库存 - if (RegInt($prize_num)) { - return $this->renderError("抽奖数量选择错误,请刷新重试"); - } - if ($prize_num > $surplus_stock) { - return $this->renderError("剩余数量不足,请刷新重试"); - } - } - #盒子单价 - $box_price = $goods['price']; - //是否首抽五折 - $shou_zhe_price = 0; - $is_shou_zhe = 0; - if ($goods['type'] != 5 && $goods['type'] != 10 && $goods['type'] != 15) { - $is_chou = Order::field('id')->where([['user_id', '=', $user['id']], ['status', '=', 1]])->find(); - $is_chou2 = Order::field('id')->where([['is_shou_zhe', '=', 1], ['status', '=', 1], ['user_id', '=', $user['id']]])->find(); - if (!$is_chou && !$is_chou2 && $goods['is_shou_zhe'] == 1) { - $shou_zhe_price = bcmul("$box_price", "0.5", 2); - } - } - $goods['shou_zhe_price'] = $shou_zhe_price; - $price = bcmul("$box_price", "$prize_num", 2); - $price = bcsub("$price", "$shou_zhe_price", 2); - #订单金额 微信支付金额 - $order_total = $order_zhe_total = $price; - #使用优惠券 - $coupon_price = 0; - - # 判断是否可使用优惠券 - if ($shou_zhe_price <= 0 && !empty($coupon_id) && $goods_extend['pay_coupon'] == 1) { - # 获取优惠券信息 - $coupon = CouponReceiveModel::where([ - 'id' => $coupon_id, - 'status' => 0, - 'user_id' => $user['id'] - ])->where('man_price', '<=', $price) - ->where('end_time', '>', time()) # 确保优惠券未过期 - ->find(); - - if ($coupon) { - $coupon_price = $coupon['price']; - } else { - $coupon_id = 0; - } - } else { - $coupon_id = 0; - } - - $price = bcsub("$price", "$coupon_price", 2); - if ($price <= 0) { - $price = 0; - } - $order_zhe_total = $price; - - # 初始化变量 - $use_money = 0; # 余额抵扣 - $use_integral = 0; # 货币1抵扣 - $use_money2 = 0; # 货币2抵扣 - $zhe = 0; # 会员折扣 - - if ($shou_zhe_price <= 0) { - $iszhifu = 0; - # 余额抵扣 - if ($use_money_is == 1 && $goods_extend['pay_balance'] == 1) { - if ($goods_extend['is_deduction'] == 1) { - # 抵扣模式 - if ($user['money'] >= $price) { - $use_money = $price; - $price = 0; - } else { - $use_money = $user['money']; - $price = bcsub("$price", "$use_money", 2); - } - } else { - # 支付模式 - if ($user['money'] >= $price) { - $use_money = $price; - $price = 0; - $iszhifu++; - } else { - # 支付模式下余额不足无法抵扣 - $use_money = 0; - return $this->renderError('金额不足'); - } - } - } - # 货币1抵扣 - if ($use_integral_is == 1 && $goods_extend['pay_currency'] == 1) { - $price_in_currency = $price * 100; # 1:100比例 - if ($goods_extend['is_deduction'] == 1) { - # 抵扣模式 - if ($user['integral'] >= $price_in_currency) { - $use_integral = $price_in_currency; - $price = 0; - } else { - $use_integral = $user['integral']; - $price = bcsub("$price", bcdiv("$use_integral", "100", 2), 2); - } - } else { - # 支付模式 - if ($user['integral'] >= $price_in_currency) { - $use_integral = $price_in_currency; - $price = 0; - $iszhifu++; - } else { - # 支付模式下货币不足无法抵扣 - $use_integral = 0; - return $this->renderError('金额不足'); - } - } - } - # 货币2抵扣 - if ($use_money2_is == 1 && $goods_extend['pay_currency2'] == 1) { - $price_in_currency2 = $price * 100; # 1:100比例 - if ($goods_extend['is_deduction'] == 1) { - # 抵扣模式 - if (isset($user['money2']) && $user['money2'] >= $price_in_currency2) { - $use_money2 = $price_in_currency2; - $price = 0; - } else if (isset($user['money2'])) { - $use_money2 = $user['money2']; - $price = bcsub("$price", bcdiv("$use_money2", "100", 2), 2); - } - } else { - # 支付模式 - if (isset($user['money2']) && $user['money2'] >= $price_in_currency2) { - $use_money2 = $price_in_currency2; - $price = 0; - $iszhifu++; - } else { - # 支付模式下货币2不足无法抵扣 - $use_money2 = 0; - return $this->renderError('金额不足'); - } - } - } - if ($goods_extend['is_deduction'] == 0 && $iszhifu == 0 && $goods_extend['pay_wechat'] == 0) { - return $this->renderError('请选择支付方式'); - } - } - #抽奖数量 - $goods['prize_num'] = $prize_num; - $data = [ - 'goods' => $goods, - 'order_total' => round(floatval($order_total), 2), - 'order_zhe_total' => round($order_zhe_total, 2), - 'zhe' => round($zhe, 2), - 'price' => round($price, 2), - 'integral' => round($user['integral'], 2), - 'use_integral' => round($use_integral, 2), - 'use_integral_money' => round(round($use_integral, 2) / 100, 2), - 'money' => round($user['money'], 2), - 'use_money' => round($use_money, 2), - 'score' => $user['money2'], - 'use_score' => $use_money2, - 'coupon_price' => round($coupon_price, 2), - 'coupon_id' => $coupon_id, - 'goods_extend' => $goods_extend - ]; - return $this->renderSuccess("请求成功", $data); + + return $this->renderSuccess("请求成功", $result); } - - /** * 创建订单 */ @@ -964,65 +747,12 @@ class Goods extends Base if (RegInt($num)) { return $this->renderError("箱号选择错误"); } - $user_id = $this->getuserid(); - - $choujiang_xianzhi = $goods['choujiang_xianzhi']; - - if ($choujiang_xianzhi && $choujiang_xianzhi > 0) { - // SELECT sum(price) FROM xinglanmh_shequt_test.`order` where user_id=4445 and status=1 - if ($goods['type'] == 15) { - - // 获取用户在该福利屋活动期间的消费情况 - $consumptionData = CommonService::getUserConsumptionByTimeRange( - $user_id, - $goods['flw_start_time'], - $goods['flw_end_time'] - ); - if ($consumptionData['total_consumed'] < $choujiang_xianzhi) { - return $this->renderError(" 需在指定时间" . date('Y-m-d H:i:s', $goods['flw_start_time']) . "-" - . date('Y-m-d H:i:s', $goods['flw_end_time']) . "消耗达到" . $choujiang_xianzhi . "钻石,即可加入房间,还需" . round(($choujiang_xianzhi - $consumptionData['total_consumed']), 2) . "钻石."); - } - - } else { - $user_price = order::where('user_id', '=', $user_id)->where('status', '=', 1)->sum('price'); - if ($user_price < $choujiang_xianzhi) { - return $this->renderError("消费满" . $choujiang_xianzhi . "元可参与 已消费" . round($user_price, 2) . "元"); - } - } - } - if ($goods['quanju_xiangou'] > 0) { - //限购 - $user_toDay_count = OrderList::field('id')->where('goods_id', '=', $goods_id) - ->where('user_id', '=', $user['id']) - ->where('parent_goods_list_id', '=', 0) - ->count(); - //已经达到限购先上限 - if ($goods['quanju_xiangou'] <= $user_toDay_count) { - return $this->renderError('当前限购' . $goods['quanju_xiangou'] . '次'); - } - $now_prize_num = $prize_num + $user_toDay_count; - if ($now_prize_num > $goods['quanju_xiangou']) { - return $this->renderError('购买超出限制,还允许购买' . ($goods['quanju_xiangou'] - $user_toDay_count) . '次'); - } - } - if ($goods['daily_xiangou'] > 0) { - //获取今天凌晨时间 - $todayMidnight = strtotime('today'); - //限购 - $user_toDay_count = OrderList::field('id') - ->where('goods_id', '=', $goods_id) - ->where('user_id', '=', $user['id']) - ->where('parent_goods_list_id', '=', 0) - ->where('addtime', '>=', $todayMidnight) - ->count(); - //已经达到限购先上限 - if ($user_toDay_count >= $goods['daily_xiangou']) { - return $this->renderError('今日限购' . $goods['daily_xiangou'] . '次'); - } - $now_prize_num = $prize_num + $user_toDay_count; - if ($now_prize_num > $goods['daily_xiangou']) { - return $this->renderError('购买超出限制,今日还允许购买' . ($goods['daily_xiangou'] - $user_toDay_count) . '次'); - } + + // 使用PaymentCalculator验证抽奖限制(限购、消费门槛等) + $paymentCalculator = new \app\common\service\PaymentCalculator(); + $validationResult = $paymentCalculator->validateDrawRestrictions($user, $goods, $prize_num); + if ($validationResult['status'] == 0) { + return $this->renderError($validationResult['msg']); } if ($goods['type'] != 15) { @@ -1085,151 +815,23 @@ class Goods extends Base return $this->renderError("剩余数量不足,请刷新重试"); } } - #盒子单价 - $box_price = $goods['price']; - //是否首抽五折 - $shou_zhe_price = 0; - $is_shou_zhe = 0; - if ($goods['type'] != 5 && $goods['type'] != 10 && $goods['type'] != 15) { - $is_chou = Order::field('id')->where([['user_id', '=', $user['id']], ['status', '=', 1]])->find(); - $is_chou2 = Order::field('id')->where([['is_shou_zhe', '=', 1], ['status', '=', 1], ['user_id', '=', $user['id']]])->find(); - if (!$is_chou && !$is_chou2 && $goods['is_shou_zhe'] == 1) { - $shou_zhe_price = bcmul("$box_price", "0.5", 2); - $is_shou_zhe = 1; - } + + // 使用PaymentCalculator计算订单金额和支付方式 + $paymentResult = $paymentCalculator->calculateOrderAmount( + $user, + $goods_id, + $prize_num, + $use_money_is, + $use_integral_is, + $use_money2_is, + $coupon_id, + $goods, + $goods_extend + ); + + if ($paymentResult['status'] == 0) { + return $this->renderError($paymentResult['msg']); } - $goods['shou_zhe_price'] = $shou_zhe_price; - $price = bcmul("$box_price", "$prize_num", 2); - $price = bcsub("$price", "$shou_zhe_price", 2); - #订单金额 微信支付金额 - $order_total = $order_zhe_total = $price; - #使用优惠券 - $coupon_price = 0; - - # 判断是否可使用优惠券 - if ($shou_zhe_price <= 0 && !empty($coupon_id) && $goods_extend['pay_coupon'] == 1) { - # 获取优惠券信息 - $coupon = CouponReceiveModel::where([ - 'id' => $coupon_id, - 'status' => 0, - 'user_id' => $user['id'] - ])->where('man_price', '<=', $price) - ->where('end_time', '>', time()) # 确保优惠券未过期 - ->find(); - - if ($coupon) { - $coupon_price = $coupon['price']; - } else { - $coupon_id = 0; - } - } else { - $coupon_id = 0; - } - - $price = bcsub("$price", "$coupon_price", 2); - if ($price <= 0) { - $price = 0; - } - $order_zhe_total = $price; - - # 初始化变量 - $use_integral = 0; # 货币1抵扣 - $use_money = 0; # 余额抵扣 - $use_money2 = 0; # 货币2抵扣 - $use_score = 0; # 积分抵扣 - $zhe = 0; # 会员折扣 - - - # 对于非积分赏类型,应用会员折扣 - if ($shou_zhe_price <= 0) { - - - $iszhifu = 0; - - # 余额抵扣 - if ($use_money_is == 1 && $goods_extend['pay_balance'] == 1) { - if ($goods_extend['is_deduction'] == 1) { - # 抵扣模式 - if ($user['money'] >= $price) { - $use_money = $price; - $price = 0; - } else { - $use_money = $user['money']; - $price = bcsub("$price", "$use_money", 2); - } - } else { - # 支付模式 - if ($user['money'] >= $price) { - $use_money = $price; - $price = 0; - $iszhifu++; - } else { - # 支付模式下余额不足无法抵扣 - $use_money = 0; - return $this->renderError('金额不足'); - } - } - } - - # 货币1抵扣 - if ($use_integral_is == 1 && $goods_extend['pay_currency'] == 1) { - $price_in_currency = $price * 100; # 1:100比例 - if ($goods_extend['is_deduction'] == 1) { - # 抵扣模式 - if ($user['integral'] >= $price_in_currency) { - $use_integral = $price_in_currency; - $price = 0; - } else { - $use_integral = $user['integral']; - $price = bcsub("$price", bcdiv("$use_integral", "100", 2), 2); - } - } else { - # 支付模式 - if ($user['integral'] >= $price_in_currency) { - $use_integral = $price_in_currency; - $price = 0; - $iszhifu++; - } else { - # 支付模式下货币不足无法抵扣 - $use_integral = 0; - return $this->renderError('金额不足'); - } - } - } - - - - # 货币2抵扣 - if ($use_money2_is == 1 && $goods_extend['pay_currency2'] == 1) { - $price_in_currency2 = $price * 100; # 1:100比例 - if ($goods_extend['is_deduction'] == 1) { - # 抵扣模式 - if (isset($user['money2']) && $user['money2'] >= $price_in_currency2) { - $use_money2 = $price_in_currency2; - $price = 0; - } else if (isset($user['money2'])) { - $use_money2 = $user['money2']; - $price = bcsub("$price", bcdiv("$use_money2", "100", 2), 2); - } - } else { - # 支付模式 - if (isset($user['money2']) && $user['money2'] >= $price_in_currency2) { - $use_money2 = $price_in_currency2; - $price = 0; - $iszhifu++; - } else { - # 支付模式下货币2不足无法抵扣 - $use_money2 = 0; - return $this->renderError('金额不足'); - } - } - } - - if ($goods_extend['is_deduction'] == 0 && $iszhifu == 0 && $goods_extend['pay_wechat'] == 0) { - return $this->renderError('请选择支付方式'); - } - } - #一番赏锁箱 if ($goods['type'] == 1 || $goods['type'] == 6 || $goods['type'] == 11) { @@ -1342,14 +944,14 @@ class Goods extends Base $res[] = $order_id = Order::insertGetId([ 'user_id' => $user['id'], 'order_num' => $order_num, - 'order_total' => $order_total,#订单金额 - 'order_zhe_total' => $order_zhe_total,#订单折扣金额 - 'price' => $price,#微信支付 - 'use_money' => $use_money,#余额抵扣 - 'use_integral' => $use_integral,#货币1抵扣 - 'use_money2' => $use_money2,#货币2抵扣 - 'use_score' => $use_score,#积分抵扣 - 'zhe' => $zhe,#会员折扣 + 'order_total' => $paymentResult['order_total'],#订单金额 + 'order_zhe_total' => $paymentResult['order_zhe_total'],#订单折扣金额 + 'price' => $paymentResult['price'],#微信支付 + 'use_money' => $paymentResult['use_money'],#余额抵扣 + 'use_integral' => $paymentResult['use_integral'],#货币1抵扣 + 'use_money2' => $paymentResult['use_money2'],#货币2抵扣 + 'use_score' => 0,#积分抵扣 + 'zhe' => $paymentResult['zhe'],#会员折扣 'goods_id' => $goods_id, 'num' => $num, 'goods_price' => $goods['price'], @@ -1360,14 +962,14 @@ class Goods extends Base 'pay_type' => 1,#1微信 2支付宝 'order_type' => $goods['type'], 'addtime' => time(), - 'coupon_id' => $coupon_id ? $coupon_id : 0, - 'use_coupon' => $coupon_price, #优惠券抵扣 - 'is_shou_zhe' => $is_shou_zhe, + 'coupon_id' => $paymentResult['coupon_id'], + 'use_coupon' => $paymentResult['coupon_price'], #优惠券抵扣 + 'is_shou_zhe' => $paymentResult['is_shou_zhe'], 'ad_id' => $ad_id, 'click_id' => $user['click_id'] ]); #微信支付金额大于0 - if ($price > 0) { + if ($paymentResult['price'] > 0) { $body = '购买盒子' . $goods['title']; if ($goods['type'] == 1) { $attach = 'order_yfs'; @@ -1402,7 +1004,7 @@ class Goods extends Base } } - $payRes = (new Pay())->wxCreateOrder($order_num, $price, $user['openid'], $body, $attach); + $payRes = (new Pay())->wxCreateOrder($order_num, $paymentResult['price'], $user['openid'], $body, $attach); if ($payRes['status'] == 1) { #结果集 $new_data = [ @@ -1657,6 +1259,8 @@ class Goods extends Base $goodsData = $data['goods']; $goodsListData = $data['goodsList']; $async_code = $data['async_code']; + $goodsExtendData = isset($data['goodsExtend']) ? $data['goodsExtend'] : null; + $rewardsData = isset($data['rewards']) ? $data['rewards'] : []; // 检查async_code是否存在 $existingGoods = Goodsmodel::where('async_code', $async_code)->find(); @@ -1677,6 +1281,9 @@ class Goods extends Base // 删除现有的商品列表数据 GoodsList::where('goods_id', $goodsId)->delete(); + + // 删除现有的扩展表数据 + GoodsExtend::where('goods_id', $goodsId)->delete(); } else { // 创建新商品 $goods['async_date'] = date('Y-m-d H:i:s'); @@ -1686,9 +1293,21 @@ class Goods extends Base $goodsModel->save($goods); $goodsId = $goodsModel->id; } + + // 处理盒子扩展数据 + if ($goodsExtendData) { + if (isset($goodsExtendData['id'])) { + unset($goodsExtendData['id']); + } + $goodsExtendData['goods_id'] = $goodsId; + $goodsExtend = new GoodsExtend(); + $goodsExtend->save($goodsExtendData); + } // 创建ID映射表,用于处理子奖品关联 $idMapping = []; + // 创建reward_id映射表,用于处理奖励关联 + $rewardMapping = []; // 先处理非子奖品(goods_list_id为0的奖品) $parentItems = []; @@ -1706,6 +1325,7 @@ class Goods extends Base // 先处理父奖品 foreach ($parentItems as $listItem) { $oldId = $listItem['id']; + $oldRewardId = isset($listItem['reward_id']) ? $listItem['reward_id'] : ''; // 处理商品列表项 if (isset($listItem['id'])) { @@ -1713,6 +1333,13 @@ class Goods extends Base } $listItem['goods_id'] = $goodsId; + + // 处理奖励ID + if (!empty($oldRewardId)) { + $newRewardId = 'MHHZ' . date('YmdHis') . mt_rand(1000, 9999); + $rewardMapping[$oldRewardId] = $newRewardId; + $listItem['reward_id'] = $newRewardId; + } // 创建新的商品列表项 $goodsListModel = new GoodsList(); @@ -1725,6 +1352,7 @@ class Goods extends Base // 再处理子奖品 foreach ($childItems as $listItem) { $originalParentId = $listItem['goods_list_id']; + $oldRewardId = isset($listItem['reward_id']) ? $listItem['reward_id'] : ''; // 处理商品列表项 if (isset($listItem['id'])) { @@ -1737,11 +1365,31 @@ class Goods extends Base if (isset($idMapping[$originalParentId])) { $listItem['goods_list_id'] = $idMapping[$originalParentId]; } + + // 处理奖励ID + if (!empty($oldRewardId)) { + $newRewardId = 'MHHZ' . date('YmdHis') . mt_rand(1000, 9999); + $rewardMapping[$oldRewardId] = $newRewardId; + $listItem['reward_id'] = $newRewardId; + } // 创建新的商品列表项 $goodsListModel = new GoodsList(); $goodsListModel->save($listItem); } + + // 处理奖励数据 + foreach ($rewardsData as $reward) { + $oldRewardId = $reward['reward_id']; + if (isset($rewardMapping[$oldRewardId])) { + // 使用新的reward_id + $reward['reward_id'] = $rewardMapping[$oldRewardId]; + unset($reward['id']); + $reward['create_time'] = time(); + $reward['update_time'] = time(); + Db::name('reward')->insert($reward); + } + } // 提交事务 Db::commit(); diff --git a/app/api/controller/Infinite.php b/app/api/controller/Infinite.php index 25157be..0459035 100755 --- a/app/api/controller/Infinite.php +++ b/app/api/controller/Infinite.php @@ -345,21 +345,13 @@ class Infinite extends Base { $goods_id = request()->param('goods_id/d', 0); $user_id = $this->getUserId(); - // #盒子信息 - // $goods = Goodsmodel::field('id,stock,status,type') - // ->where(['id' => $goods_id]) - // ->find(); - // if (!$goods) { - // return $this->renderError("盒子不存在"); - // } - // if ($goods['status'] != 1) { - // return $this->renderError("盒子已下架"); - // } - #中奖记录分类 + + // 查询中奖记录 $where = []; $where[] = ['goods_id', '=', $goods_id]; $where[] = ['num', '=', 0]; $where[] = ['user_id', '=', $user_id]; + $data = OrderList::field('user_id,goodslist_title,goodslist_imgurl,addtime') ->where($where) ->where('source', '=', 1) @@ -369,6 +361,7 @@ class Infinite extends Base $item['goodslist_imgurl'] = imageUrl($item['goodslist_imgurl']); return $item; }); + return $this->renderSuccess("请求成功", $data); } @@ -394,231 +387,33 @@ class Infinite extends Base if ($goods['status'] != 1) { return $this->renderError("盒子已下架"); } - $goods_type = $goods['type']; - $goods_extend = GoodsExtend::getGoodsExtendByGoodsId($goods_id, $goods_type); - if (!$goods_extend) { - return $this->renderError("盒子类型配置不存在"); + + // 获取服务实例 + $calculator = new \app\common\service\PaymentCalculator(); + + // 验证抽奖限制 + $validationResult = $calculator->validateDrawRestrictions($user, $goods, $prize_num); + if ($validationResult['status'] == 0) { + return $this->renderError($validationResult['msg']); } - if ($goods['quanju_xiangou'] > 0) { - //限购 - $user_quanju_count = OrderList::field('id')->where('goods_id', '=', $goods_id) - ->where('user_id', '=', $user['id']) - ->where('parent_goods_list_id', '=', 0) - ->count(); - //已经达到限购先上限 - if ($user_quanju_count >= $goods['quanju_xiangou']) { - return $this->renderError('当前限购' . $goods['quanju_xiangou'] . '次'); - } - $now_prize_num = $prize_num + $user_quanju_count; - if ($now_prize_num > $goods['quanju_xiangou']) { - return $this->renderError('购买超出限制,还允许购买' . ($goods['quanju_xiangou'] - $user_quanju_count) . '次'); - } - + + // 计算订单金额 + $result = $calculator->calculateOrderAmount( + $user, + $goods_id, + $prize_num, + $use_money_is, + $use_integral_is, + $use_money2_is, + $coupon_id, + $goods + ); + + if ($result['status'] == 0) { + return $this->renderError($result['msg']); } - if ($goods['daily_xiangou'] > 0) { - //获取今天凌晨时间 - $todayMidnight = strtotime('today'); - //限购 - $user_toDay_count = OrderList::field('id') - ->where('goods_id', '=', $goods_id) - ->where('user_id', '=', $user['id']) - ->where('parent_goods_list_id', '=', 0) - ->where('addtime', '>=', $todayMidnight) - ->count(); - //已经达到限购先上限 - if ($user_toDay_count >= $goods['daily_xiangou']) { - return $this->renderError('今日限购' . $goods['daily_xiangou'] . '次'); - } - $now_prize_num = $prize_num + $user_toDay_count; - if ($now_prize_num > $goods['daily_xiangou']) { - return $this->renderError('购买超出限制,今日还允许购买' . ($goods['daily_xiangou'] - $user_toDay_count) . '次'); - } - } - $user_id = $user['id']; - $choujiang_xianzhi = $goods['choujiang_xianzhi']; - if ($choujiang_xianzhi && $choujiang_xianzhi > 0) { - $user_price = order::where('user_id', '=', $user_id)->where('status', '=', 1)->sum('price'); - if ($user_price < $choujiang_xianzhi) { - if ($user['istest'] > 0) { - $user_price = order::where('user_id', '=', $user_id)->where('status', '=', 1)->sum('order_zhe_total'); - } - if ($user_price < $choujiang_xianzhi) { - return $this->renderError("消费满" . $choujiang_xianzhi . "元可参与 已消费" . round($user_price, 2) . "元"); - } - } - } - $goods['imgurl_detail'] = imageUrl($goods['imgurl_detail']); - if ($goods['type'] == 9) { - //连击赏 - $prize_num = intval($prize_num); - if ($prize_num > 20) { - return $this->renderError("一次最多购买20次"); - } - - } else { - if ($prize_num != 1 && $prize_num != 3 && $prize_num != 5 && $prize_num != 10 && $prize_num != 50) { - return $this->renderError("请求参数错误!!!"); - } - } - #盒子单价 - $box_price = $goods['price']; - //是否首抽五折 - $shou_zhe_price = 0; - - if ($goods['type'] != 5 && $goods_type != 10) { - $is_chou = Order::field('id')->where([['user_id', '=', $user['id']], ['status', '=', 1]])->find(); - $is_chou2 = Order::field('id')->where([['is_shou_zhe', '=', 1], ['status', '=', 1], ['user_id', '=', $user['id']]])->find(); - if (!$is_chou && !$is_chou2 && $goods['is_shou_zhe'] == 1) { - $shou_zhe_price = bcmul("$box_price", "0.5", 2); - } - } - $goods['shou_zhe_price'] = $shou_zhe_price; - $price = bcmul("$box_price", "$prize_num", 2); - $price = bcsub("$price", "$shou_zhe_price", 2); - #订单金额 微信支付金额 - $order_total = $order_zhe_total = $price; - - # 初始化变量 - $coupon_id = 0; - $use_money = 0; # 余额抵扣 - $use_integral = 0; # 货币1抵扣 - $use_money2 = 0; # 货币2抵扣 - $zhe = 0; # 会员折扣 - $coupon_price = 0; # 优惠券金额 - #首抽半价 - if ($shou_zhe_price <= 0) { - # 判断是否可使用优惠券 - if (!empty($coupon_id) && $goods_extend['pay_coupon'] == 1) { - # 获取优惠券信息 - $coupon = CouponReceiveModel::where([ - 'id' => $coupon_id, - 'status' => 0, - 'user_id' => $user['id'] - ])->where('man_price', '<=', $price) - ->where('end_time', '>', time()) # 确保优惠券未过期 - ->find(); - - if ($coupon) { - $coupon_price = $coupon['price']; - } else { - $coupon_id = 0; - } - } else { - $coupon_id = 0; - } - - $price = bcsub("$price", "$coupon_price", 2); - - if ($price <= 0) { - $price = 0; - } - $order_zhe_total = $price; - - $iszhifu = 0; - # 余额抵扣 - if ($use_money_is == 1 && $goods_extend['pay_balance'] == 1) { - if ($goods_extend['is_deduction'] == 1) { - # 抵扣模式 - if ($user['money'] >= $price) { - $use_money = $price; - $price = 0; - } else { - $use_money = $user['money']; - $price = bcsub("$price", "$use_money", 2); - } - } else { - # 支付模式 - if ($user['money'] >= $price) { - $use_money = $price; - $price = 0; - $iszhifu++; - } else { - # 支付模式下余额不足无法抵扣 - $use_money = 0; - return $this->renderError('金额不足'); - } - } - } - - # 货币1抵扣 - if ($use_integral_is == 1 && $goods_extend['pay_currency'] == 1) { - $price_in_currency = $price * 100; # 1:100比例 - if ($goods_extend['is_deduction'] == 1) { - # 抵扣模式 - if ($user['integral'] >= $price_in_currency) { - $use_integral = $price_in_currency; - $price = 0; - } else { - $use_integral = $user['integral']; - $price = bcsub("$price", bcdiv("$use_integral", "100", 2), 2); - } - } else { - # 支付模式 - if ($user['integral'] >= $price_in_currency) { - $use_integral = $price_in_currency; - $price = 0; - $iszhifu++; - } else { - # 支付模式下货币不足无法抵扣 - $use_integral = 0; - return $this->renderError('金额不足'); - } - } - } - - - - # 货币2抵扣 - if ($use_money2_is == 1 && $goods_extend['pay_currency2'] == 1) { - $price_in_currency2 = $price * 100; # 1:100比例 - if ($goods_extend['is_deduction'] == 1) { - # 抵扣模式 - if (isset($user['money2']) && $user['money2'] >= $price_in_currency2) { - $use_money2 = $price_in_currency2; - $price = 0; - } else if (isset($user['money2'])) { - $use_money2 = $user['money2']; - $price = bcsub("$price", bcdiv("$use_money2", "100", 2), 2); - } - } else { - # 支付模式 - if (isset($user['money2']) && $user['money2'] >= $price_in_currency2) { - $use_money2 = $price_in_currency2; - $price = 0; - $iszhifu++; - } else { - # 支付模式下货币2不足无法抵扣 - $use_money2 = 0; - return $this->renderError('金额不足'); - } - } - } - - if ($goods_extend['is_deduction'] == 0 && $iszhifu == 0 && $goods_extend['pay_wechat'] == 0) { - return $this->renderError('请选择支付方式'); - } - } - - #抽奖数量 - $goods['prize_num'] = $prize_num; - $data = [ - 'goods' => $goods, - 'order_total' => round(floatval($order_total), 2), - 'order_zhe_total' => round($order_zhe_total, 2), - 'zhe' => round($zhe, 2), - 'price' => round($price, 2), - 'integral' => round($user['integral'], 2), - 'use_integral' => round($use_integral, 2), - 'use_integral_money' => round(round($use_integral, 2) / 100, 2), - 'money' => round($user['money'], 2), - 'use_money' => round($use_money, 2), - 'score' => isset($user['money2']) ? $user['money2'] : 0, - 'use_score' => $use_money2, - 'coupon_id' => $coupon_id, - 'coupon_price' => round($coupon_price, 2), - 'goods_extend' => $goods_extend - ]; - return $this->renderSuccess("请求成功", $data); + + return $this->renderSuccess("请求成功", $result); } /** @@ -626,7 +421,6 @@ class Infinite extends Base */ public function infinite_orderbuy() { - $user = $this->getUser(); if (empty($user['mobile'])) { return $this->renderError('请先绑定手机号', [], -9); @@ -661,55 +455,15 @@ class Infinite extends Base if (!in_array($goods['type'], [2, 8, 9, 10, 16, 17])) { return $this->renderError("非法请求"); } - - if ($goods['quanju_xiangou'] > 0) { - //限购 - $user_toDay_count = OrderList::field('id')->where('goods_id', '=', $goods_id) - ->where('user_id', '=', $user['id']) - ->where('parent_goods_list_id', '=', 0) - ->count(); - //已经达到限购先上限 - if ($goods['quanju_xiangou'] <= $user_toDay_count) { - return $this->renderError('当前限购' . $goods['quanju_xiangou'] . '次'); - } - $now_prize_num = $prize_num + $user_toDay_count; - if ($now_prize_num > $goods['quanju_xiangou']) { - return $this->renderError('购买超出限制,还允许购买' . ($goods['quanju_xiangou'] - $user_toDay_count) . '次'); - } - } - if ($goods['daily_xiangou'] > 0) { - //获取今天凌晨时间 - $todayMidnight = strtotime('today'); - //限购 - $user_toDay_count = OrderList::field('id') - ->where('goods_id', '=', $goods_id) - ->where('user_id', '=', $user['id']) - ->where('parent_goods_list_id', '=', 0) - ->where('addtime', '>=', $todayMidnight) - ->count(); - //已经达到限购先上限 - if ($user_toDay_count >= $goods['daily_xiangou']) { - return $this->renderError('今日限购' . $goods['daily_xiangou'] . '次'); - } - $now_prize_num = $prize_num + $user_toDay_count; - if ($now_prize_num > $goods['daily_xiangou']) { - return $this->renderError('购买超出限制,今日还允许购买' . ($goods['daily_xiangou'] - $user_toDay_count) . '次'); - } + + // 使用PaymentCalculator验证抽奖限制(限购、消费门槛等) + $paymentCalculator = new \app\common\service\PaymentCalculator(); + $validationResult = $paymentCalculator->validateDrawRestrictions($user, $goods, $prize_num); + if ($validationResult['status'] == 0) { + return $this->renderError($validationResult['msg']); } - $user_id = $user['id']; - $choujiang_xianzhi = $goods['choujiang_xianzhi']; - if ($choujiang_xianzhi && $choujiang_xianzhi > 0) { - $user_price = order::where('user_id', '=', $user_id)->where('status', '=', 1)->sum('price'); - if ($user_price < $choujiang_xianzhi) { - if ($user['istest'] > 0) { - $user_price = order::where('user_id', '=', $user_id)->where('status', '=', 1)->sum('order_zhe_total'); - } - if ($user_price < $choujiang_xianzhi) { - return $this->renderError("消费满" . $choujiang_xianzhi . "元可参与 已消费" . round($user_price, 2) . "元"); - } - } - } + // 验证奖品信息 $where = []; $where[] = ['goods_id', '=', $goods_id]; @@ -721,18 +475,21 @@ class Infinite extends Base $where[] = ['real_pro', '>', 0]; $where[] = ['shang_id', 'between', self::$shang_prize_id]; } + #奖品信息 if ($goods['type'] == 9 && $is_mibao == 1) { //秘宝池 $where[] = ['lian_ji_type', '=', 1]; return $this->renderError('请求错误'); } + $is_goodslist = GoodsList::field('id') ->where($where) ->find(); if (!$is_goodslist) { return $this->renderError('暂无奖品信息'); } + if ($goods['type'] == 9) { $prize_num = intval($prize_num); if ($prize_num > 20) { @@ -749,144 +506,23 @@ class Infinite extends Base } } - #盒子单价 - $box_price = $goods['price']; - //是否首抽五折 - $shou_zhe_price = 0; - $is_shou_zhe = 0; - if ($goods['type'] != 5 && $goods['type'] != 10) { - $is_chou = Order::field('id')->where([['user_id', '=', $user['id']], ['status', '=', 1]])->find(); - $is_chou2 = Order::field('id')->where([['is_shou_zhe', '=', 1], ['status', '=', 1], ['user_id', '=', $user['id']]])->find(); - if (!$is_chou && !$is_chou2 && $goods['is_shou_zhe'] == 1) { - $shou_zhe_price = bcmul("$box_price", "0.5", 2); - $is_shou_zhe = 1; - } + // 使用PaymentCalculator计算订单金额和支付方式 + $paymentResult = $paymentCalculator->calculateOrderAmount( + $user, + $goods_id, + $prize_num, + $use_money_is, + $use_integral_is, + $use_money2_is, + $coupon_id, + $goods, + $goods_extend + ); + + if ($paymentResult['status'] == 0) { + return $this->renderError($paymentResult['msg']); } - - $goods['shou_zhe_price'] = $shou_zhe_price; - $price = bcmul("$box_price", "$prize_num", 2); - $price = bcsub("$price", "$shou_zhe_price", 2); - #订单金额 微信支付金额 - $order_total = $order_zhe_total = $price; - - # 初始化变量 - $coupon_id = 0; - $use_money = 0; # 余额抵扣 - $use_integral = 0; # 货币1抵扣 - $use_money2 = 0; # 货币2抵扣 - $zhe = 0; # 会员折扣 - $coupon_price = 0; # 优惠券金额 - - #使用折扣 - if ($is_shou_zhe <= 0) { - # 判断是否可使用优惠券 - if (!empty($coupon_id) && $goods_extend['pay_coupon'] == 1) { - # 获取优惠券信息 - $coupon = CouponReceiveModel::where([ - 'id' => $coupon_id, - 'status' => 0, - 'user_id' => $user['id'] - ])->where('man_price', '<=', $price) - ->where('end_time', '>', time()) # 确保优惠券未过期 - ->find(); - - if ($coupon) { - $coupon_price = $coupon['price']; - } else { - $coupon_id = 0; - } - } else { - $coupon_id = 0; - } - - $price = bcsub("$price", "$coupon_price", 2); - - if ($price <= 0) { - $price = 0; - } - $order_zhe_total = $price; - $iszhifu = 0; - - # 余额抵扣 - if ($use_money_is == 1 && $goods_extend['pay_balance'] == 1) { - if ($goods_extend['is_deduction'] == 1) { - # 抵扣模式 - if ($user['money'] >= $price) { - $use_money = $price; - $price = 0; - } else { - $use_money = $user['money']; - $price = bcsub("$price", "$use_money", 2); - } - } else { - # 支付模式 - if ($user['money'] >= $price) { - $use_money = $price; - $price = 0; - $iszhifu++; - } else { - # 支付模式下余额不足无法抵扣 - $use_money = 0; - return $this->renderError('金额不足'); - } - } - } - # 货币1抵扣 - if ($use_integral_is == 1 && $goods_extend['pay_currency'] == 1) { - $price_in_currency = $price * 100; # 1:100比例 - if ($goods_extend['is_deduction'] == 1) { - # 抵扣模式 - if ($user['integral'] >= $price_in_currency) { - $use_integral = $price_in_currency; - $price = 0; - } else { - $use_integral = $user['integral']; - $price = bcsub("$price", bcdiv("$use_integral", "100", 2), 2); - } - } else { - # 支付模式 - if ($user['integral'] >= $price_in_currency) { - $use_integral = $price_in_currency; - $price = 0; - $iszhifu++; - } else { - # 支付模式下货币不足无法抵扣 - $use_integral = 0; - return $this->renderError('金额不足'); - } - } - } - # 货币2抵扣 - if ($use_money2_is == 1 && $goods_extend['pay_currency2'] == 1) { - $price_in_currency2 = $price * 100; # 1:100比例 - if ($goods_extend['is_deduction'] == 1) { - # 抵扣模式 - if (isset($user['money2']) && $user['money2'] >= $price_in_currency2) { - $use_money2 = $price_in_currency2; - $price = 0; - } else if (isset($user['money2'])) { - $use_money2 = $user['money2']; - $price = bcsub("$price", bcdiv("$use_money2", "100", 2), 2); - } - } else { - # 支付模式 - if (isset($user['money2']) && $user['money2'] >= $price_in_currency2) { - $use_money2 = $price_in_currency2; - $price = 0; - $iszhifu++; - } else { - # 支付模式下货币2不足无法抵扣 - $use_money2 = 0; - return $this->renderError('金额不足'); - } - } - } - - if ($goods_extend['is_deduction'] == 0 && $iszhifu == 0 && $goods_extend['pay_wechat'] == 0) { - return $this->renderError('请选择支付方式'); - } - } - + $redis = (new \app\common\server\RedisHelper())->getRedis(); $redis_key = "kpw_infinite_orderbuy" . '_' . $user['id']; $redis_key_info = $redis->get($redis_key); @@ -895,11 +531,13 @@ class Infinite extends Base } else { $redis->set($redis_key, 1, 3); } + Db::startTrans(); $num = 0; if ($goods['type'] == 10) { $num = 1; } + if ($goods['daily_xiangou'] > 0) { // 查看一天内有没有未支付的订单,未支付的订单要先作废 $order_info = Order::where('goods_id', '=', $goods_id) @@ -913,20 +551,22 @@ class Infinite extends Base $order_info->save(); } } + $res = []; $order_num = create_order_no('MH_', 'order', 'order_num'); + #创建订单 $res[] = $order_id = Order::insertGetId([ 'user_id' => $user['id'], 'order_num' => $order_num, - 'order_total' => $order_total,#订单金额 - 'order_zhe_total' => $order_zhe_total,#订单折扣金额 - 'price' => $price,#微信支付 - 'use_money' => $use_money,#余额抵扣 - 'use_integral' => $use_integral,#吧唧币抵扣 - 'use_money2' => $use_money2,#货币2抵扣 + 'order_total' => $paymentResult['order_total'],#订单金额 + 'order_zhe_total' => $paymentResult['order_zhe_total'],#订单折扣金额 + 'price' => $paymentResult['price'],#微信支付 + 'use_money' => $paymentResult['use_money'],#余额抵扣 + 'use_integral' => $paymentResult['use_integral'],#吧唧币抵扣 + 'use_money2' => $paymentResult['use_money2'],#货币2抵扣 'use_score' => 0,#积分抵扣 - 'zhe' => $zhe,#会员折扣 + 'zhe' => $paymentResult['zhe'],#会员折扣 'goods_id' => $goods_id, 'num' => $num, 'goods_price' => $goods['price'], @@ -937,21 +577,22 @@ class Infinite extends Base 'pay_type' => 1,#1微信 2支付宝 'order_type' => $goods['type'], 'addtime' => time(), - 'coupon_id' => $coupon_id ? $coupon_id : 0, - 'use_coupon' => $coupon_price, #优惠券抵扣 + 'coupon_id' => $paymentResult['coupon_id'], + 'use_coupon' => $paymentResult['coupon_price'], #优惠券抵扣 'is_mibao' => $is_mibao, - 'is_shou_zhe' => $is_shou_zhe, + 'is_shou_zhe' => $paymentResult['is_shou_zhe'], 'ad_id' => $ad_id, 'click_id' => $user['click_id'] ]); + #微信支付金额大于0 - if ($price > 0) { + if ($paymentResult['price'] > 0) { $body = '购买盒子' . $goods['title']; $attach = 'order_wxs'; if ($goods['type'] == 16) { $attach = 'order_fbs'; } - $payRes = (new Pay())->wxCreateOrder($order_num, $price, $user['openid'], $body, $attach); + $payRes = (new Pay())->wxCreateOrder($order_num, $paymentResult['price'], $user['openid'], $body, $attach); if ($payRes['status'] == 1) { #结果集 $new_data = [ diff --git a/app/common/service/CommonService.php b/app/common/service/CommonService.php index 532fee3..ab0aff8 100755 --- a/app/common/service/CommonService.php +++ b/app/common/service/CommonService.php @@ -6,37 +6,44 @@ use app\common\model\Reward; use app\common\model\CouponReceive; use app\common\model\Coupon; use app\common\model\Order; + +/** + * 通用服务类 + */ class CommonService { /** * 获取用户在指定时间范围内的消费情况 * - * @param int $userId 用户ID - * @param int $startTime 开始时间戳 - * @param int $endTime 结束时间戳 - * @return array 包含余额消费和微信支付消费的数组 + * @param int $user_id 用户ID + * @param int $start_time 开始时间戳 + * @param int $end_time 结束时间戳 + * @return array 消费数据 */ - public static function getUserConsumptionByTimeRange($userId, $startTime, $endTime) + public static function getUserConsumptionByTimeRange($user_id, $start_time, $end_time) { - // 查询用户在指定时间范围内的订单消费情况 - $consumptionData = Order::where('user_id', '=', $userId) - ->where(function ($query) { - $query->where('price', '>', 0) - ->whereOr('use_money', '>', 0); - }) - ->where('status', '=', 1) - ->where('pay_time', '>=', $startTime) - ->where('pay_time', '<=', $endTime) - ->field('sum(use_money) as balance_consumed, sum(price) as wechat_consumed') - ->find(); - - // 处理查询结果 - $result = [ - 'money_consumed' => round(floatval($consumptionData['balance_consumed'] ?? 0), 2), // 余额消费 - 'wechat_consumed' => round(floatval($consumptionData['wechat_consumed'] ?? 0), 2), // 微信支付消费 - 'total_consumed' => round(floatval(($consumptionData['balance_consumed'] ?? 0) + ($consumptionData['wechat_consumed'] ?? 0)), 2) // 总消费 + // 查询用户在指定时间范围内的订单 + $query = Order::where('user_id', '=', $user_id) + ->where('status', '=', 1); + + // 添加时间范围条件 + if ($start_time) { + $query->where('addtime', '>=', $start_time); + } + + if ($end_time) { + $query->where('addtime', '<=', $end_time); + } + + // 计算总消费金额 + $total_consumed = $query->sum('price'); + + // 获取订单数量 + $order_count = $query->count(); + + return [ + 'total_consumed' => $total_consumed, + 'order_count' => $order_count ]; - - return $result; } } \ No newline at end of file diff --git a/app/common/service/PaymentCalculator.php b/app/common/service/PaymentCalculator.php new file mode 100644 index 0000000..c035354 --- /dev/null +++ b/app/common/service/PaymentCalculator.php @@ -0,0 +1,329 @@ +where(['id' => $goods_id]) + ->find(); + + if (!$goods) { + return ['status' => 0, 'msg' => '盒子不存在']; + } + + if ($goods['status'] != 1) { + return ['status' => 0, 'msg' => '盒子已下架']; + } + } + + // 获取盒子类型 + $goods_type = $goods['type']; + + // 如果未传入扩展信息,则从数据库获取 + if (!$goodsExtend) { + $goodsExtend = GoodsExtend::getGoodsExtendByGoodsId($goods_id, $goods_type); + if (!$goodsExtend) { + return ['status' => 0, 'msg' => '盒子类型配置不存在']; + } + } + + // 处理图片URL + $goods['imgurl_detail'] = imageUrl($goods['imgurl_detail']); + + // 盒子单价 + $box_price = $goods['price']; + + // 首抽五折处理 + $shou_zhe_price = 0; + if ($goods['type'] != 5 && $goods_type != 10 && $goods_type != 15) { + $is_chou = Order::field('id')->where([['user_id', '=', $user['id']], ['status', '=', 1]])->find(); + $is_chou2 = Order::field('id')->where([['is_shou_zhe', '=', 1], ['status', '=', 1], ['user_id', '=', $user['id']]])->find(); + if (!$is_chou && !$is_chou2 && $goods['is_shou_zhe'] == 1) { + $shou_zhe_price = bcmul("$box_price", "0.5", 2); + } + } + + // 计算总价 + $goods['shou_zhe_price'] = $shou_zhe_price; + $price = bcmul("$box_price", "$prize_num", 2); + $price = bcsub("$price", "$shou_zhe_price", 2); + + // 订单金额 + $order_total = $order_zhe_total = $price; + + // 初始化变量 + $coupon_price = 0; + $use_money = 0; // 余额抵扣 + $use_integral = 0; // 货币1抵扣 + $use_money2 = 0; // 货币2抵扣 + $zhe = 0; // 会员折扣 + + // 优惠券处理 + if ($shou_zhe_price <= 0 && !empty($coupon_id) && $goodsExtend['pay_coupon'] == 1) { + // 获取优惠券信息 + $coupon = CouponReceiveModel::where([ + 'id' => $coupon_id, + 'status' => 0, + 'user_id' => $user['id'] + ])->where('man_price', '<=', $price) + ->where('end_time', '>', time()) // 确保优惠券未过期 + ->find(); + + if ($coupon) { + $coupon_price = $coupon['price']; + } else { + $coupon_id = 0; + } + } else { + $coupon_id = 0; + } + + $price = bcsub("$price", "$coupon_price", 2); + if ($price <= 0) { + $price = 0; + } + $order_zhe_total = $price; + + // 如果不是首抽五折,处理各种支付抵扣 + if ($shou_zhe_price <= 0) { + $iszhifu = 0; + + // 余额抵扣 + if ($use_money_is == 1 && $goodsExtend['pay_balance'] == 1) { + if ($goodsExtend['is_deduction'] == 1) { + // 抵扣模式 + if ($user['money'] >= $price) { + $use_money = $price; + $price = 0; + } else { + $use_money = $user['money']; + $price = bcsub("$price", "$use_money", 2); + } + } else { + // 支付模式 + if ($user['money'] >= $price) { + $use_money = $price; + $price = 0; + $iszhifu++; + } else { + // 支付模式下余额不足无法抵扣 + $use_money = 0; + return ['status' => 0, 'msg' => '金额不足']; + } + } + } + + // 货币1抵扣 + if ($use_integral_is == 1 && $goodsExtend['pay_currency'] == 1) { + $price_in_currency = $price * 100; // 1:100比例 + if ($goodsExtend['is_deduction'] == 1) { + // 抵扣模式 + if ($user['integral'] >= $price_in_currency) { + $use_integral = $price_in_currency; + $price = 0; + } else { + $use_integral = $user['integral']; + $price = bcsub("$price", bcdiv("$use_integral", "100", 2), 2); + } + } else { + // 支付模式 + if ($user['integral'] >= $price_in_currency) { + $use_integral = $price_in_currency; + $price = 0; + $iszhifu++; + } else { + // 支付模式下货币不足无法抵扣 + $use_integral = 0; + return ['status' => 0, 'msg' => '金额不足']; + } + } + } + + // 货币2抵扣 + if ($use_money2_is == 1 && $goodsExtend['pay_currency2'] == 1) { + $price_in_currency2 = $price * 100; // 1:100比例 + if ($goodsExtend['is_deduction'] == 1) { + // 抵扣模式 + if (isset($user['money2']) && $user['money2'] >= $price_in_currency2) { + $use_money2 = $price_in_currency2; + $price = 0; + } else if (isset($user['money2'])) { + $use_money2 = $user['money2']; + $price = bcsub("$price", bcdiv("$use_money2", "100", 2), 2); + } + } else { + // 支付模式 + if (isset($user['money2']) && $user['money2'] >= $price_in_currency2) { + $use_money2 = $price_in_currency2; + $price = 0; + $iszhifu++; + } else { + // 支付模式下货币2不足无法抵扣 + $use_money2 = 0; + return ['status' => 0, 'msg' => '金额不足']; + } + } + } + + // 如果是支付模式但未选择任何支付方式 + if ($goodsExtend['is_deduction'] == 0 && $iszhifu == 0 && $goodsExtend['pay_wechat'] == 0) { + return ['status' => 0, 'msg' => '请选择支付方式']; + } + } + + // 设置抽奖数量 + $goods['prize_num'] = $prize_num; + + // 组装返回数据 + $data = [ + 'status' => 1, + 'goods' => $goods, + 'order_total' => round(floatval($order_total), 2), + 'order_zhe_total' => round($order_zhe_total, 2), + 'zhe' => round($zhe, 2), + 'price' => round($price, 2), + 'integral' => round($user['integral'], 2), + 'use_integral' => round($use_integral, 2), + 'use_integral_money' => round(round($use_integral, 2) / 100, 2), + 'money' => round($user['money'], 2), + 'use_money' => round($use_money, 2), + 'score' => isset($user['money2']) ? $user['money2'] : 0, + 'use_score' => $use_money2, + 'coupon_id' => $coupon_id, + 'coupon_price' => round($coupon_price, 2), + 'goods_extend' => $goodsExtend, + 'use_money2' => $use_money2 + ]; + + // 添加首抽五折状态 + $data['is_shou_zhe'] = $shou_zhe_price > 0 ? 1 : 0; + + return $data; + } + + /** + * 验证抽奖限制 + * + * @param array $user 用户信息 + * @param array $goods 盒子信息 + * @param int $prize_num 抽奖数量 + * @return array 验证结果 ['status' => 0/1, 'msg' => '提示信息'] + */ + public function validateDrawRestrictions($user, $goods, $prize_num) + { + // 验证抽奖门槛 + $user_id = $user['id']; + $choujiang_xianzhi = $goods['choujiang_xianzhi']; + + if ($choujiang_xianzhi && $choujiang_xianzhi > 0) { + // 验证福利屋活动 + if ($goods['type'] == 15) { + // 获取用户在该福利屋活动期间的消费情况 + $consumptionData = \app\common\service\CommonService::getUserConsumptionByTimeRange( + $user_id, + $goods['flw_start_time'], + $goods['flw_end_time'] + ); + + if ($consumptionData['total_consumed'] < $choujiang_xianzhi) { + return [ + 'status' => 0, + 'msg' => "需在指定时间" . date('Y-m-d H:i:s', $goods['flw_start_time']) . "-" + . date('Y-m-d H:i:s', $goods['flw_end_time']) . "消耗达到" . $choujiang_xianzhi + . "钻石,即可加入房间,还需" . round(($choujiang_xianzhi - $consumptionData['total_consumed']), 2) . "钻石." + ]; + } + } else { + // 常规消费验证 + $user_price = Order::where('user_id', '=', $user_id)->where('status', '=', 1)->sum('price'); + + if ($user_price < $choujiang_xianzhi) { + if ($user['istest'] > 0) { + $user_price = Order::where('user_id', '=', $user_id)->where('status', '=', 1)->sum('order_zhe_total'); + } + + if ($user_price < $choujiang_xianzhi) { + return [ + 'status' => 0, + 'msg' => "消费满" . $choujiang_xianzhi . "元可参与 已消费" . round($user_price, 2) . "元" + ]; + } + } + } + } + + // 验证全局限购 + if ($goods['quanju_xiangou'] > 0) { + $user_quanju_count = \app\common\model\OrderList::field('id') + ->where('goods_id', '=', $goods['id']) + ->where('user_id', '=', $user_id) + ->where('parent_goods_list_id', '=', 0) + ->count(); + + if ($user_quanju_count >= $goods['quanju_xiangou']) { + return ['status' => 0, 'msg' => '当前限购' . $goods['quanju_xiangou'] . '次']; + } + + $now_prize_num = $prize_num + $user_quanju_count; + if ($now_prize_num > $goods['quanju_xiangou']) { + return [ + 'status' => 0, + 'msg' => '购买超出限制,还允许购买' . ($goods['quanju_xiangou'] - $user_quanju_count) . '次' + ]; + } + } + + // 验证每日限购 + if ($goods['daily_xiangou'] > 0) { + $todayMidnight = strtotime('today'); + $user_toDay_count = \app\common\model\OrderList::field('id') + ->where('goods_id', '=', $goods['id']) + ->where('user_id', '=', $user_id) + ->where('parent_goods_list_id', '=', 0) + ->where('addtime', '>=', $todayMidnight) + ->count(); + + if ($user_toDay_count >= $goods['daily_xiangou']) { + return ['status' => 0, 'msg' => '今日限购' . $goods['daily_xiangou'] . '次']; + } + + $now_prize_num = $prize_num + $user_toDay_count; + if ($now_prize_num > $goods['daily_xiangou']) { + return [ + 'status' => 0, + 'msg' => '购买超出限制,今日还允许购买' . ($goods['daily_xiangou'] - $user_toDay_count) . '次' + ]; + } + } + + return ['status' => 1, 'msg' => '验证通过']; + } +} \ No newline at end of file