mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-12 11:19:56 +00:00
feat: 管理员系统设置新增:新增邮件设置
This commit is contained in:
parent
ab388f1ef5
commit
cf7e7c1a06
@ -500,4 +500,58 @@ class SystemController extends AbstractController
|
|||||||
'home_footer' => Base::settingFind('system', 'home_footer')
|
'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('{}'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,10 +7,12 @@ use App\Module\Base;
|
|||||||
use App\Tasks\PushTask;
|
use App\Tasks\PushTask;
|
||||||
use Arr;
|
use Arr;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use Config;
|
||||||
use DB;
|
use DB;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
use Mail;
|
||||||
use Request;
|
use Request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1208,4 +1210,33 @@ class ProjectTask extends AbstractModel
|
|||||||
//
|
//
|
||||||
return $task;
|
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()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2982,4 +2982,112 @@ class Base
|
|||||||
},
|
},
|
||||||
$str);
|
$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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
64
app/Tasks/OverdueRemindEmailTask.php
Normal file
64
app/Tasks/OverdueRemindEmailTask.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -36,15 +36,14 @@ return [
|
|||||||
'mailers' => [
|
'mailers' => [
|
||||||
'smtp' => [
|
'smtp' => [
|
||||||
'transport' => 'smtp',
|
'transport' => 'smtp',
|
||||||
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
|
'host' => 'smtp.qq.com',
|
||||||
'port' => env('MAIL_PORT', 587),
|
'port' => 465,
|
||||||
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
|
'encryption' => 'ssl',
|
||||||
'username' => env('MAIL_USERNAME'),
|
'username' => '302645122@qq.com',
|
||||||
'password' => env('MAIL_PASSWORD'),
|
'password' => 'ijncezxbmhrvbhab',
|
||||||
'timeout' => null,
|
'timeout' => 15,
|
||||||
'auth_mode' => null,
|
|
||||||
],
|
],
|
||||||
|
|
||||||
'ses' => [
|
'ses' => [
|
||||||
'transport' => 'ses',
|
'transport' => 'ses',
|
||||||
],
|
],
|
||||||
@ -70,6 +69,7 @@ return [
|
|||||||
'array' => [
|
'array' => [
|
||||||
'transport' => 'array',
|
'transport' => 'array',
|
||||||
],
|
],
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
117
resources/assets/js/pages/manage/setting/system/emailSetting.vue
Normal file
117
resources/assets/js/pages/manage/setting/system/emailSetting.vue
Normal 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>
|
||||||
@ -10,6 +10,9 @@
|
|||||||
<TabPane :label="$L('项目模板')" name="columnTemplate">
|
<TabPane :label="$L('项目模板')" name="columnTemplate">
|
||||||
<SystemColumnTemplate/>
|
<SystemColumnTemplate/>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
|
<TabPane :label="$L('邮件设置')" name="emailSetting">
|
||||||
|
<SystemEmailSetting/>
|
||||||
|
</TabPane>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -18,8 +21,10 @@
|
|||||||
import SystemSetting from "./setting";
|
import SystemSetting from "./setting";
|
||||||
import SystemTaskPriority from "./taskPriority";
|
import SystemTaskPriority from "./taskPriority";
|
||||||
import SystemColumnTemplate from "./columnTemplate";
|
import SystemColumnTemplate from "./columnTemplate";
|
||||||
|
import SystemEmailSetting from "./emailSetting";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {SystemColumnTemplate, SystemTaskPriority, SystemSetting},
|
components: {SystemColumnTemplate, SystemTaskPriority, SystemSetting, SystemEmailSetting},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tabAction: 'setting',
|
tabAction: 'setting',
|
||||||
|
|||||||
17
resources/views/taskOverdueRemind.blade.php
Normal file
17
resources/views/taskOverdueRemind.blade.php
Normal 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>
|
||||||
Loading…
x
Reference in New Issue
Block a user