$params['address_id']]); } // 订单需支付总金额 $order_amount = 0; $goods_price = 0; $goods = IntegralGoods::withoutField(['content', 'update_time'])->findOrEmpty($params['id'])->toArray(); // 兑换方式为纯积分 if ($goods['exchange_way'] == IntegralGoodsEnum::EXCHANGE_WAY_INTEGRAL) { // 订单需支付积分 $order_integral = $goods['need_integral'] * $params['num']; } else { // 订单需支付总金额 $goods_price = $goods['need_money'] * $params['num']; $order_amount = $goods_price; // 订单需支付总积分 $order_integral = $goods['need_integral'] * $params['num']; } // 运费 $shipping_price = 0; // 快递配送 && 快递统一运费 && 运费>0 if ($goods['delivery_way'] == IntegralGoodsEnum::DELIVERY_EXPRESS && $goods['express_type'] == IntegralGoodsEnum::EXPRESS_TYPE_UNIFIED && $goods['express_money'] > 0) { $order_amount = $order_amount + $goods['express_money']; $shipping_price = $goods['express_money']; } return [ 'address' => $address, 'goods' => $goods, 'need_pay' => $order_amount > 0 ? 1 : 0, 'exchange_way' => $goods['exchange_way'], 'delivery_way' => $goods['delivery_way'], 'total_num' => intval($params['num']), 'shipping_price' => $shipping_price, // 运费 'goods_price' => round($goods_price, 2), // 商品金额(不包含运费) 'order_amount' => round($order_amount, 2), // 订单需要的金额(包含运费) 'order_integral' => $order_integral, // 订单需要返回的积分 ]; } /** * @notes 提交订单 * @param $params * @return array|false * @author 段誉 * @date 2022/3/2 9:50 */ public static function submitOrder($params) { Db::startTrans(); try { // 结算详情(支付积分,支付金额) $settle = self::settlement($params); // 提交前验证 $user = User::findOrEmpty($params['user_id']); if ($user['user_integral'] < $settle['order_integral']) { throw new \Exception('积分不足'); } $settle['goods']['image'] = UrlServer::setFileUrl($settle['goods']['image']); // 提交订单 $order = IntegralOrder::create([ 'order_sn' => createSn('integral_order', 'order_sn'), 'user_id' => $params['user_id'], 'order_source' => $params['client'], 'delivery_way' => $settle['goods']['delivery_way'], 'exchange_type' => $settle['goods']['type'], 'exchange_way' => $settle['goods']['exchange_way'], 'consignee' => $settle['address']['contact'], 'province' => $settle['address']['province_id'], 'city' => $settle['address']['city_id'], 'district' => $settle['address']['district_id'], 'address' => $settle['address']['address'], 'mobile' => $settle['address']['telephone'], 'order_amount' => $settle['order_amount'], 'order_integral' => $settle['order_integral'], 'total_num' => $settle['total_num'], 'goods_price' => $settle['goods_price'], 'shipping_price' => $settle['shipping_price'], 'user_remark' => $params['user_remark'] ?? '', 'goods_snap' => $settle['goods'] ]); // 扣减应付积分 if ($settle['order_integral'] > 0) { User::where(['id' => $params['user_id']]) ->dec('user_integral', $settle['order_integral']) ->update(); AccountLogLogic::AccountRecord( $params['user_id'], $settle['order_integral'], 2, AccountLog::pay_integral_order, '', $order['id'], $order['order_sn'] ); } // 兑换方式-积分 且没有运费 扣减积分后 直接支付完成 if ($settle['goods']['exchange_way'] == IntegralGoodsEnum::EXCHANGE_WAY_INTEGRAL && $settle['order_amount'] <= 0) { PayNotifyLogic::handle('integral', $order['order_sn']); } Db::commit(); return ['order_id' => $order['id'], 'type' => 'integral']; } catch (\Exception $e) { Db::rollback(); self::$error = $e->getMessage(); return false; } } /** * @notes 订单列表 * @param $user_id * @param $type * @param $page * @param $size * @return array * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException * @author 段誉 * @date 2022/3/2 9:39 */ public static function lists($user_id, $type, $page, $size) { $order = new IntegralOrder(); $where[] = ['del', '=', 0]; $where[] = ['user_id', '=', $user_id]; if (isset($type) && $type != '') { $where[] = ['order_status', '=', $type]; } $field = [ 'id', 'order_sn', 'order_status', 'pay_status', 'shipping_status', 'shipping_price', 'delivery_way', 'order_amount', 'total_num', 'order_integral', 'goods_snap', 'create_time', 'refund_status' ]; $count = $order->where($where)->count(); $lists = $order->where($where)->field($field)->page($page, $size) ->order('id desc') ->append(['btns']) ->select()->toArray(); foreach ($lists as &$item) { $item['order_status'] = IntegralOrderEnum::getOrderStatus($item['order_status']); $goods = $item['goods_snap']; $item['goods'] = [ 'image' => UrlServer::getFileUrl($goods['image']), 'name' => $goods['name'], 'need_integral' => $goods['need_integral'], 'need_money' => $goods['need_money'], 'exchange_way' => $goods['exchange_way'], ]; unset($item['goods_snap']); } $data = [ 'list' => $lists, 'page' => $page, 'size' => $size, 'count' => $count, 'more' => is_more($count, $page, $size) ]; return $data; } /** * @notes 订单详情 * @param $id * @return array * @author 段誉 * @date 2022/3/2 10:22 */ public static function detail($id) { $order = IntegralOrder::where(['id' => $id]) ->withoutField(['content', 'order_source', 'transaction_id', 'refund_amount']) ->append(['delivery_address', 'pay_time', 'btns']) ->findOrEmpty()->toArray(); $order['pay_time'] = $order['pay_time'] ? date('Y-m-d H:i:s', $order['pay_time']) : '-' ; $order['shipping_time'] = $order['shipping_time'] ? date('Y-m-d H:i:s', $order['shipping_time']) : '-' ; $order['pay_way'] = PayEnum::getPayWay($order['pay_way']); $goods_snap = $order['goods_snap']; unset($order['goods_snap']); $order['goods'] = [ 'image' => UrlServer::getFileUrl($goods_snap['image']), 'name' => $goods_snap['name'], 'exchange_way' => $goods_snap['exchange_way'], 'need_integral' => $goods_snap['need_integral'], 'need_money' => $goods_snap['need_money'], 'total_num' => $order['total_num'], ]; return $order; } /** * @notes 确认收货 * @param $id * @param $user_id * @author 段誉 * @date 2022/3/2 10:59 */ public static function confirm($id, $user_id) { //更新订单状态 IntegralOrder::update([ 'order_status' => IntegralOrderEnum::ORDER_STATUS_COMPLETE, 'confirm_time' => time(), ], ['id' => $id, 'user_id' => $user_id]); } /** * @notes 删除订单 * @param $id * @param $user_id * @author 段誉 * @date 2022/3/2 10:59 */ public static function del($id, $user_id) { //更新订单状态 IntegralOrder::update(['del' => 1], ['id' => $id, 'user_id' => $user_id]); } /** * @notes 取消订单 * @param $id * @return bool * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException * @author 段誉 * @date 2022/3/3 14:56 */ public static function cancel($id) { Db::startTrans(); try { $order = IntegralOrder::findOrEmpty($id); // 更新订单状态, 退回库存, 扣减销量 IntegralOrderRefundLogic::cancelOrder($id); // 退回已支付积分 IntegralOrderRefundLogic::refundOrderIntegral($id); // 退回订单已支付积分或已支付金额 if ($order['pay_status'] == PayEnum::ISPAID) { IntegralOrderRefundLogic::refundOrderAmount($id); } Db::commit(); return true; } catch (\Exception $e) { Db::rollback(); self::$error = $e->getMessage(); IntegralOrderRefundLogic::addRefundLog( $order, $order['order_amount'], 2, $e->getMessage() ); return false; } } /** * @notes 订单物流轨迹 * @param $id * @return array * @author 段誉 * @date 2022/3/3 17:29 */ public static function orderTraces($id) { $order = IntegralOrder::alias('o') ->field('invoice_no, shipping_name, shipping_id, send_type, o.shipping_status, o.mobile, o.province, o.city, o.district, o.address,o.total_num,o.goods_snap') ->join('integral_delivery d', 'd.order_id = o.id') ->where(['o.id' => $id]) ->findOrEmpty(); if ($order->isEmpty() || $order['send_type'] != 1) { return []; } //数据合并 $order_traces = [ 'order' => [ 'tips' => self::getTracesOrderTips($order), 'image' => UrlServer::getFileUrl($order['goods_snap']['image']), 'count' => $order['total_num'], 'invoice_no' => $order['invoice_no'], 'shipping_name' => empty($order['shipping_name']) ? '-' : $order['shipping_name'], ], 'take' => [ 'contacts' => $order['consignee'], 'mobile' => $order['mobile'], 'address' => $order['delivery_address'], ], 'finish' => self::getTracesFinish($order), 'delivery' => [ 'title' => '运输中', 'traces' => self::getTraces($order) ], 'shipment' => self::getTracesShipment($order), 'buy' => [ 'title' => '已下单', 'tips' => '订单提交成功', 'time' => date('Y-m-d H:i:s', $order['pay_time']) ], ]; return $order_traces; } /** * @notes 订单物流-备注信息 * @param $order * @return string * @author 段誉 * @date 2022/3/3 17:30 */ public static function getTracesOrderTips($order) { $order_tips = '已下单'; //确认收货 if ($order['order_status'] == IntegralOrderEnum::ORDER_STATUS_COMPLETE) { $order_tips = '交易完成'; } return $order_tips; } /** * @notes 订单物流-待收货信息 * @param $order * @return string[] * @author 段誉 * @date 2022/3/3 17:30 */ public static function getTracesShipment($order) { $shipment = [ 'title' => '已发货', 'tips' => '', 'time' => '', ]; //待收货 if ($order['order_status'] == IntegralOrderEnum::ORDER_STATUS_GOODS) { $shipment['tips'] = '商品已出库'; $shipment['time'] = date('Y-m-d H:i:s', $order['shipping_time']); } return $shipment; } /** * @notes 订单物流-订单完成信息 * @param $order * @return string[] * @author 段誉 * @date 2022/3/3 17:30 */ public static function getTracesFinish($order) { $finish = [ 'title' => '交易完成', 'tips' => '', 'time' => '', ]; //确认收货 if ($order['order_status'] == IntegralOrderEnum::ORDER_STATUS_COMPLETE) { $finish['tips'] = '订单交易完成'; $finish['time'] = $order['confirm_time'] ? date('Y-m-d H:i:s', $order['confirm_time']) : $order['confirm_time']; } return $finish; } /** * @notes 订单物流-物流轨迹 * @param $order * @return array|bool * @author 段誉 * @date 2022/3/3 17:31 */ public static function getTraces($order) { $express = ConfigServer::get('express', 'way', '', ''); $key = ConfigServer::get($express, 'appkey'); $app = ConfigServer::get($express, 'appsecret'); // 没有配置,没有发货 if (empty($express) || empty($key) || empty($app) || $order['shipping_status'] != IntegralOrderEnum::SHIPPING_FINISH) { return []; } //快递配置设置为快递鸟时 if ($express === 'kdniao') { $expressage = (new Kdniao($app, $key, Env::get('app.app_debug', 'true'))); $shipping_field = 'codebird'; } else { $expressage = (new Kd100($app, $key, Env::get('app.app_debug', 'true'))); $shipping_field = 'code100'; } //快递编码 $shipping_code = Db::name('express')->where(['id' => $order['shipping_id']])->value($shipping_field); //获取物流轨迹 if ($shipping_code === 'SF' && $express === 'kdniao') { $expressage->logistics($shipping_code, $order['invoice_no'], substr($order['mobile'], -4)); } else { $expressage->logistics($shipping_code, $order['invoice_no']); } $traces = $expressage->logisticsFormat(); //获取不到物流轨迹时 if ($traces == false) { $error = $expressage->getError(); $error = json_decode($error, true); if ($express === 'kdniao') { if ($error['Success'] == false) { $traces[] = [$error['Reason']]; } } else { if ($error['result'] == false) { $traces[] = [$error['message']]; } } } else { foreach ($traces as &$item) { $item = array_values(array_unique($item)); } } return $traces; } }