BaseUtil.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. <?php
  2. namespace App\Http\Utils;
  3. use App\Exceptions\CommonException;
  4. use App\Http\Enum\ErrorEnum;
  5. use App\Http\Enum\PlatformTypeEnum;
  6. use App\Http\Utils\Pdd\DuoDuoKeUtil;
  7. use App\Models\PlatformSidModel;
  8. use App\Models\TaobaoPidModel;
  9. use App\Models\WebSiteModel;
  10. use App\Models\WechatAccountModel;
  11. use Illuminate\Support\Facades\DB;
  12. use Tool\ShanTaoTool\HttpCurl;
  13. use Tool\ShanTaoTool\QiWeiTool;
  14. class BaseUtil
  15. {
  16. /**
  17. * sql监听
  18. */
  19. public static function listenSql()
  20. {
  21. DB::listen(function ($sql) {
  22. $i = 0;
  23. $bindings = $sql->bindings;
  24. $rawSql = preg_replace_callback('/\?/', function ($matches) use ($bindings, &$i) {
  25. $item = isset($bindings[$i]) ? $bindings[$i] : $matches[0];
  26. $i++;
  27. return gettype($item) == 'string' ? "'$item'" : $item;
  28. }, $sql->sql);
  29. //记录sql
  30. LoggerFactoryUtil::addSqlMessage($rawSql);
  31. // echo $rawSql, "\n<br /><br />\n";
  32. });
  33. }
  34. /**
  35. * 统一企微报警
  36. * @param $params
  37. * @param $response
  38. * @param $funcname
  39. * @throws \Tool\ShanTaoTool\Exception\QiWeiException
  40. */
  41. public static function sendBaoJing($params,$response,$funcname)
  42. {
  43. $param = [
  44. "功能"=>$funcname,
  45. "请求参数"=>$params,
  46. "用户ID"=>"",
  47. "相应信息"=>$response,
  48. "信息时间"=>date("Y-m-d H:i:s"),
  49. "环境"=>env("ENV_NAME")
  50. ];
  51. QiWeiTool::sendMessageToBaoJing(json_encode($param,JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
  52. }
  53. /**
  54. * 获取应用编号
  55. */
  56. public static function getAppCodeByQuery()
  57. {
  58. return request()->input("wechat_app_code");
  59. }
  60. /**
  61. * 从redis中获取数据
  62. * @param $key string 键
  63. */
  64. public static function getCacheFromRedis($key)
  65. {
  66. /**
  67. * @var \Redis $redis
  68. */
  69. $redis = app("redis");
  70. return $redis->get($key);
  71. }
  72. /**
  73. * 设置redis数据的过期时间
  74. * @param $key string 键
  75. * @param $val string 值
  76. * @param $ttl int 过期时间
  77. */
  78. public static function setRedisCache($key, $val, $ttl)
  79. {
  80. /**
  81. * @var \Redis $redis
  82. */
  83. $redis = app("redis");
  84. if($ttl==0){
  85. return $redis->set($key,$val);
  86. }else{
  87. return $redis->setex($key,$ttl,$val);
  88. }
  89. }
  90. /**
  91. * 获取redis锁
  92. * @param $lokKey string 键
  93. * @param $ttl int 过期时间
  94. */
  95. public static function setRedisLock($lokKey, $ttl)
  96. {
  97. /**
  98. * @var \Redis $redis
  99. */
  100. $redis = app("redis")->client();
  101. $flag = $redis->set($lokKey,1,["nx","ex"=>$ttl]);
  102. if(!$flag){
  103. throw new CommonException(ErrorEnum::ERROR_REPEAT);
  104. }
  105. }
  106. /**
  107. * 生成美团推广位
  108. * @param $userId int 用户ID
  109. */
  110. public static function generateMeiTuanSid($userId)
  111. {
  112. return "meituanSpread:".$userId;
  113. }
  114. /**
  115. * 生成聚推客推广位
  116. * @param $userId
  117. */
  118. public static function generateJutuiKeSid($userId)
  119. {
  120. return "jtkupstream".$userId;
  121. }
  122. /**
  123. * 获取用户的平台推广位
  124. * @param $platformType int 平台
  125. * @param $userId int 用户ID
  126. */
  127. public static function getPlatformUserSpreadId($platformType,$userId,$userSpreadId="")
  128. {
  129. //获取平台推广位
  130. $platformSid = PlatformSidModel::query()
  131. ->where("user_id",$userId)
  132. ->where("platform_type",$platformType)
  133. ->first();
  134. if($platformSid){
  135. //存在则直接返回
  136. return $platformSid->platform_sid;
  137. }else{
  138. switch ($platformType){
  139. case PlatformTypeEnum::PLATFORM_TAOBAO:
  140. //淘宝
  141. DB::beginTransaction();
  142. $taobaoPid = TaobaoPidModel::query()->where("status",0)->lock(true)->first();
  143. if(!$taobaoPid){
  144. DB::rollBack();
  145. BaseUtil::sendBaoJing("","淘宝推广位不足","获取淘宝推广位");
  146. throw new CommonException(ErrorEnum::ERROR_SYSTEM);
  147. }
  148. TaobaoPidModel::query()->where("id",$taobaoPid["id"])->update(["status"=>1]);
  149. DB::commit();
  150. $sid = $taobaoPid["adzone_id"];
  151. break;
  152. case PlatformTypeEnum::PLATFORM_PINGDUODUO:
  153. //拼多多
  154. $res = DuoDuoKeUtil::goodsPidGenerate(1,["用户:".$userId]);
  155. $instance = new LoggerFactoryUtil(BaseUtil::class);
  156. $instance->info("拼多多返回数据:".json_encode($res));
  157. $sid = $res["p_id_generate_response"]["p_id_list"][0]["p_id"];
  158. break;
  159. case PlatformTypeEnum::PLATFORM_JINGDONG:
  160. //京东
  161. break;
  162. case PlatformTypeEnum::PLATFORM_MEITUAN:
  163. //美团
  164. $sid = self::generateMeiTuanSid($userId);
  165. break;
  166. case PlatformTypeEnum::PLATFORM_FANBUTING:
  167. //平台(饭不停)
  168. break;
  169. case PlatformTypeEnum::PLATFORM_JUTUIKE:
  170. //聚推客
  171. $sid = self::generateJutuiKeSid($userId);
  172. break;
  173. default:
  174. throw new CommonException(ErrorEnum::ERROR_EXIST_PLATFORM);
  175. }
  176. if(!$userSpreadId){
  177. //不存在用户自传的推广位,则默认和平台的推广位相等
  178. $userSpreadId = $sid;
  179. }
  180. //写入用户的推广位
  181. PlatformSidModel::query()->insert(
  182. [
  183. "user_id"=>$userId,
  184. "user_sid"=>$userSpreadId,
  185. "platform_type"=>$platformType,
  186. "platform_sid"=>$sid,
  187. "created_at"=>date("Y-m-d H:i:s"),
  188. "updated_at"=>date("Y-m-d H:i:s")
  189. ]
  190. );
  191. return $sid;
  192. }
  193. }
  194. /**
  195. * 根据app ID和secret获取accesstoken
  196. * @param $appId
  197. * @param $appSecret
  198. */
  199. public static function getAccessToken($appId, $appSecret)
  200. {
  201. $key = $appId."accesstoken";
  202. $val = self::getCacheFromRedis($key);
  203. if($val){
  204. return $val;
  205. }
  206. //不存在则获取
  207. $params = [
  208. "grant_type"=>"client_credential",
  209. "appid"=>$appId,
  210. "secret"=>$appSecret
  211. ];
  212. $res = HttpCurl::getCurl("https://api.weixin.qq.com/cgi-bin/token",$params);
  213. if(isset($res["errcode"])){
  214. $instance = new LoggerFactoryUtil(BaseUtil::class);
  215. $instance->info("微信返回信息:".json_encode($res));
  216. throw new CommonException(ErrorEnum::ERROR_ACCOUNT_ACCESS_TOKEN);
  217. }
  218. self::setRedisCache($key,$res["access_token"],7100);
  219. return $res["access_token"];
  220. }
  221. /**
  222. * 获取jsapi_ticket
  223. * @param $appId
  224. * @param $appSecret
  225. */
  226. public static function getJsapiTicket($appId, $appSecret)
  227. {
  228. $key = $appId."getJsapiTicket";
  229. $val = self::getCacheFromRedis($key);
  230. if($val){
  231. return $val;
  232. }
  233. $accessToken = self::getAccessToken($appId,$appSecret);
  234. $params = [
  235. "access_token"=>$accessToken,
  236. "type"=>"jsapi"
  237. ];
  238. $res = HttpCurl::getCurl("https://api.weixin.qq.com/cgi-bin/ticket/getticket",$params);
  239. if($res["errcode"]==0){
  240. self::setRedisCache($key,$res["ticket"],7000);
  241. return $res["ticket"];
  242. }
  243. throw new CommonException(ErrorEnum::ERROR_ACCOUNT_ACCESS_TOKEN);
  244. }
  245. /**
  246. * 获取公众号支付参数校验数据
  247. * @param $appId
  248. * @param $appSecret
  249. */
  250. public static function getJsapiSign($appId, $appSecret,$url)
  251. {
  252. $jsapi_ticket = self::getJsapiTicket($appId,$appSecret);
  253. $instance = new LoggerFactoryUtil(BaseUtil::class);
  254. $instance->info("jsapiticket:".$jsapi_ticket);
  255. $noncestr = uniqid();
  256. $timestamp = time();
  257. $instance->info("url:".$url);
  258. // $url = substr($url,0,strpos($url,"#"));
  259. $string = "jsapi_ticket=".$jsapi_ticket."&noncestr=$noncestr"."&timestamp=".$timestamp."&url=".$url;
  260. $instance->info("签名字符串:".$string);
  261. $signature = sha1($string);
  262. return [
  263. "appId"=>$appId,
  264. "timestamp"=>$timestamp,
  265. "nonceStr"=>$noncestr,
  266. "signature"=>$signature
  267. ];
  268. }
  269. /**
  270. * 根据网址获取微信公众号
  271. * @param $host string 网址
  272. */
  273. public static function getWechatAccountByHost($host)
  274. {
  275. $webSite = WebSiteModel::query()->where("web_site_host",$host)->first();
  276. if(!$webSite){
  277. throw new CommonException(ErrorEnum::ERROR_EXIST_WEB_SITE);
  278. }
  279. $wechatAccount = WechatAccountModel::query()->find($webSite->wechat_account_id);
  280. if(!$wechatAccount){
  281. throw new CommonException(ErrorEnum::ERROR_ACCOUNT_EXIST);
  282. }
  283. return $wechatAccount;
  284. }
  285. /**
  286. * 获取用户ID
  287. */
  288. public static function getUserId()
  289. {
  290. return request()->header("user_id");
  291. }
  292. /**
  293. * 从url中获取get参数,以数组形式返回
  294. * @param $url
  295. */
  296. public static function getParamsByUrl($url)
  297. {
  298. $flag = preg_match("/(.*)\?(.*)/",$url,$match);
  299. $tmp = [];
  300. if($flag){
  301. $arrs = explode("&",$match[2]);
  302. foreach ($arrs as $arr){
  303. $t = explode("=",$arr);
  304. $tmp[$t[0]] = $t[1];
  305. }
  306. $tmp["url"]=$match[1];
  307. }
  308. return $tmp;
  309. }
  310. /**
  311. * 获取订单编号
  312. * @param $userId
  313. */
  314. public static function getOrderNumber($userId)
  315. {
  316. return date("YmdHis").$userId.random_int(10000,99999);
  317. }
  318. }