orderRepository = $orderRepository; $this->orderCardPartitionRepository = $orderCardPartitionRepository; } /** * 订单列表 * * @param array $conditions * @return mixed */ public function paginate(array $conditions = []) { $limit = $conditions['limit'] ?? 35; $res = $this->orderRepository->withConditions($conditions)->applyConditions()->orderBy('order_at', 'desc')->paginate($limit); $orderShipments = $this->orderCardPartitionRepository->select([ 'order_id', DB::raw('SUM(counts) as counts'), ])->withConditions($conditions)->groupBy('order_id')->get()->keyBy('order_id'); $res->map(function ($item) use ($orderShipments) { $item->company = CompanyService::load($item->company_id); $item->package = PackageService::load($item->package_id); $item->unit_price = sprintf('%.02f', $item->unit_price/100); $item->total_price = sprintf('%.02f', $item->total_price/100); $item->custom_price = sprintf('%.02f', $item->custom_price/100); $item->shipments = $orderShipments[$item->id]['counts'] ?? 0; }); return $res; } /** * 订单计数 * * @param array $conditions * @return mixed */ public function count(array $conditions = []) { $select = [ DB::raw('COUNT(*) as total_count'), DB::raw('SUM(custom_price) as total_price'), DB::raw('SUM(CASE WHEN transaction_status=1 THEN custom_price ELSE 0 END) as transacted_price'), ]; $res = $this->orderRepository->select($select)->withConditions($conditions)->applyConditions()->first()->toArray(); $res['total_price'] = $res['total_price'] ?? 0; $res['total_price'] = sprintf('%.02f', $res['total_price']/100); $res['transacted_price'] = $res['transacted_price'] ?? 0; $res['transacted_price'] = sprintf('%.02f', $res['transacted_price']/100); unset($res['company']); unset($res['package']); return $res; } /** * 下单 * * @param array $attributes * @return Order */ public function store(array $attributes = []) { $rule = [ 'type' => ['in:0,1,2,3'], 'company_id' => ['exists:virtual_companies,id'], 'product_id' => [], 'counts' => [], 'pay_channel' => [Rule::in(array_collapse(app(Dicts::class)->get('pay_channel')))], 'order_status' => ['in:0,1,2,3,4'], 'transaction_status' => ['in:0,1,2'], 'extends' => ['array'], ]; $message = [ 'company_id.required' => '请输入企业ID', 'company_id.exists' => '企业不存在或已删除', 'product_id.required' => '请选择套餐', 'counts.required' => '请输入订购数量', 'pay_channel.required' => '请选择支付方式', 'pay_channel.in' => '支付方式不合法', 'contacts.required' => '请选择收货地址', 'mobile.required' => '请选择收货地址', 'address.required' => '请选择收货地址', ]; DB::beginTransaction(); if (!$attributes['id']) { $attributes['sn'] = $attributes['sn'] ?: $this->generateSn(); if ($attributes['company_id'] && $attributes['package_id'] && isset($attributes['unit_price'])) { $attributes['unit_price'] = intval($attributes['unit_price'] * 100); $product = ProductService::getProduct($attributes['company_id'], $attributes['package_id'], $attributes['unit_price']); } elseif ($attributes['product_id']) { $product = app(ProductRepository::class)->find($attributes['product_id']); } if (!$product) { throw new NotExistException('请选择套餐'); } $attributes['product_id'] = $product->id; $rule['type'][] = 'required'; $rule['company_id'][] = 'required'; $rule['product_id'][] = 'required'; $rule['counts'][] = 'required'; $rule['pay_channel'][] = 'required'; if (!$attributes['source']) { $rule['contacts'][] = 'required'; $rule['mobile'][] = 'required'; $rule['address'][] = 'required'; } } Validator::validate($attributes, $rule, $message); if (!$attributes['id']) { if ($product->company_id != $attributes['company_id']) { throw new NotAllowedException('非法操作'); } $attributes['price'] = $product->price; $attributes['total_price'] = $attributes['unit_price'] * $attributes['counts']; $attributes['custom_price'] = $attributes['unit_price'] * $attributes['counts']; $attributes['order_at'] = $attributes['order_at'] ?? date('Y-m-d H:i:s'); $attributes['package_id'] = $attributes['package_id'] ?? $product->package_id; $node = $this->orderRepository->create($attributes); } if ($attributes['id']) { if (!$node = $this->orderRepository->find($attributes['id'])) { throw new NotExistException('订单不存在或已删除'); } if (!empty($attributes['extends']) && is_array($attributes['extends'])) { $attributes['extends'] = array_merge($node->extends ?: [], $attributes['extends']); } $this->orderRepository->setModel($node)->update($attributes); } if ($attributes['selected']) { try { $table = $this->tables[$node['type']]; $cards = array_pluck($attributes['selected'], 'cards'); $cards = array_collapse($cards); $data = []; foreach ($cards as $card) { $data[] = [ 'sim' => $card['sim'], 'counts' => $card['counts'], 'type' => $node['type'], 'order_id' => $node['id'], 'company_id' => $node['company_id'], 'package_id' => $node['package_id'], 'product_id' => $node['product_id'], 'unit_price' => $node['unit_price'], 'created_at' => $node['order_at'], 'updated_at' => date('Y-m-d H:i:s'), ]; } if (!empty($data)) { $array = array_chunk($data, 1000); foreach ($array as $value) { DB::table($table)->upsert($value, ['sim', 'order_id', 'deleted_at']); $simArray = implode(',', array_pluck($value, 'sim')); DB::statement("select fix_timelines('{{$simArray}}'::INT8[]);"); RealOrderCardPartition::whereIn('order_id', array_pluck($attributes['selected'], 'id')) ->whereIn('sim', array_pluck($value, 'sim'))->update(['virtual_order_id' => $node['id']]); } } $this->orderRepository->forgetCached(); app(RealOrderCardPartitionRepository::class)->forgetCached(); app(RealOrderRepository::class)->forgetCached(); } catch (\Exception $e) { DB::rollBack(); throw new HttpException('操作失败'); } } DB::commit(); return $node; } /** * 取消订单 * * @return bool */ public function cancel($id) { if (!$node = $this->orderRepository->find($id)) { throw new NotExistException('订单不存在或已删除'); } if ($node->order_status !== 0) { throw new NotExistException('订单已出库,不能取消'); } if ($node->transaction_status !== 0) { throw new NotExistException('订单已付款,不能取消'); } $this->orderRepository->setModel($node)->update(['order_status' => 1]); return $node; } /** * 确认收货 * * @return bool */ public function received($id) { if (!$node = $this->orderRepository->find($id)) { throw new NotExistException('订单不存在或已删除'); } if ($node->order_status !== 3) { throw new NotExistException('订单未发货,不能修改'); } $this->orderRepository->setModel($node)->update(['order_status' => 4]); return $node; } /** * 删除 * * @return bool */ public function destroy($ids) { $ids = is_array($ids) ? $ids : [$ids]; foreach ($ids as $id) { if (!$node = $this->orderRepository->find($id)) { throw new NotExistException('订单不存在或已删除'); } } DB::transaction(function () use ($ids) { $this->orderRepository->destroy($ids); $this->orderCardPartitionRepository->whereIn('order_id', $ids)->delete(); app(RealOrderCardPartitionRepository::class)->whereIn('virtual_order_id', $ids)->update(['virtual_order_id' => 0]); }); app(RealOrderCardPartitionRepository::class)->forgetCached(); app(RealOrderRepository::class)->forgetCached(); return true; } /** * 生成订单编号 * * @return void */ public function generateSn() { return date('YmdHis') .sprintf('%04d', explode('.', microtime(true))[1]) . sprintf('%02d', rand(0, 99)); } }