2020-06-20 08:49:16 +08:00
|
|
|
<?php
|
2020-06-21 10:48:11 +08:00
|
|
|
/**
|
|
|
|
* @filename GetModuleTrait.php
|
|
|
|
* @createdAt 2020/2/24
|
|
|
|
* @project https://github.com/yanwenwu/catch-admin
|
|
|
|
* @document http://doc.catchadmin.com
|
|
|
|
* @author JaguarJack <njphper@gmail.com>
|
|
|
|
* @copyright By CatchAdmin
|
|
|
|
* @license https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace catchAdmin\wechat\command;
|
|
|
|
|
|
|
|
use catchAdmin\wechat\model\WechatUsers;
|
2020-06-21 18:04:30 +08:00
|
|
|
use catcher\exceptions\FailedException;
|
2020-06-21 10:48:11 +08:00
|
|
|
use catcher\facade\Trie;
|
|
|
|
use catcher\library\ProgressBar;
|
|
|
|
use catcher\library\WeChat;
|
2020-06-21 18:04:30 +08:00
|
|
|
use catcher\Utils;
|
2020-06-21 10:48:11 +08:00
|
|
|
use think\Collection;
|
|
|
|
use think\console\Command;
|
|
|
|
use think\console\Input;
|
|
|
|
use think\console\Output;
|
2020-06-21 18:04:30 +08:00
|
|
|
use think\Db;
|
2020-06-21 10:48:11 +08:00
|
|
|
|
|
|
|
class SyncUsersCommand extends Command
|
|
|
|
{
|
|
|
|
protected $officialAccount;
|
|
|
|
|
|
|
|
public function configure()
|
|
|
|
{
|
|
|
|
$this->setName('sync:users')
|
|
|
|
->setDescription('sync wechat users');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function execute(Input $input, Output $output)
|
|
|
|
{
|
|
|
|
$this->officialAccount = WeChat::officialAccount();
|
|
|
|
|
2020-06-21 18:04:30 +08:00
|
|
|
$latest = WechatUsers::order('subscribe_time')->find();
|
|
|
|
|
|
|
|
if ($latest) {
|
|
|
|
throw new FailedException('暂时无法增量同步');
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->sync($latest ? $latest->openid : null);
|
|
|
|
|
|
|
|
$this->syncTags();
|
2020-06-21 10:48:11 +08:00
|
|
|
}
|
|
|
|
|
2020-06-21 18:04:30 +08:00
|
|
|
protected function syncTags()
|
|
|
|
{
|
|
|
|
$users = WechatUsers::cursor();
|
|
|
|
|
|
|
|
foreach ($users as $user) {
|
|
|
|
if ($user->tag_list) {
|
|
|
|
$tagIds = Utils::stringToArrayBy($user->tag_list);
|
|
|
|
$relate = [];
|
|
|
|
|
|
|
|
foreach ($tagIds as $id) {
|
|
|
|
$relate[] = [
|
|
|
|
'user_id' => $user->id,
|
|
|
|
'tag_id' => $id,
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
Db::name('wechat_user_has_tags')->insertAll($relate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-06-21 10:48:11 +08:00
|
|
|
/**
|
|
|
|
* 同步
|
|
|
|
*
|
|
|
|
* @time 2020年06月20日
|
|
|
|
* @param $nextOpenid
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
protected function sync($nextOpenid)
|
|
|
|
{
|
|
|
|
$userOpenids = $this->getWechatUserOpenids($nextOpenid);
|
|
|
|
|
|
|
|
if ($userOpenids['next_openid']) {
|
|
|
|
$this->getUsersBy($userOpenids['data']['openid']);
|
|
|
|
$this->sync($userOpenids['next_openid']);
|
|
|
|
} else {
|
|
|
|
if ($userOpenids['count']) {
|
|
|
|
$openids = $userOpenids['data']['openid'];
|
|
|
|
$this->getUsersBy($openids);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 获取用户
|
|
|
|
*
|
|
|
|
* @time 2020年06月20日
|
|
|
|
* @param $openids
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
protected function getUsersBy($openids)
|
|
|
|
{
|
|
|
|
$chunks = array_chunk($openids, $this->getChunkSize($openids));
|
|
|
|
|
|
|
|
$total = count($chunks);
|
|
|
|
|
|
|
|
$bar = new ProgressBar($this->output, $total);
|
|
|
|
|
|
|
|
$bar->setHeader('[开始同步]');
|
|
|
|
|
|
|
|
$bar->start();
|
|
|
|
foreach ($chunks as $chunk) {
|
|
|
|
$users = $this->officialAccount->user->select($chunk);
|
|
|
|
$this->syncToDatabase($users);
|
|
|
|
$bar->advance();
|
|
|
|
}
|
|
|
|
$bar->finished();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 同步到数据库
|
|
|
|
*
|
|
|
|
* @time 2020年06月20日
|
|
|
|
* @param $users
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
protected function syncToDatabase($users)
|
|
|
|
{
|
|
|
|
$users = $users['user_info_list'];
|
|
|
|
|
|
|
|
foreach ($users as &$user) {
|
|
|
|
$user['avatar'] = $user['headimgurl'];
|
|
|
|
$user['unionid'] = $user['unionid'] ?? '';
|
|
|
|
$user['created_at'] = time();
|
|
|
|
$user['updated_at'] = time();
|
|
|
|
if (!empty($user['tagid_list'])) {
|
|
|
|
$user['tagid_list'] = trim(implode(',', $user['tagid_list']), ',');
|
|
|
|
}
|
|
|
|
unset($user['headimgurl']);
|
|
|
|
unset($user['qr_scene'], $user['qr_scene_str']);
|
|
|
|
}
|
|
|
|
|
|
|
|
WechatUsers::insertAll($users);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 获取 chunk size
|
|
|
|
*
|
|
|
|
* @time 2020年06月20日
|
|
|
|
* @param $openids
|
|
|
|
* @return int
|
|
|
|
*/
|
|
|
|
protected function getChunkSize($openids)
|
|
|
|
{
|
|
|
|
$size = count($openids);
|
|
|
|
|
|
|
|
if ($size < 10) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($size > 10 && $size < 100) {
|
|
|
|
return 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($size > 100 && $size < 1000) {
|
|
|
|
return 100;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($size > 1000 && $size < 10000) {
|
|
|
|
return 100;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 获取微信 openids
|
|
|
|
*
|
|
|
|
* @time 2020年06月20日
|
|
|
|
* @param $nextOpenId
|
|
|
|
* @return mixed
|
|
|
|
*/
|
|
|
|
public function getWechatUserOpenids($nextOpenId)
|
|
|
|
{
|
|
|
|
return $this->officialAccount->user->list($nextOpenId);
|
|
|
|
}
|
|
|
|
}
|