$data['order_sn']]); } public function getPayurlAttr($value, $data) { return addon_url('shop/payment/index') . '?orderid=' . $data['order_sn']; } public function getCommenturlAttr($value, $data) { return url('shop.comment/post') . '?orderid=' . $data['order_sn']; } /** * 获取快递查询URL */ public function getLogisticsurlAttr($value, $data) { $url = self::$config['logisticstype'] == 'kdnapi' ? url('shop.order/logistics') . '?orderid=' . $data['order_sn'] : "https://www.kuaidi100.com/chaxun?com={$data['expressname']}&nu={$data['expressno']}"; return $url; } public function getOrderstateList() { return ['0' => __('Orderstate 0'), '1' => __('Orderstate 1'), '2' => __('Orderstate 2'), '3' => __('Orderstate 3'), '4' => __('Orderstate 4'), '5' => __('Orderstate 5')]; } public function getShippingstateList() { return ['0' => __('Shippingstate 0'), '1' => __('Shippingstate 1'), '2' => __('Shippingstate 2'), '3' => __('Shippingstate 3')]; } public function getPaystateList() { return ['0' => __('Paystate 0'), '1' => __('Paystate 1')]; } public function getOrderstateTextAttr($value, $data) { $value = $value ? $value : $data['orderstate']; $list = $this->getOrderstateList(); return $list[$value] ?? ''; } public function getShippingstateTextAttr($value, $data) { $value = $value ? $value : $data['shippingstate']; $list = $this->getShippingstateList(); return $list[$value] ?? ''; } public function getPaystateTextAttr($value, $data) { $value = $value ? $value : $data['paystate']; $list = $this->getPaystateList(); return $list[$value] ?? ''; } public function getStatusTextAttr($value, $data) { if ($data['orderstate'] == 0) { if ($data['paystate'] == 0) { return '待付款'; } if ($data['shippingstate'] == 0) { return '待发货'; } elseif ($data['shippingstate'] == 1) { return '待收货'; } elseif ($data['shippingstate'] == 2) { return '待评价'; } } elseif ($data['orderstate'] == 1) { return '已取消'; } elseif ($data['orderstate'] == 2) { return '已失效'; } elseif ($data['orderstate'] == 3) { return '已完成'; } elseif ($data['orderstate'] == 4) { return '退货/退款中'; } return '未知'; } //获取订单剩余有效时长 public function getRemainsecondsAttr($value, $data) { return max(0, $data['expiretime'] - time()); } /** * @ DateTime 2021-05-31 * @ 订单信息 * @param $order_sn * @param $user_id * @return array|false|\PDOStatement|string|Model */ public static function getDetail($order_sn, $user_id) { return self::with(['orderGoods'])->where('order_sn', $order_sn)->where('user_id', $user_id)->find(); } /** * 判断订单是否失效 * @param $order_sn * @return bool */ public static function isExpired($order_sn) { $orderInfo = Order::getByOrderSn($order_sn); //订单过期 if (!$orderInfo['orderstate'] && !$orderInfo['paystate'] && time() > $orderInfo['expiretime']) { // 启动事务 Db::startTrans(); try { $orderInfo->save(['orderstate' => 2]); //库存恢复 OrderGoods::setGoodsStocksInc($orderInfo->order_sn); //恢复优惠券 UserCoupon::resetUserCoupon($orderInfo->user_coupon_id, $orderInfo->order_sn); // 提交事务 Db::commit(); } catch (\Exception $e) { // 回滚事务 Db::rollback(); } return true; } return false; } /** * @ 支付 * @param string $orderid * @param int $user_id * @param string $paytype * @param string $method * @param string $openid * @param string $notifyurl * @param string $returnurl * @return \addons\epay\library\Collection|\addons\epay\library\RedirectResponse|\addons\epay\library\Response|null * @throws \Exception */ public static function pay($orderid, $user_id, $paytype, $method = 'web', $openid = '', $notifyurl = null, $returnurl = null) { $request = \think\Request::instance(); $order = self::getDetail($orderid, $user_id); if (!$order) { throw new \Exception('订单不存在!'); } if ($order->paystate) { throw new \Exception('订单已支付!'); } if ($order->orderstate) { throw new \Exception('订单已失效!'); } //支付金额为0,无需支付 if ($order->saleamount == 0) { throw new \Exception('无需支付!'); } $order_sn = $order->order_sn; // 启动事务 Db::startTrans(); try { //支付方式变更 if (($order['paytype'] == $paytype && $order['method'] != $method)) { $order_sn = date("Ymdhis") . sprintf("%08d", $user_id) . mt_rand(1000, 9999); //更新电子面单 $electronics = $order->order_electronics; foreach ($electronics as $aftersales) { $aftersales->order_sn = $order_sn; $aftersales->save(); } //更新操作日志 $orderAction = $order->order_action; foreach ($orderAction as $action) { $action->order_sn = $order_sn; $action->save(); } $order->save(['order_sn' => $order_sn]); //更新订单明细 foreach ($order->order_goods as $item) { $item->order_sn = $order_sn; $item->save(); } } //更新支付类型和方法 $order->allowField(true)->save(['paytype' => $paytype, 'method' => $method, 'openid' => $openid]); //提交事务 Db::commit(); } catch (\Exception $e) { // 回滚事务 Db::rollback(); throw new \Exception($e->getMessage()); } $response = null; $epay = get_addon_info('epay'); if ($epay && $epay['state']) { $notifyurl = $notifyurl ? $notifyurl : $request->root(true) . '/addons/shop/order/epay/type/notify/paytype/' . $paytype; $returnurl = $returnurl ? $returnurl : $request->root(true) . '/addons/shop/order/epay/type/return/paytype/' . $paytype . '/order_sn/' . $order_sn; //保证取出的金额一致,不一致将导致订单重复错误 $amount = sprintf("%.2f", $order->saleamount); $params = [ 'amount' => $amount, 'orderid' => $order_sn, 'type' => $paytype, 'title' => "支付{$amount}元", 'notifyurl' => $notifyurl, 'returnurl' => $returnurl, 'method' => $method, 'openid' => $openid ]; try { $response = Service::submitOrder($params); } catch (GatewayException $e) { throw new \Exception(config('app_debug') ? $e->getMessage() : "支付失败,请稍后重试"); } } else { throw new \Exception("请在后台安装配置微信支付宝整合插件"); } return $response; } /** * 订单列表 * * @param $param * @return \think\Paginator */ public static function tableList($param) { $pageNum = 15; if (!empty($param['num'])) { $pageNum = $param['num']; } return self::with(['orderGoods']) ->where(function ($query) use ($param) { $query->where('status', 'normal'); if (!empty($param['user_id'])) { $query->where('user_id', $param['user_id']); } if (isset($param['orderstate']) && $param['orderstate'] != '') { $query->where('orderstate', $param['orderstate']); } if (isset($param['shippingstate']) && $param['shippingstate'] != '') { $query->where('shippingstate', $param['shippingstate']); } if (isset($param['paystate']) && $param['paystate'] != '') { $query->where('paystate', $param['paystate']); } if (isset($param['q']) && $param['q'] != '') { $query->where('order_sn', 'in', function ($query) use ($param) { return $query->name('shop_order_goods')->where('order_sn|title', 'like', '%' . $param['q'] . '%')->field('order_sn'); }); } }) ->order('createtime desc')->paginate($pageNum, false, ['query' => request()->get()]); } /** * @ DateTime 2021-06-01 * @ 订单结算 * @param string $order_sn 订单号 * @param float $payamount 支付金额 * @param string $transactionid 流水号 * @return bool */ public static function settle($order_sn, $payamount, $transactionid = '') { $order = self::with(['orderGoods'])->where('order_sn', $order_sn)->find(); if (!$order || $order->paystate == 1) { return false; } if ($payamount != $order->saleamount) { \think\Log::write("[shop][pay][{$order_sn}][订单支付金额不一致]"); return false; } // 启动事务 Db::startTrans(); try { $order->paystate = 1; $order->transactionid = $transactionid; $order->payamount = $payamount; $order->paytime = time(); $order->paytype = !$order->paytype ? 'system' : $order->paytype; $order->method = !$order->method ? 'system' : $order->method; $order->save(); if ($order->payamount == $order->saleamount) { //支付完成后,商品销量+1 foreach ($order->order_goods as $item) { $goods = $item->goods; $sku = $item->sku; if ($goods) { $goods->setInc('sales', $item->nums); } if ($sku) { $sku->setInc('sales', $item->nums); } } } // 提交事务 Db::commit(); } catch (\Exception $e) { // 回滚事务 Db::rollback(); return false; } //记录操作 OrderAction::push($order_sn, '系统', '订单支付成功'); //发送通知 TemplateMsg::sendTempMsg(0, $order->order_sn); return true; } public function user() { return $this->belongsTo('User', 'user_id', 'id', [], 'LEFT')->setEagerlyType(0); } public function address() { return $this->belongsTo('Address', 'address_id', 'id', [], 'LEFT')->setEagerlyType(0); } public function orderGoods() { return $this->hasMany('OrderGoods', 'order_sn', 'order_sn'); } public function orderElectronics() { return $this->hasMany('OrderElectronics', 'order_sn', 'order_sn'); } public function orderAction() { return $this->hasMany('OrderAction', 'order_sn', 'order_sn'); } }