Java tutorial
package com.gongpingjia.carplay.service.impl; import com.gongpingjia.carplay.common.chat.ChatThirdPartyService; import com.gongpingjia.carplay.common.domain.ResponseDo; import com.gongpingjia.carplay.common.exception.ApiException; import com.gongpingjia.carplay.common.photo.PhotoService; import com.gongpingjia.carplay.common.util.*; import com.gongpingjia.carplay.dao.activity.ActivityDao; import com.gongpingjia.carplay.dao.activity.AppointmentDao; import com.gongpingjia.carplay.dao.activity.PushInfoDao; import com.gongpingjia.carplay.dao.common.PhotoDao; import com.gongpingjia.carplay.dao.history.InterestMessageDao; import com.gongpingjia.carplay.dao.statistic.StatisticActivityMatchDao; import com.gongpingjia.carplay.dao.user.SubscriberDao; import com.gongpingjia.carplay.dao.user.UserDao; import com.gongpingjia.carplay.entity.activity.Activity; import com.gongpingjia.carplay.entity.activity.Appointment; import com.gongpingjia.carplay.entity.activity.PushInfo; import com.gongpingjia.carplay.entity.common.Address; import com.gongpingjia.carplay.entity.common.Landmark; import com.gongpingjia.carplay.entity.common.Photo; import com.gongpingjia.carplay.entity.history.InterestMessage; import com.gongpingjia.carplay.entity.statistic.StatisticActivityMatch; import com.gongpingjia.carplay.entity.user.Subscriber; import com.gongpingjia.carplay.entity.user.User; import com.gongpingjia.carplay.service.ActivityService; import com.gongpingjia.carplay.service.util.ActivityQueryParam; import com.gongpingjia.carplay.service.util.DistanceUtil; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.domain.Sort; import org.springframework.data.geo.Point; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import java.text.MessageFormat; import java.util.*; /** * Created by heyongyu on 2015/9/22. */ @Service("activityService") public class ActivityServiceImpl implements ActivityService { private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(ActivityServiceImpl.class); @Autowired private ChatThirdPartyService chatThirdPartyService; @Autowired private ChatCommonService chatCommonService; @Autowired private UserDao userDao; @Autowired private ActivityDao activityDao; @Autowired private AppointmentDao appointmentDao; @Autowired private SubscriberDao subscriberDao; @Autowired private InterestMessageDao interestMessageDao; @Autowired private PushInfoDao pushInfoDao; @Autowired private StatisticActivityMatchDao statisticActivityMatchDao; @Autowired @Qualifier("thirdPhotoManager") private PhotoService thirdPhotoManager; @Autowired private PhotoDao photoDao; /** * * * @param userId * @param activity * @return * @throws ApiException */ @Override public ResponseDo activityRegister(String userId, Activity activity) throws ApiException { LOG.debug("activityRegister"); buildUserActivityCover(userId, activity); User user = userDao.findById(userId); Long current = DateUtil.getTime(); saveUserActivity(userId, activity, current); saveInterestMessage(userId, activity, current); //???? Map<String, Object> ext = new HashMap<>(1); ext.put("avatar", CommonUtil.getLocalPhotoServer() + user.getAvatar()); String message = MessageFormat.format( PropertiesUtil.getProperty("dynamic.format.interest", "{0}{1}"), user.getNickname(), activity.getType()); chatThirdPartyService.sendUserGroupMessage(chatCommonService.getChatToken(), Constants.EmchatAdmin.INTEREST, buildUserSubscribers(userId), message, ext); chatThirdPartyService.sendUserGroupMessage(chatCommonService.getChatToken(), Constants.EmchatAdmin.NEARBY, buildNearByUsers(user, activity.getActivityId()), message, ext); return ResponseDo.buildSuccessResponse(activity.getActivityId()); } private void buildUserActivityCover(String userId, Activity activity) throws ApiException { if (StringUtils.isNotEmpty(activity.getCover())) { //?? Photo photo = photoDao.findById(activity.getCover()); if (photo == null) { LOG.warn("Input parameter cover is not exist, photoId:{}", activity.getCover()); throw new ApiException("???"); } if (!thirdPhotoManager.isExist(photo.getKey())) { LOG.warn("Input parameter cover is not exist"); throw new ApiException("???"); } activity.setCover(photo.getKey()); } else { Photo photo = photoDao.getLatestAlbumPhoto(userId); if (photo != null) { //????? activity.setCover(photo.getKey()); } } } private void saveInterestMessage(String userId, Activity activity, Long current) { InterestMessage oldMessage = interestMessageDao .findOne(Query.query(Criteria.where("relatedId").is(activity.getActivityId()))); if (oldMessage == null) { LOG.debug("Old message is not exist, with activityId:{}", activity.getActivityId()); InterestMessage interestMessage = new InterestMessage(); interestMessage.setUserId(userId); interestMessage.setType(InterestMessage.USER_ACTIVITY); interestMessage.setRelatedId(activity.getActivityId()); interestMessage.setCreateTime(current); interestMessageDao.save(interestMessage); } else { LOG.debug("Old message is exist, with activityId:{}, update create time", activity.getActivityId()); interestMessageDao.update(Query.query(Criteria.where("relatedId").is(activity.getActivityId())), Update.update("createTime", current)); } } private void saveUserActivity(String userId, Activity activity, Long current) { Activity oldActivity = activityDao.findOne(Query .query(Criteria.where("userId").is(userId).and("deleteFlag").is(false).and("majorType") .is(activity.getMajorType()).and("type").is(activity.getType())) .with(new Sort(new Sort.Order(Sort.Direction.DESC, "createTime")))); if (oldActivity == null) { LOG.debug("Old activity is not exist, create a new"); //?? activity.setActivityId(null); //ID activity.setUserId(userId); List<String> memberIds = new ArrayList<String>(1); //? memberIds.add(userId); activity.setMembers(memberIds); activity.setCreateTime(current); activity.setDeleteFlag(false); activityDao.save(activity); } else { LOG.debug("Old activity is exist, update activity info, activityId:{}", activity.getActivityId()); //?? Update update = new Update(); update.set("pay", activity.getPay()); update.set("destPoint", activity.getDestPoint()); update.set("destination", activity.getDestination()); update.set("estabPoint", activity.getEstabPoint()); update.set("establish", activity.getEstablish()); update.set("transfer", activity.isTransfer()); update.set("createTime", current); update.set("applyIds", new ArrayList<>(0)); update.set("cover", activity.getCover()); activityDao.update(Query.query(Criteria.where("activityId").is(oldActivity.getActivityId())), update); activity.setActivityId(oldActivity.getActivityId()); } } private List<String> buildNearByUsers(User user, String activityId) { LOG.debug("Send nearby user message, sendUser:{}", user.getUserId()); PushInfo pushInfo = pushInfoDao.findOne(Query.query(Criteria.where("sendUserId").is(user.getUserId()))); if (pushInfo != null) { //?? LOG.info("User:{} has already send push once today", user.getUserId()); return new ArrayList<>(0); } //?? Double distance = Double.parseDouble(PropertiesUtil.getProperty("carplay.nearby.distance.limit", "6000")); //?? Set<String> subUserIdSet = getSubscribeUsers(user); LOG.debug("Get nearby users"); List<User> nearbyUserList = userDao.find(Query.query(Criteria.where("landmark") .near(new Point(user.getLandmark().getLongitude(), user.getLandmark().getLatitude())) .maxDistance(distance * 180 / DistanceUtil.EARTH_RADIUS).and("deleteFlag").is(false))); Map<String, User> userMap = new HashMap<>(nearbyUserList.size()); for (User item : nearbyUserList) { if (item.getUserId().equals(user.getUserId())) { continue;// } if (subUserIdSet.contains(item.getUserId())) { continue;//?????? } userMap.put(item.getUserId(), item); } return buildEmchatNames(user, nearbyUserList, userMap, activityId); } /** * @param user ??? * @param nearbyUserList * @param userMap * @return */ private List<String> buildEmchatNames(User user, List<User> nearbyUserList, Map<String, User> userMap, String activityId) { LOG.debug("Get already pushed message users"); Long current = DateUtil.getTime(); Integer pushLimit = Integer.parseInt(PropertiesUtil.getProperty("carplay.nearby.push.limit", "3"));// ??? Set<String> pushedUsers = pushInfoDao.groupByReceivedUsers(userMap.keySet(), pushLimit); // ??? Integer userLimit = Integer.parseInt(PropertiesUtil.getProperty("carplay.nearby.users.limit", "3"));//? List<String> emchatNames = new ArrayList<>(userLimit);//ID int count = 0; for (User item : nearbyUserList) { if (count >= userLimit) { break; //??? } if (!userMap.containsKey(item.getUserId())) { continue;//??userMap } if (pushedUsers.contains(item.getUserId())) { continue; //????? } PushInfo info = new PushInfo(); info.setSendUserId(user.getUserId()); info.setReceivedUserId(item.getUserId()); info.setCreateTime(current); info.setActivityId(activityId); pushInfoDao.save(info); emchatNames.add(item.getEmchatName()); count++; } LOG.debug("Finished build push users"); return emchatNames; } private Set<String> getSubscribeUsers(User user) { LOG.debug("Get subscribed users"); List<Subscriber> subscriberList = subscriberDao .find(Query.query(Criteria.where("toUser").is(user.getUserId()))); Set<String> subUserIdSet = new HashSet<>(subscriberList.size()); for (Subscriber item : subscriberList) { subUserIdSet.add(item.getFromUser()); } return subUserIdSet; } /** * ?Id * * @param userId Id * @return Id */ private List<String> buildUserSubscribers(String userId) { //?? List<Subscriber> subscribers = subscriberDao.find(Query.query(Criteria.where("toUser").is(userId))); List<String> userIds = new ArrayList<>(subscribers.size()); for (Subscriber subscriber : subscribers) { userIds.add(subscriber.getFromUser()); } List<User> users = userDao.find(Query.query(Criteria.where("userId").in(userIds))); List<String> emchatNames = new ArrayList<>(users.size()); for (User user : users) { emchatNames.add(user.getEmchatName()); } return emchatNames; } @Override public ResponseDo getActivityInfo(String userId, String activityId, Landmark landmark) throws ApiException { LOG.debug("getActivityInfo"); Criteria criteria = Criteria.where("activityId").is(activityId); criteria.and("deleteFlag").is(false); Activity activity = activityDao.findOne(Query.query(criteria)); if (null == activity) { LOG.warn("activity not exist"); throw new ApiException("id ?"); } User organizer = userDao.findById(activity.getUserId()); if (null == organizer) { LOG.error("the activity {} cannot found the organizer user {}", activityId, userId); throw new ApiException("? User"); } Map<String, Object> map = organizer.buildCommonUserMap(); User.appendCover(map, userDao.getCover(activity.getCover(), organizer.getUserId())); activity.setOrganizer(map); if (landmark.getLatitude() != null && landmark.getLongitude() != null) { activity.setDistance(DistanceUtil.getDistance(landmark, activity.getEstabPoint())); } return ResponseDo.buildSuccessResponse(activity); } @Override public ResponseDo sendAppointment(String activityId, String userId, Appointment appointment) throws ApiException { Activity activity = activityDao.findOne(Query.query(Criteria.where("activityId").is(activityId))); if (activity == null) { LOG.warn("No activity exist : {}", activityId); throw new ApiException(""); } List<String> members = activity.getMembers(); for (String member : members) { if (member.equals(userId)) { LOG.warn("Already be a member"); throw new ApiException("????"); } } Appointment appointmentData = appointmentDao.findOne(Query.query(Criteria.where("activityId").is(activityId) .and("applyUserId").is(userId).and("status").is(Constants.AppointmentStatus.APPLYING))); if (appointmentData != null) { LOG.warn("already applying for this activity"); throw new ApiException("??"); } User user = userDao.findById(userId); Long current = DateUtil.getTime(); appointment.setActivityId(activity.getActivityId()); appointment.setApplyUserId(userId); appointment.setInvitedUserId(activity.getUserId()); appointment.setCreateTime(current); appointment.setStatus(Constants.AppointmentStatus.APPLYING); appointment.setModifyTime(current); appointment.setActivityCategory(Constants.ActivityCatalog.COMMON); //appointment destination activity destination destPoint estabPoint //appointment estabPoint applyUserId ? landmark appointment.setDestPoint(activity.getEstabPoint()); appointment.setDestination(activity.getDestination()); appointment.setEstabPoint(user.getLandmark()); appointment.setDistance(DistanceUtil.getDistance(appointment.getEstabPoint(), appointment.getDestPoint())); appointmentDao.save(appointment); //?ID Update update = new Update(); update.addToSet("applyIds", userId); activityDao.update(activityId, update); //???? User organizer = userDao.findById(activity.getUserId()); User applier = userDao.findById(userId); String message = MessageFormat.format( PropertiesUtil.getProperty("dynamic.format.activity.invite", "{0}{1}"), applier.getNickname(), activity.getType()); chatThirdPartyService.sendUserGroupMessage(chatCommonService.getChatToken(), Constants.EmchatAdmin.ACTIVITY_STATE, organizer.getEmchatName(), message); return ResponseDo.buildSuccessResponse(); } /** * * * @param appointmentId * @param userId * @param acceptFlag * @return * @throws ApiException */ @Override public ResponseDo processAppointment(String appointmentId, String userId, boolean acceptFlag) throws ApiException { LOG.debug("applyJoinActivity, appointmentId:{}, accept:{}", appointmentId, acceptFlag); Appointment appointment = checkAppointment(appointmentId, userId); // Activity activity = checkAppointmentActivity(appointment); //? User applyUser = userDao.findById(appointment.getApplyUserId()); if (applyUser == null) { LOG.warn("Apply user is not exist"); throw new ApiException("?"); } int status = Constants.AppointmentStatus.ACCEPT; if (!acceptFlag) { //??? status = Constants.AppointmentStatus.REJECT; } appointmentDao.update(appointmentId, Update.update("status", status).set("modifyTime", DateUtil.getTime())); // //?? // // // try { // chatThirdPartyService.addUserToChatGroup(emchatTokenService.getToken(), activity.getEmchatGroupId(), applyUser.getEmchatName()); // } catch (ApiException e) { // LOG.warn(e.getMessage(), e); // // // throw new ApiException("?"); // } // //activity members ; // Update activityUpdate = new Update(); // activityUpdate.addToSet("members", appointment.getApplyUserId()); // activityDao.update(activity.getActivityId(), activityUpdate); User user = userDao.findById(userId); //????,???? if (acceptFlag) { String message = MessageFormat.format( PropertiesUtil.getProperty("dynamic.format.activity.state", "{0}{1}{2}"), user.getNickname(), "?", appointment.getType()); chatThirdPartyService.sendUserGroupMessage(chatCommonService.getChatToken(), Constants.EmchatAdmin.ACTIVITY_STATE, applyUser.getEmchatName(), message); } return ResponseDo.buildSuccessResponse(); } /** * ? * * @param appointment * @return * @throws ApiException */ private Activity checkAppointmentActivity(Appointment appointment) throws ApiException { //? Activity activity = activityDao.findById(appointment.getActivityId()); if (activity == null) { LOG.warn("activity not exist"); throw new ApiException("?"); } for (String memberId : activity.getMembers()) { if (memberId.equals(appointment.getApplyUserId())) { LOG.warn("user has in the activity"); throw new ApiException("??"); } } return activity; } /** * appointmentuser???? * * @param appointmentId * @param userId * @return * @throws ApiException */ private Appointment checkAppointment(String appointmentId, String userId) throws ApiException { //appointment ? Appointment appointment = appointmentDao.findById(appointmentId); if (appointment == null) { LOG.warn("appoint not exist"); throw new ApiException("?"); } if (!userId.equals(appointment.getInvitedUserId())) { LOG.warn("appoint not belong this user"); throw new ApiException("?"); } if (Constants.AppointmentStatus.APPLYING != appointment.getStatus()) { LOG.warn("appoint is applying"); throw new ApiException("?"); } return appointment; } /** * activityListUser???? * * @param activityList * @throws ApiException */ private void initOrganizer(List<Activity> activityList, List<String> subscribeIds) throws ApiException { Set<String> userIdSet = new HashSet<>(activityList.size()); for (Activity activity : activityList) { userIdSet.add(activity.getUserId()); } List<User> users = userDao.findByIds(userIdSet); Map<String, User> userMap = new HashMap<>(users.size(), 1); for (User user : users) { userMap.put(user.getUserId(), user); } for (Activity activity : activityList) { User organizer = userMap.get(activity.getUserId()); if (null == organizer) { throw new ApiException("?? ActivityOrganizer"); } Map<String, Object> map = organizer.buildCommonUserMap(); map.put("subscribeFlag", subscribeIds.contains(organizer.getUserId())); activity.setOrganizer(map); } } /** * * ??? * * */ /** * ??? * <p/> * criteria: * city estabPoint.city * phone ? phone user ? userId activity * fromDate toDate createTime * pay -1 ?? ? AA * type -1 type ? type * transfer -1 true false * * @param json * @return * @throws ApiException */ @Override public ResponseDo getUserActivityList(JSONObject json, String userId) throws ApiException { //TODO? int draw = json.getInt("draw"); int start = json.getInt("start"); int length = json.getInt("length"); JSONObject resultJson = new JSONObject(); Query query = new Query(); Criteria criteria = new Criteria(); String startTimeStr = json.getString("fromTime"); String endTimeStr = json.getString("toTime"); if (StringUtils.isNotEmpty(startTimeStr) && StringUtils.isNotEmpty(endTimeStr)) { long startTime = TypeConverUtil.convertToLong("fromTime", startTimeStr, true); long endTime = TypeConverUtil.convertToLong("toTime", endTimeStr, true) + 24 * 60 * 60 * 1000; criteria.and("createTime").gte(startTime).lte(endTime); } String phone = json.getString("phone"); if (StringUtils.isNotEmpty(phone)) { User user = userDao.findOne(Query.query(Criteria.where("phone").is(phone))); if (null == user || StringUtils.isEmpty(user.getUserId())) { throw new ApiException("???"); } criteria.and("userId").is(user.getUserId()); } criteria.and("deleteFlag").is(false); String province = json.getString("province"); if (StringUtils.isNotEmpty(province)) { criteria.and("destination.province").is(province); } String city = json.getString("city"); if (StringUtils.isNotEmpty(city)) { criteria.and("destination.city").is(city); } String majorType = json.getString("majorType"); if (StringUtils.isNotEmpty(majorType)) { criteria.and("majorType").is(majorType); } String type = json.getString("type"); if (StringUtils.isNotEmpty(type) && !StringUtils.equals(type, "-1")) { criteria.and("type").is(type); } String pay = json.getString("pay"); if (StringUtils.isNotEmpty(pay) && !StringUtils.equals(pay, "-1")) { criteria.and("pay").is(pay); } String transferStr = json.getString("transfer"); if (StringUtils.isNotEmpty(transferStr) && !StringUtils.equals(transferStr, "-1")) { criteria.and("transfer").is(TypeConverUtil.convertToBoolean("transfer", transferStr, true)); } query.addCriteria(criteria); long totalNum = activityDao.count(query); query.with(new Sort(new Sort.Order(Sort.Direction.DESC, "createTime"))); query.skip(start).limit(length); List<Activity> activityList = activityDao.find(query); resultJson.put("draw", draw); resultJson.put("recordsFiltered", totalNum); resultJson.put("recordsTotal", totalNum); if (null == activityList || activityList.isEmpty()) { return ResponseDo.buildSuccessResponse(resultJson); } Set<String> userIdSet = new HashSet<>(activityList.size()); for (Activity activity : activityList) { userIdSet.add(activity.getUserId()); } List<User> userList = userDao.findByIds(userIdSet); Map<String, User> userMap = new HashMap<>(userList.size()); if (null == userList || userList.isEmpty()) { throw new ApiException(" ??"); } for (User user : userList) { userMap.put(user.getUserId(), user); } JSONArray jsonArray = new JSONArray(); for (Activity activity : activityList) { JSONObject item = new JSONObject(); item.put("activityId", activity.getActivityId()); item.put("nickname", userMap.get(activity.getUserId()).getNickname()); item.put("phone", userMap.get(activity.getUserId()).getPhone()); item.put("establish", activity.getEstablish()); item.put("destination", activity.getDestination()); item.put("type", activity.getType()); item.put("pay", activity.getPay()); item.put("transfer", activity.isTransfer()); item.put("createTime", activity.getCreateTime()); item.put("cover", userDao.getCover(activity.getCover(), activity.getUserId())); jsonArray.add(item); } resultJson.put("activityList", jsonArray); return ResponseDo.buildSuccessResponse(resultJson); } @Override public ResponseDo updateUserActivity(JSONObject json, String activityId) throws ApiException { Update update = new Update(); try { if (json.containsKey("destination") && StringUtils.isNotEmpty(json.getString("destination"))) { update.set("destination", JSONObject.toBean(json.getJSONObject("establish"), Address.class)); } if (json.containsKey("destPoint") && StringUtils.isNotEmpty(json.getString("destination"))) { update.set("destPoint", JSONObject.toBean(json.getJSONObject("destPoint"), Landmark.class)); } update.set("establish", JSONObject.toBean(json.getJSONObject("establish"), Address.class)); update.set("estabPoint", JSONObject.toBean(json.getJSONObject("estabPoint"), Landmark.class)); update.set("majorType", json.getString("majorType")); update.set("type", json.getString("type")); update.set("pay", json.getString("pay")); update.set("transfer", json.getBoolean("transfer")); } catch (Exception e) { LOG.error(e.getMessage(), e); throw new ApiException("?"); } Activity toFind = activityDao.findById(activityId); if (null == toFind) { throw new ApiException("id?"); } activityDao.update(activityId, update); return ResponseDo.buildSuccessResponse(); } @Override public ResponseDo viewUserActivity(String activityId) throws ApiException { Activity activity = activityDao.findById(activityId); if (null == activity) { throw new ApiException("?"); } User organizer = userDao.findById(activity.getUserId()); if (null == organizer || StringUtils.isEmpty(organizer.getUserId())) { throw new ApiException(""); } activity.setOrganizer(organizer.buildCommonUserMap()); Criteria criteria = new Criteria(); criteria.and("activityId").is(activity.getActivityId()); Query query = Query.query(criteria); query.with(new Sort(new Sort.Order(Sort.Direction.DESC, "createTime"))); List<Appointment> appointmentList = appointmentDao.find(query); if (null != appointmentList && !appointmentList.isEmpty()) { activity.setAppointmentList(appointmentList); } return ResponseDo.buildSuccessResponse(activity); } @Override public ResponseDo deleteUserActivities(Collection ids) throws ApiException { if (null == ids || ids.isEmpty()) { throw new ApiException(""); } List<Activity> byIds = activityDao.findByIds(ids); if (null == byIds || ids.isEmpty()) { throw new ApiException("id??"); } if (byIds.size() != ids.size()) { throw new ApiException("id??"); } activityDao.update(Query.query(Criteria.where("_id").in(ids)), Update.update("deleteFlag", true)); return ResponseDo.buildSuccessResponse(); } /** * ?? * * @param param ? * @return */ @Override public ResponseDo getNearByActivityList(HttpServletRequest request, ActivityQueryParam param) { LOG.info("Query parameters:{}", param.toString()); //? List<Activity> activityList = activityDao.find(Query.query(param.buildCommonQueryParam())); if (activityList.isEmpty()) { LOG.warn("No activity result found from database"); return ResponseDo.buildSuccessResponse(activityList); } Map<String, User> userMap = buildUserMap(activityList); //? id List<Activity> activities = rebuildActivities(param, activityList, userMap); //? sortActivityList(userMap, activities); if (activities.size() < param.getIgnore()) { LOG.warn("No data exist after ignore:{}", param.getIgnore()); return ResponseDo.buildSuccessResponse(new ArrayList<>(0)); } List<Activity> remainActivities = activities.subList(param.getIgnore(), activities.size()); if (remainActivities.size() > param.getLimit()) { remainActivities = remainActivities.subList(0, param.getLimit()); } LOG.debug("Query user subscriber info"); Map<String, Subscriber> subscriberMap = initSubscriberMap(param.getUserId()); Set<String> subscriberSet = subscriberMap.keySet(); //Activity ? return ResponseDo .buildSuccessResponse(buildResponse(param.getUserId(), userMap, remainActivities, subscriberSet)); } private void sortActivityList(Map<String, User> userMap, List<Activity> activities) { //??? Collections.sort(activities); for (Activity item : activities) { User user = userMap.get(item.getUserId()); //?????????, ???0.1,???0.2,???0.4,0.8,1.6... if (user.getMatchTimes() > 0) { item.setSortFactor(item.getSortFactor() - 0.1 * Math.pow(2, user.getMatchTimes() - 1)); } user.setMatchTimes(user.getMatchTimes() + 1); } Collections.sort(activities); } private void initAndSaveStatisticActivityReMatch(HttpServletRequest request, ActivityQueryParam param, String eventType) { StatisticActivityMatch statisticActivityMatch = new StatisticActivityMatch(); statisticActivityMatch.setType(param.getType()); statisticActivityMatch.setMajorType(param.getMajorType()); statisticActivityMatch.setPay(param.getPay()); Address address = new Address(); address.setProvince(param.getProvince()); address.setCity(param.getCity()); address.setDistrict(param.getDistrict()); statisticActivityMatch.setDestination(address); Landmark landmark = new Landmark(); landmark.setLongitude(param.getLongitude()); landmark.setLatitude(param.getLatitude()); statisticActivityMatch.setDestPoint(landmark); statisticActivityMatch.setTransfer(param.getTransfer()); statisticActivityMatch.setUserId(param.getUserId()); statisticActivityMatch.setIp(IPFetchUtil.getIPAddress(request)); statisticActivityMatch.setEvent(eventType); statisticActivityMatch.setCount(1); Date currentTime = new Date(); Calendar calendar = Calendar.getInstance(); calendar.setTime(currentTime); statisticActivityMatch.setCreateTime(currentTime.getTime()); statisticActivityMatch.setYear(calendar.get(Calendar.YEAR)); statisticActivityMatch.setMonth(calendar.get(Calendar.MONTH) + 1); statisticActivityMatch.setDay(calendar.get(Calendar.DAY_OF_MONTH) + 1); statisticActivityMatch.setHour(calendar.get(Calendar.HOUR)); statisticActivityMatch.setMinute(calendar.get(Calendar.MINUTE)); statisticActivityMatchDao.save(statisticActivityMatch); } private boolean isApplied(String userId, List<String> applyIds) { if (StringUtils.isEmpty(userId)) { return false; } if (null == applyIds || applyIds.isEmpty()) { return false; } boolean applyFlag = false; for (String id : applyIds) { if (StringUtils.equals(id, userId)) { applyFlag = true; } } return applyFlag; } private List<Map<String, Object>> buildResponse(String userId, Map<String, User> userMap, List<Activity> remainActivities, Set<String> subscriberSet) { List<Map<String, Object>> result = new ArrayList<>(remainActivities.size()); for (Activity item : remainActivities) { Map<String, Object> map = new HashMap<>(); map.put("activityId", item.getActivityId()); map.put("transfer", item.isTransfer()); map.put("distance", item.getDistance()); map.put("applyFlag", isApplied(userId, item.getApplyIds())); User user = userMap.get(item.getUserId()); Map<String, Object> organizer = new HashMap<>(9, 1); if (user != null) { organizer = user.buildCommonUserMap(); User.appendCover(organizer, userDao.getCover(item.getCover(), user.getUserId())); organizer.put("userId", user.getUserId()); } map.put("organizer", organizer); map.put("pay", item.getPay()); map.put("majorType", item.getMajorType()); map.put("type", item.getType()); map.put("destination", item.getDestination()); result.add(map); } return result; } /** * ???? * * @param param * @param activityList * @param userMap * @return */ private List<Activity> rebuildActivities(ActivityQueryParam param, List<Activity> activityList, Map<String, User> userMap) { Map<String, Appointment> appointmentActivityMap = buildUserAppointmentActivityIds(param); LOG.debug("Filter user by idle status and compute weight"); Long current = DateUtil.getTime(); List<Activity> activities = new ArrayList<>(activityList.size()); for (Activity item : activityList) { if (StringUtils.isNotEmpty(param.getUserId())) { //Id? //????? Appointment appointment = appointmentActivityMap.get(item.getActivityId()); if (appointment != null && appointment.getCreateTime() > item.getCreateTime()) { //???????? continue; } } User user = userMap.get(item.getUserId()); if (param.isCommonQuery()) { if (StringUtils.isNotEmpty(param.getGender())) { if (!StringUtils.equals(param.getGender(), user.getGender())) { //??? continue; } } } if (user != null && user.getIdle()) { //???? item.setSortFactor(computeWeight(param, current, item, user)); activities.add(item); } } return activities; } /** * ?? * * @param param * @return */ private Map<String, Appointment> buildUserAppointmentActivityIds(ActivityQueryParam param) { LOG.debug("Check user is already appointment or not, filter the activity"); List<Appointment> appointmentList = new ArrayList<>(0); if (StringUtils.isNotEmpty(param.getUserId())) { appointmentList = appointmentDao.find(Query.query( Criteria.where("applyUserId").is(param.getUserId()).and("deleteFlag").is(false).and("status") .in(Constants.AppointmentStatus.ACCEPT, Constants.AppointmentStatus.REJECT))); } Map<String, Appointment> activityAppointmentMap = new HashMap<>(); for (Appointment item : appointmentList) { //?? Appointment appointment = activityAppointmentMap.get(item.getActivityId()); if (appointment == null) { //map activityAppointmentMap.put(item.getActivityId(), item); continue; } if (item.getCreateTime() > appointment.getCreateTime()) { //?? activityAppointmentMap.put(item.getActivityId(), item); } } return activityAppointmentMap; } /** * ?? * * @param param ???? * @param current ? * @param item * @param user ? * @return ?? */ private double computeWeight(ActivityQueryParam param, Long current, Activity item, User user) { //??? // item.setDistance(DistanceUtil.getDistance(param.getLongitude(), param.getLatitude(), item.getEstabPoint().getLongitude(), item.getEstabPoint().getLatitude())); item.setDistance(DistanceUtil.getDistance(new Landmark(param.getLongitude(), param.getLatitude()), item.getEstabPoint())); double sortFactor = 0.2 * (1 - item.getDistance() / param.getMaxDistance()); sortFactor += 0.1 * (1 - (current - item.getCreateTime()) / param.getMaxTimeLimit()); //??? if (Constants.AuthStatus.ACCEPT.equals(user.getLicenseAuthStatus())) { sortFactor += 0.15; } //???? if (Constants.AuthStatus.ACCEPT.equals(user.getPhotoAuthStatus())) { sortFactor += 0.25; } //TODO ??? //?? if (item.getDestination() != null) { Address address = item.getDestination(); if (address.getProvince() != null && address.getDistrict() != null) { sortFactor += 0.15; } } //??? sortFactor += 0.05; return sortFactor; } private Map<String, User> buildUserMap(List<Activity> activityList) { LOG.debug("Query users by activity list"); Map<String, User> userMap = new HashMap<>(activityList.size(), 1); for (Activity item : activityList) { userMap.put(item.getUserId(), null); } List<User> users = userDao.findByIds(userMap.keySet()); for (User item : users) { userMap.put(item.getUserId(), item); } return userMap; } private Map<String, Subscriber> initSubscriberMap(String userId) { List<Subscriber> subscribers = new ArrayList<>(0); if (!StringUtils.isEmpty(userId)) { subscribers = subscriberDao.find(Query.query(Criteria.where("fromUser").is(userId))); } Map<String, Subscriber> subscriberMap = new HashMap<>(subscribers.size(), 1); for (Subscriber item : subscribers) { subscriberMap.put(item.getToUser(), item); } return subscriberMap; } /** * ?? * * @param param ? * @return */ public ResponseDo getRandomActivities(ActivityQueryParam param) { LOG.info("Query random activities parameters:{}", param.toString()); int counts = 0; List<Activity> activities = new ArrayList<>(0); do { //?4? if (counts >= 4) { break; } if (counts > 0) { //?10? param.setMaxDistance(param.getMaxDistance() * 10); } //? List<Activity> activityList = activityDao.find(Query.query(param.buildExpandQueryParam())); Map<String, User> userMap = buildUserMap(activityList); //? id activities = rebuildActivities(param, activityList, userMap); counts++; } while (activities.size() < param.getLimit()); if (activities.size() > param.getLimit()) { activities = activities.subList(0, param.getLimit()); } Map<String, User> userMap = buildUserMap(activities); LOG.debug("Begin build response"); return ResponseDo.buildSuccessResponse( buildResponse(param.getUserId(), userMap, activities, new HashSet<String>(0))); } @Override public ResponseDo getNearByActivityCount(ActivityQueryParam param) { LOG.info("Query parameters:{}", param.toString()); Map<String, Object> data = new HashMap<>(1); //? List<Activity> activityList = activityDao.find(Query.query(param.buildCommonQueryParam())); if (activityList.isEmpty()) { // LOG.info("No result find, begin expand query"); data.put("count", 0); return ResponseDo.buildSuccessResponse(data); } Map<String, User> userMap = buildUserMap(activityList); //? id List<Activity> activities = rebuildActivities(param, activityList, userMap); data.put("count", activities.size()); //Activity ? return ResponseDo.buildSuccessResponse(data); } @Override public ResponseDo getActivityPushInfos(HttpServletRequest request, String userId, Integer limit, Integer ignore) { LOG.debug("Query user pushInfo, userId:{}", userId); List<PushInfo> pushInfoList = pushInfoDao .find(Query.query(Criteria.where("receivedUserId").is(userId).and("deleteFlag").is(false)) .limit(limit).skip(ignore)); Set<String> activityIds = new HashSet<>(pushInfoList.size(), 1); for (PushInfo item : pushInfoList) { activityIds.add(item.getActivityId()); } LOG.debug("Query user subscriber info"); Map<String, Subscriber> subscriberMap = initSubscriberMap(userId); Set<String> subscriberSet = subscriberMap.keySet(); List<Activity> activityList = activityDao .find(Query.query(Criteria.where("activityId").in(activityIds).and("deleteFlag").is(false)) .with(new Sort(new Sort.Order(Sort.Direction.DESC, "createTime")))); Map<String, User> userMap = buildUserMap(activityList); User user = userDao.findById(userId); for (Activity item : activityList) { User organizer = userMap.get(item.getUserId()); item.setDistance(DistanceUtil.getDistance(user.getLandmark(), organizer.getLandmark())); } LOG.debug("Finished query data, begin build response"); return ResponseDo.buildSuccessResponse(buildResponse(userId, userMap, activityList, subscriberSet)); } @Override public ResponseDo registerUserActivity(String phone, String userId, Activity activity) throws ApiException { LOG.debug("activityRegister"); User user = userDao.findUserByPhone(phone); // if (user == null) { // throw new ApiException("?"); // } if (user == null) { user = userDao.findById(userId); } Long current = DateUtil.getTime(); saveUserActivity(user.getUserId(), activity, current); saveInterestMessage(user.getUserId(), activity, current); //???? Map<String, Object> ext = new HashMap<>(1); ext.put("avatar", CommonUtil.getLocalPhotoServer() + user.getAvatar()); String message = MessageFormat.format( PropertiesUtil.getProperty("dynamic.format.interest", "{0}{1}"), user.getNickname(), activity.getType()); chatThirdPartyService.sendUserGroupMessage(chatCommonService.getChatToken(), Constants.EmchatAdmin.INTEREST, buildUserSubscribers(user.getUserId()), message, ext); chatThirdPartyService.sendUserGroupMessage(chatCommonService.getChatToken(), Constants.EmchatAdmin.NEARBY, buildNearByUsers(user, activity.getActivityId()), message, ext); return ResponseDo.buildSuccessResponse(); } }