$activityId]; if ($sex) { $where['u.sex'] = $sex; } return Books::alias('b') ->join('user u', 'u.id=b.uid', 'left') ->where($where) ->where('b.id', '>', 0) ->where(function ($query) use ($status) { $status = is_array($status) ? $status : [$status]; return $query->where('b.status', 'in', $status); }) ->count('b.id'); } /** * 获取活动报名人数 * @param $activityId * @return float|string */ public static function getBookNumBySex($activityId, $sex = 0) { $where = ['b.aid' => $activityId]; return Books::alias('b') ->join('user u', 'u.id=b.uid', 'left') ->where($where) ->where('b.id', '>', 0) ->where(function ($query) use ($sex) { if ($sex) { $query->where('b.book_num', 'like', "{$sex}%"); } $query->whereNotNull('b.book_num')->where('b.status', 3); }) ->max('b.book_num_val'); } /** * 获取活动报名用户列表 * @param $activityId * @return float|string */ public static function getBookList($activityId, $pageSize = 20, $field = '', $userId = 0) { $userInfo = []; $field = $field ? $field : 'b.id,b.uid,b.aid,b.book_at,m.user_nickname,m.avatar'; if ($userId) { $userInfo = Member::getInfo(['id' => $userId], 'id,sex'); } $dataList = Books::alias('b') ->join('user m', 'm.id=b.uid', 'left') ->join('user_profile up', 'up.userid=m.id', 'left') ->where(['b.aid' => $activityId, 'b.status' => 3]) ->where('b.id', '>', 0) ->where(function ($query) use ($userInfo) { $querys = $query; $userId = isset($userInfo['id']) ? intval($userInfo['id']) : 0; $sex = isset($userInfo['sex']) ? intval($userInfo['sex']) : 0; if ($userId) { $querys = $querys->where('b.uid', 'not in', $userId); } if ($sex) { $sex = $sex == 1 ? 2 : 1; $querys = $querys->where('m.sex', 'in', [0, $sex]); } return $querys; }) ->field($field) ->order('b.book_num_val,b.id') ->paginate($pageSize) ->each(function ($item, $k) use ($userId) { $item['avatar'] = isset($item['avatar']) ? cmf_get_image_preview_url($item['avatar']) : ''; if (isset($item['birthday'])) { $birthday = isset($item['birthday']) ? $item['birthday'] : 0; $item['birthday_txt'] = $birthday ? date('Y年m月d日', $birthday) : '无'; $item['birthday_day'] = $birthday ? date('y年', $birthday) : '无'; } $height = isset($item['height']) ? intval($item['height']) : 0; $item['height_txt'] = $height ? intval($item['height']) . 'CM' : '无'; $item['height'] = $height; $weight = isset($item['weight']) ? intval($item['weight']) : 0; $item['weight_txt'] = $weight ? intval($item['weight']) . 'KG' : '无'; $item['weight'] = $weight; // VIP $vipAuth = isset($item['vip_auth']) ? intval($item['vip_auth']) : 0; $vipExpire = isset($item['vip_expire']) ? intval($item['vip_expire']) : 0; if ($vipAuth && $vipExpire >= time()) { $item['vip_auth'] = 1; $item['vip_expire'] = date('Y-m-d', $item['vip_expire']); } else { $item['vip_auth'] = 0; $item['vip_expire'] = ''; } // 学历 $educations = config('weixin.educations'); $edu = isset($item['education']) ? $item['education'] : 0; $item['education_txt'] = $edu && isset($educations[$edu]) ? $educations[$edu] : '无'; $item['education'] = $edu; // 地址 $province = isset($item['province']) ? trim($item['province']) : ''; $city = isset($item['city']) ? trim($item['city']) : ''; $item['now_address'] = trim($province . ' ' . $city); $homeProvince = isset($item['home_province']) ? trim($item['home_province']) : ''; $homeCity = isset($item['home_city']) ? trim($item['home_city']) : ''; $item['home_address'] = trim($homeProvince . ' ' . $homeCity); if ($userId) { $item['is_select'] = 0; $item['select_num'] = ''; $uid = isset($item['uid']) ? intval($item['uid']) : 0; $heartUids = HeartMatch::getHeartUids($item['aid'], $userId); if ($heartUids && $uid && in_array($uid, $heartUids)) { $item['is_select'] = 1; $item['select_num'] = array_search($uid, $heartUids) + 1; } } return $item; }); return $dataList ? $dataList->toArray() : []; } /** * 获取推送用户列表 * @param $activityId 活动ID * @param string $field 字段 * @return array */ public static function getPushUserList($activityId, $field = '') { $field = $field ? $field : 'b.id,b.uid,b.aid,m.openid,m.user_nickname'; $dataList = Books::alias('b') ->join('user m', 'm.id=b.uid', 'left') ->where(['b.aid' => $activityId, 'b.status' => 3]) ->field($field) ->select(); return $dataList ? $dataList->toArray() : []; } /** * 获取报名信息 * @param $where 条件 * @param string $field 字段 * @return array */ public static function getInfo($where, $field = '') { $field = $field ? $field : 'id,uid,aid,money,credit,pay_type,book_num,order_sn,prepay_id,status'; $info = Books::where($where)->where('id', '>', 0)->field($field)->find(); return $info ? $info->toArray() : []; } /** * 更新报名数据 * @param $where * @param $data * @return bool|int|string */ public static function saveData($where, $data) { if (!is_array($data)) { return false; } $data['updated_at'] = date('Y-m-d H:i:s'); return Books::where($where)->update($data); } /** * 验证用户是否已经报名该活动 * @param $userId 用户ID * @param $activityId 活动ID * @return mixed */ public static function checkUserBook($userId, $activityId, $status = 3) { return Books::where(['uid' => $userId, 'aid' => $activityId, 'status' => $status])->value('id'); } /** * 生成报名编号 * @param $activityId * @return mixed */ public static function makeBookNo($activityId, $prefix = '', $sex = 0) { $num = self::getBookNumBySex($activityId, $prefix); $num = $num ? $num : 0; $bookNo = makeNo($num + 1, $prefix); return $bookNo; } /** * 获取选我的人列表 * @param $activityId 活动ID * @param $userId 当前用户 * @param int $pageSize 分页大小 * @param string $field 字段 * @return array */ public static function getMatchList($activityId, $userId, $pageSize = 10, $field = '') { $userInfo = []; $field = $field ? $field : "hm.id,hm.aid,hm.uid,hm.heart_uids,m.user_nickname,m.avatar,m.sex,m.birthday,m.real_name,up.age,up.height,up.weight,m.vip_auth,m.vip_expire,up.company,up.occupation,up.graduate,up.education,up.province,up.city,up.home_province,up.home_city,up.show_company,up.show_graduate,up.idcard_check,up.education_check,up.position_check,find_in_set('{$userId}', hm.`heart_uids`) as choose_rank"; if ($userId) { $userInfo = Member::getInfo(['id' => $userId], 'id,sex'); } $dataList = HeartMatch::alias('hm') ->join('user m', 'm.id=hm.uid', 'left') ->join('user_profile up', 'up.userid=m.id', 'left') ->where(['hm.aid' => $activityId]) ->where("find_in_set('{$userId}', hm.`heart_uids`)") ->where('hm.status', 'in', [1, 2, 3]) ->where('hm.id', '>', 0) ->where(function ($query) use ($userInfo) { $querys = $query; $userId = isset($userInfo['id']) ? intval($userInfo['id']) : 0; $sex = isset($userInfo['sex']) ? intval($userInfo['sex']) : 0; if ($userId) { $querys = $querys->where('hm.uid', 'not in', $userId); } if ($sex) { $sex = $sex == 1 ? 2 : 1; $querys = $querys->where('m.sex', 'in', [0, $sex]); } return $querys; }) ->field($field) ->order('hm.created_at desc') ->paginate($pageSize) ->each(function ($item, $k) { $item['avatar'] = isset($item['avatar']) ? cmf_get_image_preview_url($item['avatar']) : ''; if (isset($item['birthday'])) { $birthday = isset($item['birthday']) ? $item['birthday'] : 0; $item['birthday_txt'] = $birthday ? date('Y年m月d日', $birthday) : '无'; $item['birthday_day'] = $birthday ? date('y年', $birthday) : '无'; } $height = isset($item['height']) ? intval($item['height']) : 0; $item['height_txt'] = $height ? intval($item['height']) . 'CM' : '无'; $item['height'] = $height; $weight = isset($item['weight']) ? intval($item['weight']) : 0; $item['weight_txt'] = $weight ? intval($item['weight']) . 'KG' : '无'; $item['weight'] = $weight; // VIP $vipAuth = isset($item['vip_auth']) ? intval($item['vip_auth']) : 0; $vipExpire = isset($item['vip_expire']) ? intval($item['vip_expire']) : 0; if ($vipAuth && $vipExpire >= time()) { $item['vip_auth'] = 1; $item['vip_expire'] = date('Y-m-d', $item['vip_expire']); } else { $item['vip_auth'] = 0; $item['vip_expire'] = ''; } // 学历 $educations = config('weixin.educations'); $edu = isset($item['education']) ? $item['education'] : 0; $item['education_txt'] = isset($educations[$edu]) ? $educations[$edu] : '无'; $item['education'] = $edu; // 地址 $province = isset($item['province']) ? trim($item['province']) : ''; $city = isset($item['city']) ? trim($item['city']) : ''; $item['now_address'] = trim($province . ' ' . $city); $homeProvince = isset($item['home_province']) ? trim($item['home_province']) : ''; $homeCity = isset($item['home_city']) ? trim($item['home_city']) : ''; $item['home_address'] = trim($homeProvince . ' ' . $homeCity); $item['book_no'] = Books::where(['uid' => $item['uid'], 'aid' => $item['aid'], 'status' => 3]) ->value('book_num'); return $item; }); return $dataList ? $dataList->toArray() : []; } /** * 获取待匹配的用户列表 * @param $activityId 活动ID * @param string $field 字段 * @return array */ public static function getMatchUserList($activityId, $field = '') { $field = $field ? $field : "hm.id,hm.aid,hm.uid,b.book_num as book_no,hm.heart_uids,m.openid,m.sex,m.user_nickname,m.real_name,m.mobile,up.wechat_code,b.book_num as book_no"; $dataList = HeartMatch::alias('hm') ->join('user m', 'm.id=hm.uid', 'left') ->join('user_profile up', 'up.userid=m.id', 'left') ->join('books b', 'b.uid=m.id and b.aid=hm.aid', 'left') ->where(['hm.aid' => $activityId, 'b.status' => 3, 'hm.status' => 1]) ->where('hm.id', '>', 0) // ->field($field) ->order('hm.id') ->column($field, 'hm.uid'); // ->select(); return $dataList; } /** * 设置匹配用户 * @param $activityId * @param $userId * @param $uids * @return array|bool|int */ public static function setMatchUser($activityId, $userId, $uids) { $siteInfo = $siteInfo = cmf_get_site_info(); $chooseNum = isset($siteInfo['choose_num']) ? intval($siteInfo['choose_num']) : 0; $contactType = isset($siteInfo['contact_type']) ? $siteInfo['contact_type'] : 1; $chooseNum = $chooseNum ? $chooseNum : 3; $uids = is_array($uids) ? $uids : explode(',', $uids); if (count($uids) > $chooseNum) { return lang('choose_limit', ['num' => $chooseNum]); } if (count($uids) <= 0) { return 6008; } // 验证活动 $activityInfo = Activity::where(['id' => $activityId, 'status' => 1]) ->field('id,title,starttime,is_match') ->find(); if (empty($activityInfo)) { return 5001; } // 验证匹配状态 $isMatch = isset($activityInfo['is_match']) ? intval($activityInfo['is_match']) : 0; if ($isMatch == 1) { return 6002; } // 验证是否签到 $isSignin = Books::where(['aid' => $activityId, 'uid' => $userId, 'status' => 3])->value('is_signin'); if (!in_array($isSignin, [2, 3])) { return 5023; } $where = ['aid' => $activityId, 'uid' => $userId]; $data = [ 'aid' => $activityId, 'uid' => $userId, 'heart_uids' => is_array($uids) ? implode(',', $uids) : $uids, 'created_at' => date('Y-m-d H:i:s'), 'status' => 1, ]; $matchData = HeartMatch::where($where)->field('id,heart_uids,status')->find(); $status = isset($matchData['status']) ? intval($matchData['status']) : 0; // 若开启互选模式则直接匹配 if ($contactType == 3) { // 是否设置过互选 $matchUids = isset($matchData['heart_uids']) ? $matchData['heart_uids'] : ''; if ($matchUids) { return 6010; } if (empty($matchData) && !HeartMatch::insertGetId($data)) { return 6007; }else if($matchData){ HeartMatch::where($where)->update(['heart_uids' => is_array($uids) ? implode(',', $uids) : $uids]); } // 处理互选 $res = Books::setMutualSelect($userId, $uids, $activityInfo); } else { if ($matchData) { // 未匹配 if ($status == 1 || $status == 4) { $res = HeartMatch::where($where)->update($data); } else { return 6009; } } else { $res = HeartMatch::insertGetId($data); } } // 操作日志 UserLog::saveLog(['user_id' => $userId, 'type' => 4, 'content' => "设置互选匹配用户"]); return ['id' => $res]; } /** * 处理互选 * @param $userId 当前互选用户 * @param $uids 选择的用户ID * @param $activityInfo 活动基础信息 * @return array|bool * @throws \think\Exception * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException * @throws \think\exception\PDOException */ private static function setMutualSelect($userId, $uids, $activityInfo) { $uids = !is_array($uids) && $uids ? [$uids] : $uids; $activityId = isset($activityInfo['id']) ? intval($activityInfo['id']) : 0; if (empty($activityId) || empty($uids)) { return false; } $field = 'm.id as uid,m.real_name,m.openid,m.sex,m.user_nickname,up.wechat_code,hm.uid as muid,hm.match_uid,hm.heart_uids,b.book_num'; $matchUsers = HeartMatch::alias('hm') ->leftJoin('user m', 'm.id=hm.uid') ->leftJoin('user_profile up', 'up.userid=hm.uid') ->leftJoin('books b', 'b.uid=hm.uid and b.aid=hm.aid') ->field($field) ->where('hm.uid', 'in', $uids) ->where(['hm.aid' => $activityId, 'b.status' => 3]) ->where('find_in_set(:uid,hm.heart_uids)', ['uid' => $userId]) ->where('hm.status', '<', 4) ->select(); // 如果不存在互选用户 $matchUsers = $matchUsers? $matchUsers->toArray() : []; if (empty($matchUsers)) { return false; } $memberInfo = Member::alias('m') ->leftJoin('user_profile up', 'up.userid=m.id') ->leftJoin('books b', 'b.uid=m.id') ->field('m.id,m.openid,m.real_name,m.sex,m.user_nickname,up.wechat_code,b.book_num') ->where(['m.id' => $userId, 'm.user_status' => 1, 'b.aid' => $activityId, 'b.status' => 3]) ->find(); if (empty($memberInfo)) { return false; } // 进行互选处理 $matchUids = []; $matchAt = time(); $title = isset($activityInfo['title']) ? trim($activityInfo['title']) : '无'; $matchTime = $matchAt ? date('Y.m.d H:i', $matchAt) : date('Y.m.d H:i', time()); $openid = isset($memberInfo['openid']) ? trim($memberInfo['openid']) : ''; $bookNo = isset($memberInfo['book_num']) ? trim($memberInfo['book_num']) : '无'; $nickname = isset($memberInfo['user_nickname']) ? $memberInfo['user_nickname'] : ''; $wechatCode = isset($memberInfo['wechat_code']) ? trim($memberInfo['wechat_code']) : '无'; $sex = isset($memberInfo['sex']) ? intval($memberInfo['sex']) : 0; $sex = $sex == 1 ? '男' : '女'; PRedis::set('matchs:activity_' . $activityId.':users_'.$userId, ['data' => $memberInfo, 'matchs' => $matchUsers], 600); foreach ($matchUsers as $matchData) { $uids = isset($matchData['match_uid']) && $matchData['match_uid'] ? explode(',', $matchData['match_uid']) : []; $matchUid = isset($matchData['muid']) ? intval($matchData['muid']) : 0; $matchName = isset($matchData['user_nickname']) ? $matchData['user_nickname'] : ''; $matchNo = isset($matchData['book_num']) ? trim($matchData['book_num']) : '无'; $matchWechatCode = isset($matchData['wechat_code']) ? trim($matchData['wechat_code']) : '无'; $matchSex = isset($matchData['sex']) ? intval($matchData['sex']) : 0; $matchSex = $matchSex == 1 ? '男' : '女'; // 通知处理 if (empty($matchUid)) { continue; } /*if (($uids && in_array($userId, $uids)) || ($matchUids && in_array($matchUid, $matchUids))) { continue; }*/ // 更新被匹配用户数据 $uids[] = $userId; $uids = array_unique($uids); $matchDate = date('Y-m-d H:i:s', $matchAt); $errorKey = 'matchs:activity_' . $activityId . ':error:u_' . $userId . '_' . $matchUid; $updateData = ['match_uid' => implode(',', $uids), 'match_at' => $matchDate, 'status' => 2]; if (empty($uids) || !HeartMatch::where(['aid' => $activityId, 'uid' => $matchUid])->update($updateData)) { PRedis::set($errorKey.'_1', ['data' => $updateData, 'match' => $matchData], 600); continue; } // 更新互选用户数据 $matchUids[] = $matchUid; $matchUids = array_unique($matchUids); $updateData = ['match_uid' => implode(',', $matchUids), 'match_at' => $matchDate, 'status' => 2]; if (empty($matchUids) || !HeartMatch::where(['aid' => $activityId, 'uid' => $userId])->update($updateData)) { PRedis::set($errorKey.'_2', ['data' => $updateData, 'match' => $matchData], 600); continue; } // 匹配消息通知 if ($openid) { $params = [ 'title' => "恭喜!活动缘分互选匹配成功,已为您匹配到缘分用户!\n\n活动主题:\t{$title}\n\n您的编号:\t{$bookNo}\n\n对方编号:\t{$matchNo}\n\n匹配时间:\t{$matchTime}\n\n对方微信号:\t{$matchWechatCode}", 'remark' => "感谢您的使用,点击详情查看互选信息", 'type' => 'match', 'keywords' => [ 'name' => [ 'value' => $matchName . '(昵称)', 'color' => '#173177', ], 'sex' => [ 'value' => $matchSex, 'color' => '#173177', ], 'tel' => [ 'value' => '隐私信息不显示', 'color' => '#173177', ], ], 'url' => url('/weixin/activity/match?id=' . $activityId . '&type=2', '', '', true), ]; PRedis::set('matchs:activity_' . $activityId . ':message:' . $userId.'_'.$matchUid, ['info' => $memberInfo, 'match'=> $matchData, 'params' => $params], 600); Wechat::sendTplMsg($openid, $params); } // 通知被匹配用户 $matchOpenId = isset($matchData['openid']) ? trim($matchData['openid']) : ''; if ($matchOpenId) { $params = [ 'title' => "恭喜!活动缘分互选匹配成功,已为您匹配到缘分用户!\n\n活动主题:\t{$title}\n\n您的编号:\t{$matchNo}\n\n对方编号:\t{$bookNo}\n\n匹配时间:\t{$matchTime}\n\n对方微信号:\t{$wechatCode}", 'remark' => "感谢您的使用,点击详情查看互选信息", 'type' => 'match', 'keywords' => [ 'name' => [ 'value' => $nickname . '(昵称)', 'color' => '#173177', ], 'sex' => [ 'value' => $sex, 'color' => '#173177', ], 'tel' => [ 'value' => '隐私信息不显示', 'color' => '#173177', ], ], 'url' => url('/weixin/activity/match?id=' . $activityId . '&type=2', '', '', true), ]; PRedis::set('matchs:activity_' . $activityId . ':message:' . $matchUid.'_'.$userId, ['info' => $matchData, 'match'=> $memberInfo, 'params' => $params], 600); Wechat::sendTplMsg($matchOpenId, $params); } } return ['matchUsers' => $matchUsers, 'matchUids' => $matchUids]; } /** * 获取匹配用户 * @param $aid 活动ID * @param $userId 当前用户ID * @param $heartUids 当前用户已选的人ID,小写都好分隔字符串 * @param int $sex * @return array */ public static function matchUser($activityId, $userId, $heartUids, $sex = 0, $round = 1) { $field = "hm.id,hm.uid,b.book_num as book_no,m.sex,m.user_nickname,m.real_name,m.mobile,up.wechat_code,find_in_set('{$userId}', hm.`heart_uids`) as choose_rank,hm.created_at"; $info = HeartMatch::alias('hm') ->join('user m', 'm.id=hm.uid', 'left') ->join('user_profile up', 'up.userid=m.id', 'left') ->join('books b', 'b.uid=m.id and b.aid=hm.aid', 'left') ->where(['hm.aid' => $activityId, 'b.status' => 3, 'hm.status' => 1]) ->where('hm.uid', 'in', $heartUids) ->where(function ($query) use ($sex) { if ($sex) { $sex = $sex == 1 ? 2 : 1; return $query->where('m.sex', 'in', [0, $sex]); } }) ->where(db()->raw("find_in_set('{$userId}', hm.`heart_uids`) = {$round}")) ->where('hm.id', '>', 0) ->field($field) ->order("hm.id") ->limit(1) ->find(); // PRedis::set('test:sql:'.$userId.'_'.$aid, HeartMatch::getLastSql(), 600); return $info ? $info->toArray() : []; } }