Member.php 96 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184
  1. <?php
  2. namespace app\weixin\model;
  3. use app\weixin\service\PRedis;
  4. use think\Db;
  5. use think\Model;
  6. class Member extends Model
  7. {
  8. protected $table = 'sg_user';
  9. /**
  10. * 注册用户
  11. * @param $params 注册参数
  12. * @return int|string
  13. */
  14. public static function regMember($params)
  15. {
  16. $mobile = isset($params['mobile']) ? trim($params['mobile']) : '';
  17. $userPass = isset($params['password']) ? trim($params['password']) : '';
  18. $payPass = isset($params['pay_password']) ? trim($params['pay_password']) : '';
  19. if ($mobile && Member::where(['user_login' => $mobile])->value('id')) {
  20. return 2001;
  21. }
  22. $userName = $mobile ? $mobile : makeUserName();
  23. $userPass = $userPass ? cmf_password($userPass) : cmf_password('123456');
  24. $payPass = $payPass ? cmf_password($payPass) : $userPass;
  25. $wxInfo = isset($params['wxInfo']) ? $params['wxInfo'] : [];
  26. $openid = isset($wxInfo['openid']) ? trim($wxInfo['openid']) : '';
  27. $headimgurl = isset($wxInfo['headimgurl']) ? trim($wxInfo['headimgurl']) : '';
  28. $nickname = isset($wxInfo['nickname']) ? trim($wxInfo['nickname']) : $userName;
  29. if (empty($openid)) {
  30. return false;
  31. }
  32. $data = [
  33. 'user_type' => 2,
  34. 'sex' => isset($params['sex']) ? intval($params['sex']) : 0,
  35. 'openid' => $openid,
  36. 'parent_id' => isset($params['parent_id']) ? intval($params['parent_id']) : 0,
  37. 'user_nickname' => isset($params['user_nickname']) ? trim($params['user_nickname']) : $nickname,
  38. 'avatar' => isset($params['avatar']) ? trim($params['avatar']) : $headimgurl,
  39. 'user_login' => $userName,
  40. 'user_pass' => $userPass,
  41. 'pay_password' => $payPass,
  42. 'is_follow' => isset($wxInfo['subscribe']) ? intval($wxInfo['subscribe']) : 0,
  43. 'last_login_ip' => get_client_ip(),
  44. 'last_login_time' => time(),
  45. 'create_time' => time(),
  46. ];
  47. if ($mobile) {
  48. $data['mobile'] = $mobile;
  49. }
  50. $userId = Member::where(['openid' => $openid])
  51. ->where('user_status','>=', 0)
  52. ->value('id');
  53. PRedis::set('test:'.$openid, $data, 600);
  54. if (!$userId) {
  55. $userId = Member::insertGetId($data);
  56. return ['userId' => $userId, 'type' => 2];
  57. } else {
  58. $data = [
  59. 'last_login_ip' => get_client_ip(),
  60. 'updated_at' => date('Y-m-d H:i:s'),
  61. ];
  62. Member::where(['openid' => $openid])
  63. ->where('user_status','>=', 0)
  64. ->update($data);
  65. return false;
  66. }
  67. }
  68. /**
  69. * 用户登录
  70. * @param $params
  71. * @return array|int|null|\PDOStatement|string|Model
  72. * @throws \think\Exception
  73. * @throws \think\db\exception\DataNotFoundException
  74. * @throws \think\db\exception\ModelNotFoundException
  75. * @throws \think\exception\DbException
  76. * @throws \think\exception\PDOException
  77. */
  78. public static function login($params)
  79. {
  80. $userName = isset($params['mobile']) ? trim($params['mobile']) : '';
  81. $password = isset($params['password']) ? trim($params['password']) : '';
  82. $field = 'id,user_login,sex,user_nickname,avatar,openid,user_pass,user_type,score,balance,user_status';
  83. $userInfo = Member::where(['user_login' => $userName])->field($field)->find();
  84. $userPass = isset($userInfo['user_pass']) ? $userInfo['user_pass'] : '';
  85. $userStatus = isset($userInfo['user_status']) ? intval($userInfo['user_status']) : 0;
  86. if (empty($userInfo)) {
  87. return 2100;
  88. }
  89. $userInfo = $userInfo->toArray();
  90. if (!cmf_compare_password($password, $userPass)) {
  91. return 2101;
  92. }
  93. if ($userStatus != 1) {
  94. return 2102;
  95. }
  96. // 更新登录数据
  97. $updateData = [
  98. 'updated_at' => date('Y-m-d H:i:s'),
  99. 'last_login_ip' => get_client_ip(),
  100. 'last_login_time' => time(),
  101. ];
  102. $curOpenId = session('openid');
  103. $openid = isset($userInfo['openid']) ? trim($userInfo['openid']) : '';
  104. if ($curOpenId) {
  105. $checkId = Member::where(['openid' => $curOpenId])->value('id');
  106. if ((empty($checkId) && empty($openid)) || ($checkId && $checkId == $userInfo['id'])) {
  107. $wxInfo = session('wxInfo');
  108. $headimgurl = isset($wxInfo['headimgurl']) ? trim($wxInfo['headimgurl']) : '';
  109. $nickname = isset($wxInfo['nickname']) ? trim($wxInfo['nickname']) : $userName;
  110. $sex = isset($wxInfo['sex']) ? intval($wxInfo['sex']) : 0;
  111. if (empty($openid)) {
  112. $updateData['openid'] = $curOpenId;
  113. }
  114. if ($headimgurl && $userInfo['avatar'] != $headimgurl) {
  115. $updateData['avatar'] = $headimgurl;
  116. }
  117. if ($nickname && $userInfo['user_nickname'] != $nickname) {
  118. $updateData['user_nickname'] = $nickname;
  119. }
  120. if ($sex && $userInfo['sex'] != $sex) {
  121. $updateData['sex'] = $sex;
  122. }
  123. }
  124. }
  125. Member::where(['user_login' => $userName])->update($updateData);
  126. unset($userInfo['user_pass']);
  127. $userInfo = array_merge($userInfo, $updateData);
  128. session('userInfo', $userInfo);
  129. return $userInfo;
  130. }
  131. /**
  132. * 获取会员信息
  133. * @param $where 条件
  134. * @param string $field 字段
  135. * @return array|false|\PDOStatement|string|Model
  136. */
  137. public static function getInfo($where, $field = "")
  138. {
  139. $field = $field ? $field : 'id,openid,user_nickname,user_type,agent_type,agent_status,avatar,user_login,collect_expire,lat,lng,address,real_name,redheart,is_reg_profile,mobile,balance,user_status,wechat_account as wechat_code,is_heart,vip_auth,vip_expire,is_follow,freezing_choose';
  140. $info = self::where($where)->field($field)->order('user_status desc,id desc')->find();
  141. return $info ? $info->toArray() : [];
  142. }
  143. /**
  144. * 获取用户主页信息
  145. * @param $userId 用户ID
  146. * @param string $field 字段
  147. * @return array
  148. */
  149. public static function getHomeInfo($userId, $field = '', $type = 0)
  150. {
  151. $where = ['m.id' => $userId, 'm.user_status' => 1, 'm.user_type' => 2];
  152. $defaultField = 'm.id,m.user_nickname,m.avatar,m.mobile,m.sex,m.birthday,m.is_heart,m.real_name,m.agent_type,m.agent_status,up.age,up.height,up.weight,up.company,up.occupation,up.property,up.graduate,up.education,up.province,up.salary,up.city,up.district,up.home_province,up.home_city,up.home_district,up.introduce,up.family,up.hobby,up.purpose,up.cause,up.expect,up.show_company,up.show_graduate,up.married,up.tags,up.isinfo,up.photolist';
  153. if ($type == 3 || $type == 4) {
  154. $defaultField = 'm.id,m.user_nickname,m.avatar,m.mobile,m.sex,m.is_heart,m.birthday,m.real_name,up.age,up.height,up.weight,up.company,up.occupation,up.property,up.graduate,up.education,up.photolist,up.salary,up.province,up.city,up.district,up.home_province,up.home_city,up.home_district,up.introduce,up.brief,up.family,up.hobby,up.purpose,up.cause,up.expect,up.show_company,up.show_graduate,up.married,up.isinfo,m.vip_auth,m.vip_expire,up.education_check,up.position_check,up.idcard_check,up.introduce_img,up.family_img,up.hobby_img,up.purpose_img,up.tags,up.cause_img,up.expect_img';
  155. } else if ($type == 2) {
  156. $defaultField = 'm.id,m.user_nickname,m.wechat_account,m.mobile,m.sex,m.birthday,m.real_name,up.age,up.height,up.weight,up.company,up.occupation,up.property,up.graduate,m.is_heart,up.education,up.province,up.salary,up.city,up.district,up.home_province,up.home_city,up.home_district,up.married,up.wechat_code,up.qq,up.education_check,up.position_check,up.idcard_check';
  157. }
  158. $field = $field ? $field : $defaultField;
  159. $info = Member::alias('m')
  160. ->join('user_profile up', 'up.userid=m.id', 'left')
  161. ->field($field)
  162. ->where($where)
  163. ->where('user_status','>=',0)
  164. ->find();
  165. if ($info) {
  166. if (isset($info['avatar'])) {
  167. $info['avatar'] = cmf_get_image_preview_url($info['avatar']);
  168. }
  169. if (isset($info['brief'])) {
  170. $info['brief'] = htmlspecialchars_decode($info['brief']);
  171. }
  172. if (isset($info['sex'])) {
  173. $sexs = ['', '男', '女'];
  174. $sex = isset($info['sex']) ? $info['sex'] : 0;
  175. $info['sex_txt'] = isset($sexs[$sex]) ? $sexs[$sex] : '';
  176. }
  177. $info['albums'] = [];
  178. $photolist = isset($info['photolist']) ? $info['photolist'] : '';
  179. $photolist = $photolist ? explode(',', $photolist) : [];
  180. if ($photolist) {
  181. $albums = [];
  182. foreach ($photolist as $k => $val) {
  183. $albums[] = cmf_get_image_preview_url($val);
  184. }
  185. $info['albums'] = $albums;
  186. }
  187. if (isset($info['birthday'])) {
  188. $birthday = isset($info['birthday']) ? $info['birthday'] : 0;
  189. $info['birthday_txt'] = $birthday ? date('Y年m月d日', $birthday) : '';
  190. $info['birthday_code'] = $birthday ? date('Y-m-d', $birthday) : '';
  191. $info['birthday_day'] = $birthday ? date('y年', $birthday) : '';
  192. $year = $birthday? date('Y', $birthday) : 0;
  193. if($year){
  194. $info['age'] = date('Y')-$year;
  195. $info['year'] = $year;
  196. }
  197. }
  198. $info['height_txt'] = '';
  199. if (isset($info['height'])) {
  200. $height = isset($info['height']) ? intval($info['height']) : 0;
  201. $info['height'] = intval($height);
  202. $info['height_txt'] = $height ? intval($info['height']) . 'CM' : '无';
  203. }
  204. $info['weight_txt'] = '';
  205. if (isset($info['weight'])) {
  206. $weight = isset($info['weight']) ? intval($info['weight']) : 0;
  207. $info['weight'] = intval($weight);
  208. $info['weight_txt'] = $weight ? intval($info['weight']) . 'KG' : '无';
  209. }
  210. // 学历
  211. $info['education_txt'] = '';
  212. if (isset($info['education'])) {
  213. $educations = config('weixin.educations');
  214. $edu = isset($info['education']) ? $info['education'] : 0;
  215. $info['education_txt'] = isset($educations[$edu]) ? $educations[$edu] : '无';
  216. }
  217. // 资产
  218. $info['property_txt'] = '暂无';
  219. $property = isset($info['property']) ? $info['property'] : 0;
  220. if (isset($info['property'])) {
  221. $propertys = config('weixin.propertys');
  222. $info['property'] = $property;
  223. $info['property_txt'] = $property && isset($propertys[$property]) ? $propertys[$property] : '暂无';
  224. }
  225. // 地址
  226. $item['now_address'] = '';
  227. if (isset($info['province'])) {
  228. $province = isset($info['province']) ? trim($info['province']) : '';
  229. $city = isset($info['city']) ? trim($info['city']) : '';
  230. $info['now_address'] = trim($province . ' ' . $city);
  231. if ($type == 2) {
  232. $district = isset($info['district']) ? trim($info['district']) : '';
  233. $info['now_address'] = $info['now_address'] . ' ' . $district;
  234. }
  235. }
  236. $item['home_address'] = '';
  237. if (isset($info['home_province'])) {
  238. $homeProvince = isset($info['home_province']) ? trim($info['home_province']) : '';
  239. $homeCity = isset($info['home_city']) ? trim($info['home_city']) : '';
  240. $info['home_address'] = trim($homeProvince . ' ' . $homeCity);
  241. if ($type == 2) {
  242. $homeDistrict = isset($info['home_district']) ? trim($info['home_district']) : '';
  243. $info['home_address'] = $info['home_address'] . ' ' . $homeDistrict;
  244. }
  245. }
  246. // 格式化婚姻状况
  247. $item['married_txt'] = '';
  248. if (isset($info['married'])) {
  249. $marrieds = config('weixin.marrieds');
  250. $married = $info['married'] ? intval($info['married']) : 0;
  251. $info['married_txt'] = $married > 0 && isset($marrieds[$married - 1]) ? $marrieds[$married - 1] : '无';
  252. }
  253. // 隐藏手机号
  254. if ($type > 0 && isset($info['mobile'])) {
  255. /*if($type==2){
  256. $info['mobile_txt'] = $info['mobile'];
  257. }*/
  258. $info['mobile'] = $info['mobile'] ? formatStr($info['mobile']) : '';
  259. }
  260. if ($type == 4) {
  261. $info['introduce'] = isset($info['introduce']) ? str_replace("\n", "<br/>", $info['introduce']) : '';
  262. $info['family'] = isset($info['family']) ? str_replace(["\n", "\s"], ["<br/>", "&nbsp;"], $info['family']) : '';
  263. $info['hobby'] = isset($info['hobby']) ? str_replace(["\n", "\s"], ["<br/>", "&nbsp;"], $info['hobby']) : '';
  264. $info['purpose'] = isset($info['purpose']) ? str_replace(["\n", "\s"], ["<br/>", "&nbsp;"], $info['purpose']) : '';
  265. $info['cause'] = isset($info['cause']) ? str_replace(["\n", "\s"], ["<br/>", "&nbsp;"], $info['cause']) : '';
  266. $info['expect'] = isset($info['expect']) ? str_replace(["\n", "\s"], ["<br/>", "&nbsp;"], $info['expect']) : '';
  267. // VIP
  268. $vipAuth = isset($info['vip_auth']) ? intval($info['vip_auth']) : 0;
  269. $vipExpire = isset($info['vip_expire']) ? intval($info['vip_expire']) : 0;
  270. if($vipAuth && $vipExpire >= time()){
  271. $info['vip_auth'] = 1;
  272. $info['vip_expire'] = date('Y-m-d', $info['vip_expire']);
  273. }else{
  274. $info['vip_auth'] = 0;
  275. $info['vip_expire'] = '';
  276. }
  277. }
  278. // 个性标签
  279. if(isset($info['tags'])){
  280. $info['tags'] = $info['tags']? explode(',', $info['tags']) : [];
  281. }
  282. if ($type == 3 || $type == 4) {
  283. if (isset($info['introduce_img'])) {
  284. $info['introduce_img_preview'] = $info['introduce_img'] ? cmf_get_image_preview_url($info['introduce_img']) : '';
  285. }
  286. if (isset($info['family_img'])) {
  287. $info['family_img_preview'] = $info['family_img'] ? cmf_get_image_preview_url($info['family_img']) : '';
  288. }
  289. if (isset($info['hobby_img'])) {
  290. $info['hobby_img_preview'] = $info['hobby_img'] ? cmf_get_image_preview_url($info['hobby_img']) : '';
  291. }
  292. if (isset($info['purpose_img'])) {
  293. $info['purpose_img_preview'] = $info['purpose_img'] ? cmf_get_image_preview_url($info['purpose_img']) : '';
  294. }
  295. if (isset($info['cause_img'])) {
  296. $info['cause_img_preview'] = $info['cause_img'] ? cmf_get_image_preview_url($info['cause_img']) : '';
  297. }
  298. if (isset($info['expect_img'])) {
  299. $info['expect_img_preview'] = $info['expect_img'] ? cmf_get_image_preview_url($info['expect_img']) : '';
  300. }
  301. }
  302. }
  303. return $info ? $info->toArray() : [];
  304. }
  305. /**
  306. * 获取推荐会员数量
  307. * @param $userId
  308. * @return float|string
  309. */
  310. public static function getInviteCount($userId)
  311. {
  312. return Member::where(['parent_id' => $userId, 'user_type' => 2, 'user_status' => 1])->count('id');
  313. }
  314. /**
  315. * 验证获取验证用户信息
  316. * @param $account
  317. * @return array|bool
  318. * @throws \think\db\exception\DataNotFoundException
  319. * @throws \think\db\exception\ModelNotFoundException
  320. * @throws \think\exception\DbException
  321. */
  322. public static function checkUserInfo($account){
  323. $cacheKey = "cache:users:check_{$account}";
  324. $info = PRedis::get($cacheKey);
  325. if($info){
  326. return $info;
  327. }
  328. $field = 'id,openid,user_type,agent_type,agent_status,user_status,freezing_choose,is_reg_profile';
  329. $info = self::where(['openid|id'=> $account, 'user_type'=> 2])->field($field)->order('user_status desc,id desc')->find();
  330. $info = $info ? $info->toArray() : [];
  331. if($info){
  332. PRedis::set($cacheKey, $info,5);
  333. }
  334. return $info;
  335. }
  336. /**
  337. * 获取邀请的分销用户信息
  338. * @param $userId 当前用户ID
  339. * @param string $field 返回字段,连表u-当前用户,uu连表用户
  340. * @return array
  341. * @throws \think\db\exception\DataNotFoundException
  342. * @throws \think\db\exception\ModelNotFoundException
  343. * @throws \think\exception\DbException
  344. */
  345. public static function getInviteInfo($userId, $field=''){
  346. $field = $field? $field : 'u.id,uu.id as invite_id,uu.openid,uu.parent_id';
  347. $info = Member::alias('u')
  348. ->leftJoin('user uu','uu.id=u.parent_id')
  349. ->where(['u.id'=> $userId,'uu.user_type'=> 2,'uu.agent_type'=> 1,'uu.agent_status'=> 1])
  350. ->field($field)
  351. ->find();
  352. return $info? $info->toArray() : [];
  353. }
  354. /**
  355. * 充值记录
  356. * @param $params
  357. * @param int $pageSize
  358. * @return mixed
  359. */
  360. public static function getRechargeLog($params, $pageSize = 15)
  361. {
  362. $where = [];
  363. $userId = isset($params['user_id']) ? $params['user_id'] : 0;
  364. if ($userId) {
  365. $where['user_id'] = $userId;
  366. }
  367. $cwhere = $where;
  368. $cwhere['is_read'] = 2;
  369. $count = db('user_recharge_log')
  370. ->where($cwhere)
  371. ->where('status', 'gt', 0)
  372. ->count('id');
  373. if ($count) {
  374. db('user_recharge_log')
  375. ->where($cwhere)
  376. ->where('status', 'gt', 0)
  377. ->update(['is_read' => 1, 'updated_at' => date('Y-m-d H:i:s')]);
  378. }
  379. $dataList = db('user_recharge_log')
  380. ->where($where)
  381. ->field('id,type,order_sn,pay_type,money,pay_money,balance,remark,created_at,status')
  382. ->where('status', 'gt', 0)
  383. ->order("created_at desc")
  384. ->paginate($pageSize)
  385. ->each(function ($item, $k) {
  386. $item['format_time'] = date('Y年m月d日 H点i分', strtotime($item['created_at']));
  387. $item['money'] = in_array($item['type'], [1, 4, 5]) ? intval($item['money']) : $item['money'];
  388. return $item;
  389. });
  390. return $dataList ? $dataList->toArray() : [];
  391. }
  392. /**
  393. * 充值记录数
  394. * @param $userId
  395. * @param int $type
  396. * @return mixed
  397. */
  398. public static function getRechargeCount($userId, $type = 0)
  399. {
  400. $where = ['user_id' => $userId, 'is_read' => 2];
  401. if ($type) {
  402. $where['type'] = $type;
  403. }
  404. return db('user_recharge_log')
  405. ->where($where)
  406. ->where('status', 'gt', 0)
  407. ->count('id');
  408. }
  409. /**
  410. * 推荐用户
  411. * @param $params 参数
  412. * @param $page 分页
  413. * @param $pageSize 分页大小
  414. * @param string $field 字段
  415. * @return array|null|\PDOStatement|string|Model
  416. */
  417. public static function getRecommendList($params, $pageSize, $field = '')
  418. {
  419. $page = input('page', 1);
  420. $cacheKey = "cache:recommends:index_".$page.'_:'.md5(json_encode($params).$pageSize.$field);
  421. $dataList = PRedis::get($cacheKey);
  422. if($dataList){
  423. return $dataList;
  424. }
  425. $where = ['m.is_tuijian' => 1,'is_heart'=> 1, 'm.is_reg_profile' => 1, 'm.user_status' => 1, 'm.user_type' => 2];
  426. // 匹配当前用户信息:性别
  427. $sex = 0;
  428. $userId = isset($params['user_id']) ? intval($params['user_id']) : 0;
  429. if ($userId) {
  430. $sex = Member::where(['id' => $userId])->value('sex');
  431. if ($sex > 0) {
  432. $sex = $sex == 1 ? 2 : 1;
  433. }
  434. }
  435. $field = $field ? $field : 'm.id,m.user_nickname,m.real_name,m.lat,m.lng,m.address,m.birthday,m.avatar,m.create_time,m.sex,up.graduate,up.education,up.height,up.weight,up.company,up.occupation,up.province,up.city,up.show_graduate,m.vip_auth,m.is_heart,m.vip_expire,up.show_company,up.idcard_check,up.education_check,up.position_check,up.province,up.home_city,up.photolist,up.introduce';
  436. // 距离
  437. $info = Member::where(['id'=> $userId])->field('lat,lng')->find();
  438. $lat = isset($params['lat'])? $params['lat'] : 0.00;
  439. $lng = isset($params['lng'])? $params['lng'] : 0.00;
  440. $lat = $lat? $lat : (isset($info['lat'])? $info['lat'] : 0);
  441. $lng = $lng? $lng : (isset($info['lng'])? $info['lng'] : 0);
  442. if($lat && $lng){
  443. $field .= ",ROUND(
  444. 6378.138 * 2 * ASIN(
  445. SQRT(
  446. POW(
  447. SIN(
  448. (
  449. {$lat} * PI() / 180 - m.`lat` * PI() / 180
  450. ) / 2
  451. ),
  452. 2
  453. ) + COS({$lat} * PI() / 180) * COS(m.`lat` * PI() / 180) * POW(
  454. SIN(
  455. (
  456. {$lng} * PI() / 180 - m.`lng` * PI() / 180
  457. ) / 2
  458. ),
  459. 2
  460. )
  461. )
  462. ) * 1000
  463. ) AS distance";
  464. }
  465. $dataList = Member::alias('m')
  466. ->join('user_profile up', 'up.userid=m.id', 'left')
  467. ->field($field)
  468. ->where($where)
  469. ->where(function ($query) use ($sex, $params) {
  470. // 性别
  471. if ($sex > 0) {
  472. $query->where('m.sex', 'in', [0, $sex]);
  473. }
  474. // 年龄
  475. $age = isset($params['age'])? trim($params['age']) : '';
  476. if($age){
  477. $ages = explode('~', $age);
  478. $age1 = isset($ages[0])? intval($ages[0]) : 0;
  479. $age2 = isset($ages[1])? intval($ages[1]) : 0;
  480. if($age2){
  481. $query->where('up.age','>=', $age1)->where('up.age','<=', $age2);
  482. }else if($age1){
  483. $query->where('up.age','>=', $age1);
  484. }
  485. }
  486. // 身高
  487. $height = isset($params['height'])? trim($params['height']) : '';
  488. if($height){
  489. $heights = explode('~', $height);
  490. $height1 = isset($heights[0])? intval($heights[0]) : 0;
  491. $height2 = isset($heights[1])? intval($heights[1]) : 0;
  492. if($height2){
  493. $query->where('up.height','>=', $height1)->where('up.height','<=', $height2);
  494. }else if($height1){
  495. $query->where('up.height','>=', $height1);
  496. }
  497. }
  498. // 学历
  499. $education = isset($params['education'])? intval($params['education']) : 0;
  500. if($education>0){
  501. $op = $education==3? '>=' : '=';
  502. $query->where('up.education',$op, $education);
  503. }
  504. // 婚姻状况
  505. $married = isset($params['married'])? intval($params['married']) : 0;
  506. if($married>0){
  507. $query->where('up.married','=', $married);
  508. }
  509. return $query;
  510. })
  511. ->where('m.id', '>', 0)
  512. ->where('m.id', 'not in', $userId)
  513. ->order('m.tuijian_time desc,m.id')
  514. ->paginate($pageSize)
  515. ->each(function ($item, $k) {
  516. $item['avatar'] = isset($item['avatar']) ? cmf_get_image_preview_url($item['avatar']) : '';
  517. $birthday = isset($item['birthday']) ? $item['birthday'] : 0;
  518. $item['birthday_txt'] = $birthday ? date('Y年m月d日', $birthday) : '';
  519. $item['birthday_day'] = $birthday ? date('y年', $birthday) : '';
  520. $height = isset($item['height']) ? intval($item['height']) : 0;
  521. $item['height_txt'] = $height ? intval($item['height']) . 'CM' : '';
  522. $weight = isset($item['weight']) ? intval($item['weight']) : 0;
  523. $item['weight_txt'] = $weight ? intval($item['weight']) . 'KG' : '';
  524. // VIP
  525. $vipAuth = isset($item['vip_auth']) ? intval($item['vip_auth']) : 0;
  526. $vipExpire = isset($item['vip_expire']) ? intval($item['vip_expire']) : 0;
  527. if($vipAuth && $vipExpire >= time()){
  528. $item['vip_auth'] = 1;
  529. $item['vip_expire'] = date('Y-m-d', $item['vip_expire']);
  530. }else{
  531. $item['vip_auth'] = 0;
  532. $item['vip_expire'] = '';
  533. }
  534. // 学历
  535. $educations = config('weixin.educations');
  536. $edu = isset($item['education']) ? $item['education'] : 0;
  537. $item['education_txt'] = $edu && isset($educations[$edu]) ? $educations[$edu] : '';
  538. // 地址
  539. $province = isset($item['province']) ? trim($item['province']) : '';
  540. $city = isset($item['city']) ? trim($item['city']) : '';
  541. $homeProvince = isset($item['home_province']) ? trim($item['home_province']) : '';
  542. $homeCity = isset($item['home_city']) ? trim($item['home_city']) : '';
  543. $item['now_address'] = trim($province . ' ' . $city);
  544. $item['home_address'] = trim($homeProvince . ' ' . $homeCity);
  545. $albums = [];
  546. $photolist = isset($item['photolist']) ? $item['photolist'] : '';
  547. $photolist = $photolist ? explode(',', $photolist) : [];
  548. if ($photolist) {
  549. foreach ($photolist as $k => $val) {
  550. $albums[] = cmf_get_image_preview_url($val);
  551. }
  552. }
  553. $item['pic_count'] = count($albums);
  554. // 坐标距离
  555. $item['distance'] = isset($item['distance'])? $item['distance'] : '';
  556. if($item['lat']<=0 || $item['lng']<=0){
  557. $item['distance'] = '';
  558. }else{
  559. $item['distance'] = $item['distance']>=1000? round($item['distance']/1000, 2).'km' : ($item['distance']? $item['distance'] . 'm' : '');
  560. }
  561. // 地址
  562. $address = isset($item['address'])? $item['address'] : '';
  563. $addressData = $address? explode(',', $address) : [];
  564. $item['district'] = isset($addressData[2])? $addressData[2] : '';
  565. return $item;
  566. });
  567. $dataList = $dataList ? $dataList->toArray() : [];
  568. //PRedis::set('recommends:query:' . $userId, Db::name('user')->getLastSql(), 600);
  569. PRedis::set($cacheKey, $dataList, 10);
  570. return $dataList;
  571. }
  572. /**
  573. * 怦然心动推荐用户
  574. * @param $userId 当前用户
  575. * @param string $field 字段
  576. * @return array|null|\PDOStatement|string|Model
  577. */
  578. public static function getHeartList($userId, $field = '', $refresh = false)
  579. {
  580. // 获取已经推荐的有效数据
  581. $updated = false;
  582. $dataList = [];
  583. $cacheKey = "hearts:recommend:" . $userId;
  584. $recommendIds = PRedis::get($cacheKey);
  585. $where = ['m.is_heart' => 1, 'm.is_reg_profile' => 1, 'm.user_status' => 1, 'm.user_type' => 2];
  586. $heartAt = Member::where(['id' => $userId])->value('heart_recommend_at');
  587. $heartAt = $heartAt ? date('Y-m-d', strtotime($heartAt)) : '';
  588. $ids = [];
  589. if (!PRedis::exists($cacheKey) || $refresh) {
  590. // 验证今天是否推荐过
  591. /*$heartAt = Member::where(['id' => $userId])->value('heart_recommend_at');
  592. $heartAt = $heartAt ? date('Y-m-d', strtotime($heartAt)) : '';
  593. if ($heartAt == date('Y-m-d')) {
  594. return true;
  595. }*/
  596. // 获取推荐的人数设置
  597. $updated = true;
  598. $siteInfo = $siteInfo = cmf_get_site_info();
  599. $ageGap = isset($siteInfo['age_gap']) ? intval($siteInfo['age_gap']) : 0;
  600. $ageGap = $ageGap ? $ageGap : 0;
  601. $recommendNum = isset($siteInfo['recommend_num']) ? intval($siteInfo['recommend_num']) : 0;
  602. $recommendNum = $recommendNum ? $recommendNum : 1;
  603. // 用户性别
  604. $memberInfo = Member::getHomeInfo($userId, 'm.sex,up.age,up.city,m.vip_auth,m.vip_expire,up.home_province');
  605. $sex = isset($memberInfo['sex']) ? intval($memberInfo['sex']) : 0;
  606. if ($sex > 0) {
  607. $sex = $sex == 1 ? 2 : 1;
  608. }
  609. // 调整VIP推荐人数
  610. $isVip = false;
  611. $vipRecommendNum = isset($siteInfo['vip_recommend_num']) ? intval($siteInfo['vip_recommend_num']) : 0;
  612. $vipAuth = isset($memberInfo['vip_auth']) ? intval($memberInfo['vip_auth']) : 0;
  613. $vipExpire = isset($memberInfo['vip_expire']) ? intval($memberInfo['vip_expire']) : 0;
  614. if($vipAuth && $vipExpire >= time() && $vipRecommendNum > 0){
  615. $isVip = true;
  616. $recommendNum = $vipRecommendNum;
  617. }
  618. $conditions = Member::getMemberConditions($userId);
  619. //var_dump($conditions);
  620. $hasMatchData = Predis::get("hearts:hasMeatch:{$userId}");
  621. $ids = isset($hasMatchData['ids'])? $hasMatchData['ids'] : '';
  622. $ids = $ids? explode(',', $ids) : [];
  623. $hasExpire = isset($hasMatchData['expire'])? $hasMatchData['expire'] : 0;
  624. if(time() > $hasExpire || !$isVip){
  625. $ids = [];
  626. }
  627. // vip会员只推荐身份认证的
  628. if($isVip){
  629. $where['up.idcard_check'] = 2;
  630. }
  631. $recommendIds = Member::alias('m')
  632. ->join('user_profile up', 'up.userid=m.id', 'left')
  633. ->where($where)
  634. ->where(function ($query) use ($sex) {
  635. return $query->where('m.sex', 'in', [0, $sex]);
  636. })
  637. ->where(function ($query) use ($ids) {
  638. // 过滤一星期内已经推荐过的
  639. if($ids){
  640. return $query->where('m.id', 'not in', $ids);
  641. }else{
  642. return $query->where('m.id', '>', 0);
  643. }
  644. })
  645. ->where(function ($query) use ($conditions, $memberInfo, $ageGap) {
  646. $querys = $query;
  647. // 年龄
  648. $year = isset($conditions['year']) ? trim($conditions['year']) : '';
  649. if ($year) {
  650. $year = explode('~', $year);
  651. $data1 = isset($year[0]) ? intval($year[0]) : 0;
  652. $data2 = isset($year[1]) ? intval($year[1]) : 0;
  653. if ($data2) {
  654. $data1 = $data1 ? strtotime($data1 . '-01-01') : 0;
  655. $data2 = $data2 ? strtotime(($data2 + 1) . '-01-01') : 0;
  656. $querys = $querys->where('m.birthday', '>=', $data1 . '')->where('m.birthday', '<=', $data2);
  657. } else if ($data1) {
  658. $data1 = $data1 ? strtotime($data1 . '-01-01') : 0;
  659. $querys = $querys->where('m.birthday', '>=', $data1);
  660. }
  661. }
  662. // 身高
  663. $height = isset($conditions['height']) ? trim($conditions['height']) : '';
  664. if ($height) {
  665. $height = explode('~', $height);
  666. $data1 = isset($height[0]) ? intval($height[0]) : 0;
  667. $data2 = isset($height[1]) ? intval($height[1]) : 0;
  668. if ($data2) {
  669. $querys = $querys->where('up.height', '>=', $data1)->where('up.height', '<=', $data2);
  670. } else if ($data1) {
  671. $querys = $querys->where('up.height', '>=', $data1);
  672. }
  673. }
  674. // 体重
  675. $weight = isset($conditions['weight']) ? intval($conditions['weight']) : 0;
  676. if ($weight) {
  677. $dataArr = config('weixin.weights');
  678. $datas = isset($dataArr[$weight]) ? $dataArr[$weight] : [];
  679. $data1 = isset($datas['value1']) ? $datas['value1'] : 0;
  680. $data2 = isset($datas['value2']) ? $datas['value2'] : 0;
  681. if ($data2) {
  682. $querys = $querys->where('up.weight', '>=', $data1)->where('up.weight', '<=', $data2);
  683. } else if ($data1) {
  684. $querys = $querys->where('up.weight', '>=', $data1);
  685. }
  686. }
  687. // 收入
  688. $salary = isset($conditions['salary']) ? intval($conditions['salary']) : 0;
  689. if ($salary) {
  690. $dataArr = config('weixin.salarys');
  691. $datas = isset($dataArr[$salary]) ? $dataArr[$salary] : [];
  692. $data1 = isset($datas['value']) ? $datas['value'] : 0;
  693. $data2 = isset($datas['value2']) ? $datas['value2'] : 0;
  694. if ($data2) {
  695. $querys = $querys->where('up.salary', '>=', $data1)->where('up.salary', '<=', $data2);
  696. } else if ($data1) {
  697. $querys = $querys->where('up.salary', '=', $data1);
  698. }
  699. }
  700. // 所在城市
  701. $city = isset($memberInfo['city']) ? trim($memberInfo['city']) : '';
  702. $cityValue = isset($conditions['city']) ? trim($conditions['city']) : '';
  703. if ($cityValue > 0 && $city) {
  704. $querys = $querys->where('up.city', '=', $city);
  705. }
  706. // 家乡省市:是否同省
  707. $homeProvince = isset($memberInfo['home_province']) ? trim($memberInfo['home_province']) : '';
  708. $homeProvinceValue = isset($conditions['home_province']) ? trim($conditions['home_province']) : '';
  709. if ($homeProvinceValue > 0 && $homeProvince) {
  710. $querys = $querys->where('up.home_province', '=', $homeProvince);
  711. }
  712. // 学历
  713. $education = isset($conditions['education']) ? intval($conditions['education']) : 0;
  714. if ($education > 0) {
  715. // 硕士及以上或按学历匹配
  716. $op = $education == 3 ? '>=' : '=';
  717. $querys = $querys->where('up.education', $op, $education);
  718. }
  719. // 婚姻状态
  720. $married = isset($conditions['married']) ? intval($conditions['married']) : 0;
  721. if ($married > 0) {
  722. $querys = $querys->where('up.married', '>=', $married);
  723. }
  724. return $querys;
  725. })
  726. ->orderRaw('rand()')
  727. ->limit($recommendNum)
  728. ->column('m.id');
  729. PRedis::set('hearts:query:' . $userId, ['where'=> $where, 'ids'=> $ids, 'query'=> Member::getLastSql()], 24 * 3600);
  730. if(empty($recommendIds)){
  731. $recommendIds = Member::alias('m')
  732. ->join('user_profile up', 'up.userid=m.id', 'left')
  733. ->where($where)
  734. ->where(function ($query) use ($sex) {
  735. return $query->where('m.sex', 'in', [0, $sex]);
  736. })
  737. ->where(function ($query) use ($ids) {
  738. // 过滤一星期内已经推荐过的
  739. if($ids){
  740. return $query->where('m.id', 'not in', $ids);
  741. }else{
  742. return $query->where('m.id', '>', 0);
  743. }
  744. })
  745. ->where(function ($query) use ($conditions, $memberInfo, $ageGap) {
  746. $querys = $query;
  747. // 年龄
  748. $year = isset($conditions['year']) ? trim($conditions['year']) : '';
  749. if ($year) {
  750. $year = explode('~', $year);
  751. $data1 = isset($year[0]) ? intval($year[0]) : 0;
  752. $data2 = isset($year[1]) ? intval($year[1]) : 0;
  753. if ($data2) {
  754. $data1 = $data1 ? strtotime($data1 . '-01-01') : 0;
  755. $data2 = $data2 ? strtotime(($data2 + 1) . '-01-01') : 0;
  756. $querys = $querys->where('m.birthday', '>=', $data1 . '')->where('m.birthday', '<=', $data2);
  757. } else if ($data1) {
  758. $data1 = $data1 ? strtotime($data1 . '-01-01') : 0;
  759. $querys = $querys->where('m.birthday', '>=', $data1);
  760. }
  761. }
  762. // 身高
  763. $height = isset($conditions['height']) ? trim($conditions['height']) : '';
  764. if ($height) {
  765. $height = explode('~', $height);
  766. $data1 = isset($height[0]) ? intval($height[0]) : 0;
  767. $data2 = isset($height[1]) ? intval($height[1]) : 0;
  768. if ($data2) {
  769. $querys = $querys->where('up.height', '>=', $data1)->where('up.height', '<=', $data2);
  770. } else if ($data1) {
  771. $querys = $querys->where('up.height', '>=', $data1);
  772. }
  773. }
  774. // 收入
  775. $salary = isset($conditions['salary']) ? intval($conditions['salary']) : 0;
  776. if ($height<=0 && $salary) {
  777. $dataArr = config('weixin.salarys');
  778. $datas = isset($dataArr[$salary]) ? $dataArr[$salary] : [];
  779. $data1 = isset($datas['value']) ? $datas['value'] : 0;
  780. $data2 = isset($datas['value2']) ? $datas['value2'] : 0;
  781. if ($data2) {
  782. $querys = $querys->where('up.salary', '>=', $data1)->where('up.salary', '<=', $data2);
  783. } else if ($data1) {
  784. $querys = $querys->where('up.salary', '=', $data1);
  785. }
  786. }
  787. // 所在城市
  788. $city = isset($memberInfo['city']) ? trim($memberInfo['city']) : '';
  789. $cityValue = isset($conditions['city']) ? trim($conditions['city']) : '';
  790. if ($cityValue > 0 && $city) {
  791. $querys = $querys->where('up.city', '=', $city);
  792. }
  793. // 婚姻状态
  794. $married = isset($conditions['married']) ? intval($conditions['married']) : 0;
  795. if ($married > 0) {
  796. $querys = $querys->where('up.married', '>=', $married);
  797. }
  798. // 学历
  799. $education = isset($conditions['education']) ? intval($conditions['education']) : 0;
  800. if ($education > 0) {
  801. if($married >0 && $education==3){
  802. $querys = $querys->where('up.education', '>=', 1);
  803. }else if($married <=0){
  804. // 硕士及以上或按学历匹配
  805. $op = $education == 3 ? '>=' : '=';
  806. $querys = $querys->where('up.education', $op, $education);
  807. }
  808. }
  809. return $querys;
  810. })
  811. ->orderRaw('rand()')
  812. ->limit($recommendNum)
  813. ->column('m.id');
  814. }
  815. if ($recommendIds) {
  816. // 更新推荐日期
  817. Member::where(['id' => $userId])->update(['heart_recommend_at' => date('Y-m-d H:i:s')]);
  818. }
  819. $expire = isset($siteInfo['recommend_expire']) ? intval($siteInfo['recommend_expire']) : 0;
  820. $expire = $expire ? $expire : 24;
  821. if($recommendIds){
  822. PRedis::set($cacheKey, $recommendIds, $expire * 3600);
  823. }
  824. }
  825. // 获取数据
  826. if ($recommendIds) {
  827. $field = $field ? $field : 'm.id,m.user_nickname,m.real_name,m.birthday,m.lat,m.lng,m.address,m.avatar,m.create_time,m.sex,m.vip_auth,m.vip_expire,up.graduate,up.education,up.height,up.weight,up.company,up.occupation,up.province,up.city,up.show_graduate,up.show_company,up.home_province,up.home_city,up.photolist,up.introduce,up.idcard_check,up.education_check,up.position_check,up.introduce';
  828. // 距离
  829. $info = Member::where(['id'=> $userId])->field('lat,lng')->find();
  830. $lat = input('lat', 0.00);
  831. $lng = input('lng', 0.00);
  832. $lat = $lat? $lat : (isset($info['lat'])? $info['lat'] : 0);
  833. $lng = $lng? $lng : (isset($info['lng'])? $info['lng'] : 0);
  834. if($lat && $lng){
  835. $field .= ",ROUND(
  836. 6378.138 * 2 * ASIN(
  837. SQRT(
  838. POW(
  839. SIN(
  840. (
  841. {$lat} * PI() / 180 - m.`lat` * PI() / 180
  842. ) / 2
  843. ),
  844. 2
  845. ) + COS({$lat} * PI() / 180) * COS(m.`lat` * PI() / 180) * POW(
  846. SIN(
  847. (
  848. {$lng} * PI() / 180 - m.`lng` * PI() / 180
  849. ) / 2
  850. ),
  851. 2
  852. )
  853. )
  854. ) * 1000
  855. ) AS distance";
  856. }
  857. $dataList = Member::alias('m')
  858. ->join('user_profile up', 'up.userid=m.id', 'left')
  859. ->where('m.id', 'in', implode(',', $recommendIds))
  860. ->where(['m.is_heart' => 1, 'm.user_type' => 2, 'm.user_status' => 1])
  861. ->field($field)
  862. ->orderField('m.id', $recommendIds)
  863. ->paginate(count($recommendIds))
  864. ->each(function ($item, $k) {
  865. $item['avatar'] = isset($item['avatar']) ? cmf_get_image_preview_url($item['avatar']) : '';
  866. $birthday = isset($item['birthday']) ? $item['birthday'] : 0;
  867. $item['birthday_txt'] = $birthday ? date('Y年m月d日', $birthday) : '';
  868. $item['birthday_day'] = $birthday ? date('y年', $birthday) : '';
  869. $height = isset($item['height']) ? intval($item['height']) : 0;
  870. $item['height_txt'] = $height ? intval($item['height']) . 'CM' : '';
  871. $weight = isset($item['weight']) ? intval($item['weight']) : 0;
  872. $item['weight_txt'] = $weight ? intval($item['weight']) . 'KG' : '';
  873. // VIP
  874. $vipAuth = isset($item['vip_auth']) ? intval($item['vip_auth']) : 0;
  875. $vipExpire = isset($item['vip_expire']) ? intval($item['vip_expire']) : 0;
  876. if($vipAuth && $vipExpire >= time()){
  877. $item['vip_auth'] = 1;
  878. $item['vip_expire'] = date('Y-m-d', $item['vip_expire']);
  879. }else{
  880. $item['vip_auth'] = 0;
  881. $item['vip_expire'] = '';
  882. }
  883. // 学历
  884. $educations = config('weixin.educations');
  885. $edu = isset($item['education']) ? $item['education'] : 0;
  886. $item['education_txt'] = $edu && isset($educations[$edu]) ? $educations[$edu] : '';
  887. // 地址
  888. $province = isset($item['province']) ? trim($item['province']) : '';
  889. $city = isset($item['city']) ? trim($item['city']) : '';
  890. $homeProvince = isset($item['home_province']) ? trim($item['home_province']) : '';
  891. $homeCity = isset($item['home_city']) ? trim($item['home_city']) : '';
  892. $item['now_address'] = trim($province . ' ' . $city);
  893. $item['home_address'] = trim($homeProvince . ' ' . $homeCity);
  894. $albums = [];
  895. $photolist = isset($item['photolist']) ? $item['photolist'] : '';
  896. $photolist = $photolist ? explode(',', $photolist) : [];
  897. if ($photolist) {
  898. foreach ($photolist as $k => $val) {
  899. $albums[] = cmf_get_image_preview_url($val);
  900. }
  901. }
  902. $item['pic_count'] = count($albums);
  903. // 坐标距离
  904. $item['distance'] = isset($item['distance'])? $item['distance'] : '';
  905. if($item['lat']<=0 || $item['lng']<=0){
  906. $item['distance'] = '';
  907. }else{
  908. $item['distance'] = $item['distance']>=1000? round($item['distance']/1000, 2).'km' : ($item['distance']? $item['distance'] . 'm' : '');
  909. }
  910. // 地址
  911. $address = isset($item['address'])? $item['address'] : '';
  912. $addressData = $address? explode(',', $address) : [];
  913. $item['district'] = isset($addressData[2])? $addressData[2] : '';
  914. return $item;
  915. });
  916. // 过滤重复
  917. if($updated && $recommendIds){
  918. if($ids){
  919. $newIds = array_merge($ids, $recommendIds);
  920. Predis::set("hearts:hasMeatch:{$userId}", ['ids'=>implode(',', $newIds), 'expire'=> $hasExpire], 3*24*3600);
  921. }else{
  922. Predis::set("hearts:hasMeatch:{$userId}", ['ids'=>implode(',', $recommendIds), 'expire'=> time()+3*24*3600], 3*24*3600);
  923. }
  924. }
  925. PRedis::set('hearts:results:' . $userId . '_' . date('Ymd'), ['datalist' => $dataList, 'sql' => Member::getLastSql()], 3 * 3600 * 24);
  926. $dataList = $dataList ? $dataList->toArray() : [];
  927. }
  928. return $dataList;
  929. }
  930. /**
  931. * 获取用户匹配条件
  932. * @param $userId 当前用户
  933. * @return array|mixed
  934. */
  935. public static function getMemberConditions($userId)
  936. {
  937. $conditions = db('user_conditions')->where(['user_id' => $userId])->value('conditions');
  938. $conditions = $conditions ? json_decode($conditions, true) : [];
  939. return $conditions;
  940. }
  941. /**
  942. * 设置用户推荐条件,怦然心动条件
  943. * @param $userId 当前用户ID
  944. * @param $params 条件参数:age、height、weight、city、home_province、education、salary
  945. * @return int|string
  946. */
  947. public static function setMemberConditions($userId, $params)
  948. {
  949. // 条件数据
  950. $condition = [
  951. 'age' => isset($params['age']) ? intval($params['age']) : 0,
  952. 'height' => isset($params['height']) ? trim($params['height']) : '',
  953. 'weight' => isset($params['weight']) ? intval($params['weight']) : 0,
  954. 'city' => isset($params['city']) ? intval($params['city']) : 0,
  955. // 'home_province' => isset($params['home_province']) ? intval($params['home_province']) : 0,
  956. 'education' => isset($params['education']) ? intval($params['education']) : 0,
  957. 'salary' => isset($params['salary']) ? intval($params['salary']) : 0,
  958. 'married' => isset($params['married']) ? intval($params['married']) : 0,
  959. 'year' => isset($params['year']) ? trim($params['year']) : '',
  960. ];
  961. $data = [
  962. 'user_id' => $userId,
  963. 'conditions' => json_encode($condition, 256),
  964. 'updated_at' => date('Y-m-d H:i:s'),
  965. 'status' => 1,
  966. ];
  967. // 验证并添加或保存
  968. $check = db('user_conditions')->where(['user_id' => $userId])->value('id');
  969. if ($check) {
  970. $res = db('user_conditions')->where(['user_id' => $userId])->update($data);
  971. } else {
  972. $res = db('user_conditions')->insertGetId($data);
  973. }
  974. return $res;
  975. }
  976. /**
  977. * 用户关注
  978. * @param $userId 当前用户
  979. * @param $collectUid 关注的用户
  980. * @param int $opType
  981. * @return int
  982. */
  983. public static function collect($userId, $collectUid, $opType = 1)
  984. {
  985. if ($userId == $collectUid) {
  986. return 2114;
  987. }
  988. if (!Member::where(['id' => $collectUid])->value('id')) {
  989. return 2104;
  990. }
  991. // 验证性别
  992. $contactSex = Member::where(['id' => $collectUid])->value('sex');
  993. $sex = Member::where(['id' => $userId])->value('sex');
  994. if (!$sex || ($sex == $contactSex)) {
  995. return 2135;
  996. }
  997. // 验证数据
  998. $collectData = UserCollect::where(['user_id' => $userId, 'source_id' => $collectUid, 'type' => 1])
  999. ->field('id,status')
  1000. ->find();
  1001. // 关注
  1002. $collectId = isset($collectData['id']) ? $collectData['id'] : 0;
  1003. $status = isset($collectData['status']) ? $collectData['status'] : 0;
  1004. if ($opType == 1) {
  1005. if ($collectId && $status == 1) {
  1006. return 2105;
  1007. }
  1008. // 若收藏时间已失效更新时间
  1009. $collectExpire = Member::where(['id' => $userId])->value('collect_expire');
  1010. if ($collectExpire - time() <= 0) {
  1011. $siteInfo = $siteInfo = cmf_get_site_info();
  1012. $collectTime = isset($siteInfo['collect_time']) ? intval($siteInfo['collect_time']) : 0;
  1013. $collectTime = $collectTime ? $collectTime : 6;
  1014. Member::saveData(['id' => $userId], ['collect_expire' => time() + $collectTime * 3600]);
  1015. $memberInfo = Member::where(['id'=> $userId])->field('collect_expire,vip_auth,vip_expire')->find();
  1016. $vipAuth = isset($memberInfo['vip_auth']) ? intval($memberInfo['vip_auth']) : 0;
  1017. $vipExpire = isset($memberInfo['vip_expire']) ? $memberInfo['vip_expire'] : 0;
  1018. if(!$vipAuth || $vipExpire < time()){
  1019. UserCollect::where(['user_id' => $userId])
  1020. ->update(['status' => 2, 'updated_at' => date('Y-m-d H:i:s')]);
  1021. }
  1022. }
  1023. $data = [
  1024. 'user_id' => $userId,
  1025. 'source_id' => $collectUid,
  1026. 'type' => 1,
  1027. 'created_at' => date('Y-m-d H:i:s'),
  1028. 'status' => 1,
  1029. ];
  1030. if ($collectId) {
  1031. if (!UserCollect::where(['user_id' => $userId, 'id' => $collectId])
  1032. ->update(['status' => 1, 'updated_at' => date('Y-m-d H:i:s')])) {
  1033. return 2107;
  1034. }
  1035. } else {
  1036. if (!UserCollect::insertGetId($data)) {
  1037. return 2107;
  1038. }
  1039. }
  1040. // 操作日志
  1041. UserLog::saveLog(['user_id' => $userId, 'type' => 4, 'content' => "收藏用户:{$collectUid}"]);
  1042. // 通知
  1043. $openid = Member::where(['id' => $collectUid])->value('openid');
  1044. $memberInfo = Member::where(['id' => $userId])->field('openid,sex,user_nickname')->find();
  1045. $nickname = isset($memberInfo['user_nickname'])? $memberInfo['user_nickname'] : '未公开';
  1046. $sex = isset($memberInfo['sex'])? $memberInfo['sex'] : 0;
  1047. $sex = $sex == 1 ? '帅哥' : '美女';
  1048. $dateTime = date('Y.m.d H:i');
  1049. if ($openid) {
  1050. $params = [
  1051. 'title' => "有个{$sex}查看了你的名片并且关注了你\n\n关注时间:\t{$dateTime}",
  1052. // 'title' => "有一位{$sex}申请加您的微信并给您留言了!\n\n申请时间:\t{$dateTime}\n\n收到留言:\t{$remark}",
  1053. 'remark' => "点击查看(如果不想再收到该类型消息,可本公众号回复“隐身设置”进入链接设置为隐身)",
  1054. 'type' => 'contact',
  1055. 'keywords' => [
  1056. 'keyword1' => [
  1057. 'value' => $nickname . '(昵称)',
  1058. 'color' => '#173177',
  1059. ],
  1060. 'keyword2' => [
  1061. 'value' => '隐私信息不显示',
  1062. 'color' => '#173177',
  1063. ],
  1064. 'keyword3' => [
  1065. 'value' => '消息提醒',
  1066. 'color' => '#173177',
  1067. ],
  1068. ],
  1069. 'url' => url("/weixin/member/collect?type=2", [], '', true),
  1070. ];
  1071. PRedis::set('messages:collect:' .$userId.'_'.$collectUid.'_'. $openid, ['data' => $data, 'params' => $params], 600);
  1072. Wechat::sendTplMsg($openid, $params, false);
  1073. }
  1074. return true;
  1075. } // 取消关注
  1076. else if ($opType == 2) {
  1077. if (!$collectId) {
  1078. return 1003;
  1079. }
  1080. if ($status != 1) {
  1081. return 2115;
  1082. }
  1083. if (!UserCollect::where(['user_id' => $userId, 'source_id' => $collectUid, 'type' => 1])
  1084. ->update(['status' => 2, 'updated_at' => date('Y-m-d H:i:s')])) {
  1085. return 2109;
  1086. }
  1087. // 操作日志
  1088. UserLog::saveLog(['user_id' => $userId, 'type' => 4, 'content' => "取消收藏用户:{$collectUid}"]);
  1089. return true;
  1090. }
  1091. return 1009;
  1092. }
  1093. /**
  1094. * 保存信息
  1095. * @param $where
  1096. * @param $data
  1097. * @return int|string
  1098. */
  1099. public static function saveData($where, $data)
  1100. {
  1101. $data['updated_at'] = date('Y-m-d H:i:s');
  1102. return Member::where($where)->update($data);
  1103. }
  1104. /**
  1105. * 想认识处理
  1106. * @param $userId 用户ID
  1107. * @param $contactUid 认识用户ID
  1108. * @return array|int
  1109. */
  1110. public static function contactUser($userId, $contactUid, $remark = '')
  1111. {
  1112. if ($userId == $contactUid) {
  1113. return 2133;
  1114. }
  1115. $contactInfo = Member::where(['id' => $contactUid, 'user_type' => 2, 'user_status' => 1])
  1116. ->field('id,openid,user_nickname,sex,real_name,is_reg_profile')
  1117. ->find();
  1118. $memberInfo = Member::where(['id' => $userId, 'user_type' => 2, 'user_status' => 1])
  1119. ->field('id,openid,user_nickname,real_name,sex,is_reg_profile,redheart,vip_auth,vip_expire')
  1120. ->find();
  1121. if (empty($contactInfo) || empty($memberInfo)) {
  1122. return false;
  1123. }
  1124. // 性别验证
  1125. $contactSex = isset($contactInfo['sex']) ? intval($contactInfo['sex']) : 0;
  1126. $sex = isset($memberInfo['sex']) ? intval($memberInfo['sex']) : 0;
  1127. if (!$sex || ($sex == $contactSex)) {
  1128. return 2134;
  1129. }
  1130. // 完善资料
  1131. $isRegProfile = isset($memberInfo['is_reg_profile']) ? $memberInfo['is_reg_profile'] : 0;
  1132. if ($isRegProfile != 1) {
  1133. return 2103;
  1134. }
  1135. // 验证是否已认识
  1136. $contactData = UserContactLog::where(['user_id' => $userId, 'contact_uid' => $contactUid])
  1137. ->where('status', 'in', [1, 2, 3])
  1138. ->field('id,status')
  1139. ->find();
  1140. $checkId = isset($contactData['id']) ? $contactData['id'] : 0;
  1141. $status = isset($contactData['status']) ? $contactData['status'] : 0;
  1142. if ($checkId && $status != 4) {
  1143. return $status == 1 ? 2117 : 2118;
  1144. }
  1145. //
  1146. Db::startTrans();
  1147. // 扣除爱心账户
  1148. $accountConfig = cmf_get_option('account_config');
  1149. $contactPay = isset($accountConfig['contact_pay']) ? intval($accountConfig['contact_pay']) : 0;
  1150. $contactPay = $contactPay ? $contactPay : 1;
  1151. // 会员不需要收录费
  1152. $vipAuth = isset($memberInfo['vip_auth']) ? intval($memberInfo['vip_auth']) : 0;
  1153. $vipExpire = isset($memberInfo['vip_expire']) ? intval($memberInfo['vip_expire']) : 0;
  1154. $contactPay = $vipAuth && $vipExpire >= time() ? 0 : $contactPay;
  1155. if ($contactPay > 0) {
  1156. $redheart = isset($memberInfo['redheart']) ? intval($memberInfo['redheart']) : 0;
  1157. if ($redheart < $contactPay) {
  1158. Db::rollback();
  1159. return 2121;
  1160. }
  1161. $newRedheart = max(0, ($redheart - $contactPay));
  1162. $memberData = ['redheart' => $newRedheart, 'updated_at' => date('Y-m-d H:i:s')];
  1163. if (!Member::where(['id' => $userId])->update($memberData)) {
  1164. Db::rollback();
  1165. return false;
  1166. }
  1167. // 账户明细
  1168. $cNickname = isset($contactInfo['user_nickname']) ? $contactInfo['user_nickname'] : '';
  1169. $accountData = [
  1170. 'user_id' => $userId,
  1171. 'type' => 2,
  1172. 'account_type' => 1,
  1173. 'change_type' => 2,
  1174. 'money' => $contactPay,
  1175. 'balance' => $redheart,
  1176. 'remark' => "认识【{$cNickname}】请求成功,扣除{$contactPay}个爱心",
  1177. 'created_at' => date('Y-m-d H:i:s'),
  1178. 'status' => 2,
  1179. ];
  1180. PRedis::set('accounts:contact:' . $contactUid . '_' . $userId, $accountData, 600);
  1181. if (!AccountLog::insertGetId($accountData)) {
  1182. Db::rollback();
  1183. return false;
  1184. }
  1185. }
  1186. $data = [
  1187. 'user_id' => $userId,
  1188. 'contact_uid' => $contactUid,
  1189. 'cost_redheart' => $contactPay,
  1190. 'remark' => $remark,
  1191. 'created_at' => date('Y-m-d H:i:s'),
  1192. 'status' => 1,
  1193. ];
  1194. $cid = UserContactLog::insertGetId($data);
  1195. if (!$cid) {
  1196. Db::rollback();
  1197. return false;
  1198. }
  1199. Db::commit();
  1200. if ($cid) {
  1201. // 模板消息
  1202. $openid = isset($contactInfo['openid']) ? $contactInfo['openid'] : '';
  1203. $nickname = isset($memberInfo['user_nickname']) ? $memberInfo['user_nickname'] : '';
  1204. $cNickname = isset($contactInfo['user_nickname']) ? $contactInfo['user_nickname'] : '';
  1205. $sex = isset($memberInfo['sex']) ? $memberInfo['sex'] : 1;
  1206. $sex = $sex == 1 ? '男生' : '女生';
  1207. $dateTime = date('Y.m.d H:i');
  1208. if ($openid) {
  1209. $remark = $remark ? $remark : '无';
  1210. $params = [
  1211. 'title' => "对方留言:{$remark}",
  1212. // 'title' => "有一位{$sex}申请加您的微信并给您留言了!\n\n申请时间:\t{$dateTime}\n\n收到留言:\t{$remark}",
  1213. 'remark' => "点击查看(如果不想再收到该类型消息,可本公众号回复“隐身设置”进入链接设置为隐身)",
  1214. 'type' => 'contact',
  1215. 'keywords' => [
  1216. 'keyword1' => [
  1217. 'value' => $nickname . '(昵称)',
  1218. 'color' => '#173177',
  1219. ],
  1220. 'keyword2' => [
  1221. 'value' => '隐私信息不显示',
  1222. 'color' => '#173177',
  1223. ],
  1224. 'keyword3' => [
  1225. 'value' => '待处理',
  1226. 'color' => '#173177',
  1227. ],
  1228. ],
  1229. 'url' => url("/weixin/member/home?id={$userId}&cid={$cid}", [], '', true),
  1230. ];
  1231. PRedis::set('messages:contact:' . $openid, ['data' => $data, 'params' => $params], 600);
  1232. Wechat::sendTplMsg($openid, $params, false);
  1233. }
  1234. // 操作日志
  1235. UserLog::saveLog(['user_id' => $userId, 'type' => 4, 'content' => "申请用户{$cNickname}微信"]);
  1236. return ['id' => $cid];
  1237. } else {
  1238. return 2119;
  1239. }
  1240. }
  1241. /**
  1242. * @param $userId
  1243. * @param $cid
  1244. * @return bool|int
  1245. */
  1246. public static function contactConfirm($userId, $cid, $checkStatus)
  1247. {
  1248. // 验证是否
  1249. $contactData = UserContactLog::where(['id' => $cid, 'contact_uid' => $userId])
  1250. ->field('id,user_id,cost_redheart,is_read,status')
  1251. ->find();
  1252. $checkId = isset($contactData['id']) ? $contactData['id'] : 0;
  1253. $status = isset($contactData['status']) ? $contactData['status'] : 0;
  1254. $contactUid = isset($contactData['user_id']) ? $contactData['user_id'] : 0;
  1255. $isRead = isset($contactData['is_read']) ? $contactData['is_read'] : 0; // 是否已读
  1256. if ($checkId && $status != 1) {
  1257. return 2120;
  1258. }
  1259. if (empty($contactUid)) {
  1260. return 2111;
  1261. }
  1262. // 更新记录数据
  1263. $updateData = ['status' => $checkStatus, 'updated_at' => date('Y-m-d H:i:s')];
  1264. Db::startTrans();
  1265. if (!UserContactLog::where(['id' => $cid])->update($updateData)) {
  1266. Db::rollback();
  1267. return 2032;
  1268. }
  1269. // 当前用户信息
  1270. $field = 'm.user_nickname,m.real_name,m.openid,up.wechat_code,up.qq';
  1271. $memberInfo = Member::getHomeInfo($userId, $field);
  1272. $nickname = isset($memberInfo['user_nickname']) ? $memberInfo['user_nickname'] : '';
  1273. $field = 'm.redheart,m.user_nickname,m.real_name,m.openid,up.wechat_code,up.qq';
  1274. $contactUserInfo = Member::getHomeInfo($contactUid, $field);
  1275. $cOpenid = isset($contactUserInfo['openid']) ? $contactUserInfo['openid'] : '';
  1276. $cNickname = isset($contactUserInfo['user_nickname']) ? $contactUserInfo['user_nickname'] : '';
  1277. $redheart = isset($contactUserInfo['redheart']) ? intval($contactUserInfo['redheart']) : 0;
  1278. $contactPay = isset($contactData['cost_redheart']) ? intval($contactData['cost_redheart']) : 0;
  1279. // 已读或拒绝退款扣除的爱心
  1280. $accountConfig = cmf_get_option('account_config');
  1281. $applyRefundPay = isset($accountConfig['apply_refund_pay']) ? intval($accountConfig['apply_refund_pay']) : 0;
  1282. if($isRead || $checkStatus==3){
  1283. $applyRefundPay = $applyRefundPay ? $applyRefundPay : 0;
  1284. $refundHeart = $contactPay>$applyRefundPay? intval($contactPay-$applyRefundPay) : 0;
  1285. }else{
  1286. $refundHeart = $contactPay;
  1287. $applyRefundPay = 0;
  1288. }
  1289. // 审核失败退还扣除的爱心
  1290. if ($contactPay > 0 && ($checkStatus == 3 || $checkStatus == 4)) {
  1291. $newRedheart = max(0, ($redheart + $refundHeart));
  1292. $memberData = ['redheart' => $newRedheart, 'updated_at' => date('Y-m-d H:i:s')];
  1293. if (!Member::where(['id' => $contactUid])->update($memberData)) {
  1294. Db::rollback();
  1295. return 2031;
  1296. }
  1297. // 账户明细
  1298. $accountData = [
  1299. 'user_id' => $contactUid,
  1300. 'type' => 3,
  1301. 'account_type' => 1,
  1302. 'change_type' => 1,
  1303. 'money' => $refundHeart,
  1304. 'balance' => $redheart,
  1305. 'remark' => "认识【{$nickname}】" . ($checkStatus == 3 ? '审核失败' : '审核超时') . ",退还{$refundHeart}个爱心,扣除{$applyRefundPay}个爱心",
  1306. 'created_at' => date('Y-m-d H:i:s'),
  1307. 'status' => 2,
  1308. ];
  1309. PRedis::set('accounts:contact:' . $contactUid . '_' . $userId, $accountData, 600);
  1310. if (!AccountLog::insertGetId($accountData)) {
  1311. Db::rollback();
  1312. return false;
  1313. }
  1314. }
  1315. Db::commit();
  1316. // 发送模板信息
  1317. /*if($openid){
  1318. $cWechatCode = isset($contactUserInfo['wechat_code'])? trim($contactUserInfo['wechat_code']) : '';
  1319. $cqq = isset($contactUserInfo['qq'])? trim($contactUserInfo['qq']) : '';
  1320. $cWechatCode = $cWechatCode? $cWechatCode : '无';
  1321. $cqq = $cqq? $cqq : '无';
  1322. $params = [
  1323. 'title' => "【{$cRealname}】想认识您的请求已确认\n\n对方微信号:\t{$cWechatCode}\n\n对方QQ:\t{$cqq}",
  1324. 'remark' => "感谢您的使用,点击详情查看对方信息",
  1325. 'type' => 'contact',
  1326. 'keywords' => [
  1327. 'keyword1' => [
  1328. 'value' => '已确认',
  1329. 'color' => '#173177',
  1330. ],
  1331. 'keyword2' => [
  1332. 'value' => date('Y年m月d日 H点i分s秒'),
  1333. 'color' => '#173177',
  1334. ],
  1335. 'keyword3' => [
  1336. 'value' => "来自【{$cNickname}】,姓名:【{$cRealname}】的认识申请已经确认通过,请及时添加对方联系方式",
  1337. 'color' => '#173177',
  1338. ],
  1339. ],
  1340. 'url' => url("/weixin/member/home?id={$contactUid}&cid=$cid", '', '', true),
  1341. ];
  1342. PRedis::set('messages:contactConfirm_' . $userId.'_'.$contactUid, ['data' => $contactData, 'params' => $params], 600);
  1343. Wechat::sendTplMsg($openid, $params);
  1344. }*/
  1345. // 通知对方模板信息
  1346. if ($cOpenid) {
  1347. $wechatCode = isset($memberInfo['wechat_code']) ? trim($memberInfo['wechat_code']) : '';
  1348. $qq = isset($memberInfo['qq']) ? trim($memberInfo['qq']) : '';
  1349. $wechatCode = $wechatCode ? $wechatCode : '无';
  1350. $qq = $qq ? $qq : '无';
  1351. $dateTime = date('Y.m.d H:i');
  1352. if ($checkStatus == 2) {
  1353. $params = [
  1354. 'title' => "你喜欢的人也喜欢你啦\n\n对方姓名:\t{$nickname}(昵称)\n\n对方微信号: \t{$wechatCode}\n\n申请时间:\t{$dateTime}",
  1355. 'remark' => "脱单需主动,交友需谨慎!",
  1356. 'type' => 'contact_confirm',
  1357. 'keywords' => [
  1358. 'keyword1' => [
  1359. 'value' => '状态通知',
  1360. 'color' => '#173177',
  1361. ],
  1362. 'keyword2' => [
  1363. 'value' => '已接受',
  1364. 'color' => '#173177',
  1365. ],
  1366. ],
  1367. 'url' => url("/weixin/member/home?id={$userId}&cid={$cid}", '', '', true),
  1368. ];
  1369. } else if ($checkStatus == 3) {
  1370. // 是否扣除爱心
  1371. $remark = $applyRefundPay? "扣除{$applyRefundPay}颗后已经原路退回" : "已经全部原路退回";
  1372. $params = [
  1373. 'title' => "Soory!亲亲!{$nickname}拒绝了您的加微信申请,您支付的爱心{$remark}。别灰心哦,您一定会遇到更好的另一半~\n\n申请时间:\t{$dateTime}",
  1374. 'remark' => "天涯何处无芳草,去看看其他的异性吧!",
  1375. 'type' => 'contact_confirm',
  1376. 'keywords' => [
  1377. 'keyword1' => [
  1378. 'value' => '状态通知',
  1379. 'color' => '#173177',
  1380. ],
  1381. 'keyword2' => [
  1382. 'value' => '已拒绝',
  1383. 'color' => '#173177',
  1384. ],
  1385. ],
  1386. 'url' => url("/weixin/match/index", '', '', true),
  1387. ];
  1388. } else {
  1389. // 是否已读
  1390. $remark = $isRead && $applyRefundPay? "扣除{$applyRefundPay}颗后已经原路退回" : "已经全部原路退回";
  1391. $params = [
  1392. 'title' => "您好亲亲,非常抱歉{$nickname}未及时反馈而导致申请超时,您被扣除的爱心{$remark}。您还可以请客服帮您牵线增加成功率哦~\n\n申请时间:\t{$dateTime}",
  1393. 'remark' => "当你有勇气主动时,其实已经打败了那些看似优秀的人,遇见不易让客服牵线试试吧!",
  1394. 'type' => 'contact_confirm',
  1395. 'keywords' => [
  1396. 'keyword1' => [
  1397. 'value' => '状态通知',
  1398. 'color' => '#173177',
  1399. ],
  1400. 'keyword2' => [
  1401. 'value' => '过期失效',
  1402. 'color' => '#173177',
  1403. ],
  1404. ],
  1405. 'url' => url("/weixin/match/index", '', '', true),
  1406. ];
  1407. }
  1408. // 操作日志
  1409. if ($checkStatus == 2 || $checkStatus == 3) {
  1410. $content = $checkStatus == 2 ? "通过用户{$cNickname}微信申请" : "拒绝用户{$cNickname}微信申请";
  1411. UserLog::saveLog(['user_id' => $userId, 'type' => 4, 'content' => $content]);
  1412. }
  1413. PRedis::set('messages:contactConfirm:' . $contactUid . '_' . $userId, ['openid' => $cOpenid, 'data' => $contactData, 'params' => $params], 600);
  1414. Wechat::sendTplMsg($cOpenid, $params);
  1415. }
  1416. return ['id' => $cid];
  1417. }
  1418. /**
  1419. * 用户页面访问统计
  1420. * @param $userId 访问用户
  1421. * @param string $type 访问类型
  1422. * @param int $targetUid 目标用户
  1423. */
  1424. public static function visitCount($userId, $type = 'login', $targetUid = 0, $expire = 1)
  1425. {
  1426. $cacheKey = 'counts:users:' . date('Ymd') . '_' . $type;
  1427. $cacheTempKey = 'counts:usersTemp:' . $userId . '_' . $type . '_' . date('Ymd');
  1428. $checkUser = Member::where(['user_type' => 2, 'id' => $userId])
  1429. ->value('id');
  1430. if ($checkUser && $userId && !PRedis::get($cacheTempKey)) {
  1431. PRedis::set($cacheTempKey, ['userId' => $userId, 'type' => $type, 'target' => $targetUid], $expire * 3600);
  1432. $types = ['login' => '登录', 'match' => '访问单身推荐', 'heart' => '访问怦然心动', 'center' => '访问用户中心', 'home' => "访问用户[{$targetUid}]信息", 'activity' => '浏览活动列表', 'book' => '想要报名'];
  1433. $title = isset($types[$type]) ? $types[$type] : '访问平台';
  1434. if ($type != 'profile') {
  1435. UserLog::saveLog(['user_id' => $userId, 'type' => 4, 'content' => "【{$userId}】用户{$title}"]);
  1436. }
  1437. if (!PRedis::get($cacheKey)) {
  1438. PRedis::set($cacheKey, 1, 2 * 24 * 3600);
  1439. } else {
  1440. PRedis::inc($cacheKey, 1);
  1441. }
  1442. }
  1443. }
  1444. /**
  1445. * 获取匹配用户数据列表
  1446. * @param $matchUids
  1447. * @return array|bool
  1448. * @throws \think\db\exception\DataNotFoundException
  1449. * @throws \think\db\exception\ModelNotFoundException
  1450. * @throws \think\exception\DbException
  1451. */
  1452. public static function getMatchList($matchUids, $activityId=0){
  1453. if(empty($matchUids)){
  1454. return false;
  1455. }
  1456. $field = 'm.id,m.user_nickname,m.avatar,m.mobile,m.sex,m.birthday,m.is_heart,m.real_name,up.age,up.height,up.weight,up.company,up.occupation,up.property,up.graduate,up.education,up.province,up.salary,up.city,up.district,up.home_province,up.home_city,up.home_district,up.introduce,up.family,up.hobby,up.purpose,up.cause,up.expect,up.show_company,up.show_graduate,up.married,up.tags,up.isinfo,m.vip_auth,m.vip_expire,up.education_check,up.position_check,up.idcard_check';
  1457. $dataList = Member::alias('m')
  1458. ->leftJoin('user_profile up','up.userid=m.id')
  1459. ->where('m.id', 'in', $matchUids)
  1460. ->field($field)
  1461. ->select()
  1462. ->each(function($item) use($activityId){
  1463. if($activityId){
  1464. $item['book_no'] = Books::where(['uid'=> $item['id'],'aid'=> $activityId, 'status'=> 3])->value('book_num');
  1465. }
  1466. Member::formatUser($item);
  1467. });
  1468. return $dataList? $dataList->toArray() : [];
  1469. }
  1470. /**
  1471. * 格式化用户信息
  1472. * @param $item 数据
  1473. * @param $type
  1474. */
  1475. private static function formatUser(&$item, $type = 0){
  1476. if (isset($item['avatar'])) {
  1477. $item['avatar'] = cmf_get_image_preview_url($item['avatar']);
  1478. }
  1479. if (isset($item['brief'])) {
  1480. $item['brief'] = htmlspecialchars_decode($item['brief']);
  1481. }
  1482. if (isset($item['sex'])) {
  1483. $sexs = ['', '男', '女'];
  1484. $sex = isset($item['sex']) ? $item['sex'] : 0;
  1485. $item['sex_txt'] = isset($sexs[$sex]) ? $sexs[$sex] : '';
  1486. }
  1487. $item['albums'] = [];
  1488. $photolist = isset($item['photolist']) ? $item['photolist'] : '';
  1489. $photolist = $photolist ? explode(',', $photolist) : [];
  1490. if ($photolist) {
  1491. $albums = [];
  1492. foreach ($photolist as $k => $val) {
  1493. $albums[] = cmf_get_image_preview_url($val);
  1494. }
  1495. $item['albums'] = $albums;
  1496. }
  1497. if (isset($item['birthday'])) {
  1498. $birthday = isset($item['birthday']) ? $item['birthday'] : 0;
  1499. $item['birthday_txt'] = $birthday ? date('Y年m月d日', $birthday) : '';
  1500. $item['birthday_code'] = $birthday ? date('Y-m-d', $birthday) : '';
  1501. $item['birthday_day'] = $birthday ? date('y年', $birthday) : '';
  1502. }
  1503. $item['height_txt'] = '';
  1504. if (isset($item['height'])) {
  1505. $height = isset($item['height']) ? intval($item['height']) : 0;
  1506. $item['height'] = intval($height);
  1507. $item['height_txt'] = $height ? intval($item['height']) . 'CM' : '无';
  1508. }
  1509. $item['weight_txt'] = '';
  1510. if (isset($item['weight'])) {
  1511. $weight = isset($item['weight']) ? intval($item['weight']) : 0;
  1512. $item['weight'] = intval($weight);
  1513. $item['weight_txt'] = $weight ? intval($item['weight']) . 'KG' : '无';
  1514. }
  1515. // 学历
  1516. $item['education_txt'] = '';
  1517. if (isset($item['education'])) {
  1518. $educations = config('weixin.educations');
  1519. $edu = isset($item['education']) ? $item['education'] : 0;
  1520. $item['education_txt'] = isset($educations[$edu]) ? $educations[$edu] : '无';
  1521. }
  1522. // 资产
  1523. $item['property_txt'] = '暂无';
  1524. $property = isset($item['property']) ? $item['property'] : 0;
  1525. if (isset($item['property'])) {
  1526. $propertys = config('weixin.propertys');
  1527. $item['property'] = $property;
  1528. $item['property_txt'] = $property && isset($propertys[$property]) ? $propertys[$property] : '暂无';
  1529. }
  1530. // 地址
  1531. $item['now_address'] = '';
  1532. if (isset($item['province'])) {
  1533. $province = isset($item['province']) ? trim($item['province']) : '';
  1534. $city = isset($item['city']) ? trim($item['city']) : '';
  1535. $item['now_address'] = trim($province . ' ' . $city);
  1536. }
  1537. $item['home_address'] = '';
  1538. if (isset($item['home_province'])) {
  1539. $homeProvince = isset($item['home_province']) ? trim($item['home_province']) : '';
  1540. $homeCity = isset($item['home_city']) ? trim($item['home_city']) : '';
  1541. $item['home_address'] = trim($homeProvince . ' ' . $homeCity);
  1542. }
  1543. // 格式化婚姻状况
  1544. $item['married_txt'] = '';
  1545. if (isset($item['married'])) {
  1546. $marrieds = config('weixin.marrieds');
  1547. $married = $item['married'] ? intval($item['married']) : 0;
  1548. $item['married_txt'] = $married > 0 && isset($marrieds[$married - 1]) ? $marrieds[$married - 1] : '无';
  1549. }
  1550. }
  1551. /**
  1552. * 获取收到或发出消息数量
  1553. * @param $userId
  1554. * @param array $params
  1555. * @return float|int|string
  1556. */
  1557. public static function getMessageTotal($userId, $params=[]){
  1558. $type = isset($params['type'])? intval($params['type']) : 1;
  1559. // 我收到的
  1560. if($type == 1){
  1561. $where = ['uc.contact_uid'=> $userId];
  1562. $joinWhere = 'u.id=uc.user_id';
  1563. }else{
  1564. $where = ['uc.user_id'=> $userId];
  1565. $joinWhere = 'u.id=uc.contact_uid';
  1566. }
  1567. $status = isset($params['status'])? intval($params['status']) : 1;
  1568. return UserContactLog::alias('uc')
  1569. ->join('user u',$joinWhere,'left')
  1570. ->where($where)
  1571. ->where('u.id','>',0)
  1572. ->where(function($query) use ($status){
  1573. if($status == 1){
  1574. $query->where('uc.status','>', 1);
  1575. }else{
  1576. $query->where('uc.status',1);
  1577. }
  1578. })
  1579. ->count('uc.id');
  1580. }
  1581. /**
  1582. * 获取用户申请消息列表
  1583. * @param $params
  1584. * @param $pageSize
  1585. * @param string $field
  1586. * @return $this
  1587. */
  1588. public static function getMessageList($userId, $params=[], $pageSize=20, $field=''){
  1589. // 验证有效时间,会员不限制
  1590. $type = isset($params['type'])? intval($params['type']) : 1;
  1591. // 我收到的
  1592. if($type == 1){
  1593. $where = ['uc.contact_uid'=> $userId];
  1594. $joinWhere = 'u.id=uc.user_id';
  1595. }else{
  1596. $where = ['uc.user_id'=> $userId];
  1597. $joinWhere = 'u.id=uc.contact_uid';
  1598. }
  1599. $status = isset($params['status'])? intval($params['status']) : 1;
  1600. $siteInfo = cmf_get_site_info();
  1601. $expire = isset($siteInfo['contact_time']) ? intval($siteInfo['contact_time']) : 0;
  1602. $expire = $expire ? $expire : 1;
  1603. $field = $field? $field : 'uc.id,uc.user_id,uc.contact_uid,uc.created_at,uc.remark,uc.updated_at,uc.is_read,uc.status,u.id as uid,u.user_login,u.real_name,u.user_nickname,u.avatar,u.sex,u.birthday,mp.graduate,mp.education,mp.height,mp.weight,mp.show_graduate,mp.show_company,mp.company,mp.occupation,mp.province,mp.city,mp.home_province,mp.home_city';
  1604. $dataList = UserContactLog::alias('uc')
  1605. ->join('user u',$joinWhere,'left')
  1606. ->join('user_profile mp', 'mp.userid=u.id', 'left')
  1607. ->where($where)
  1608. ->where('u.id','>',0)
  1609. ->where(function($query) use ($status){
  1610. if($status == 1){
  1611. $query->where('uc.status', 1);
  1612. }else{
  1613. $query->where('uc.status', '>',1);
  1614. }
  1615. })
  1616. ->field($field)
  1617. ->order('uc.status asc,uc.created_at desc')
  1618. ->paginate($pageSize)
  1619. ->each(function($item, $k) use ($expire){
  1620. $expire = $expire? $expire*86400 : 0;
  1621. $status = isset($item['status'])? intval($item['status']) : 0;
  1622. $item['avatar'] = isset($item['avatar']) ? cmf_get_image_preview_url($item['avatar']) : '';
  1623. $rtime = $item['created_at']? strtotime($item['created_at']) : 0;
  1624. $rtime = $rtime>time()-$expire? $rtime-(time()-$expire) : 0;
  1625. $item['rtime'] = $rtime;
  1626. $rtime = $rtime>23*3600? ceil($rtime/86400).'天' : ($rtime>3600? ceil($rtime/3600).'小时' : ($rtime>60? ceil($rtime/60).'分钟' : ''));
  1627. if($status == 1){
  1628. if($rtime){
  1629. $item['time'] = '<em class="red">'.$rtime.'后</em> 自动拒绝';
  1630. }else{
  1631. $item['time'] = '待处理';
  1632. }
  1633. }else{
  1634. $item['time'] = $status == 2? '已通过':($status == 3? '已拒绝' : '待处理');
  1635. if($status == 4){
  1636. $info['time'] = '过期自动处理';
  1637. }
  1638. }
  1639. Member::formatUser($item);
  1640. return $item;
  1641. });
  1642. $dataList = $dataList? $dataList->toArray() : ['total'=> 0];
  1643. $dataList['total1'] = Member::getMessageTotal($userId, $params);
  1644. return $dataList;
  1645. }
  1646. /**
  1647. * 获取用户申请消息列表
  1648. * @param $params
  1649. * @param $pageSize
  1650. * @param string $field
  1651. * @return $this
  1652. */
  1653. public static function getMessageInfo($id, $userId=0, $field=''){
  1654. $siteInfo = cmf_get_site_info();
  1655. $expire = isset($siteInfo['contact_time']) ? intval($siteInfo['contact_time']) : 0;
  1656. $expire = $expire ? $expire : 1;
  1657. $type = 1;
  1658. $joinWhere = 'u.id=uc.user_id';
  1659. $data = UserContactLog::where(['id'=> $id])->field('user_id,contact_uid')->find();
  1660. if($userId && isset($data['user_id']) && $data['user_id'] == $userId){
  1661. $joinWhere = 'u.id=uc.contact_uid';
  1662. $type = 2;
  1663. }
  1664. $field = $field? $field : 'uc.id,uc.user_id,uc.contact_uid,uc.created_at,uc.remark,uc.updated_at,uc.is_read,uc.status,u.id as uid,u.user_login,u.real_name,u.user_nickname,u.avatar,u.sex,u.birthday,mp.graduate,mp.education,mp.height,mp.weight,mp.show_graduate,mp.show_company,mp.company,mp.occupation,mp.province,mp.city,mp.home_province,mp.home_city,mp.education_check,mp.position_check,mp.idcard_check';
  1665. $info = UserContactLog::alias('uc')
  1666. ->join('user u', $joinWhere,'left')
  1667. ->join('user_profile mp', 'mp.userid=u.id', 'left')
  1668. ->where(['uc.id'=> $id])
  1669. ->where('u.id','>',0)
  1670. ->field($field)
  1671. ->find();
  1672. $info = $info? $info->toArray() : [];
  1673. if($info){
  1674. $info['type'] = $type;
  1675. $expire = $expire? $expire*86400 : 0;
  1676. $status = isset($info['status'])? intval($info['status']) : 0;
  1677. $info['avatar'] = isset($info['avatar']) ? cmf_get_image_preview_url($info['avatar']) : '';
  1678. $rtime = $info['created_at']? strtotime($info['created_at']) : 0;
  1679. $rtime = $rtime>time()-$expire? $rtime-(time()-$expire) : 0;
  1680. $info['rtime'] = $rtime;
  1681. $rtime = $rtime>23*3600? ceil($rtime/86400).'天' : ($rtime>3600? ceil($rtime/3600).'小时' : ($rtime>60? ceil($rtime/60).'分钟' : ''));
  1682. if($status == 1){
  1683. if($rtime){
  1684. $info['time'] = '<em class="red">'.$rtime.'后</em> 自动拒绝';
  1685. }else{
  1686. $info['time'] = '待处理';
  1687. }
  1688. }else{
  1689. $info['time'] = $status == 2? '已通过':($status == 3? '已拒绝' : '待处理');
  1690. if($status == 4){
  1691. $info['time'] = '过期自动处理';
  1692. }
  1693. }
  1694. Member::formatUser($info);
  1695. }
  1696. return $info;
  1697. }
  1698. /**
  1699. * 余额明细
  1700. * @param $params
  1701. * @param int $pageSize
  1702. * @return mixed
  1703. */
  1704. public static function getBalanceLog($params, $pageSize = 15)
  1705. {
  1706. $where = [];
  1707. $userId = isset($params['user_id']) ? $params['user_id'] : 0;
  1708. if ($userId) {
  1709. $where['b.user_id'] = $userId;
  1710. }
  1711. $changeType = isset($params['change_type']) ? $params['change_type'] : 0;
  1712. if ($changeType) {
  1713. $where['b.change_type'] = $changeType;
  1714. }
  1715. $type = isset($params['type']) ? $params['type'] : 0;
  1716. $model = db('user_balance_log')->alias('b')
  1717. ->leftJoin('user u','u.id=b.source_uid')
  1718. ->where($where)
  1719. ->where(function($query) use ($type){
  1720. if($type == 'income'){
  1721. $query->where('b.type', '>', 1);
  1722. } else if ($type){
  1723. $type = is_array($type)? $type : [$type];
  1724. $query->whereIn('b.type', $type);
  1725. }
  1726. });
  1727. $types = config('weixin.incomeTypes');
  1728. $dataList = $model->field('b.id,b.type,b.order_sn,b.change as money,b.change_type,b.balance,b.remark,b.description,b.create_time,status,u.user_nickname')
  1729. ->where('b.status', 'lt', 4)
  1730. ->order("b.create_time desc")
  1731. ->paginate($pageSize)
  1732. ->each(function ($item, $k) use($types){
  1733. $item['format_time'] = $item['create_time']? date('Y年m月d日 H点i分', $item['create_time']) : '';
  1734. $item['money'] = floatval($item['money']);
  1735. $type = isset($item['type'])? $item['type'] : 0;
  1736. $item['typeName'] = isset($types[$type])? $types[$type] : '';
  1737. return $item;
  1738. });
  1739. $dataList = $dataList ? $dataList->toArray() : [];
  1740. if($dataList){
  1741. $total = $model->where('b.status','=',2)->sum('b.change');
  1742. $dataList['total_money'] = moneyFormat($total);
  1743. $total = db('user_balance_log')->alias('b')
  1744. ->leftJoin('user u','u.id=b.source_uid')
  1745. ->where($where)
  1746. ->where(function($query) use ($type){
  1747. if($type == 'income'){
  1748. $query->where('b.type', '>', 1);
  1749. } else if ($type){
  1750. $type = is_array($type)? $type : [$type];
  1751. $query->whereIn('b.type', $type);
  1752. }
  1753. })
  1754. ->where('b.status','=',1)
  1755. ->where('b.status', 'lt', 4)
  1756. ->order("b.create_time desc")
  1757. ->sum('b.change');
  1758. $dataList['nopay_money'] = moneyFormat($total);
  1759. }
  1760. return $dataList;
  1761. }
  1762. /**
  1763. * 邀请扽团队成员或会员列表
  1764. * @param $params 参数
  1765. * @param $type 类型:1-团队成员,2-邀请的会员
  1766. * @param int $pageSize
  1767. * @return mixed
  1768. */
  1769. public static function getInviteList($inviteId, $type = 1, $pageSize = 15)
  1770. {
  1771. $where = ['user_type'=> 2, 'user_status'=> 1];
  1772. if ($inviteId) {
  1773. $where['parent_id'] = $inviteId;
  1774. }
  1775. if($type == 1){
  1776. $where['agent_type'] = 1;
  1777. $orderBy = "agent_create_time desc";
  1778. }else{
  1779. $where['agent_type'] = 0;
  1780. $orderBy = "create_time desc";
  1781. }
  1782. $model = Member::where($where)
  1783. ->where(function($query) use($type){
  1784. if($type == 1){
  1785. $query->where('agent_status','<', 4);
  1786. }else{
  1787. $query->whereIn('user_status', [0,1,2]);
  1788. }
  1789. });
  1790. $field = 'id,openid,user_nickname,sex,user_type,agent_type,agent_status,agent_create_time,create_time,avatar,is_reg_profile,user_status,is_heart,vip_auth,vip_expire,is_follow';
  1791. $dataList = $model->field($field)
  1792. ->order($orderBy)
  1793. ->paginate($pageSize)
  1794. ->each(function ($item, $k) use($type, $inviteId){
  1795. $item['avatar'] = $item['avatar']? cmf_get_image_preview_url($item['avatar']) : '';
  1796. if($type == 1){
  1797. $item['format_time'] = $item['agent_create_time']? date('Y-m-d H:i', $item['agent_create_time']) : '';
  1798. $item['invite_num'] = Member::getInviteCounts(['parent_id'=> $item['id']], 2);
  1799. $item['invite_market_num'] = Member::getInviteCounts(['parent_id'=> $item['id']], 1);
  1800. $item['invite_sum'] = Member::getBalanceCount($inviteId, $item['id']);
  1801. }else{
  1802. // VIP
  1803. $vipAuth = isset($item['vip_auth']) ? intval($item['vip_auth']) : 0;
  1804. $vipExpire = isset($item['vip_expire']) ? intval($item['vip_expire']) : 0;
  1805. if($vipAuth && $vipExpire >= time()){
  1806. $item['vip_auth'] = 1;
  1807. $item['vip_expire'] = date('Y-m-d', $item['vip_expire']);
  1808. }else{
  1809. $item['vip_auth'] = 0;
  1810. $item['vip_expire'] = '';
  1811. }
  1812. $item['format_time'] = $item['create_time']? date('Y-m-d H:i', $item['create_time']) : '';
  1813. $item['invite_sum'] = Member::getBalanceCount($inviteId, $item['id'], 2);
  1814. }
  1815. $item['avatar'] = $item['avatar']? cmf_get_image_preview_url($item['avatar']) : '';
  1816. return $item;
  1817. });
  1818. $dataList = $dataList ? $dataList->toArray() : [];
  1819. if($dataList){
  1820. $counts = [];
  1821. if($type == 1){
  1822. $counts['invite_num'] = Member::getInviteCounts(['parent_id'=> $inviteId], 1);
  1823. $total = Member::getBalanceCount($inviteId);
  1824. $counts['invite_sum'] = moneyFormat($total);
  1825. }else{
  1826. $counts['invite_sex_1'] = Member::getInviteCounts(['parent_id'=> $inviteId,'sex'=> 1], 2);
  1827. $counts['invite_sex_2'] = Member::getInviteCounts(['parent_id'=> $inviteId,'sex'=> 2], 2);
  1828. $counts['invite_vip'] = Member::getInviteCounts(['parent_id'=> $inviteId,'vip_auth'=> 1], 2);
  1829. $total = Member::getBalanceCount($inviteId,0,2);
  1830. $counts['invite_sum'] = moneyFormat($total);
  1831. }
  1832. $dataList['counts'] = $counts;
  1833. }
  1834. return $dataList;
  1835. }
  1836. /**
  1837. * 统计邀请的会员或团队成员
  1838. * @param $params
  1839. * @param int $type
  1840. * @return float|int|string
  1841. */
  1842. public static function getInviteCounts($params, $type=1){
  1843. $where = ['user_type'=> 2, 'user_status'=> 1];
  1844. $inviteId = isset($params['parent_id'])? $params['parent_id'] : 0;
  1845. if ($inviteId) {
  1846. $where['parent_id'] = $inviteId;
  1847. }
  1848. if($type == 1){
  1849. $where['agent_type'] = 1;
  1850. }else{
  1851. $where['agent_type'] = 0;
  1852. }
  1853. $sex = isset($params['sex'])? $params['sex'] : 0;
  1854. if($sex){
  1855. $where['sex'] = $sex;
  1856. }
  1857. $sex = isset($params['sex'])? $params['sex'] : 0;
  1858. if($sex){
  1859. $where['sex'] = $sex;
  1860. }
  1861. $count = Member::where($where)
  1862. ->where(function($query) use($type){
  1863. if($type == 1){
  1864. $query->where('agent_status','<', 4);
  1865. }else{
  1866. $query->whereIn('user_status', [0,1,2]);
  1867. }
  1868. })
  1869. ->where(function ($query) use($params){
  1870. $sex = isset($params['sex'])? $params['sex'] : 0;
  1871. if($sex){
  1872. $query->where('sex','=', $sex);
  1873. }
  1874. $vipAuth = isset($params['vip_auth'])? $params['vip_auth'] : 0;
  1875. if($vipAuth){
  1876. $query->where('vip_auth','=', $vipAuth)->where('vip_expire','>=', time());
  1877. }
  1878. })
  1879. ->count('id');
  1880. return intval($count);
  1881. }
  1882. /**
  1883. * 统计收益金额
  1884. * @param $userId 所属用户
  1885. * @param int $sourceUid 来源用户
  1886. * @param int $type 类型:0-收益分成,
  1887. * @return float
  1888. */
  1889. public static function getBalanceCount($userId, $sourceUid=0, $userType=1, $profitType = 0){
  1890. $where = ['b.user_id'=> $userId,'b.status'=> 2,'u.user_type'=> 2];
  1891. if($sourceUid){
  1892. $where['b.source_uid'] = $sourceUid;
  1893. }
  1894. if($userType==1){
  1895. $where['u.agent_type'] = 1;
  1896. }else{
  1897. $where['u.agent_type'] = 0;
  1898. }
  1899. if($profitType){
  1900. $where['b.type'] = $profitType;
  1901. }
  1902. //var_dump($where);
  1903. $sum = UserBalanceLog::alias('b')
  1904. ->leftJoin('user u','u.id=b.source_uid')
  1905. ->where($where)
  1906. ->where('b.type','>',1)
  1907. ->where('b.type','<',30)
  1908. ->sum('b.pay_money');
  1909. return moneyFormat($sum);
  1910. }
  1911. /**
  1912. * 投诉拉黑用户列表
  1913. * @param int $type 类型
  1914. * @param int $pageSize 分页大小
  1915. * @return array|bool|\think\Paginator
  1916. * @throws \think\exception\DbException
  1917. */
  1918. public static function getComplainList($type, $pageSize=30){
  1919. $page = input('page', 1);
  1920. $cacheKey = "cache:complainList:p_{$type}_{$page}_{$pageSize}";
  1921. $dataList = PRedis::get($cacheKey);
  1922. if($dataList){
  1923. return $dataList;
  1924. }
  1925. $complainTypes = config('weixin.complainTypes');
  1926. $dataList = Complain::alias('c')
  1927. ->leftJoin('user u','u.id=c.c_uid')
  1928. ->field('c.id,u.id as uid,u.real_name,u.user_nickname,u.avatar,u.mobile,c.type,c.remark,c.status')
  1929. ->where(['c.status'=> 2])
  1930. ->where('u.id','>', 0)
  1931. ->where(function ($query) use($type){
  1932. if($type == 2){
  1933. $query->where('c.created_time','>=', time() - 3*24*3600);
  1934. }
  1935. })
  1936. ->order('c.created_time desc')
  1937. ->paginate($pageSize)
  1938. ->each(function($item, $k) use($complainTypes){
  1939. $item['wechat_code'] = UserProfile::where(['userid'=> $item['uid']])->value('wechat_code');
  1940. $item['wechat_code'] = $item['wechat_code']? formatName($item['wechat_code']) : '';
  1941. $item['avatar'] = $item['avatar']? cmf_get_image_preview_url($item['avatar']) : '';
  1942. $type = isset($item['type'])? $item['type'] : 8;
  1943. $item['type_name'] = isset($complainTypes[$type])? $complainTypes[$type] : '其他';
  1944. $item['remark_count'] = $item['remark']? mb_strlen($item['remark'],'utf-8') : 0;
  1945. $item['remark_sub'] = $item['remark_count']>30? substr($item['remark'], 0, 30) : '';
  1946. });
  1947. if($dataList){
  1948. PRedis::set($cacheKey, $dataList, 10);
  1949. }
  1950. return $dataList;
  1951. }
  1952. }