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.

455 lines
20 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\AppointmentType;
use App\Models\Book;
use App\Models\Calendar;
use App\Models\CourseContentEvaluationAsk;
use App\Models\CourseContentEvaluationForm;
use App\Models\CustomForm;
use App\Models\CustomFormField;
use App\Models\EmailRecord;
use App\Models\EmailRecordUser;
use App\Models\EmailTemplate;
use App\Models\SupplyDemand;
use App\Models\Upload;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Facades\Excel;
use Rap2hpoutre\FastExcel\FastExcel;
class EmailRecordController extends BaseController
{
/**
* 构造函数
*/
public function __construct()
{
parent::__construct(new EmailRecord());
}
/**
* @OA\Get(
* path="/api/admin/email-record/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="需要输出的关联关系数组包括teachercourseSettingscoursePeriods"),
* @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('emailTemplate')
->withCount('emailRecordUsers')
->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 . '%');
}
// 范围搜索
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);
foreach ($list as $detail) {
// 成功数量
$detail->success_count = $detail->emailRecordUsers->where('status', 1)->count();
// 失败数量
$detail->fail_count = $detail->emailRecordUsers->where('status', 2)->count();
}
}
return $this->success($list);
}
/**
* @OA\Get(
* path="/api/admin/email-record/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 = [
'title.required' => '标题必填',
];
$validator = Validator::make($all, [
'title' => 'required'
], $messages);
if ($validator->fails()) {
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$detail = $this->model->with('emailTemplate', 'emailRecordUsers')->withCount('emailRecordUsers')->find($all['id']);
// 成功数量
$detail->success_count = $detail->emailRecordUsers->where('status', 1)->count();
// 失败数量
$detail->fail_count = $detail->emailRecordUsers->where('status', 2)->count();
return $this->success($detail);
}
/**
* @OA\Post(
* path="/api/admin/email-record/save",
* tags={"邮件发送配置"},
* summary="保存",
* description="",
* @OA\Parameter(name="id", in="query", @OA\Schema(type="integer", format="int64"), required=true, description="ID存在则更新不存在则新增"),
* @OA\Parameter(name="time", in="query", @OA\Schema(type="string", format="date"), required=false, description="发送时间"),
* @OA\Parameter(name="subject", in="query", @OA\Schema(type="string", maxLength=255), required=false, description="主题"),
* @OA\Parameter(name="email_template_id", in="query", @OA\Schema(type="string", format="mediumtext"), required=false, description="邮件模版id"),
* @OA\Parameter(name="email_record_users", in="query", @OA\Schema(type="string", format="mediumtext"), required=false, description="二维数组包括建明emailvar_data自定义数据"),
* @OA\Parameter(name="attachments", in="query", @OA\Schema(type="array", @OA\Items(type="file")), required=false, description="附件文件数组,支持多个附件"),
* @OA\Parameter(name="attachment_ids", in="query", @OA\Schema(type="string"), required=false, 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;
}
// 处理附件上传
$attachmentIds = [];
// 如果提供了已上传的附件ID
if (isset($all['attachment_ids']) && !empty($all['attachment_ids'])) {
$attachmentIds = array_merge($attachmentIds, explode(',', $all['attachment_ids']));
$attachmentIds = array_filter(array_map('trim', $attachmentIds));
}
// 如果有新上传的附件文件
if (\request()->hasFile('attachments')) {
$files = \request()->file('attachments');
// 如果是单个文件,转换为数组
if (!is_array($files)) {
$files = [$files];
}
foreach ($files as $file) {
if ($file && $file->isValid()) {
// 获取文件大小,单位B
$fileSize = floor($file->getSize());
if ($fileSize >= 50 * 1024 * 1024) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '文件必须小于50M']);
}
// 过滤文件后缀
$ext = $file->getClientOriginalExtension();
if (in_array($ext, ['zip', 'rar', 'ppt', 'pptx', 'xls', 'xlsx', 'doc', 'docx', 'png', 'gif', 'jpg', 'jpeg', 'pdf', 'mp4'])) {
// 保存目录
$dir = 'files';
// 文件名
$fileName = time() . uniqid() . '.' . $ext;
$file->storeAs($dir, $fileName, ['disk' => 'public']);
// 写入上传文件记录表
$uploadData = [
'original_name' => $file->getClientOriginalName(),
'folder' => 'storage/' . $dir,
'name' => $fileName,
'extension' => $ext,
'size' => $fileSize,
'creator_id' => $this->getUserId(),
'created_at' => date('Y-m-d H:i:s')
];
$uploadId = Upload::insertGetId($uploadData);
$attachmentIds[] = $uploadId;
} else {
return $this->fail([ResponseCode::ERROR_BUSINESS, '文件格式错误仅支持zip、rar、ppt、pptx、xls、xlsx、doc、docx、png、gif、jpg、jpeg、pdf、mp4']);
}
}
}
}
// 保存附件ID用逗号分隔
if (!empty($attachmentIds)) {
$all['attachments'] = implode(',', $attachmentIds);
}
$original = $model->getOriginal();
$model->fill($all);
$model->save();
if (isset($all['email_record_users'])) {
$model->emailRecordUsers()->delete();
$model->emailRecordUsers()->createMany($all['email_record_users']);
}
DB::commit();
// 记录日志
$this->saveLogs($original, $model);
return $this->success($model);
} catch (\Exception $exception) {
DB::rollBack();
return $this->fail([$exception->getCode(), $exception->getMessage()]);
}
}
/**
* @OA\Post(
* path="/api/admin/email-record/send-example",
* tags={"邮件发送配置"},
* summary="发送测试邮件",
* description="",
* @OA\Parameter(name="email_template_id", in="query", @OA\Schema(type="integer", format="int64"), required=true, description="模版id"),
* @OA\Parameter(name="subject", in="query", @OA\Schema(type="string", format="date"), required=false, description="标题"),
* @OA\Parameter(name="email", in="query", @OA\Schema(type="string", format="date"), required=false, description="邮箱地址"),
* @OA\Parameter(name="var_data", in="query", @OA\Schema(type="string", format="mediumtext"), required=false, description="数组var_data自定义数据"),
* @OA\Parameter(name="attachments", in="query", @OA\Schema(type="array", @OA\Items(type="file")), required=false, description="附件文件数组,支持多个附件"),
* @OA\Parameter(name="attachment_ids", in="query", @OA\Schema(type="string"), required=false, description="附件ID多个用英文逗号分隔如果已上传附件"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="认证token"),
* @OA\Response(
* response="200",
* description="操作成功"
* )
* )
*/
public function sendExample()
{
$all = \request()->all();
$validator = Validator::make($all, [
'email_template_id' => 'required',
'subject' => 'required',
'email' => 'required',
'var_data' => 'required',
]);
if ($validator->fails()) {
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
try {
$emailTemplate = EmailTemplate::find($all['email_template_id']);
// 替换后的标题
$title = EmailRecordUser::template($all['subject'], $all['var_data']);
// 替换后的内容
$template = EmailRecordUser::template($emailTemplate->content, $all['var_data']);
// 处理附件
$attachments = [];
// 如果提供了已上传的附件ID
if (isset($all['attachment_ids']) && !empty($all['attachment_ids'])) {
$attachmentIds = explode(',', $all['attachment_ids']);
$attachmentIds = array_filter(array_map('trim', $attachmentIds));
$attachments = Upload::whereIn('id', $attachmentIds)->get();
}
// 如果有新上传的附件文件
if (\request()->hasFile('attachments')) {
$files = \request()->file('attachments');
// 如果是单个文件,转换为数组
if (!is_array($files)) {
$files = [$files];
}
foreach ($files as $file) {
if ($file && $file->isValid()) {
// 获取文件大小,单位B
$fileSize = floor($file->getSize());
if ($fileSize >= 50 * 1024 * 1024) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '文件必须小于50M']);
}
// 过滤文件后缀
$ext = $file->getClientOriginalExtension();
if (in_array($ext, ['zip', 'rar', 'ppt', 'pptx', 'xls', 'xlsx', 'doc', 'docx', 'png', 'gif', 'jpg', 'jpeg', 'pdf', 'mp4'])) {
// 保存目录
$dir = 'files';
// 文件名
$fileName = time() . uniqid() . '.' . $ext;
$file->storeAs($dir, $fileName, ['disk' => 'public']);
// 写入上传文件记录表
$uploadData = [
'original_name' => $file->getClientOriginalName(),
'folder' => 'storage/' . $dir,
'name' => $fileName,
'extension' => $ext,
'size' => $fileSize,
'creator_id' => $this->getUserId(),
'created_at' => date('Y-m-d H:i:s')
];
$uploadId = Upload::insertGetId($uploadData);
$upload = Upload::find($uploadId);
$attachments[] = $upload;
} else {
return $this->fail([ResponseCode::ERROR_BUSINESS, '文件格式错误仅支持zip、rar、ppt、pptx、xls、xlsx、doc、docx、png、gif、jpg、jpeg、pdf、mp4']);
}
}
}
}
try {
// 发送邮件(带附件)
EmailRecordUser::email($title, $template, $all['email'], $attachments);
return $this->success("发送成功");
} catch (\Exception $e) {
return $this->fail([ResponseCode::ERROR_BUSINESS, $e->getMessage()]);
}
} catch (\Exception $exception) {
return $this->fail([$exception->getCode(), $exception->getMessage()]);
}
}
/**
* @OA\Get(
* path="/api/admin/email-record/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()
{
return parent::destroy();
}
/**
* @OA\Post(
* path="/api/admin/email-record/excel-show",
* tags={"邮件发送配置"},
* summary="导入预览",
* 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');
//判断文件是否有效
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();
$list = [];
foreach ($dataArray as $key => $value) {
if (!isset($value['邮箱']) || empty($value['邮箱'])) {
continue;
}
// 时间标准格式化
foreach ($value as $k => &$v) {
if ($v instanceof \DateTimeImmutable) {
$v = Carbon::parse($v)->rawFormat('Y-m-d H:i');
}
}
$list[] = [
'email' => $value['邮箱'],
'var_data' => $value
];
}
return $this->success($list);
}
}