TransferFans.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <?php
  2. namespace app\admin\command;
  3. use app\common\library\Redis;
  4. use app\common\library\WeChatObject;
  5. use EasyWeChat\Factory;
  6. use Symfony\Component\Cache\Simple\RedisCache;
  7. use think\Config;
  8. use think\console\Command;
  9. use think\console\Input;
  10. use think\console\input\Argument;
  11. use think\console\Output;
  12. use think\Log;
  13. use think\Request;
  14. class TransferFans extends Command
  15. {
  16. protected function configure()
  17. {
  18. $this
  19. ->setName('TransferFans')
  20. ->addArgument('out', Argument::REQUIRED, "转移粉丝的渠道")
  21. ->addArgument('in', Argument::REQUIRED, "接受粉丝的渠道")
  22. ->addArgument('id', Argument::OPTIONAL, "开始ID(包含当前ID)")
  23. ->setDescription('转移渠道粉丝到另一个渠道');
  24. }
  25. protected function execute(Input $input, Output $output)
  26. {
  27. try{
  28. //cli模式下无法获取到当前的项目模块,手动指定一下
  29. Request::instance()->module('admin');
  30. $adminConfigModel = model('AdminConfig');
  31. //获取参数
  32. $in = $input->getArgument('in');
  33. $out = $input->getArgument('out');
  34. $id = $input->getArgument('id');
  35. //检测参数是否合法
  36. if(empty($in) || empty($out)){
  37. $output->error('WeChat->TransferFans Error: 转移粉丝的渠道ID AND 接受粉丝的渠道ID 为必填项');
  38. Log::error('WeChat->TransferFans Error: 转移粉丝的渠道ID AND 接受粉丝的渠道ID 为必填项');
  39. return;
  40. }
  41. if(!is_numeric($in) || !is_numeric($out)){
  42. $output->error('WeChat->TransferFans Error: 转移粉丝的渠道ID AND 接受粉丝的渠道ID 必须为Int类型');
  43. Log::error('WeChat->TransferFans Error: 转移粉丝的渠道ID AND 接受粉丝的渠道ID 必须为Int类型');
  44. return;
  45. }
  46. $output->info("WeChat->TransferFans Info: 粉丝转移渠道[ {$out} ],粉丝接收渠道[ {$in} ]");
  47. Log::info("WeChat->TransferFans Info: 粉丝转移渠道[ {$out} ],粉丝接收渠道[ {$in} ]");
  48. //获取渠道信息
  49. if(!$inAdminConfig = $adminConfigModel->getAdminInfoAll($in)){
  50. $output->error("WeChat->TransferFans Channel_in:{$in},Error: 获取接受粉丝渠道信息失败");
  51. Log::error("WeChat->TransferFans Channel_in:{$in},Error: 获取接受粉丝渠道信息失败");
  52. return;
  53. }
  54. Log::info("WeChat->TransferFans Info: 粉丝接收渠道[ {$in} ],配置信息 ".var_export($inAdminConfig,true));
  55. if(!$outAdminConfig = $adminConfigModel->getAdminInfoAll($out)){
  56. $output->error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},Error: 获取转移粉丝渠道信息失败");
  57. Log::error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},Error: 获取转移粉丝渠道信息失败");
  58. return;
  59. }
  60. Log::info("WeChat->TransferFans Info: 粉丝转移渠道[ {$out} ],配置信息 ".var_export($outAdminConfig,true));
  61. //确认转移信息
  62. if(!$confirm = $output->confirm($input,"请确认把渠道[ {$out} ]的粉丝转移到渠道[ {$in} ]上面:")){
  63. $output->info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},Info: 已取消粉丝转移操作");
  64. Log::info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},Info: 已取消粉丝转移操作");
  65. return;
  66. }
  67. $map['channel_id'] = $out;
  68. $map['id'] = ['>=',$id ?? 1];
  69. //一次最多转移100个
  70. while($fans_list = model('Oldwx')->where($map)->limit(100)->column('id,openid')){
  71. //获取渠道WeChat对象
  72. if(!$inOfficialAccount = $this->getChannelWechat($inAdminConfig)){
  73. $output->error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},Error: 获取接受粉丝渠道WeChat对象失败");
  74. Log::error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},Error: 获取接受粉丝渠道WeChat对象失败");
  75. return;
  76. }
  77. $output->write('WeChat->TransferFans ------------------------------------->转移100个粉丝',5,$output::OUTPUT_NORMAL);
  78. //输出查询语句
  79. $execSQL = model('Oldwx')->where($map)->limit(100)->fetchSql(true)->column('id,openid');
  80. $output->info('WeChat->TransferFans QuerySQL:'.$execSQL);
  81. Log::info('WeChat->TransferFans QuerySQL:'.$execSQL);
  82. //构造查询条件
  83. $keys = array_keys($fans_list);
  84. $map['id'] = ['>',end($keys)];
  85. //调用微信接口转移
  86. Log::info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},Call_WeChat_Interface_Params:".var_export(array('old_appid'=>$outAdminConfig['appid'],'open_list'=>$fans_list),true));
  87. $transferRes = $inOfficialAccount->user->changeOpenid($outAdminConfig['appid'],array_values($fans_list));
  88. Log::info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},Call_WeChat_Interface_Result:".var_export($transferRes,true));
  89. //检测是否转移是否成功
  90. if(isset($transferRes['errcode']) && $transferRes['errcode'] != 0){
  91. $output->error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},Code:{$transferRes['errcode']},Error:".$transferRes['errmsg']);
  92. Log::error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},Code:{$transferRes['errcode']},Error:".$transferRes['errmsg']);
  93. continue;
  94. }
  95. $output->info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},Code:{$transferRes['errcode']},Info:微信粉丝转移接口调用成功");
  96. Log::info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},Code:{$transferRes['errcode']},Info:微信粉丝转移接口调用成功");
  97. if(!isset($transferRes['result_list']) || empty($transferRes['result_list'])){
  98. $output->error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},Code:{$transferRes['errcode']},Error:微信返回数据错误,结果集为空");
  99. Log::error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},Code:{$transferRes['errcode']},Error:微信返回数据错误,结果集为空");
  100. continue;
  101. }
  102. foreach($transferRes['result_list'] as $result){
  103. $output->write('WeChat->TransferFans ------------------------------------->处理微信返回结果',3,$output::OUTPUT_NORMAL);
  104. //粉丝是否转移成功
  105. if($result['err_msg'] != 'ok'){
  106. $output->error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},Error:".$result['err_msg'].',Resutl:'.var_export($result,true));
  107. Log::error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},Error:".$result['err_msg'].',Resutl:'.var_export($result,true));
  108. continue;
  109. }
  110. $output->info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},Info:{$result['err_msg']}");
  111. Log::info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},Info:{$result['err_msg']}");
  112. //成功转移的粉丝,获取用户ID ori_openid new_openid 是否删除OpenID?
  113. $openInfo = model('Openid')->setConnect($out, $result['ori_openid'])->where(['channel_openid' => $out.'_'.$result['ori_openid']])->find();
  114. if(!$openInfo || !isset($openInfo['user_id']) || (isset($openInfo['user_id']) && empty($openInfo['user_id']))){
  115. Log::error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},Error:查找数据库OpenID失败");
  116. $output->error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},Error:查找数据库OpenID失败");
  117. continue;
  118. }
  119. $openInfo = $openInfo->toArray();
  120. $user_id = $openInfo['user_id'];
  121. Log::info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},Info:获取OpenID信息成功,Result:".var_export($openInfo,true));
  122. $output->info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},Info:获取OpenID信息成功");
  123. //查找是否存在OpenID
  124. if($open_exists = model('Openid')->setConnect($in, $result['new_openid'])->where(['channel_openid' => $in.'_'.$result['new_openid']])->find()){
  125. Log::error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},User_id:{$user_id},Error:用户新OPENID已存在,Data:".var_export($open_exists->toArray(),true));
  126. $output->error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},User_id:{$user_id},Error:用户新OPENID已存在,Data:".var_export($open_exists->toArray(),true));
  127. continue;
  128. }
  129. // //插入新的OPEN_ID
  130. $open_data = ['channel_openid' => $in . '_' . $result['new_openid'], 'user_id' => $user_id, 'createtime' => time(), 'updatetime' => time()];
  131. if(!$insertOpenID = model('openid')->setConnect($in, $result['new_openid'])->insertGetId($open_data)){
  132. Log::error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},User_id:{$user_id},Error:创建新的OPENID信息失败,Data:".var_export($open_data,true));
  133. $output->error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},User_id:{$user_id},Error:创建新的OPENID信息失败,Data:".var_export($open_data,true));
  134. die();
  135. }
  136. $output->info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},User_id:{$user_id},Info:创建新的OPENID信息成功,Data:".var_export($open_data,true));
  137. Log::info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},User_id:{$user_id},Info:创建新的OPENID信息成功,Data:".var_export($open_data,true));
  138. //删除旧的OPEN_ID
  139. if(!model('Openid')->setConnect($out, $result['ori_openid'])->where(['channel_openid' => $out.'_'.$result['ori_openid']])->delete()){
  140. Log::error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},Error:删除旧的OpenID信息失败,Result:".var_export($openInfo,true));
  141. $output->error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},Error:删除旧的OpenID信息失败,Result:".var_export($openInfo,true));
  142. die();
  143. }
  144. $output->info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},OpenID:{$openInfo['id']},Info:删除旧的OpenID信息成功");
  145. Log::info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},OpenID:{$openInfo['id']},Info:删除旧的OpenID信息成功");
  146. //更新用户基础数据
  147. $user_data = ['openid'=>$result['new_openid'],'channel_id'=>$in];
  148. if(false === model('User')->setConnect($user_id)->where('id',$user_id)->update($user_data)){
  149. $output->error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},User_id:{$user_id},Error:更新用户基础信息失败,Data:".var_export($user_data,true));
  150. Log::error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},User_id:{$user_id},Error:更新用户基础信息失败,Data:".var_export($user_data,true));
  151. die();
  152. }
  153. $output->info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},User_id:{$user_id},Info:更新用户基础信息成功,Data:".var_export($user_data,true));
  154. Log::info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},User_id:{$user_id},Info:更新用户基础信息成功,Data:".var_export($user_data,true));
  155. //清空用户缓存
  156. if(!$this->clearCache($user_id)){
  157. $output->error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},User_id:{$user_id},Error:清除用户缓存失败");
  158. Log::error("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},User_id:{$user_id},Error:清除用户缓存失败");
  159. die();
  160. }
  161. $output->info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},User_id:{$user_id},Info:清除用户缓存成功");
  162. Log::info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},OLD_OPENID:{$result['ori_openid']},NEW_OPENID:{$result['new_openid']},User_id:{$user_id},Info:清除用户缓存成功");
  163. }
  164. }
  165. $output->info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},Info: 已完成粉丝转移操作");
  166. Log::info("WeChat->TransferFans Channel_in:{$in},Channel_out:{$out},Info: 已完成粉丝转移操作");
  167. }catch (\Exception $e){
  168. Log::error('WeChat->TransferFans Error: '.$e->getMessage(). ' Code:'.$e->getLine());
  169. $output->error('WeChat->TransferFans Error: '.$e->getMessage(). ' Code:'.$e->getLine());
  170. }
  171. }
  172. /**
  173. * 删除用户缓存
  174. * @param $user_id
  175. * @return bool
  176. */
  177. private function clearCache($user_id){
  178. $redis = Redis::instance();
  179. $redis->del('UN:' . $user_id);
  180. if ($redis->exists('UN:' . $user_id)) {
  181. return false;
  182. }
  183. return true;
  184. }
  185. /**
  186. * 获取渠道对象
  187. * @param $adminConfig
  188. * @return \EasyWeChat\OpenPlatform\Authorizer\OfficialAccount\Application
  189. */
  190. private function getChannelWechat($adminConfig){
  191. $wechat = new WeChatObject($adminConfig);
  192. $officialAccount = $wechat->getOfficialAccount();
  193. return $officialAccount;
  194. }
  195. }