<?php
namespace app\api\model\sharing;
use app\api\model\User as UserModel;
use app\api\model\Setting as SettingModel;
use app\api\model\UserCoupon as UserCouponModel;
use app\api\model\dealer\Order as DealerOrderModel;
use app\api\model\sharing\Goods as GoodsModel;
use app\api\model\sharing\GoodsSku as GoodsSkuModel;
use app\common\model\sharing\Order as OrderModel;
use app\api\model\sharing\OrderGoods as OrderGoodsModel;
use app\api\service\User as UserService;
use app\api\service\sharing\order\PaySuccess;
use app\api\service\Payment as PaymentService;
use app\common\enum\OrderType as OrderTypeEnum;
use app\common\enum\order\Status as OrderStatusEnum;
use app\common\enum\DeliveryType as DeliveryTypeEnum;
use app\common\enum\order\PayType as PayTypeEnum;
use app\common\enum\order\PayStatus as PayStatusEnum;
use app\common\service\order\Complete as OrderCompleteService;
use app\common\library\helper;
use app\common\exception\BaseException;
class Order extends OrderModel
{
protected $hidden = [
'wxapp_id',
'update_time'
];
private $checkoutParam = [
'active_id' => 0, 'delivery' => null, 'shop_id' => 0, 'linkman' => '', 'phone' => '', 'coupon_id' => 0, 'remark' => '', 'pay_type' => PayTypeEnum::WECHAT, ];
public static function getPayDetail($orderNo)
{
return self::get(['order_no' => $orderNo, 'pay_status' => 10, 'is_delete' => 0], ['goods', 'user']);
}
public function getOrderGoodsListByNow($params)
{
$goods = GoodsModel::detail($params['goods_id']);
$goods['goods_sku'] = GoodsModel::getGoodsSku($goods, $params['goods_sku_id']);
$goodsList = [$goods->hidden(['category', 'content', 'image', 'sku'])];
foreach ($goodsList as &$item) {
$item['goods_price'] = $params['order_type'] == 10 ? $item['goods_sku']['goods_price']
: $item['goods_sku']['sharing_price'];
$item['total_num'] = $params['goods_num'];
$item['spec_sku_id'] = $item['goods_sku']['spec_sku_id'];
$item['total_price'] = helper::bcmul($item['goods_price'], $params['goods_num']);
}
return $goodsList;
}
public function onPay($payType = PayTypeEnum::WECHAT)
{
if (!$this->checkGoodsStatusFromOrder($this['goods'])) {
return false;
}
if ($payType == PayTypeEnum::BALANCE) {
return $this->onPaymentByBalance($this['order_no']);
}
return true;
}
public function onOrderPayment($user, $order, $payType)
{
if ($payType == PayTypeEnum::WECHAT) {
return $this->onPaymentByWechat($user, $order);
}
return [];
}
private function onPaymentByWechat($user, $order)
{
return PaymentService::wechat(
$user,
$order['order_id'],
$order['order_no'],
$order['pay_price'],
OrderTypeEnum::SHARING
);
}
public function onPaymentByBalance($orderNo)
{
$PaySuccess = new PaySuccess($orderNo);
$status = $PaySuccess->onPaySuccess(PayTypeEnum::BALANCE);
if (!$status) {
$this->error = $PaySuccess->getError();
}
return $status;
}
public function checkActiveIsAllowJoin($active_id)
{
$detail = Active::detail($active_id);
if (!$detail) {
throw new BaseException('很抱歉,拼单不存在');
}
return $detail->checkAllowJoin();
}
public function saveOrderExtract($linkman, $phone)
{
UserService::setLastExtract($this['user_id'], trim($linkman), trim($phone));
return $this->extract()->save([
'linkman' => trim($linkman),
'phone' => trim($phone),
'user_id' => $this['user_id'],
'wxapp_id' => self::$wxapp_id,
]);
}
public function getList($user_id, $type = 'all')
{
$filter = [];
switch ($type) {
case 'all':
break;
case 'payment';
$filter['pay_status'] = PayStatusEnum::PENDING;
break;
case 'sharing';
$filter['active.status'] = 10;
break;
case 'delivery';
$this->where('IF ( (`order`.`order_type` = 20), (`active`.`status` = 20), TRUE)');
$filter['pay_status'] = 20;
$filter['delivery_status'] = 10;
break;
case 'received';
$filter['pay_status'] = 20;
$filter['delivery_status'] = 20;
$filter['receipt_status'] = 10;
break;
case 'comment';
$filter['order_status'] = 30;
$filter['is_comment'] = 0;
break;
}
return $this->with(['goods.image', 'active'])
->alias('order')
->field('order.*, active.status as active_status')
->join('sharing_active active', 'order.active_id = active.active_id', 'LEFT')
->where('user_id', '=', $user_id)
->where($filter)
->where('order.is_delete', '=', 0)
->order(['create_time' => 'desc'])
->paginate(15, false, [
'query' => \request()->request()
]);
}
public function cancel($user)
{
if ($this['delivery_status']['value'] == 20) {
$this->error = '已发货订单不可取消';
return false;
}
if ($this['order_type']['value'] == 20) {
$this->error = '拼团订单不允许取消';
return false;
}
$this->transaction(function () use ($user) {
$isPay = $this['pay_status']['value'] == PayStatusEnum::SUCCESS;
if ($isPay == false) {
(new OrderGoodsModel)->backGoodsStock($this['goods'], $isPay);
$this['coupon_id'] > 0 && UserCouponModel::setIsUse($this['coupon_id'], false);
$describe = "订单取消:{$this['order_no']}";
$this['points_num'] > 0 && $user->setIncPoints($this['points_num'], $describe);
}
return $this->save(['order_status' => $isPay ? OrderStatusEnum::APPLY_CANCEL : OrderStatusEnum::CANCELLED]);
});
return true;
}
public function receipt()
{
if ($this['delivery_status']['value'] != 20 || $this['receipt_status']['value'] != 10) {
$this->error = '该订单不合法';
return false;
}
return $this->transaction(function () {
$status = $this->save([
'receipt_status' => 20,
'receipt_time' => time(),
'order_status' => 30
]);
(new OrderCompleteService)->complete([$this], OrderTypeEnum::SHARING, static::$wxapp_id);
return $status;
});
}
public function getCount($user_id, $type = 'all')
{
$filter = [];
switch ($type) {
case 'all':
break;
case 'payment';
$filter['pay_status'] = PayStatusEnum::PENDING;
break;
case 'received';
$filter['pay_status'] = PayStatusEnum::SUCCESS;
$filter['delivery_status'] = 20;
$filter['receipt_status'] = 10;
break;
case 'comment';
$filter['order_status'] = 30;
$filter['is_comment'] = 0;
break;
}
return $this->where('user_id', '=', $user_id)
->where('order_status', '<>', 20)
->where($filter)
->where('is_delete', '=', 0)
->count();
}
public static function getUserOrderDetail($order_id, $user_id)
{
$order = (new static)->with(['goods' => ['image', 'refund'], 'address', 'express', 'extract_shop'])
->alias('order')
->field('order.*, active.status as active_status')
->join('sharing_active active', 'order.active_id = active.active_id', 'LEFT')
->where([
'order_id' => $order_id,
'user_id' => $user_id,
])->find();
if (!$order) {
throw new BaseException(['msg' => '订单不存在']);
}
return $order;
}
private function checkGoodsStatusFromOrder($goodsList)
{
foreach ($goodsList as $goods) {
if (
empty($goods['goods'])
|| $goods['goods']['goods_status']['value'] != 10
) {
$this->error = "很抱歉,商品 [{$goods['goods_name']}] 已下架";
return false;
}
$goodsSku = GoodsSkuModel::detail($goods['goods_id'], $goods['spec_sku_id']);
if (empty($goodsSku)) {
$this->error = "很抱歉,商品 [{$goods['goods_name']}] sku已不存在,请重新下单";
return false;
}
if ($goods['deduct_stock_type'] == 20 && $goods['total_num'] > $goodsSku['stock_num']) {
$this->error = "很抱歉,商品 [{$goods['goods_name']}] 库存不足";
return false;
}
}
return true;
}
public function isAllowRefund()
{
$refund_days = SettingModel::getItem('trade')['order']['refund_days'];
if ($refund_days == 0) {
return false;
}
if (time() > $this['receipt_time'] + ((int)$refund_days * 86400)) {
return false;
}
if ($this['receipt_status']['value'] != 20) {
return false;
}
return true;
}
public function checkExtractOrder(&$order)
{
if (
$order['pay_status']['value'] == PayStatusEnum::SUCCESS
&& $order['delivery_type']['value'] == DeliveryTypeEnum::EXTRACT
&& $order['delivery_status']['value'] == 10
&& ($order['order_type']['value'] == 20 ? $order['active']['status']['value'] == 20 : true)
) {
return true;
}
$this->setError('该订单不能被核销');
return false;
}
private function setError($error)
{
empty($this->error) && $this->error = $error;
}
public function hasError()
{
return !empty($this->error);
}
}