feat: 管理员系统设置新增:新增邮件设置

This commit is contained in:
韦荣超 2022-02-28 18:15:17 +08:00
parent ab388f1ef5
commit cf7e7c1a06
8 changed files with 405 additions and 9 deletions

View File

@ -500,4 +500,58 @@ class SystemController extends AbstractController
'home_footer' => Base::settingFind('system', 'home_footer')
]);
}
/**
* @api {get} api/system/emailSetting 14. 获取邮箱设置、保存邮箱设置
*
* @apiVersion 1.0.0
* @apiGroup system
* @apiName emailSetting
*
* @apiParam {String} type
* - get: 获取(默认)
* - all: 获取所有(需要管理员权限)
* - save: 保存设置参数smtp_server port account password reg_verify notice task_remind_hours task_remind_hours2
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function emailSetting()
{
$type = trim(Request::input('type'));
if ($type == 'save') {
if (env("SYSTEM_SETTING") == 'disabled') {
return Base::retError('当前环境禁止修改');
}
User::auth('admin');
$all = Request::input();
foreach ($all as $key => $value) {
if (!in_array($key, ['smtp_server', 'port', 'account', 'password', 'reg_verify', 'notice', 'task_remind_hours', 'task_remind_hours2'])) {
unset($all[$key]);
}
}
$setting = Base::setting('emailSetting', Base::newTrim($all));
} else {
$setting = Base::setting('emailSetting');
}
//
if ($type == 'all' || $type == 'save') {
User::auth('admin');
$setting['reg_invite'] = $setting['reg_invite'] ?: Base::generatePassword(8);
} else {
if (isset($setting['reg_invite'])) unset($setting['reg_invite']);
}
//
$setting['smtp_server'] = $setting['smtp_server'] ?: '';
$setting['port'] = $setting['port'] ?: '';
$setting['account'] = $setting['account'] ?: '';
$setting['password'] = $setting['password'] ?: '';
$setting['reg_verify'] = $setting['reg_verify'] ?: 'close';
$setting['notice'] = $setting['notice'] ?: 'open';
$setting['task_remind_hours'] = floatval($setting['task_remind_hours']) ?: 0;
$setting['task_remind_hours2'] = floatval($setting['task_remind_hours2']) ?: 0;
//
return Base::retSuccess('success', $setting ?: json_decode('{}'));
}
}

View File

@ -7,10 +7,12 @@ use App\Module\Base;
use App\Tasks\PushTask;
use Arr;
use Carbon\Carbon;
use Config;
use DB;
use Exception;
use Hhxsv5\LaravelS\Swoole\Task\Task;
use Illuminate\Database\Eloquent\SoftDeletes;
use Mail;
use Request;
/**
@ -1208,4 +1210,33 @@ class ProjectTask extends AbstractModel
//
return $task;
}
/**
* 预超期任务提醒
* @param $ownerIds
*/
public static function overdueRemindEmail($ownerIds)
{
$users = User::whereIn('userid', $ownerIds)->get();
if (!$users) {
throw new ApiException("ProjectTask::overdueRemindEmail--没有负责人");
}
Config::set("mail.mailers.smtp.host", Base::settingFind('emailSetting', 'smtp_server'));
Config::set("mail.mailers.smtp.port", Base::settingFind('emailSetting', 'port'));
Config::set("mail.mailers.smtp.username", Base::settingFind('emailSetting', 'account'));
Config::set("mail.mailers.smtp.password", Base::settingFind('emailSetting', 'password'));
foreach ($users as $user) {
/** @var User $user */
$email = $user->email;
try {
Mail::send('taskOverdueRemind', ['url' => 'https://www.baidu.com'], function ($m) use ($email) {
$m->from(Config::get("mail.mailers.smtp.username"), env('APP_NAME'));
$m->to($email);
$m->subject("过期任务提醒");
});
} catch (\Exception $e) {
\Log::error($email.'--邮箱发动报错:', [$e->getMessage()]);
}
}
}
}

View File

@ -2982,4 +2982,112 @@ class Base
},
$str);
}
//去重复
public static function assoc_unique($array, $keyid,$desc=true) {
if(empty($array)){
return false;
}
$array = array_values($array);
//倒叙排列数
if($desc)
{
$array =(new Self)->array_rsort($array,true);
}
//提取需要判断的项目变成一维数组
$a = (new Self)->array_tq($array,$keyid);
//去除一维数组重复值
$a = array_unique($a);
//提取二维数组项目值
foreach($array[0] AS $key=>$value)
{
$akey[] = $key;
}
//重新拼接二维数组
foreach($akey AS $key=>$value)
{
$b = (new Self)->array_tq($array,$value);
foreach($a AS $key2=>$value2)
{
$c[$key2][$value] = $b[$key2];
}
}
if($desc)
{
$c = (new Self)->array_rsort($c,true);
}
return $c;
}
//提取二维数组项目
public static function array_tq($array,$aval="")
{
foreach($array AS $key=>$value)
{
$result[] = $value[$aval];
}
return $result;
}
public static function array_rsort($arr,$isvalues=false)
{
if(is_array($arr)){
$flag = false;
//一维数组
if(count($arr) == count($arr,1)){
$flag = true;
$i = 0;
//转换成二维数组
foreach($arr AS $key=>$value){
$a[$i]["okey"] = $key;
$a[$i]["value"] = $value;
$i++;
}
$arr = $a;
}
//多维数组
else
{
//添加临时key值
foreach($arr AS $key=>$value){
$value["okey"] = $key;
$array[] = $value;
}
$arr = $array;
}
//倒叙并还原key值
$count = count($arr)-1;
for($i=0;$i<count($arr);$i++){
$b[$arr[$count]["okey"]] = $arr[$count];
$count--;
}
//重构一维数组
if($flag == true){
foreach($b AS $key=>$value){
if($isvalues){
$c[] = $value["value"];
}else{
$c[$value["okey"]] = $value["value"];
}
}
}
//多维数组去除临时key值
else
{
foreach($b AS $key=>$value) {
unset($value["okey"]);
if($isvalues){
$c[] = $value;
}else{
$c[$key] = $value;
}
}
}
return $c;
}
}
}

View File

@ -0,0 +1,64 @@
<?php
namespace App\Tasks;
use App\Models\ProjectTask;
use App\Models\ProjectTaskUser;
use App\Module\Base;
use Carbon\Carbon;
class OverdueRemindEmailTask extends AbstractTask
{
public function __construct()
{
//
}
public function start()
{
$setting = Base::setting('emailSetting');
if ($setting['notice'] === 'open') {
$hours = floatval($setting['task_remind_hours']);
$hours2 = floatval($setting['task_remind_hours2']);
$taskLists1 = [];
$taskLists2 = [];
$startTime = Carbon::now();
if ($hours > 0) {
$endTime = Carbon::now()->addHours($hours);
$taskLists1 = ProjectTask::whereNull('complete_at')
->where('end_at', '>=', $startTime)
->where('end_at', '<=', $endTime)
->whereNull('archived_at')
->take(100)
->get()
->toArray();
}
if ($hours2 > 0) {
$endTime2 = Carbon::now()->addHours($hours2);
$taskLists2 = ProjectTask::whereNull('complete_at')
->where('end_at', '>=', $startTime)
->where('end_at', '<=', $endTime2)
->whereNull('archived_at')
->take(100)
->get()
->toArray();
}
$taskLists = array_merge($taskLists1, $taskLists2);
$taskLists = Base::assoc_unique($taskLists, 'id');
$ownerIdsArr = [];
foreach ($taskLists as &$task) {
$ownerIds = ProjectTaskUser::whereTaskId($task['id'])->whereOwner(1)->pluck('userid')->toArray();
foreach ($ownerIds as $ownerId) {
$ownerIdsArr[] = $ownerId;
}
}
if (!empty($ownerIdsArr)) {
ProjectTask::overdueRemindEmail($ownerIdsArr);
}
}
}
}

View File

@ -36,15 +36,14 @@ return [
'mailers' => [
'smtp' => [
'transport' => 'smtp',
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
'port' => env('MAIL_PORT', 587),
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
'timeout' => null,
'auth_mode' => null,
'host' => 'smtp.qq.com',
'port' => 465,
'encryption' => 'ssl',
'username' => '302645122@qq.com',
'password' => 'ijncezxbmhrvbhab',
'timeout' => 15,
],
'ses' => [
'transport' => 'ses',
],
@ -70,6 +69,7 @@ return [
'array' => [
'transport' => 'array',
],
],
/*

View File

@ -0,0 +1,117 @@
<template>
<div class="setting-item submit">
<Form ref="formData" :model="formData" :rules="ruleData" label-width="auto" @submit.native.prevent>
<h3>{{ $L('邮箱服务器设置') }}</h3>
<FormItem :label="$L('SMTP服务器')" prop="smtp_server">
<Input v-model="formData.smtp_server"/>
</FormItem>
<FormItem :label="$L('端口')" prop="port">
<Input :maxlength="20" v-model="formData.port"/>
</FormItem>
<FormItem :label="$L('账号')" prop="account">
<Input :maxlength="20" v-model="formData.account"/>
</FormItem>
<FormItem :label="$L('密码')" prop="password">
<Input :maxlength="20" v-model="formData.password"/>
</FormItem>
<h3>{{ $L('邮件通知设置') }}</h3>
<FormItem :label="$L('开启注册验证')" prop="reg_verify">
<RadioGroup v-model="formData.reg_verify">
<Radio label="open">{{ $L('开启') }}</Radio>
<Radio label="close">{{ $L('关闭') }}</Radio>
</RadioGroup>
</FormItem>
<FormItem :label="$L('开启通知')" prop="notice">
<RadioGroup v-model="formData.notice">
<Radio label="open">{{ $L('开启') }}</Radio>
<Radio label="close">{{ $L('关闭') }}</Radio>
</RadioGroup>
</FormItem>
<template v-if="formData.notice == 'open'">
<FormItem :label="$L('任务提醒:')" prop="task_remind_hours">
<label>{{ $L('到期前') }}</label>
<InputNumber v-model="formData.task_remind_hours"/>
<label>{{ $L('小时') }}</label>
</FormItem>
<FormItem :label="$L('第二次任务提醒:')" prop="task_remind_hours2">
<label>{{ $L('到期前') }}</label>
<InputNumber v-model="formData.task_remind_hours2"/>
<label>{{ $L('小时') }}</label>
</FormItem>
</template>
</Form>
<div class="setting-footer">
<Button :loading="loadIng > 0" type="primary" @click="submitForm">{{ $L('提交') }}</Button>
<Button :loading="loadIng > 0" @click="resetForm" style="margin-left: 8px">{{ $L('重置') }}</Button>
</div>
</div>
</template>
<script>
export default {
name: "SystemEmailSetting",
data() {
return {
loadIng: 0,
formData: {
smtp_server: '',
port: '',
account: '',
password: '',
reg_verify: 'colse',
notice: 'open',
task_remind_hours: 0,
task_remind_hours2: 0,
},
ruleData: {},
}
},
mounted() {
this.systemSetting();
},
methods: {
submitForm() {
this.$refs.formData.validate((valid) => {
if (valid) {
this.systemSetting(true);
}
})
},
resetForm() {
this.formData = $A.cloneJSON(this.formDatum_bak);
},
formArchived(value) {
this.formData = {...this.formData, auto_archived: value};
},
systemSetting(save) {
this.loadIng++;
this.$store.dispatch("call", {
url: 'system/emailSetting?type=' + (save ? 'save' : 'all'),
data: this.formData,
}).then(({data}) => {
if (save) {
$A.messageSuccess('修改成功');
}
this.loadIng--;
this.formData = data;
this.formDatum_bak = $A.cloneJSON(this.formData);
}).catch(({msg}) => {
if (save) {
$A.modalError(msg);
}
this.loadIng--;
});
}
}
}
</script>
<style scoped>
</style>

View File

@ -10,6 +10,9 @@
<TabPane :label="$L('项目模板')" name="columnTemplate">
<SystemColumnTemplate/>
</TabPane>
<TabPane :label="$L('邮件设置')" name="emailSetting">
<SystemEmailSetting/>
</TabPane>
</Tabs>
</div>
</template>
@ -18,8 +21,10 @@
import SystemSetting from "./setting";
import SystemTaskPriority from "./taskPriority";
import SystemColumnTemplate from "./columnTemplate";
import SystemEmailSetting from "./emailSetting";
export default {
components: {SystemColumnTemplate, SystemTaskPriority, SystemSetting},
components: {SystemColumnTemplate, SystemTaskPriority, SystemSetting, SystemEmailSetting},
data() {
return {
tabAction: 'setting',

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
</head>
<body>
<p>用户您好, {{env('APP_NAME') }} 任务到期。</p>
<p>若需要重新设定账号密码,请点击下方链接:</p>
<div style="display: flex; justify-content: left;">
<a href="{{$url}}">{{$url}}</a>
</div>
<p>如果连接无法点击请复制此URL然后贴入到您浏览器的地址栏中。</p>
</body>
<body>