482 lines
20 KiB
PHP
482 lines
20 KiB
PHP
<?php
|
|
namespace addon\futures\model;
|
|
use addon\futures\model\Futures as FuturesModel;
|
|
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',
|
|
'old_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.member_id',
|
|
'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',
|
|
'seller.nickname as buyer_name'
|
|
];
|
|
// 表关联
|
|
$join = [
|
|
['member seller', 'seller.member_id = a.seller_uid', 'left'],// 获取卖家信息
|
|
['member buyer', 'buyer.member_id = a.member_id', 'left'],// 获取买家信息
|
|
['goods g', 'g.goods_id = a.goods_id', 'left'],// 获取商品信息
|
|
['order o', 'o.order_id = a.order_id', 'left'],// 获取商品信息
|
|
['futures f', 'f.id = a.old_futures_id', 'left'],// 获取旧订单信息
|
|
['member old_seller', 'old_seller.member_id = f.seller_uid', '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('', '添加失败');
|
|
}
|
|
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('', '发布失败-db');
|
|
}
|
|
$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;
|
|
$splitOrderNum = $basics['split_order_num'];
|
|
for ($i = 0; $i < $splitOrderNum; $i++) {
|
|
$newSmallFuturesId = $this->add([
|
|
'site_id' => $futuresInfo['site_id'],
|
|
'seller_uid' => $futuresInfo['seller_uid'],
|
|
'old_futures_id' => $id,
|
|
'goods_id' => $futuresInfo['goods_id'],
|
|
'total' => $futuresInfo['total'] / $splitOrderNum,
|
|
'unit_price' => $futuresInfo['unit_price'] / $splitOrderNum,
|
|
'status' => 1,
|
|
'order_id' => $futuresInfo['order_id'],
|
|
'created_time' => time()
|
|
])['data'];
|
|
$this->release($newSmallFuturesId, $price / $splitOrderNum);
|
|
}
|
|
model('futures')->commit();
|
|
return $this->success();
|
|
}
|
|
}
|
|
$service_price = $date['unit_price'] * $basics['service_price'] / 100; //更改为买入价格
|
|
$technical_range = $service_price * $basics['technical_range'] / 100;
|
|
if (model('member')->getValue(['member_id' => $date['seller_uid']], 'balance_money') < $service_price) {
|
|
return error(-800, '您余额不足!');
|
|
}
|
|
$release_time= time() + $basics['release_wait'] * 24 * 60 * 60;// 配置上线延迟时间
|
|
if(Db::name('futures_user')->where('member_id', '=',$futuresInfo['seller_uid'])->cache($futuresInfo['seller_uid'].'is_special')->value('is_special')==1){
|
|
$release_time=time();
|
|
} //排除特殊用户时间限制
|
|
model('futures')->update([
|
|
'status' => $futuresInfo['status'],
|
|
'release_time' => $release_time,// 配置上线延迟时间
|
|
'price' => $price,
|
|
'total' => $futuresInfo['total'],
|
|
'service_price' => $service_price,
|
|
'real_income' => $price,
|
|
], [['id', '=', $id]]);
|
|
//扣除服务费
|
|
$memberAccountModel = new MemberAccount();
|
|
$memberAccountModel->addMemberAccount($date['site_id'], $date['seller_uid'], 'balance_money', -$technical_range, 'service_price', $date['id'], '服务费', $date['id']);
|
|
$memberAccountModel->addMemberAccount($date['site_id'], $date['seller_uid'], 'balance_money', -($service_price - $technical_range), 'service_price', $date['id'], '商家分账', $date['id']);
|
|
model('futures')->commit();
|
|
return $this->success();
|
|
} catch (\Exception $e) {
|
|
model('futures')->rollback();
|
|
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('', '下架失败');
|
|
}
|
|
model('futures')->update([
|
|
'status' => 1,
|
|
'release_time' => 0,
|
|
], [['id', '=', $id]]);
|
|
//扣除服务费
|
|
$memberAccountModel = new MemberAccount();
|
|
$memberAccountModel->addMemberAccount($date['site_id'], $date['seller_uid'], 'balance_money', $date['service_price'], 'service_price', $date['id'], '退回服务费与商家分账', $date['id']);
|
|
Cache::store('redis_concurrent')->delete('addon_futures_' . $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, '提货失败');
|
|
}
|
|
$member_address = input('member_address', []);
|
|
$member_address = isset($member_address) && !empty($member_address) ? json_decode($member_address, true) : [];
|
|
if (empty($member_address)) {
|
|
return $this->error($date, '提货失败-无收获地址');
|
|
}
|
|
model('futures')->update([
|
|
'status' => 5,
|
|
], [['id', '=', $id]]);
|
|
$order_info = [
|
|
'name' => $member_address['name'] ?? '',
|
|
'mobile' => $member_address['mobile'] ?? '',
|
|
'telephone' => $member_address['telephone'] ?? '',
|
|
'province_id' => $member_address['province_id'] ?? '',
|
|
'city_id' => $member_address['city_id'] ?? '',
|
|
'district_id' => $member_address['district_id'] ?? '',
|
|
'community_id' => $member_address['community_id'] ?? '',
|
|
'address' => $member_address['address'] ?? '',
|
|
'full_address' => $member_address['full_address'] ?? '',
|
|
'longitude' => $member_address['longitude'] ?? '',
|
|
'latitude' => $member_address['latitude'] ?? '',
|
|
'promotion_type' => 'futures_tihuo',
|
|
];
|
|
model('order')->update($order_info, [['order_id', '=', $date['order_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)
|
|
{
|
|
|
|
if(Cache::store('redis_concurrent')->get('addon_futures_' . $id)){
|
|
return $this->error('', '你太慢了已被抢购');
|
|
}
|
|
$date = model('futures')->getInfo([['id', '=', $id]]);
|
|
if (empty($date) || ($date['status'] !== 2 && $date['status'] !== 7)) {
|
|
return $this->error($date, '下单失败-1001');
|
|
}
|
|
model('futures')->update(
|
|
[
|
|
'status' => 6,
|
|
'created_time' => time(),
|
|
'member_id' => $member_id,
|
|
'order_id' => $order_id,
|
|
],
|
|
[['id', '=', $id]]);
|
|
//增加用户已下单次数
|
|
Db::name('futures_user')
|
|
->where('member_id', $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')->tag('addon_futures_goods')->set('addon_futures_' . $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, '完成失败');
|
|
}
|
|
$date = model('futures')->getInfo([['id', '=', $id]]);
|
|
model('futures')->update([
|
|
'status' => 3,
|
|
'sell_time' => time()
|
|
], [['id', '=', $id]]);
|
|
$this->add(
|
|
[
|
|
'order_id' => $order_id,
|
|
'site_id' => $date['site_id'],
|
|
'seller_uid' => $date['member_id'],
|
|
'member_id' => $date['member_id'],
|
|
'old_futures_id' => $id,
|
|
'goods_id' => (int)$date['goods_id'],
|
|
'total' => (int)$date['total'],
|
|
'unit_price' => $date['price'],
|
|
'status' => 1,
|
|
'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']);
|
|
$futuresModel = new FuturesModel;
|
|
$basics = $futuresModel->getBasicsConfig($date['site_id'])['data']['value'];
|
|
if ($basics['give_integral'] > 0) { //首单赠送积分
|
|
if (model('futures')->getCount(['seller_uid' => $date['member_id']]) == 1) {
|
|
$memberAccountModel->addMemberAccount($date['site_id'], $date['member_id'], 'point', $basics['give_integral'], 'sell', $date['id'], '秒杀首单赠送积分', $date['id']);
|
|
}
|
|
}
|
|
$point = $date['price'] * $basics['order_give_points_ratio'] / 100;
|
|
//赠送积分
|
|
$memberAccountModel->addMemberAccount($date['site_id'], $date['member_id'], 'point', intval($point), 'sell', $date['id'], '秒杀赠送积分', $date['id']);
|
|
Cache::store('redis_concurrent')->delete('addon_futures_' . $id);
|
|
return $this->success();
|
|
}
|
|
|
|
/**
|
|
* 订单取消
|
|
* @return array
|
|
*/
|
|
public function orderClose($id)
|
|
{
|
|
$date = model('futures')->getInfo([['id', '=', $id]]);
|
|
///将未被抢购方法抢购区
|
|
// model('futures')->update(['status' => 7], [
|
|
// ['status', '=', 2],
|
|
// ['release_time', '<', time()],
|
|
// ]);
|
|
if (empty($date) || $date['status'] !== 6) {
|
|
return $this->error($date, '取消失败');
|
|
}
|
|
// if(!Cache::store('redis_concurrent')->delete('addon_futures_pay_'.$id)){
|
|
// return $this->error('','取消失败');
|
|
// }
|
|
// Cache::store('redis_concurrent')->delete('addon_futures_pay_' . $id);
|
|
model('futures')->update(['status' => 7,'member_id'=>$date['seller_uid']], [['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'];
|
|
$punish_money=$basics['punish_money'];
|
|
if($punish_money){
|
|
//扣除服务费
|
|
$memberAccountModel = new MemberAccount();
|
|
$memberAccountModel->addMemberAccount($date['site_id'], $date['member_id'], 'balance_money', -$punish_money, 'service_price', $id, '服务罚金', $id);
|
|
}else{
|
|
$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}")// 减少违规次数
|
|
]);
|
|
}
|
|
}
|
|
Cache::store('redis_concurrent')->tag('addon_futures_goods')->clear();//删除缓存
|
|
(new Message())->addMessage($date['site_id'], '订单取消', 1, $date['member_id'], $id);
|
|
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('member')->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('', '参数不合法');
|
|
}
|
|
$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);
|
|
}
|
|
} |