package controllers; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.bson.types.ObjectId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import play.Play; import play.data.validation.Required; import play.modules.morphia.Model.MorphiaQuery; import play.mvc.Before; import vo.CommentVO; import vo.ShareVO; import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; import com.mongodb.CommandResult; import com.mongodb.gridfs.GridFSInputFile; import com.withiter.common.Constants; import com.withiter.models.account.Account; import com.withiter.models.merchant.Comment; import com.withiter.models.merchant.Merchant; import com.withiter.models.social.Share; import com.withiter.models.social.ShareNice; public class ShareController extends BaseController { public static final int NUMBER_PER_PAGE = 10; private static Logger logger = LoggerFactory.getLogger(ShareController.class); /** * Interception any caller on this controller, will first invoke this method */ @Before static void checkAuthentification() { if(session.contains(Constants.SESSION_USERNAME)){ return; } Map headers = request.headers; Iterator it = headers.keySet().iterator(); while(it.hasNext()){ String key = (String) it.next(); logger.debug(key+", " +headers.get(key)); } if(headers.containsKey("user-agent")){ if(!(request.headers.get("user-agent").values.contains("QuhaoAndroid") || request.headers.get("user-agent").values.contains("QuhaoIOS"))){ renderJSON("请使用Android/iOS APP访问。"); } } else { renderJSON("请使用Android/iOS APP访问。"); } } /** * 用户未开启定位,获取分享列表, 在time之后的数据 * @param page 第page页 * @param cityCode 城市代码 */ public static void getShareAfterDate(int page, String cityCode, long time) { page = (page == 0) ? 1 : page; List<Share> list = Share.nextPage(page, cityCode, time); List<ShareVO> voList = new ArrayList<ShareVO>(); ShareVO svo = null; for(Share s : list){ svo = new ShareVO(); svo.build(s); voList.add(svo); } renderJSON(voList); } /** * 用户未开启定位,获取分享列表 * @param page 第page页 * @param cityCode 城市代码 */ public static void getShare(int page, String cityCode) { page = (page == 0) ? 1 : page; List<Share> list = Share.nextPage(page, cityCode); List<ShareVO> voList = new ArrayList<ShareVO>(); ShareVO svo = null; for(Share s : list){ svo = new ShareVO(); svo.build(s); voList.add(svo); } renderJSON(voList); } /** * 获取周边分享, 在time之后 * @param page 第page页 * @param userX x坐标 * @param userY y坐标 * @param maxDis 最远距离 * @param cityCode 城市代码 */ public static void getNearShareAfterDate(int page, double userX, double userY, double maxDis, String cityCode, long time) { // page = (page == 0) ? 1 : page; // int num = (page - 1) * NUMBER_PER_PAGE; BasicDBObject cmdBody = new BasicDBObject("aggregate", "Share"); List<BasicDBObject> pipeline = new ArrayList<BasicDBObject>(); BasicDBObject geoNearParams = new BasicDBObject(); geoNearParams.put("near", new double[] { userX, userY }); if (maxDis >= 0) { geoNearParams.put("maxDistance", maxDis / 6371); } geoNearParams.put("distanceField", "dis"); geoNearParams.put("distanceMultiplier", 6371000); geoNearParams.put("spherical", true); geoNearParams.put("num", 60); // 限制返回数量 // filter BasicDBObject filterParams = new BasicDBObject(); filterParams.put("deleted", false); filterParams.put("cityCode", cityCode); geoNearParams.put("query", filterParams); pipeline.add(new BasicDBObject("$geoNear", geoNearParams)); // if (num != 0) { // pipeline.add(new BasicDBObject("$skip", num)); // } BasicDBObject projectParams = new BasicDBObject(); projectParams.put("_id", 1); projectParams.put("content", 1); projectParams.put("address", 1); projectParams.put("dis", 1); projectParams.put("aid", 1); projectParams.put("image", 1); projectParams.put("created", 1); projectParams.put("userImage", 1); projectParams.put("nickName", 1); projectParams.put("up", 1); projectParams.put("showAddress", 1); pipeline.add(new BasicDBObject("$project", projectParams)); cmdBody.put("pipeline", pipeline); if (!MorphiaQuery.ds().getDB().command(cmdBody).ok()) { logger.warn("geoNear查询出错: " + MorphiaQuery.ds().getDB().command(cmdBody).getErrorMessage()); } CommandResult myResult = MorphiaQuery.ds().getDB().command(cmdBody); if (myResult.containsField("result")) { List<ShareVO> shareVOList = analyzeResults(myResult, time); renderJSON(shareVOList); } else { renderJSON(""); } } /** * 获取周边分享 * @param page 第page页 * @param userX x坐标 * @param userY y坐标 * @param maxDis 最远距离 * @param cityCode 城市代码 */ public static void getNearShare(int page, double userX, double userY, double maxDis, String cityCode) { // page = (page == 0) ? 1 : page; // int num = (page - 1) * NUMBER_PER_PAGE; BasicDBObject cmdBody = new BasicDBObject("aggregate", "Share"); List<BasicDBObject> pipeline = new ArrayList<BasicDBObject>(); BasicDBObject geoNearParams = new BasicDBObject(); geoNearParams.put("near", new double[] { userX, userY }); if (maxDis >= 0) { geoNearParams.put("maxDistance", maxDis / 6371); } geoNearParams.put("distanceField", "dis"); geoNearParams.put("distanceMultiplier", 6371000); geoNearParams.put("spherical", true); geoNearParams.put("num", 60); // 限制返回数量 // filter BasicDBObject filterParams = new BasicDBObject(); filterParams.put("deleted", false); filterParams.put("cityCode", cityCode); geoNearParams.put("query", filterParams); pipeline.add(new BasicDBObject("$geoNear", geoNearParams)); // if (num != 0) { // pipeline.add(new BasicDBObject("$skip", num)); // } BasicDBObject projectParams = new BasicDBObject(); projectParams.put("_id", 1); projectParams.put("content", 1); projectParams.put("address", 1); projectParams.put("dis", 1); projectParams.put("aid", 1); projectParams.put("image", 1); projectParams.put("created", 1); projectParams.put("userImage", 1); projectParams.put("nickName", 1); projectParams.put("up", 1); projectParams.put("showAddress", 1); pipeline.add(new BasicDBObject("$project", projectParams)); cmdBody.put("pipeline", pipeline); if (!MorphiaQuery.ds().getDB().command(cmdBody).ok()) { logger.warn("geoNear查询出错: " + MorphiaQuery.ds().getDB().command(cmdBody).getErrorMessage()); } CommandResult myResult = MorphiaQuery.ds().getDB().command(cmdBody); if (myResult.containsField("result")) { List<ShareVO> shareVOList = analyzeResults(myResult, 0); renderJSON(shareVOList); } else { renderJSON(""); } } /** * 解析geoNearShare返回的数据 * * @param commandResult * @return */ private static List<ShareVO> analyzeResults(CommandResult commandResult, long time) { List<ShareVO> lists = new ArrayList<ShareVO>(); BasicDBList resultList = (BasicDBList) commandResult.get("result"); Iterator<Object> it = resultList.iterator(); BasicDBObject resultContainer = null; ObjectId resultId = null; ShareVO s = null; while (it.hasNext()) { s = new ShareVO(); resultContainer = (BasicDBObject) it.next(); // 下拉刷新 if(time != 0){ Date d = new Date(time); if(d.after((Date) resultContainer.get("created"))){ continue; } } resultId = (ObjectId) resultContainer.get("_id"); s.id = resultId.toString(); s.aid = resultContainer.getString("aid"); s.address = resultContainer.getString("address"); s.showAddress = resultContainer.getBoolean("showAddress"); s.content = resultContainer.getString("content"); s.x = resultContainer.getString("x"); s.y = resultContainer.getString("y"); s.dis = resultContainer.getDouble("dis"); s.image = resultContainer.getString("image"); s.date = (Date) resultContainer.get("created"); s.userImage = resultContainer.getString("userImage"); if(!StringUtils.isEmpty(s.image)){ try { s.image = URLDecoder.decode(s.image, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } if(!StringUtils.isEmpty(s.userImage)){ try { s.userImage = URLDecoder.decode(s.userImage, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } s.nickName = resultContainer.getString("nickName"); s.up = resultContainer.getLong("up"); lists.add(s); } // 对list按照时间排序 Collections.sort(lists, new Comparator(){ @Override public int compare(Object arg0, Object arg1) { if(((ShareVO)arg0).date.before(((ShareVO)arg1).date)){ return 1; } else { return -1; } } }); return lists; } /** * 添加分享 * @param content 分享内容 * @param x x坐标 * @param y y坐标 * @param address 地址信息 * @param aid Account id * @param image 图片 * @param cityCode 城市代码 * */ public static void add(){ String content = params.get("content"); String x = params.get("x"); String y = params.get("y"); String address = params.get("address"); String aid = params.get("aid"); String image = params.get("image"); String cityCode = params.get("cityCode"); boolean showAddress = Boolean.valueOf(params.get("showAddress")); // 用户头像 Account a = Account.findById(new ObjectId(aid)); String userImage = a.userImage; String nickName = a.nickname; Share s = new Share(); s.content = content; s.cityCode = cityCode; s.userImage = userImage; s.nickName = nickName; s.showAddress = showAddress; s.up = 0l; if(!StringUtils.isEmpty(x)){ s.x = x; s.y = y; s.loc[0] = Float.parseFloat(y); s.loc[1] = Float.parseFloat(x); s.address = address; } s.aid = aid; s.save(); if (!StringUtils.isEmpty(image)) { GridFSInputFile file = uploadFirst(image, aid); if (file != null) { if (!StringUtils.isEmpty(aid)) { try { String imageStorePath = Play.configuration.getProperty("imageShare.store.path"); String imageUrl = URLEncoder.encode(imageStorePath + file.getFilename(), "UTF-8"); s.image = imageUrl; s.save(); renderJSON(true); } catch (UnsupportedEncodingException e) { e.printStackTrace(); renderJSON(false); } } } } } private static GridFSInputFile uploadFirst(String param, String aid) { GridFSInputFile gfsFile = null; File[] files = params.get(param, File[].class); for (File file : files) { try { gfsFile = UploadController.saveBinaryForShare(file, aid); break; } catch (IOException e) { e.printStackTrace(); } } if (gfsFile == null) { return null; } else { return gfsFile; } } /** * 赞接口 * @param sid Share的id * @param aid 用户Account id */ public static void addNice(){ String sid = params.get("sid"); String aid = params.get("aid"); Share s = Share.findById(new ObjectId(sid)); s.up+=1l; s.save(); ShareNice sn = new ShareNice(); sn.aid = aid; sn.sid = sid; sn.save(); renderJSON(true); } /** * 我的分享 * @param aid * @param page * GET /share/my ShareController.my */ public static void my(@Required String aid, @Required int page) { if(validation.hasErrors()){ renderJSON(validation.errors()); } page = (page == 0) ? 1 : page; List<Share> Shares = Share.findbyAccountId(page, aid); List<ShareVO> ShareVOs = new ArrayList<ShareVO>(); ShareVO svo = new ShareVO(); for (Share s : Shares) { svo = new ShareVO(); svo.build(s); ShareVOs.add(svo); } renderJSON(ShareVOs); } /** * 删除我的分享 * @param sid Share id * GET /share/delete ShareController.delete */ public static void delete(@Required String sid){ if(validation.hasErrors()){ renderJSON(validation.errors()); } Share share = Share.findById(new ObjectId(sid)); share.deleted = true; share.save(); renderJSON(true); } }