Member.php 89 KB

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