This commit is contained in:
parent
dc1d3c1cc1
commit
d3b1927b3e
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Controller\Admin;
|
||||
|
||||
use App\Annotation\Auth;
|
||||
use App\Model\Attachment as aModel;
|
||||
use App\Model\GenTable as gtModel;
|
||||
use App\Request\GenTable as gtRequest;
|
||||
use App\Model\Message as mModel;
|
||||
|
|
@ -269,4 +270,22 @@ class Tools extends Base
|
|||
if (!$data['id']) return $this->error();
|
||||
return $this->toAjax(mModel::edit(['message_id' => $data['id'], 'recalled_flag' => 1]));
|
||||
}
|
||||
|
||||
#[GetMapping(path: "file/export")]
|
||||
#[Auth(auth: "file:export")]
|
||||
public function messageExport()
|
||||
{
|
||||
$param = Param::only(["module" => "demo", "name" => "数据导出", "params" => []]);
|
||||
$res = aModel::add([
|
||||
'account_id' => $this->accountId(),
|
||||
'name' => $param['name'],
|
||||
'module' => $param['module'],
|
||||
'params' => json_encode($param['params'], true),
|
||||
'status' => 0,
|
||||
'create_time' => date("Y-m-d H:i:s")
|
||||
]);
|
||||
if (!$res) return $this->error("导出任务创建失败");
|
||||
QueueClient::push("App\Job\FileExportJob", ['messageId' => $res, 'channels' => ['websocket', 'email']]);
|
||||
return $this->success("导出任务创建成功");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace App\Job;
|
||||
|
||||
use Hyperf\AsyncQueue\Job;
|
||||
use App\Model\Attachment as aModel;
|
||||
use App\Model\Post as pModel;
|
||||
|
||||
class FileExportJob extends Job
|
||||
{
|
||||
protected int $maxAttempts = 1;
|
||||
protected int $attachmentId;
|
||||
|
||||
public function __construct(array $params)
|
||||
{
|
||||
$this->attachmentId = $params['attachmentId'];
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
try {
|
||||
$attach = aModel::find($this->attachmentId);
|
||||
if (empty($attach)) return false;
|
||||
switch ($attach->module) {
|
||||
case "post_export":
|
||||
$res = pModel::exportData($attach->params);
|
||||
$res = true;
|
||||
break;
|
||||
default:
|
||||
throw new \Exception("导出模块不存在");
|
||||
}
|
||||
aModel::edit([
|
||||
'attachment_id' => $this->attachmentId,
|
||||
'status' => $res ? 1 : 2,
|
||||
'fail_reason' => $res ? "" : "导出失败"
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
aModel::edit([
|
||||
'attachment_id' => $this->attachmentId,
|
||||
'status' => 2,
|
||||
'fail_reason' => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Model;
|
||||
|
||||
/**
|
||||
* @property int $attachment_id
|
||||
* @property int $account_id
|
||||
* @property string $name
|
||||
* @property string $module
|
||||
* @property string $params
|
||||
* @property string $type
|
||||
* @property string $path
|
||||
* @property int $status
|
||||
* @property string $fail_reason
|
||||
* @property string $deleted_at
|
||||
* @property string $create_time
|
||||
* @property string $update_time
|
||||
*/
|
||||
class Attachment extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*/
|
||||
protected ?string $table = 'attachment';
|
||||
|
||||
protected string $primaryKey = 'attachment_id';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*/
|
||||
protected array $fillable = [];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
*/
|
||||
protected array $casts = ['attachment_id' => 'integer', 'account_id' => 'integer', 'status' => 'integer'];
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace App\Utils;
|
||||
|
||||
use Exception;
|
||||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use function Hyperf\Config\config;
|
||||
|
||||
class Excel
|
||||
{
|
||||
/**
|
||||
* 获取excel内容
|
||||
*/
|
||||
public static function importData($file)
|
||||
{
|
||||
try {
|
||||
if (!$file) return false;
|
||||
$file = BASE_PATH . DIRECTORY_SEPARATOR . 'runtime' . DIRECTORY_SEPARATOR . $file;
|
||||
if (!file_exists($file)) return false;
|
||||
// 显式使用 Xlsx 读取器并配置兼容选项
|
||||
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
|
||||
// 关键配置:跳过样式/公式等兼容性陷阱
|
||||
$reader->setReadDataOnly(true); // 只读数据,忽略公式
|
||||
$reader->setReadEmptyCells(false); // 跳过空单元格处理
|
||||
$reader->setLoadSheetsOnly(["Sheet1"]); // 明确加载指定工作表
|
||||
$spreadsheet = $reader->load($file);
|
||||
return $spreadsheet->getSheet(0)->toArray();
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出文件
|
||||
* Author: cfn <cfn@leapy.cn>
|
||||
* @param $name
|
||||
* @param $header
|
||||
* @param $data
|
||||
* @return false|string
|
||||
*/
|
||||
public static function exportData($name, $header, $data)
|
||||
{
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$sheet->setTitle('sheet1');
|
||||
//表头
|
||||
$sheet->fromArray($header, '', 'A1');
|
||||
$sheet->fromArray($data, '', 'A2');
|
||||
$sheet->getDefaultColumnDimension()->setWidth(12);
|
||||
$date = date("Ymd");
|
||||
$saveDir = BASE_PATH . '/static' . "/export/{$date}/";
|
||||
if (!is_dir($saveDir)) {
|
||||
mkdir($saveDir, 0777, true);
|
||||
}
|
||||
$saveFile = "{$saveDir}{$name}.xlsx";
|
||||
//按照指定格式生成Excel文件
|
||||
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
|
||||
$writer->save($saveFile);
|
||||
if (is_file($saveFile)) {
|
||||
return config("app.domain") . "xlsx/{$date}/{$name}.xlsx";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue