428 lines
16 KiB
PHP
428 lines
16 KiB
PHP
<?php
|
|
|
|
namespace addon\futures\model;
|
|
use addon\fenxiao\model\FenxiaoAccount;
|
|
use addon\message\model\Message;
|
|
use app\model\member\MemberAccount;
|
|
use app\model\system\Config as ConfigModel;
|
|
use app\model\BaseModel;
|
|
use Psr\SimpleCache\InvalidArgumentException;
|
|
use think\facade\Cache;
|
|
use think\facade\Db;
|
|
|
|
class Futures extends BaseModel{
|
|
|
|
/**
|
|
* 获取列表
|
|
* @param array $condition
|
|
* @param int $page
|
|
* @param int $page_size
|
|
* @param string $order
|
|
* @param string $field
|
|
* @param string $alias
|
|
* @param array $join
|
|
* @return array
|
|
*/
|
|
public function getPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = 'a.*', $alias = 'a', $join = [])
|
|
{
|
|
$list = model('futures')->pageList($condition, $field, $order, $page, $page_size, $alias, $join);
|
|
return $this->success($list);
|
|
}
|
|
/**
|
|
* 详情
|
|
* @param $id
|
|
* @param $site_id
|
|
* @return array
|
|
*/
|
|
public function detail($id, $site_id){
|
|
$condition = [
|
|
['a.id', '=', $id],
|
|
['a.site_id','=',$site_id]
|
|
];
|
|
|
|
// 获取内容
|
|
$field = [
|
|
'seller.username as seller_username',
|
|
'seller.nickname as seller_nickname',
|
|
'seller.headimg as seller_headimg',
|
|
'g.goods_name',
|
|
'g.goods_image',
|
|
'g.goods_content',
|
|
'g.market_price',
|
|
'g.unit',
|
|
'a.service_price',
|
|
'a.real_income',
|
|
'a.site_id',
|
|
'a.seller_uid',
|
|
'a.goods_id',
|
|
'a.id',
|
|
'a.total',
|
|
'a.unit_price',
|
|
'a.order_id',
|
|
'a.price',
|
|
'a.status',
|
|
'a.release_time',
|
|
'a.sell_time',
|
|
'a.created_time',
|
|
'a.take_time',
|
|
'o.order_no',
|
|
'o.buyer_message',
|
|
];
|
|
// 表关联
|
|
$join = [
|
|
['member seller', 'seller.member_id = a.seller_uid', 'left'],// 获取卖家信息
|
|
['goods g', 'g.goods_id = a.goods_id', 'left'],// 获取商品信息
|
|
['order o', 'o.order_id = a.order_id', 'left'],// 获取商品信息
|
|
];
|
|
|
|
$detail = model('futures')->getInfo($condition, $field, 'a', $join);
|
|
return $this->success($detail);
|
|
}
|
|
/**
|
|
* 增加库存
|
|
* @param $data
|
|
* @return array
|
|
* @throws InvalidArgumentException
|
|
*/
|
|
public function add($data){
|
|
$id = model('futures')->add($data);
|
|
if(!($id > 0)){
|
|
return $this->error('','添加失败');
|
|
}
|
|
Cache::store('redis_concurrent')->set('addon_futures_stock_'.$id,'1');
|
|
return $this->success($id);
|
|
}
|
|
/**
|
|
* 发布
|
|
* @param $id
|
|
* @param $price
|
|
* @return array
|
|
* @throws InvalidArgumentException
|
|
*/
|
|
public function release($id, $price, $agree_split_order = 0){
|
|
$date = model('futures')->getInfo([['id', '=', $id]]);
|
|
if(empty($date) || $date['status'] !== 1){
|
|
return $this->error('','发布失败');
|
|
}
|
|
if(!Cache::store('redis_concurrent')->delete('addon_futures_stock_'.$id)){
|
|
return $this->error('','发布失败');
|
|
}
|
|
|
|
$basics = $this->getBasicsConfig($date['site_id'])['data']['value'];
|
|
model('futures')->startTrans();
|
|
try{
|
|
//拆单
|
|
$futuresInfo = $this->detail($id,$date['site_id'])['data'];
|
|
$futuresInfo['status'] = 2;
|
|
if($price >= $futuresInfo['market_price'] * $futuresInfo['total']){
|
|
$futuresInfo['total'] *= 2;
|
|
if($futuresInfo['total'] > pow(2,$basics['order_total_double_times'])){// 配置单订单商品最大裂变次数
|
|
if($agree_split_order == 0){
|
|
model('futures')->rollback();
|
|
Cache::store('redis_concurrent')->set('addon_futures_stock_'.$id,'1');
|
|
return error(-800, '订单价格达到订单拆分限制,是否同意订单拆分?');
|
|
}
|
|
//拆单
|
|
$futuresInfo['status'] = 8;
|
|
for($i = 0;$i < $futuresInfo['total'];$i++){
|
|
$newSmallFuturesId = $this->add([
|
|
'site_id' => $futuresInfo['site_id'],
|
|
'seller_uid' => $futuresInfo['seller_uid'],
|
|
'old_futures_id' => $id,
|
|
'goods_id' => $futuresInfo['goods_id'],
|
|
'total' => 1,
|
|
'unit_price' => $futuresInfo['unit_price'] / $futuresInfo['total'],
|
|
'status' => 1,
|
|
'order_id' => $futuresInfo['order_id'],
|
|
'created_time' => time()
|
|
])['data'];
|
|
$this->release($newSmallFuturesId,$price / $futuresInfo['total']);
|
|
}
|
|
}
|
|
}
|
|
$service_price = $price * $basics['service_price'] / 100;
|
|
model('futures')->update([
|
|
'status' => $futuresInfo['status'],
|
|
'release_time' => time() + $basics['release_wait'] * 24 * 60 * 60,// 配置上线延迟时间
|
|
'price' => $price,
|
|
'total' => $futuresInfo['total'],
|
|
'service_price' => $service_price,
|
|
'real_income' => $price - $service_price,
|
|
],[['id','=',$id]]);
|
|
model('futures')->commit();
|
|
|
|
Cache::store('redis_concurrent')->set('addon_futures_'.$id,'1');
|
|
return $this->success();
|
|
|
|
} catch (\Exception $e) {
|
|
model('futures')->rollback();
|
|
Cache::store('redis_concurrent')->set('addon_futures_stock_'.$id,'1');
|
|
return $this->error('', $e->getMessage() . $e->getFile() . $e->getLine());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 下架到库存
|
|
* @return array
|
|
*/
|
|
public function stock($id){
|
|
$date = model('futures')->getInfo([['id', '=', $id]]);
|
|
if(empty($date) || $date['status'] !== 2){
|
|
return $this->error('','下架失败');
|
|
}
|
|
if(!Cache::store('redis_concurrent')->delete('addon_futures_'.$id)){
|
|
return $this->error('','下架失败');
|
|
}
|
|
model('futures')->update([
|
|
'status' => 1,
|
|
], [['id', '=', $id]]);
|
|
return $this->success();
|
|
}
|
|
/**
|
|
* 提货
|
|
* @param $id
|
|
* @return array
|
|
* @throws InvalidArgumentException
|
|
*/
|
|
public function pickUp($id){
|
|
$date = model('futures')->getInfo([['id', '=', $id]]);
|
|
if(empty($date) || $date['status'] !== 1){
|
|
return $this->error($date,'提货失败');
|
|
}
|
|
if(!Cache::store('redis_concurrent')->delete('addon_futures_stock_'.$id)){
|
|
return $this->error('','提货失败');
|
|
}
|
|
model('futures')->update([
|
|
'status' => 5,
|
|
], [['id', '=', $id]]);
|
|
|
|
|
|
$basics = $this->getBasicsConfig($date['site_id'])[ 'data' ][ 'value' ];
|
|
|
|
// 提货用来减少用户买入限制
|
|
Db::name('futures_user')
|
|
->where('member_id',$date['member_id'])
|
|
->update([
|
|
'business_num' => Db::raw('business_num-'.$basics['order_restrictions_num']),
|
|
]);
|
|
return $this->success();
|
|
}
|
|
|
|
/**
|
|
* 订单创建
|
|
* @return array
|
|
*/
|
|
public function orderCreate($id, $order_id, $member_id){
|
|
$date = model('futures')->getInfo([['id', '=', $id]]);
|
|
if(empty($date) || ($date['status'] !== 2 && $date['status'] !== 7)){
|
|
return $this->error($date,'下单失败-1001');
|
|
}
|
|
if(!Cache::store('redis_concurrent')->delete('addon_futures_'.$id)){
|
|
return $this->error('','下单失败-1002');
|
|
}
|
|
model('futures')->update([
|
|
'status' => 6,
|
|
'created_time' => time(),
|
|
'member_id' => $member_id
|
|
], [['id', '=', $id]]);
|
|
|
|
// 增加用户已下单次数
|
|
Db::name('futures_user')
|
|
->where('member_id',$date['member_id'])
|
|
->update([
|
|
'business_num' => Db::raw('business_num+1'),
|
|
'total_business_num' => Db::raw('total_business_num+1'),
|
|
]);
|
|
|
|
(new Message())->addMessage($date['site_id'],'订单创建',1,$member_id,$id);
|
|
Cache::store('redis_concurrent')->set('addon_futures_pay_'.$id,'1');
|
|
return $this->success();
|
|
}
|
|
|
|
/**
|
|
* 订单完成
|
|
* @return array
|
|
*/
|
|
public function orderComplete($id,$order_id){
|
|
$date = model('futures')->getInfo([['id', '=', $id]]);
|
|
if(empty($date) || $date['status'] !== 6){
|
|
return $this->error($date,'完成失败');
|
|
}
|
|
if(!Cache::store('redis_concurrent')->delete('addon_futures_pay_'.$id)){
|
|
return $this->error('','完成失败');
|
|
}
|
|
$date = model('futures')->getInfo([['id', '=', $id]]);
|
|
model('futures')->update([
|
|
'status' => 3,
|
|
'sell_time' => time()
|
|
], [['id', '=', $id]]);
|
|
$this->add([
|
|
'site_id' => $date['site_id'],
|
|
'seller_uid' => $date['member_id'],
|
|
'old_futures_id' => $id,
|
|
'goods_id' => (int)$date['goods_id'],
|
|
'total' => (int)$date['total'],
|
|
'unit_price' => $date['price'],
|
|
'status' => 1,
|
|
'order_id' => $order_id,
|
|
'created_time' => time()]);
|
|
(new Message())->addMessage($date['site_id'],'订单完成',1,$date['member_id'],$id);
|
|
(new Message())->addMessage($date['site_id'],'订单售卖完成',1,$date['seller_uid'],$id);
|
|
// 给用户增加余额
|
|
$memberAccountModel = new MemberAccount();
|
|
$memberAccountModel->addMemberAccount($date['site_id'], $date['seller_uid'], 'balance_money', $date['price'], 'sell', $date['id'], '售卖产品', $date['id']);
|
|
$memberAccountModel->addMemberAccount($date['site_id'], $date['seller_uid'], 'balance_money', -$date['service_price'], 'service_price', $date['id'], '服务费', $date['id']);
|
|
|
|
//赠送积分
|
|
$memberAccountModel->addMemberAccount($date['site_id'], $date['member_id'], 'point', $date['price'], 'sell', $date['id'], '秒杀赠送积分', $date['id']);
|
|
return $this->success();
|
|
}
|
|
|
|
/**
|
|
* 订单取消
|
|
* @return array
|
|
*/
|
|
public function orderClose($id){
|
|
$date = model('futures')->getInfo([['id', '=', $id]]);
|
|
if(empty($date) || $date['status'] !== 6){
|
|
return $this->error($date,'取消失败');
|
|
}
|
|
if(!Cache::store('redis_concurrent')->delete('addon_futures_pay_'.$id)){
|
|
return $this->error('','取消失败');
|
|
}
|
|
model('futures')->update([
|
|
'status' => 7,
|
|
], [['id', '=', $id]]);
|
|
Cache::store('redis_concurrent')->set('addon_futures_'.$id,'1');
|
|
(new Message())->addMessage($date['site_id'],'订单取消',1,$date['member_id'],$id);
|
|
// 订单取消后 添加违规次数
|
|
Db::name('futures_user')
|
|
->where('member_id',$date['member_id'])
|
|
->update([
|
|
'violation_num' => Db::raw('violation_num+1'),
|
|
'total_violation_num' => Db::raw('total_violation_num+1'),
|
|
]);
|
|
Db::name('futures_user_violation_records')
|
|
->insert([
|
|
'site_id' => $date['site_id'],
|
|
'member_id' => $date['member_id'],
|
|
'futures_id' => $id,
|
|
'created_time' => time(),
|
|
]);
|
|
// 判断:如果当前次数已经到达限制 进行惩罚操作
|
|
$futuresUserInfo = Db::name('futures_user')
|
|
->field('violation_num,site_id,punish_time')
|
|
->where('member_id',$date['member_id'])
|
|
->find();
|
|
$basics = (new Futures())->getBasicsConfig($futuresUserInfo['site_id'])[ 'data' ][ 'value' ];
|
|
$violationHour = $basics['violation_hour'] ?? 0;
|
|
$violationUnpaid = $basics['violation_unpaid'] ?? 0;
|
|
if($violationUnpaid > 0 && $futuresUserInfo['violation_num'] >= $violationUnpaid){
|
|
$startTime = $futuresUserInfo['punish_time'] > time() ? $futuresUserInfo['punish_time'] : time();
|
|
Db::name('futures_user')
|
|
->where('member_id',$date['member_id'])
|
|
->update([
|
|
'punish_time' => strtotime("+{$violationHour} hours", $startTime),// 添加惩罚时间
|
|
'violation_num' => Db::raw("violation_num - {$violationUnpaid}")// 减少违规次数
|
|
]);
|
|
}
|
|
|
|
return $this->success();
|
|
}
|
|
|
|
/**
|
|
* 写入基本设置
|
|
* @param $data
|
|
* @param $is_use
|
|
* @param $site_id
|
|
* @return array
|
|
*/
|
|
public function setBasicsConfig($data, $is_use, $site_id)
|
|
{
|
|
$config = new ConfigModel();
|
|
$miaosha_start_time_arr = array_column($data['times'], 'miaosha_start_time');
|
|
array_multisort($miaosha_start_time_arr, SORT_ASC, $data['times']);
|
|
return $config->setConfig($data, '秒杀基本配置', $is_use, [['site_id', '=', $site_id], ['app_module', '=', 'shop'], ['config_key', '=', 'MIAOSHA_BASICS_CONFIG']]);
|
|
}
|
|
|
|
/**
|
|
* 读取基本设置
|
|
* @param $site_id
|
|
* @return array
|
|
*/
|
|
public function getBasicsConfig($site_id)
|
|
{
|
|
$config = new ConfigModel();
|
|
return $config->getConfig([['site_id', '=', $site_id], ['app_module', '=', 'shop'], ['config_key', '=', 'MIAOSHA_BASICS_CONFIG']]);
|
|
}
|
|
/**
|
|
* 判断当前时间是否在秒杀开启时间,并区分有无钻石用户
|
|
* @param $site_id
|
|
* @param $member_id
|
|
* @param $status
|
|
* @return array
|
|
*/
|
|
public function checkTimes($site_id, $member_id, $status = 2){
|
|
switch($status){
|
|
case '2':
|
|
$startTimeKey = 'miaosha_start_time';
|
|
$endTimeKey = 'miaosha_end_time';
|
|
$fenxiao = model('fenxiao')->getInfo([['member_id', '=', $member_id]]);
|
|
if(!empty($fenxiao) && $fenxiao['diamond'] > 0){
|
|
$startTimeKey = 'miaosha_early_start_time';
|
|
}
|
|
break;
|
|
case '7':
|
|
$startTimeKey = 'jianlou_start_time';
|
|
$endTimeKey = 'jianlou_end_time';
|
|
break;
|
|
default:
|
|
return $this->error('','参数不合法');
|
|
break;
|
|
}
|
|
|
|
$nowTime = time() - strtotime("today");
|
|
$is_read = FALSE;
|
|
$nowtimes = [];
|
|
|
|
$basics = $this->getBasicsConfig($site_id)['data']['value'];
|
|
if(empty($basics['times'])){
|
|
return $this->error('','暂无秒杀活动');
|
|
}
|
|
$recentlyTimes = [];
|
|
foreach($basics['times'] as $times){
|
|
if($times[$startTimeKey] <= $nowTime && $times[$endTimeKey] >= $nowTime){
|
|
$is_read = TRUE;
|
|
$nowtimes = [
|
|
'original' => $times,
|
|
'start_time' => $times[$startTimeKey],
|
|
'end_time' => $times[$endTimeKey]
|
|
];
|
|
break;
|
|
}
|
|
if(empty($recentlyTimes) && $times['miaosha_start_time'] >= $nowTime){
|
|
$recentlyTimes = $times;
|
|
foreach($recentlyTimes as $timeKey => $time){
|
|
$recentlyTimes[$timeKey] += strtotime(date("Y-m-d", time()));
|
|
}
|
|
}
|
|
}
|
|
if(empty($recentlyTimes)){
|
|
$recentlyTimes = $basics['times'][0];
|
|
foreach($recentlyTimes as $timeKey => $time){
|
|
$recentlyTimes[$timeKey] += strtotime(date("Y-m-d", time())) + 24 * 60 * 60;
|
|
}
|
|
}
|
|
|
|
if(!$is_read){
|
|
return error(-801,'未到秒杀时间', $recentlyTimes);
|
|
|
|
}
|
|
//判断是否是提前秒杀
|
|
$nowtimes['is_early'] = FALSE;
|
|
if($times['miaosha_early_start_time'] <= $nowTime && $times['miaosha_start_time'] >= $nowTime){
|
|
$nowtimes['is_early'] = TRUE;
|
|
}
|
|
return $this->success($nowtimes);
|
|
}
|
|
} |