修改_零时提交

This commit is contained in:
邓皓元 2018-12-07 19:03:07 +08:00
parent 169a6ac86b
commit 1ab0fc98a8
22 changed files with 539 additions and 489 deletions

View File

@ -35,10 +35,11 @@ class ActivateSync extends Command
$this->line('拼装更新数据:'.count($res));
$chucks = array_chunk($res, $this->chunks);
foreach ($chucks as $chuck) {
echo '.';
$cards = Card::select(['sim', 'package_id'])->whereIn('sim', array_pluck($chuck, 'cNo'))->get()->keyBy('sim')->toArray();
$total += count($cards);
$total += count($chuck);
foreach ($chuck as $card) {
$value = $cards[$card['cNo']];
@ -51,7 +52,7 @@ class ActivateSync extends Command
$activate_at = $card['saDate']->toDateTime()->format('Y-m-d H:i:s');
$list[] = [
'sim' => $value['sim'],
'sim' => intval($value['sim']),
'activate_at' => $activate_at,
];
}
@ -59,13 +60,13 @@ class ActivateSync extends Command
$this->line('更新卡表数据,总计更新条数:' . count($list));
$except = count($list) - $total;
$except = $total - count($list);
$this->line("其中有{$except}张卡不在表内");
foreach (array_chunk($list, 3000) as $data) {
foreach (array_chunk($list, $this->chunks) as $data) {
echo '.';
app(CardRepository::class)->updateActivateAt($data);
app(CardRepository::class)->where('sim')->updateActivateAt($data);
}
app(CardRepository::class)->forgetCached();

View File

@ -19,7 +19,7 @@ class BlocSync extends Command
{
$datetime = $this->getDateTime();
$select = ['bloc_code as id', "bloc_name as name", 'carrieroperator as carrier_operator', 'create_time as created_at', 'del'];
$select = ['id', 'bloc_code as sn', "bloc_name as name", 'carrieroperator as carrier_operator', 'create_time as created_at', 'del'];
$blocs = DB::connection('real')->table('jxc_bloc_manage')->select($select)->get()->toArray();
$carders = DB::connection('real')->table('jxc_carder_manage')->select(['bloc_code', 'inside_card_from_sn'])->get()->toArray();

View File

@ -18,7 +18,7 @@ class CompanySync extends Command
{
$datetime = $this->getDateTime();
$sql = "SELECT c.custom_no AS id,c.name,c.create_time AS created_at,c.del FROM jxc_user a
$sql = "SELECT c.id,c.custom_no AS sn,c.name,c.create_time AS created_at,c.del FROM jxc_user a
INNER JOIN jxc_user_custom_relation b ON a.id=b.uid
INNER JOIN jxc_custom c ON b.custom_no=c.custom_no
WHERE a.parent_user IN (SELECT id FROM jxc_user WHERE parent_user=3 AND role_tag='normal')";
@ -27,7 +27,6 @@ class CompanySync extends Command
foreach ($data as &$item) {
$item = (array)$item;
$item['id'] = CommonService::parseCompanyId($item['id']);
$item['created_at'] = Carbon::parse($item['created_at']);
$item['updated_at'] = date('Y-m-d H:i:s');
$item['deleted_at'] = $item['del'] ? date('Y-m-d H:i:s') : null;

View File

@ -0,0 +1,94 @@
<?php
namespace App\Domains\Real\Commands\Sync;
use Carbon\Carbon;
use App\Models\Real\Card;
use MongoDB\BSON\UTCDateTime;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use App\Domains\Real\Repositories\CardRepository;
class MongoSync extends Command
{
protected $name = 'real:sync-mongo';
protected $description = '同步卡基础信息数据';
protected static $carrierOperators = [1, 0, 2];
protected $limit = 10;
const FILENAME = 'app/command/sync-mongo.json';
const INIT_MICROTIME = 946656000000; // '2000-01-01 00:00:00'
public function handle()
{
$contents = $this->getFile();
$microtime = $contents['microtime'];
$this->saveFile(1, $microtime);
$utcDateTime = new UTCDateTime($microtime);
$query = DB::connection('mongo')->table('tblCard')->select(['cNo', 'iccid', 'imsi', 'comId', 'oType'])->where('isDel', '<>', 1)->where('sDate', '>', $utcDateTime);
$total = $query->count();
$page = 1;
while ($total) {
$res = $query->offset(($page - 1) * $limit)->limit($limit)->get();
dd($res);
if ($page * $limit >= $total) {
break;
}
}
$this->saveFile(0, $microtime);
}
/**
* 获取文件内容
*
* @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_MICROTIME);
}
$contents = file_get_contents($file);
return json_decode($contents, 256);
}
/**
* 写入文件
*
* @param integer $status 状态 1运行中 0运行结束
* @param integer $microtime 最后查询时间
* @return void
*/
protected function saveFile(int $status, int $microtime)
{
$file = storage_path(self::FILENAME);
$contents = json_encode([
'status' => $status,
'microtime' => $microtime,
]);
file_put_contents($file, $contents);
}
}

View File

@ -7,9 +7,11 @@ use App\Models\Real\Card;
use App\Models\Real\Order;
use Illuminate\Support\Facades\DB;
use App\Domains\Real\Services\CommonService;
use App\Domains\Real\Repositories\BlocRepository;
use App\Domains\Real\Repositories\CardRepository;
use App\Domains\Real\Repositories\OrderRepository;
use App\Domains\Real\Repositories\CompanyRepository;
use App\Domains\Real\Repositories\PackageRepository;
class OrderBaseSync extends Command
{
@ -23,49 +25,62 @@ class OrderBaseSync extends Command
protected static $carrierOperators = [1, 0, 2];
protected $chunks = 1000;
protected $chunks = 2000;
public function handle()
{
$this->companies = app(CompanyRepository::class)->get()->pluck('name', 'id')->toArray();
$cards = $this->getCards();
$this->companies = app(CompanyRepository::class)->get()->keyBy('sn');
$this->packages = app(PackageRepository::class)->get()->keyBy('sn');
$this->blocs = app(BlocRepository::class)->get()->keyBy('sn');
$this->chunks *
$bar = $this->output->createProgressBar(count($cards));
$orders = $this->getOrders();
$cards = $this->getCards($orders);
$card_details = $this->getCardDetails($cards);
list($dataOrders, $dataCards, $dataOrderCards) = $this->transforms($cards, $card_details);
unset($cards);
unset($card_details);
try {
$this->line('插入订单数据,条数:'.count($dataOrders));
foreach (array_chunk($dataOrders, $this->chunks) as $data) {
$this->line('插入订单数据,条数:'.count($orders));
foreach (array_chunk($orders, $this->chunks) as $data) {
echo '.';
foreach ($data as &$item) {
unset($item['package_id']);
}
Order::upsert($data, 'id');
}
app(OrderRepository::class)->forgetCached();
unset($dataOrders);
$this->line('插入订单数据成功');
$this->line('插入卡数据,条数:'.count($dataCards));
foreach (array_chunk($dataCards, $this->chunks) as $data) {
$this->line('插入卡数据,条数:'.count($cards));
foreach (array_chunk($cards, $this->chunks) as $data) {
echo '.';
Card::upsert($data, 'sim');
foreach ($data as &$item) {
unset($item['order_id']);
unset($item['order_at']);
}
Card::upsert($data, 'sim,deleted_at');
}
app(CardRepository::class)->forgetCached();
unset($dataCards);
$this->line('插入卡数据成功');
$this->line('插入订单关联数据,条数:'.count($dataOrderCards));
foreach (array_chunk($dataOrderCards, $this->chunks) as $data) {
$this->line('插入订单关联数据,条数:'.count($cards));
foreach (array_chunk($cards, $this->chunks) as $data) {
echo '.';
DB::table('real_order_base_cards')->upsert($data, 'sim');
$card_ids = app(CardRepository::class)->select(['id', 'sim'])->whereIn('sim', array_pluck($data, 'sim'))->get()->pluck('id', 'sim')->toArray();
$array = [];
foreach ($data as $item) {
$array[] = [
'card_id' => $card_ids[$item['sim']],
'order_id' => $item['order_id'],
'counts' => 1,
'unit_price' => $item['price'],
];
}
DB::table('real_order_base_cards')->whereIn('card_id', array_pluck($array, 'card_id'))->delete();
DB::table('real_order_base_cards')->insert($array);
}
unset($dataOrderCards);
$this->line('插入订单关联数据成功');
} catch (\Exception $e) {
$this->error($e->getMessage());
@ -73,10 +88,77 @@ class OrderBaseSync extends Command
}
}
// 获取月销售卡数据
protected function getCards()
// 查询订单
protected function getOrders()
{
$orders = $this->getOrders();
$this->line('查询订单记录');
$datetime = $this->getDateTime();
$starttime = $datetime->copy()->startOfMonth()->startOfDay()->format('Y-m-d H:i:s');
$endtime = $datetime->copy()->endOfMonth()->endOfDay()->format('Y-m-d H:i:s');
$select = [
'o_id',
'o_number',
'o_customer_number',
'o_customer_name',
'o_p_number',
'o_p_name',
'o_create_date',
'o_create_time',
'o_update_time',
'o_amount',
'o_price',
'o_card_counts',
'o_address',
'o_contacts',
'o_contact_number',
'o_remark',
'o_logistics_content',
'o_is_del',
];
$orders = DB::connection('real')->table('jxc_order')->select($select)->where(function ($query) {
$query->where('o_status', '已出库待确认')->orWhere('o_status', '已确认');
})->whereBetween('o_create_date', [$starttime, $endtime])->where('o_card_use', '销售卡')
->whereNotIn('o_b_number', config('filter.bloc'))->whereIn('o_customer_number', $this->companies->pluck('sn')->toArray())
->orderBy('o_create_date')->get()->keyBy('o_number')->toArray();
$array = [];
foreach ($orders as $item) {
$item = (array)$item;
$array[] = [
'id' => $item['o_id'],
'sn' => $item['o_number'],
'type' => 0,
'company_id' => $this->companies[$item['o_customer_number']]['id'] ?? 0,
'package_id' => $this->packages[$item['o_p_number']]['id'] ?? 0,
'transaction_no' => '',
'pay_channel' => 0,
'unit_price' => floatval($item['o_price']) * 100,
'counts' => $item['o_card_counts'],
'total_price' => floatval($item['o_amount']) * 100,
'order_at' => Carbon::parse($item['o_create_date'])->format('Y-m-d H:i:s'),
'address' => $item['o_address'],
'contact' => $item['o_contacts'],
'phone' => $item['o_contact_number'],
'remark' => $item['o_remark'],
'logistics_remark' => $item['o_logistics_content'],
'created_at' => date('Y-m-d H:i:s', $item['o_create_time']),
'updated_at' => $item['o_update_time'],
'deleted_at' => $item['o_is_del'] ? $item['o_update_time'] : null,
];
}
return $array;
}
// 获取月销售卡数据
protected function getCards($orders)
{
$orders = array_keyBy($orders, 'sn');
$orderRows = $this->getOrderRows($orders);
$orderItems = $this->getOrderItems($orderRows);
@ -93,14 +175,12 @@ class OrderBaseSync extends Command
for ($i=0; $i < $value['counts']; $i++) {
$cards[] = [
'sim' => (string)$sim,
'order_id' => $item['o_number'],
'company_id' => $order['o_customer_number'],
'package_id' => $order['o_p_number'],
'order_at' => $order['o_create_date'],
'total_price' => intval($order['o_amount'] * 100),
'unit_price' => intval($order['o_price'] * 100),
'counts' => $order['o_card_counts'],
'sim' => intval($sim),
'order_id' => $order['id'],
'company_id' => $this->companies[$order['o_customer_number']]['id'] ?? 0,
'package_id' => $order['package_id'],
'order_at' => $order['order_at'],
'price' => $order['unit_price'],
];
$sim++;
@ -124,10 +204,28 @@ class OrderBaseSync extends Command
if (!count($cards)) {
throw new \Exception('销售数据为空');
}
return $cards;
}
$card_details = $this->getCardDetails($cards);
foreach ($cards as &$value) {
$card_detail = $card_details[$value['sim']];
if (!$card_detail) {
$this->error('Mongo上未找到卡数据:' . $value['sim']);
}
$value['imsi'] = intval($card_detail['imsi']) ?? 0;
$value['iccid'] = intval($card_detail['iccid']) ?? 0;
$value['bloc_id'] = $this->blocs[$card_detail['comId']]['id'] ?? 0;
$value['carrier_operator'] = self::$carrierOperators[$card_detail['oType']] ?? 255;
$value['created_at'] = date('Y-m-d H:i:s');
$value['updated_at'] = date('Y-m-d H:i:s');
$value['deleted_at'] = null;
}
return array_values($cards);
}
// 获取卡详细数据
protected function getCardDetails($cards)
{
@ -137,12 +235,11 @@ class OrderBaseSync extends Command
$card_details = [];
foreach ($cardChunks as $cardChunk) {
echo '.';
$res = DB::connection('mongo')->table('tblCard')->select(['cNo', 'iccid', 'imsi', 'comId', 'oType'])
->where('isDel', '<>', 1)
->whereIn('cNo', array_pluck($cardChunk, 'sim'))->get()->toArray();
->whereIn('cNo', array_map('strval', array_pluck($cardChunk, 'sim')))->get()->toArray();
$card_details = array_merge($card_details, $res);
echo '.';
}
unset($cardChunks);
@ -154,39 +251,12 @@ class OrderBaseSync extends Command
return $card_details;
}
// 查询订单
protected function getOrders()
{
$this->line('查询订单记录');
$datetime = $this->getDateTime();
$starttime = $datetime->copy()->startOfMonth()->startOfDay()->format('Y-m-d H:i:s');
$endtime = $datetime->copy()->endOfMonth()->endOfDay()->format('Y-m-d H:i:s');
$company_ids = array_map([CommonService::class, 'stringifyCompanyId'], array_keys($this->companies));
$select = ['o_number', 'o_customer_number', 'o_customer_name', 'o_p_number', 'o_p_name', 'o_create_date', 'o_update_time','o_amount','o_price','o_card_counts'];
$orders = DB::connection('real')->table('jxc_order')->select($select)->where(function ($query) {
$query->where('o_status', '已出库待确认')->orWhere('o_status', '已确认');
})->whereBetween('o_create_date', [$starttime, $endtime])->where('o_card_use', '销售卡')
->whereNotIn('o_b_number', config('filter.bloc'))->where('o_is_del', 0)
->whereIn('o_customer_number', $company_ids)
->orderBy('o_create_date')->get()->keyBy('o_number')->toArray();
foreach ($orders as &$item) {
$item = (array)$item;
}
return $orders;
}
// 查询排单记录
protected function getOrderRows($orders)
{
$this->line('查询排单记录');
$orderRows = DB::connection('real')->table('jxc_order_single_row')->select('o_number', 's_number', 's_create_time')
->whereIn('o_number', array_keys($orders))->where(function ($query) {
->whereIn('o_number', array_pluck($orders, 'sn'))->where(function ($query) {
$query->where('s_status', 4)->where('s_card_counts', '>', 0);
})->get()->keyBy('s_number')->toArray();
@ -212,60 +282,4 @@ class OrderBaseSync extends Command
return $orderItems;
}
// 拼装插入数据
protected function transforms($cards, $card_details)
{
$this->line('拼装插入数据');
$dataOrders = [];
$dataCards = [];
$dataOrderCards = [];
foreach ($cards as $key => $value) {
$card_detail = $card_details[$value['sim']];
if (!$card_detail) {
$this->error('Mongo上未找到卡数据:' . $value['sim']);
}
$value['order_at'] = Carbon::parse($value['order_at'])->format('Y-m-d H:i:s');
$dataOrders[$value['order_id']] = [
'id' => $value['order_id'],
'type' => 0,
'company_id' => CommonService::parseCompanyId($value['company_id']),
'transaction_no' => '',
'pay_channel' => 0,
'unit_price' => $value['unit_price'],
'counts' => $value['counts'],
'total_price' => $value['total_price'],
'order_at' => $value['order_at'],
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
];
$dataCards[$value['sim']] = [
'sim' => $value['sim'],
'imsi' => $card_detail['imsi'] ?? '',
'iccid' => $card_detail['iccid'],
'company_id' => CommonService::parseCompanyId($value['company_id']),
'package_id' => $value['package_id'],
'bloc_id' => $card_detail['comId'] ?? '',
'price' => $value['unit_price'],
'carrier_operator' => self::$carrierOperators[$card_detail['oType']] ?? 255,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
];
$dataOrderCards[$value['sim']] = [
'sim' => $value['sim'],
'order_id' => $value['order_id'],
'counts' => 1,
'unit_price' => $value['unit_price'],
];
}
return [array_values($dataOrders), array_values($dataCards), $dataOrderCards];
}
}

View File

@ -84,7 +84,7 @@ class OrderCustomSync extends Command
foreach ($dataOrderCards as $type => $orderCards) {
foreach (array_chunk($orderCards, $this->chunks) as $data) {
echo '.';
DB::table($tables[$type])->upsert($data, 'sim');
DB::table($tables[$type])->upsert($data, ['sim','order_id']);
}
}
unset($dataOrderCards);
@ -102,7 +102,7 @@ class OrderCustomSync extends Command
foreach ($dataPackageCards as $type => $packageCards) {
foreach (array_chunk($packageCards, $this->chunks) as $data) {
echo '.';
DB::table($tables[$type])->upsert($data, 'sim');
DB::table($tables[$type])->upsert($data, ['sim','package_id']);
}
}
unset($dataPackageCards);
@ -118,7 +118,8 @@ class OrderCustomSync extends Command
$endtime = $this->datetime->copy()->endOfMonth()->endOfDay();
$select = [
'sn as order_id',
'id as order_id',
'sn as order_sn',
'custom_no as company_id',
'transaction_no',
'sim_count as counts',

View File

@ -6,6 +6,7 @@ use Carbon\Carbon;
use App\Models\Real\Package;
use Illuminate\Support\Facades\DB;
use App\Domains\Real\Services\CommonService;
use App\Exceptions\InvalidArgumentException;
use App\Domains\Real\Repositories\CompanyRepository;
use App\Domains\Real\Repositories\PackageRepository;
@ -27,35 +28,18 @@ class PackageSync extends Command
public function handle()
{
$datetime = $this->getDateTime();
$this->companies = app(CompanyRepository::class)->get()->pluck('id')->toArray();
$this->companies = array_map([CommonService::class, 'stringifyCompanyId'], $this->companies);
$this->companies = app(CompanyRepository::class)->get()->pluck('sn')->toArray();
$basePackages = $this->getBasePackages();
$renewalPackages = $this->getRenewalPackages();
foreach ($renewalPackages as &$item) {
$basePackage = $basePackages[$item['parent_id']];
if (!$basePackage) {
throw new \App\Exceptions\InvalidArgumentException('续费包未找到对应基础套餐 #:'.$$item['id']);
}
$item['carrier_operator'] = $basePackage['carrier_operator'];
$item['flows'] = $basePackage['flows'];
$item['voices'] = $basePackage['voices'];
$item['messages'] = $basePackage['messages'];
$item['has_message_switch'] = $basePackage['has_message_switch'];
$item['has_lbs'] = $basePackage['has_lbs'];
$item['reset_months'] = $basePackage['reset_months'];
}
$renewalPackages = $this->getRenewalPackages($basePackages);
$flowPackages = $this->getFlowPackages();
$optionalPackages = $this->getOptionalPackages();
$additionalPackages = $this->getAdditionalPackages();
$packages = array_merge($basePackages, $renewalPackages, $flowPackages, $optionalPackages, $additionalPackages);
Package::upsert($packages, 'id');
app(PackageRepository::class)->forgetCached();
@ -66,7 +50,8 @@ class PackageSync extends Command
{
$select = [
DB::raw('0 as type'),
'jxc_package.package_sn as id',
'jxc_package.id as id',
'jxc_package.package_sn as sn',
'jxc_package.name as name',
'jxc_package.carrieroperator as carrier_operator',
'jxc_package.price as cost_price',
@ -91,12 +76,15 @@ class PackageSync extends Command
}
// 续费包
protected function getRenewalPackages()
protected function getRenewalPackages($basePackages)
{
$basePackages = array_keyBy($basePackages, 'sn');
$select = [
DB::raw('1 as type'),
'jxc_package_renewal.bag_number as id',
'jxc_package_renewal.package_sn as parent_id',
'jxc_package_renewal.id as id',
'jxc_package_renewal.bag_number as sn',
'jxc_package_renewal.package_sn as parent_sn',
'jxc_package_renewal.name as name',
'jxc_package_renewal.price as cost_price',
'jxc_package_renewal.guide_price as guide_price',
@ -111,6 +99,23 @@ class PackageSync extends Command
->where('jxc_package_value_add_relation.type', 1);
})->select($select)->get();
$packages->map(function ($item) use ($basePackages) {
$basePackage = $basePackages[$item->parent_sn];
if (!$basePackage) {
throw new InvalidArgumentException('续费包未找到对应基础套餐 #:'.$item->sn);
}
$item->parent_id = $basePackage['id'];
$item->carrier_operator = $basePackage['carrier_operator'];
$item->flows = $basePackage['flows'];
$item->voices = $basePackage['voices'];
$item->messages = $basePackage['messages'];
$item->has_message_switch = $basePackage['has_message_switch'];
$item->has_lbs = $basePackage['has_lbs'];
$item->reset_months = $basePackage['reset_months'];
});
return $this->transform($packages);
}
@ -119,7 +124,8 @@ class PackageSync extends Command
{
$select = [
DB::raw('2 as type'),
'jxc_package_flows.bag_number as id',
'jxc_package_flows.id as id',
'jxc_package_flows.bag_number as sn',
'jxc_package_flows.name as name',
'jxc_package_flows.carrieroperator as carrier_operator',
'jxc_package_flows.price as cost_price',
@ -148,7 +154,8 @@ class PackageSync extends Command
{
$select = [
DB::raw('3 as type'),
'jxc_package_optional.bag_number as id',
'jxc_package_optional.id as id',
'jxc_package_optional.bag_number as sn',
'jxc_package_optional.name as name',
'jxc_package_optional.carrieroperator as carrier_operator',
'jxc_package_optional.price as cost_price',
@ -177,7 +184,8 @@ class PackageSync extends Command
{
$select = [
DB::raw('4 as type'),
'jxc_package_addoptional.bag_number as id',
'jxc_package_addoptional.id as id',
'jxc_package_addoptional.bag_number as sn',
'jxc_package_addoptional.name as name',
DB::raw('"qw" as carrier_operator'),
DB::raw('0 as cost_price'),
@ -205,8 +213,8 @@ class PackageSync extends Command
foreach ($packages as &$package) {
$package = (array)$package;
$package['parent_id'] = $package['parent_id'] ?: '';
$package['id'] = ($package['type'] + 1) * 1000000 + $package['id'];
$package['parent_id'] = $package['parent_id'] ?? 0;
$package['carrier_operator'] = self::$carrier_operator[$package['carrier_operator']] ?? 255;
$package['cost_price'] = floatval($package['cost_price']) * 100;
$package['guide_price'] = floatval($package['guide_price']) * 100;
@ -221,6 +229,7 @@ class PackageSync extends Command
$package['updated_at'] = date('Y-m-d H:i:s');
$package['deleted_at'] = $package['del'] ? date('Y-m-d H:i:s') : null;
unset($package['del']);
unset($package['parent_sn']);
ksort($package);
}

View File

@ -21,6 +21,7 @@ class RealServiceProvider extends ServiceProvider
// $this->mergeConfigFrom(realpath(__DIR__ . '/../config.php'), 'domain.real');
$this->commands([
\App\Domains\Real\Commands\Sync\MongoSync::class,
\App\Domains\Real\Commands\Sync\CompanySync::class,
\App\Domains\Real\Commands\Sync\BlocSync::class,
\App\Domains\Real\Commands\Sync\PackageSync::class,

View File

@ -73,10 +73,10 @@ class CardRepository extends Repository
$connection = $this->model->getConnection();
$arr = array_map(function ($value) {
return sprintf("('%s', '%s')", $value['sim'], $value['activate_at']);
return sprintf("(%d, '%s'::timestamp)", $value['sim'], $value['activate_at']);
}, $data);
$sql = 'UPDATE real_cards SET activate_at = list.activate_at::timestamp FROM (VALUES ' . implode(',', $arr) . ') AS list(sim, activate_at) WHERE real_cards.sim = list.sim AND real_cards.activate_at IS NULL';
$sql = 'UPDATE real_cards SET activate_at = list.activate_at FROM (VALUES ' . implode(',', $arr) . ') AS list(sim, activate_at) WHERE real_cards.sim = list.sim AND real_cards.activate_at IS NULL';
return $connection->update($sql);
}

View File

@ -33,7 +33,7 @@ class CompanySync extends Command
unset($item['del']);
}
Company::replace($data);
Company::upsert($data, 'id');
app(CompanyRepository::class)->forgetCached();
}

View File

@ -6,9 +6,11 @@ use Carbon\Carbon;
use App\Models\Real\Card;
use App\Models\Real\Order;
use Illuminate\Support\Facades\DB;
use App\Domains\Real\Repositories\BlocRepository;
use App\Domains\Real\Repositories\CardRepository;
use App\Domains\Real\Repositories\OrderRepository;
use App\Domains\Real\Repositories\CompanyRepository;
use App\Domains\Real\Repositories\PackageRepository;
class OrderBaseSync extends Command
{
@ -17,8 +19,8 @@ class OrderBaseSync extends Command
protected $description = '同步VD基础订单数据';
protected $companies;
protected $packages;
protected $blocs;
protected static $carrierOperators = [1, 0, 2];
@ -26,242 +28,5 @@ class OrderBaseSync extends Command
public function handle()
{
$this->companies = app(CompanyRepository::class)->get()->pluck('name', 'id')->toArray();
$cards = $this->getCards();
$bar = $this->output->createProgressBar(count($cards));
$card_details = $this->getCardDetails($cards);
list($dataOrders, $dataCards, $dataOrderCards) = $this->transforms($cards, $card_details);
unset($cards);
unset($card_details);
try {
$this->line('插入订单数据,条数:'.count($dataOrders));
foreach (array_chunk($dataOrders, $this->chunks) as $data) {
echo '.';
Order::replace($data);
}
app(OrderRepository::class)->forgetCached();
unset($dataOrders);
$this->line('插入订单数据成功');
$this->line('插入卡数据,条数:'.count($dataCards));
foreach (array_chunk($dataCards, $this->chunks) as $data) {
echo '.';
Card::replace($data);
}
app(CardRepository::class)->forgetCached();
unset($dataCards);
$this->line('插入卡数据成功');
$this->line('插入订单关联数据,条数:'.count($dataOrderCards));
foreach (array_chunk($dataOrderCards, $this->chunks) as $data) {
echo '.';
DB::table('real_order_base_cards')->replace($data);
}
unset($dataOrderCards);
$this->line('插入订单关联数据成功');
} catch (\Exception $e) {
$this->error($e->getMessage());
throw $e;
}
}
// 获取月销售卡数据
protected function getCards()
{
$orders = $this->getOrders();
$orderRows = $this->getOrderRows($orders);
$orderItems = $this->getOrderItems($orderRows);
$cards = [];
foreach ($orderItems as &$item) {
$item['s_section_number'] = json_decode($item['s_section_number'], true);
$item['o_number'] = $orderRows[$item['s_number']]['o_number'];
foreach ($item['s_section_number'] as $value) {
$sim = explode('-', $value['section_no'])[0];
$order = $orders[$item['o_number']];
$orderRow = $orderRows[$item['s_number']];
for ($i=0; $i < $value['counts']; $i++) {
$cards[] = [
'sim' => (string)$sim,
'order_id' => $item['o_number'],
'company_id' => $order['o_customer_number'],
'package_id' => $order['o_p_number'],
'order_at' => $order['o_create_date'],
'total_price' => intval($order['o_amount'] * 100),
'unit_price' => intval($order['o_price'] * 100),
'counts' => $order['o_card_counts'],
];
$sim++;
}
}
}
unset($orderRows);
unset($orderItems);
$this->line('排单卡总数: ' . count($cards));
$cards = array_sort($cards, function ($item) {
return $item['order_at'];
});
$cards = array_keyBy($cards, 'sim');
$this->line('排重后卡总数: ' . count($cards));
if (!count($cards)) {
throw new \Exception('销售数据为空');
}
return $cards;
}
// 获取卡详细数据
protected function getCardDetails($cards)
{
$this->line('从MongoDB中取卡详细数据');
$cardChunks = array_chunk($cards, $this->chunks);
$card_details = [];
foreach ($cardChunks as $cardChunk) {
echo '.';
$res = DB::connection('mongo')->table('tblCard')->select(['cNo', 'bNo', 'sPCode', 'iccid', 'imsi', 'soDate', 'comId', 'oType', 'jBatchNo'])
->where('isDel', '<>', 1)
->whereIn('cNo', array_pluck($cardChunk, 'sim'))->get()->toArray();
$card_details = array_merge($card_details, $res);
}
unset($cardChunks);
$card_details = array_keyBy($card_details, 'cNo');
$this->line('获取成功,卡详情总数:' . count($card_details));
return $card_details;
}
// 查询订单
protected function getOrders()
{
$this->line('查询订单记录');
$datetime = $this->getDateTime();
$starttime = $datetime->copy()->startOfMonth()->startOfDay()->format('Y-m-d H:i:s');
$endtime = $datetime->copy()->endOfMonth()->endOfDay()->format('Y-m-d H:i:s');
$select = ['o_number', 'o_customer_number', 'o_customer_name', 'o_p_number', 'o_p_name', 'o_create_date', 'o_update_time','o_amount','o_price','o_card_counts'];
$orders = DB::connection('real')->table('jxc_order')->select($select)->where(function ($query) {
$query->where('o_status', '已出库待确认')->orWhere('o_status', '已确认');
})->whereBetween('o_create_date', [$starttime, $endtime])->where('o_card_use', '销售卡')
->whereNotIn('o_b_number', config('filter.bloc'))->where('o_is_del', 0)
->whereIn('o_customer_number', array_keys($this->companies))
->orderBy('o_create_date')->get()->keyBy('o_number')->toArray();
foreach ($orders as &$item) {
$item = (array)$item;
}
return $orders;
}
// 查询排单记录
protected function getOrderRows($orders)
{
$this->line('查询排单记录');
$orderRows = DB::connection('real')->table('jxc_order_single_row')->select('o_number', 's_number', 's_create_time')
->whereIn('o_number', array_keys($orders))->where(function ($query) {
$query->where('s_status', 4)->where('s_card_counts', '>', 0);
})->get()->keyBy('s_number')->toArray();
foreach ($orderRows as &$item) {
$item = (array)$item;
}
return $orderRows;
}
// 查询排单详情
protected function getOrderItems($orderRows)
{
$this->line('查询排单详情');
$orderItems = DB::connection('real')->table('jxc_order_single_row_item')
->select('i_id', 's_number', 's_section_number')
->whereIn('s_number', array_keys($orderRows))->get()->toArray();
foreach ($orderItems as &$item) {
$item = (array)$item;
}
return $orderItems;
}
// 拼装插入数据
protected function transforms($cards, $card_details)
{
$this->line('拼装插入数据');
$dataOrders = [];
$dataCards = [];
$dataOrderCards = [];
foreach ($cards as $key => $value) {
$card_detail = $card_details[$value['sim']];
if (!$card_detail) {
$this->error('Mongo上未找到卡数据:' . $value['sim']);
}
$value['order_at'] = Carbon::parse($value['order_at'])->format('Y-m-d H:i:s');
$dataOrders[$value['order_id']] = [
'id' => $value['order_id'],
'type' => 0,
'company_id' => $value['company_id'],
'transaction_no' => '',
'pay_channel' => 0,
'unit_price' => $value['unit_price'],
'counts' => $value['counts'],
'total_price' => $value['total_price'],
'order_at' => $value['order_at'],
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
];
$dataCards[$value['sim']] = [
'sim' => $value['sim'],
'imsi' => $card_detail['imsi'] ?? '',
'iccid' => $card_detail['iccid'],
'company_id' => $value['company_id'],
'package_id' => $value['package_id'],
'bloc_id' => $card_detail['comId'] ?? '',
'price' => $value['unit_price'],
'carrier_operator' => self::$carrierOperators[$card_detail['oType']] ?? 255,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
];
$dataOrderCards[] = [
'sim' => $value['sim'],
'order_id' => $value['order_id'],
'counts' => 1,
'unit_price' => $value['unit_price'],
];
}
return [array_values($dataOrders), array_values($dataCards), $dataOrderCards];
}
}

View File

@ -175,22 +175,4 @@ class OrderCustomSync extends Command
return $orderItems;
}
// 从MongoDB上获取卡数据
protected function getCards()
{
$starttime = new UTCDateTime($this->datetime->copy()->startOfDay()->startOfMonth()->timestamp * 1000);
$endtime = new UTCDateTime($this->datetime->copy()->endOfDay()->endOfMonth()->timestamp * 1000);
$select = ['cNo', 'bNo', 'sPCode', 'iccid', 'imsi', 'jBatchNo', 'exPCodes.cDate', 'exPCodes.pEffDate', 'exPCodes.oNo', 'exPCodes.pType', 'comId', 'oType'];
return DB::connection('mongo')->table('tblCard')->select($select)->where('pNo', 'No00000000768')->where('isDel', '<>', 1)->where('bNo', 'exists', true)
->where(function ($query) use ($starttime, $endtime) {
$query->where(function ($q) use ($starttime, $endtime) {
$q->where('exPCodes.cDate', '>=', $starttime)->where('exPCodes.cDate', '<=', $endtime)->where('exPCodes.oDate', 'exists', false);
})->orWhere(function ($q) use ($starttime, $endtime) {
$q->where('exPCodes.oDate', '>=', $starttime)->where('exPCodes.oDate', '<=', $endtime);
});
})->get()->toArray();
}
}

View File

@ -26,7 +26,7 @@ class PackageSync extends Command
$packages = array_merge($basePackages, $renewalPackages, $flowPackages);
Package::replace($packages);
Package::upsert($packages, 'id');
app(PackageRepository::class)->forgetCached();
}

View File

@ -3,9 +3,12 @@
namespace App\Models;
use App\Core\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
abstract class CompanyBase extends Model
{
use SoftDeletes;
protected $table = 'real_companies';
public $incrementing = false;

View File

@ -3,9 +3,12 @@
namespace App\Models;
use App\Core\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
abstract class OrderBase extends Model
{
use SoftDeletes;
protected $table = 'real_orders';
public $incrementing = false;

View File

@ -3,9 +3,12 @@
namespace App\Models;
use App\Core\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
abstract class PackageBase extends Model
{
use SoftDeletes;
protected $table = 'real_packages';
public $incrementing = false;

View File

@ -15,36 +15,42 @@ class CreateBaseTables extends Migration
public function up()
{
Schema::create("real_blocs", function (Blueprint $table) {
$table->string('id', 32)->comment('集团编号');
$table->increments('id')->comment('集团ID');
$table->string('sn', 32)->comment('集团编号');
$table->string('name', 32)->comment('集团名称');
$table->string('shorthand', 32)->comment('英文简称');
$table->tinyInteger('carrier_operator')->unsigned()->default(255)->comment('运营商(0:联通 1:移动 2:电信)');
$table->timestamps();
$table->softDeletes();
$table->primary('id');
$table->unique(['sn', 'deleted_at']);
$table->index('name');
$table->index('carrier_operator');
$table->softDeletes();
});
db_alter("real_blocs", "卡源集团");
foreach (app(Dicts::class)->get('tables') as $prefix => $type) {
Schema::create("{$prefix}_companies", function (Blueprint $table) {
$table->increments('id')->comment('企业编号');
$table->increments('id')->comment('企业ID');
$table->string('sn', 32)->comment('企业编号');
$table->string('name', 32)->default('')->comment('企业名称');
$table->string('contacts', 20)->default('')->comment('联系人');
$table->string('phone', 20)->default('')->comment('手机号');
$table->string('username', 32)->default('')->comment('登录名');
$table->string('password', 32)->default('')->comment('密码');
$table->string('address')->default('')->comment('地址');
$table->text('remark')->nullable()->comment('订单备注');
$table->timestamps();
$table->softDeletes();
$table->unique(['sn', 'deleted_at']);
});
db_alter("{$prefix}_companies", "{$type}企业");
Schema::create("{$prefix}_packages", function (Blueprint $table) {
$table->string('id', 20)->comment('套餐编号');
$table->string('parent_id', 20)->comment('父级编号');
$table->increments('id')->comment('企业ID');
$table->integer('parent_id')->unsigned()->default(0)->comment('父级ID');
$table->string('sn', 20)->comment('套餐编号');
$table->string('name', 32)->comment('套餐名称');
$table->tinyInteger('type')->unsigned()->default(255)->comment('套餐类型0:基础套餐 1续费包 2:加油包 3:可选包 4:附加包)');
$table->tinyInteger('carrier_operator')->unsigned()->default(255)->comment('运营商(0:联通 1:移动 2:电信)');
@ -61,52 +67,83 @@ class CreateBaseTables extends Migration
$table->tinyInteger('delay_months')->unsigned()->default(0)->comment('服务器延长周期(月)');
$table->text('description')->nullable()->comment('描述');
$table->timestamps();
$table->softDeletes();
$table->primary('id');
$table->unique(['sn', 'deleted_at']);
$table->index('name');
$table->index('parent_id');
$table->index('type');
$table->index('carrier_operator');
$table->softDeletes();
});
db_alter("{$prefix}_packages", "{$type}套餐");
Schema::create("{$prefix}_cards", function (Blueprint $table) {
$table->string('sim', 20)->comment('sim号');
$table->string('imsi', 20)->comment('imsi号');
$table->string('iccid', 20)->comment('iccid号');
$table->string('bloc_id', 32)->comment('来源集团ID');
$table->integer('company_id')->unsigned()->default(0)->comment("{$type}企业编号");
$table->string('package_id', 20)->comment('套餐编号');
$table->string('price', 20)->comment('单价');
$table->increments('id')->comment('卡ID');
$table->bigInteger('sim')->unsigned()->default(0)->comment('sim号');
$table->bigInteger('imsi')->unsigned()->default(0)->comment('imsi号');
$table->bigInteger('iccid')->unsigned()->default(0)->comment('iccid号');
$table->integer('bloc_id')->unsigned()->default(0)->comment('来源集团ID');
$table->integer('company_id')->unsigned()->default(0)->comment("{$type}企业ID");
$table->integer('package_id')->unsigned()->default(0)->comment('套餐ID');
$table->integer('order_id')->unsigned()->default(0)->comment('订单ID');
$table->integer('price')->unsigned()->default(0)->comment('单价');
$table->tinyInteger('carrier_operator')->unsigned()->default(255)->comment('运营商(0:联通 1:移动 2:电信)');
$table->timestamp('activate_at')->nullable()->comment('激活时间');
$table->timestamp('virtual_activate_at')->nullable()->comment('虚拟激活时间');
$table->timestamps();
$table->softDeletes();
$table->primary('sim');
$table->unique(['sim', 'deleted_at']);
$table->index('imsi');
$table->index('iccid');
});
db_alter("{$prefix}_cards", "{$type}卡基础信息表");
Schema::create("{$prefix}_orders", function (Blueprint $table) {
$table->string('id', 32)->comment('订单编号');
$table->tinyInteger('type')->unsigned()->default(255)->comment('订单类型0:基础套餐 1:套餐续费 2续费包 3:加油包 4:可选包 5:附加包)');
$table->integer('company_id')->unsigned()->default(0)->comment("{$type}企业编号");
$table->increments('id')->comment('订单ID');
$table->string('sn', 32)->comment('订单编号');
$table->tinyInteger('type')->unsigned()->default(0)->comment('订单类型0:基础套餐)');
$table->integer('company_id')->unsigned()->default(0)->comment("{$type}企业ID");
$table->string('transaction_no', 64)->comment('交易流水号');
$table->tinyInteger('pay_channel')->unsigned()->default(0)->comment('支付方式(0:银行转账 1:账户余额 2:微信支付 3:支付宝 4:天猫续费)');
$table->integer('unit_price')->unsigned()->default(0)->comment('单价');
$table->integer('counts')->unsigned()->default(0)->comment('数量');
$table->integer('total_price')->unsigned()->default(0)->comment('总价');
$table->timestamp('order_at')->nullable()->comment('下单时间');
$table->string('address')->default('')->comment('收货地址');
$table->string('contact')->default('')->comment('联系人');
$table->string('phone')->default('')->comment('电话');
$table->text('logistics_remark')->nullable()->comment('物流备注');
$table->text('remark')->nullable()->comment('订单备注');
$table->timestamps();
$table->softDeletes();
$table->primary('id');
$table->unique(['sn', 'deleted_at']);
$table->index('type');
$table->index('company_id');
$table->index('order_at');
});
db_alter("{$prefix}_orders", "{$type}订单");
Schema::create("{$prefix}_custom_orders", function (Blueprint $table) {
$table->increments('id')->comment('订单ID');
$table->string('sn', 32)->comment('订单编号');
$table->tinyInteger('type')->unsigned()->default(0)->comment('订单类型1:套餐续费 2续费包 3:加油包 4:可选包 5:附加包)');
$table->integer('company_id')->unsigned()->default(0)->comment("{$type}企业ID");
$table->string('transaction_no', 64)->comment('交易流水号');
$table->tinyInteger('pay_channel')->unsigned()->default(0)->comment('支付方式(0:银行转账 1:账户余额 2:微信支付 3:支付宝 4:天猫续费)');
$table->integer('unit_price')->unsigned()->default(0)->comment('单价');
$table->integer('counts')->unsigned()->default(0)->comment('数量');
$table->integer('total_price')->unsigned()->default(0)->comment('总价');
$table->timestamp('order_at')->nullable()->comment('下单时间');
$table->text('remark')->nullable()->comment('订单备注');
$table->timestamps();
$table->softDeletes();
$table->unique(['sn', 'deleted_at']);
$table->index('type');
$table->index('company_id');
$table->index('order_at');
@ -114,6 +151,58 @@ class CreateBaseTables extends Migration
db_alter("{$prefix}_orders", "{$type}订单");
}
Schema::create("card_infos", function (Blueprint $table) {
$table->bigInteger('sim')->unsigned()->default(0)->comment('sim号');
$table->bigInteger('imsi')->unsigned()->default(0)->comment('imsi号');
$table->bigInteger('iccid')->unsigned()->default(0)->comment('iccid号');
$table->integer('bloc_id')->unsigned()->default(0)->comment('来源集团ID');
$table->tinyInteger('carrier_operator')->unsigned()->default(255)->comment('运营商(0:联通 1:移动 2:电信)');
$table->timestamp('activate_at')->nullable()->comment('激活时间');
$table->timestamps();
});
db_alter("card_infos", "卡基础信息表");
Schema::create("virtual_company_accounts", function (Blueprint $table) {
$table->increments('id')->comment('自增ID');
$table->string('company_id', 32)->comment('企业ID');
$table->string('phone', 20)->default('')->comment('手机号');
$table->string('username', 32)->default('')->comment('登录名');
$table->string('password', 32)->default('')->comment('密码');
$table->tinyInteger('status')->unsigned()->default(0)->comment('状态 0:正常 1:禁用');
$table->timestamps();
$table->softDeletes();
$table->unique('phone');
});
Schema::create("virtual_company_address", function (Blueprint $table) {
$table->increments('id')->comment('自增ID');
$table->string('company_id', 32)->comment('企业ID');
$table->string('contacts', 20)->default('')->comment('联系人');
$table->string('phone', 20)->default('')->comment('手机号');
$table->string('area')->default('')->comment('区域');
$table->string('address')->default('')->comment('地址');
$table->tinyInteger('default')->unsigned()->default(0)->comment('是否默认 0:不是 1:是');
$table->tinyInteger('status')->unsigned()->default(0)->comment('状态 0:正常 1:禁用');
$table->timestamps();
$table->softDeletes();
});
Schema::create("virtual_products", function (Blueprint $table) {
$table->increments('id')->comment('自增ID');
$table->string('sn', 32)->comment('产品编码');
$table->string('name', 32)->comment('产品名称');
$table->string('company_id', 32)->comment('企业ID');
$table->integer('package_id')->unsigned()->default(0)->comment('套餐ID');
$table->integer('base_price')->unsigned()->default(0)->comment('基础价格');
$table->integer('renewal_price')->unsigned()->default(0)->comment('续费价格');
$table->timestamps();
$table->softDeletes();
$table->unique(['sn', 'deleted_at']);
});
}
/**
@ -124,12 +213,15 @@ class CreateBaseTables extends Migration
public function down()
{
foreach (app(Dicts::class)->get('tables') as $prefix => $type) {
Schema::dropIfExists("{$prefix}_custom_orders");
Schema::dropIfExists("{$prefix}_orders");
Schema::dropIfExists("{$prefix}_cards");
Schema::dropIfExists("{$prefix}_packages");
Schema::dropIfExists("{$prefix}_companies");
}
Schema::dropIfExists("real_blocs");
Schema::dropIfExists("virtual_products");
Schema::dropIfExists("virtual_company_address");
Schema::dropIfExists("virtual_company_accounts");
}
}

View File

@ -8,12 +8,11 @@ use Illuminate\Database\Migrations\Migration;
class CreateOrderTables extends Migration
{
protected $tables = [
'order_additional_package_cards' => '卡关联基础订单',
'order_optional_package_cards' => '卡关联续费订单',
'order_flows_package_cards' => '卡关联续费包订单',
'order_renewal_package_cards' => '卡关联加油包订单',
'order_renewal_cards' => '卡关联可选包订单',
'order_base_cards' => '卡关联附加订单',
'custom_order_renewal_cards' => '卡关联可选包订单',
'custom_order_renewal_package_cards' => '卡关联加油包订单',
'custom_order_flows_package_cards' => '卡关联续费包订单',
'custom_order_optional_package_cards' => '卡关联续费订单',
'custom_order_additional_package_cards' => '卡关联基础订单',
];
/**
@ -28,19 +27,17 @@ class CreateOrderTables extends Migration
$table_name = $prefix . '_' . $table_name;
$table_comment = $type . $table_comment;
Schema::create($table_name, function (Blueprint $table) use ($prefix) {
$table->string('order_id', 32)->comment('订单编号');
$table->string('sim', 20)->comment('sim卡号');
$table->integer('order_id')->unsigned()->default(0)->comment('订单ID');
$table->integer('card_id')->unsigned()->default(0)->comment('卡ID');
if ($prefix === 'virtual') {
$table->integer('company_id')->unsigned()->default(0)->comment("企业编号");
$table->string('package_id', 32)->comment('套餐编号');
$table->integer('company_id')->unsigned()->default(0)->comment("企业ID");
$table->integer('package_id')->unsigned()->default(0)->comment('套餐ID');
}
$table->integer('counts')->unsigned()->default(1)->comment('数量');
$table->integer('unit_price')->unsigned()->default(0)->comment('单价');
$table->primary(['order_id', 'sim']);
$table->unique('sim');
$table->primary(['order_id', 'card_id']);
});
db_alter($table_name, $table_comment);

View File

@ -24,11 +24,9 @@ class CreatePackageTables extends Migration
{
foreach ($this->tables as $table_name => $table_comment) {
Schema::create($table_name, function (Blueprint $table) {
$table->string('package_id', 20)->comment('套餐编号');
$table->string('sim', 20)->comment('sim卡号');
$table->primary(['package_id', 'sim']);
$table->unique('sim');
$table->integer('package_id')->unsigned()->default(0)->comment('套餐ID');
$table->integer('card_id')->unsigned()->default(0)->comment('卡ID');
$table->primary(['package_id', 'card_id']);
});
db_alter($table_name, $table_comment);

View File

@ -24,7 +24,7 @@ class DatabaseServiceProvider extends ServiceProvider
QueryBuilder::macro('insertUpdate', $this->macroInsertUpdate());
QueryBuilder::macro('createOrIgnore', $this->macroCreateOrIgnore());
QueryBuilder::macro('createNotExist', $this->macroCreateNotExist());
QueryBuilder::macro('updateBatch', $this->macroUpsert());
QueryBuilder::macro('updateBatch', $this->macroUpdateBatch());
}
/**
@ -186,6 +186,37 @@ class DatabaseServiceProvider extends ServiceProvider
};
}
/**
* macro an update batch statement into SQL.
* 批量更新
* 默认以ID为条件更新如果没有ID则以第一个字段为条件
*
* @return void
*/
public function macroUpdateBatch()
{
return function (array $values, $filed = 'id') {
if (empty($values)) {
return false;
}
if (!is_array(reset($values))) {
$values = [$values];
} else {
foreach ($values as $key => $value) {
$values[$key] = $value;
}
}
$grammar = DatabaseServiceProvider::getGrammar($this->connection);
return $this->connection->affectingStatement(
$grammar->compileUpdateBatch($this, $values, $filed),
$this->cleanBindings(Arr::flatten($values, 1))
);
};
}
public static function getGrammar(Connection $connection)
{
$driver = $connection->getDriverName();

View File

@ -161,7 +161,7 @@ class MySqlGrammar extends Grammar
* @param string $filed
* @return string
*/
public function compileUpsert(QueryBuilder $query, array $values, $filed = 'id')
public function compileUpdateBatch(QueryBuilder $query, array $values, $filed = 'id')
{
// Essentially we will force every insert to be treated as a batch insert which
// simply makes creating the SQL easier for us since we can utilize the same
@ -177,20 +177,12 @@ class MySqlGrammar extends Grammar
$columns = array_keys(reset($values));
// 指定更新字段默认id字段,不存在时选用第一个字段。
if (isset($row[$filed])) {
$reference = $filed;
$key = array_search($filed, $columns);
} else {
$reference = current($columns);
$key = 0;
}
$reference = isset($row[$filed]) ? $filed : current($columns);
$key = isset($row[$filed]) ? array_search($filed, $columns) : 0;
unset($columns[$key]);
$reference = isset($row[$filed]) ? $filed : current($columns);
$sql = "update $table set";
$sql = "UPDATE $table SET";
$sets = [];
@ -209,4 +201,17 @@ class MySqlGrammar extends Grammar
return rtrim($sql, ', ') . " WHERE `" . $reference . "` IN (" . implode(', ', $whereIn) . ")";
}
/**
* Compile an upsert statement into SQL.
*
* @param Builder $query
* @param array $values
* @param array|string $unique
* @return string
*/
public function compileUpsert(QueryBuilder $query, array $values, $filed = ['id'])
{
return $this->compileInsertUpdate($query, $values);
}
}

View File

@ -2,20 +2,69 @@
namespace Dipper\Foundation\Database;
use DateTime;
use DateTimeInterface;
use Illuminate\Database\Query\Builder as QueryBuilder;
use Illuminate\Database\Query\Grammars\PostgresGrammar as Grammar;
class PostgresGrammar extends Grammar
{
/**
* Compile an update batch statement into SQL.
*
* @param \Illuminate\Database\Query\Builder $query
* @param array $values
* @param string $filed
* @return string
*/
public function compileUpdateBatch(QueryBuilder $query, array $values, $filed = 'id')
{
$as = 'as_table';
$table = $this->wrapTable($query->from);
if (! is_array(reset($values))) {
$values = [$values];
}
$row = current($values);
$columns = array_keys(reset($values));
$reference = isset($row[$filed]) ? $filed : current($columns);
$updates = collect($columns)->filter(function ($column) use ($reference) {
return $column !== $reference;
})->map(function ($column) use ($table, $as) {
return "{$column} = {$as}.{$column}";
})->implode(', ');
$parameters = collect($values)->map(function ($record) {
return '('.$this->parameterize($record).')';
})->implode(', ');
$columns = '('.$this->columnize($columns).')';
$from = "FROM (VALUES $parameters) AS {$as}{$columns}";
if (is_null($query->wheres)) {
$where = "WHERE {$table}.{$reference} = {$as}.{$reference}";
} else {
$where = $this->compileUpdateWheres($query) . " AND {$table}.{$reference} = {$as}.{$reference}";
}
return trim("UPDATE {$table} SET {$updates} {$from} {$where}");
}
/**
* Compile an upsert statement into SQL.
*
* @param Builder $query
* @param array $values
* @param string $unique
* @param array|string $unique
* @return string
*/
public function compileUpsert(QueryBuilder $query, array $values, $filed = 'id')
public function compileUpsert(QueryBuilder $query, array $values, $filed = ['id'])
{
$insert = $this->compileInsert($query, $values);
@ -27,13 +76,16 @@ class PostgresGrammar extends Grammar
$keys = array_keys(reset($values));
// 指定更新字段默认id字段,不存在时选用第一个字段。
$reference = isset($row[$filed]) ? $filed : current($keys);
if (!is_array($filed)) {
$filed = explode(',', $filed);
}
$reference = implode(',', $filed);
// excluded fields are all fields except $unique one that will be updated
// also created_at should be excluded since record already exists
$excluded = array_filter($keys, function ($e) use ($reference) {
return $e != $reference && $e != 'created_at';
$excluded = array_filter($keys, function ($e) use ($filed) {
return !in_array($e, $filed) && $e != 'created_at';
});
$update = join(', ', array_map(function ($e) {