0, 11 => 1, 12 => 2]; protected static $payChannels = [10 => 'wx', 11 => 'alipay', 12 => 'bank']; protected $blocs; protected $packages; protected $products; protected $limit = 1; const FILENAME = 'app/command/sync-card.json'; const INIT_ID = 0; public function handle() { $contents = $this->getFile(); $maxId = $contents['maxId']; $nextId = $contents['maxId']; $this->saveFile(1, $maxId); $query = DB::connection('vd_old')->table('ckb_custom') ->select(['id', 'custom_no', 'imsi', 'carrieroperator', 'iccid', 'card_number', 'card_from', 'iccid', 'company', 'custom_state', 'create_time' ,'update_time']) ->where('id', '>', $maxId); $logQuery = DB::connection('vd_old')->table('ckb_custom_handle_log') ->select(['type', 'company', 'pay_type', 'content', 'valid_start_time', 'valid_end_time', 'sale_account', 'order_account', 'create_time']); $total = $query->count(); $this->line('待同步条数:' . $total); if ($total) { $this->blocs = app(BlocRepository::class)->get()->pluck('id', 'shorthand')->toArray(); $this->packages = app(PackageRepository::class)->get()->keyBy('sn'); $this->products = app(ProductRepository::class)->get()->keyBy('sn'); } $page = 1; while ($total) { echo $page . PHP_EOL; $value = $query->offset(($page - 1) * $this->limit)->limit($this->limit)->get()->first(); if (!$value) { break; } $value = (array)$value; $logs = $logQuery->where('custom_no', $value['custom_no'])->get()->collect(); $existed = Card::where('sim', $value['card_number'])->first(); DB::beginTransaction(); try { $card = $this->handleCard($value, $logs, $existed); $this->handleOrder($card, $logs, $existed); $this->handleRenewals($card, $logs, $existed); $this->handleRenewalPackages($card, $logs, $existed); $this->handleFlows($card, $logs, $existed); DB::commit(); } catch (\Exception $e) { DB::rollback(); throw $e; } $nextId = $value['id']; if ($page * $this->limit >= $total) { break; } $page++; } app(CardRepository::class)->forgetCached(); $this->saveFile(0, $nextId); } // 卡数据转换 protected function handleCard($value, $logs, $existed) { // 判断卡类型 $type = ($value['card_number'][3] >= 5) ? 1 : ($existed ? 0 : 2); // 激活记录 $activateLog = $logs->where('type', 10)->first(); $activated_at = $activateLog ? date('Y-m-d H:i:s', $activateLog['valid_start_time']) : null; $cardData = [ 'sim' => $value['card_number'], 'imsi' => $value['imsi'], 'iccid' => $value['iccid'], 'bloc_id' => $this->blocs[$value['card_from']] ?? 0, 'carrier_operator' => self::$carrierOperators[$value['carrieroperator']], 'activated_at' => $existed['activated_at'] ?? $activated_at, 'virtual_activated_at' => $activated_at, 'type' => $type, 'cancelled_at' => ($value['custom_state'] === 13) ? date('Y-m-d H:i:s', $value['update_time']) : null, 'created_at' => date('Y-m-d H:i:s', $value['create_time']), 'updated_at' => date('Y-m-d H:i:s', $value['update_time']), ]; if ($existed) { $card = Card::where('sim', $card['sim'])->update($cardData); } else { $card = Card::create($cardData); } return $card; } // 销售记录 protected function handleOrder($card, $logs, $existed) { if (!$res = $logs->where('type', 13)->first()) { return null; } $package = $this->getPackage($res['content']); $unit_price = floatval($res['sale_account']) * 100; $custom_price = floatval($res['order_account']) * 100; $product = $this->getProduct($package, $res['company'], $unit_price); // 按规则生成订单编号 (月+公司+产品) $sn = date('Ym', $res['create_time']) . sprintf('%08d', $custom_price) . sprintf('%04d', $product['id']); $orderData = [ 'sn' => $sn, 'source' => 1, 'type' => 0, 'company_id' => $res['company'], 'package_id' => $package['id'], 'product_id' => $product['id'], 'pay_channel' => self::$payChannels[$res['pay_type']], 'unit_price' => $unit_price, 'counts' => 1, 'total_price' => $unit_price, 'custom_price' => $custom_price, 'order_at' => date('Y-m-d H:i:s', $res['create_time']), 'order_status' => 4, 'transaction_status' => 1, 'created_at' => date('Y-m-d H:i:s', $res['create_time']), ]; if ($order = Order::where('sn', $orderData['sn'])->first()) { $order->counts = $order->counts + 1; $order->total_price = $order->total_price + $unit_price; $order->custom_price = $order->custom_price + $custom_price; $order->save(); } else { $order = Order::create($orderData); } OrderCard::upsert([ 'sim' => $card['sim'], 'order_id' => $order['id'], 'company_id' => $order['company_id'], 'package_id' => $order['package_id'], ], ['sim', 'order_id']); } // 续费记录 protected function handleRenewals($card, $logs, $existed) { $res = $logs->where('type', 11)->values()->all(); if (empty($res)) { return ; } $array = []; foreach ($res as $item) { $package = $this->getPackage($item['content']); $unit_price = floatval($item['sale_account']) * 100; $custom_price = floatval($item['order_account']) * 100; $sn = date('Ym', $item['create_time']) . sprintf('%04d', $item['company']) . sprintf('%04d', $package['id']) . sprintf('%04d', $custom_price); if (!$array[$sn]) { $array[$sn] = [ 'sn' => $sn, 'type' => 1, 'company_id' => $item['company'], 'package_id' => $package->id, 'unit_price' => $unit_price, 'counts' => 1, 'total_price' => $unit_price, 'custom_price' => $custom_price, 'order_at' => date('Y-m-d H:i:s', $item['create_time']), ]; } else { $array[$sn] = []; } if ($order = Order::where('sn', $orderData['sn'])->first()) { $order->counts = $order->counts + 1; $order->total_price = $order->total_price + $unit_price; $order->custom_price = $order->custom_price + $custom_price; $order->save(); } else { $order = Order::create($orderData); } if ($orderRenewalCard = OrderRenewalCard::where('sim', $card['sim'])->where('order_id', $order->id)->first()) { $orderRenewalCard->count = $orderRenewalCard->count + 1; $orderRenewalCard->save(); } else { OrderRenewalCard::upsert([ 'sim' => $card->sim, 'order_id' => $order->id, 'company_id' => $order->company_id, 'package_id' => $order->package_id, 'counts' => 1, 'unit_price' => $order->unit_price ], ['sim', 'order_id']); } } } // 续费包记录 protected function handleRenewalPackages($card, $logs, $existed) { $res = $logs->where('type', 14)->values()->all(); if (empty($res)) { return ; } foreach ($res as $item) { $package = $this->getPackage($item['content']); $unit_price = floatval($item['sale_account']) * 100; $custom_price = floatval($item['order_account']) * 100; $sn = date('Ym', $item['create_time']) . sprintf('%04d', $item['company']) . sprintf('%04d', $package['id']) . sprintf('%04d', $custom_price); $array[] = [ 'sn' => $sn, 'type' => 2, 'company_id' => $item['company'], 'unit_price' => $unit_price, 'counts' => DB::raw('counts + 1'), 'total_price' => DB::raw("total_price + {$unit_price}"), 'custom_price' => DB::raw("custom_price + {$custom_price}"), 'order_at' => date('Y-m-d H:i:s', $item['create_time']), ]; } } // 加油包记录 protected function handleFlows($card, $logs, $existed) { $res = $logs->where('type', 15)->values()->all(); if (empty($res)) { return ; } foreach ($res as $item) { $package = $this->getPackage($item['content']); $unit_price = floatval($item['sale_account']) * 100; $custom_price = floatval($item['order_account']) * 100; $sn = date('Ym', $item['create_time']) . sprintf('%04d', $item['company']) . sprintf('%04d', $package['id']) . sprintf('%04d', $custom_price); $array[] = [ 'sn' => $sn, 'type' => 3, 'company_id' => $item['company'], 'unit_price' => $unit_price, 'counts' => DB::raw('counts + 1'), 'total_price' => DB::raw("total_price + {$unit_price}"), 'custom_price' => DB::raw("custom_price + {$custom_price}"), 'order_at' => date('Y-m-d H:i:s', $item['create_time']), ]; } } /** * 获取套餐 * * @param string $sn * @return void */ protected function getPackage($sn) { if (!$package = $this->packages[$sn]) { throw new \Exception('套餐不存在'); } return $package; } /** * 获取定价 * * @param string $sn * @return void */ protected function getProduct($package, $companyId, $price) { $sn = strtoupper($package['sn'] . '_' . $companyId . '_' . $price); if (!$product = $this->products[$sn]) { $product = app(ProductService::class)->store([ 'name' => $package['name'] . '' . $price, 'company_id' => $companyId, 'package_id' => $package['id'], 'base_price' => $price, 'renewal_price' => $price, ]); $this->products[$sn] = $product; } return $product; } /** * 获取文件内容 * * @return void */ protected function getFile() { $file = storage_path(self::FILENAME); if (!file_exists($file)) { $dir = dirname($file); if (null !== $dir && !is_dir($dir)) { mkdir($dir, 0777, true); } $this->saveFile(0, self::INIT_ID); } $contents = file_get_contents($file); return json_decode($contents, 256); } /** * 写入文件 * * @param integer $status 状态 1运行中 0运行结束 * @param integer $maxId 最后查询的ID * @return void */ protected function saveFile(int $status, int $maxId) { $file = storage_path(self::FILENAME); $contents = json_encode([ 'status' => $status, 'maxId' => $maxId, ]); file_put_contents($file, $contents); } }