diff --git a/app/Domains/Stats/Exports/AbstractExport.php b/app/Domains/Stats/Exports/AbstractExport.php new file mode 100644 index 00000000..d15e610d --- /dev/null +++ b/app/Domains/Stats/Exports/AbstractExport.php @@ -0,0 +1,149 @@ + '企业统计', + ]; + + public $sn; + + public $filename; + + public function __construct() + { + $this->sn = $this->sn(); + $this->filename = $this->filename(); + } + + /** + * @return array + */ + public function registerEvents(): array + { + return [ + BeforeExport::class => [self::class, 'beforeExport'], + BeforeWriting::class => [self::class, 'beforeWriting'], + AfterExport::class => [self::class, 'afterExport'], + AfterStore::class => [self::class, 'afterStore'], + ]; + } + + /** + * 开始导出 + * + * @param BeforeExport $event + * @return void + */ + public static function beforeExport(BeforeExport $event) + { + $data = [ + 'sn' => $event->getConcernable()->sn, + 'filename' => $event->getConcernable()->filename, + 'filesize' => 0, + 'conditions' => $event->getConcernable()->conditions ?: null, + 'status' => 0, + 'progress' => 0, + ]; + + Export::create($data); + } + + /** + * 写入数据 + * + * @param BeforeWriting $event + * @return void + */ + public static function beforeWriting(BeforeWriting $event) + { + Export::where(['sn' => $event->getConcernable()->sn])->update([ + 'status' => 1, + 'progress' => 50, + ]); + } + + /** + * 写入结束 + * + * @param AfterExport $event + * @return void + */ + public static function afterExport(AfterExport $event) + { + Export::where(['sn' => $event->getConcernable()->sn])->update([ + 'status' => 2, + 'progress' => 90, + ]); + } + + /** + * 保持结束 + * + * @param AfterStore $event + * @return void + */ + public static function afterStore(AfterStore $event) + { + $disk = Storage::disk($event->getDisk()); + + if ($disk->exists($event->getFilePath())) { + Export::where(['sn' => $event->getConcernable()->sn])->update([ + 'filesize' => $disk->size($event->getFilePath()), + 'status' => 3, + 'progress' => 100, + ]); + } else { + Export::where(['sn' => $event->getConcernable()->sn])->update([ + 'status' => 4, + 'progress' => 100, + ]); + } + } + + /** + * 表格标题 + * + * @return string + */ + public function title(): string + { + return self::$classes[get_class($this)] ?? '列表'; + } + + /** + * 序列号 + * + * @return string + */ + private function sn(): string + { + return date('YmdHis') .sprintf('%04d', explode('.', microtime(true))[1]) . sprintf('%02d', rand(0, 99)); + } + + /** + * 文件名称 + * + * @return string + */ + private function filename(): string + { + $filename = $this->title() . date('YmdHis'); + + return "export/{$filename}.xlsx"; + } +} diff --git a/app/Domains/Stats/Exports/CompanyCountExport.php b/app/Domains/Stats/Exports/CompanyCountExport.php index 03e4b2ad..9db89842 100644 --- a/app/Domains/Stats/Exports/CompanyCountExport.php +++ b/app/Domains/Stats/Exports/CompanyCountExport.php @@ -7,15 +7,16 @@ use Dipper\Excel\Concerns\WithHeadings; use Dipper\Excel\Concerns\FromCollection; use App\Domains\Stats\Services\CompanyCountService; -class CompanyCountExport implements FromCollection, WithHeadings +class CompanyCountExport extends AbstractExport implements FromCollection, WithHeadings { use Exportable; - protected $conditions; + public $conditions; public function __construct(array $conditions = []) { $this->conditions = $conditions; + parent::__construct(); } public function collection() diff --git a/app/Domains/Stats/Http/Controllers/CompanyCountController.php b/app/Domains/Stats/Http/Controllers/CompanyCountController.php index ab2c1889..8f404992 100644 --- a/app/Domains/Stats/Http/Controllers/CompanyCountController.php +++ b/app/Domains/Stats/Http/Controllers/CompanyCountController.php @@ -46,9 +46,9 @@ class CompanyCountController extends Controller $conditions = $this->request->all(); $conditions['limit'] = 0; - $filename = $this->getFilename('企业统计'); + $export = new CompanyCountExport($conditions); - $res = Excel::queue(new CompanyCountExport($conditions), $filename); + $res = Excel::queue($export, $export->filename(), $this->disk); dd($res); diff --git a/app/Domains/Stats/Http/Controllers/Controller.php b/app/Domains/Stats/Http/Controllers/Controller.php index b4196712..25c53e92 100644 --- a/app/Domains/Stats/Http/Controllers/Controller.php +++ b/app/Domains/Stats/Http/Controllers/Controller.php @@ -11,14 +11,5 @@ use App\Core\Controller as BaseController; */ abstract class Controller extends BaseController { - protected function getFilename($prefix = '列表') - { - $filename = $prefix; - - if (Request::get('starttime') && Request::get('endtime')) { - $filename .= ' ' . Carbon::parse(Request::get('starttime'))->format('Ymd') . '-' . Carbon::parse(Request::get('endtime'))->format('Ymd'); - } - - return "export/{$filename}.xlsx"; - } + public $disk = 'public'; } diff --git a/app/Domains/Virtual/Services/OrderService.php b/app/Domains/Virtual/Services/OrderService.php index ae762b35..a8bbe186 100644 --- a/app/Domains/Virtual/Services/OrderService.php +++ b/app/Domains/Virtual/Services/OrderService.php @@ -204,6 +204,6 @@ class OrderService extends Service */ public function generateSn() { - return date('YmdHis') . explode('.', microtime(true))[1] . sprintf('%02d', rand(0, 99)); + return date('YmdHis') .sprintf('%04d', explode('.', microtime(true))[1]) . sprintf('%02d', rand(0, 99)); } } diff --git a/app/Models/Stats/Export.php b/app/Models/Stats/Export.php new file mode 100644 index 00000000..a0b0cb79 --- /dev/null +++ b/app/Models/Stats/Export.php @@ -0,0 +1,16 @@ + 'array', + ]; +} diff --git a/composer.lock b/composer.lock index baaf94cb..a22a83ff 100644 --- a/composer.lock +++ b/composer.lock @@ -591,17 +591,17 @@ }, { "name": "dipper/excel", - "version": "3.1.4", + "version": "3.1.6", "source": { "type": "git", "url": "ssh://gogs@git.fxft.net:2222/composer/excel.git", - "reference": "1488a26fad170bd2d07d6f54723ef0ec437e355d" + "reference": "6b622871f65b501b9037c85f6a29f8ff8a9d0841" }, "dist": { "type": "tar", - "url": "https://composer.fxft.online/dist/dipper/excel/dipper-excel-3.1.4-152322.tar", - "reference": "1488a26fad170bd2d07d6f54723ef0ec437e355d", - "shasum": "6a2aa6fa78289887105026666559f16d358656e3" + "url": "https://composer.fxft.online/dist/dipper/excel/dipper-excel-3.1.6-7b07a0.tar", + "reference": "6b622871f65b501b9037c85f6a29f8ff8a9d0841", + "shasum": "bf0ab6605e6a46929d711bc0551638b19044ea52" }, "require": { "illuminate/support": "5.5.* || 5.6.* || 5.7.*", @@ -641,7 +641,7 @@ "MIT" ], "description": "Supercharged Excel exports and imports in Laravel", - "time": "2018-12-29T02:00:31+00:00" + "time": "2018-12-29T08:53:53+00:00" }, { "name": "dipper/flashmessage", diff --git a/config/excel.php b/config/excel.php index dbe24eca..e05fabc0 100644 --- a/config/excel.php +++ b/config/excel.php @@ -1,6 +1,6 @@ [ diff --git a/database/migrations/2018_12_29_112239_create_stats_exports_table.php b/database/migrations/2018_12_29_112239_create_stats_exports_table.php new file mode 100644 index 00000000..6fe76070 --- /dev/null +++ b/database/migrations/2018_12_29_112239_create_stats_exports_table.php @@ -0,0 +1,39 @@ +increments('id')->comment('自增ID'); + $table->string('sn', 32)->comment('命令编号'); + $table->string('filename')->default('')->comment('文件名'); + $table->integer('filesize')->unsigned()->default(0)->comment('文件大小'); + $table->text('conditions')->nullable()->comment('查询条件'); + $table->tinyInteger('status')->unsigned()->default(0)->comment('状态 0:数据准备中 1:开始写入 2:写入结束 3:保存成功 4:任务失败'); + $table->tinyInteger('progress')->unsigned()->default(0)->comment('进度'); + $table->timestamps(); + $table->unique('sn'); + $table->comment('VD统计导出表'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('stats_exports'); + } +} diff --git a/storage/app/public/企业统计.xlsx b/storage/app/public/企业统计.xlsx new file mode 100644 index 00000000..383f98a2 Binary files /dev/null and b/storage/app/public/企业统计.xlsx differ diff --git a/tests/StatsTest.php b/tests/StatsTest.php index 0f5f4858..fe735860 100644 --- a/tests/StatsTest.php +++ b/tests/StatsTest.php @@ -1,10 +1,13 @@ filename); \ No newline at end of file diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index b7c1d311..3ff9cefc 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -20,6 +20,7 @@ return array( 'CreateRealOrderCardsTable' => $baseDir . '/database/migrations/2018_12_24_164434_create_real_order_cards_table.php', 'CreateRealOrdersTable' => $baseDir . '/database/migrations/2018_12_24_164430_create_real_orders_table.php', 'CreateRealPackagesTable' => $baseDir . '/database/migrations/2018_12_24_164423_create_real_packages_table.php', + 'CreateStatsExportsTable' => $baseDir . '/database/migrations/2018_12_29_112239_create_stats_exports_table.php', 'CreateVirtualCompaniesTable' => $baseDir . '/database/migrations/2018_12_24_164716_create_virtual_companies_table.php', 'CreateVirtualCompanyAccountsTable' => $baseDir . '/database/migrations/2018_12_24_164728_create_virtual_company_accounts_table.php', 'CreateVirtualCompanyAddressesTable' => $baseDir . '/database/migrations/2018_12_24_164735_create_virtual_company_addresses_table.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 248d9bf2..8df748aa 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -723,6 +723,7 @@ class ComposerStaticInite79258a3e34ad3e251999111d9f334d9 'CreateRealOrderCardsTable' => __DIR__ . '/../..' . '/database/migrations/2018_12_24_164434_create_real_order_cards_table.php', 'CreateRealOrdersTable' => __DIR__ . '/../..' . '/database/migrations/2018_12_24_164430_create_real_orders_table.php', 'CreateRealPackagesTable' => __DIR__ . '/../..' . '/database/migrations/2018_12_24_164423_create_real_packages_table.php', + 'CreateStatsExportsTable' => __DIR__ . '/../..' . '/database/migrations/2018_12_29_112239_create_stats_exports_table.php', 'CreateVirtualCompaniesTable' => __DIR__ . '/../..' . '/database/migrations/2018_12_24_164716_create_virtual_companies_table.php', 'CreateVirtualCompanyAccountsTable' => __DIR__ . '/../..' . '/database/migrations/2018_12_24_164728_create_virtual_company_accounts_table.php', 'CreateVirtualCompanyAddressesTable' => __DIR__ . '/../..' . '/database/migrations/2018_12_24_164735_create_virtual_company_addresses_table.php', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 62ddff69..3c9ee450 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -604,18 +604,18 @@ }, { "name": "dipper/excel", - "version": "3.1.4", - "version_normalized": "3.1.4.0", + "version": "3.1.6", + "version_normalized": "3.1.6.0", "source": { "type": "git", "url": "ssh://gogs@git.fxft.net:2222/composer/excel.git", - "reference": "1488a26fad170bd2d07d6f54723ef0ec437e355d" + "reference": "6b622871f65b501b9037c85f6a29f8ff8a9d0841" }, "dist": { "type": "tar", - "url": "https://composer.fxft.online/dist/dipper/excel/dipper-excel-3.1.4-152322.tar", - "reference": "1488a26fad170bd2d07d6f54723ef0ec437e355d", - "shasum": "6a2aa6fa78289887105026666559f16d358656e3" + "url": "https://composer.fxft.online/dist/dipper/excel/dipper-excel-3.1.6-7b07a0.tar", + "reference": "6b622871f65b501b9037c85f6a29f8ff8a9d0841", + "shasum": "bf0ab6605e6a46929d711bc0551638b19044ea52" }, "require": { "illuminate/support": "5.5.* || 5.6.* || 5.7.*", @@ -630,7 +630,7 @@ "phpunit/phpunit": "^7.0", "predis/predis": "^1.1" }, - "time": "2018-12-29T02:00:31+00:00", + "time": "2018-12-29T08:53:53+00:00", "type": "library", "extra": { "laravel": { diff --git a/vendor/dipper/excel/src/Concerns/RegistersEventListeners.php b/vendor/dipper/excel/src/Concerns/RegistersEventListeners.php index d3743763..2474f2de 100644 --- a/vendor/dipper/excel/src/Concerns/RegistersEventListeners.php +++ b/vendor/dipper/excel/src/Concerns/RegistersEventListeners.php @@ -3,6 +3,8 @@ namespace Dipper\Excel\Concerns; use Dipper\Excel\Events\AfterSheet; +use Dipper\Excel\Events\AfterStore; +use Dipper\Excel\Events\AfterExport; use Dipper\Excel\Events\AfterImport; use Dipper\Excel\Events\BeforeSheet; use Dipper\Excel\Events\BeforeExport; @@ -42,6 +44,14 @@ trait RegistersEventListeners $listeners[AfterSheet::class] = [static::class, 'afterSheet']; } + if (method_exists($this, 'afterExport')) { + $listeners[AfterExport::class] = [static::class, 'afterExport']; + } + + if (method_exists($this, 'afterStore')) { + $listeners[AfterStore::class] = [static::class, 'afterStore']; + } + return $listeners; } } diff --git a/vendor/dipper/excel/src/Events/AfterExport.php b/vendor/dipper/excel/src/Events/AfterExport.php new file mode 100644 index 00000000..a4f03602 --- /dev/null +++ b/vendor/dipper/excel/src/Events/AfterExport.php @@ -0,0 +1,52 @@ +writer = $writer; + $this->exportable = $exportable; + } + + /** + * @return Writer + */ + public function getWriter(): Writer + { + return $this->writer; + } + + /** + * @return object + */ + public function getConcernable() + { + return $this->exportable; + } + + /** + * @return mixed + */ + public function getDelegate() + { + return $this->writer; + } +} diff --git a/vendor/dipper/excel/src/Events/AfterStore.php b/vendor/dipper/excel/src/Events/AfterStore.php new file mode 100644 index 00000000..dec7903c --- /dev/null +++ b/vendor/dipper/excel/src/Events/AfterStore.php @@ -0,0 +1,80 @@ +writer = $writer; + $this->exportable = $exportable; + $this->filePath = $filePath; + $this->disk = $disk; + } + + /** + * @return Writer + */ + public function getWriter(): Writer + { + return $this->writer; + } + + /** + * @return object + */ + public function getConcernable() + { + return $this->exportable; + } + + /** + * @return mixed + */ + public function getDelegate() + { + return $this->writer; + } + + /** + * @return mixed + */ + public function getFilePath() + { + return $this->filePath; + } + + /** + * @return string + */ + public function getDisk() + { + return $this->disk; + } +} diff --git a/vendor/dipper/excel/src/Excel.php b/vendor/dipper/excel/src/Excel.php index 9e9cfd1d..4cdcc962 100644 --- a/vendor/dipper/excel/src/Excel.php +++ b/vendor/dipper/excel/src/Excel.php @@ -2,17 +2,20 @@ namespace Dipper\Excel; +use Dipper\Excel\HasEventBus; use Illuminate\Support\Collection; +use Dipper\Excel\Events\AfterStore; +use Dipper\Excel\Bus\PendingDispatch; +use Dipper\Excel\Concerns\WithEvents; use PhpOffice\PhpSpreadsheet\IOFactory; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Filesystem\Factory; -use Dipper\Excel\Bus\PendingDispatch; -use Symfony\Component\HttpFoundation\File\UploadedFile; use Dipper\Excel\Exceptions\NoTypeDetectedException; +use Symfony\Component\HttpFoundation\File\UploadedFile; class Excel implements Exporter, Importer { - use RegistersCustomConcerns; + use RegistersCustomConcerns, HasEventBus; const XLSX = 'Xlsx'; @@ -97,7 +100,15 @@ class Excel implements Exporter, Importer $file = $this->export($export, $filePath, $writerType); - return $this->filesystem->disk($disk)->put($filePath, fopen($file, 'r+')); + if ($export instanceof WithEvents) { + $this->registerListeners($export->registerEvents()); + } + + $result = $this->filesystem->disk($disk)->put($filePath, fopen($file, 'r+')); + + $this->raise(new AfterStore($this->writer, $export)); + + return $result; } /** diff --git a/vendor/dipper/excel/src/Jobs/AfterQueueExportJob.php b/vendor/dipper/excel/src/Jobs/AfterQueueExportJob.php new file mode 100644 index 00000000..79674cb5 --- /dev/null +++ b/vendor/dipper/excel/src/Jobs/AfterQueueExportJob.php @@ -0,0 +1,59 @@ +writer = $writer; + $this->exportable = $exportable; + $this->filePath = $filePath; + $this->disk = $disk; + } + + /** + * @param FilesystemManager $filesystem + */ + public function handle() + { + if ($this->exportable instanceof WithEvents) { + $this->registerListeners($this->exportable->registerEvents()); + } + + $this->raise(new AfterStore($this->writer, $this->exportable, $this->filePath, $this->disk)); + } +} diff --git a/vendor/dipper/excel/src/QueuedWriter.php b/vendor/dipper/excel/src/QueuedWriter.php index 11ca0bbc..c24dd9e4 100644 --- a/vendor/dipper/excel/src/QueuedWriter.php +++ b/vendor/dipper/excel/src/QueuedWriter.php @@ -3,15 +3,16 @@ namespace Dipper\Excel; use Traversable; -use Illuminate\Support\Collection; use Dipper\Excel\Jobs\CloseSheet; use Dipper\Excel\Jobs\QueueExport; +use Illuminate\Support\Collection; use Dipper\Excel\Concerns\FromQuery; use Dipper\Excel\Jobs\SerializedQuery; use Dipper\Excel\Jobs\AppendDataToSheet; use Dipper\Excel\Jobs\StoreQueuedExport; use Dipper\Excel\Concerns\FromCollection; use Dipper\Excel\Jobs\AppendQueryToSheet; +use Dipper\Excel\Jobs\AfterQueueExportJob; use Dipper\Excel\Concerns\WithMultipleSheets; use Dipper\Excel\Concerns\WithCustomChunkSize; use Dipper\Excel\Concerns\WithCustomQuerySize; @@ -52,6 +53,7 @@ class QueuedWriter $jobs = $this->buildExportJobs($export, $tempFile, $writerType); $jobs->push(new StoreQueuedExport($tempFile, $filePath, $disk)); + $jobs->push(new AfterQueueExportJob($this->writer, $export, $filePath, $disk)); return QueueExport::withChain($jobs->toArray())->dispatch($export, $tempFile, $writerType); } diff --git a/vendor/dipper/excel/src/RegistersCustomConcerns.php b/vendor/dipper/excel/src/RegistersCustomConcerns.php index 03811395..a02592a1 100644 --- a/vendor/dipper/excel/src/RegistersCustomConcerns.php +++ b/vendor/dipper/excel/src/RegistersCustomConcerns.php @@ -4,6 +4,8 @@ namespace Dipper\Excel; use Dipper\Excel\Events\Event; use Dipper\Excel\Events\AfterSheet; +use Dipper\Excel\Events\AfterStore; +use Dipper\Excel\Events\AfterExport; use Dipper\Excel\Events\BeforeSheet; use Dipper\Excel\Events\BeforeExport; use Dipper\Excel\Events\BeforeWriting; @@ -18,6 +20,8 @@ trait RegistersCustomConcerns BeforeExport::class => Writer::class, BeforeSheet::class => Sheet::class, AfterSheet::class => Sheet::class, + AfterExport::class => Writer::class, + AfterStore::class => Writer::class, ]; /** diff --git a/vendor/dipper/excel/src/Writer.php b/vendor/dipper/excel/src/Writer.php index 043e4432..4693d293 100644 --- a/vendor/dipper/excel/src/Writer.php +++ b/vendor/dipper/excel/src/Writer.php @@ -2,21 +2,22 @@ namespace Dipper\Excel; -use PhpOffice\PhpSpreadsheet\Cell\Cell; -use PhpOffice\PhpSpreadsheet\IOFactory; -use PhpOffice\PhpSpreadsheet\Writer\Csv; use Dipper\Excel\Concerns\WithTitle; -use PhpOffice\PhpSpreadsheet\Spreadsheet; +use Dipper\Excel\Events\AfterExport; use Dipper\Excel\Concerns\WithCharts; use Dipper\Excel\Concerns\WithEvents; use Dipper\Excel\Events\BeforeExport; use Dipper\Excel\Events\BeforeWriting; +use PhpOffice\PhpSpreadsheet\Cell\Cell; +use PhpOffice\PhpSpreadsheet\IOFactory; +use PhpOffice\PhpSpreadsheet\Writer\Csv; +use PhpOffice\PhpSpreadsheet\Spreadsheet; use Dipper\Excel\Concerns\MapsCsvSettings; use Dipper\Excel\Concerns\WithMultipleSheets; use Dipper\Excel\Concerns\WithCustomCsvSettings; use Dipper\Excel\Concerns\WithCustomValueBinder; -use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder; use Dipper\Excel\Concerns\WithPreCalculateFormulas; +use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder; class Writer { @@ -164,6 +165,8 @@ class Writer $this->spreadsheet->disconnectWorksheets(); unset($this->spreadsheet); + $this->raise(new AfterExport($this, $this->exportable)); + return $fileName; }