fix:修复BUG/升级1.1.6版本

This commit is contained in:
Ying
2023-04-25 20:11:49 +08:00
parent 445e5f9662
commit 6a6866bbaf
2357 changed files with 456920 additions and 140567 deletions

View File

@@ -10,12 +10,19 @@ declare (strict_types=1);
// | Author: meystack <coolsec@foxmail.com> Apache 2.0 License
// +----------------------------------------------------------------------
namespace app;
use support\Log;
use support\Response;
use think\db\exception\BindParamException;
use think\facade\Db;
use think\helper\Str;
use think\Validate;
use Webman\Http\Request;
use Gregwar\Captcha\CaptchaBuilder;
use Webman\Captcha\CaptchaBuilder;
use PhpOffice\PhpSpreadsheet\Exception;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Shared\Date;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
class BaseController
{
@@ -204,14 +211,15 @@ class BaseController
* 返回错误信息
* @param string $msg
* @param int $code
* @param string $app
* @return Response
*/
protected function retResponseError(string $msg = '404 not found', int $code = 404): Response
protected function retResponseError(string $msg = '404 not found', int $code = 404, string $app = 'index'): Response
{
if (\request()->expectsJson()) {
return json(['code' => 404, 'msg' => $msg]);
}
return response(request_error(), $code);
return response(request_error($app), $code);
}
/**
@@ -250,6 +258,195 @@ class BaseController
return response($img_content, 200, ['Content-Type' => 'image/jpeg']);
}
/**
* 导入数据
* @return Response
* @throws Exception
* @throws BindParamException
*/
public function import(): Response
{
$file = request()->file('file');
if (!$file || !$file->isValid()) {
return $this->error('上传文件校验失败!');
}
// 获取临时目录
$filePath = uniqid() . '.' . strtolower($file->getUploadExtension());
$resource = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $filePath;
if (!$file->move($resource)) {
return $this->error('上传文件读写失败!');
}
$ext = pathinfo($filePath, PATHINFO_EXTENSION);
if (!in_array($ext, ['xls', 'xlsx'])) {
return $this->error('仅支持xls xlsx文件格式');
}
try {
// 实例化Excel对象
$fileType = IOFactory::identify($filePath);
$reader = IOFactory::createReader($fileType);
$reader->setReadDataOnly(true);
$spreadsheet = $reader->load($resource);
} catch (\Exception $e) {
return $this->error($e->getMessage());
}
// 默认获取第一张表
$currentSheet = $spreadsheet->getSheet(0);
$listSheetData = $currentSheet->toArray();
// 数据量最小为1条
$listRows = count($listSheetData);
if ($listRows <= 2) {
return $this->error('数据行最小为2');
}
// 获取Excel首行预处理
$fields = $listSheetData[0];
array_shift($listSheetData);
// 获取数据表字段注释
$table = $this->model->getTable();
$columns = Db::query("SHOW FULL COLUMNS FROM {$table}");
$comments = array_column($columns, 'Comment', 'Field');
$columnType = !isset($this->columnType) ? 'comment' : $this->columnType;
// 循环处理要插入的row
$inserts = [];
foreach ($listSheetData as $row => $item) {
foreach ($fields as $key => $value) {
$excelValue = function ($field, $value) {
if (in_array($field, ['create_time', 'update_time']) && !empty($value)) {
$time = Date::excelToTimestamp($value);
$value = strlen((string)$time) >= 12 ? $value : $time;
if ($value <= 1) { // 负值时间戳
$value = time();
}
}
return $value;
};
// 默认首行为注释模式
if (strtolower($columnType) == 'comment') {
$field = array_search($value, $comments);
if (!empty($field)) {
$inserts[$row][$field] = $excelValue($field, $item[$key]);
}
} else if (array_key_exists($value, $comments)) {
$inserts[$row][$value] = $excelValue($value, $item[$key]);
}
}
// 录入登录用户ID
if (array_key_exists('admin_id', $comments)) {
$entry_id = $inserts[$row]['admin_id'] ?? 0;
if (empty($entry_id)) {
$inserts[$row]['admin_id'] = get_admin_id();
}
}
}
// 判断是否有可导入的数据
if (count($inserts) == 0) {
return $this->error('没有可导入的数据!');
}
try {
// 批量插入数据
$this->model->insertAll($inserts);
unlink($resource);
} catch (\Exception $e) {
return $this->error($e->getMessage());
}
return $this->success('导入成功!', '/');
}
/**
* 导出数据
* @return Response
* @throws BindParamException
*/
public function export(): Response
{
if (\request()->isAjax()) {
// 获取分页
$page = input('page', 1);
$limit = input('limit', 1000);
// 查询表数据
$table = $this->model->getTable();
$columns = Db::query("SHOW FULL COLUMNS FROM {$table}");
$titles = array_column($columns, 'Comment', 'Field');
$data = $this->model->limit($limit)->page($page)->select()->toArray();
$folder = date('Y-m-d', time());
// 使用表注释为文件名称
$tableInfo = Db::query("SHOW TABLE STATUS LIKE '{$table}'");
$Comment = $tableInfo[0]['Comment'] ?: '数据_';
$fileName = $Comment . $folder . '.xlsx';
$filePath = public_path('upload/files') . DIRECTORY_SEPARATOR . $folder . DIRECTORY_SEPARATOR . $fileName;
if (!$this->exportThread($titles, $data, $filePath)) {
return $this->error('导出失败!');
}
$downUrl = str_replace(public_path(), '', $filePath);
return $this->success('导出成功!', $downUrl);
}
return $this->error('非法请求!');
}
/**
* @param array $titles
* @param array $data
* @param string $filePath
* @return bool
*/
protected function exportThread(array $titles, array $data, string $filePath): bool
{
// 实例化Xls接口
$spreadSheet = new Spreadsheet();
$activeSheet = $spreadSheet->getActiveSheet();
// 设表列头样式居中
$activeSheet->getStyle('A1:AZ1')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
$columnType = !isset($this->columnType) ? 'comment' : $this->columnType;
try {
$titCol = 'A';
foreach ($titles as $key => $value) {
$value = $columnType == 'comment' ? $value : $key;
$activeSheet->setCellValue($titCol . '1', $value);
$titCol++;
}
$rowLine = 2;
foreach ($data as $item) {
$rowCol = 'A';
foreach ($item as $value) {
$activeSheet->setCellValue($rowCol . $rowLine, $value);
$rowCol++;
}
$rowLine++;
}
$writer = IOFactory::createWriter($spreadSheet, 'Xlsx');
mk_dirs(dirname($filePath));
$writer->save($filePath);
$spreadSheet->disconnectWorksheets();
unset($spreadsheet);
} catch (\Throwable $e) {
Log::error($e->getMessage());
return false;
}
return true;
}
/**
* 检查验证码
* @param string $text