diff --git a/app/Domains/Real/Commands/Sync/MongoSync.php b/app/Domains/Real/Commands/Sync/MongoSync.php
index a377c7cc..fb5fda45 100644
--- a/app/Domains/Real/Commands/Sync/MongoSync.php
+++ b/app/Domains/Real/Commands/Sync/MongoSync.php
@@ -4,6 +4,7 @@ namespace App\Domains\Real\Commands\Sync;
use Carbon\Carbon;
use App\Models\Card\Card;
+use Illuminate\Support\Arr;
use MongoDB\BSON\UTCDateTime;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Artisan;
@@ -25,7 +26,8 @@ class MongoSync extends Command
public function handle()
{
- $nextMicrotime = $microtime = app(ConfigService::class)->get(self::CURSOR_KEY) ?: 946656000000;
+ $microtime = app(ConfigService::class)->get(self::CURSOR_KEY) ?: 946656000000;
+ $nextMicrotime = intval(microtime(true) * 1000);
$utcDateTime = new UTCDateTime($microtime);
@@ -33,9 +35,8 @@ class MongoSync extends Command
$blocs = app(BlocRepository::class)->get()->pluck('id', 'sn')->toArray();
$query = DB::connection('mongo')->table('tblCard')
- ->select(['cNo', 'iccid', 'imsi', 'comId', 'oType', 'saDate', 'sDate'])
- ->where('isDel', '<>', 1)
- ->where('sDate', '>', $utcDateTime)
+ ->select(['cNo', 'bNo', 'iccid', 'imsi', 'comId', 'oType', 'saDate', 'sDate'])
+ ->where('oRDate', '>', $utcDateTime)
->orderBy('sDate');
$total = $query->count();
@@ -66,18 +67,22 @@ class MongoSync extends Command
'carrier_operator' => self::$carrierOperators[$value['oType']] ?? 255,
'activated_at' => $activated_at,
'virtual_activated_at' => $activated_at,
+ 'order_status' => intval(!empty($value['bNo'])),
'created_at' => $value['sDate']->toDateTime()->format('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
];
-
- $nextMicrotime = (string) $value['sDate'];
-
- $nextMicrotime = ($nextMicrotime > $microtime) ? $nextMicrotime : $microtime;
}
- Card::upsert($values, 'sim', true);
+ $builder = Card::query()->toBase();
- app(ConfigService::class)->set(self::CURSOR_KEY, intval($nextMicrotime));
+ $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),
+ order_status=excluded.order_status';
+
+ $builder->connection->insert($sql, Arr::flatten($array, 1));
if ($page * $this->limit >= $total) {
break;
@@ -86,6 +91,8 @@ class MongoSync extends Command
$page++;
}
+ app(ConfigService::class)->set(self::CURSOR_KEY, intval($nextMicrotime));
+
app(CardRepository::class)->forgetCached();
}
}
diff --git a/app/Domains/Stats/Http/Controllers/OrderController.php b/app/Domains/Stats/Http/Controllers/OrderController.php
index 0be1fe2c..de801944 100644
--- a/app/Domains/Stats/Http/Controllers/OrderController.php
+++ b/app/Domains/Stats/Http/Controllers/OrderController.php
@@ -24,44 +24,27 @@ class OrderController extends Controller
*
* @return \Illuminate\Http\Response
*/
- public function index($type)
+ public function index()
{
$conditions = $this->request->all();
- $conditions['type'] = $type;
- $res = $this->OrderService->index($conditions);
+ $res = $this->orderService->index($conditions);
return res($res, '订单统计', 201);
}
/**
- * 创建.
+ * 统计明细.
*
* @return \Illuminate\Http\Response
*/
- public function create()
+ public function detail()
{
- //
- }
+ $conditions = $this->request->all();
- /**
- * 编辑.
- *
- * @return \Illuminate\Http\Response
- */
- public function update($id)
- {
- //
- }
-
- /**
- * 删除.
- *
- * @return \Illuminate\Http\Response
- */
- public function destroy()
- {
- //
+ $res = $this->orderService->detail($conditions);
+
+ return res($res, '统计明细', 201);
}
}
diff --git a/app/Domains/Stats/Routes/api.php b/app/Domains/Stats/Routes/api.php
index 3d2e2dff..3cc90eba 100644
--- a/app/Domains/Stats/Routes/api.php
+++ b/app/Domains/Stats/Routes/api.php
@@ -7,6 +7,6 @@ $router->group(['prefix' => 'stats', 'as' => 'stats', 'middleware' => ['adminAut
$router->get('/company-count/export', ['as' => 'company-count.export', 'uses' => 'CompanyCountController@export']);
// 订单统计
- $router->get('/order/{type}', ['as' => 'order.index', 'uses' => 'OrderController@index']);
+ $router->get('/order', ['as' => 'order.index', 'uses' => 'OrderController@index']);
});
diff --git a/app/Domains/Stats/Services/OrderService.php b/app/Domains/Stats/Services/OrderService.php
index 0283d318..c30d0feb 100644
--- a/app/Domains/Stats/Services/OrderService.php
+++ b/app/Domains/Stats/Services/OrderService.php
@@ -43,16 +43,15 @@ class OrderService extends Service
*
* @return void
*/
- public function index($type, array $conditions = [])
+ public function index(array $conditions = [])
{
- $conditions['type'] = $type;
$conditions['source'] = 1;
$companies = $this->companyRepository->withTrashed()->get()->pluck('name', 'id')->toArray();
$packages = $this->packageRepository->withTrashed()->get()->pluck('name', 'id')->toArray();
$select = [
- DB::raw("string_agg(DISTINCT id, ',') as id"),
+ DB::raw("array_to_string(array_agg(id), ',') as order_id"),
'company_id',
'package_id',
'product_id',
@@ -63,10 +62,12 @@ class OrderService extends Service
];
$orders = $this->orderRepository->select($select)->withConditions($conditions)->applyConditions()
- ->groupBy(['company_id', 'product_id', 'pay_channel'])->paginate($conditions['limit']);
-
+ ->groupBy(['company_id', 'package_id', 'product_id', 'unit_price', 'pay_channel'])->paginate($conditions['limit']);
+
$orders->map(function ($item) use ($companies, $packages) {
- $item->company_name = $packages[$item->company_id];
+ $item->unit_price = floatval(sprintf('%.02f', $item->unit_price/100));
+ $item->custom_price = floatval(sprintf('%.02f', $item->custom_price/100));
+ $item->company_name = $companies[$item->company_id];
$item->package_name = $packages[$item->package_id];
$item->pay_channel_name = CommonService::namePayChannel($item->pay_channel);
});
@@ -88,29 +89,19 @@ class OrderService extends Service
$repository = app($class);
$companies = $this->companyRepository->withTrashed()->get()->pluck('name', 'id')->toArray();
- $packages = $this->packageRepository->withTrashed()->get()->pluck('name', 'id')->toArray();
+ $packages = $this->packageRepository->withTrashed()->get()->keyBy('id')->toArray();
- $repository->withConditions($conditions)->applyConditions()->paginate($conditions['limit']);
+ $cards = $repository->with('order:id,unit_price,pay_channel,order_at')->withConditions($conditions)->applyConditions()->paginate($conditions['limit']);
- $select = [
- 'id',
- 'company_id',
- 'package_id',
- 'unit_price',
- 'pay_channel',
- DB::raw('SUM(counts) as counts'),
- DB::raw('SUM(custom_price) as custom_price'),
- ];
-
- $orders = $this->orderRepository->select($select)->withConditions($conditions)->applyConditions()
- ->groupBy(['company_id', 'product_id', 'pay_channel'])->paginate($conditions['limit']);
-
- $orders->map(function ($item) use ($companies, $packages) {
+ $cards->map(function ($item) use ($companies, $packages) {
$item->company_name = $packages[$item->company_id];
- $item->package_name = $packages[$item->package_id];
- $item->pay_channel_name = CommonService::namePayChannel($item->pay_channel);
+ $item->package_name = $packages[$item->package_id]['name'];
+ $item->service_months = $packages[$item->package_id]['service_months'];
+ $item->unit_price = $item->order['unit_price'];
+ $item->pay_channel_name = CommonService::namePayChannel($item->order['pay_channel']);
+ $item->order_at = $item->order['order_at'];
});
- return $orders;
+ return $cards;
}
}
diff --git a/app/Domains/Virtual/Repositories/Concerns/OrderCardConcern.php b/app/Domains/Virtual/Repositories/Concerns/OrderCardConcern.php
index f7f2c323..402041f7 100644
--- a/app/Domains/Virtual/Repositories/Concerns/OrderCardConcern.php
+++ b/app/Domains/Virtual/Repositories/Concerns/OrderCardConcern.php
@@ -18,6 +18,11 @@ trait OrderCardConcern
$this->model = $this->model->whereIn('id', $conditions['id']);
}
+ if (isset($conditions['order_id'])) {
+ $conditions['order_id'] = array_wrap($conditions['order_id']);
+ $this->model = $this->model->whereIn('order_id', $conditions['order_id']);
+ }
+
if (isset($conditions['sim'])) {
$conditions['sim'] = array_wrap($conditions['sim']);
$this->model = $this->model->whereIn('sim', $conditions['sim']);
diff --git a/database/migrations/2018_12_24_164218_create_cards_table.php b/database/migrations/2018_12_24_164218_create_cards_table.php
index 739b59e5..783b4698 100644
--- a/database/migrations/2018_12_24_164218_create_cards_table.php
+++ b/database/migrations/2018_12_24_164218_create_cards_table.php
@@ -26,6 +26,7 @@ class CreateCardsTable extends Migration
$table->timestamp('activated_at')->nullable()->comment('激活时间');
$table->timestamp('virtual_activated_at')->nullable()->comment('虚拟激活时间');
$table->tinyInteger('type')->unsigned()->default(0)->comment('类型(0:真实卡 1:虚拟卡 2:未知卡)');
+ $table->tinyInteger('order_status')->unsigned()->default(0)->comment('订单状态 0:正常 1:退货');
$table->timestamp('cancelled_at')->nullable()->comment('注销时间');
$table->timestamps();
diff --git a/database/seeds/PermissionSeeder.php b/database/seeds/PermissionSeeder.php
index d36cd255..b0baacb3 100644
--- a/database/seeds/PermissionSeeder.php
+++ b/database/seeds/PermissionSeeder.php
@@ -153,9 +153,11 @@ class PermissionSeeder extends Seeder
'type' => 0,
'open' => 3,
'children' => [
- [
- 'name' => 'stats.company-index', 'title' => '企业统计', 'path' => '/stats/company-count', 'icon' => 'md-pulse', 'type' => 0, 'open' => 3
- ],
+ ['name' => 'stats.company-index', 'title' => '企业统计', 'path' => '/stats/company-count', 'icon' => 'md-pulse', 'type' => 0, 'open' => 3],
+ ['name' => 'stats.order.0', 'title' => '销售订单统计', 'path' => '/stats/order/0', 'icon' => 'md-pulse', 'type' => 0, 'open' => 3],
+ ['name' => 'stats.order.1', 'title' => '续费订单统计', 'path' => '/stats/order/1', 'icon' => 'md-pulse', 'type' => 0, 'open' => 3],
+ ['name' => 'stats.order.2', 'title' => '续费包订单统计', 'path' => '/stats/order/2', 'icon' => 'md-pulse', 'type' => 0, 'open' => 3],
+ ['name' => 'stats.order.3', 'title' => '加油包订单统计', 'path' => '/stats/order/3', 'icon' => 'md-pulse', 'type' => 0, 'open' => 3],
],
],
[
diff --git a/frontend/src/router/routes.js b/frontend/src/router/routes.js
index 648dee6a..473e4060 100644
--- a/frontend/src/router/routes.js
+++ b/frontend/src/router/routes.js
@@ -24,7 +24,8 @@ const routes = [
{ path: '/packages/:type', name: 'Packages', component: load('virtual/packages/index'), meta: { title: '套餐管理' } },
{ path: '/cards', name: 'Cards', component: load('virtual/cards/index'), meta: { title: '客户列表' } },
{ path: '/exports', name: 'StatsExports', component: load('exports/index'), meta: { title: '导出记录' } },
- { path: '/stats/company-count', name: 'StatsCompanyCount', component: load('stats/company-count/index'), meta: { title: '企业统计' } }
+ { path: '/stats/company-count', name: 'StatsCompanyCount', component: load('stats/company-count/index'), meta: { title: '企业统计' } },
+ { path: '/stats/order/:type', name: 'StatsOrder', component: load('stats/order/index'), meta: { title: '订单统计' } }
]
},
{ path: '*', redirect: { path: '/home' } }
diff --git a/frontend/src/views/stats/company-count/js/index.js b/frontend/src/views/stats/company-count/js/index.js
index b87a7973..3644d59a 100644
--- a/frontend/src/views/stats/company-count/js/index.js
+++ b/frontend/src/views/stats/company-count/js/index.js
@@ -52,9 +52,7 @@ export default {
};
},
created() {
- window.t = this;
this.index();
- console.log(this.$refs.table);
},
methods: {
/**
@@ -129,7 +127,6 @@ export default {
this.$nextTick(() => {
setTimeout(() => {
let html = $('.ivu-table-header colgroup').html();
- console.log(html);
$('.table-footer-colgroup').html(html);
}, 10);
});
diff --git a/frontend/src/views/stats/order/index.vue b/frontend/src/views/stats/order/index.vue
new file mode 100644
index 00000000..134b55a0
--- /dev/null
+++ b/frontend/src/views/stats/order/index.vue
@@ -0,0 +1,114 @@
+
+
+
+
+
+
+ -
+
+ 全部信息
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/views/stats/order/js/index.js b/frontend/src/views/stats/order/js/index.js
new file mode 100644
index 00000000..d4e67a29
--- /dev/null
+++ b/frontend/src/views/stats/order/js/index.js
@@ -0,0 +1,162 @@
+import { sumBy } from 'service/util';
+export default {
+ name: 'StatsOrder',
+ data() {
+ return {
+ search: {
+ show: true
+ },
+ options: {
+ company_name: null,
+ package_name: null,
+ pay_channel: null,
+ time: null
+ },
+ data: [],
+ list: [],
+ stats: {},
+ page: {
+ total: 0,
+ limit: 10,
+ page: 1
+ },
+ columns: [
+ {
+ title: '企业名称',
+ key: 'company_name'
+ },
+ {
+ title: '套餐名称',
+ key: 'package_name',
+ width: 150
+ },
+ {
+ title: '支付方式',
+ key: 'pay_channel_name',
+ width: 120
+ },
+ {
+ title: '销售单价',
+ key: 'unit_price',
+ width: 120
+ },
+ {
+ title: '销售数量',
+ key: 'counts',
+ width: 120
+ },
+ {
+ title: '销售总金额',
+ key: 'custom_price',
+ width: 120
+ }
+ ]
+ };
+ },
+ created() {
+ this.type = Number(this.$route.params.type);
+ this.index();
+ },
+ methods: {
+ /**
+ * [index 列表]
+ * @param {Number} page [description]
+ * @return {[type]} [description]
+ */
+ index() {
+ let options = Object.assign({
+ orderBy: 'company_id',
+ sortedBy: 'asc',
+ type: this.type
+ },
+ this.options);
+
+ let params = this.searchDataHandle({}, {
+ limit: 0
+ }, options);
+
+ this.isShowLoading(true);
+
+ service.get('api/stats/order', { params }).then(res => {
+ this.isShowLoading(false);
+ if (res.code == 0) {
+ this.list = res.data;
+ this.page.total = this.list.length;
+ this.changePage(1);
+ }
+ }).catch(() => {
+ this.isShowLoading(false);
+ });
+ },
+
+ /**
+ * [request 刷新]
+ * @return {[type]} [description]
+ */
+ request() {
+ let page = this.page.page;
+
+ if (this.data.length == 1) {
+ page = this.returnPage(this.page.total, this.page.page, this.page.limit);
+ }
+
+ this.index();
+ this.changePage(page);
+ },
+
+ resetSearch() {
+ for (let k in this.options) {
+ this.options[k] = null;
+ }
+
+ this.index();
+ },
+ changeLimit(limit) {
+ this.page.limit = limit;
+ this.changePage(1);
+ },
+ changePage(page) {
+ this.page.page = page;
+ this.data = this.list.slice((page - 1) * this.page.limit, page * this.page.limit);
+
+ this.stats = {
+ counts: sumBy(this.list, 'counts'),
+ custom_price: sumBy(this.list, 'custom_price')
+ };
+
+ this.$nextTick(() => {
+ setTimeout(() => {
+ let html = $('.ivu-table-header colgroup').html();
+ $('.table-footer-colgroup').html(html);
+ }, 10);
+ });
+ },
+
+ exportExcel() {
+ this.isShowLoading(true);
+
+ let options = Object.assign({
+ orderBy: 'id',
+ sortedBy: 'asc'
+ },
+
+ this.options);
+
+ let params = this.searchDataHandle({}, {}, options);
+
+ this.isShowLoading(true);
+
+ service.get('api/stats/company-count/export', {
+ params
+ }).then((res) => {
+ if (res.code === 0) {
+ this.downloadFile(res.data);
+ }
+
+ this.isShowLoading(false);
+ }).catch(() => {
+ this.isShowLoading(false);
+ });
+ }
+ }
+};
diff --git a/tests/MongoTest.php b/tests/MongoTest.php
index c0b069be..73f1e9f7 100644
--- a/tests/MongoTest.php
+++ b/tests/MongoTest.php
@@ -1,25 +1,10 @@
modify('-1 month');
-echo $date->format('Y-m-d');
-$res = Carbon::parse('2018-10')->endOfMonth()->subMonth();
+$count = DB::connection('mongo')->table('tblCard')
+->count();
-dd($res);
-
-$conditions = [
- 'starttime' => Carbon::parse('2018-10-01')->startOfDay(),
- 'endtime' => Carbon::parse('2018-10-31')->startOfDay(),
-];
-
-$res = \DB::connection('mongo')->table('tblCard')->where(function ($query) use ($conditions) {
- $query->where('exPCodes.cDate', '>=', $conditions['starttime'])->where('exPCodes.cDate', '<=', $conditions['endtime'])->where('oDate', 'exists', false);
-})->orWhere(function ($query) use ($conditions) {
- $query->where('exPCodes.oDate', '>=', $conditions['starttime'])->where('exPCodes.oDate', '<=', $conditions['endtime'])->where('pType', 0);
-})->first();
-
-dd($res['exPCodes']);
+dd($count);