徐总多门店
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
jiuhaoshenghuo/app/services/work/WorkGroupTemplateServices.php

334 lines
12 KiB

2 months ago
<?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\work;
use app\dao\work\WorkGroupTemplateDao;
use app\jobs\work\WorkGroupMsgJob;
use app\services\BaseServices;
use crmeb\services\wechat\WechatResponse;
use crmeb\traits\service\ContactWayQrCode;
use crmeb\traits\ServicesTrait;
use think\exception\ValidateException;
use think\facade\Event;
use think\facade\Log;
/**
* 企业微信群发模板
* Class WorkGroupTemplateServices
* @package app\services\work
* @mixin WorkGroupTemplateDao
*/
class WorkGroupTemplateServices extends BaseServices
{
use ContactWayQrCode, ServicesTrait;
/**
* WorkGroupTemplateServices constructor.
* @param WorkGroupTemplateDao $dao
*/
public function __construct(WorkGroupTemplateDao $dao)
{
$this->dao = $dao;
}
/**
* 获取群聊模板列表
* @param array $where
* @return array
*/
public function getGroupTemplate(array $where)
{
[$page, $limit] = $this->getPageValue();
$list = $this->dao->getDataList($where, ['*'], $page, $limit, 'create_time', ['msgIds']);
/** @var WorkGroupMsgTaskServices $taskService */
$taskService = app()->make(WorkGroupMsgTaskServices::class);
foreach ($list as &$item) {
$item['user_count'] = $item['unuser_count'] = $item['external_user_count'] = $item['external_unuser_count'] = 0;
if (!empty($item['msgIds'])) {
$msgIds = [];
foreach ($item['msgIds'] as $value) {
$msgIds[] = $value['msg_id'];
if ($value['msg_id']) {
WorkGroupMsgJob::dispatchDo('getTaks', [(int)$item['type'], $value['msg_id'], null]);
}
}
$item = array_merge($item, $taskService->getSendMsgStatistics($msgIds, (int)$item['type']));
}
}
$count = $this->dao->count($where);
return compact('list', 'count');
}
/**
* 创建或者修改
* @param array $data
*/
public function saveGroupTemplate(array $data)
{
$this->checkWelcome($data['welcome_words'], 0);
$this->transaction(function () use ($data) {
$res = $this->dao->save($data);
//立即发送或者选择的时间小于当前时间
if (!$data['template_type'] || ($data['template_type'] == 1 && $data['send_time'] < time())) {
if ($data['type']) {
WorkGroupMsgJob::dispatchDo('batch', [$res->id, '', 0]);
} else {
foreach ($data['userids'] as $key => $userid) {
WorkGroupMsgJob::dispatchDo('batch', [$res->id, $userid, $key + 1]);
}
}
}
});
}
/**
* 批量发送
* @param int $id
* @param string $userId
* @param int $count
* @return bool
*/
public function batch(int $id, string $userId, int $count)
{
try {
$groupTempInfo = $this->dao->get($id);
if (!$groupTempInfo) {
return true;
}
if ($groupTempInfo->send_type == 1) {
return true;
}
$groupTempInfo = $groupTempInfo->toArray();
$externalUserid = [];
if (!$groupTempInfo['type']) {
/** @var WorkClientServices $service */
$service = app()->make(WorkClientServices::class);
$where = ['userid' => $userId];
if ($groupTempInfo['client_type']) {
//条件筛选
if ($groupTempInfo['where_time']) {
$where['time'] = $groupTempInfo['where_time'];
$where['timeKey'] = 'create_time';
}
if ($groupTempInfo['where_label']) {
$where['label'] = $groupTempInfo['where_label'];
}
if ($groupTempInfo['notLabel']) {
$where['notLabel'] = $groupTempInfo['where_not_label'];
}
}
$externalUserid = $service->getClientUserIds($where);
}
$this->sendTask($id, $externalUserid, $groupTempInfo, $count);
return true;
} catch (\Throwable $e) {
Log::error([
'message' => '创建群发任务失败:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
//记录发送失败原因
try {
$this->dao->update($id, ['send_type' => -1, 'fail_message' => '创建群发任务失败:' . $e->getMessage()]);
} catch (\Throwable $e) {
}
return true;
}
}
/**
* @param int $id
* @param array $externalUserid
* @param array $data
* @param int $count
*/
public function sendTask(int $id, array $externalUserid, array $data, int $count)
{
$update = [];
/** @var WorkGroupMsgRelationServices $msgRelationService */
$msgRelationService = app()->make(WorkGroupMsgRelationServices::class);
if ($data['type']) {
//群主群发
$failList = [];
$msgIdData = [];
foreach ($data['userids'] as $item) {
$res = $this->sendMsgTemplate([], $data['welcome_words'], 'group', $item);
$failList = array_merge($failList, $res['fail_list'] ?? []);
if (isset($res['msgid'])) {
$msgIdData[] = $res['msgid'];
}
}
$update['send_type'] = 1;
if ($failList) {
$update['fail_external_userid'] = json_encode($failList);
}
if ($update) {
$this->dao->update($id, $update);
}
$msgRelation = [];
foreach ($msgIdData as $msgId) {
$msgRelation[] = ['template_id' => $id, 'msg_id' => $msgId];
WorkGroupMsgJob::dispatchSece(60, 'getTaks', [(int)$data['type'], $msgId, null]);
}
$msgRelationService->saveAll($msgRelation);
} else {
//成员群发
$sendTemplateWelcome = $this->sendMsgTemplate($externalUserid, $data['welcome_words']);
$failList = $sendTemplateWelcome['fail_list'] ?? [];
if ($failList) {
$update['fail_external_userid'] = json_encode($failList);
}
if ($count == count($data['userids'])) {
$update['send_type'] = 1;
} else {
$update['send_type'] = 2;
}
if ($update) {
$this->dao->update($id, $update);
}
$msgRelationService->save(['template_id' => $id, 'msg_id' => $sendTemplateWelcome['msgid']]);
WorkGroupMsgJob::dispatchSece(60, 'getTaks', [(int)$data['type'], $sendTemplateWelcome['msgid'], null]);
}
}
/**
* 群发任务详情
* @param int $id
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getGroupTemplateInfo(int $id)
{
$info = $this->dao->get($id, ['*'], ['msgIds']);
if (!$info) {
throw new ValidateException('没有查到此数据');
}
$msgIds = [];
$info = $info->toArray();
if (!empty($info['msgIds'])) {
$msgIds = array_column($info['msgIds'], 'msg_id');
}
$info['user_count'] = $info['unuser_count'] = $info['external_user_count'] = $info['external_unuser_count'] = 0;
$info['user_list'] = [];
if ($info['userids']) {
/** @var WorkMemberServices $service */
$service = app()->make(WorkMemberServices::class);
$info['user_list'] = $service->getColumn([
['userid', 'in', $info['userids']]
], 'userid,name');
}
if ($msgIds) {
/** @var WorkGroupMsgTaskServices $taskService */
$taskService = app()->make(WorkGroupMsgTaskServices::class);
$info = array_merge($info, $taskService->getSendMsgStatistics($msgIds, (int)$info['type']));
}
return $info;
}
/**
* 删除群发模板
* @param int $id
* @return bool
*/
public function deleteGroupTemplate(int $id)
{
/** @var WorkGroupMsgTaskServices $taskService */
$taskService = app()->make(WorkGroupMsgTaskServices::class);
/** @var WorkGroupMsgRelationServices $msgRelationService */
$msgRelationService = app()->make(WorkGroupMsgRelationServices::class);
/** @var WorkGroupMsgSendResultServices $sendResultService */
$sendResultService = app()->make(WorkGroupMsgSendResultServices::class);
$msgIds = $msgRelationService->getColumn(['template_id' => $id], 'msg_id');
$this->transaction(function () use ($id, $msgRelationService, $msgIds, $taskService, $sendResultService) {
$this->dao->delete($id);
if ($msgIds) {
$taskService->delete(['msg_id' => $msgIds]);
$sendResultService->delete(['msg_id' => $msgIds]);
}
});
return true;
}
/**
* 执行定时发送群发内容
*/
public function cornHandle()
{
$time = time();
$list = $this->dao->getDataList(['send_time' => $time, 'send_type' => 0], ['*'], 0, 0, null, ['msgIds']);
foreach ($list as $item) {
if ($item['type']) {
WorkGroupMsgJob::dispatchDo('batch', [$item['id'], '', 0]);
} else {
foreach ($item['userids'] as $count => $userid) {
WorkGroupMsgJob::dispatchDo('batch', [$item['id'], $userid, $count + 1]);
}
}
}
return true;
}
/**
* 发送应用消息
* @param int $id
* @param string $userid
* @param string $sendTime
* @return WechatResponse
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function sendMessage(int $id, string $userid, string $sendTime)
{
if ($id) {
$template = $this->dao->get(['id' => $id], ['userids', 'type', 'name', 'create_time']);
if (!$template) {
throw new ValidateException('没有查到群发模板');
}
$template = $template->toArray();
if (isset($template[0]['userid'])) {
$template['userids'] = array_column($template['userids'], 'userid');
}
$userids = $template['userids'];
$task = $template['type'] ? '客户群群发任务' : '客户群发任务';
$text = "【任务提醒】有新的任务啦!\n" .
"任务类型:{$task}\n" .
"任务名称:{$template['name']}\n" .
"创建时间:{$template['create_time']}\n" .
"可前往【群发助手】中确认发送,记得及时完成哦\n";
} else {
$userids = [$userid];
$text = "【任务提醒】有新的任务啦!\n" .
"任务类型:客户群发任务\n" .
"创建时间:{$sendTime}\n" .
"可前往【群发助手】中确认发送,记得及时完成哦\n";
}
$res = Event::until('work.message', [
'text', $text, ['toUser' => $userids], []
]);
if ($res === false) {
throw new ValidateException('发送消息失败');
}
}
}