You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

381 lines
15 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Http\Controllers\Admin;
use App\Exports\BaseExport;
use App\Helpers\ResponseCode;
use App\Models\CustomForm;
use App\Models\CustomFormField;
use App\Models\CustomFormFieldUpdate;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Facades\Excel;
use Rap2hpoutre\FastExcel\FastExcel;
class BaseController extends CommonController
{
protected $model;
/**
* CommonController构造函数
*
* @param object $model 要操作的模型
*/
public function __construct($model)
{
$this->model = $model;
}
/**
* @OA\Get(
* path="/api/admin/{table_name}/index",
* tags={"通用接口"},
* summary="列表",
* description="",
* @OA\Parameter(name="is_export", in="query", @OA\Schema(type="string"), required=false, description="是否导出0否1是"),
* @OA\Parameter(name="export_fields", in="query", @OA\Schema(type="string"), required=false, description="需要导出的字段数组"),
* @OA\Parameter(name="filter", in="query", @OA\Schema(type="string"), required=false, description="查询条件。数组"),
* @OA\Parameter(name="show_relation", in="query", @OA\Schema(type="string"), required=false, description="需要输出的关联关系数组,填写输出指定数据"),
* @OA\Parameter(name="page_size", in="query", @OA\Schema(type="string"), required=false, description="每页显示的条数"),
* @OA\Parameter(name="page", in="query", @OA\Schema(type="string"), required=false, description="页码"),
* @OA\Parameter(name="sort_name", in="query", @OA\Schema(type="string"), required=false, description="排序字段名字"),
* @OA\Parameter(name="sort_type", in="query", @OA\Schema(type="string"), required=false, description="排序类型"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="暂无"
* )
* )
*/
public function index()
{
$all = request()->all();
$list = $this->model->with(underlineToHump($all['show_relation'] ?? []))->where(function ($query) use ($all) {
if (isset($all['filter']) && !empty($all['filter'])) {
foreach ($all['filter'] as $condition) {
$key = $condition['key'] ?? null;
$op = $condition['op'] ?? null;
$value = $condition['value'] ?? null;
if (!isset($key) || !isset($op) || !isset($value)) {
continue;
}
// 等于
if ($op == 'eq') {
$query->where($key, $value);
}
// 不等于
if ($op == 'neq') {
$query->where($key, '!=', $value);
}
// 大于
if ($op == 'gt') {
$query->where($key, '>', $value);
}
// 大于等于
if ($op == 'egt') {
$query->where($key, '>=', $value);
}
// 小于
if ($op == 'lt') {
$query->where($key, '<', $value);
}
// 小于等于
if ($op == 'elt') {
$query->where($key, '<=', $value);
}
// 模糊搜索
if ($op == 'like') {
$query->where($key, 'like', '%' . $value . '%');
}
// 否定模糊搜索
if ($op == 'notlike') {
$query->where($key, 'not like', '%' . $value . '%');
}
// null搜索
if ($op == 'null') {
$query->whereNull($key);
}
// notnull搜索
if ($op == 'notnull') {
$query->whereNotNull($key);
}
// 范围搜索
if ($op == 'range') {
list($from, $to) = explode(',', $value);
if (empty($from) || empty($to)) {
continue;
}
$query->whereBetween($key, [$from, $to]);
}
}
}
})->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc');
if (isset($all['is_export']) && !empty($all['is_export'])) {
$list = $list->get()->toArray();
$export_fields = $all['export_fields'] ?? [];
// 导出文件名字
$tableName = $this->model->getTable();
$filename = (new CustomForm())->getTableComment($tableName);
return Excel::download(new BaseExport($export_fields, $list, $tableName), $filename . date('YmdHis') . '.xlsx');
} else {
// 输出
$list = $list->paginate($all['page_size'] ?? 20);
}
return $this->success($list);
}
/**
* @OA\Get(
* path="/api/admin/{table_name}/show",
* tags={"通用接口"},
* summary="详情",
* description="",
* @OA\Parameter(name="id", in="query", @OA\Schema(type="string"), required=true, description="id"),
* @OA\Parameter(name="show_relation", in="query", @OA\Schema(type="string"), required=false, description="需要输出的关联关系数组,填写输出指定数据"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="暂无"
* )
* )
*/
public function show()
{
$all = \request()->all();
$messages = [
'id.required' => 'Id必填',
];
$validator = Validator::make($all, [
'id' => 'required'
], $messages);
if ($validator->fails()) {
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$detail = $this->model->with(underlineToHump($all['show_relation'] ?? []))->find($all['id']);
return $this->success($detail);
}
/**
* @OA\Post(
* path="/api/admin/{table_name}/save",
* tags={"通用接口"},
* summary="更新",
* description="",
* @OA\Parameter(name="id", in="query", @OA\Schema(type="int"), required=true, description="Id(存在更新,不存在新增)"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="暂无"
* )
* )
*/
public function save()
{
$all = \request()->all();
DB::beginTransaction();
try {
if (isset($all['id'])) {
$model = $this->model->find($all['id']);
if (empty($model)) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '数据不存在']);
}
} else {
$model = $this->model;
$all['admin_id'] = $this->getUserId();
$all['department_id'] = $this->getUser()->department_id;
}
$original = $model->getOriginal();
$model->fill($all);
$model->save();
DB::commit();
// 记录日志
$this->saveLogs($original, $model);
return $this->success($model);
} catch (\Exception $exception) {
DB::rollBack();
return $this->fail([$exception->getCode(), $exception->getMessage()]);
}
}
/**
* @OA\Get(
* path="/api/admin/{table_name}/destroy",
* tags={"通用接口"},
* summary="删除",
* description="",
* @OA\Parameter(name="id", in="query", @OA\Schema(type="string"), required=true, description="id"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="暂无"
* )
* )
*/
public function destroy()
{
$all = \request()->all();
$messages = [
'id.required' => 'Id必填',
];
$validator = Validator::make($all, [
'id' => 'required'
], $messages);
if ($validator->fails()) {
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$model = $this->model->find($all['id']);
if (empty($model)) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '数据不存在']);
}
$model->delete();
// 记录日志
$this->saveLogs('delete', $model);
return $this->success('删除成功');
}
/**
* @OA\Post(
* path="/api/admin/{table_name}/excel-show",
* tags={"通用接口"},
* summary="导入预览",
* description="",
* @OA\Parameter(name="data", in="query", @OA\Schema(type="string"), required=true, description="统一数据键值对数组"),
* @OA\Parameter(name="file", in="query", @OA\Schema(type="string"), required=true, description="文件"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="暂无"
* )
* )
*/
public function excelShow()
{
$file = \request()->file('file');
$data = \request('data', []);
//判断文件是否有效
if (!(\request()->hasFile('file') && $file->isValid())) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '文件不存在或无效']);
}
//获取文件大小
$img_size = floor($file->getSize() / 1024);
if ($img_size >= 50 * 1024) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '文件必须小于50M']);
}
//过滤文件后缀
$ext = $file->getClientOriginalExtension();
if (!in_array($ext, ['xls', 'xlsx', 'csv'])) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '仅支持xls/xlsx/csv格式']);
}
$tempFile = $file->getRealPath();
$dataArray = (new FastExcel)->import($tempFile)->toArray();
// 数据过滤,只能导入数据表有的字段
$tableName = $this->model->getTable();
$rowTableFieldByComment = (new CustomFormField)->getRowTableFieldsByComment($tableName);
$list = [];
foreach ($dataArray as $key => $value) {
foreach ($rowTableFieldByComment as $k => $v) {
if (isset($value[$v])) {
$list[$key][$k] = $value[$v];
}
}
$list[$key] = array_merge($list[$key], $data);
}
return $this->success($list);
}
/**
* @OA\Post(
* path="/api/admin/{table_name}/import",
* tags={"通用接口"},
* summary="导入",
* description="",
* @OA\Parameter(name="data", in="query", @OA\Schema(type="string"), required=true, description="导入分析获取到的二维数组"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="暂无"
* )
* )
*/
public function import()
{
$all = \request()->all();
$messages = [
'data.required' => '数据必填',
];
$validator = Validator::make($all, [
'data' => 'required',
], $messages);
if ($validator->fails()) {
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$records = $all['data'];
DB::beginTransaction();
try {
// 获取数据表的所有字段
$tableName = $this->model->getTable();
$existingColumns = (new CustomFormField)->getRowTableFieldsByComment($tableName);
// 过滤掉不存在的字段
$filteredRecords = array_map(function ($record) use ($existingColumns) {
return array_intersect_key($record, $existingColumns);
}, $records);
// 去除空数据
$filteredRecords = array_filter($filteredRecords);
// 分段导入
foreach (array_chunk($filteredRecords, 500) as $chunk) {
$this->model->insert($chunk);
}
DB::commit();
return $this->success(['total' => count($records), 'filter_total' => count($filteredRecords)]);
} catch (\Exception $exception) {
DB::rollBack();
return $this->fail([$exception->getCode(), $exception->getMessage()]);
}
}
/**
* 创建/更新/删除字段数据记录
* @param $original 原数据
* @param $model 新数据
* @return mixed
*/
protected function saveLogs($original, $model)
{
$user = $this->getUser();
$tableName = $this->model->getTable();
$fileds = (new CustomFormField())->getRowTableFieldsByComment($tableName);
$list = [];
if (empty($original)) {
$operate = '新建';
// 新增
foreach ($model->toArray() as $key => $item) {
$list[] = json_encode(($fileds[$key] ?? $key), JSON_UNESCAPED_UNICODE) . "" . json_encode($item, JSON_UNESCAPED_UNICODE);
}
} elseif ($original == 'delete') {
$operate = '删除';
} else {
// 更新
$operate = '更新';
$changes = $model->getChanges();
// 修改了内容
foreach ($changes as $key => $item) {
if (in_array($key, ['updated_at'])) continue;
if (isset($original[$key])) {
$list[] = json_encode(($fileds[$key] ?? $key), JSON_UNESCAPED_UNICODE) . "" . json_encode($original[$key], JSON_UNESCAPED_UNICODE) . "=>" . json_encode($item, JSON_UNESCAPED_UNICODE);
}
}
}
return CustomFormFieldUpdate::create([
'table_name' => $tableName,
'admin_id' => $user->id,
'operate' => $operate,
'table_id' => $model->id,
'department_id' => $user->department_id ?? 0,
'ip' => $_SERVER['REMOTE_ADDR'],
'content' => implode('。', $list),
'requst_data' => json_encode(request()->all(), JSON_UNESCAPED_UNICODE)
]);
}
}