徐总多门店
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/WorkGroupChatServices.php

440 lines
17 KiB

<?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\WorkGroupChatDao;
use app\jobs\work\WorkClientJob;
use app\jobs\work\WorkGroupChatJob;
use app\services\BaseServices;
use crmeb\services\wechat\config\WorkConfig;
use crmeb\services\wechat\Work;
use crmeb\traits\ServicesTrait;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\exception\ValidateException;
/**
* Class WorkGroupChatServices
* @package app\services\work
* @mixin WorkGroupChatDao
*/
class WorkGroupChatServices extends BaseServices
{
use ServicesTrait;
/**
* WorkGroupChatServices constructor.
* @param WorkGroupChatDao $dao
*/
public function __construct(WorkGroupChatDao $dao)
{
$this->dao = $dao;
}
/**
* 获取客户群群发列表
* @param array $where
* @param array $with
* @return array
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function groupChatList(array $where, array $with = [])
{
[$page, $limit] = $this->getPageValue();
$list = $this->dao->groupChat($where)->with($with)->page($page, $limit)->select()->toArray();
$count = $this->dao->groupChat($where)->count();
return compact('list', 'count');
}
/**
* 群发详情列表
* @param array $chatIds
* @return array
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getOwnerChatList(array $chatIds, $status = null)
{
return $this->groupChatList(['chat_id' => $chatIds, 'status' => $status], [
'sendResult' => function ($query) {
$query->field(['chat_id', 'status']);
}, 'chatMember' => function ($query) {
$query->field(['count(*) as sun', 'group_id']);
}
]);
}
/**
* 同步企业微信客户群
* @param string|null $nextCursor
* @return bool
* @author 等风来
* @email 136327134@qq.com
* @date 2022/10/10
*/
public function authGroupChat(string $nextCursor = null)
{
/** @var WorkConfig $confg */
$config = app()->make(WorkConfig::class);
$corpId = $config->get('corpId');
if (!$corpId) {
throw new ValidateException('请先配置企业微信ID');
}
$res = Work::getGroupChats([], 100, $nextCursor);
if (0 !== ($res['errcode'] ?? 0)) {
throw new ValidateException($res['errmsg']);
}
$groupChatList = $res['group_chat_list'] ?? [];
if ($groupChatList) {
$groupChat = [];
foreach ($groupChatList as $item) {
$item['corp_id'] = $corpId;
if (($id = $this->dao->value(['chat_id' => $item['chat_id'], 'corp_id' => $corpId], 'id'))) {
$this->dao->update($id, $item);
} else {
$item['create_time'] = time();
$groupChat[] = $item;
}
}
if ($groupChat) {
$this->dao->saveAll($groupChat);
}
foreach ($groupChatList as $item) {
WorkGroupChatJob::dispatchDo('authChat', [$corpId, $item['chat_id']]);
}
//如果有下一页继续执行
if (!empty($res['next_cursor'])) {
WorkGroupChatJob::dispatchDo('authGroupChat', [$res['next_cursor']]);
}
}
return true;
}
/**
* 保存群详情
* @param string $corpId
* @param string $chatId
* @return bool
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function saveWorkGroupChat(string $corpId, string $chatId)
{
$response = Work::getGroupChat($chatId);
if (0 !== $response['errcode']) {
throw new ValidateException($response['errmsg']);
}
$groupInfo = $response['group_chat'] ?? [];
$groupInfo['admin_list'] = json_encode(array_column($groupInfo['admin_list'], 'userid'));
$memberList = $groupInfo['member_list'] ?? [];
unset($groupInfo['member_list']);
$group = $this->dao->get(['corp_id' => $corpId, 'chat_id' => $chatId]);
return $this->transaction(function () use ($chatId, $corpId, $group, $groupInfo, $memberList) {
if ($group) {
$group->name = $groupInfo['name'];
$group->owner = $groupInfo['owner'];
$group->notice = $groupInfo['notice'] ?? '';
$group->group_create_time = $groupInfo['create_time'];
$group->member_num = count($memberList);
$group->save();
} else {
$group = $this->dao->save([
'corp_id' => $corpId,
'chat_id' => $chatId,
'name' => $groupInfo['name'],
'owner' => $groupInfo['owner'],
'notice' => $groupInfo['notice'] ?? '',
'member_num' => count($memberList),
'group_create_time' => $groupInfo['create_time'],
'status' => $groupInfo['status'] ?? 0,
]);
}
$this->saveMember($memberList, $group->id, $group->member_num);
return $group->id;
});
}
/**
* @param array $where
* @return array
*/
public function getList(array $where)
{
[$page, $limit] = $this->getPageValue();
$where['timeKey'] = 'group_create_time';
$where['status'] = [0, 2, 3];
$list = $this->dao->getDataList($where, ['*'], $page, $limit, 'group_create_time', [
'ownerInfo' => function ($query) {
$query->field(['userid', 'name']);
},
]);
//提取管理员数据
$adminUserId = [];
foreach ($list as $item) {
$adminUserId = array_merge($adminUserId, $item['admin_list'] ?? []);
}
$adminUserId = array_merge(array_unique(array_filter($adminUserId)));
if ($adminUserId) {
/** @var WorkMemberServices $memberService */
$memberService = app()->make(WorkMemberServices::class);
$adminUserList = $memberService->getColumn([
['userid', 'in', $adminUserId],
], 'name', 'userid');
foreach ($list as &$item) {
$newAdminUser = [];
if (!empty($item['admin_list'])) {
foreach ($adminUserList as $key => $value) {
if (in_array($key, $item['admin_list'])) {
$newAdminUser[] = ['name' => $value, 'userid' => $key];
}
}
}
$item['admin_user_list'] = $newAdminUser;
}
}
$count = $this->dao->count();
return compact('list', 'count');
}
/**
* 企业微信客户群变动
* @param array $payload
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function updateGroupChat(array $payload)
{
$corpId = $payload['ToUserName'];
$chatId = $payload['ChatId'];
$groupInfo = $this->dao->get(['corp_id' => $corpId, 'chat_id' => $chatId]);
if (!$groupInfo) {
$groupId = $this->saveWorkGroupChat($corpId, $chatId);
$groupInfo = $this->dao->get($groupId);
}
$response = Work::getGroupChat($chatId);
if (0 !== $response['errcode']) {
throw new ValidateException($response['errmsg'] ?? '企业微信查询群详情失败');
}
$groupChat = $response['group_chat'] ?? [];
$memberList = $groupChat['member_list'];
/** @var WorkGroupChatStatisticServices $statisticService */
$statisticService = app()->make(WorkGroupChatStatisticServices::class);
$this->transaction(function () use ($payload, $groupInfo, $groupChat, $memberList, $statisticService) {
switch ($payload['UpdateDetail']) {
case 'add_member':
$groupInfo->member_num++;
$this->saveMember($memberList, $groupInfo->id, $groupInfo->member_num, true);
$statisticService->saveOrUpdate($groupInfo->id, true, false, $groupInfo->member_num, $groupInfo->retreat_group_num);
break;
case 'del_member':
$groupInfo->member_num--;
$groupInfo->retreat_group_num++;
$this->saveMember($memberList, $groupInfo->id, $groupInfo->member_num, false);
$statisticService->saveOrUpdate($groupInfo->id, false, true, $groupInfo->member_num, $groupInfo->retreat_group_num);
break;
case 'change_owner':
$groupInfo->owner = $groupChat['owner'];
break;
case 'change_name':
$groupInfo->name = $groupChat['name'];
break;
case 'change_notice':
$groupInfo->notice = $groupChat['notice'];
break;
}
if (!empty($groupChat['admin_list'])) {
$groupInfo->admin_list = json_encode(array_column($groupChat['admin_list'], 'userid'));
}
$groupInfo->save();
});
}
/**
* 保存群成员
* @param array $memberList
* @param int $groupId
* @param int $sum
* @param bool $plus
* @return mixed
*/
public function saveMember(array $memberList, int $groupId, int $sum = 0, bool $plus = false)
{
$data = [];
/** @var WorkGroupChatMemberServices $chatMemberService */
$chatMemberService = app()->make(WorkGroupChatMemberServices::class);
$newUserIds = array_column($memberList, 'userid');
$userids = $chatMemberService->getColumn(['group_id' => $groupId], 'userid');
$unUserIds = array_diff($userids, $newUserIds);
$labelList = [];
foreach ($memberList as $item) {
$item['group_id'] = $groupId;
$state = $item['state'] ?? '';
if (isset($item['state'])) {
unset($item['state']);
}
$item['invitor_userid'] = $item['invitor']['userid'] ?? '';
$unionid = $item['unionid'] ?? '';
unset($item['invitor'], $item['unionid']);
if ($chatMemberService->count(['group_id' => $groupId, 'userid' => $item['userid']])) {
$chatMemberService->update(['group_id' => $groupId, 'userid' => $item['userid']], [
'type' => $item['type'],
'unionid' => $unionid,
'chat_sum' => $sum,
'status' => 1,
'join_time' => $item['join_time'],
'join_scene' => $item['join_scene'],
'invitor_userid' => $item['invitor_userid'],
'group_nickname' => $item['group_nickname'],
]);
} else {
if ($state) {
$labelList[] = ['userid' => $item['userid'], 'type' => $item['type'], 'state' => $state];
}
$item['unionid'] = $unionid;
$item['chat_sum'] = $sum;
$item['state'] = $state;
$item['create_time'] = time();
$data[] = $item;
}
}
if ($data) {
$chatMemberService->saveAll($data);
//如果没有客户信息同步客户信息
/** @var WorkClientServices $clientService */
$clientService = app()->make(WorkClientServices::class);
$corpId = app()->make(WorkConfig::class)->get('corpId');
foreach ($data as $item) {
if (2 == $item['type'] && $clientService->count(['external_userid' => $item['userid']])) {
WorkClientJob::dispatchDo('saveClientInfo', [$corpId, $item['userid'], '']);
}
}
}
if ($unUserIds) {
$chatMemberService->update([
['userid', 'in', $unUserIds]
], ['status' => 0]);
}
return true;
}
/**
* 解散客户群
* @param string $corpId
* @param string $chatId
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function dismissGroupChat(string $corpId, string $chatId)
{
$groupChat = $this->dao->get(['corp_id' => $corpId, 'chat_id' => $chatId], ['id']);
if (!$groupChat) {
throw new ValidateException('没有查询到群');
}
return $this->transaction(function () use ($groupChat) {
/** @var WorkGroupChatMemberServices $chatMemberService */
$chatMemberService = app()->make(WorkGroupChatMemberServices::class);
$chatMemberService->delete(['group_id' => $groupChat->id]);
return $groupChat->delete();
});
}
/**
* 群统计
* @param int $id
* @param string $time
* @return array
*/
public function getChatStatistics(int $id, string $time)
{
/** @var WorkGroupChatMemberServices $chatMemberService */
$chatMemberService = app()->make(WorkGroupChatMemberServices::class);
$data = [
'toDaySum' => $chatMemberService->getToDaySum($id),
'toDayReturn' => $chatMemberService->getToDayReturn($id),
'groupChatSum' => $this->dao->value(['id' => $id], 'member_num'),
'groupChatReturnSum' => $this->dao->value(['id' => $id], 'retreat_group_num')
];
$data['groupChatList'] = $chatMemberService->getChatMemberStatistics($id, 'join_time', ['count(*) as sum'], 1, $time);
$data['groupChatReturnList'] = $chatMemberService->getChatMemberStatistics($id, 'join_time', ['count(*) as sum'], 0, $time);
return $data;
}
/**
* 群成员统计
* @param int $id
* @param string $time
* @return array
*/
public function getChatStatisticsList(int $id, string $time)
{
[$page, $limit] = $this->getPageValue();
/** @var WorkGroupChatMemberServices $chatMemberService */
$chatMemberService = app()->make(WorkGroupChatMemberServices::class);
$newCount = $chatMemberService->getChatMemberStatisticsCount($id, 1, $time);
$returnCount = $chatMemberService->getChatMemberStatisticsCount($id, 0, $time);
$SumCount = $newCount > $returnCount ? $newCount : $returnCount;
$groupChatList = $chatMemberService->getChatMemberStatistics($id, 'join_time', ['count(*) as sum', 'chat_sum', 'retreat_chat_num'], 1, $time, $page, $limit);
$groupChatReturnList = $chatMemberService->getChatMemberStatistics($id, 'join_time', ['count(*) as retreat_sum'], 0, $time, $page, $limit);
$count = ($rCount = count($groupChatReturnList)) > ($count = count($groupChatList)) ? $rCount : $count;
$data = [];
for ($i = 0; $i < $count; $i++) {
$data[] = [
'time' => $groupChatList[$i]['time'] ?? $groupChatReturnList[$i]['time'] ?? '',
'sum' => $groupChatList[$i]['sum'] ?? 0,
'retreat_chat_num' => $groupChatList[$i]['retreat_chat_num'] ?? 0,
'chat_sum' => $groupChatList[$i]['chat_sum'] ?? 0,
'retreat_sum' => $groupChatReturnList[$i]['retreat_sum'] ?? 0,
];
}
return ['list' => $data, 'count' => $SumCount];
}
/**
* @param string $chatId
* @param string $corpId
* @return array
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getGroupInfo(string $chatId, string $corpId)
{
$groupInfo = $this->dao->get(['chat_id' => $chatId, 'corp_id' => $corpId]);
if (!$groupInfo) {
throw new ValidateException('客户群未查到');
}
/** @var WorkGroupChatMemberServices $service */
$service = app()->make(WorkGroupChatMemberServices::class);
$groupInfo['todaySum'] = $service->getToDaySum($groupInfo->id);
$groupInfo['todayReturnSum'] = $service->getToDayReturn($groupInfo->id);
return $groupInfo->toArray();
}
}