manghe/app/api/controller/Goods.php
2025-05-04 16:54:54 +08:00

1530 lines
58 KiB
PHP
Executable File
Raw 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
declare(strict_types=1);
namespace app\api\controller;
use app\api\controller\Base;
use app\common\model\Goods as Goodsmodel;
use app\common\model\GoodsLock;
use app\common\model\GoodsList;
use app\common\model\Collect;
use app\common\model\Shang;
use app\common\model\User;
use app\common\model\Order;
use app\common\model\OrderList;
use app\common\model\UserVip;
use app\common\service\GoodsService;
use think\facade\Db;
use \think\Request;
use app\common\model\CouponReceive as CouponReceiveModel;
use app\common\model\UserCoupon;
use app\common\model\GoodsType;
use app\common\service\CommonService;
use app\common\model\GoodsExtend;
use think\Collection;
class Goods extends Base
{
static $page_size = 10;
static $shang_prize_id = [10, 33];#抽奖赏品id
static $shang_count_id = [10, 38];#统计次数
// static $shang_give_arr = [
// 1 => '上半场随机获得',
// 2 => '下半场随机获得',
// 3 => '最后一发获得',
// 4 => '全场随机获得',
// 5 => '获取指定数量全局赏获得',
// ];#赠送(FIRST赏 LAST赏 最终赏 全局赏 拳王赏)赏品id
static $shang_give_arr = [
1 => '只赠不售',
2 => '只赠不售',
3 => '只赠不售',
4 => '只赠不售',
5 => '只赠不售',
];#赠送(FIRST赏 LAST赏 最终赏 全局赏 拳王赏)赏品id
/**
* 首页盒子列表
* @param Request $request
* @param [type] 类型 (14)推荐 (1)一番赏 (2)积分赏 (3)擂台赏
* @return \think\response\Json
* @throws \think\db\exception\DbException
* created by Admin at 2022/12/7 15:49
*/
public function goods(Request $request)
{
$type_str = request()->param('type', -1);
$user_id = $this->getUserId();
$page = request()->param('page', 1);
// 获取Redis实例并检查缓存
$redis = (new \app\common\server\RedisHelper())->getRedis();
$cache_key = "goods_list_{$type_str}_{$user_id}_{$page}";
$cache_data = $redis->get($cache_key);
// 如果缓存存在,直接返回缓存数据
if ($cache_data) {
$cached_data = json_decode($cache_data, true);
// 在返回缓存数据前,更新参与次数
if (!empty($cached_data['data'])) {
$redis = (new \app\common\server\RedisHelper())->getRedis();
foreach ($cached_data['data'] as &$item) {
// 读取商品参与次数缓存
$goods_id = $item['id'];
$cacheKey = "order_goods_count:{$goods_id}";
$join_count = $redis->get($cacheKey);
// 如果参与次数缓存存在,更新数据
if ($join_count !== false) {
$item['join_count'] = intval($join_count);
}
}
}
return $this->renderSuccess('请求成功', $cached_data);
}
$whe = [];
$whe[] = ['status', '=', 1];
$whe[] = ['show_is', '=', 0];
$paginate = 15;
// 1一番赏 2无限赏 3擂台赏 4抽卡机 5积分赏 6全局赏 7福利盲盒 8领主赏 9连击赏 10 商品赏
// 使用映射数组简化类型条件判断
$typeMapping = [
1 => ['type' => 1],
2 => ['type' => 2],
3 => ['type' => 3],
5 => ['type' => 5],
6 => ['type' => 6],
7 => ['type' => 7],
8 => ['type' => 8],
9 => ['type' => 'in', 'value' => [9]],
10 => ['type' => 10, 'paginate' => 999],
11 => ['type' => 11],
12 => ['type' => 12],
15 => ['type' => 15],
16 => ['type' => 16],
];
if (isset($typeMapping[$type_str])) {
if (isset($typeMapping[$type_str]['paginate'])) {
$paginate = $typeMapping[$type_str]['paginate'];
}
if (isset($typeMapping[$type_str]['type']) && $typeMapping[$type_str]['type'] === 'in') {
$whe[] = ['type', 'in', $typeMapping[$type_str]['value']];
} else {
$whe[] = ['type', '=', $typeMapping[$type_str]['type']];
}
} else {
$whe[] = ['type', 'in', [2, 6, 8, 16]];
}
if ($user_id == 0) {
//充值金额
$whe[] = ['unlock_amount', '=', 0];
} else {
// $isTest = \app\common\helper\ConfigHelper::getSystemTestKey("enable_test");
// if ($isTest == "1") {
// $order_money = Order::where('status', '=', 1)->where('user_id', '=', $user_id)->sum('order_zhe_total');
// } else {
// $order_money = Order::where('status', '=', 1)->where('user_id', '=', $user_id)->sum('price');
// }
$order_money = Order::where('status', '=', 1)->where('user_id', '=', $user_id)->sum('price');
// $order_money = Order::where('status', '=', 1)->where('user_id', '=', $user_id)->sum('price');
$userInfo = User::where('id', '=', $user_id)->field('istest')->find();
if ($userInfo && $userInfo['istest'] > 0) {
//推广账号,门槛计算是全部的
$order_money = Order::where('status', '=', 1)->where('user_id', '=', $user_id)->sum('order_zhe_total');
}
$whe[] = ['unlock_amount', '<=', $order_money];
}
//将goods_type表中的所有数据查询出来查询字段value,corner_text,将数组转换为map
$goods_types_arr = GoodsType::field('value,corner_text')->select()->toArray();
$goods_types_map = [];
foreach ($goods_types_arr as $goods_type) {
$goods_types_map[$goods_type['value']] = $goods_type['corner_text'];
}
#盒子
$goods = GoodsModel::where($whe)
->field("id,title,imgurl,price,type,stock,sale_stock,status,lock_is,is_shou_zhe,new_is")
->order("sort desc,id desc")
->paginate($paginate);
// 获取所有商品项
$goodsItems = $goods->items();
// 如果没有商品,直接返回
if (empty($goodsItems)) {
$new_data = [
'data' => [],
'last_page' => $goods->lastPage(),
];
// 缓存空结果,避免重复查询
$redis->set($cache_key, json_encode($new_data), 10);
return $this->renderSuccess('请求成功', $new_data);
}
// 获取所有商品ID和类型
$goodsIds = [];
$goodsTypes = [];
$type10GoodsIds = [];
foreach ($goodsItems as $item) {
$goodsIds[] = $item['id'];
$goodsTypes[$item['id']] = $item['type'];
// 记录type=10的商品ID
if ($item['type'] == 10) {
$type10GoodsIds[] = $item['id'];
}
}
// 批量查询所有商品的参与次数
// 移除外部查询使用Redis缓存在循环中查询每个商品的参与次数
$redis = (new \app\common\server\RedisHelper())->getRedis();
// 批量查询type=10的商品库存
$goodslistMap = [];
if (!empty($type10GoodsIds)) {
$goodslists = GoodsList::field('goods_id, sum(`stock`) as stock, sum(`surplus_stock`) as surplus_stock')
->where('goods_id', 'in', $type10GoodsIds)
->where('num', '=', 1)
->where('shang_id', 'between', self::$shang_prize_id)
->group('goods_id')
->select()
->toArray();
foreach ($goodslists as $goodslist) {
$goodslistMap[$goodslist['goods_id']] = [
'stock' => intval($goodslist['stock']),
'surplus_stock' => intval($goodslist['surplus_stock'])
];
}
}
// 处理所有商品数据
foreach ($goodsItems as &$item) {
$item['imgurl'] = imageUrl($item['imgurl']);
// 计算剩余库存
$item['sale_stock'] = $item['stock'] - $item['sale_stock'];
// 处理type=10的商品
if ($item['type'] == 10 && isset($goodslistMap[$item['id']])) {
$goodslistData = $goodslistMap[$item['id']];
$item['sale_stock'] = $goodslistData['surplus_stock'];
$item['stock'] = $goodslistData['stock'];
}
// 使用Redis缓存获取参与次数
$goods_id = $item['id'];
$cacheKey = "order_goods_count:{$goods_id}";
$join_count = $redis->get($cacheKey);
// 缓存未命中,从数据库获取并缓存
if ($join_count === false) {
$join_count = OrderList::field('id')
->where('goods_id', '=', $goods_id)
->where('num', '=', $item['num'])
->where('shang_id', 'between', self::$shang_count_id)
->where('order_type', '=', $item['type'])
->count();
// 设置缓存5分钟过期
$redis->set($cacheKey, $join_count, 300);
} else {
// 转为整数
$join_count = intval($join_count);
}
// 设置参与次数
$item['join_count'] = $join_count;
// 设置需要抽奖的数量
$item['need_draw_num'] = $item['type'] == 7 ? 1 : 0;
// 设置角标文字,合并之前的第二个循环逻辑
if (isset($goods_types_map[$item['type']])) {
$item['type_text'] = $goods_types_map[$item['type']];
}
}
// 将处理后的数据设置回分页对象
$goods->setCollection(new Collection($goodsItems));
$new_data = [
'data' => $goods->items(),
'last_page' => $goods->lastPage(),
];
// 将结果缓存到Redis设置过期时间为30秒30秒
$redis->set($cache_key, json_encode($new_data), 10);
return $this->renderSuccess('请求成功', $new_data);
}
/**
* 商品详情
* @param $goods_id 盒子id
* @param $goods_num 盒子箱号
*/
public function goodsdetail()
{
$user_id = $this->getUserId();
$goods_id = request()->param('goods_id/d', 0);
$goods_num = request()->param('goods_num/d', 0);
$goods = Goodsmodel::field('id,title,imgurl_detail,price,stock,sale_stock,lock_is,type,status,sale_time,is_shou_zhe,quanju_xiangou,daily_xiangou,quanju_xiangou')
->where(['id' => $goods_id])
->find();
if (!$goods) {
return $this->renderError("盒子不存在");
}
if ($goods['status'] != 1 && $goods['status'] != 3) {
return $this->renderError("盒子已下架");
}
if (($goods_num > $goods['stock']) || ($goods_num < 0)) {
return $this->renderError("箱号错误");
}
if ($goods['sale_time']) {
$goods['addtime'] = date('m-d', $goods['sale_time']);
} else {
$goods['addtime'] = '';
}
$goods['imgurl_detail'] = imageUrl($goods['imgurl_detail']);
#自动找箱号
if ($goods_num == 0) {
#奖品信息
$goodslist_info = GoodsList::field('num,sum(`surplus_stock`) as all_surplus_stock')
->where(['goods_id' => $goods_id])
->where('shang_id', '>', 5)//[1, 2, 3, 4, 5]
->where('goods_list_id', '=', 0)
->having('all_surplus_stock', '>', 0)
->group('num')
->order('num asc')
->find();
if ($goodslist_info) {
$goods_num = $goodslist_info['num'];
} else {
$goods_num = 1;
}
}
$goods['num'] = $goods_num;
$collection_is = 0;
$goods_type = GoodsType::field('corner_text')->where('value', '=', $goods['type'])->find();
if ($goods_type) {
$goods['type_text'] = $goods_type['corner_text'];
}
#本箱子余量
$goods_surplus = GoodsList::field('sum(`stock`) as stock, sum(`surplus_stock`) as surplus_stock')
->where('goods_id', '=', $goods_id)
->where('num', '=', $goods_num)
->where('goods_list_id', '=', 0)
->where('shang_id', 'between', self::$shang_prize_id)
->find();
$all_surplus_stock = $goods_surplus['surplus_stock'];
$goods['surplus_stock'] = $goods['stock'] - $goods['sale_stock'];
$goods['goodslist_stock'] = $goods_surplus['stock'];
$goods['goodslist_surplus_stock'] = $goods_surplus['surplus_stock'];
#概率不足时
$pro_all = 0;
$pro_max = 0;
$pro_key = 0;
#所有奖品信息
$goodslist = GoodsList::field('id,shang_id,title,stock,surplus_stock,imgurl,goods_type,sale_time,price,sc_money')
->append(['shang_info'])
->where(['goods_id' => $goods_id])
->where(['num' => $goods_num])
->where('goods_list_id', '=', 0)
->order('sort desc,shang_id asc,id asc')
->select()->toArray();
foreach ($goodslist as $key => &$value) {
#价格
$value['price'] = $value['price'] * 1;
#预售时间
if ($value['sale_time']) {
$value['sale_time'] = date('Y-m-d', $value['sale_time']);
}
#剩余
$surplus_stock = $value['surplus_stock'];
if (array_key_exists($value['shang_id'], self::$shang_give_arr)) {
#概率
$pro = self::$shang_give_arr[$value['shang_id']];
$pro_num = 0;
} else {
#概率
if ($surplus_stock > 0) {
$pro_basics = bcdiv("$surplus_stock", "$all_surplus_stock", 4);
$pro = '概率:' . removeTrailingZeros(($pro_basics * 100)) . '%';
$pro_num = removeTrailingZeros(($pro_basics * 100));
} else {
$pro = '概率:' . 0 . '%';
$pro_num = 0;
}
}
$value['surplus_stock'] = $surplus_stock;
$value['pro'] = $pro;
$value['imgurl'] = imageUrl($value['imgurl']);
#计算剩余概率
$pro_all += $pro_num;
if ($pro_num >= $pro_max) {
$pro_max = $pro_num;
$pro_key = $key;
}
if ($value['goods_type'] == 4) {
//表示有子奖品
$value['children'] = true;
} else {
$value['children'] = false;
}
}
#概率不足时
if ($pro_max > 0 && $pro_all < 100) {
$surplus_pro = bcsub("100", "$pro_all", 2);
$goodslist[$pro_key]['pro'] = '概率:' . bcadd("$pro_max", "$surplus_pro", 2) . '%';
}
#锁箱信息===============
$goods_lock_user_nickname = 0;
$goods_lock_user_headimg = 0;
$goods_lock_surplus_time = 0;
$goods_id_num = $goods_id . '_' . $goods_num;
$goods_lock_info = GoodsLock::where(['goods_id_num' => $goods_id_num])
->where('endtime', '>', time())
->order('id desc')
->find();
if ($goods['lock_is'] && $goods_lock_info) {
$goods_lock_surplus_time = $goods_lock_info['endtime'];
$user_info_lock = User::field('nickname,headimg')->where(['id' => $goods_lock_info['user_id']])->find();
$goods_lock_user_nickname = $user_info_lock['nickname'];
$goods_lock_user_headimg = imageUrl($user_info_lock['headimg']);
}
$lock_info = [
'lock_is' => $goods['lock_is'],
'goods_lock_user_nickname' => $goods_lock_user_nickname,
'goods_lock_user_headimg' => $goods_lock_user_headimg,
'goods_lock_surplus_time' => $goods_lock_surplus_time,
];
#锁箱信息===============
#参与人数
$join_user = OrderList::field('user_id')
->append(['userinfo'])
->where('goods_id', '=', $goods_id)
->where('num', '=', $goods_num)
->where('shang_id', 'between', self::$shang_count_id)
->where('order_type', '=', $goods['type'])
->order('id desc')
->group('user_id')
->limit(5)
->select();
$new_join_user = [];
foreach ($join_user as $join_user_value) {
$new_join_user[] = $join_user_value['userinfo']['headimg'];
}
#参与次数
$redis = (new \app\common\server\RedisHelper())->getRedis();
$cacheKey = "order_goods_count:{$goods_id}";
$join_count = $redis->get($cacheKey);
// 缓存未命中,从数据库获取并缓存
if ($join_count === false) {
$join_count = OrderList::field('id')
->where('goods_id', '=', $goods_id)
->where('num', '=', $goods_num)
->where('shang_id', 'between', self::$shang_count_id)
->where('order_type', '=', $goods['type'])
->count();
// 设置缓存5分钟过期
$redis->set($cacheKey, $join_count, 300);
} else {
// 转为整数
$join_count = intval($join_count);
}
#时间配置
$config = getConfig('base');
$goods['three_time'] = $config['three_time'];
$goods['five_time'] = $config['five_time'];
$goodsService = new GoodsService();
$limitInfo = $goodsService->getPurchaseLimitInfo($user_id, $goods_num, $goods, self::$shang_count_id);
if ($user_id > 0) {
#是否收藏
$collection_is = Collect::field('id')
->where(['user_id' => $user_id])
->where(['goods_id' => $goods_id])
->where(['num' => $goods_num])
->find();
$goods['collection_is'] = $collection_is ? 1 : 0;
}
$new_data = [
'goods' => $goods,
'lock_info' => $lock_info,
'join_user' => $new_join_user,
'join_count' => $join_count,
'goodslist' => $goodslist,
'limitInfo' => $limitInfo
];
return $this->renderSuccess("请求成功", $new_data);
}
/**
* 获取商品子奖品信息
* @param $goods_id 盒子id
* @param $goods_num 盒子箱号
* @param $goods_list_id 父奖品ID
*/
public function getGoodsChildren()
{
$goods_id = request()->param('goods_id/d', 0);
$goods_num = request()->param('goods_num/d', 0);
$goods_list_id = request()->param('goods_list_id/d', 0);
if (!$goods_list_id) {
return $this->renderError("对应的宝箱ID不能为空");
}
#盒子信息
$goods = Goodsmodel::field('id,title,status')
->where(['id' => $goods_id])
->find();
if (!$goods) {
return $this->renderError("盒子不存在");
}
if ($goods['status'] != 1 && $goods['status'] != 3) {
return $this->renderError("盒子已下架");
}
#所有奖品信息
$goodslist_1 = GoodsList::field('id,shang_id,title,stock,surplus_stock,imgurl,goods_type,sale_time,price,real_pro,sc_money')
->append(['shang_info'])
->where(['goods_id' => $goods_id])
->where(['num' => $goods_num])
->where('goods_list_id', '=', $goods_list_id)
->order('sort desc,shang_id asc,id asc')
->select()->toArray();
if ($goodslist_1) {
//过滤数组将数组中的shang_id 等于 shang_give_arr 的全部过滤掉。然后在将数组中的surplus_stock求和
$goodslist_1_1 = array_filter($goodslist_1, function ($item) {
return !array_key_exists($item['shang_id'], self::$shang_give_arr);
});
//将数组中的surplus_stock求和
$goodsList_surplus_stock = array_sum(array_column($goodslist_1_1, 'surplus_stock'));
foreach ($goodslist_1 as $key_1 => &$value_1) {
$value_1['imgurl'] = imageUrl($value_1['imgurl']);
if ($value_1['shang_id'] == 38) {
unset($value_1['shang_info']);
}
if ($value_1['stock'] == 0) {
//保留两位小数
$value_1['pro'] = '概率:' . removeTrailingZeros(round($value_1['real_pro'], 2)) . '%';
$value_1['pro_num'] = removeTrailingZeros(round($value_1['real_pro'], 2));
unset($value_1['surplus_stock']);
unset($value_1['stock']);
continue;
}
$surplus_stock_1 = $value_1['surplus_stock'];
$pro_num_1 = 0;
$pro_1 = 0;
if (array_key_exists($value_1['shang_id'], self::$shang_give_arr)) {
#概率
$pro_1 = self::$shang_give_arr[$value_1['shang_id']];
$pro_num_1 = 0;
} else {
#概率
if ($surplus_stock_1 > 0) {
//计算概率,保留两位小数
$pro_num_1 = removeTrailingZeros(round(($surplus_stock_1 / $goodsList_surplus_stock) * 100, 2));
$pro_1 = '概率:' . $pro_num_1 . '%';
} else {
$pro_1 = '概率:' . 0 . '%';
$pro_num_1 = 0;
}
}
$value_1['pro'] = $pro_1;
$value_1['pro_num'] = $pro_num_1;
}
}
return $this->renderSuccess("请求成功", $goodslist_1);
}
/**
* 获取商品扩展信息
*/
public function getGoodExtend()
{
$goods_id = request()->param('goods_id/d', 0);
$goods_type = request()->param('goods_type/d', 0);
$goods_extend = GoodsExtend::where('goods_id', $goods_id)->find();
if (!$goods_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) {
// 如果找到了盒子类型的默认配置
$goods_extend = [
'goods_id' => $goods_id,
'pay_wechat' => $goodsType['pay_wechat'],
'pay_balance' => $goodsType['pay_balance'],
'pay_currency' => $goodsType['pay_currency'],
'pay_currency2' => $goodsType['pay_currency2'],
'pay_coupon' => $goodsType['pay_coupon'],
'is_deduction' => $goodsType['is_deduction']
];
}
}
return $this->renderSuccess("请求成功", $goods_extend);
}
/**
* 换箱箱号
*/
public function goodslist_count()
{
$goods_id = request()->param('goods_id/d', 0);
#盒子信息
$goods = Goodsmodel::field('id,stock,status')
->where(['id' => $goods_id])
->find();
if (!$goods) {
return $this->renderError("盒子不存在");
}
if ($goods['status'] != 1 && $goods['status'] != 3) {
return $this->renderError("盒子已下架");
}
$page_size = self::$page_size;
$length = ceil($goods['stock'] / $page_size);
$data = [];
for ($i = 0; $i < $length; $i++) {
$start_length = ($i * $page_size) + 1;
$end_length = ($i * $page_size) + $page_size;
if ($end_length >= $goods['stock']) {
$end_length = $goods['stock'];
}
$data[] = [
'title' => $start_length . '-' . $end_length,
'page_no' => $i,
];
}
return $this->renderSuccess("请求成功", $data);
}
/**
* 统计多少箱
*/
public function goodslist_content(Request $request)
{
$sort = request()->param('sort/d', 0);#排序1箱号高 2余量高
$goods_id = request()->param('goods_id/d', 0);
$page_no = request()->param('page_no/d', 0);#页码
if ($page_no <= 0) {
$page_no = 0;
}
#盒子信息
$goods = Goodsmodel::field('id,stock,status')
->where(['id' => $goods_id])
->find();
if (!$goods) {
return $this->renderError("盒子不存在");
}
if ($goods['status'] != 1 && $goods['status'] != 3) {
return $this->renderError("盒子已下架");
}
$page_size = self::$page_size;
$start_length = ($page_no * $page_size) + 1;
$end_length = ($page_no * $page_size) + $page_size;
if ($end_length >= $goods['stock']) {
$end_length = $goods['stock'];
}
$data = [];
for ($goods_num = $start_length; $goods_num <= $end_length; $goods_num++) {
#奖品信息
$goodlist = GoodsList::field('id,stock,surplus_stock,shang_id')
->append(['shang_info'])
->where(['goods_id' => $goods_id])
->where(['num' => $goods_num])
->order('sort desc,shang_id asc,id asc')
->select();
#剩余
$surplus_all_stock = 0;
foreach ($goodlist as $key => $value) {
if (!array_key_exists($value['shang_id'], self::$shang_give_arr)) {
$surplus_all_stock += $value['surplus_stock'];
}
unset($value['id']);
}
if ($surplus_all_stock <= 0) {
$surplus_all_stock = 0;
}
$data[] = [
'num' => $goods_num,
'surplus_all_stock' => $surplus_all_stock,
'goodslist' => $goodlist,
];
}
if ($sort == 2) {
$data = arraySequence($data, 'surplus_all_stock');
}
return $this->renderSuccess("请求成功", $data);
}
/**
* 中赏记录
*/
public function shang_log(Request $request)
{
$shang_id = request()->param('shang_id/d', 0);
$goods_id = request()->param('goods_id/d', 0);
$goods_num = request()->param('goods_num/d', 0);
#盒子信息
$goods = Goodsmodel::field('id,stock,status,type')
->where(['id' => $goods_id])
->find();
if (!$goods) {
return $this->renderError("盒子不存在");
}
if ($goods['status'] != 1 && $goods['status'] != 3) {
return $this->renderError("盒子已下架");
}
if (RegInt($goods_num)) {
return $this->renderError("箱号选择错误");
}
#中奖记录分类
$category = GoodsList::field('shang_id')
->append(['shang_title'])
->where('goods_id', '=', $goods_id)
->where('num', '=', $goods_num)
->group('shang_id')
->select()->toArray();
array_unshift($category, ['shang_id' => 0, 'shang_title' => '全部']);
$where = [];
if ($shang_id) {
$where[] = ['shang_id', '=', $shang_id];
}
$data = OrderList::field('user_id,goodslist_title,goodslist_imgurl,shang_id,addtime,count(`id`) as prize_num')
->append(['shang_title', 'user_info', 'shang_color'])
->where('goods_id', '=', $goods_id)
->where('num', '=', $goods_num)
->where('order_type', '=', $goods['type'])
->where('source', '=', 1)
->where($where)
->order('id desc')
->group("order_id,goodslist_id,user_id")
->paginate(100)->each(function ($item) {
$item['user_info']['headimg'] = imageUrl($item['user_info']['headimg']);
$item['addtime'] = date('Y-m-d H:i:s', $item['addtime']);
$item['goodslist_imgurl'] = imageUrl($item['goodslist_imgurl']);
return $item;
});
// dd($data);
$new_data = [
'category' => $category,
'data' => $data->items(),
'last_page' => $data->lastPage(),
];
return $this->renderSuccess("请求成功", $new_data);
}
/**
* 下单计算金额
*/
public function ordermoney()
{
$user = $this->getUser();
$prize_num = request()->param('prize_num/d', 0); #抽几发
$goods_id = request()->param('goods_id/d', 0); #盒子ID
$num = request()->param('goods_num/d', 0); #第几箱
$use_money_is = request()->param('use_money_is/d', 0); #0不抵扣 1抵扣
$use_integral_is = request()->param('use_integral_is/d', 0); #0不抵扣 1抵扣
$use_money2_is = request()->param('use_money2_is/d', 0); #0不抵扣 1抵扣 货币2抵扣
$coupon_id = request()->param('coupon_id/d', 0); //优惠券
#盒子信息
$goods = Goodsmodel::field('id,title,imgurl_detail,type,price,status,is_shou_zhe,quanju_xiangou,lock_is,choujiang_xianzhi,lock_time,flw_start_time,flw_end_time,daily_xiangou')->where(['id' => $goods_id])
->find();
if (!$goods) {
return $this->renderError("盒子不存在");
}
if ($goods['status'] != 1) {
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']);
}
// 计算订单金额
$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']);
}
return $this->renderSuccess("请求成功", $result);
}
/**
* 创建订单
*/
public function orderbuy()
{
$ad_id = request()->header('adid');
$user = $this->getUser();
if (empty($user['mobile'])) {
return $this->renderError('请先绑定手机号', [], -9);
}
$prize_num = request()->param('prize_num/d', 0); #抽几发
$goods_id = request()->param('goods_id/d', 0); #盒子ID
$num = request()->param('goods_num/d', 0); #第几箱
$use_money_is = request()->param('use_money_is/d', 0); #0不抵扣 1抵扣 余额抵扣
$use_integral_is = request()->param('use_integral_is/d', 0); #0不抵扣 1抵扣 货币1抵扣
$use_money2_is = request()->param('use_money2_is/d', 0); #0不抵扣 1抵扣 货币2抵扣
$coupon_id = request()->param('coupon_id/d', 0); //优惠券
#盒子信息
$goods = Goodsmodel::field('*')->where(['id' => $goods_id])
->find();
if (!$goods) {
return $this->renderError("盒子不存在");
}
# 获取盒子类型配置
$goods_type = $goods['type'];
$goods_extend = GoodsExtend::getGoodsExtendByGoodsId($goods_id, $goods_type);
if (!$goods_extend) {
return $this->renderError("盒子类型配置不存在");
}
if ($goods['status'] != 1) {
return $this->renderError("盒子已下架");
}
$goods['imgurl_detail'] = imageUrl($goods['imgurl_detail']);
if (RegInt($num)) {
return $this->renderError("箱号选择错误");
}
// 使用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) {
#奖品信息
$is_goodslist = GoodsList::field('id')
->where('goods_id', '=', $goods_id)
->where('num', '=', $num)
->where('shang_id', 'between', self::$shang_prize_id)
->find();
if (!$is_goodslist) {
return $this->renderError('暂无奖品信息');
}
} else {
$num = 0;
}
#锁箱信息===============
if ($goods['type'] == 1 || $goods['type'] == 6 || $goods['type'] == 11) {
$goods_id_num = $goods_id . '_' . $num;
$lock_info = GoodsLock::where(['goods_id_num' => $goods_id_num])
->where('endtime', '>', time())
->order('id desc')
->find();
if ($lock_info && $lock_info['endtime'] > time() && $lock_info['user_id'] !== $user['id']) {
$surplus_time = $lock_info['endtime'] - time();
return $this->renderError('有会员正在锁箱,请等待' . $surplus_time . '秒');
}
}
#锁箱信息===============
#擂台赏限购===============
if ($goods['type'] == 3) {
$user_order_list = OrderList::field('id')
->where('goods_id', '=', $goods_id)
->where('user_id', $user['id'])
->where('num', '=', $num)
->where('order_type', '=', $goods['type'])
->where('shang_id', 'between', self::$shang_prize_id)
->find();
if ($user_order_list) {
return $this->renderError('限购一发');
}
}
#擂台赏限购===============
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();
$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("剩余数量不足,请刷新重试");
}
}
// 使用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']);
}
#一番赏锁箱
if ($goods['type'] == 1 || $goods['type'] == 6 || $goods['type'] == 11) {
#盒子id_箱号
$goods_id_num = $goods_id . '_' . $num;
#盒子是否配置锁箱
if ($goods['lock_is'] == 1 && $goods['lock_time'] > 0) {
$redis = (new \app\common\server\RedisHelper())->getRedis();
$redis_key = "kpw_lock" . '_' . $goods_id_num;
$redis_key_info = $redis->get($redis_key);
if ($redis_key_info) {
return $this->renderError("有会员正在锁箱,请等待");
} else {
$redis->set($redis_key, 1, 1);
}
#默认锁箱时间
$defaulttime = (time() + $goods['lock_time']);
#锁箱信息
$lock_info = GoodsLock::where('goods_id_num', '=', $goods_id_num)
->where('endtime', '>', time())
->order('id desc')
->find();
if ($lock_info) {#存在锁箱
if ($prize_num == 3 || $prize_num == 5) {
$config_time = getConfig('base');
if ($prize_num == 3) {
$endtime = $defaulttime + $config_time['three_time'];
} elseif ($prize_num == 5) {
$endtime = $defaulttime + $config_time['five_time'];
}
GoodsLock::where('id', '=', $lock_info['id'])
->update([
'endtime' => $endtime,
'update_time' => time(),
]);
} else {
GoodsLock::where('id', '=', $lock_info['id'])
->update([
'endtime' => $defaulttime,
'update_time' => time(),
]);
}
} else {
if ($prize_num == 3 || $prize_num == 5) {
$config_time = getConfig('base');
if ($prize_num == 3) {
$endtime = $defaulttime + $config_time['three_time'];
} elseif ($prize_num == 5) {
$endtime = $defaulttime + $config_time['five_time'];
}
#新增锁箱信息
GoodsLock::insert([
'user_id' => $user['id'],
'goods_id_num' => $goods_id_num,
'endtime' => $endtime,
'update_time' => time(),
]);
} else {
#新增锁箱信息
GoodsLock::insert([
'user_id' => $user['id'],
'goods_id_num' => $goods_id_num,
'endtime' => $defaulttime,
'update_time' => time(),
]);
}
}
}
}
#一番赏锁箱
$redis = (new \app\common\server\RedisHelper())->getRedis();
$redis_key = "kpw_orderbuy" . '_' . $user['id'];
$redis_key_info = $redis->get($redis_key);
if ($redis_key_info) {
return $this->renderError("当前操作太快了,请等待");
} else {
$redis->set($redis_key, 1, 2);
}
Db::startTrans();
#===================================================***********
#奖品信息加锁
GoodsList::field('id,stock,surplus_stock')
->where('goods_id', '=', $goods_id)
->where('num', '=', $num)
->lock(true)->select();
#奖品信息
if ($goods['type'] != 15) {
$goodslist_lock = GoodsList::field('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_lock['surplus_stock'] <= 0) {
Db::rollback();
$redis->del($redis_key);
return $this->renderError("已售空,请刷新重试");
}
}
#===================================================***********
if ($goods['quanju_xiangou'] > 0) {
// 查看一天内有没有未支付的订单,未支付的订单要先作废
Order::where('goods_id', '=', $goods_id)
->where('user_id', '=', $user['id'])
->where('status', '=', 0)
// ->where('addtime', '>=', time() - 86400)
// ->where('order_num', '!=', $order_num)
->update(['status' => 2]);
}
if ($goods['daily_xiangou'] > 0) {
// 查看一天内有没有未支付的订单,未支付的订单要先作废
Order::where('goods_id', '=', $goods_id)
->where('user_id', '=', $user['id'])
->where('status', '=', 0)
->where('addtime', '>=', time() - 86400)
// ->where('order_num', '!=', $order_num)
->update(['status' => 2]);
}
$attach = "";
if ($goods['type'] == 1) {
$attach = 'order_yfs';
} elseif ($goods['type'] == 3) {
$attach = 'order_lts';
} elseif ($goods['type'] == 5) {
$attach = 'order_jfs';
} elseif ($goods['type'] == 6) {
$attach = 'order_lts';
} elseif ($goods['type'] == 11) {
$attach = 'order_zzs';
} elseif ($goods['type'] == 10) {
$attach = 'order_scs';
} elseif ($goods['type'] == 15) {
$attach = 'order_flw';
} else {
$attach = 'order_qts';
}
$title = '购买盒子' . $goods['title'];
$payRes = \app\common\server\platform\PlatformFactory::createPay($user, $paymentResult['price'], $title, $attach, "MH_");
if ($payRes['status'] !== 1) {
Db::rollback();
#删除redis
$redis->del($redis_key);
return $this->renderError("购买失败,请刷新重试");
}
$order_num = $payRes['data']['order_no'];
$res = [];
#创建订单
$res[] = $order_id = Order::insertGetId([
'user_id' => $user['id'],
'order_num' => $order_num,
'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'],
'goods_title' => $goods['title'],
'goods_imgurl' => $goods['imgurl_detail'],
'prize_num' => $prize_num,
'status' => 0,
'pay_type' => 1,#1微信 2支付宝
'order_type' => $goods['type'],
'addtime' => time(),
'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 ($paymentResult['price'] > 0) {
if ($payRes['status'] == 1) {
#结果集
$new_data = [
'status' => 1,
'order_num' => $order_num,
'res' => $payRes['data']['res'],
];
} else {
Db::rollback();
#删除redis
$redis->del($redis_key);
return $this->renderError("下单失败");
}
} else {
try {
#开盒子
$res[] = (new Notify($this->app))->drawprize_notice($user['id'], $order_id, $goods_id, $num);
} catch (\Throwable $e) {
Db::rollback();
#删除redis
$redis->del($redis_key);
return $this->renderError("火爆中...请刷新重新购买");
}
#结果集
$new_data = [
'status' => 0,
'order_num' => $order_num,
];
}
if (resCheck($res)) {
Db::commit();
#删除redis
$redis->del($redis_key);
return $this->renderSuccess("下单成功", $new_data);
} else {
Db::rollback();
#删除redis
$redis->del($redis_key);
return $this->renderError("购买失败,请刷新重试");
}
}
/**
* 抽中的奖品
*/
public function prizeorderlog()
{
$user = $this->getUser();
$order_num = request()->param('order_num', '');
$order_info = Order::field('id,goods_id,num,order_type,prize_num')
->where('order_num', '=', $order_num)
->where('user_id', '=', $user['id'])
->find();
if (!$order_info) {
return $this->renderError("支付异常,请刷新重试");
}
$prize_num = $order_info['prize_num'] ?? 0;
$userCoupon = UserCoupon::field('id,level,title,num')
->where('user_id', '=', $user['id'])
->where('from_id', '=', $order_info['id'])
->order('level desc')
->find();
if ($userCoupon != null) {
//1特级赏券 2终极赏券 3高级赏券 4普通赏券
if ($userCoupon['level'] == 1) {
$userCoupon['level_text'] = '特级赏券';
$userCoupon['level_img'] = imageUrl('/storage/coupon/coupon_a.png');
} elseif ($userCoupon['level'] == 2) {
$userCoupon['level_text'] = '终极赏券';
$userCoupon['level_img'] = imageUrl('/storage/coupon/coupon_b.png');
} elseif ($userCoupon['level'] == 3) {
$userCoupon['level_text'] = '高级赏券';
$userCoupon['level_img'] = imageUrl('/storage/coupon/coupon_c.png');
} elseif ($userCoupon['level'] == 4) {
$userCoupon['level_text'] = '普通赏券';
$userCoupon['level_img'] = imageUrl('/storage/coupon/coupon_d.png');
}
}
#普通赏
$data = OrderList::field('id,user_id,shang_id,goodslist_id,goodslist_title,goodslist_imgurl,goodslist_money,count(id) as prize_num')
->append(['shang_title'])
->where('user_id', '=', $user['id'])
->where('order_id', '=', $order_info['id'])
->where('order_type', '=', $order_info['order_type'])
->order('shang_id asc, id asc')
->group('prize_code')
->paginate(100)->each(function ($item) {
$item['goodslist_imgurl'] = imageUrl($item['goodslist_imgurl']);
return $item;
});
//重抽卡数量
$item_card_count = Db::name('user_item_card')->where(['user_id' => $user['id'], 'status' => 1])->count();
$new_data = [
'data' => $data->items(),
'item_card_count' => $item_card_count,
'user_coupon' => $userCoupon,
'prize_num' => $prize_num
];
return $this->renderSuccess("请求成功", $new_data);
}
/**
* 收藏列表
*/
public function listCollect(Request $request)
{
//1一番赏 2无限赏 3擂台赏 4抽卡机 5积分赏 6全局赏 7福利盲盒 8领主赏 9连击赏
$user = $this->getUser();
$type = \request()->param('type', 0);
$data = Collect::field('id,goods_id,type,num')
->where(['user_id' => $user['id']])
->where('type', '=', $type)
->append(['goods_info'])
->paginate(100)->each(function ($item) {
$item['goods_title'] = $item['goods_info']['title'];
$item['goods_price'] = $item['goods_info']['price'];
$item['imgurl'] = imageUrl($item['goods_info']['imgurl']);
if (in_array($item['type'], [1, 3, 5, 6, 10, 11])) {
#库存
$surplus = GoodsList::field('sum(`stock`) as stock, sum(`surplus_stock`) as surplus_stock')
->where('goods_id', '=', $item['goods_id'])
->where('num', '=', $item['num'])
->where('shang_id', 'between', self::$shang_prize_id)
->find();
$item['stock'] = $surplus['stock'];
$item['surplus_stock'] = $surplus['surplus_stock'];
} else {
$item['stock'] = 0;
$item['surplus_stock'] = 0;
}
return $item;
});
$new_data = [
'data' => $data->items(),
'last_page' => $data->lastPage(),
];
return $this->renderSuccess("操作成功", $new_data);
}
/**
* 添加收藏
*/
public function addCollect(Request $request)
{
$user = $this->getUser();
$goods_id = request()->param('goods_id/d', 0);
$goods_num = request()->param('goods_num/d', 0);
#盒子信息
$goods = Goodsmodel::field('id,stock,status,type')
->where(['id' => $goods_id])
->find();
if (!$goods) {
return $this->renderError("盒子不存在");
}
if ($goods['status'] != 1 && $goods['status'] != 3) {
return $this->renderError("盒子已下架");
}
$info = Collect::field('id')
->where(['user_id' => $user['id']])
->where(['goods_id' => $goods_id])
->where(['num' => $goods_num])
->find();
if ($info) {
$res = Collect::where(['id' => $info['id']])->delete();
} else {
$res = Collect::insert([
'user_id' => $user['id'],
'goods_id' => $goods_id,
'num' => $goods_num,
'type' => $goods['type'],
'addtime' => time(),
]);
}
// 清除相关缓存
if ($res) {
$redis = (new \app\common\server\RedisHelper())->getRedis();
// 清除商品详情缓存
$redis->del("goods_detail_{$goods_id}_{$user['id']}");
// 清除无限抽盒子缓存(如果有)
$redis->del("infinite_goodsdetail_{$goods_id}_{$user['id']}");
return $this->renderSuccess("操作成功");
} else {
return $this->renderError("操作失败");
}
}
/**
* 删除收藏
*/
public function delCollect(Request $request)
{
$user = $this->getUser();
$id = request()->param('id/d', 0);
$info = Collect::field('id')
->where(['user_id' => $user['id']])
->where(['id' => $id])
->find();
if (!$info) {
return $this->renderError("请求重复操作");
}
$res = Collect::where(['id' => $info['id']])->delete();
if ($res) {
return $this->renderSuccess("删除成功");
} else {
return $this->renderError("删除失败");
}
}
/**
* 抽奖统计
* @param Request $request
*created by Admin at 2022/12/21 11:14
*/
public function luck_draw_log(Request $request)
{
$id = $request->param('id');
$goods = Goodsmodel::where('id', $id)->find();
if (!$goods) {
return $this->renderError("盒子不存在");
}
$user_ids = OrderList::field('user_id')
->append(['userinfo'])
->where('goods_id', $goods['id'])
->where('source', '=', 1)
->group('user_id')
->paginate(20);
foreach ($user_ids as $value) {
$count = OrderList::field('user_id')
->where('goods_id', $goods['id'])
->where('user_id', $value['user_id'])
->count();
$value['count'] = $count;
}
return $this->renderSuccess("操作成功", $user_ids);
}
/**
* 接收盒子同步数据
*/
public function receive_sync()
{
// 获取POST的JSON数据
$input = file_get_contents('php://input');
$data = json_decode($input, true);
if (!$data || !isset($data['goods']) || !isset($data['goodsList']) || !isset($data['async_code'])) {
return $this->renderError('无效的同步数据');
}
// 开始事务
Db::startTrans();
try {
$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();
// 准备商品数据
$goods = $goodsData;
if (isset($goods['id'])) {
unset($goods['id']);
}
$goods['status'] = 2;
if ($existingGoods) {
// 更新现有商品
$goodsId = $existingGoods->id;
// 更新商品数据
$goods['async_date'] = date('Y-m-d H:i:s');
$existingGoods->save($goods);
// 删除现有的商品列表数据
GoodsList::where('goods_id', $goodsId)->delete();
// 删除现有的扩展表数据
GoodsExtend::where('goods_id', $goodsId)->delete();
} else {
// 创建新商品
$goods['async_date'] = date('Y-m-d H:i:s');
$goods['addtime'] = time();
$goods['update_time'] = time();
$goods['king_user_id'] = 0;
$goodsModel = new Goodsmodel();
$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 = [];
$childItems = [];
// 将奖品分为父奖品和子奖品
foreach ($goodsListData as $listItem) {
if (empty($listItem['goods_list_id'])) {
$parentItems[] = $listItem;
} else {
$childItems[] = $listItem;
}
}
// 先处理父奖品
foreach ($parentItems as $listItem) {
$oldId = $listItem['id'];
$oldRewardId = isset($listItem['reward_id']) ? $listItem['reward_id'] : '';
// 处理商品列表项
if (isset($listItem['id'])) {
unset($listItem['id']);
}
$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();
$goodsListModel->save($listItem);
// 记录ID映射
$idMapping[$oldId] = $goodsListModel->id;
}
// 再处理子奖品
foreach ($childItems as $listItem) {
$originalParentId = $listItem['goods_list_id'];
$oldRewardId = isset($listItem['reward_id']) ? $listItem['reward_id'] : '';
// 处理商品列表项
if (isset($listItem['id'])) {
unset($listItem['id']);
}
$listItem['goods_id'] = $goodsId;
// 更新goods_list_id为目标系统中的ID
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();
return $this->renderSuccess('同步成功');
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
// 记录异常日志
\think\facade\Log::error('盒子同步数据异常:' . $e->getMessage() . "\n" . $e->getTraceAsString());
return $this->renderError('同步失败: ' . $e->getMessage());
}
}
}