<?php
namespace app\api\model;
use app\api\model\User as UserModel;
use app\api\model\Goods as GoodsModel;
use app\api\model\Setting as SettingModel;
use app\api\model\UserCoupon as UserCouponModel;
use app\api\service\order\PaySuccess;
use app\api\service\Payment as PaymentService;
use app\api\service\order\source\Factory as OrderSourceFactory;
use app\common\model\Order as OrderModel;
use app\common\enum\OrderType as OrderTypeEnum;
use app\common\enum\DeliveryType as DeliveryTypeEnum;
use app\common\enum\order\Status as OrderStatusEnum;
use app\common\enum\order\PayType as PayTypeEnum;
use app\common\enum\order\PayStatus as PayStatusEnum;
use app\common\service\goods\source\Factory as FactoryStock;
use app\common\service\order\Complete as OrderCompleteService;
use app\common\exception\BaseException;
use app\common\library\helper;
class Order extends OrderModel
{
protected $hidden = [
'wxapp_id',
'update_time'
];
public static function getPayDetail($orderNo)
{
return self::get(['order_no' => $orderNo, 'pay_status' => 10, 'is_delete' => 0], ['goods', 'user']);
}
public function onPay($payType = PayTypeEnum::WECHAT)
{
$orderSource = OrderSourceFactory::getFactory($this['order_source']);
if (!$orderSource->checkOrderStatusOnPay($this)) {
$this->error = $orderSource->getError();
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 [];
}
protected function onPaymentByWechat($user, $order)
{
return PaymentService::wechat(
$user,
$order['order_id'],
$order['order_no'],
$order['pay_price'],
OrderTypeEnum::MASTER
);
}
public function getOrderGoodsListByNow($goodsId, $goodsSkuId, $goodsNum)
{
$goods = GoodsModel::detail($goodsId);
$goods['goods_sku'] = GoodsModel::getGoodsSku($goods, $goodsSkuId);
$goodsList = [$goods->hidden(['category', 'content', 'image', 'sku'])];
foreach ($goodsList as &$item) {
$item['goods_price'] = $item['goods_sku']['goods_price'];
$item['total_num'] = $goodsNum;
$item['spec_sku_id'] = $item['goods_sku']['spec_sku_id'];
$item['total_price'] = helper::bcmul($item['goods_price'], $goodsNum);
}
return $goodsList;
}
public function onPaymentByBalance($orderNo)
{
$PaySuccess = new PaySuccess($orderNo);
$status = $PaySuccess->onPaySuccess(PayTypeEnum::BALANCE);
if (!$status) {
$this->error = $PaySuccess->getError();
}
return $status;
}
public function getList($user_id, $type = 'all')
{
$filter = [];
switch ($type) {
case 'all':
break;
case 'payment';
$filter['pay_status'] = PayStatusEnum::PENDING;
$filter['order_status'] = 10;
break;
case 'delivery';
$filter['pay_status'] = PayStatusEnum::SUCCESS;
$filter['delivery_status'] = 10;
$filter['order_status'] = 10;
break;
case 'received';
$filter['pay_status'] = PayStatusEnum::SUCCESS;
$filter['delivery_status'] = 20;
$filter['receipt_status'] = 10;
$filter['order_status'] = 10;
break;
case 'comment';
$filter['is_comment'] = 0;
$filter['order_status'] = 30;
break;
}
return $this->with(['goods.image'])
->where('user_id', '=', $user_id)
->where($filter)
->where('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;
}
return $this->transaction(function () use ($user) {
$isPay = $this['pay_status']['value'] == PayStatusEnum::SUCCESS;
if ($isPay == false) {
FactoryStock::getFactory($this['order_source'])->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]);
});
}
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::MASTER, 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)
{
if (!$order = self::get([
'order_id' => $order_id,
'user_id' => $user_id,
], [
'goods' => ['image', 'goods', 'refund'],
'address', 'express', 'extract_shop'
])
) {
throw new BaseException(['msg' => '订单不存在']);
}
return $order;
}
public function checkExtractOrder(&$order)
{
if (
$order['pay_status']['value'] == PayStatusEnum::SUCCESS
&& $order['delivery_type']['value'] == DeliveryTypeEnum::EXTRACT
&& $order['delivery_status']['value'] == 10
) {
return true;
}
$this->setError('该订单不能被核销');
return false;
}
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;
}
protected function setError($error)
{
empty($this->error) && $this->error = $error;
}
public function hasError()
{
return !empty($this->error);
}
}