CRMEB_PRO_M/app/services/system/timer/SystemTimerServices.php

356 lines
13 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\services\system\timer;
use app\services\BaseServices;
use crmeb\exceptions\AdminException;
use app\dao\system\timer\SystemTimerDao;
/**
* 定时器service
* Class SystemTimerServices
* @package app\services\system\timer
* @mixin SystemTimerDao
*/
class SystemTimerServices extends BaseServices
{
/**
* 定时任务名称及标识
* @var string[]
*/
protected $taskName = [
'auto_cancel' => '自动取消订单',
'auto_take' => '自动确认收货',
'auto_comment' => '自动好评',
'auto_clear_integral' => '自动清空用户积分',
'auto_off_user_svip' => '自动取消用户到期svip',
'auto_agent' => '自动解绑上下级',
'auto_clear_poster' => '自动清除昨日海报',
'auto_live' => '自动更新直播产品状态和直播间状态',
'auto_pink' => '拼团状态自动更新',
'auto_show' => '自动上下架商品',
'auto_channel' => '渠道码定时任务',
'auto_moment' => '定时创建发送朋友圈任务',
'auto_group_task' => '定时发送群发任务',
'auto_seckill' => '定时清理秒杀数据过期的数据缓存',
'rebate_points_orders' => '未支付积分订单退积分',
'code_not_operating' => '桌码长期未操作取消桌码记录',
'collate_not_operating' => '拼单长期未操作取消拼单记录',
'reminder_unverified_remind' => '次卡商品未核销短信提醒',
'sign_remind_time' => '用户签到提醒'
];
/**
* SystemTimerServices constructor.
* @param SystemTimerDao $dao
*/
public function __construct(SystemTimerDao $dao)
{
$this->dao = $dao;
}
/**
* 获取定时任务名称
* @return array|string[]
*/
public function getTasKName()
{
return $this->taskName;
}
/**
* 获取定时器列表
* @param array $where
* @return array
*/
public function getTimerList(array $where)
{
[$page, $limit] = $this->getPageValue();
$list = $this->dao->getList($where, $page, $limit);
foreach ($list as $key => &$item) {
$last_execution_time = $this->dao->cacheHander()->get($item['mark']);
$item['last_execution_time'] = $last_execution_time > 0 ? date('Y-m-d H:i:s', $last_execution_time) : '';
switch ($item['type']) {
case 1:
$item['execution_cycle'] = '每隔' . $item['cycle'] . '分钟执行';
break;
case 2:
$arr = explode('/', $item['cycle']);
$item['execution_cycle'] = '每' . $arr[0] . '小时, 第' . $arr[1] . '分钟 执行';
break;
case 3:
$item['execution_cycle'] = '每小时, 第' . $item['cycle'] . '分钟执行';
break;
case 4:
$arr = explode('/', $item['cycle']);
$item['execution_cycle'] = '每天, ' . $arr[0] . '点' . $arr[1] . '分 执行';
break;
case 5:
$arr = explode('/', $item['cycle']);
$item['execution_cycle'] = '每隔' . $arr[0] . '天, ' . $arr[1] . '点' . $arr[2] . '分 执行';
break;
case 6:
$arr = explode('/', $item['cycle']);
$item['execution_cycle'] = '每周' . $arr[0] . ', ' . $arr[1] . '点' . $arr[2] . '分执行';
break;
case 7:
$arr = explode('/', $item['cycle']);
$item['execution_cycle'] = '每月' . $arr[0] . '日 ' . $arr[1] . '点' . $arr[2] . '分执行';
break;
case 8:
$arr = explode('/', $item['cycle']);
$item['execution_cycle'] = '每年' . $arr[0] . '月' . $arr[1] . '日 ' . $arr[2] . '点' . $arr[3] . '分执行';
break;
default:
$item['execution_cycle'] = '周期有误!';
break;
}
}
$count = $this->dao->count($where);
return compact('list', 'count');
}
/**设置或更新定时任务缓存
* @return void
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function setAllTimerCache()
{
$where['is_del'] = 0;
$list = $this->dao->getList($where, 0, 0);
foreach ($list as $key => &$value) {
if (!$value['update_execution_time']) {
$update_time = time();
$value['update_execution_time'] = $update_time;
$this->dao->update($value['id'], ['update_execution_time' => $update_time]);
}
}
$this->dao->cacheCreate($list);
}
/**
* 设置定时器状态
* @param $id
* @param $is_show
*/
public function setShow(int $id, int $is_show)
{
$this->dao->update($id, ['is_open' => $is_show]);
}
/**
* 删除定时器
* @param string $id
*/
public function del(int $id)
{
if (!$id) throw new AdminException('请选择要删除的定时任务');
$this->dao->delete((int)$id);
}
/**
* 新增数据
* @param $data
*/
public function createData($data)
{
if ($this->dao->be(['mark' => $data['mark'], 'name' => $data['name']])) {
throw new AdminException('该定时任务已经存在');
}
$data['add_time'] = time();
$data['update_execution_time'] = time();
$res = $this->dao->save($data);
if (!$res) throw new AdminException('添加失败');
return $res;
}
/**
* 保存修改数据
* @param $id
* @param $data
*/
public function editData($id, $data)
{
if (!$this->dao->be(['id' => $id])) {
throw new AdminException('该定时任务不存在');
}
$data['update_execution_time'] = time();
$res = $this->dao->update($id, $data);
if (!$res) throw new AdminException('修改失败');
return $res;
}
/**更新缓存
* @param $id
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function updateOneTimerCache($id)
{
if (!$id) throw new AdminException('参数错误');
$timer = $this->dao->get($id);
$this->dao->cacheUpdate($timer->toArray());
return true;
}
/**删除缓存
* @param $id
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function delOneTimerCache($id)
{
if (!$id) throw new AdminException('参数错误');
$this->dao->cacheDelById($id);
return true;
}
/**获取单条定时器数据
* @param $id
* @return array
*/
public function getOneTimer($id)
{
if (!$id) throw new AdminException('请选择要删除的定时任务');
$timer = $this->dao->get($id);
if (!$timer) throw new AdminException('该定时任务不存在');
return $timer->toArray();
}
/**获取下次执行时间
* @param $type
* @param $cycle
* @param $time
* @param $start_time
* @return array
*/
public function getTimerCycleTime($type, $cycle, $time, $start_time = 0)
{
if (!$time) $time = time();
switch ($type) {
case 1: // N分钟
$cycle_time = 60 * $cycle;
$i = $time - $start_time;
$more = $i % $cycle_time;
if ($more == 0) {
$cycle_time = $time;
} else {
$cycle_time = $time - $more + $cycle_time;
}
break;
case 2: //N小时
$arr = explode('/', $cycle);
$todaystart = strtotime(date('Y-m-d H' . ':00:00', $time));
$start_time = strtotime(date('Y-m-d H' . ':00:00', $start_time));
$h = ($todaystart - $start_time) / 3600;
$h = floor($h);
$more = $h % $arr[0];
if ($more == 0) {
$cycle_time = 60 * $arr[1];
$cycle_time = $todaystart + $cycle_time;
if ($cycle_time <= $time) {
$cycle_time = 60 * 60 * $arr[0] + 60 * $arr[1];
}
} else {
$sh = $arr[0] - $more;
$cycle_time = 60 * 60 * $sh + 60 * $arr[1];
}
$cycle_time = $todaystart + $cycle_time;
break;
case 3: //每小时
$cycle_time = strtotime(date('Y-m-d ' . 'H:' . $cycle . ':00', $time));
break;
case 4: //每天
$arr = explode('/', $cycle);
$cycle_time = strtotime(date('Y-m-d ' . $arr[0] . ':' . $arr[1] . ':00', $time));
break;
case 5: //N天
$arr = explode('/', $cycle);
$todaystart = strtotime(date('Y-m-d ' . '00:00:00', $time));
$start_time = strtotime(date('Y-m-d ' . '00:00:00', $start_time));
$d = ($todaystart - $start_time) / 86400;
$d = floor($d);
$more = $d % $arr[0];
if ($more == 0) {
$cycle_time = 60 * 60 * $arr[1] + 60 * $arr[2];
$cycle_time = $todaystart + $cycle_time;
if ($cycle_time < $time) {
$cycle_time = 60 * 60 * 24 * $more + 60 * 60 * $arr[1] + 60 * $arr[2];
}
} else {
$sd = $arr[0] - $more;
$cycle_time = 60 * 60 * 24 * $sd + 60 * 60 * $arr[1] + 60 * $arr[2];
}
$cycle_time = $todaystart + $cycle_time;
break;
case 6: //每星期
$arr = explode('/', $cycle);
$todaystart = strtotime(date('Y-m-d ' . '00:00:00', $time));
$w = date("w");
if ($w > $arr[0]) {
$d = 7 - $w + $arr[0];
$cycle_time = $todaystart + 60 * 60 * 24 * $d + 60 * 60 * $arr[1] + 60 * $arr[2];
} else if ($w == $arr[0]) {
$to_time = 60 * 60 * $arr[1] + 60 * $arr[2];
$to_time = $todaystart + $to_time;
if ($time > $to_time) {
$d = 7 - $w + $arr[0];
$cycle_time = $todaystart + 60 * 60 * 24 * $d + 60 * 60 * $arr[1] + 60 * $arr[2];
} else {
$cycle_time = $to_time;
}
} else {
$d = $arr[0] - $w;
$cycle_time = $todaystart + 60 * 60 * 24 * $d + 60 * 60 * $arr[1] + 60 * $arr[2];
}
break;
case 7: //每月
$arr = explode('/', $cycle);
$current_d = date("d");
$firstDate = date('Y-m-01', $time);
$max_d = date('d', strtotime("$firstDate + 1 month -1 day"));
$todaystart = strtotime(date('Y-m-d ' . '00:00:00', $time));
if ($current_d > $arr[0]) {
$d = $max_d - $current_d + $arr[0];
$cycle_time = $todaystart + 60 * 60 * 24 * $d + 60 * 60 * $arr[1] + 60 * $arr[2];
} elseif ($current_d == $arr[0]) {
$to_time = 60 * 60 * $arr[1] + 60 * $arr[2];
$to_time = $todaystart + $to_time;
if ($time > $to_time) {
$d = $max_d - $current_d + $arr[0];
$cycle_time = $todaystart + 60 * 60 * 24 * $d + 60 * 60 * $arr[1] + 60 * $arr[2];
} else {
$cycle_time = $to_time;
}
} else {
$d = $arr[0] - $current_d;
$cycle_time = $todaystart + 60 * 60 * 24 * $d + 60 * 60 * $arr[1] + 60 * $arr[2];
}
break;
case 8: //每年
$arr = explode('/', $cycle);
$cycle_time = strtotime(date('Y-' . $arr[0] . '-' . $arr[1] . ' ' . $arr[2] . ':' . $arr[3] . ':00', $time));
break;
default:
$cycle_time = 0;
break;
}
return ['cycle_time' => $cycle_time];
}
}