This commit is contained in:
邓皓元 2019-03-22 11:00:05 +08:00
parent 5e59e5bb03
commit 1392e2ee52
49 changed files with 722 additions and 133335 deletions

View File

@ -26,7 +26,7 @@ class Kernel extends ConsoleKernel
protected function schedule(Schedule $schedule)
{
$logPath = storage_path('logs/artisan.log');
$schedule->command('real:sync-mongo')->cron('*/5 * * * *')->withoutOverlapping()->appendOutputTo($logPath);
$schedule->command('real:sync-activated')->cron('* */4 * * *')->withoutOverlapping()->appendOutputTo($logPath);
}
/**

View File

@ -22,7 +22,6 @@ class Dicts extends Repository
'carrier_operator' => ['联通', '移动', '电信', '全网'],
'service_type' => ['套餐开通', '套餐续费', '套餐更换', '套餐销售'],
'card_status' => ['测试期', '沉默期', '服务期', '已注销'],
'bloc_channel' => ['运营商', '中间商'],
'package_type' => ['基础套餐', '续费包', '加油包', '可选包', '附加包'],
'tables' => ['real' => 'RD', 'virtual' => 'VD'],
'order_status' => ['已下单', '已取消', '已排单', '已出库', '已发货', '已签收'],

View File

@ -0,0 +1,78 @@
<?php
namespace App\Domains\Card\Jobs;
use App\Models\Card\Card;
use Illuminate\Support\Arr;
use Illuminate\Bus\Queueable;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Dipper\Foundation\Bus\Dispatchable;
use App\Domains\Card\Services\CardService;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Domains\Card\Repositories\CardRepository;
use App\Domains\Virtual\Repositories\OrderCardPartitionRepository;
class MongoCardJob implements ShouldQueue
{
use Queueable, Dispatchable;
public $simArray;
protected static $carrierOperators = [1, 0, 2];
/**
* Undocumented function
*
* @param array $simArray
*/
public function __construct(array $simArray)
{
$this->simArray = $simArray;
}
/**
*
*/
public function handle()
{
foreach (array_chunk($this->simArray, 1000) as $simArray) {
Log::notice('MongoCardJob #:' . implode(',', $simArray));
$this->cardsJob($simArray);
}
}
public function cardsJob($simArray)
{
$values = CardService::getMongoCardsInfo($simArray);
if (empty($values)) {
Log::notice('MongoCardJob not result!');
return ;
}
$builder = Card::query()->toBase();
$sql = $builder->getGrammar()->compileInsert($builder, $values);
$sql .= ' on conflict (sim) do update set
imsi=excluded.imsi,
iccid=excluded.iccid,
carrier_operator=excluded.carrier_operator,
activated_at=excluded.activated_at,
virtual_activated_at=COALESCE(cards.virtual_activated_at, excluded.activated_at),
created_at=excluded.created_at
updated_at=excluded.updated_at
';
$builder->connection->insert($sql, Arr::flatten($values, 1));
app(CardRepository::class)->forgetCached();
$simArray = implode(',', array_keys($values));
DB::statement("select fix_timelines('{{$simArray}}'::INT8[]);");
app(OrderCardPartitionRepository::class)->forgetCached();
}
}

View File

@ -1,62 +0,0 @@
<?php
namespace App\Domains\Card\Repositories;
use App\Core\Repository;
use App\Models\Card\Bloc as Model;
class BlocRepository extends Repository
{
/**
* 是否关闭缓存
*
* @var boolean
*/
protected $cacheSkip = false;
/**
* 是否开启数据转化
*
* @var bool
*/
protected $needTransform = false;
/**
* @var array
*/
protected $fieldSearchable = [
'id' => '=',
'created_at' => 'like',
];
public function model() {
return Model::class;
}
/**
* 数据格式化
*
* @param mixed $result
*
* @return mixed
*/
public function transform($model)
{
return $model->toArray();
}
/**
* 查询条件
*
* @return void
*/
public function withConditions(array $conditions = [])
{
if (isset($conditions['id'])) {
$conditions['id'] = array_wrap($conditions['id']);
$this->model = $this->model->whereIn('id', $conditions['id']);
}
return $this;
}
}

View File

@ -16,7 +16,7 @@ class CardRepository extends Repository
/**
* 是否开启数据转化
*
*
* @var bool
*/
protected $needTransform = false;
@ -59,4 +59,4 @@ class CardRepository extends Repository
return $this;
}
}
}

View File

@ -1,10 +1,14 @@
<?php
namespace App\Domains\Card\Services;
use Carbon\Carbon;
use App\Core\Service;
use App\Models\Mongo\TblCard;
class CardService extends Service
{
protected static $carrierOperators = [1, 0, 2];
/**
* 构造函数
*
@ -14,4 +18,43 @@ class CardService extends Service
{
//
}
/**
* 从MongoDB上获取卡详情
*
* @param array $simArray
* @return array
*/
public static function getMongoCardsInfo(array $simArray)
{
$simArray = array_map('strval', $simArray);
$res = TblCard::select(['cNo', 'iccid', 'imsi', 'oType', 'saDate', 'sDate'])
->whereIn('cNo', $simArray)->get();
$values = [];
foreach ($res as $value) {
$activated_at = $value['saDate'] ? $value['saDate']->toDateTime()->format('Y-m-d H:i:s') : null;
if ($activated_at && Carbon::parse($activated_at) < Carbon::parse('2000-01-01 00:00:00')) {
$activated_at = null;
}
$sim = intval(preg_replace('/\D/', '', $value['cNo']));
$values[$sim] = [
'sim' => $sim,
'imsi' => $value['imsi'] ?? '',
'iccid' => $value['iccid'] ?? '',
'carrier_operator' => self::$carrierOperators[$value['oType']] ?? 255,
'activated_at' => $activated_at,
'virtual_activated_at' => $activated_at,
'created_at' => $value['sDate'] ? $value['sDate']->toDateTime()->format('Y-m-d H:i:s') : null,
'updated_at' => date('Y-m-d H:i:s'),
];
}
return $values;
}
}

View File

@ -0,0 +1,81 @@
<?php
namespace App\Domains\Real\Commands\Sync;
use Carbon\Carbon;
use App\Models\Card\Card;
use App\Models\Mongo\TblCard;
use MongoDB\BSON\UTCDateTime;
use Illuminate\Support\Facades\DB;
use App\Domains\Card\Repositories\CardRepository;
use App\Domains\Virtual\Repositories\OrderCardPartitionRepository;
class ActivatedSync extends Command
{
protected $name = 'real:sync-activated';
protected $description = '同步激活数据(每天同步昨天的激活数据)';
protected $limit = 1000;
public function handle()
{
$day = $this->getDay();
$startMicrotime = new UTCDateTime($day->startOfDay());
$endMicrotime = new UTCDateTime($day->endOfDay());
$query = TblCard::where('pNo', 'No00000000768')->where('isDel', 0)
->where('saDate', 'exists', true)
->where('bNo', 'exists', true)
->where('saDate', '>=', $startMicrotime)
->where('saDate', '<=', $endMicrotime);
$total = $query->count();
$this->line('待同步条数:'.$total);
$page = 1;
while ($total) {
if (($page - 1) * $this->limit >= $total) {
break;
}
$res = $query->select(['cNo', 'saDate'])
->forPage($page, $this->limit)->get();
$array = $res->map(function ($item) {
return [
'sim' => $item['cNo'],
'activated_at' => $item['saDate'] ? $item['saDate']->toDateTime()->format('Y-m-d H:i:s') : null,
];
})->all();
$table = app(Card::class)->getTable();
$as = 'as_table';
$reference = 'sim';
$updates = "activated_at={$as}.activated_at::timestamp,
virtual_activated_at=COALESCE({$table}.activated_at, {$as}.activated_at::timestamp)::timestamp";
$parameters = collect($array)->map(function ($item) {
return "({$item['sim']}, '{$item['activated_at']}')";
})->implode(', ');
$from = "FROM (VALUES $parameters) AS {$as}(sim, activated_at)";
$where = "WHERE {$table}.{$reference} = {$as}.{$reference}::int8";
$sql = trim("UPDATE {$table} SET {$updates} {$from} {$where}");
$simArray = implode(',', array_pluck($array, 'sim'));
DB::statement($sql);
DB::statement("select fix_timelines('{{$simArray}}'::INT8[]);");
$page++;
}
app(CardRepository::class)->forgetCached();
app(OrderCardPartitionRepository::class)->forgetCached();
}
}

View File

@ -98,7 +98,7 @@ class AddedOrderSync extends Command
}
}
DB::table($table)->upsert($data, ['sim', 'order_id'], true);
DB::table($table)->upsert($data, ['sim', 'order_id'], []);
}
}

View File

@ -1,42 +0,0 @@
<?php
namespace App\Domains\Real\Commands\Sync;
use Carbon\Carbon;
use App\Models\Card\Bloc;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use App\Domains\Card\Repositories\BlocRepository;
class BlocSync extends Command
{
protected $name = 'real:sync-bloc';
protected $description = '同步RD集团数据';
protected $carrier_operator = ['lt' => 0, 'yd' => 1, 'dx' => 2, 'qw' => 3];
public function handle()
{
$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()->collect()->toArray();
$carders = DB::connection('real')->table('jxc_carder_manage')->select(['bloc_code', 'inside_card_from_sn'])->get()->collect()->toArray();
$carders = array_pluck($carders, 'inside_card_from_sn', 'bloc_code');
foreach ($blocs as &$item) {
$item['shorthand'] = $carders[$item['sn']] ?? '';
$item['carrier_operator'] = $this->carrier_operator[$item['carrier_operator']];
$item['created_at'] = Carbon::createFromTimestamp($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;
unset($item['del']);
}
$blocs = array_values(array_keyBy($blocs, 'id'));
Bloc::upsert($blocs, 'id');
app(BlocRepository::class)->forgetCached();
}
}

View File

@ -0,0 +1,71 @@
<?php
namespace App\Domains\Real\Commands\Sync;
use Carbon\Carbon;
use App\Models\Card\Card;
use Illuminate\Support\Facades\DB;
use App\Domains\Card\Repositories\CardRepository;
use Symfony\Component\Console\Input\InputArgument;
use App\Domains\Virtual\Repositories\OrderCardPartitionRepository;
class CancelledSync extends Command
{
protected $name = 'real:sync-cancelled';
protected $description = '同步注销数据(每天同步昨天的注销数据)';
protected $limit = 1000;
public function handle()
{
$day = $this->getDay();
$cancelRecords = DB::connection('real')->table('jxc_cancel_card')
->where('cn_date', $day->format('Y-m-d'))
->where('cn_status', 1)->get();
$this->line('待同步条数:'.count($cancelRecords));
if (empty($cancelRecords)) {
return;
}
$cards = DB::connection('real')->table('jxc_cancel_card_item')
->whereIn('item_cn_id', $cancelRecords->pluck('cn_id')->toArray())->get();
$array = [];
foreach ($cards as $item) {
$array[] = [
'sim' => $item->item_sim,
'cancelled_at' => $day,
];
}
Card::updateBatch($array, 'sim::int8');
app(CardRepository::class)->forgetCached();
app(OrderCardPartitionRepository::class)->forgetCached();
}
protected function getDay()
{
if ($day = $this->argument('day')) {
if (!preg_match('/\d{4}-\d{1,2}-\d{1,2}/', $day)) {
throw new \App\Exceptions\InvalidArgumentException('请输入正确的日期 #示例: 2018-10-01');
}
return Carbon::parse($day)->startOfDay();
}
return Carbon::yesterday()->startOfDay();
}
protected function getArguments()
{
return [
['day', InputArgument::OPTIONAL, '要同步的数据日期,默认昨天 #示例: 2018-10-01'],
];
}
}

View File

@ -1,58 +0,0 @@
<?php
namespace App\Domains\Real\Commands\Sync;
use App\Models\Mongo\TblCard;
use MongoDB\BSON\UTCDateTime;
use Illuminate\Support\Collection;
use App\Domains\Real\Jobs\MongoSyncJob;
use Illuminate\Support\Facades\Artisan;
use App\Domains\Config\Services\ConfigService;
class MongoSync extends Command
{
protected $name = 'real:sync-mongo';
protected $description = '同步卡基础信息数据';
protected $limit = 1000;
const CURSOR_KEY = 'sync_mongo_cursor';
public function handle()
{
$microtime = app(ConfigService::class)->get(self::CURSOR_KEY) ?: intval(microtime(true) * 1000);
$nextMicrotime = intval(microtime(true) * 1000);
$utcDateTime = new UTCDateTime($microtime);
$total = TblCard::where('pNo', 'No00000000768')->where('oRDate', '>', $utcDateTime)->where('sDate', 'exists', true)->count();
$this->line('待同步条数:'.$total);
if ($total) {
Artisan::call('real:sync-bloc');
Artisan::call('real:sync-company');
}
$page = 2;
$jobs = new Collection();
while ($total) {
if (($page - 1) * $this->limit >= $total) {
break;
}
$jobs->push(new MongoSyncJob($page, $this->limit, $utcDateTime));
$page++;
}
$total && MongoSyncJob::withChain($jobs->toArray())
->dispatch(1, $this->limit, $utcDateTime)
->allOnQueue('sync');
app(ConfigService::class)->set(self::CURSOR_KEY, intval($nextMicrotime));
}
}

View File

@ -53,7 +53,7 @@ class OrderBaseSync extends Command
$value['virtual_order_id'] = $orders[$value['sim']] ?? 0;
}
DB::table('real_order_cards')->upsert($data, ['sim', 'deleted_at'], true);
DB::table('real_order_cards')->upsert($data, ['sim', 'deleted_at'], []);
}
app(OrderCardPartitionRepository::class)->forgetCached();
$this->line('插入订单关联数据成功');

View File

@ -107,7 +107,7 @@ class PackageSync extends Command
}
$item->parent_id = $basePackage['id'];
$item->carrier_operator = $basePackage['carrier_operator'];
$item->carrier_operator = array_flip(self::$carrier_operator)[$basePackage['carrier_operator']] ?? 'qw';
$item->flows = $basePackage['flows'];
$item->voices = $basePackage['voices'];
$item->messages = $basePackage['messages'];

View File

@ -0,0 +1,40 @@
<?php
namespace App\Domains\Real\Commands\Sync;
use Illuminate\Support\Facades\DB;
class RefundSync extends Command
{
protected $name = 'real:sync-refund';
protected $description = '同步RD退货数据';
protected $companies;
public function handle()
{
$datetime = $this->getDateTime();
$starttime = $datetime->copy()->startOfMonth()->startOfDay();
$endtime = $datetime->copy()->endOfMonth()->endOfDay();
$refunds = DB::connection('real')->table('jxc_back_card')
->select(['sim', 'create_time'])
->where('status', 2)
->where('create_time', '>=', $starttime)
->where('create_time', '<=', $endtime)
->get();
$refunds->map(function ($item) {
$item->sim = str_to_array($item->sim, ',');
});
DB::transaction(function () use ($refunds) {
foreach ($refunds as $item) {
DB::table('real_order_cards')->whereIn('sim', $item['sim'])->where('created_at', '<=', $item['create_time'])->delete();
DB::table('virtual_order_cards')->whereIn('sim', $item['sim'])->where('created_at', '<=', $item['create_time'])->delete();
}
});
}
}

View File

@ -1,110 +0,0 @@
<?php
namespace App\Domains\Real\Jobs;
use Carbon\Carbon;
use App\Models\Card\Card;
use Illuminate\Support\Arr;
use App\Models\Mongo\TblCard;
use Illuminate\Bus\Queueable;
use MongoDB\BSON\UTCDateTime;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Dipper\Foundation\Bus\Dispatchable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Domains\Card\Repositories\BlocRepository;
use App\Domains\Card\Repositories\CardRepository;
use App\Domains\Real\Repositories\CompanyRepository;
use App\Domains\Virtual\Repositories\OrderCardPartitionRepository;
class MongoSyncJob implements ShouldQueue
{
use Queueable, Dispatchable;
public $page;
public $limit;
public $utcDateTime;
protected static $carrierOperators = [1, 0, 2];
/**
* Undocumented function
*
* @param int $page
* @param int $limit
* @param UTCDateTime $utcDateTime
*/
public function __construct($page, $limit, UTCDateTime $utcDateTime)
{
$this->page = $page;
$this->limit = $limit;
$this->utcDateTime = $utcDateTime;
}
/**
*
*/
public function handle()
{
Log::info("MongoSyncJob #: utcDateTime {$this->utcDateTime} - page {$this->page}");
$query = TblCard::select(['cNo', 'bNo', 'iccid', 'imsi', 'comId', 'oType', 'saDate', 'sDate', 'oRDate'])
->where('pNo', 'No00000000768')
->where('oRDate', '>', $this->utcDateTime)
->where('sDate', 'exists', true)
->orderBy('sDate');
$res = $query->forPage($this->page, $this->limit)->get();
if (empty($res)) {
Log::notice('MongoSyncJob not result!');
return ;
}
$companies = app(CompanyRepository::class)->withTrashed()->get()->keyBy('sn');
$blocs = app(BlocRepository::class)->withTrashed()->get()->pluck('id', 'sn')->toArray();
$values = [];
foreach ($res as $key => $value) {
$activated_at = $value['saDate'] ? $value['saDate']->toDateTime()->format('Y-m-d H:i:s') : null;
if ($activated_at && Carbon::parse($activated_at) < Carbon::parse('2000-01-01 00:00:00')) {
$activated_at = null;
}
$sim = intval(preg_replace('/\D/', '', $value['cNo']));
$values[$sim] = [
'sim' => $sim,
'imsi' => $value['imsi'] ?? '',
'iccid' => $value['iccid'] ?? '',
'bloc_id' => $blocs[$value['comId']] ?? 0,
'carrier_operator' => self::$carrierOperators[$value['oType']] ?? 255,
'activated_at' => $activated_at,
'virtual_activated_at' => $activated_at,
'created_at' => $value['sDate'] ? $value['sDate']->toDateTime()->format('Y-m-d H:i:s') : null,
'updated_at' => date('Y-m-d H:i:s'),
];
}
$builder = Card::query()->toBase();
$sql = $builder->getGrammar()->compileInsert($builder, $values);
$sql .= ' on conflict (sim) do update set
activated_at=excluded.activated_at,
virtual_activated_at=COALESCE(cards.virtual_activated_at, excluded.activated_at)';
$builder->connection->insert($sql, Arr::flatten($values, 1));
app(CardRepository::class)->forgetCached();
$simArray = implode(',', array_keys($values));
DB::statement("select fix_timelines('{{$simArray}}'::INT8[]);");
app(OrderCardPartitionRepository::class)->forgetCached();
Log::info("MongoSyncJob END #: utcDateTime {$this->utcDateTime} - page {$this->page}");
}
}

View File

@ -21,13 +21,14 @@ 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,
\App\Domains\Real\Commands\Sync\OrderBaseSync::class,
\App\Domains\Real\Commands\Sync\AddedOrderSync::class,
\App\Domains\Real\Commands\Sync\FlowPoolSync::class,
\App\Domains\Real\Commands\Sync\RefundSync::class,
\App\Domains\Real\Commands\Sync\ActivatedSync::class,
\App\Domains\Real\Commands\Sync\CancelledSync::class,
]);
}

View File

@ -64,7 +64,7 @@ class ProductSync extends Command
Product::upsert($products, ['sn', 'deleted_at'], true);
Product::upsert($products, ['sn', 'deleted_at'], []);
$subSql = 'SELECT DISTINCT ON (company_id, package_id) id FROM virtual_products ORDER BY company_id, package_id, updated_at DESC';

View File

@ -35,8 +35,16 @@ class FetchController extends Controller
*/
public function packages(PackageRepository $packageRepository)
{
$type = $this->request->ids('type');
return res($this->search($packageRepository->whereIn('type', $type), ['name', 'carrier_operator']), '', 201);
$packages = $this->search($packageRepository, ['type', 'name', 'carrier_operator']);
if ($this->request->has('type')) {
$type = $this->request->ids('type');
$packages = $packages->filter(function ($item) use ($type) {
return !in_array($item->type, $type);
});
}
return res($packages, '', 201);
}
/**
@ -78,11 +86,7 @@ class FetchController extends Controller
});
}
$sorted = $results->sortBy($field)->values()->all();
if ($limit) {
return array_slice($sorted, 0, $limit);
}
$sorted = $results->sortBy($primaryKey)->values()->all();
return $sorted;
}

View File

@ -1,67 +0,0 @@
<?php
namespace App\Domains\Virtual\Jobs;
use Illuminate\Support\Arr;
use Illuminate\Bus\Queueable;
use App\Models\Real\RealVirtual;
use Dipper\Foundation\Bus\Dispatchable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Domains\Real\Repositories\OrderRepository as RealOrderRepository;
use App\Domains\Virtual\Repositories\OrderRepository as VirtualOrderRepository;
class CreateRealVirtualRelation implements ShouldQueue
{
use Queueable, Dispatchable;
protected $virtualOrderId;
protected $realOrderIds;
public function __construct($virtualOrderId, $realOrderIds)
{
$this->virtualOrderId = $virtualOrderId;
$this->realOrderIds = $realOrderIds;
}
/**
*
*/
public function handle(RealOrderRepository $realOrderRepository, VirtualOrderRepository $virtualOrderRepository)
{
$select = ['id', 'company_id', 'package_id'];
if (!$virtualOrder = $virtualOrderRepository->select($select)->find($this->virtualOrderId)) {
return ;
}
$realOrders = $realOrderRepository->select($select)->whereIn('id', $this->realOrderIds)->get();
if (empty($realOrders)) {
return ;
}
$array = [];
foreach ($realOrders as $value) {
$k = implode(',', [$value['company_id'], $value['package_id'], $virtualOrder['company_id'], $virtualOrder['package_id']]);
$array[$k] = [
'real_company_id' => $value['company_id'],
'real_package_id' => $value['package_id'],
'virtual_company_id' => $virtualOrder['company_id'],
'virtual_package_id' => $virtualOrder['package_id'],
'times' => 1,
'updated_at' => date('Y-m-d H:i:s'),
];
}
$builder = RealVirtual::query()->toBase();
$sql = $builder->getGrammar()->compileInsert($builder, $array);
$sql .= ' on conflict (real_company_id,real_package_id,virtual_company_id,virtual_package_id) do update set
times=real_virtual_relations.times+excluded.times,
updated_at=excluded.updated_at';
$builder->connection->insert($sql, Arr::flatten($array, 1));
}
}

View File

@ -15,13 +15,13 @@ use Illuminate\Database\Query\Grammars\Grammar;
use App\Domains\Virtual\Services\CompanyService;
use App\Domains\Virtual\Services\PackageService;
use App\Domains\Virtual\Repositories\OrderRepository;
use App\Domains\Virtual\Jobs\CreateRealVirtualRelation;
use App\Domains\Virtual\Repositories\ProductRepository;
use App\Models\Real\OrderCardPartition as RealOrderCardPartition;
use App\Domains\Virtual\Repositories\OrderCardPartitionRepository;
use App\Domains\Real\Repositories\OrderRepository as RealOrderRepository;
use App\Domains\Real\Repositories\OrderCardPartitionRepository as RealOrderCardPartitionRepository;
use App\Exceptions\InvalidArgumentException;
use App\Models\Card\Card;
class OrderService extends Service
{
@ -119,6 +119,7 @@ class OrderService extends Service
'order_status' => ['in:0,1,2,3,4,5'],
'transaction_status' => ['in:0,1,2'],
'extends' => ['array'],
'selected' => ['array'],
];
$message = [
@ -165,61 +166,48 @@ class OrderService extends Service
Validator::validate($attributes, $rule, $message);
DB::beginTransaction();
if (isset($attributes['sign']) && $attributes['sign'] == 2) {
if (empty($attributes['selected'])) {
throw new InvalidArgumentException('请选择卡');
}
// 改企业的卡新增一批虚拟卡,并替换原有订单里的卡
$simArray = implode(',', array_pluck($attributes['selected'], 'sim'));
try {
DB::statement("select change_cards('{{$simArray}}'::INT8[]);");
} catch (\Exception $e) {
DB::rollBack();
throw $e;
}
if (isset($attributes['selected']) && empty('selected')) {
throw new InvalidArgumentException('请选择卡');
}
// 转销售和改企业的都立即激活卡
if (isset($attributes['sign']) && in_array($attributes['sign'], [1, 2])) {
$params = array_pluck($attributes['selected'], 'sim');
$sql = 'UPDATE cards SET virtual_activated_at = ? WHERE sim IN (%s)';
$sql = sprintf($sql, app(Grammar::class)->parameterize($params));
array_unshift($params, $attributes['order_at']);
DB::update($sql, $params);
$attributes['type'] = 0;
$originType = $attributes['type'];
DB::beginTransaction();
// 销售订单,如果单卡使用多次,仅第一次为销售,其他改续费。
$extras = [];
$selected = $attributes['selected'];
$attributes['counts'] = count($selected);
try {
// 改企业的卡新增一批虚拟卡,并替换原有订单里的卡
if (isset($attributes['sign']) && $attributes['sign'] == 2) {
$simArray = implode(',', array_pluck($attributes['selected'], 'sim'));
DB::statement("select change_cards('{{$simArray}}'::INT8[]);");
}
foreach ($selected as &$card) {
if ($card['counts'] > 1) {
array_push($extras, [
'sim' => $card['sim'],
'counts' => $card['counts'] - 1,
]);
// 转销售和改企业的都立即激活卡
if (isset($attributes['sign']) && in_array($attributes['sign'], [1, 2])) {
$array = array_map(function ($item) use ($attributes) {
return ['sim' => $item['sim'], 'virtual_activated_at' => $attributes['order_at']];
}, $attributes['selected']);
$card['counts'] = 1;
Card::upsert($array, ['sim', 'deleted'], ['virtual_activated_at']);
$attributes['type'] = 0;
$originType = $attributes['type'];
// 销售订单,如果单卡使用多次,仅第一次为销售,其他改续费。
$extras = [];
$selected = $attributes['selected'];
$attributes['counts'] = count($selected);
foreach ($selected as &$card) {
if ($card['counts'] > 1) {
array_push($extras, [
'sim' => $card['sim'],
'counts' => $card['counts'] - 1,
]);
$card['counts'] = 1;
}
}
$attributes['selected'] = $selected;
}
$attributes['selected'] = $selected;
if (!empty($extras)) {
$extraOrderData = $attributes;
$extraOrderData['type'] = $originType;
$extraOrderData['counts'] = array_sum(array_pluck($extras, 'counts'));
$extraOrderData['total_price'] = $attributes['unit_price'] * $extraOrderData['counts'];
$extraOrderData['custom_price'] = $attributes['unit_price'] * $extraOrderData['counts'];
$extraOrder = $this->orderRepository->create($attributes);
$this->upsertOrderCards($extras, $extraOrder);
}
if (!$attributes['id']) {
if ($product->company_id != $attributes['company_id']) {
throw new NotAllowedException('非法操作');
@ -233,35 +221,43 @@ class OrderService extends Service
$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 {
$this->upsertOrderCards($attributes['selected'], $node);
$this->orderRepository->forgetCached();
$this->orderCardPartitionRepository->forgetCached();
app(RealOrderCardPartitionRepository::class)->forgetCached();
// 销售订单创建企业套餐关联
if ($node['type'] === 0) {
CreateRealVirtualRelation::dispatch($node->id, array_pluck($attributes['selected'], 'order_id'));
if ($attributes['id']) {
if (!$node = $this->orderRepository->find($attributes['id'])) {
throw new NotExistException('订单不存在或已删除');
}
} catch (\Exception $e) {
DB::rollBack();
throw new HttpException('操作失败');
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 {
$this->upsertOrderCards($attributes['selected'], $node);
$this->orderRepository->forgetCached();
$this->orderCardPartitionRepository->forgetCached();
app(RealOrderCardPartitionRepository::class)->forgetCached();
} catch (\Exception $e) {
DB::rollBack();
throw new HttpException('操作失败');
}
}
if (!empty($extras)) {
$extraOrderData = $attributes;
$extraOrderData['type'] = $originType;
$extraOrderData['counts'] = array_sum(array_pluck($extras, 'counts'));
$extraOrderData['total_price'] = $attributes['unit_price'] * $extraOrderData['counts'];
$extraOrderData['custom_price'] = $attributes['unit_price'] * $extraOrderData['counts'];
$extraOrder = $this->orderRepository->create($attributes);
$this->upsertOrderCards($extras, $extraOrder);
}
} catch (\Exception $e) {
DB::rollBack();
throw $e;
}
DB::commit();

View File

@ -35,14 +35,11 @@ class Artisan extends Model
public static $names = [
'real:sync-added-order' => '同步RD企业订单数据',
'real:sync-bloc' => '同步RD集团数据',
'real:sync-company' => '同步RD企业数据',
'real:sync-mongo' => '同步卡基础信息数据',
'real:sync-order' => '同步RD基础订单数据',
'real:sync-package' => '同步RD套餐数据',
'virtual:sync-card' => '同步VD卡信息数据',
'virtual:sync-company' => '同步VD企业数据',
'virtual:sync-log' => '同步VD订单数据',
'virtual:sync-package' => '同步VD套餐数据',
'virtual:sync-product' => '同步VD定价',
];

View File

@ -1,48 +0,0 @@
<?php
namespace App\Models\Card;
use App\Core\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* App\Models\Card\Bloc
*
* @property int $id 集团ID
* @property string $sn 集团编号
* @property string $name 集团名称
* @property string $shorthand 英文简称
* @property int $carrier_operator 运营商(0:联通 1:移动 2:电信)
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string|null $deleted_at
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Card\Card[] $cards
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Card\Bloc newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Card\Bloc newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Card\Bloc query()
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Card\Bloc whereCarrierOperator($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Card\Bloc whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Card\Bloc whereDeletedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Card\Bloc whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Card\Bloc whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Card\Bloc whereShorthand($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Card\Bloc whereSn($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Card\Bloc whereUpdatedAt($value)
* @mixin \Eloquent
* @method static bool|null forceDelete()
* @method static \Illuminate\Database\Query\Builder|\App\Models\Card\Bloc onlyTrashed()
* @method static bool|null restore()
* @method static \Illuminate\Database\Query\Builder|\App\Models\Card\Bloc withTrashed()
* @method static \Illuminate\Database\Query\Builder|\App\Models\Card\Bloc withoutTrashed()
*/
class Bloc extends Model
{
use SoftDeletes;
protected $table = 'blocs';
public function cards()
{
return $this->hasMany(Card::class, 'bloc_id', 'id');
}
}

View File

@ -10,7 +10,6 @@ use App\Core\Model;
* @property int $sim sim号
* @property string $imsi imsi号
* @property string $iccid iccid号
* @property int $bloc_id 来源集团ID
* @property int $carrier_operator 运营商(0:联通 1:移动 2:电信)
* @property \Illuminate\Support\Carbon|null $activated_at 激活时间
* @property \Illuminate\Support\Carbon|null $virtual_activated_at 虚拟激活时间
@ -23,7 +22,6 @@ use App\Core\Model;
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Card\Card newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Card\Card query()
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Card\Card whereActivatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Card\Card whereBlocId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Card\Card whereCancelledAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Card\Card whereCarrierOperator($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Card\Card whereCreatedAt($value)

View File

@ -3,7 +3,6 @@
namespace App\Models\Real;
use App\Core\Model;
use App\Models\Card\Card;
/**
* App\Models\Real\FlowPool

View File

@ -3,7 +3,6 @@
namespace App\Models\Real;
use App\Core\Model;
use App\Models\Card\Card;
/**
* App\Models\Real\Order

View File

@ -4,9 +4,7 @@ namespace App\Models\Virtual;
use App\Core\Model;
use App\Models\Card\Card;
use App\Models\Real\OrderCard;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Models\Virtual\Relations\OrderRelations;
/**
* App\Models\Virtual\Order

View File

@ -1,46 +0,0 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateBlocsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
if (Schema::hasTable('blocs')) {
return;
}
Schema::create('blocs', function (Blueprint $table) {
$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->unique(['sn', 'deleted_at']);
$table->index('name');
$table->index('carrier_operator');
$table->comment('卡源集团');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('blocs');
}
}

View File

@ -21,7 +21,6 @@ class CreateCardsTable extends Migration
$table->bigInteger('sim')->unsigned()->default(0)->comment('sim号');
$table->string('imsi', 32)->default('')->comment('imsi号');
$table->string('iccid', 32)->default('')->comment('iccid号');
$table->integer('bloc_id')->unsigned()->default(0)->comment('来源集团ID');
$table->tinyInteger('carrier_operator')->unsigned()->default(255)->comment('运营商(0:联通 1:移动 2:电信)');
$table->timestamp('activated_at')->nullable()->comment('激活时间');
$table->timestamp('virtual_activated_at')->nullable()->comment('虚拟激活时间');

View File

@ -27,6 +27,7 @@ class CreateRealOrderCardsTable extends Migration
$table->integer('counts')->unsigned()->default(0)->comment('数量');
$table->integer('unit_price')->unsigned()->default(0)->comment('单价');
$table->integer('virtual_order_id')->unsigned()->default(0)->comment('VD 订单ID');
$table->tinyInteger('refunded')->unsigned()->default(0)->comment('退货标志 0:未退货 1:已退货');
$table->timestamps();
$table->softDeletes();

View File

@ -35,6 +35,7 @@ class CreateVirtualOrderCardsTables extends Migration
$table->timestamp('service_start_at')->nullable()->comment('服务开始时间');
$table->timestamp('service_end_at')->nullable()->comment('服务结束时间');
$table->bigInteger('original_sim')->unsigned()->default(0)->comment('原始sim号');
$table->tinyInteger('refunded')->unsigned()->default(0)->comment('退货标志 0:未退货 1:已退货');
$table->timestamps();
$table->softDeletes();

View File

@ -1,42 +0,0 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCompanyRelations extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
if (!Schema::hasTable('real_virtual_relations')) {
Schema::create('real_virtual_relations', function (Blueprint $table) {
$table->integer('real_company_id')->unsigned()->default(0)->comment('RD企业ID');
$table->integer('real_package_id')->unsigned()->default(0)->comment('RD套餐ID');
$table->integer('virtual_company_id')->unsigned()->default(0)->comment('VD企业ID');
$table->integer('virtual_package_id')->unsigned()->default(0)->comment('VD套餐ID');
$table->integer('times')->unsigned()->default(0)->comment('关联次数');
$table->timestamp('updated_at')->comment('更新时间');
$table->primary(['real_company_id', 'real_package_id', 'virtual_company_id', 'virtual_package_id']);
$table->comment('RD VD关系关联');
});
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('real_virtual_relations');
}
}

View File

@ -20,10 +20,21 @@ BEGIN
SELECT array_to_json(array_agg(row_to_json(t))) INTO activate_cards
FROM (SELECT cards.sim, cards.virtual_activated_at FROM vd.cards WHERE cards.sim = ANY ($1)) t;
query := 'SELECT virtual_order_cards_partition.id, virtual_order_cards_partition.type, virtual_order_cards_partition.sim, virtual_order_cards_partition.package_id, virtual_order_cards_partition.created_at, virtual_packages.service_months, virtual_packages.effect_months, virtual_packages.delay_months, virtual_order_cards_partition.counts
FROM vd.virtual_order_cards_partition JOIN vd.virtual_packages ON virtual_order_cards_partition.package_id = virtual_packages."id"
WHERE virtual_order_cards_partition.sim = ANY($1)
ORDER BY sim ASC, created_at ASC';
query := 'SELECT
virtual_order_cards_partition.id,
virtual_order_cards_partition.type,
virtual_order_cards_partition.sim,
virtual_order_cards_partition.package_id,
virtual_order_cards_partition.created_at,
virtual_packages.service_months,
virtual_packages.effect_months,
virtual_packages.delay_months,
virtual_order_cards_partition.counts,
virtual_order_cards_partition.service_start_at,
virtual_order_cards_partition.service_end_at
FROM vd.virtual_order_cards_partition JOIN vd.virtual_packages ON virtual_order_cards_partition.package_id = virtual_packages."id"
WHERE virtual_order_cards_partition.sim = ANY($1)
ORDER BY sim ASC, created_at ASC';
FOR order_row IN EXECUTE query USING $1
LOOP
@ -80,8 +91,8 @@ BEGIN
sim := order_row.sim::INT8;
"type" := order_row."type"::INT2;
package_id := order_row."package_id"::INT;
service_start_at := temp_service_start_at::TIMESTAMP;
service_end_at := temp_service_end_at::TIMESTAMP;
service_start_at := COALESCE(order_row.service_start_at::TIMESTAMP, temp_service_start_at::TIMESTAMP);
service_end_at := COALESCE(order_row.service_end_at::TIMESTAMP, temp_service_end_at::TIMESTAMP);
RETURN NEXT;
END LOOP;
RETURN;
@ -97,7 +108,6 @@ BEGIN
service_end_at=tmp.service_end_at
FROM (SELECT * FROM GET_TIMELINES($1)) as tmp
WHERE tmp.id = virtual_order_cards_partition.id;
END;
$$ LANGUAGE plpgsql SET synchronous_commit TO OFF;
@ -157,12 +167,12 @@ BEGIN
OVERLAY(cards.sim::TEXT PLACING (4 + t.counts)::TEXT FROM 4 FOR 1)::INT8 as sim,
OVERLAY(imsi::TEXT PLACING (1 + t.counts)::TEXT FROM 3 FOR 1) as imsi,
OVERLAY(iccid::TEXT PLACING (1 + t.counts)::TEXT FROM 5 FOR 1) as iccid,
bloc_id, carrier_operator, activated_at, virtual_activated_at, type, real_company_id, cancelled_at, created_at, updated_at
carrier_operator, activated_at, virtual_activated_at, type, real_company_id, cancelled_at, created_at, updated_at
FROM cards JOIN (
SELECT OVERLAY(sim::TEXT PLACING $1 FROM 4 FOR 1), COUNT ( * ) AS counts, MIN ( sim ) AS sim FROM cards WHERE sim::TEXT SIMILAR TO $2 GROUP BY 1
) AS t ON t.sim = cards.sim
), new_inserts AS (
INSERT INTO cards SELECT sim,imsi,iccid,bloc_id, carrier_operator, activated_at, virtual_activated_at, type, real_company_id, cancelled_at, created_at, updated_at FROM new_cards
INSERT INTO cards SELECT sim,imsi,iccid, carrier_operator, activated_at, virtual_activated_at, type, real_company_id, cancelled_at, created_at, updated_at FROM new_cards
)
UPDATE virtual_order_cards_partition SET original_sim=t.original_sim,sim=t.sim FROM (SELECT sim,original_sim FROM new_cards) as t
WHERE virtual_order_cards_partition.sim=t.original_sim';

View File

@ -30,3 +30,18 @@ OR DELETE
ON cards
FOR EACH ROW
EXECUTE PROCEDURE REINDEX_TIMELINES ();
CREATE OR REPLACE VIEW real_virtual_relations AS
SELECT
r.type as type,
r.company_id as real_company_id,
r.package_id as real_package_id,
v.company_id as virtual_company_id,
v.package_id as virtual_package_id,
COUNT(*) as times,
MAX(v.created_at) as updated_at
FROM real_order_cards_partition as r
JOIN virtual_order_cards as v ON v.id = r.virtual_order_id
WHERE r.virtual_order_id <> 0
GROUP BY r.type,r.company_id,r.package_id,v.company_id,v.package_id

View File

@ -94,25 +94,21 @@ CREATE MATERIALIZED VIEW logs AS
ckb_custom_handle_log.pay_type;
-- 第三步:同步卡数据
INSERT INTO vd.cards (sim, imsi, iccid, bloc_id, carrier_operator, "type", activated_at, virtual_activated_at, cancelled_at, created_at, updated_at)
INSERT INTO vd.cards (sim, imsi, iccid, carrier_operator, "type", virtual_activated_at, cancelled_at, created_at, updated_at)
(
SELECT
card_number::BIGINT as sim,
imsi,
iccid,
COALESCE(blocs.id, 0) as bloc_id,
CASE carrieroperator WHEN 10 THEN 0 WHEN 11 THEN 1 WHEN 12 THEN 2 ELSE 255 END AS carrier_operator,
CASE WHEN substr(card_number, 4, 1)::INT >= 5 THEN 1 ELSE 0 END AS "type",
CASE card_cycle_start::int WHEN 0 THEN NULL ELSE to_timestamp(card_cycle_start::int) END AS activated_at,
CASE card_cycle_start::int WHEN 0 THEN NULL ELSE to_timestamp(card_cycle_start::int) END AS virtual_activated_at,
CASE custom_state WHEN 13 THEN to_timestamp(update_time) ELSE NULL END AS cancelled_at,
to_timestamp(create_time) as created_at,
to_timestamp(update_time) as updated_at
FROM
ckb_custom
LEFT JOIN vd.blocs ON blocs.sn = ckb_custom.card_from
) ON CONFLICT (sim) DO UPDATE SET
activated_at=COALESCE(cards.activated_at, excluded.virtual_activated_at),
virtual_activated_at=excluded.virtual_activated_at,
cancelled_at=excluded.cancelled_at;

View File

@ -7,13 +7,8 @@
* @param {[type]} name [description]
* @return {[type]} [description]
*/
export function companies(name, limit = 5) {
return service.get('api/virtual/fetch/companies', {
params: {
search: name,
limit
}
});
export function companies() {
return service.get('api/virtual/fetch/companies');
}
/**
@ -21,12 +16,6 @@ export function companies(name, limit = 5) {
* @param {[type]} name [description]
* @return {[type]} [description]
*/
export function packages(type = 0, name, limit = 5) {
return service.get('api/virtual/fetch/packages', {
params: {
type: type,
search: name,
limit
}
});
export function packages() {
return service.get('api/virtual/fetch/packages');
}

View File

@ -38,7 +38,7 @@ export default {
return new Promise((resolve, reject) => {
if (!this.completeCompanyInitialized) {
this.completeCompanyInitialized = true;
FETCH.companies(null, 0).then(res => {
FETCH.companies().then(res => {
if (res.code === 0) {
this.completeCompanies = res.data;
resolve(res.data);
@ -59,14 +59,19 @@ export default {
});
});
},
initCompletePackages(type = 0) {
initCompletePackages(type = null) {
return new Promise((resolve, reject) => {
if (!this.completePackageInitialized) {
FETCH.packages(type, null, 0).then(res => {
FETCH.packages().then(res => {
if (res.code === 0) {
this.completePackageInitialized = true;
this.completePackages = res.data;
resolve(res.data);
this.completePackages = res.data.filter(el => {
if (type !== null && el.type !== type) {
return false;
}
return true;
});
resolve(this.completePackages);
}
reject(res);

View File

@ -77,7 +77,7 @@ export default {
let search = [];
let init_options = {
orderBy: 'created_at',
orderBy: 'updated_at',
sortedBy: 'desc'
};
@ -165,24 +165,24 @@ export default {
* @return {[type]} [description]
*/
return h('p', {
style: {
fontSize: '14px',
marginTop: '15px'
}
},
style: {
fontSize: '14px',
marginTop: '15px'
}
},
[
h('span', data.message + ' 请点击下载:'),
h('span', {
domProps: {
innerHTML: '导入失败.xls'
},
class: ['primary-color', 'c-p'],
on: {
click: () => {
this.downloadExcel(tHeader, this.formatJson(filterVal, data.result), '导入失败');
}
domProps: {
innerHTML: '导入失败.xls'
},
class: ['primary-color', 'c-p'],
on: {
click: () => {
this.downloadExcel(tHeader, this.formatJson(filterVal, data.result), '导入失败');
}
})
}
})
]);
},
exportExcelInfo(h, data) {
@ -194,28 +194,28 @@ export default {
*/
return h('p', {
style: {
fontSize: '14px',
marginTop: '15px'
}
},
style: {
fontSize: '14px',
marginTop: '15px'
}
},
[
h('span', data.message + ' 请点击下载:'),
h('span', {
domProps: {
innerHTML: '导入失败.xls'
},
class: ['primary-color', 'c-p'],
on: {
click: () => {
if (data.url !== '') {
window.open(data.url);
} else {
this.$Message.info('无数据可下载');
}
domProps: {
innerHTML: '导入失败.xls'
},
class: ['primary-color', 'c-p'],
on: {
click: () => {
if (data.url !== '') {
window.open(data.url);
} else {
this.$Message.info('无数据可下载');
}
}
})
}
})
]
);
},

View File

@ -22,35 +22,29 @@ export default {
loading: false,
disabled: false,
steps: [
{
'title': '同步集团',
'content': '所有卡源集团的数据',
'command': 'real:sync-bloc',
'max': 5
},
{
'title': '同步企业',
'content': '所有企业数据',
'command': 'real:sync-company',
'max': 10
'max': 5
},
{
'title': '同步套餐',
'content': '所有套餐数据',
'command': 'real:sync-package',
'max': 25
'max': 10
},
{
'title': '同步流量池',
'content': '所有流量池的数据',
'command': 'real:sync-flow-pool',
'max': 30
'max': 20
},
{
'title': '同步订单',
'content': '指定月份的销售订单数据',
'command': 'real:sync-order',
'max': 70,
'max': 60,
'datePicker': true
},
{
@ -105,7 +99,7 @@ export default {
if (this.circle.percent < max) {
this.circle.percent++;
}
}, 1500);
}, 1000);
service.post('/api/artisan/call', params).then(res => {
if (res.code == 0) {

View File

@ -7,7 +7,6 @@ export default {
return {
commands: {
'real:sync-added-order': '同步RD企业订单数据',
'real:sync-bloc': '同步RD集团数据',
'real:sync-company': '同步RD企业数据',
'real:sync-mongo': '同步卡基础信息数据',
'real:sync-order': '同步RD基础订单数据',

View File

@ -19,6 +19,14 @@
</Select>
</li>
<li class="handle-item w-250">
<Select clearable placeholder="支付方式" v-model="params.pay_channel">
<Option :value="0">联通</Option>
<Option :value="1">移动</Option>
<Option :value="2">电信</Option>
</Select>
</li>
<li class="handle-item w-250">
<Select clearable placeholder="使用状态" v-model="params.used">
<Option :value="0">未使用</Option>

View File

@ -559,7 +559,7 @@ export default {
this.resetParams();
this.changePage(1);
},
sortOrders(sortBy = 'times') {
sortOrders(sortBy = 'updated_at') {
let mapped = [];
if (sortBy === 'order_at') {

View File

@ -205,20 +205,13 @@ export default {
this.my_show = false;
},
handleChange(type) {
let packageType = this.type === 1 ? 0 : this.type;
this.initCompletePackages(packageType).then(packages => {
let completePackagesFilter = [];
completePackagesFilter = packages.filter(item => {
this.initCompletePackages().then(packages => {
packages = packages.filter(item => {
return item.status === 0;
});
if (type === 1) {
this.params.package_id = '';
completePackagesFilter = packages.filter(item => {
return item.carrier_operator === this.params.carrier_operator;
});
}
if (type === 2) {
@ -231,7 +224,15 @@ export default {
}
}
this.completePackagesFilter = completePackagesFilter;
if (typeof (this.params.carrier_operator) === 'number') {
packages = packages.filter(item => {
return item.carrier_operator === this.params.carrier_operator;
});
}
this.completePackagesFilter = packages.filter(item => {
return item.type === 0;
});
});
},
cards() {
@ -329,6 +330,8 @@ export default {
return this.companies[el.index];
});
this.params.company_id = this.companies[0].company_id;
let mappedPackage = this.completePackagesFilter.map(el, i => {
return { index: i, package_id: el.id };
});
@ -349,6 +352,8 @@ export default {
this.completePackagesFilter = mappedPackage.map(el => {
return this.completePackagesFilter[el.index];
});
this.params.package_id = this.completePackagesFilter[0].package_id;
}
},
handelSuccess() {

View File

@ -7,14 +7,14 @@ use Illuminate\Support\Facades\Artisan;
require_once realpath(dirname(__FILE__) . '/TestCase.php');
Artisan::queue('real:sync-company');
Artisan::queue('real:sync-bloc');
Artisan::queue('real:sync-package');
Artisan::queue('real:sync-flow-pool');
$datetime = Carbon::parse('2017-04-01');
call('real:sync-order');
call('real:sync-activate');
call('real:sync-custom-order');
call('real:sync-added-order');
call('real:sync-refund');
function call($command)
{

View File

@ -8,169 +8,82 @@ require_once realpath(dirname(__FILE__) . '/TestCase.php');
set_time_limit(-1);
ini_set('memory_limit', '4096m');
$file = __DIR__ . '/db.csv';
$file = getcwd() . '/' . $argv[1];
$array = [];
if (($handle = fopen($file, 'r')) !== false) {
while (($data = fgetcsv($handle)) !== false) {
$sim = trim(str_replace('\t', '', $data[0]));
$packages = DB::connection('vd_old')->table('ckb_add_value_package')->where('del_status', 10)->get()->keyBy('package_sn');
if ($sim === 'sim' || empty($sim)) {
if (($handle = fopen($file, 'r')) !== false) {
$i = 0;
while (($data = fgetcsv($handle)) !== false) {
$i ++;
$custom_no = trim(str_replace('\t', '', $data[1]));
if ($i < 3 || $custom_no === '用户编号' || empty($custom_no)) {
continue;
}
$content = trim($data[1]);
$startTime = DB::connection('vd_old')->table('ckb_custom_handle_log')->selectRaw('MAX(valid_end_time) as valid_end_time')
->where('custom_no', $custom_no)
->where('type', 14)->first();
$array[] = [
'sim' => $sim,
'content' => $content,
];
}
fclose($handle);
}
$startTime = $startTime->valid_end_time + 1;
$packages = DB::connection('vd_old')->table('ckb_package')->select(['package_sn', 'cycle_value'])->get()->pluck('cycle_value', 'package_sn');
$logs = DB::connection('vd_old')->table('ckb_custom_handle_log')->where('custom_no', $custom_no)
->where('type', 11)->get();
$addValuePackages = DB::connection('vd_old')->table('ckb_add_value_package')->select(['package_sn', 'service_cycle'])->get()->pluck('service_cycle', 'package_sn');
echo $custom_no . PHP_EOL;
echo 'total - ' . count($array) . PHP_EOL;
$custom = DB::connection('vd_old')->table('ckb_custom')->where('custom_no', $custom_no)->first();
foreach (array_chunk($array, 5000) as $k => $data) {
$updates = [];
$content = $data[23];
echo 'k - ' . $k . PHP_EOL;
$package = $packages[$content];
$t = array_pluck($data, 'content', 'sim');
$customs = DB::connection('vd_old')->table('ckb_custom')->select(['custom_no', 'card_number'])
->whereIn('card_number', array_pluck($data, 'sim'))->get()->keyBy('custom_no')->toArray();
foreach ($customs as &$custom) {
$custom = (array)$custom;
}
$rows = DB::connection('vd_old')->table('ckb_custom_handle_log')->select(['id', 'type', 'content', 'custom_no', 'valid_start_time', 'valid_end_time'])
->whereIn('custom_no', array_keys($customs))->orderBy('valid_start_time', 'asc')->get()->groupBy('custom_no');
$renews = [];
foreach ($rows as $custom_no => $items) {
$sim = $customs[$custom_no]['card_number'];
$count = 0;
foreach ($items as $row) {
echo $row->id . '-' . $custom_no . PHP_EOL;
if ($row->type === 13 || $row->type === 10) {
$valid_end_time = Carbon::createFromTimestamp($row->valid_start_time)->addMonths($packages[$row->content] - 1)->endOfMonth()->timestamp;
$updates[] = [
'id' => $row->id,
'valid_start_time' => $row->valid_start_time,
'content' => $row->content,
'valid_end_time' => $valid_end_time,
];
$valid_start_time = $valid_end_time + 1;
continue;
}
if ($row->type == 14) {
$count++;
if ($count > 1) {
echo $row->id . PHP_EOL;
DB::connection('vd_old')->table('ckb_custom_handle_log')->where('id', $row->id)->delete();
continue;
}
$vet = Carbon::createFromTimestamp($valid_start_time)->addMonths($addValuePackages[$t[$sim]] - 1)->endOfMonth()->timestamp;
$updates[] = [
'id' => $row->id,
'valid_start_time' => $valid_start_time,
'content' =>$t[$sim],
'valid_end_time' => $vet,
];
$renews[$sim] = [
'valid_start_time' => $valid_start_time,
'content' =>$t[$sim],
'valid_end_time' => $vet,
];
}
if(!$package){
throw new \Exception('未找到套餐包');
}
}
$rows = DB::connection('vd_old')->table('ckb_user_order')->select(['id', 'package_id', 'new_package_id', 'sim', 'valid_start_time', 'valid_end_time'])
->whereIn('sim', array_pluck($customs, 'card_number'))->orderBy('valid_start_time', 'asc')->get()->groupBy('sim');
foreach ($logs as $item) {
$endTime = strtotime("+ {$package->service_cycle} month", $startTime) - 1;
$userUpdates = [];
foreach ($rows as $sim => $items) {
echo $sim . PHP_EOL;
$count = 0;
foreach ($items as $row) {
$count++;
if ($count > 1) {
DB::connection('vd_old')->table('ckb_user_order')->where('id', $row->id)->delete();
continue;
}
if (!$renews[$sim]) {
throw new \Exception('未找到卡 #:'. $item);
}
$userUpdates[] = [
'id' => $row->id,
'valid_start_time' => $renews[$sim]['valid_start_time'],
'package_id' => $renews[$sim]['content'],
'new_package_id' => $renews[$sim]['content'],
'valid_end_time' =>$renews[$sim]['valid_end_time'],
$data = [
'type' => 14,
'content' => $content,
'valid_start_time' => $startTime,
'valid_end_time' => $endTime,
'sale_account' => 0,
'order_account' => 0,
'task_number' => 'change_renew_to_renew_package',
];
DB::connection('vd_old')->table('ckb_custom_handle_log')->where('id', $item->id)->update($data);
$userOrder = [
'package_id' => $content,
'new_package_id' => $content,
'imsi' => $custom->imsi,
'company' => $item->company,
'pay_type' => $item->pay_type,
'service_type' => 13,
'pay_value' => 0,
'order_time' => $item->create_time,
'pay_status' => 10,
'valid_start_time' => $startTime,
'valid_end_time' => $endTime,
'create_time' => $item->create_time,
'task_number' => 'change_renew_to_renew_package',
'sim' => $custom->card_number,
];
DB::connection('vd_old')->table('ckb_user_order')->insert($userOrder);
$startTime = $endTime + 1;
}
}
DB::connection('vd_old')->table('ckb_custom_handle_log')->upsert($updates, 'id');
DB::connection('vd_old')->table('ckb_user_order')->upsert($userUpdates, 'id');
}
dd(1);
$file = __DIR__ . '/test.csv';
$out = __DIR__ . '/test_out.csv';
$fp = fopen($out, 'w');
fputcsv($fp, ['sim', 'iccid', 'imsi']);
$array = [];
if (($handle = fopen($file, 'r')) !== false) {
while (($data = fgetcsv($handle)) !== false) {
$sim = trim($data[0]);
if ($sim === 'sim' || empty($sim)) {
continue;
}
$array[] = $sim;
}
fclose($handle);
}
foreach (array_chunk($array, 10000) as $values) {
$rows = DB::connection('vd_old')->table('ckb_custom')->select(['card_number as sim', 'iccid', 'imsi'])
->whereIn('card_number', $values)->get()->keyBy('sim');
foreach ($values as $value) {
$row = $rows[$value];
if (!$row) {
throw new \Exception('未找到卡 #:' . $value);
}
fputcsv($fp, [$row->sim."\t", $row->iccid."\t", $row->imsi."\t"]);
}
}
fclose($fp);

View File

@ -1,9 +1,14 @@
<?php
use Illuminate\Support\Facades\Schema;
use App\Domains\Card\Services\CardService;
require_once realpath(dirname(__FILE__) . '/TestCase.php');
Schema::table('virtual_products', function ($table) {
$table->integer('renew_price')->unsigned()->default(0)->comment('续费价格');
});
$simArray = [
];
$values = CardService::getMongoCardsInfo($simArray);
dd($values);

View File

@ -1,3 +1,3 @@
<?php
require realpath(dirname(__FILE__) . '/../bootstrap/app.php');

View File

@ -0,0 +1,115 @@
用户编号,续费时间,修正订单时间
No00003799858,2018/10/15,2018/10/26
No00003799859,2018/10/15,2018/10/26
No00003799860,2018/10/15,2018/10/26
No00003799862,2018/10/15,2018/10/26
No00003799878,2018/10/15,2018/10/26
No00003799879,2018/10/15,2018/10/26
No00003799880,2018/10/15,2018/10/26
No00003799881,2018/10/15,2018/10/26
No00003799883,2018/10/15,2018/10/26
No00003799884,2018/10/15,2018/10/26
No00004332795,2018/12/5,2018/12/21
No00004332795,2018/12/5,2018/12/21
No00004332921,2018/12/5,2018/12/21
No00004332921,2018/12/5,2018/12/21
No00004332972,2018/12/5,2018/12/21
No00004332972,2018/12/5,2018/12/21
No00004332974,2018/12/5,2018/12/21
No00004332974,2018/12/5,2018/12/21
No00004333728,2018/12/5,2018/12/21
No00004333728,2018/12/5,2018/12/21
No00004333789,2018/12/5,2018/12/21
No00004333789,2018/12/5,2018/12/21
No00004333789,2018/12/5,2018/12/21
No00004333794,2018/12/5,2018/12/21
No00004333794,2018/12/5,2018/12/21
No00004334080,2018/12/5,2018/12/21
No00004334080,2018/12/5,2018/12/21
No00004334113,2018/12/5,2018/12/21
No00004334113,2018/12/5,2018/12/21
No00004334159,2018/12/5,2018/12/21
No00004334159,2018/12/5,2018/12/21
No00004334167,2018/12/5,2018/12/21
No00004334167,2018/12/5,2018/12/21
No00004334168,2018/12/5,2018/12/21
No00004334168,2018/12/5,2018/12/21
No00004334169,2018/12/5,2018/12/21
No00004334169,2018/12/5,2018/12/21
No00004334170,2018/12/5,2018/12/21
No00004334170,2018/12/5,2018/12/21
No00004334174,2018/12/5,2018/12/21
No00004334174,2018/12/5,2018/12/21
No00004334178,2018/12/5,2018/12/21
No00004334178,2018/12/5,2018/12/21
No00004334207,2018/12/5,2018/12/21
No00004334207,2018/12/5,2018/12/21
No00004334213,2018/12/5,2018/12/21
No00004334213,2018/12/5,2018/12/21
No00004334214,2018/12/5,2018/12/21
No00004334214,2018/12/5,2018/12/21
No00004334215,2018/12/5,2018/12/21
No00004334215,2018/12/5,2018/12/21
No00004334221,2018/12/5,2018/12/21
No00004334221,2018/12/5,2018/12/21
No00004334223,2018/12/5,2018/12/21
No00004334223,2018/12/5,2018/12/21
No00004334224,2018/12/5,2018/12/21
No00004334224,2018/12/5,2018/12/21
No00004334226,2018/12/5,2018/12/21
No00004334226,2018/12/5,2018/12/21
No00004334240,2018/12/5,2018/12/21
No00004334240,2018/12/5,2018/12/21
No00004334252,2018/12/5,2018/12/21
No00004334252,2018/12/5,2018/12/21
No00004334309,2018/12/5,2018/12/21
No00004334309,2018/12/5,2018/12/21
No00004334311,2018/12/5,2018/12/21
No00004334311,2018/12/5,2018/12/21
No00004334327,2018/12/5,2018/12/21
No00004334327,2018/12/5,2018/12/21
No00004334355,2018/12/5,2018/12/21
No00004334355,2018/12/5,2018/12/21
No00004334362,2018/12/5,2018/12/21
No00004334362,2018/12/5,2018/12/21
No00004334363,2018/12/5,2018/12/21
No00004334363,2018/12/5,2018/12/21
No00004334365,2018/12/5,2018/12/21
No00004334365,2018/12/5,2018/12/21
No00004334380,2018/12/5,2018/12/21
No00004334380,2018/12/5,2018/12/21
No00004334381,2018/12/5,2018/12/21
No00004334381,2018/12/5,2018/12/21
No00004334388,2018/12/5,2018/12/21
No00004334388,2018/12/5,2018/12/21
No00004334389,2018/12/5,2018/12/21
No00004334389,2018/12/5,2018/12/21
No00004334492,2018/12/5,2018/12/21
No00004334492,2018/12/5,2018/12/21
No00004334518,2018/12/5,2018/12/21
No00004334518,2018/12/5,2018/12/21
No00004334530,2018/12/5,2018/12/21
No00004334530,2018/12/5,2018/12/21
No00004334534,2018/12/5,2018/12/21
No00004334534,2018/12/5,2018/12/21
No00004334535,2018/12/5,2018/12/21
No00004334535,2018/12/5,2018/12/21
No00004334586,2018/12/5,2018/12/21
No00004334586,2018/12/5,2018/12/21
No00004334602,2018/12/5,2018/12/21
No00004334602,2018/12/5,2018/12/21
No00004334603,2018/12/5,2018/12/21
No00004334603,2018/12/5,2018/12/21
No00004334605,2018/12/5,2018/12/21
No00004334605,2018/12/5,2018/12/21
No00004334606,2018/12/5,2018/12/21
No00004334606,2018/12/5,2018/12/21
No00004334660,2018/12/5,2018/12/21
No00004334660,2018/12/5,2018/12/21
No00004334679,2018/12/5,2018/12/21
No00004334679,2018/12/5,2018/12/21
No00004334725,2018/12/5,2018/12/21
No00004334725,2018/12/5,2018/12/21
No00004336337,2018/12/5,2018/12/21
No00004336339,2018/12/5,2018/12/21
No00004336504,2018/12/5,2018/12/21
1 用户编号 续费时间 修正订单时间
2 No00003799858 2018/10/15 2018/10/26
3 No00003799859 2018/10/15 2018/10/26
4 No00003799860 2018/10/15 2018/10/26
5 No00003799862 2018/10/15 2018/10/26
6 No00003799878 2018/10/15 2018/10/26
7 No00003799879 2018/10/15 2018/10/26
8 No00003799880 2018/10/15 2018/10/26
9 No00003799881 2018/10/15 2018/10/26
10 No00003799883 2018/10/15 2018/10/26
11 No00003799884 2018/10/15 2018/10/26
12 No00004332795 2018/12/5 2018/12/21
13 No00004332795 2018/12/5 2018/12/21
14 No00004332921 2018/12/5 2018/12/21
15 No00004332921 2018/12/5 2018/12/21
16 No00004332972 2018/12/5 2018/12/21
17 No00004332972 2018/12/5 2018/12/21
18 No00004332974 2018/12/5 2018/12/21
19 No00004332974 2018/12/5 2018/12/21
20 No00004333728 2018/12/5 2018/12/21
21 No00004333728 2018/12/5 2018/12/21
22 No00004333789 2018/12/5 2018/12/21
23 No00004333789 2018/12/5 2018/12/21
24 No00004333789 2018/12/5 2018/12/21
25 No00004333794 2018/12/5 2018/12/21
26 No00004333794 2018/12/5 2018/12/21
27 No00004334080 2018/12/5 2018/12/21
28 No00004334080 2018/12/5 2018/12/21
29 No00004334113 2018/12/5 2018/12/21
30 No00004334113 2018/12/5 2018/12/21
31 No00004334159 2018/12/5 2018/12/21
32 No00004334159 2018/12/5 2018/12/21
33 No00004334167 2018/12/5 2018/12/21
34 No00004334167 2018/12/5 2018/12/21
35 No00004334168 2018/12/5 2018/12/21
36 No00004334168 2018/12/5 2018/12/21
37 No00004334169 2018/12/5 2018/12/21
38 No00004334169 2018/12/5 2018/12/21
39 No00004334170 2018/12/5 2018/12/21
40 No00004334170 2018/12/5 2018/12/21
41 No00004334174 2018/12/5 2018/12/21
42 No00004334174 2018/12/5 2018/12/21
43 No00004334178 2018/12/5 2018/12/21
44 No00004334178 2018/12/5 2018/12/21
45 No00004334207 2018/12/5 2018/12/21
46 No00004334207 2018/12/5 2018/12/21
47 No00004334213 2018/12/5 2018/12/21
48 No00004334213 2018/12/5 2018/12/21
49 No00004334214 2018/12/5 2018/12/21
50 No00004334214 2018/12/5 2018/12/21
51 No00004334215 2018/12/5 2018/12/21
52 No00004334215 2018/12/5 2018/12/21
53 No00004334221 2018/12/5 2018/12/21
54 No00004334221 2018/12/5 2018/12/21
55 No00004334223 2018/12/5 2018/12/21
56 No00004334223 2018/12/5 2018/12/21
57 No00004334224 2018/12/5 2018/12/21
58 No00004334224 2018/12/5 2018/12/21
59 No00004334226 2018/12/5 2018/12/21
60 No00004334226 2018/12/5 2018/12/21
61 No00004334240 2018/12/5 2018/12/21
62 No00004334240 2018/12/5 2018/12/21
63 No00004334252 2018/12/5 2018/12/21
64 No00004334252 2018/12/5 2018/12/21
65 No00004334309 2018/12/5 2018/12/21
66 No00004334309 2018/12/5 2018/12/21
67 No00004334311 2018/12/5 2018/12/21
68 No00004334311 2018/12/5 2018/12/21
69 No00004334327 2018/12/5 2018/12/21
70 No00004334327 2018/12/5 2018/12/21
71 No00004334355 2018/12/5 2018/12/21
72 No00004334355 2018/12/5 2018/12/21
73 No00004334362 2018/12/5 2018/12/21
74 No00004334362 2018/12/5 2018/12/21
75 No00004334363 2018/12/5 2018/12/21
76 No00004334363 2018/12/5 2018/12/21
77 No00004334365 2018/12/5 2018/12/21
78 No00004334365 2018/12/5 2018/12/21
79 No00004334380 2018/12/5 2018/12/21
80 No00004334380 2018/12/5 2018/12/21
81 No00004334381 2018/12/5 2018/12/21
82 No00004334381 2018/12/5 2018/12/21
83 No00004334388 2018/12/5 2018/12/21
84 No00004334388 2018/12/5 2018/12/21
85 No00004334389 2018/12/5 2018/12/21
86 No00004334389 2018/12/5 2018/12/21
87 No00004334492 2018/12/5 2018/12/21
88 No00004334492 2018/12/5 2018/12/21
89 No00004334518 2018/12/5 2018/12/21
90 No00004334518 2018/12/5 2018/12/21
91 No00004334530 2018/12/5 2018/12/21
92 No00004334530 2018/12/5 2018/12/21
93 No00004334534 2018/12/5 2018/12/21
94 No00004334534 2018/12/5 2018/12/21
95 No00004334535 2018/12/5 2018/12/21
96 No00004334535 2018/12/5 2018/12/21
97 No00004334586 2018/12/5 2018/12/21
98 No00004334586 2018/12/5 2018/12/21
99 No00004334602 2018/12/5 2018/12/21
100 No00004334602 2018/12/5 2018/12/21
101 No00004334603 2018/12/5 2018/12/21
102 No00004334603 2018/12/5 2018/12/21
103 No00004334605 2018/12/5 2018/12/21
104 No00004334605 2018/12/5 2018/12/21
105 No00004334606 2018/12/5 2018/12/21
106 No00004334606 2018/12/5 2018/12/21
107 No00004334660 2018/12/5 2018/12/21
108 No00004334660 2018/12/5 2018/12/21
109 No00004334679 2018/12/5 2018/12/21
110 No00004334679 2018/12/5 2018/12/21
111 No00004334725 2018/12/5 2018/12/21
112 No00004334725 2018/12/5 2018/12/21
113 No00004336337 2018/12/5 2018/12/21
114 No00004336339 2018/12/5 2018/12/21
115 No00004336504 2018/12/5 2018/12/21

132504
tests/db.csv

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,7 @@ class PostgresGrammar extends Grammar
public function compileUpdateBatch(QueryBuilder $query, array $values, $filed = 'id')
{
$as = 'as_table';
$table = $this->wrapTable($query->from);
if (! is_array(reset($values))) {
@ -31,12 +31,20 @@ class PostgresGrammar extends Grammar
$columns = array_keys(reset($values));
$referenceType = strpos($filed, '::') ? '::'.explode('::', $filed)[1] : '';
$filed = strpos($filed, '::') ? explode('::', $filed)[0] : $filed;
$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}";
})->map(function ($column, $index) use ($as, $values) {
$columnType = '';
if ($values[0][$column] instanceof \DateTime) {
$columnType = '::timestamp';
}
return "{$column} = {$as}.{$column}{$columnType}";
})->implode(', ');
$parameters = collect($values)->map(function ($record) {
@ -47,10 +55,10 @@ class PostgresGrammar extends Grammar
$from = "FROM (VALUES $parameters) AS {$as}{$columns}";
if (is_null($query->wheres)) {
$where = "WHERE {$table}.{$reference} = {$as}.{$reference}";
if (empty($query->wheres)) {
$where = "WHERE {$table}.{$reference}$referenceType = {$as}.{$reference}$referenceType";
} else {
$where = $this->compileUpdateWheres($query) . " AND {$table}.{$reference} = {$as}.{$reference}";
$where = $this->compileUpdateWheres($query) . " AND {$table}.{$reference}$referenceType = {$as}.{$reference}$referenceType";
}
return trim("UPDATE {$table} SET {$updates} {$from} {$where}");
@ -61,10 +69,11 @@ class PostgresGrammar extends Grammar
*
* @param Builder $query
* @param array $values
* @param array|string $unique
* @param array|string $fields
* @param array|null $only
* @return string
*/
public function compileUpsert(QueryBuilder $query, array $values, $fields = ['id'], $doNothing = false)
public function compileUpsert(QueryBuilder $query, array $values, $fields = ['id'], $only = null)
{
$insert = $this->compileInsert($query, $values);
@ -85,7 +94,7 @@ class PostgresGrammar extends Grammar
$field = "COALESCE($field, '1970-01-01 08:00:00'::timestamp)";
}
}
$reference = implode(',', $fields);
// excluded fields are all fields except $unique one that will be updated
@ -94,18 +103,16 @@ class PostgresGrammar extends Grammar
return !in_array($e, $fields) && $e != 'created_at';
});
if (empty($excluded)) {
if (empty($excluded) || (!is_null($only) && empty($only))) {
return "$insert on conflict ($reference) do nothing";
}
if ($doNothing) {
return "$insert on conflict ($reference) do nothing";
}
$only = is_null($only) ? $excluded : $only;
$update = join(', ', array_map(function ($e) {
return "\"$e\" = \"excluded\".\"$e\"";
}, $excluded));
}, $only));
return "$insert on conflict ($reference) do update set $update";
}
}