UserDivisionCpcPropertyService.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: z-yang
  5. * Date: 2019/4/26
  6. * Time: 10:14
  7. */
  8. namespace App\Modules\User\Services;
  9. use App\Modules\User\Models\UserDivisionCpcProperty;
  10. use App\Modules\User\Models\UserDivisionCpcPropertyV2;
  11. use DB;
  12. class UserDivisionCpcPropertyService
  13. {
  14. public static function userLevel($openid){
  15. return UserDivisionCpcProperty::where('openid',$openid)->where('is_enable',1)->select('property','earliest_subscribe_time','type')->first();
  16. }
  17. public static function getUserProperty($uid){
  18. $result = UserDivisionCpcProperty::join('users','users.openid','=','user_division_cpc_property.openid')
  19. ->where('users.id',$uid)
  20. ->select('user_division_cpc_property.property')->first();
  21. if($result)
  22. return $result->property;
  23. return '';
  24. }
  25. public static function getUserSubscribeAndChargeInfoByUid($uid){
  26. $sql_format = "SELECT u.id,f.created_at as subscribe_time,u.openid,
  27. (SELECT ifnull(sum(price),0) from orders where uid = u.id and `status` = 'PAID' LIMIT 1)as amount,
  28. (SELECT ifnull(sum(price),0) from orders where uid=u.id and `status` = 'PAID' and created_at <= DATE_ADD(f.created_at,INTERVAL 3 day)) as three_day_amount
  29. FROM users u
  30. JOIN force_subscribe_users f on u.id = f.uid
  31. WHERE u.openid in (SELECT openid from users WHERE id = %s)";
  32. $result = DB::select(sprintf($sql_format,$uid));
  33. if($result){
  34. return self::level($result);
  35. }
  36. return [];
  37. }
  38. public static function getUserSubscribeAndChargeInfoByOpenid($openid){
  39. $sql_format = "SELECT u.id,f.created_at as subscribe_time,u.openid,
  40. (SELECT ifnull(sum(price),0) from orders where uid = u.id and `status` = 'PAID' LIMIT 1)as amount,
  41. (SELECT ifnull(sum(price),0) from orders where uid=u.id and `status` = 'PAID' and created_at <= DATE_ADD(f.created_at,INTERVAL 3 day)) as three_day_amount
  42. FROM users u
  43. JOIN force_subscribe_users f on u.id = f.uid
  44. WHERE u.openid ='%s'";
  45. $result = DB::select(sprintf($sql_format,$openid));
  46. if($result){
  47. return self::level($result);
  48. }
  49. return [];
  50. }
  51. private static function level($res){
  52. $earliest_subscribe_time = $res[0]->subscribe_time;
  53. $subscribe_three_day_info = [];
  54. $subscribe_no_three_day_info = [];
  55. foreach ($res as $v){
  56. (strtotime($v->subscribe_time) < strtotime($earliest_subscribe_time)) && $earliest_subscribe_time = $v->subscribe_time;
  57. if(time()-strtotime($v->subscribe_time) >= 86400*3){
  58. array_push($subscribe_three_day_info,$v->amount);
  59. }else{
  60. array_push($subscribe_no_three_day_info,$v->three_day_amount);
  61. }
  62. }
  63. $result = [
  64. 'earliest_subscribe_time'=>$earliest_subscribe_time,
  65. 'property'=>'',
  66. 'type'=>'',
  67. 'openid'=> $res[0]->openid
  68. ];
  69. if($subscribe_three_day_info){
  70. //存量用户
  71. $result['type'] = 'CUILIANG';
  72. $amount = round(array_sum($subscribe_three_day_info)/count($subscribe_three_day_info),2);
  73. if($amount>15){
  74. $result['property'] = 'high';
  75. }elseif($amount >2){
  76. $result['property'] = 'medium';
  77. } elseif($amount >0){
  78. $result['property'] = 'low';
  79. } else{
  80. $result['property'] = 'none';
  81. }
  82. }else{
  83. //新用户
  84. $result['type'] = 'NEW';
  85. if($subscribe_no_three_day_info)
  86. $amount = max($subscribe_no_three_day_info);
  87. else
  88. $amount = 0;
  89. if($amount>=50){
  90. $result['property'] = 'high';
  91. }elseif($amount >2){
  92. $result['property'] = 'medium';
  93. } elseif($amount >0){
  94. $result['property'] = 'low';
  95. } else{
  96. $result['property'] = 'none';
  97. }
  98. }
  99. return $result;
  100. }
  101. public static function update($openid,$property='',$type=''){
  102. if(empty($property) && empty($type)) return ;
  103. $update_info = [];
  104. $property && $update_info['property'] = $property;
  105. $type && $update_info['type'] = $type;
  106. UserDivisionCpcProperty::where('openid',$openid)->where('is_enable',1)->update($update_info);
  107. }
  108. public static function createorUpdate($data){
  109. $old = UserDivisionCpcProperty::where('openid',$data['openid'])->where('is_enable',1)->first();
  110. if(!$old){
  111. UserDivisionCpcProperty::create([
  112. 'openid'=>$data['openid'] ,
  113. 'property'=>$data['property'] ,
  114. 'is_enable'=>1 ,
  115. 'type'=>$data['type'] ,
  116. 'earliest_subscribe_time'=>$data['earliest_subscribe_time']
  117. ]);
  118. }else{
  119. $old->property = $data['property'];
  120. $old->type = $data['type'];
  121. $old->save();
  122. }
  123. }
  124. public static function afterForceSubscribe($uid){
  125. $sql_format = "SELECT u.id,f.created_at as subscribe_time,u.openid,
  126. (SELECT ifnull(sum(price),0) from orders where uid = u.id and `status` = 'PAID' LIMIT 1)as amount,
  127. (SELECT ifnull(sum(price),0) from orders where uid=u.id and `status` = 'PAID' and created_at <= DATE_ADD(f.created_at,INTERVAL 3 day)) as three_day_amount
  128. FROM users u
  129. JOIN force_subscribe_users f on u.id = f.uid
  130. WHERE u.openid in (SELECT openid from users WHERE id = %s)";
  131. $res = DB::select(sprintf($sql_format,$uid));
  132. if(!$res) return ;
  133. //判断用户属性
  134. $earliest_subscribe_time = $res[0]->subscribe_time;
  135. $subscribe_total_info = [];
  136. $subscribe_no_three_day_info = [];
  137. foreach ($res as $v){
  138. (strtotime($v->subscribe_time) < strtotime($earliest_subscribe_time)) && $earliest_subscribe_time = $v->subscribe_time;
  139. if(time()-strtotime($v->subscribe_time) >= 86400*3){
  140. array_push($subscribe_total_info,$v->amount);
  141. }else{
  142. array_push($subscribe_no_three_day_info,$v->three_day_amount);
  143. }
  144. }
  145. $result = [
  146. 'earliest_subscribe_time'=>$earliest_subscribe_time,
  147. 'property'=>'',
  148. 'type'=>'',
  149. 'openid'=> $res[0]->openid
  150. ];
  151. if($subscribe_total_info){
  152. //存量用户
  153. $result['type'] = 'CUILIANG';
  154. $amount = round(array_sum($subscribe_total_info)/count($subscribe_total_info),2);
  155. if($amount>15){
  156. $result['property'] = 'high';
  157. }elseif($amount >2){
  158. $result['property'] = 'medium';
  159. } elseif($amount >0){
  160. $result['property'] = 'low';
  161. } else{
  162. $result['property'] = 'none';
  163. }
  164. }else{
  165. //新用户
  166. $result['type'] = 'NEW';
  167. if($subscribe_no_three_day_info)
  168. $amount = max($subscribe_no_three_day_info);
  169. else
  170. $amount = 0;
  171. if($amount>50){
  172. $result['property'] = 'high';
  173. }elseif($amount >2){
  174. $result['property'] = 'medium';
  175. } elseif($amount >0){
  176. $result['property'] = 'low';
  177. } else{
  178. $result['property'] = 'none';
  179. }
  180. }
  181. //保存或者创建用户属性
  182. $old = DB::table('user_division_cpc_property')->where('openid',$result['openid'])->where('is_enable',1)->first();
  183. if(!$old){
  184. UserDivisionCpcProperty::create([
  185. 'openid'=>$result['openid'] ,
  186. 'property'=>$result['property'] ,
  187. 'is_enable'=>1 ,
  188. 'type'=>$result['type'] ,
  189. 'earliest_subscribe_time'=>$result['earliest_subscribe_time'],
  190. 'updated_at'=>date('Y-m-d H:i:s'),
  191. 'created_at'=>date('Y-m-d H:i:s')
  192. ]);
  193. }else{
  194. DB::table('user_division_cpc_property')->where('openid',$result['openid'])->where('is_enable',1)->update(
  195. [
  196. 'type'=>$result['type'] ,
  197. 'property'=>$result['property'] ,
  198. 'updated_at'=>date('Y-m-d H:i:s')
  199. ]
  200. );
  201. }
  202. }
  203. /**
  204. * Openid一对一注册uid,充值超过30元直接成为高净值用户,否则注册3天后做净值分档;
  205. * Openid一对多注册uid,注册3天以上成为有效uid,有效uid充值总额比uid个数;
  206. * 净值区间无论一对一注册uid还是一对多注册uid:
  207. * 低净值:0<充值<10,openid数占比35.51%,充值占比6.03%;
  208. * 中净值:10=<充值<=30,openid数占比32.89%,充值占比23.81%;
  209. * 高净值:充值>30,openid数占比31.60%,充值占比70.16%;
  210. * @param $uid
  211. */
  212. public static function calculateUserPropertyV2($uid)
  213. {
  214. $sql = "SELECT users.id as uid,users.openid,users.created_at as register,(select SUM(price) from orders where orders.uid = users.id and `status` = 'PAID') as price FROM users
  215. WHERE openid in (SELECT openid FROM users WHERE id = $uid)";
  216. $result = DB::select($sql);
  217. if (!$result) return [];
  218. if(count($result) == 1 ){
  219. if($result[0]->price && $result[0]->price>30){
  220. return ['openid'=>$result[0]->openid,'property'=>'high'];
  221. }
  222. if(time()-strtotime($result[0]->register) < 3*86400){
  223. return ['openid'=>$result[0]->openid,'property'=>'undefined'];
  224. }
  225. }
  226. $valid_user_num = 0;
  227. $amount = 0;
  228. $openid = '';
  229. $all_amount = 0;
  230. foreach ($result as $item){
  231. $openid = $item->openid;
  232. if($item->price) $all_amount += $item->price;
  233. if(time()-strtotime($item->register) < 3*86400) continue;
  234. if($item->price) $amount += $item->price;
  235. $valid_user_num += 1;
  236. }
  237. if(!$valid_user_num){
  238. if($all_amount)return ['openid'=>$openid,'property'=>'undefined'];
  239. return [];
  240. }
  241. $average_amount = $amount/$valid_user_num;
  242. if($average_amount >30){
  243. return ['openid'=>$openid,'property'=>'high'];
  244. }elseif ($average_amount >=10){
  245. return ['openid'=>$openid,'property'=>'medium'];
  246. }else{
  247. return ['openid'=>$openid,'property'=>'low'];
  248. }
  249. }
  250. public static function userLevelV2($openid){
  251. $result = UserDivisionCpcPropertyV2::where('openid',$openid)->where('is_enable',1)->select('property')->first();
  252. if($result)
  253. return $result->property;
  254. $sql_format = 'select id,created_at from users WHERE openid="%s" ORDER by created_at limit 1';
  255. $info = DB::select(sprintf($sql_format,$openid));
  256. if(!$info) return 'unknown';
  257. foreach ($info as $item){
  258. if( time()-strtotime($item->created_at) > 3*86400 )
  259. return 'none';
  260. }
  261. return 'unknown';
  262. }
  263. public static function getUserPropertyV2($uid){
  264. $result = UserDivisionCpcPropertyV2::join('users','users.openid','=','user_division_cpc_property_v2.openid')
  265. ->where('users.id',$uid)
  266. ->select('user_division_cpc_property_v2.property')->first();
  267. if($result)
  268. return $result->property;
  269. $sql_format = 'select id,created_at from users WHERE openid = (select openid FROM users WHERE id=%s) ORDER by created_at limit 1';
  270. $info = DB::select(sprintf($sql_format,$uid));
  271. if(!$info) return 'unknown';
  272. foreach ($info as $item){
  273. if( time()-strtotime($item->created_at) > 3*86400 )
  274. return 'none';
  275. }
  276. return 'unknown';
  277. }
  278. public static function updateV2($openid,$property=''){
  279. if(empty($property)) return ;
  280. $update_info = [];
  281. $property && $update_info['property'] = $property;
  282. UserDivisionCpcPropertyV2::where('openid',$openid)->where('is_enable',1)->update($update_info);
  283. }
  284. public static function createorUpdateV2($data){
  285. $old = UserDivisionCpcPropertyV2::where('openid',$data['openid'])->where('is_enable',1)->first();
  286. if(!$old){
  287. UserDivisionCpcPropertyV2::create([
  288. 'openid'=>$data['openid'] ,
  289. 'property'=>$data['property'] ,
  290. 'is_enable'=>1
  291. ]);
  292. }else{
  293. $old->property = $data['property'];
  294. $old->save();
  295. }
  296. }
  297. }