mirror of
https://github.com/kuaifan/dootask.git
synced 2026-02-28 04:40:37 +00:00
feat: 新增任务过期app推送提醒
This commit is contained in:
parent
6112d6950a
commit
b6614b0974
@ -217,7 +217,7 @@ class SystemController extends AbstractController
|
||||
*
|
||||
* @apiParam {String} type
|
||||
* - get: 获取(默认)
|
||||
* - save: 保存设置(参数:['push', 'ios_key', 'ios_secret', 'android_key', 'android_secret'])
|
||||
* - save: 保存设置(参数:['push', 'ios_key', 'ios_secret', 'android_key', 'android_secret', 'push_msg', 'push_task', 'task_start_minute', 'task_remind_hours', 'task_remind_hours2'])
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
* @apiSuccess {Object} data 返回数据
|
||||
@ -238,7 +238,12 @@ class SystemController extends AbstractController
|
||||
'ios_key',
|
||||
'ios_secret',
|
||||
'android_key',
|
||||
'android_secret'
|
||||
'android_secret',
|
||||
'push_msg',
|
||||
'push_task',
|
||||
'task_start_minute',
|
||||
'task_remind_hours',
|
||||
'task_remind_hours2'
|
||||
])) {
|
||||
unset($all[$key]);
|
||||
}
|
||||
@ -249,6 +254,11 @@ class SystemController extends AbstractController
|
||||
}
|
||||
//
|
||||
$setting['push'] = $setting['push'] ?: 'close';
|
||||
$setting['push_msg'] = $setting['push_msg'] ?: 'open';
|
||||
$setting['push_task'] = $setting['push_task'] ?: 'open';
|
||||
$setting['task_start_minute'] = intval($setting['task_start_minute']);
|
||||
$setting['task_remind_hours'] = floatval($setting['task_remind_hours']);
|
||||
$setting['task_remind_hours2'] = floatval($setting['task_remind_hours2']);
|
||||
//
|
||||
return Base::retSuccess('success', $setting ?: json_decode('{}'));
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ use App\Models\File;
|
||||
use App\Module\Base;
|
||||
use App\Module\Ihttp;
|
||||
use App\Module\RandomColor;
|
||||
use App\Tasks\AppPushTask;
|
||||
use App\Tasks\AutoArchivedTask;
|
||||
use App\Tasks\DeleteTmpTask;
|
||||
use App\Tasks\EmailNoticeTask;
|
||||
@ -180,6 +181,8 @@ class IndexController extends InvokeController
|
||||
Task::deliver(new AutoArchivedTask());
|
||||
// 邮件通知
|
||||
Task::deliver(new EmailNoticeTask());
|
||||
// App推送
|
||||
Task::deliver(new AppPushTask());
|
||||
// 删除过期的临时表数据
|
||||
Task::deliver(new DeleteTmpTask('wg_tmp_msgs', 1));
|
||||
Task::deliver(new DeleteTmpTask('tmp', 24));
|
||||
|
||||
42
app/Models/ProjectTaskPushLog.php
Normal file
42
app/Models/ProjectTaskPushLog.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
|
||||
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* App\Models\ProjectTaskPushLog
|
||||
*
|
||||
* @property int $id
|
||||
* @property int|null $userid 用户id
|
||||
* @property int|null $task_id 任务id
|
||||
* @property int|null $type 提醒类型:0 任务开始提醒,1 距离到期提醒,2到期超时提醒
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @property \Illuminate\Support\Carbon|null $deleted_at
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog newQuery()
|
||||
* @method static \Illuminate\Database\Query\Builder|ProjectTaskPushLog onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog whereDeletedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog whereEmail($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog whereIsSend($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog whereSendError($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog whereTaskId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog whereType($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog whereUserid($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|ProjectTaskPushLog withTrashed()
|
||||
* @method static \Illuminate\Database\Query\Builder|ProjectTaskPushLog withoutTrashed()
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class ProjectTaskPushLog extends AbstractModel
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
}
|
||||
132
app/Tasks/AppPushTask.php
Normal file
132
app/Tasks/AppPushTask.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tasks;
|
||||
|
||||
use App\Models\ProjectTask;
|
||||
use App\Models\ProjectTaskPushLog;
|
||||
use App\Models\User;
|
||||
use App\Module\Base;
|
||||
use Carbon\Carbon;
|
||||
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
||||
|
||||
@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
|
||||
|
||||
class AppPushTask extends AbstractTask
|
||||
{
|
||||
protected $endArray = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function start()
|
||||
{
|
||||
$setting = Base::setting('appPushSetting');
|
||||
$pushTask = $setting['push'] === 'open' && $setting['push_task'] !== 'close';
|
||||
if (!$pushTask) {
|
||||
return;
|
||||
}
|
||||
$start = intval($setting['task_start_minute']);
|
||||
$hours = floatval($setting['task_remind_hours']);
|
||||
$hours2 = floatval($setting['task_remind_hours2']);
|
||||
if ($start > -1) {
|
||||
ProjectTask::whereNull("complete_at")
|
||||
->whereNull("archived_at")
|
||||
->whereBetween("start_at", [
|
||||
Carbon::now()->subMinutes($start + 10),
|
||||
Carbon::now()->subMinutes($start)
|
||||
])->chunkById(100, function ($tasks) {
|
||||
/** @var ProjectTask $task */
|
||||
foreach ($tasks as $task) {
|
||||
$this->taskPush($task, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
if ($hours > -1) {
|
||||
ProjectTask::whereNull("complete_at")
|
||||
->whereNull("archived_at")
|
||||
->whereBetween("end_at", [
|
||||
Carbon::now()->addMinutes($hours * 60),
|
||||
Carbon::now()->addMinutes($hours * 60 + 10)
|
||||
])->chunkById(100, function ($tasks) {
|
||||
/** @var ProjectTask $task */
|
||||
foreach ($tasks as $task) {
|
||||
$this->taskPush($task, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
if ($hours2 > -1) {
|
||||
ProjectTask::whereNull("complete_at")
|
||||
->whereNull("archived_at")
|
||||
->whereBetween("end_at", [
|
||||
Carbon::now()->subMinutes($hours2 * 60 + 10),
|
||||
Carbon::now()->subMinutes($hours2 * 60)
|
||||
])->chunkById(100, function ($tasks) {
|
||||
/** @var ProjectTask $task */
|
||||
foreach ($tasks as $task) {
|
||||
$this->taskPush($task, 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function end()
|
||||
{
|
||||
foreach ($this->endArray as $task) {
|
||||
Task::deliver($task);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务过期前、超期后提醒
|
||||
* @param ProjectTask $task
|
||||
* @param int $type
|
||||
* @return void
|
||||
*/
|
||||
private function taskPush(ProjectTask $task, int $type)
|
||||
{
|
||||
$userids = $task->taskUser->where('owner', 1)->pluck('userid')->toArray();
|
||||
if (empty($userids)) {
|
||||
return;
|
||||
}
|
||||
$users = User::whereIn('userid', $userids)->whereNull('disable_at')->get();
|
||||
if (empty($users)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$setting = Base::setting('appPushSetting');
|
||||
|
||||
/** @var User $user */
|
||||
foreach ($users as $user) {
|
||||
$data = [
|
||||
'type' => $type,
|
||||
'userid' => $user->userid,
|
||||
'task_id' => $task->id,
|
||||
];
|
||||
$pushLog = ProjectTaskPushLog::where($data)->exists();
|
||||
if ($pushLog) {
|
||||
continue;
|
||||
}
|
||||
$title = match ($type) {
|
||||
1 => "任务提醒",
|
||||
2 => "任务过期提醒",
|
||||
default => "任务开始提醒",
|
||||
};
|
||||
$body = view('push.task', [
|
||||
'type' => str_replace([0, 1, 2], ['start', 'before', 'after'], $type),
|
||||
'user' => $user,
|
||||
'task' => $task,
|
||||
'setting' => $setting,
|
||||
])->render();
|
||||
$this->endArray[] = new PushUmengMsg($data['userid'], [
|
||||
'title' => $title,
|
||||
'body' => $body,
|
||||
'description' => "TID:{$data['task_id']}",
|
||||
'seconds' => 3600,
|
||||
'badge' => 1,
|
||||
]);
|
||||
ProjectTaskPushLog::createInstance($data)->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8,6 +8,7 @@ use App\Models\User;
|
||||
use App\Models\WebSocketDialog;
|
||||
use App\Models\WebSocketDialogMsg;
|
||||
use App\Models\WebSocketDialogMsgRead;
|
||||
use App\Module\Base;
|
||||
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
||||
use Request;
|
||||
|
||||
@ -139,7 +140,9 @@ class WebSocketDialogMsgTask extends AbstractTask
|
||||
];
|
||||
}
|
||||
// umeng推送app
|
||||
if (!$this->silence) {
|
||||
$setting = Base::setting('appPushSetting');
|
||||
$pushMsg = $setting['push'] === 'open' && $setting['push_msg'] !== 'close';
|
||||
if (!$this->silence && $pushMsg) {
|
||||
$umengUserid = $array;
|
||||
if (isset($umengUserid[$msg->userid])) {
|
||||
unset($umengUserid[$msg->userid]);
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateProjectTaskPushLogsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('project_task_push_logs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->bigInteger('userid')->nullable()->default(0)->comment('用户id');
|
||||
$table->integer('task_id')->nullable()->default(0)->comment('任务id');
|
||||
$table->tinyInteger('type')->nullable()->default(0)->comment('提醒类型:0 任务开始提醒,1 距离到期提醒,2到期超时提醒');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('project_task_push_logs');
|
||||
}
|
||||
}
|
||||
@ -10,20 +10,54 @@
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<template v-if="formData.push === 'open'">
|
||||
<Divider orientation="left">iOS</Divider>
|
||||
<Divider orientation="left">iOS {{$L('参数配置')}}</Divider>
|
||||
<FormItem label="Appkey" prop="ios_appkey">
|
||||
<Input :maxlength="255" v-model="formData.ios_key"/>
|
||||
</FormItem>
|
||||
<FormItem label="App Master Secret" prop="secret">
|
||||
<Input :maxlength="255" v-model="formData.ios_secret" type="password"/>
|
||||
</FormItem>
|
||||
<Divider orientation="left">Android</Divider>
|
||||
<Divider orientation="left">Android {{$L('参数配置')}}</Divider>
|
||||
<FormItem label="Appkey" prop="android_appkey">
|
||||
<Input :maxlength="255" v-model="formData.android_key"/>
|
||||
</FormItem>
|
||||
<FormItem label="App Master Secret" prop="secret">
|
||||
<Input :maxlength="255" v-model="formData.android_secret" type="password"/>
|
||||
</FormItem>
|
||||
<Divider orientation="left">{{$L('推送内容')}}</Divider>
|
||||
<FormItem :label="$L('消息提醒')" prop="push_msg">
|
||||
<RadioGroup v-model="formData.push_msg">
|
||||
<Radio label="open">{{ $L('开启') }}</Radio>
|
||||
<Radio label="close">{{ $L('关闭') }}</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('任务提醒')" prop="push_task">
|
||||
<RadioGroup v-model="formData.push_task">
|
||||
<Radio label="open">{{ $L('开启') }}</Radio>
|
||||
<Radio label="close">{{ $L('关闭') }}</Radio>
|
||||
</RadioGroup>
|
||||
<Form v-if="formData.push_task == 'open'" @submit.native.prevent>
|
||||
<FormItem :label="$L('任务开始')" prop="task_start_minute">
|
||||
<div class="input-number-box">
|
||||
<InputNumber v-model="formData.task_start_minute" :min="0" :step="1"/>
|
||||
<label>{{ $L('分钟') }}(m)</label>
|
||||
</div>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('距离到期')" prop="task_remind_hours">
|
||||
<div class="input-number-box">
|
||||
<InputNumber v-model="formData.task_remind_hours" :min="0" :step="0.5" @on-change="hoursChange($event, 'task_remind_hours')"/>
|
||||
<label>{{ $L('小时') }}(h)</label>
|
||||
</div>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('到期超时')" prop="task_remind_hours2">
|
||||
<div class="input-number-box">
|
||||
<InputNumber v-model="formData.task_remind_hours2" :min="0" :step="0.5" @on-change="hoursChange($event, 'task_remind_hours2')"/>
|
||||
<label>{{ $L('小时') }}(h)</label>
|
||||
</div>
|
||||
</FormItem>
|
||||
<div class="form-tip">{{$L('填写-1则不通知,误差±10分钟')}}</div>
|
||||
</Form>
|
||||
</FormItem>
|
||||
</template>
|
||||
</div>
|
||||
</Form>
|
||||
@ -86,7 +120,17 @@ export default {
|
||||
}).finally(_ => {
|
||||
this.loadIng--;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
hoursChange(e, key) {
|
||||
let newNum = e * 10;
|
||||
if (newNum % 5 !== 0) {
|
||||
setTimeout(() => {
|
||||
this.$set(this.formData, key, Math.round(e))
|
||||
})
|
||||
$A.messageError('任务提醒只能是0.5的倍数');
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
7
resources/views/push/task.blade.php
Executable file
7
resources/views/push/task.blade.php
Executable file
@ -0,0 +1,7 @@
|
||||
@if ($type === 'before')
|
||||
您有一个任务【{{ $task->name }}】还有{{ $setting['task_remind_hours'] }}小时即将超时,请及时处理。
|
||||
@elseif ($type === 'after')
|
||||
您的任务【{{ $task->name }}】已经超时{{ $setting['task_remind_hours2'] }}小时,请及时处理。
|
||||
@else
|
||||
您有一个新任务【{{ $task->name }}】已开始,请及时处理。
|
||||
@endif
|
||||
Loading…
x
Reference in New Issue
Block a user