diff --git a/app/Core/AbstractExport.php b/app/Core/AbstractExport.php index 8552e3f8..d7025be6 100644 --- a/app/Core/AbstractExport.php +++ b/app/Core/AbstractExport.php @@ -12,6 +12,7 @@ use Dipper\Excel\Concerns\WithEvents; use Dipper\Excel\Events\BeforeExport; use Illuminate\Filesystem\Filesystem; use Dipper\Excel\Events\BeforeWriting; +use App\Exceptions\NotAllowedException; use Illuminate\Support\Facades\Request; use Illuminate\Support\Facades\Storage; use Dipper\Excel\Concerns\ShouldAutoSize; @@ -24,6 +25,7 @@ abstract class AbstractExport implements WithEvents, WithTitle, ShouldAutoSize public static $classes = [ \App\Domains\Virtual\Exports\CardExport::class => '客户列表', \App\Domains\Stats\Exports\CompanyCountExport::class => '企业统计', + \App\Domains\Stats\Exports\OrderExport::class => '订单统计', ]; public $sn; @@ -141,7 +143,7 @@ abstract class AbstractExport implements WithEvents, WithTitle, ShouldAutoSize */ public function title(): string { - $title = self::$classes[get_class($this)]; + $title = $this->tag(); if (($conditions = $this->conditions) && $conditions['starttime'] && $conditions['endtime']) { $title .= Carbon::parse($conditions['starttime'])->format('Ymd') . '-' . Carbon::parse($conditions['endtime'])->format('Ymd'); @@ -167,7 +169,7 @@ abstract class AbstractExport implements WithEvents, WithTitle, ShouldAutoSize */ private function filename(): string { - $title = self::$classes[get_class($this)]; + $title = $this->tag(); $filename = $title . date('YmdHis'); @@ -181,15 +183,10 @@ abstract class AbstractExport implements WithEvents, WithTitle, ShouldAutoSize */ private function tag() { - $className = get_class($this); + if (!$tag = self::$classes[get_class($this)]) { + throw new NotAllowedException('类型不允许'); + } - return self::transformerClassName($className); - } - - public static function transformerClassName($className) - { - $baseName = array_last(explode('\\', $className)); - - return str_replace('Export', '', $baseName); + return $tag; } } diff --git a/app/Domains/Export/Services/ExportService.php b/app/Domains/Export/Services/ExportService.php index aa39f92d..66986c5a 100644 --- a/app/Domains/Export/Services/ExportService.php +++ b/app/Domains/Export/Services/ExportService.php @@ -39,14 +39,6 @@ class ExportService extends Service $exports = $this->exportRepository->withConditions($conditions)->applyConditions()->paginate($limit); - $classes = AbstractExport::$classes; - - foreach ($classes as $key => $value) { - $new = AbstractExport::transformerClassName($key); - $classes[$new] = $value; - unset($classes[$key]); - } - $status = app(Dicts::class)->get('export_status'); $exports->transform(function ($item) use ($classes, $status) { @@ -68,7 +60,7 @@ class ExportService extends Service return [ 'id' => $item->id, - 'tag_name' => $classes[$item['tag']] ?? '未知', + 'tag' => $item->tag, 'filesize' => human_filesize($item->filesize), 'dateline' => !$item->conditions['starttime'] ? '所有' : $item->conditions['starttime'] . ' 至 ' . $item->conditions['endtime'], 'conditions' => $conditions, diff --git a/app/Domains/Stats/Exports/OrderExport.php b/app/Domains/Stats/Exports/OrderExport.php new file mode 100644 index 00000000..df4c2e71 --- /dev/null +++ b/app/Domains/Stats/Exports/OrderExport.php @@ -0,0 +1,93 @@ +conditions = $conditions; + parent::__construct(); + } + + public function collection() + { + set_time_limit(-1); + + + $orders = app(OrderService::class)->index($this->conditions)->map(function ($item) { + return collect([ + 'company_name' => $item->company_name, + 'package_name' => $item->package_name, + 'pay_channel_name' => $item->pay_channel_name, + 'unit_price' => $item->unit_price, + 'counts' => $item->counts, + 'custom_price' => $item->custom_price, + ]); + }); + + $orders->push([ + '总计', + '', + '', + '', + array_sum($orders->pluck('counts')->toArray()) ?: 0, + array_sum($orders->pluck('custom_price')->toArray()) ?: 0, + ]); + + return $orders; + } + + public function headings(): array + { + return [ + '企业名称', + '套餐名称', + '支付方式', + '单价', + '数量', + '总金额', + ]; + } + + /** + * 表格标题 + * + * @return string + */ + public function title(): string + { + $title = parent::title(); + + $title = self::$types[$this->conditions['type']] . $title; + + return $title; + } + + /** + * 文件名称 + * + * @return string + */ + private function filename(): string + { + $title = self::$classes[get_class($this)]; + + $filename = $title . date('YmdHis'); + + $filename = self::$types[$this->conditions['type']] . $filename; + + return "export/{$filename}.xlsx"; + } +} diff --git a/app/Domains/Stats/Http/Controllers/OrderController.php b/app/Domains/Stats/Http/Controllers/OrderController.php index de801944..8721e203 100644 --- a/app/Domains/Stats/Http/Controllers/OrderController.php +++ b/app/Domains/Stats/Http/Controllers/OrderController.php @@ -1,9 +1,10 @@ request->all(); + $conditions['limit'] = 0; + + try { + $export = new OrderExport($conditions); + $url = ExportService::store($export, $this->disk); + } catch (\Exception $e) { + throw $e; + } + + return res($url, '导出成功', 201); + } + /** * 统计明细. @@ -47,4 +68,24 @@ class OrderController extends Controller return res($res, '统计明细', 201); } + + /** + * 统计明细导出. + * + * @return \Illuminate\Http\Response + */ + public function detailExport() + { + $conditions = $this->request->all(); + $conditions['limit'] = 0; + + try { + $export = new OrderExport($conditions); + $url = ExportService::store($export, $this->disk); + } catch (\Exception $e) { + throw $e; + } + + return res($url, '导出成功', 201); + } } diff --git a/app/Domains/Stats/Routes/api.php b/app/Domains/Stats/Routes/api.php index 3cc90eba..5ffe0212 100644 --- a/app/Domains/Stats/Routes/api.php +++ b/app/Domains/Stats/Routes/api.php @@ -8,5 +8,8 @@ $router->group(['prefix' => 'stats', 'as' => 'stats', 'middleware' => ['adminAut // 订单统计 $router->get('/order', ['as' => 'order.index', 'uses' => 'OrderController@index']); + $router->get('/order/export', ['as' => 'order.export', 'uses' => 'OrderController@export']); + $router->get('/order/detail', ['as' => 'order.detail', 'uses' => 'OrderController@detail']); + $router->get('/order/detail/export', ['as' => 'order.detail.export', 'uses' => 'OrderController@detailExport']); }); diff --git a/app/Domains/Stats/Services/OrderService.php b/app/Domains/Stats/Services/OrderService.php index 5dd9d34e..0fd20be0 100644 --- a/app/Domains/Stats/Services/OrderService.php +++ b/app/Domains/Stats/Services/OrderService.php @@ -1,6 +1,7 @@ companyRepository->withTrashed()->get()->pluck('name', 'id')->toArray(); $packages = $this->packageRepository->withTrashed()->get()->keyBy('id')->toArray(); + $carrierOperators = app(Dicts::class)->get('carrier_operator'); + $cards = $repository->with('order:id,unit_price,pay_channel,order_at')->withConditions($conditions)->applyConditions()->paginate($conditions['limit']); - $cards->map(function ($item) use ($companies, $packages) { - $item->company_name = $packages[$item->company_id]; - $item->package_name = $packages[$item->package_id]['name']; - $item->service_months = $packages[$item->package_id]['service_months']; + $cards->map(function ($item) use ($companies, $packages, $carrierOperators) { + $package = $packages[$item->package_id]; + + $item->company_name = $companies[$item->company_id]; + $item->package_name = $package['name']; + $item->carrier_operator_name = $carrierOperators[$package['carrier_operator']]; + $item->service_months = $package['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']; diff --git a/app/Domains/Virtual/Commands/Sync/LogSync.php b/app/Domains/Virtual/Commands/Sync/LogSync.php index 43fed009..5184c25c 100644 --- a/app/Domains/Virtual/Commands/Sync/LogSync.php +++ b/app/Domains/Virtual/Commands/Sync/LogSync.php @@ -68,7 +68,7 @@ class LogSync extends Command $value = (array)$value; $package = $this->getPackage($value['content']); - $unit_price = intval($value['sale_account'] * 100); + $unit_price = intval($value['order_account'] * 100); $custom_price = intval($value['order_account'] * 100); $product = $this->getProduct($package, $value['company'], $unit_price); $type = self::$types[$value['type']]; diff --git a/app/Domains/Virtual/Commands/Sync/ProductSync.php b/app/Domains/Virtual/Commands/Sync/ProductSync.php index 93a3ffe3..a9319d3d 100644 --- a/app/Domains/Virtual/Commands/Sync/ProductSync.php +++ b/app/Domains/Virtual/Commands/Sync/ProductSync.php @@ -19,7 +19,7 @@ class ProductSync extends Command { $packages = app(PackageRepository::class)->where('type', 0)->get()->keyBy('sn')->toArray(); - $fields = ['company', 'content', 'sale_account']; + $fields = ['company', 'content', 'order_account']; $list = DB::connection('vd_old')->table('ckb_custom_handle_log')->select($fields) ->where('type', 13) @@ -33,13 +33,13 @@ class ProductSync extends Command throw new \Exception('套餐不存在'); } - $base_price = intval($value['sale_account'] * 100) ; + $base_price = intval($value['order_account'] * 100) ; $products[] = [ 'sn' => strtoupper($package['sn'] . '_' . $value['company'] . '_' . $base_price), 'company_id' => $value['company'], 'package_id' => $package['id'], - 'name' => $package['name'] . ' ' . $value['sale_account'], + 'name' => $package['name'] . ' ' . $value['order_account'], 'base_price' => $base_price, 'renewal_price' => $base_price, 'created_at' => date('Y-m-d H:i:s'), diff --git a/frontend/src/router/routes.js b/frontend/src/router/routes.js index 473e4060..ae8b5ec9 100644 --- a/frontend/src/router/routes.js +++ b/frontend/src/router/routes.js @@ -25,7 +25,8 @@ const routes = [ { 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/order/:type', name: 'StatsOrder', component: load('stats/order/index'), meta: { title: '订单统计' } } + { path: '/stats/order/:type', name: 'StatsOrder', component: load('stats/order/index'), meta: { title: '订单统计' } }, + { path: '/stats/order/detail/:type', name: 'StatsOrderDetail', component: load('stats/order/detail'), meta: { title: '订单明细' } } ] }, { path: '*', redirect: { path: '/home' } } diff --git a/frontend/src/service/menus.js b/frontend/src/service/menus.js deleted file mode 100644 index b879d5a6..00000000 --- a/frontend/src/service/menus.js +++ /dev/null @@ -1,139 +0,0 @@ -const menus = [ - { - title: '系统设置', - link: '', - icon: 'md-albums', - children: [ - { - title: '菜单管理', - link: '/menus', - icon: '', - children: [] - }, - { - title: '角色管理', - link: '/roles', - icon: '', - children: [] - }, - { - title: '开发者管理', - link: '/developer', - icon: '', - children: [] - } - ] - }, - - { - title: '用户管理', - link: '', - icon: 'md-analytics', - children: [ - { - title: '用户权限管理', - link: '/jurisdiction', - icon: '', - children: [] - }, - { - title: '管理员管理', - link: '/admin', - icon: '', - children: [] - }, - { - title: '教师管理', - link: '/teacher', - icon: '', - children: [] - }, - { - title: '学员管理', - link: '/student', - icon: '', - children: [] - } - ] - }, - - { - title: '测评管理', - link: '', - icon: 'ios-aperture', - children: [ - { - title: '专注力测评管理', - link: '/evaluation', - icon: '', - children: [] - }, - { - title: '专注力题库管理', - link: '/questions', - icon: '', - children: [] - } - ] - }, - - { - title: '课程管理', - link: '', - icon: 'ios-barcode', - children: [ - { - title: '课程分类管理', - link: '/course_classify', - icon: '', - children: [] - }, - { - title: '课程项目管理', - link: '/course_project', - icon: '', - children: [] - }, - { - title: '学员排课管理', - link: '/course_work', - icon: '', - children: [] - } - ] - }, - - { - title: '教学管理', - link: '', - icon: 'md-beer', - children: [ - { - title: '学员课业管理', - link: '/lessons', - icon: '', - children: [] - }, - { - title: '请假调课管理', - link: '/leave', - icon: '', - children: [] - }, - { - title: '课业反馈管理', - link: '/feedback', - icon: '', - children: [] - }, - { - title: '家庭作业素材', - link: '/work_material', - icon: '', - children: [] - } - ] - } -]; - -export default menus; diff --git a/frontend/src/service/util.js b/frontend/src/service/util.js index 55db40e1..a87059bf 100644 --- a/frontend/src/service/util.js +++ b/frontend/src/service/util.js @@ -144,7 +144,7 @@ export function objectDot(object, prepend = '') { */ export function sumBy(array, key) { return array.map((item) => { - return item[key]; + return Number(item[key]); }).reduce((acc, cur) => { return acc + cur; }); diff --git a/frontend/src/views/exports/index.vue b/frontend/src/views/exports/index.vue index 88ffa0b2..e463ea01 100644 --- a/frontend/src/views/exports/index.vue +++ b/frontend/src/views/exports/index.vue @@ -28,8 +28,12 @@