SaveController.class.php 13.8 KB
<?php
/**
 * Created by PhpStorm.
 * User: zhonglei
 * Date: 17/7/25
 * Time: 11:57
 */
namespace Apicp\Controller\Customtask;

use Com\PackageValidate;
use Common\Common\AttachOperation;
use Common\Common\Constant;
use Common\Common\TaskHelper;
use Common\Model\CustomtaskModel;
use Common\Service\CustomtaskContentService;
use Common\Service\CustomtaskCronService;
use Common\Service\CustomtaskRightService;
use Common\Service\CustomtaskService;

class SaveController extends \Apicp\Controller\AbstractController
{
    /**
     * Save
     * @author tangxingguo
     * @desc 保存常规任务接口
     * @param Int customtask_id 常规任务ID(新增为0)
     * @param String task_name:true 常规任务名(max:20)
     * @param Int start_time:true 任务开始时间
     * @param Int end_time:true 任务结束时间
     * @param Array right:true 权限数据
     * @param Int right.is_all 是否全公司(1=否;2=是)
     * @param Array right.uids 人员ID
     * @param Array right.dp_ids 部门ID
     * @param Array right.tag_ids 标签ID
     * @param Array right.job_ids 岗位ID
     * @param Array right.role_ids 角色ID
     * @param String description 任务描述
     * @param Array content:true 任务内容
     * @param String content[].app 应用(news=新闻;course=课程;exam=考试;activity=活动;questionnaire=调研)
     * @param Int content[].app_data_id 数据ID
     * @param String content[].title 标题
     * @param Int content[].order 顺序
     * @param Int is_reward:true 开启激励(1=不开启;2=开启)
     * @param Array reward 激励数据(开启激励时必要)
     * @param Array reward.type 激励类型(1=勋章;2=积分)
     * @param Array reward.medal_id 勋章ID
     * @param Array reward.integral 积分值
     * @param Int is_notice:true 发布消息提醒(1=不提醒;2=提醒)
     * @param Int task_type:true 任务状态(1=草稿;2=发布)
     * @param Int is_auto_remind:true 是否自动提醒(1=否;2=是)
     * @param Int interval_time 提醒间隔时间(单位:小时)
     */
    public function Index_post()
    {
        // 验证规则
        $rules = [
            'customtask_id' => 'require|integer',
            'task_name' => 'require|max:20',
            'start_time' => 'require|integer',
            'end_time' => 'require|integer',
            'right' => 'require|array',
            'content' => 'require|array',
            'reward' => 'array',
            'is_reward' => 'require|integer|in:1,2',
            'is_notice' => 'require|integer|in:1,2',
            'task_type' => 'require|integer|in:1,2',
            'is_auto_remind' => 'require|integer|in:1,2',
            'interval_time' => 'integer',
        ];

        // 验证数据
        $validate = new PackageValidate($rules, [], array_keys($rules));
        $postData = $validate->postData;
        $postData['description'] = I('post.description', '', 'trim');

        // 编辑任务,必须任务状态为草稿
        $customtaskServ = new CustomtaskService();
        if ($postData['customtask_id'] > 0) {
            $customtaskInfo = $customtaskServ->get($postData['customtask_id']);
            if (empty($customtaskInfo)) {
                E('_ERR_CUSTOMTASK_NOT_FOUND');
            }
            if (!in_array($customtaskInfo['task_status'], [Constant::CUSTOMTASK_STATUS_DRAFT, Constant::CUSTOMTASK_STATUS_UNSTART])) {
                $errorMsg = [
                    Constant::CUSTOMTASK_STATUS_PROCESS => '任务已发布!',
                    Constant::CUSTOMTASK_STATUS_END => '任务已结束!',
                    Constant::CUSTOMTASK_STATUS_STOP => '任务已终止!',
                ];
                E($errorMsg[$customtaskInfo['task_status']]);
            }
        }

        // 数据格式化
        list($sqlData, $right, $contents) = $this->_formatPostData($postData);

        // 获取任务描述中的附件
        $attach_serv = new AttachOperation();
        $attach_ids = $attach_serv->match_at_ids($sqlData['description']);

        // 保存任务草稿
        if ($postData['customtask_id'] > 0) {
            $customtaskId = $postData['customtask_id'];
            $customtaskServ->update($customtaskId, $sqlData);

            // 更新附件操作
            $attach_serv->update_attach(
                APP_DIR,
                'customtask',
                $customtaskId,
                ['attach_ids' => $attach_ids]
            );
        } else {
            $customtaskId = $customtaskServ->insert($sqlData);

            // 新增附件操作
            $attach_serv->insert_attach(
                APP_DIR,
                'customtask',
                $customtaskId,
                ['attach_ids' => $attach_ids]
            );
        }

        // 保存任务内容
        $this->_saveContents($contents, $customtaskId);

        // 保存权限
        $rightServ = new CustomtaskRightService();
        $rightServ->saveData(['customtask_id' => $customtaskId], $right);

        // 检查任务内容是否被删除
        $ContentServ = new CustomtaskContentService();
        list($dels) = $ContentServ->contentStatus($customtaskId);
        if (!empty($dels)) {
            // 修改状态为草稿
            $customtaskServ->update($customtaskId, ['task_status' => Constant::CUSTOMTASK_STATUS_DRAFT]);
            // 返回被删除项
            $titles = implode(',', array_column($dels, 'title'));
            E($titles . '被删除');
        }

        $cronServ = new CustomtaskCronService();
        $customtask = $customtaskServ->get($customtaskId);
        if ($postData['task_type'] == Constant::CUSTOMTASK_SAVE_SEND) {
            $startTime = rgmdate($postData['start_time'], 'Y-m-d H:i');
            $nowTime = rgmdate(MILLI_TIME, 'Y-m-d H:i');
            if ($startTime <= $nowTime) {
                // 任任务开始时间小于当前时间=立即发布
                $taskHelper = new TaskHelper();
                $taskHelper->sendCustomtask($customtaskId);
            } elseif ($startTime > $nowTime) {
                // 任务开始时间大于当前时间=创建发布计划任务
                $cronServ->sendCustomtask($customtask);
            }
        }

        // 终止任务
        $cronServ->stopCustomtask($customtask);
    }

    /**
     * @desc 格式化数据
     * @author tangxingguo
     * @param array $postData 用户提交的数据
     * @return array
     */
    private function _formatPostData($postData)
    {
        $user = $this->_login->user;
        $sqlData = [
            'task_name' => $postData['task_name'],
            'start_time' => $postData['start_time'],
            'end_time' => $postData['end_time'],
            'description' => $postData['description'],
            'is_notice' => $postData['is_notice'],
            'is_reward' => $postData['is_reward'],
            'ea_id' => $user['eaId'],
            'ea_name' => $user['eaRealname'],
            'update_time' => MILLI_TIME,
            'is_auto_remind' => isset($postData['is_auto_remind']) ? $postData['is_auto_remind'] :
                CustomtaskModel::IS_AUTO_REMIND_FALSE,
            'interval_time' => isset($postData['interval_time']) ? $postData['interval_time'] : 0,
        ];

        // 结束时间需大于当前时间,结束时间需大于开始时间
        if ($postData['end_time'] <= MILLI_TIME || $postData['start_time'] >= $postData['end_time']) {
            E('_ERR_DAILYTASK_TIME_SCOPE_ERROR');
        }

        // 权限数据校验
        $rightServ = new CustomtaskRightService();
        $right = $rightServ->formatPostData($postData['right']);
        if (empty($right)) {
            E('_ERR_DAILYTASK_RIGHT_IS_EMPTY');
        }
        // 参与人数
        $uids = $rightServ->getUidsByRight($right);
        $sqlData['user_total'] = count($uids);
        $right = $postData['right'];

        // 任务内容校验
        foreach ($postData['content'] as $k => $v) {
            // 检查字段是否缺失
            if (!isset($v['app'], $v['app_data_id'], $v['title'], $v['order'])) {
                E('_ERR_DAILYTASK_CONTENT_KEY_DEFECT');
            }
        }

        // 验证间隔时间
        if ($postData['is_auto_remind'] == Constant::CUSTOMTASK_AUTO_REMIND_TRUE && $postData['interval_time'] <= 0) {

            E('_ERR_INTERVAL_TIME_ERROR');
        }

        // 过滤字段
        $keys = ['app', 'app_data_id', 'title', 'order'];
        $contents = array_intersect_key_reserved($postData['content'], $keys);


        // 激励校验
        if ($postData['is_reward'] == Constant::CUSTOMTASK_REWARD_OPEN) {
            $types = [Constant::REWARD_TYPE_MEDAL, Constant::REWARD_TYPE_INTEGRAL];
            if (!isset($postData['reward']['type']) && !in_array($postData['reward']['type'], $types)) {
                // 缺少数据
                E('_ERR_DAILYTASK_REWARD_FORMAT_ERROR');
            } elseif ($postData['reward']['type'] == Constant::REWARD_TYPE_INTEGRAL) {
                // 积分值校验
                if (!isset($postData['reward']['integral']) || strlen($postData['reward']['integral']) > 6 || $postData['reward']['integral'] < 1) {
                    E('_ERR_DAILYTASK_REWARD_INTEGRAL_ERROR');
                }
            } elseif ($postData['reward']['type'] == Constant::REWARD_TYPE_MEDAL && !isset($postData['reward']['medal_id'])) {
                // 勋章
                E('_ERR_DAILYTASK_MEDAL_ID_IS_EMPTY');
            }
            $sqlData['reward_setting'] = serialize($postData['reward']);
        } else {
            // 编辑的时候,如果激励关闭,清空激励设置
            $sqlData['reward_setting'] = '';
        }

        // 任务状态
        if ($postData['task_type'] == Constant::CUSTOMTASK_SAVE_DRAFT) {
            // 草稿
            $sqlData['task_status'] = Constant::CUSTOMTASK_STATUS_DRAFT;
        } elseif ($postData['task_type'] == Constant::CUSTOMTASK_SAVE_SEND) {
            // 未开始
            $sqlData['task_status'] = Constant::CUSTOMTASK_STATUS_UNSTART;
        }

        return [$sqlData, $right, $contents];
    }

    /**
     * @desc 保存任务内容
     * @author tangxingguo
     * @param array $postContents 用户提交的任务内容
     * @param $customtaskId 任务ID
     */
    private function _saveContents($postContents, $customtaskId)
    {
        // 添加任务ID字段
        foreach ($postContents as $k => $v) {
            $postContents[$k]['customtask_id'] = $customtaskId;
        }

        // 数据库数据
        $contentServ = new CustomtaskContentService();
        $dbContents = $contentServ->list_by_conds(['customtask_id' => $customtaskId]);
        if (empty($dbContents)) {
            // 数据库内没有历史数据,全部添加
            $contentServ->insert_all($postContents);
            return;
        }

        // 数据分组
        $dbGroup = $this->groupDataId($dbContents);
        $postGroup = $this->groupDataId($postContents);

        // 应用集合
        $apps = [
            Constant::APP_NEWS,
            Constant::APP_COURSE,
            Constant::APP_EXAM,
            Constant::APP_ACTIVITY,
            Constant::APP_QUESTIONNAIRE,
        ];
        // 数据对比
        foreach ($apps as $v) {
            $dbGroup[$v] = isset($dbGroup[$v]) ? $dbGroup[$v] : [];
            $postGroup[$v] = isset($postGroup[$v]) ? $postGroup[$v] : [];
            // 要删除的数据
            if (!empty(array_diff($dbGroup[$v], $postGroup[$v]))) {
                $delDataIds[$v] = array_diff($dbGroup[$v], $postGroup[$v]);
            }
            // 要新增的数据
            if (!empty(array_diff($postGroup[$v], $dbGroup[$v]))) {
                $addDataIds[$v] = array_diff($postGroup[$v], $dbGroup[$v]);
            }
        }

        // 删除数据
        if (!empty($delDataIds)) {
            foreach ($delDataIds as $app => $ids) {
                foreach ($ids as $id) {
                    $contentServ->delete_by_conds([
                        'app_data_id' => $id,
                        'app' => $app,
                        'customtask_id' => $customtaskId,
                    ]);
                }
            }
        }
        // 插入数据
        if (!empty($addDataIds)) {
            $addContents = [];
            foreach ($addDataIds as $app => $ids) {
                foreach ($ids as $id) {
                    foreach ($postContents as $v) {
                        if ($v['app'] == $app && $v['app_data_id'] == $id) {
                            $addContents[] = $v;
                            break;
                        }
                    }
                }

            }
            if (!empty($addContents)) {
                $contentServ->insert_all($addContents);
            }
        }
    }

    /**
     * @desc 将任务内容数据按app分组
     * @author tangxingguo
     * @param array $contentList 任务内容数据
     * @return array|bool
     */
    private function groupDataId($contentList)
    {
        if (empty($contentList) || !is_array($contentList)) {
            return false;
        }
        $dataIds = [];
        // 分组
        foreach ($contentList as $v) {
            switch ($v['app']) {
                case Constant::APP_NEWS:
                    $dataIds[Constant::APP_NEWS][] = $v['app_data_id'];
                    break;
                case Constant::APP_COURSE:
                    $dataIds[Constant::APP_COURSE][] = $v['app_data_id'];
                    break;
                case Constant::APP_EXAM:
                    $dataIds[Constant::APP_EXAM][] = $v['app_data_id'];
                    break;
                case Constant::APP_ACTIVITY:
                    $dataIds[Constant::APP_ACTIVITY][] = $v['app_data_id'];
                    break;
                case Constant::APP_QUESTIONNAIRE:
                    $dataIds[Constant::APP_QUESTIONNAIRE][] = $v['app_data_id'];
                    break;
            }
        }
        return $dataIds;
    }
}