admin
2025-02-25 30d8e227e8d823b6c38c3b9c90ac2df03b63befe
fanli/src/main/java/com/yeshi/fanli/controller/client/v1/UserMsgController.java
@@ -1,1062 +1,1134 @@
package com.yeshi.fanli.controller.client.v1;
import java.io.PrintWriter;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.yeshi.utils.BigDecimalUtil;
import org.yeshi.utils.JsonUtil;
import org.yeshi.utils.taobao.TbImgUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.yeshi.fanli.dto.msg.MsgCommonDTO;
import com.yeshi.fanli.entity.accept.AcceptData;
import com.yeshi.fanli.entity.bus.homemodule.Special;
import com.yeshi.fanli.entity.bus.lable.QualityFactory;
import com.yeshi.fanli.entity.bus.msg.MsgAccountDetail;
import com.yeshi.fanli.entity.bus.msg.MsgDeviceReadState;
import com.yeshi.fanli.entity.bus.msg.MsgInviteDetail;
import com.yeshi.fanli.entity.bus.msg.MsgMoneyDetail;
import com.yeshi.fanli.entity.bus.msg.MsgOrderDetail;
import com.yeshi.fanli.entity.bus.msg.MsgOrderDetail.MsgTypeOrderTypeEnum;
import com.yeshi.fanli.entity.bus.msg.MsgOtherDetail;
import com.yeshi.fanli.entity.bus.msg.UserMsgUnReadNum;
import com.yeshi.fanli.entity.bus.msg.UserSystemMsg;
import com.yeshi.fanli.entity.bus.user.UserInfoExtra;
import com.yeshi.fanli.entity.common.JumpDetailV2;
import com.yeshi.fanli.entity.goods.CommonGoods;
import com.yeshi.fanli.entity.goods.RecommendUserGoods;
import com.yeshi.fanli.entity.push.DeviceActive;
import com.yeshi.fanli.entity.push.PushGoods;
import com.yeshi.fanli.entity.taobao.TaoBaoGoodsBrief;
import com.yeshi.fanli.entity.taobao.TaoBaoSearchResult;
import com.yeshi.fanli.exception.goods.CommonGoodsException;
import com.yeshi.fanli.exception.goods.RecommendUserGoodsException;
import com.yeshi.fanli.exception.msg.UserSystemMsgException;
import com.yeshi.fanli.exception.user.UserCustomSettingsException;
import com.yeshi.fanli.service.inter.common.JumpDetailV2Service;
import com.yeshi.fanli.service.inter.config.BusinessSystemService;
import com.yeshi.fanli.service.inter.goods.CommonGoodsService;
import com.yeshi.fanli.service.inter.goods.RecommendUserGoodsService;
import com.yeshi.fanli.service.inter.homemodule.SpecialService;
import com.yeshi.fanli.service.inter.lable.QualityFactoryService;
import com.yeshi.fanli.service.inter.money.msg.MsgMoneyDetailService;
import com.yeshi.fanli.service.inter.msg.MsgConfigService;
import com.yeshi.fanli.service.inter.msg.MsgDeviceReadStateService;
import com.yeshi.fanli.service.inter.msg.MsgOtherDetailService;
import com.yeshi.fanli.service.inter.msg.UserMsgReadStateService;
import com.yeshi.fanli.service.inter.msg.UserSystemMsgService;
import com.yeshi.fanli.service.inter.order.msg.MsgOrderDetailService;
import com.yeshi.fanli.service.inter.push.DeviceActiveService;
import com.yeshi.fanli.service.inter.push.PushGoodsService;
import com.yeshi.fanli.service.inter.user.UserCustomSettingsService;
import com.yeshi.fanli.service.inter.user.UserInfoExtraService;
import com.yeshi.fanli.service.inter.user.UserInfoService;
import com.yeshi.fanli.service.inter.user.invite.MsgInviteDetailService;
import com.yeshi.fanli.service.inter.user.msg.MsgAccountDetailService;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.RedisManager;
import com.yeshi.fanli.util.StringUtil;
import com.yeshi.fanli.util.TimeUtil;
import com.yeshi.fanli.util.VersionUtil;
import com.yeshi.fanli.util.account.UserUtil;
import com.yeshi.fanli.util.annotation.RequestSerializableByKey;
import com.yeshi.fanli.util.factory.CommonGoodsFactory;
import com.yeshi.fanli.util.factory.msg.UserMsgVOFactory;
import com.yeshi.fanli.util.taobao.TaoKeApiUtil;
import com.yeshi.fanli.vo.msg.UserCommonMsgVO;
import com.yeshi.fanli.vo.msg.UserHomeMsgVO;
import com.yeshi.fanli.vo.msg.UserMsgCenter;
import com.yeshi.fanli.vo.msg.UserMsgVO;
import com.yeshi.fanli.vo.msg.UserSystemMsgVO;
import com.yeshi.fanli.vo.user.UserSettingsVO;
import net.sf.json.JSONObject;
@Controller
@RequestMapping("api/v1/user/msg")
public class UserMsgController {
   @Resource
   private BusinessSystemService businessSystemService;
   @Resource
   private MsgOrderDetailService msgOrderDetailService;
   @Resource
   private MsgMoneyDetailService msgMoneyDetailService;
   @Resource
   private MsgInviteDetailService msgInviteDetailService;
   @Resource
   private MsgAccountDetailService msgAccountDetailService;
   @Resource
   private MsgOtherDetailService msgOtherDetailService;
   @Resource
   private UserMsgReadStateService userMsgReadStateService;
   @Resource
   private RecommendUserGoodsService recommendUserGoodsService;
   @Resource
   private UserInfoService userInfoService;
   @Resource
   private UserSystemMsgService userSystemMsgService;
   @Resource
   private CommonGoodsService commonGoodsService;
   @Resource
   private QualityFactoryService qualityFactoryService;
   @Resource
   private UserCustomSettingsService userCustomSettingsService;
   @Resource
   private RedisManager redisManager;
   @Resource
   private SpecialService specialService;
   @Resource
   private JumpDetailV2Service jumpDetailV2Service;
   @Resource
   private PushGoodsService pushGoodsService;
   @Resource
   private DeviceActiveService deviceActiveService;
   @Resource
   private MsgConfigService msgConfigService;
   @Resource
   private MsgDeviceReadStateService msgDeviceReadStateService;
   @Resource
   private UserInfoExtraService userInfoExtraService;
   // 消息的类型
   final static String MSG_TYPE_ORDER = "order";
   final static String MSG_TYPE_MONEY = "money";
   final static String MSG_TYPE_ACCOUNT = "account";
   final static String MSG_TYPE_INVITE = "invite";
   final static String MSG_TYPE_OTHER = "other";
   /**
    * 获取消息列表
    *
    * @param acceptData
    * @param uid
    * @param page
    * @param type
    * @param out
    */
   @RequestMapping(value = "getMsgList", method = RequestMethod.POST)
   public void getMsgList(AcceptData acceptData, Long uid, int page, String type, PrintWriter out) {
      if (uid == null) {
         out.print(JsonUtil.loadFalseResult(1, "用户未登录"));
         return;
      }
      if (StringUtil.isNullOrEmpty(type)) {
         out.print(JsonUtil.loadFalseResult(2, "请上传type"));
         return;
      }
      List<UserMsgVO> list = new ArrayList<>();
      long count = 0;
      switch (type) {
      case MSG_TYPE_ORDER:
         userMsgReadStateService.readOrderMsg(uid);
         List<MsgOrderDetail> detailList = msgOrderDetailService.listMsgOrderDetail(uid, page);
         count = msgOrderDetailService.countMsgOrderDetail(uid);
         if (detailList != null)
            for (MsgOrderDetail detail : detailList) {
               JSONObject params = new JSONObject();
               params.put("orderNo", detail.getOrderId());
               if (detail.getType() == MsgTypeOrderTypeEnum.share
                     || detail.getType() == MsgTypeOrderTypeEnum.invite)
                  params.put("orderHideNo", UserUtil.filterOrderId(detail.getOrderId()));
               list.add(UserMsgVOFactory.create(detail, jumpDetailV2Service.getByTypeCache("order_search"),
                     params));
            }
         break;
      case MSG_TYPE_MONEY:
         userMsgReadStateService.readMoneyMsg(uid);
         List<MsgMoneyDetail> detailList1 = msgMoneyDetailService.listMsgMoneyDetail(uid, page);
         count = msgMoneyDetailService.countMsgMoneyDetail(uid);
         if (detailList1 != null)
            for (MsgMoneyDetail detail : detailList1)
               list.add(UserMsgVOFactory.create(detail));
         break;
      case MSG_TYPE_ACCOUNT:
         userMsgReadStateService.readAccountMsg(uid);
         List<MsgAccountDetail> detailList2 = msgAccountDetailService.listMsgAccountDetail(uid, page);
         count = msgAccountDetailService.countMsgAccountDetail(uid);
         if (detailList2 != null)
            for (MsgAccountDetail detail : detailList2)
               list.add(UserMsgVOFactory.create(detail));
         break;
      case MSG_TYPE_INVITE:
         userMsgReadStateService.readInviteMsg(uid);
         List<MsgInviteDetail> detailList3 = msgInviteDetailService.listMsgInviteDetail(uid, page);
         count = msgInviteDetailService.countMsgInviteDetail(uid);
         if (detailList3 != null)
            for (MsgInviteDetail detail : detailList3) {
               UserMsgVO vo = UserMsgVOFactory.create(detail);
               if (vo != null)
                  list.add(vo);
               else
                  count--;
            }
         break;
      case MSG_TYPE_OTHER:
         userMsgReadStateService.readOtherMsg(uid);
         List<MsgOtherDetail> detailList4 = msgOtherDetailService.listMsgOtherDetail(uid, page);
         count = msgOtherDetailService.countMsgOtherDetail(uid);
         if (detailList4 != null)
            for (MsgOtherDetail detail : detailList4) {
               UserMsgVO vo = UserMsgVOFactory.create(detail);
               if (vo != null)
                  list.add(vo);
               else
                  count--;
            }
         break;
      }
      GsonBuilder builder = new GsonBuilder();
      builder = getTimeDescJsonBuilder(builder);
      JSONObject root = new JSONObject();
      root.put("data", builder.create().toJson(list));
      root.put("count", count);
      out.print(JsonUtil.loadTrueResult(root));
   }
   /**
    * 获取消息未读数
    *
    * @param acceptData
    * @param uid
    * @param out
    */
   @RequestSerializableByKey(key = "#acceptData.device")
   @RequestMapping(value = "getUnReadMsgCount", method = RequestMethod.POST)
   public void getUnReadMsgCount(AcceptData acceptData, Long uid, PrintWriter out) {
      GsonBuilder androidBuilder = new GsonBuilder().registerTypeAdapter(Integer.class,
            new JsonSerializer<Integer>() {
               @Override
               public JsonElement serialize(Integer value, Type theType, JsonSerializationContext context) {
                  if (value == null) {
                     return new JsonPrimitive("0");
                  } else {
                     if (value >= 100)
                        return new JsonPrimitive("99+");
                     else
                        return new JsonPrimitive(value);
                  }
               }
            });
      if (uid == null) {
         // 如果用户未登录就读取设备消息
         UserMsgUnReadNum num = new UserMsgUnReadNum();
         num.setTypeAccount(0);
         num.setTypeInvite(0);
         num.setTypeMoney(0);
         num.setTypeOrder(0);
         num.setTypeOther(0);
         num.setTypeScore(0);
         num.setTypeSystem(0);
         JSONObject data = null;
         if ("android".equalsIgnoreCase(acceptData.getPlatform())) {
            data = JSONObject
                  .fromObject(androidBuilder.excludeFieldsWithoutExposeAnnotation().create().toJson(num));
         } else {
            data = JSONObject.fromObject(JsonUtil.getApiCommonGson().toJson(num));
         }
         data.put("totalCount", 0);
         try {
            UserSettingsVO vo = userCustomSettingsService.getMySettings(uid);
            if (vo != null && vo.getNoNewsRedDot() != null && vo.getNoNewsRedDot() == 1) {
               data.put("totalCount", 0);
            }
         } catch (UserCustomSettingsException e) {
         }
         if (VersionUtil.greaterThan_1_5_50(acceptData.getPlatform(), acceptData.getVersion())) {
            int totalCount = msgDeviceReadStateService.getUnReadCount(acceptData.getDevice(),
                  "android".equalsIgnoreCase(acceptData.getPlatform()) ? 1 : 2, MsgDeviceReadState.TYPE_KEFU);
            data.put("totalCount", totalCount);
         }
         data.put("mineCount", 0);
         out.print(JsonUtil.loadTrueResult(data));
         return;
      }
      UserMsgUnReadNum num = userMsgReadStateService.getReadStateByUid(uid);
      int totalCount = num.getTypeAccount() + num.getTypeInvite() + num.getTypeMoney() + num.getTypeOrder()
            + num.getTypeScore() + num.getTypeSystem() + num.getTypeOther();
      // 1.5.50及以后的版本需要添加设备未读消息
      if (VersionUtil.greaterThan_1_5_50(acceptData.getPlatform(), acceptData.getVersion())) {
         totalCount += msgDeviceReadStateService.getUnReadCount(acceptData.getDevice(),
               "android".equalsIgnoreCase(acceptData.getPlatform()) ? 1 : 2, MsgDeviceReadState.TYPE_KEFU);
      }
      JSONObject data = null;
      if ("android".equalsIgnoreCase(acceptData.getPlatform())) {
         data = JSONObject.fromObject(androidBuilder.excludeFieldsWithoutExposeAnnotation().create().toJson(num));
      } else {
         data = JSONObject.fromObject(JsonUtil.getApiCommonGson().toJson(num));
      }
      data.put("totalCount", totalCount);
      // "我的"选项角标
      int welfareCenterNews = 0;
      if (uid != null) {
         UserInfoExtra userInfoExtra = userInfoExtraService.getUserInfoExtra(uid);
         if (userInfoExtra != null) {
            if (userInfoExtra.getCouponNews() != null) {
               welfareCenterNews = userInfoExtra.getCouponNews();
            }
         }
      }
      data.put("mineCount", welfareCenterNews);
      try {
         UserSettingsVO vo = userCustomSettingsService.getMySettings(uid);
         if (vo != null && vo.getNoNewsRedDot() != null && vo.getNoNewsRedDot() == 1) {
            data.put("totalCount", 0);
         }
      } catch (UserCustomSettingsException e) {
         e.printStackTrace();
      }
      out.print(JsonUtil.loadTrueResult(data));
   }
   private String getTimeDesc(Date nowDate, Date targetDate) {
      Calendar now = Calendar.getInstance();
      now.setTime(nowDate);
      if (TimeUtil.getGernalTime(targetDate.getTime(), "yyyy-MM-dd")
            .equalsIgnoreCase(TimeUtil.getGernalTime(now.getTimeInMillis(), "yyyy-MM-dd"))) {
         return "今天 " + TimeUtil.getGernalTime(targetDate.getTime(), "HH:mm");
      } else if (TimeUtil.getGernalTime(targetDate.getTime(), "yyyy-MM-dd")
            .equalsIgnoreCase(TimeUtil.getGernalTime(now.getTimeInMillis() - 1000 * 60 * 60 * 24L, "yyyy-MM-dd"))) {
         return "昨天 " + TimeUtil.getGernalTime(targetDate.getTime(), "HH:mm");
      } else {
         return TimeUtil.getGernalTime(targetDate.getTime(), "yyyy.MM.dd HH:mm");
      }
   }
   private GsonBuilder getTimeDescJsonBuilder(GsonBuilder builder) {
      builder = builder.registerTypeAdapter(Date.class, new JsonSerializer<Date>() {
         @Override
         public JsonElement serialize(Date value, Type theType, JsonSerializationContext context) {
            if (value == null) {
               return new JsonPrimitive("");
            } else {
               Calendar now = Calendar.getInstance();
               return new JsonPrimitive(getTimeDesc(new Date(now.getTimeInMillis()), value));
            }
         }
      }).registerTypeAdapter(BigDecimal.class, new JsonSerializer<BigDecimal>() {
         @Override
         public JsonElement serialize(BigDecimal value, Type theType, JsonSerializationContext context) {
            if (value == null) {
               return new JsonPrimitive("0");
            } else {
               return new JsonPrimitive(BigDecimalUtil.getWithNoZera(value).toString());
            }
         }
      });
      return builder;
   }
   private void addRecommendGoods(Long uid, String device, String imei, String idfa) {
      TaoBaoSearchResult result = TaoKeApiUtil.guessDeviceLike(1, 50, imei, idfa);
      if (result != null && result.getTaoBaoGoodsBriefs() != null) {
         for (int i = 0; i < result.getTaoBaoGoodsBriefs().size(); i++) {
            if (result.getTaoBaoGoodsBriefs().get(i).getCouponAmount() == null
                  || result.getTaoBaoGoodsBriefs().get(i).getCouponAmount().compareTo(new BigDecimal(0)) <= 0) {
               result.getTaoBaoGoodsBriefs().remove(i);
               i--;
            }
         }
         // 随机几个
         int count = (int) (Math.random() * 3) + 1;
         Set<Integer> positionList = new HashSet<>();
         for (int i = 0; i < count; i++)
            if (result.getTaoBaoGoodsBriefs().size() > 0) {
               positionList.add((int) (result.getTaoBaoGoodsBriefs().size() * Math.random()));
            }
         if (positionList != null && positionList.size() > 0) {
            List<CommonGoods> goodsList = new ArrayList<>();
            for (Integer p : positionList) {
               TaoBaoGoodsBrief goodsB = result.getTaoBaoGoodsBriefs().get(p);
               try {
                  CommonGoods cgoods = commonGoodsService
                        .addOrUpdateCommonGoods(CommonGoodsFactory.create(goodsB));
                  goodsList.add(cgoods);
               } catch (CommonGoodsException e) {
                  e.printStackTrace();
               }
            }
            try {
               recommendUserGoodsService.addRecommend(uid, device, "", goodsList);
            } catch (RecommendUserGoodsException e) {
               e.printStackTrace();
            }
         }
      }
   }
   private void addRecommendGoods(Long uid, String device) {
      List<QualityFactory> qfList = qualityFactoryService.listByMinSalesCountOrderByCreateTimeDesc(10000, 1, 20);
      if (qfList != null && qfList != null) {
         for (int i = 0; i < qfList.size(); i++) {
            if (qfList.get(i).getTaoBaoGoodsBrief().getCouponAmount() == null
                  || qfList.get(i).getTaoBaoGoodsBrief().getCouponAmount().compareTo(new BigDecimal(0)) <= 0) {
               qfList.remove(i);
               i--;
            }
         }
         // 随机几个
         int count = (int) (Math.random() * 3) + 1;
         Set<Integer> positionList = new HashSet<>();
         for (int i = 0; i < count; i++)
            if (qfList.size() > 0) {
               positionList.add((int) (qfList.size() * Math.random()));
            }
         if (positionList != null && positionList.size() > 0) {
            List<CommonGoods> goodsList = new ArrayList<>();
            for (Integer p : positionList) {
               TaoBaoGoodsBrief goodsB = qfList.get(p).getTaoBaoGoodsBrief();
               try {
                  CommonGoods cgoods = commonGoodsService
                        .addOrUpdateCommonGoods(CommonGoodsFactory.create(goodsB));
                  goodsList.add(cgoods);
               } catch (CommonGoodsException e) {
                  e.printStackTrace();
               }
            }
            try {
               recommendUserGoodsService.addRecommend(uid, device, "", goodsList);
            } catch (RecommendUserGoodsException e) {
               e.printStackTrace();
            }
         }
      }
   }
   /**
    * 获取首页消息
    *
    * @param acceptData
    * @param uid
    * @param page
    * @param out
    */
   @RequestMapping(value = "getHomeMsgList", method = RequestMethod.POST)
   public void getHomeMsgList(AcceptData acceptData, Long uid, int page, HttpSession session, PrintWriter out) {
      if (uid != null && uid == 0)
         uid = null;
      if (uid != null)
         userSystemMsgService.syncSystemZNX(uid);
      String device = acceptData.getDevice();
      if (device == null || device.trim().length() == 0) {
         out.print(JsonUtil.loadFalseResult("设备号不能为空"));
         return;
      }
      if (page == 1) {
         if (uid != null)
            recommendUserGoodsService.syncDeviceAndUid(uid, acceptData.getDevice());
         boolean canAdd = false;
         int hour = Calendar.getInstance().get(Calendar.HOUR);
         RecommendUserGoods goods = recommendUserGoodsService.getLatestRecommendUserGoodsByDevice(device);
         if (goods == null) {
            canAdd = true;
         } else {
            // 是否和上次间隔时间足够
            if (System.currentTimeMillis() - goods.getCreateTime().getTime() >= 1000 * 60 * 60 * 4L) {
               canAdd = true;
            }
         }
         // String key = "recommend-goods-user-" + uid;
         String key = "recommend-goods-user-" + device;
         if (Constant.IS_OUTNET) {
            if (canAdd && StringUtil.isNullOrEmpty(redisManager.getCommonString(key))) {
               if (Constant.IS_OUTNET)
                  redisManager.cacheCommonString(key, "1", 20);
               if (hour < 12)
                  addRecommendGoods(uid, device);
               else
                  addRecommendGoods(uid, device, acceptData.getImei(), acceptData.getIdfa());
               session.removeAttribute("recommendgoods");
            }
         } else {
            if (canAdd) {
               if (hour < 12)
                  addRecommendGoods(uid, device);
               else
                  addRecommendGoods(uid, device, acceptData.getImei(), acceptData.getIdfa());
            }
         }
      }
      List<UserHomeMsgVO> volist = new ArrayList<>();
      List<RecommendUserGoods> list = recommendUserGoodsService.listRecommendGoodsByDevice(device, page,
            Constant.PAGE_SIZE);
      long count = recommendUserGoodsService.countRecommendGoodsByDevice(device);
      Date now = new Date();
      for (RecommendUserGoods goods : list) {
         UserHomeMsgVO vo = new UserHomeMsgVO();
         vo.setContent(goods.getRecommendDesc());
         vo.setCreateTime(getTimeDesc(now, goods.getCreateTime()));
         if (goods.getGoodsList().size() == 1)
            vo.setType(UserHomeMsgVO.TYPE_GOODS_1);
         else if (goods.getGoodsList().size() == 2)
            vo.setType(UserHomeMsgVO.TYPE_GOODS_2);
         else if (goods.getGoodsList().size() == 3)
            vo.setType(UserHomeMsgVO.TYPE_GOODS_3);
         List<TaoBaoGoodsBrief> goodsList = new ArrayList<>();
         for (CommonGoods cg : goods.getGoodsList()) {
            if (goods.getGoodsList().size() == 1)
               cg.setPicture(TbImgUtil.getTBSizeImg(
                     StringUtil.isNullOrEmpty(cg.getPictureWhite()) ? cg.getPicture() : cg.getPictureWhite(),
                     400));
            else if (goods.getGoodsList().size() == 2)
               cg.setPicture(TbImgUtil.getTBSizeImg(
                     StringUtil.isNullOrEmpty(cg.getPictureWhite()) ? cg.getPicture() : cg.getPictureWhite(),
                     320));
            else if (goods.getGoodsList().size() == 3)
               cg.setPicture(TbImgUtil.getTBSizeImg(
                     StringUtil.isNullOrEmpty(cg.getPictureWhite()) ? cg.getPicture() : cg.getPictureWhite(),
                     220));
            TaoBaoGoodsBrief tbGoods = new TaoBaoGoodsBrief();
            if (cg.getCouponAmount() == null)
               tbGoods.setCouponAmount(new BigDecimal(0));
            else
               tbGoods.setCouponAmount(cg.getCouponAmount());
            tbGoods.setAuctionId(cg.getGoodsId());
            tbGoods.setPictUrl(cg.getPicture());
            goodsList.add(tbGoods);
         }
         vo.setGoodsList(goodsList);
         vo.setTitle("猜你喜欢");
         vo.setIcon("http://img.flqapp.com/resource/msg/icon_msg_guess_like.png");
         volist.add(vo);
      }
      Long time = (uid == null ? System.currentTimeMillis() : userInfoService.selectByPKey(uid).getCreatetime());
      if (volist.size() > 0 && volist.size() < Constant.PAGE_SIZE) {
         // 添加欢迎语
         // 创建时间在28号后的才有新人欢迎
         if ((time > TimeUtil.convertToTimeTemp("2019-01-28", "yyyy-MM-dd") || uid == null)) {
            UserHomeMsgVO vo = new UserHomeMsgVO();
            vo.setContent(String.format("恭喜你,成为%s的用户\n独家优惠券帮你省钱;\n参与奖金活动帮你赚钱;\n让%s成为你的省钱助手吧!",Constant.getAppName(acceptData.getPlatform(), acceptData.getVersion()),Constant.getAppName(acceptData.getPlatform(), acceptData.getVersion())));
            vo.setTitle("新人欢迎");
            vo.setCreateTime(getTimeDesc(now, new Date(time)));
            vo.setType(UserHomeMsgVO.TYPE_WELCOME);
            volist.add(vo);
            count++;
         }
      }
      JSONObject root = new JSONObject();
      root.put("msgList", new Gson().toJson(volist));
      if (page == 1 && uid != null) {
         UserMsgUnReadNum num = userMsgReadStateService.getReadStateByUid(uid);
         UserSystemMsg usm = userSystemMsgService.getLatestUserSystemMsg(uid);
         if (usm != null)
            root.put("systemMsg",
                  new UserSystemMsgVO(usm.getId(), usm.getType().name(), usm.getSolved(), "系统消息", usm.getTitle(),
                        usm.getTimeTag() == 1 ? "http://img.flqapp.com/resource/msg/icon_emergent.png" : "",
                        "http://img.flqapp.com/resource/msg/icon_msg_system.png",
                        getTimeDesc(now, usm.getCreateTime()), num.getTypeSystem()));
      }
      root.put("count", count);
      out.print(JsonUtil.loadTrueResult(root));
   }
   private UserCommonMsgVO getKeFuMsg(AcceptData acceptData) {
      MsgDeviceReadState kefuState = msgDeviceReadStateService.getByDeviceAndPlatformAndType(
            UserCommonMsgVO.TYPE_KEFU, acceptData.getDevice(),
            acceptData.getPlatform().equalsIgnoreCase("android") ? 1 : 2);
      // 人工客服
      UserCommonMsgVO vo = new UserCommonMsgVO("http://img.flqapp.com/resource/msg/icon_kefu.png", "人工客服", new Date(),
            UserCommonMsgVO.TYPE_KEFU, "", false, null, null, 0);
      if (kefuState != null) {
         vo.setUnReadCount(kefuState.getUnReadCount() == null ? 0 : kefuState.getUnReadCount());
         if (!StringUtil.isNullOrEmpty(kefuState.getLatestContent()))
            vo.setLatestMsg(kefuState.getLatestContent());
         if (vo.getUnReadCount() != null && vo.getUnReadCount() > 0)
            vo.setRead(false);
         else
            vo.setRead(true);
         if (kefuState.getLatestContentTime() != null)
            vo.setTime(kefuState.getLatestContentTime());
      } else
         vo.setRead(true);
      if (StringUtil.isNullOrEmpty(vo.getLatestMsg()))
         vo.setLatestMsg("[点击打开人工客服]");
      return vo;
   }
   /**
    * 获取消息列表
    *
    * @param acceptData
    * @param uid
    * @param page
    * @param type
    * @param out
    */
   @RequestSerializableByKey(key = "#acceptData.device")
   @RequestMapping(value = "getHomeMsgListNew", method = RequestMethod.POST)
   public void getHomeMsgListNew(AcceptData acceptData, Long uid, PrintWriter out) {
      if (uid != null && uid == 0)
         uid = null;
      if (uid != null) {
         userSystemMsgService.syncSystemZNX(uid);
      }
      List<UserMsgCenter> listCenter = new ArrayList<>();
      // 单条消息
      List<UserCommonMsgVO> commonMsgList = new ArrayList<>();
      long currentTime = System.currentTimeMillis();
      // 官宣任务
      if (uid != null) {
         MsgCommonDTO guanXuanMsg = msgConfigService.getGuanXuanMsg();
         if (guanXuanMsg != null && guanXuanMsg.getShow() == true) {
            boolean read = false;
            UserMsgUnReadNum num = userMsgReadStateService.getReadStateByUid(uid);
            if (num != null && (num.getGuanXuanReadTime() != null
                  && guanXuanMsg.getUpdateTime().getTime() < num.getGuanXuanReadTime().getTime()))
               read = true;
            // 查询是否已读
            if ((guanXuanMsg.getStartTime() != null && currentTime < guanXuanMsg.getStartTime().getTime())
                  || (guanXuanMsg.getEndTime() != null && currentTime > guanXuanMsg.getEndTime().getTime())) {
               // 不显示
            } else
               commonMsgList.add(new UserCommonMsgVO(guanXuanMsg.getIcon(), guanXuanMsg.getTitle(),
                     guanXuanMsg.getUpdateTime(), UserCommonMsgVO.TYPE_GUANXUAN, guanXuanMsg.getContent(), read,
                     guanXuanMsg.getJumpDetail(), guanXuanMsg.getParams(), 0));
         }
      }
      // 板栗快省小助手
      MsgCommonDTO zhuShouMsg = msgConfigService.getZhuShouMsg();
      if (zhuShouMsg != null && zhuShouMsg.getShow() == true) {
         boolean read = false;
         MsgDeviceReadState state = msgDeviceReadStateService.getByDeviceAndPlatformAndType(
               UserCommonMsgVO.TYPE_ZHUSHOU, acceptData.getDevice(),
               acceptData.getPlatform().equalsIgnoreCase("android") ? 1 : 2);
         if (state != null && state.getReadTime() != null
               && zhuShouMsg.getUpdateTime().getTime() < state.getReadTime().getTime())
            read = true;
         // 查询是否已读
         if ((zhuShouMsg.getStartTime() != null && currentTime < zhuShouMsg.getStartTime().getTime())
               || (zhuShouMsg.getEndTime() != null && currentTime > zhuShouMsg.getEndTime().getTime())) {
            // 不显示
         } else
            commonMsgList.add(new UserCommonMsgVO(zhuShouMsg.getIcon(), zhuShouMsg.getTitle(),
                  zhuShouMsg.getUpdateTime(), UserCommonMsgVO.TYPE_ZHUSHOU, zhuShouMsg.getContent(), read,
                  zhuShouMsg.getJumpDetail(), zhuShouMsg.getParams(), 0));
      }
      // 人工客服
      commonMsgList.add(getKeFuMsg(acceptData));
      // 推荐记录
      DeviceActive deviceActive = deviceActiveService.getDeviceByDeviceAndPlatform(acceptData.getDevice(),
            acceptData.getDevice(), acceptData.getPlatform());
      if (deviceActive != null) {
         // 设备注册时间
         Date createTime = deviceActive.getCreateTime();
         List<PushGoods> list = pushGoodsService.listHistoryByPushTime(0, 1, uid, createTime);
         if (list != null && list.size() > 0) {
            MsgDeviceReadState state = msgDeviceReadStateService.getByDeviceAndPlatformAndType(
                  UserCommonMsgVO.TYPE_RECOMMEND, acceptData.getDevice(),
                  acceptData.getPlatform().equalsIgnoreCase("android") ? 1 : 2);
            boolean read = false;
            if (state != null && state.getReadTime() != null
                  && list.get(0).getPushTime().getTime() < state.getReadTime().getTime())
               read = true;
            commonMsgList.add(new UserCommonMsgVO("http://img.flqapp.com/resource/msg/icon_recommend.png", "推荐记录",
                  list.get(0).getPushTime(), UserCommonMsgVO.TYPE_RECOMMEND, list.get(0).getContent(), read,
                  jumpDetailV2Service.getByTypeCache("recommend_list"), null, 0));
         }
      }
      //
      // list = pushGoodsService.listHistoryByPushTime(0, 1, uid, createTime);
      // 1、活动区域
      int platformCode = Constant.getPlatformCode(acceptData.getPlatform());
      List<Special> listSpecial = specialService.listByPlaceKey("msg_activities", platformCode, Integer.parseInt(acceptData.getVersion()));
      if (listSpecial != null && listSpecial.size() > 0) {
         for (Special special : listSpecial) {
            boolean needLogin = special.isJumpLogin();
            JumpDetailV2 jumpDetail = special.getJumpDetail();
            if (jumpDetail != null) {
               jumpDetail.setNeedLogin(needLogin);
               special.setJumpDetail(jumpDetail);
            }
            UserMsgCenter msgCenter = new UserMsgCenter();
            msgCenter.setSpecial(special);
            listCenter.add(msgCenter);
         }
      }
      // 2、消息区域
      if (uid != null && uid > 0) {
         int page = 1;
         List<UserMsgVO> list = new ArrayList<>();
         List<MsgOrderDetail> detailList = msgOrderDetailService.listMsgOrderDetail(uid, page);
         if (detailList != null && detailList.size() > 0) {
            for (MsgOrderDetail detail : detailList) {
               JSONObject params = new JSONObject();
               params.put("orderNo", detail.getOrderId());
               if (detail.getType() == MsgTypeOrderTypeEnum.share
                     || detail.getType() == MsgTypeOrderTypeEnum.invite)
                  params.put("orderHideNo", UserUtil.filterOrderId(detail.getOrderId()));
               UserMsgVO userMsgVO = UserMsgVOFactory.create(detail,
                     jumpDetailV2Service.getByTypeCache("order_search"), params);
               userMsgVO.setType(MSG_TYPE_ORDER);
               list.add(userMsgVO);
            }
         }
         List<MsgMoneyDetail> detailList1 = msgMoneyDetailService.listMsgMoneyDetail(uid, page);
         if (detailList1 != null && detailList1.size() > 0) {
            for (MsgMoneyDetail detail : detailList1) {
               UserMsgVO userMsgVO = UserMsgVOFactory.create(detail);
               userMsgVO.setType(MSG_TYPE_MONEY);
               list.add(userMsgVO);
            }
         }
         List<MsgAccountDetail> detailList2 = msgAccountDetailService.listMsgAccountDetail(uid, page);
         if (detailList2 != null && detailList2.size() > 0) {
            for (MsgAccountDetail detail : detailList2) {
               UserMsgVO userMsgVO = UserMsgVOFactory.create(detail);
               userMsgVO.setType(MSG_TYPE_ACCOUNT);
               list.add(userMsgVO);
            }
         }
         List<MsgInviteDetail> detailList3 = msgInviteDetailService.listMsgInviteDetail(uid, page);
         if (detailList3 != null && detailList3.size() > 0) {
            for (MsgInviteDetail detail : detailList3) {
               UserMsgVO userMsgVO = UserMsgVOFactory.create(detail);
               if (userMsgVO != null) {
                  userMsgVO.setType(MSG_TYPE_INVITE);
                  list.add(userMsgVO);
               }
            }
         }
         List<MsgOtherDetail> detailList4 = msgOtherDetailService.listMsgOtherDetail(uid, page);
         if (detailList4 != null && detailList4.size() > 0) {
            for (MsgOtherDetail detail : detailList4) {
               UserMsgVO userMsgVO = UserMsgVOFactory.create(detail);
               if (userMsgVO != null) {
                  userMsgVO.setType(MSG_TYPE_OTHER);
                  list.add(userMsgVO);
               }
            }
         }
         if (list.size() > 0) {
            // 时间排序
            listSort(list);
            if (list.size() >= 20) {
               list = list.subList(0, 19);
            }
            for (UserMsgVO userMsgVO : list) {
               UserMsgCenter userMsgCenter = new UserMsgCenter();
               userMsgCenter.setUserMsg(userMsgVO);
               listCenter.add(userMsgCenter);
            }
         }
      }
      // 3、添加欢迎语
      Long time = (uid == null ? System.currentTimeMillis() : userInfoService.selectByPKey(uid).getCreatetime());
      // 创建时间在28号后的才有新人欢迎
      if ((time > TimeUtil.convertToTimeTemp("2019-01-28", "yyyy-MM-dd") || uid == null)) {
         Map<String, Object> map = new HashMap<String, Object>();
         map.put("title", "新人欢迎");
         map.put("content",String.format("恭喜你,成为%s的用户\n独家优惠券帮你省钱;\n参与奖金活动帮你赚钱;\n让%s成为你的省钱助手吧!",Constant.getAppName(acceptData.getPlatform(), acceptData.getVersion()),Constant.getAppName(acceptData.getPlatform(), acceptData.getVersion())));
         map.put("createTime", new Date(time));
         UserMsgCenter msgCenternre = new UserMsgCenter();
         msgCenternre.setWelcomeMsg(map);
         listCenter.add(msgCenternre);
      }
      GsonBuilder builder = new GsonBuilder();
      builder = getTimeDescJsonBuilder(builder);
      JSONObject root = new JSONObject();
      if (uid != null && uid > 0) {
         UserMsgUnReadNum num = userMsgReadStateService.getReadStateByUid(uid);
         UserSystemMsg usm = userSystemMsgService.getLatestUserSystemMsg(uid);
         if (usm != null) {
            // commonMsgList.add(0,new UserCommonMsgVO(icon, "系统消息", time,
            // type, latestMsg, ,
            // jumpDetailV2Service.getByTypeCache("system_msg"), params));
            root.put("systemMsg",
                  new UserSystemMsgVO(usm.getId(), usm.getType().name(), usm.getSolved(), "系统消息", usm.getTitle(),
                        usm.getTimeTag() == 1 ? "http://img.flqapp.com/resource/msg/icon_emergent.png" : "",
                        "http://img.flqapp.com/resource/msg/icon_msg_system.png",
                        getTimeDesc(new Date(), usm.getCreateTime()), num.getTypeSystem()));
         }
      }
      /**
       * 提醒大图
       */
      MsgCommonDTO notify = msgConfigService.getNotifyMsg();
      if (notify != null && notify.getShow() == true) {
         boolean read = false;
         MsgDeviceReadState state = msgDeviceReadStateService.getByDeviceAndPlatformAndType(
               UserCommonMsgVO.TYPE_NOTIFY, acceptData.getDevice(),
               acceptData.getPlatform().equalsIgnoreCase("android") ? 1 : 2);
         if (state != null && state.getReadTime() != null
               && zhuShouMsg.getUpdateTime().getTime() < state.getReadTime().getTime())
            read = true;
         if (notify.getJumpDetail() == null)
            read = true;
         // 查询是否已读
         UserCommonMsgVO vo = new UserCommonMsgVO(notify.getIcon(), notify.getTitle(), notify.getUpdateTime(),
               UserCommonMsgVO.TYPE_NOTIFY, notify.getContent(), read, notify.getJumpDetail(), notify.getParams(),
               0);
         vo.setPicture(notify.getPicture());
         root.put("notifyMsg", builder.create().toJson(vo));
      }
      root.put("list", builder.create().toJson(listCenter));
      root.put("commonList", builder.create().toJson(commonMsgList));
      root.put("count", listCenter.size());
      out.print(JsonUtil.loadTrueResult(root));
   }
   public static void listSort(List<UserMsgVO> list) {
      Collections.sort(list, new Comparator<UserMsgVO>() {
         @Override
         public int compare(UserMsgVO o1, UserMsgVO o2) {
            if (o1.getTime().getTime() > o2.getTime().getTime()) {
               return -1;
            } else if (o1 == o2) {
               return 0;
            } else {
               return 1;
            }
         }
      });
   }
   /**
    * 获取系统消息列表
    *
    * @param acceptData
    * @param uid
    * @param page
    * @param out
    */
   @RequestMapping(value = "getSystemMsgList", method = RequestMethod.POST)
   public void getSystemMsgList(AcceptData acceptData, Long uid, int page, PrintWriter out) {
      if (uid == null) {
         out.print(JsonUtil.loadFalseResult(1, "用户未登录"));
         return;
      }
      List<UserSystemMsgVO> voList = new ArrayList<>();
      List<UserSystemMsg> list = userSystemMsgService.listUserSystemMsg(uid, page, Constant.PAGE_SIZE);
      if (list != null)
         for (UserSystemMsg usm : list) {
            voList.add(new UserSystemMsgVO(usm.getId(), usm.getType().name(), usm.getSolved(), usm.getTitle(),
                  usm.getContent(),
                  usm.getTimeTag() == 1 ? "http://img.flqapp.com/resource/msg/icon_emergent.png" : "", null,
                  usm.getCreateTime().getTime() + "", 0));
         }
      long count = userSystemMsgService.countUserSystemMsg(uid);
      userMsgReadStateService.readUserSystemMsg(uid);
      JSONObject root = new JSONObject();
      root.put("data", voList);
      root.put("count", count);
      out.print(JsonUtil.loadTrueResult(root));
   }
   /**
    * 设置问题已经解决
    *
    * @param acceptData
    * @param uid
    * @param id
    * @param out
    */
   @RequestMapping(value = "setSystemMsgSolved", method = RequestMethod.POST)
   public void setSystemMsgSolved(AcceptData acceptData, Long uid, Long id, PrintWriter out) {
      if (uid == null) {
         out.print(JsonUtil.loadFalseResult(1, "用户未登录"));
         return;
      }
      if (id == null) {
         out.print(JsonUtil.loadFalseResult(2, "消息ID为空"));
         return;
      }
      try {
         userSystemMsgService.setSystemMsgSolved(uid, id);
         out.print(JsonUtil.loadTrueResult(""));
      } catch (UserSystemMsgException e) {
         out.print(JsonUtil.loadFalseResult(e.getCode(), e.getMsg()));
      }
   }
   @RequestMapping(value = "setAllMsgRead", method = RequestMethod.POST)
   public void setAllMsgRead(AcceptData acceptData, Long uid, PrintWriter out) {
      msgDeviceReadStateService.setAllMsgRead(acceptData.getDevice(),
            "android".equalsIgnoreCase(acceptData.getPlatform()) ? 1 : 2);
      if (uid == null) {
         out.print(JsonUtil.loadFalseResult(1, "用户未登录"));
         return;
      }
      // 初始化读取状态
      msgDeviceReadStateService.initReadState(acceptData.getDevice(),
            "android".equalsIgnoreCase(acceptData.getPlatform()) ? 1 : 2, UserCommonMsgVO.TYPE_RECOMMEND);
      msgDeviceReadStateService.initReadState(acceptData.getDevice(),
            "android".equalsIgnoreCase(acceptData.getPlatform()) ? 1 : 2, UserCommonMsgVO.TYPE_ZHUSHOU);
      // 设置设备消息所有已读
      msgDeviceReadStateService.setAllMsgRead(acceptData.getDevice(),
            "android".equalsIgnoreCase(acceptData.getPlatform()) ? 1 : 2);
      UserMsgUnReadNum num = userMsgReadStateService.getReadStateByUid(uid);
      int totalNum = num.getTypeAccount() + num.getTypeInvite() + num.getTypeMoney() + num.getTypeOrder()
            + num.getTypeScore() + num.getTypeSystem() + num.getTypeOther();
      if (totalNum == 0) {
         out.print(JsonUtil.loadFalseResult(1, "没有未读消息"));
         return;
      } else
         userMsgReadStateService.setAllMsgRead(uid);
      out.print(JsonUtil.loadTrueResult(""));
   }
   /**
    * 阅读通用消息
    *
    * @param acceptData
    * @param uid
    * @param out
    */
   @RequestMapping(value = "readCommonMsg", method = RequestMethod.POST)
   public void readCommonMsg(AcceptData acceptData, Long uid, String type, PrintWriter out) {
      if (StringUtil.isNullOrEmpty(type)) {
         out.print(JsonUtil.loadFalseResult(2, "请上传type"));
         return;
      }
      if (type.equalsIgnoreCase(UserCommonMsgVO.TYPE_GUANXUAN)) {
         if (uid != null) {
            UserMsgUnReadNum num = userMsgReadStateService.getReadStateByUid(uid);
            UserMsgUnReadNum update = new UserMsgUnReadNum();
            update.setId(num.getId());
            update.setGuanXuanReadTime(new Date());
            update.setUpdateTime(new Date());
            userMsgReadStateService.updateSelective(update);
         }
      } else if (type.equalsIgnoreCase(UserCommonMsgVO.TYPE_RECOMMEND)) {
         msgDeviceReadStateService.setDeviceMsgRead(UserCommonMsgVO.TYPE_RECOMMEND, acceptData.getDevice(),
               (acceptData.getPlatform().equalsIgnoreCase("android") ? 1 : 2));
      } else if (type.equalsIgnoreCase(UserCommonMsgVO.TYPE_ZHUSHOU)) {
         msgDeviceReadStateService.setDeviceMsgRead(UserCommonMsgVO.TYPE_ZHUSHOU, acceptData.getDevice(),
               (acceptData.getPlatform().equalsIgnoreCase("android") ? 1 : 2));
      }
      out.print(JsonUtil.loadTrueResult(""));
   }
   /**
    * 上传最近的客服消息
    *
    * @param acceptData
    * @param content
    * @param time
    * @param out
    */
   @RequestMapping(value = "uploadLatestKeFuMsg", method = RequestMethod.POST)
   public void uploadLatestKeFuMsg(AcceptData acceptData, String content, Long datetime, PrintWriter out) {
      if (StringUtil.isNullOrEmpty(content) || datetime == null) {
         out.print(JsonUtil.loadFalseResult("参数不完整"));
         return;
      }
      msgDeviceReadStateService.addUnreadDeviceMsg(MsgDeviceReadState.TYPE_KEFU, acceptData.getDevice(),
            "android".equalsIgnoreCase(acceptData.getPlatform()) ? 1 : 2, 0, content, new Date(datetime));
      out.print(JsonUtil.loadTrueResult(""));
   }
}
package com.yeshi.fanli.controller.client.v1;
import java.io.PrintWriter;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import com.yeshi.fanli.entity.SystemEnum;
import com.yeshi.fanli.entity.system.ConfigKeyEnum;
import com.yeshi.fanli.service.inter.config.ConfigService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.yeshi.utils.BigDecimalUtil;
import org.yeshi.utils.JsonUtil;
import org.yeshi.utils.taobao.TbImgUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.yeshi.fanli.dto.msg.MsgCommonDTO;
import com.yeshi.fanli.entity.accept.AcceptData;
import com.yeshi.fanli.entity.bus.homemodule.Special;
import com.yeshi.fanli.entity.bus.lable.QualityFactory;
import com.yeshi.fanli.entity.bus.msg.MsgAccountDetail;
import com.yeshi.fanli.entity.bus.msg.MsgDeviceReadState;
import com.yeshi.fanli.entity.bus.msg.MsgInviteDetail;
import com.yeshi.fanli.entity.bus.msg.MsgMoneyDetail;
import com.yeshi.fanli.entity.bus.msg.MsgOrderDetail;
import com.yeshi.fanli.entity.bus.msg.MsgOrderDetail.MsgTypeOrderTypeEnum;
import com.yeshi.fanli.entity.bus.msg.MsgOtherDetail;
import com.yeshi.fanli.entity.bus.msg.UserMsgUnReadNum;
import com.yeshi.fanli.entity.bus.msg.UserSystemMsg;
import com.yeshi.fanli.entity.bus.user.UserInfoExtra;
import com.yeshi.fanli.entity.common.JumpDetailV2;
import com.yeshi.fanli.entity.goods.CommonGoods;
import com.yeshi.fanli.entity.goods.RecommendUserGoods;
import com.yeshi.fanli.entity.push.DeviceActive;
import com.yeshi.fanli.entity.push.PushGoods;
import com.yeshi.goods.facade.entity.taobao.TaoBaoGoodsBrief;
import com.yeshi.fanli.entity.taobao.TaoBaoSearchResult;
import com.yeshi.fanli.exception.goods.CommonGoodsException;
import com.yeshi.fanli.exception.goods.RecommendUserGoodsException;
import com.yeshi.fanli.exception.msg.UserSystemMsgException;
import com.yeshi.fanli.exception.user.UserCustomSettingsException;
import com.yeshi.fanli.service.inter.common.JumpDetailV2Service;
import com.yeshi.fanli.service.inter.goods.CommonGoodsService;
import com.yeshi.fanli.service.inter.goods.RecommendUserGoodsService;
import com.yeshi.fanli.service.inter.homemodule.SpecialService;
import com.yeshi.fanli.service.inter.lable.QualityFactoryService;
import com.yeshi.fanli.service.inter.money.msg.MsgMoneyDetailService;
import com.yeshi.fanli.service.inter.msg.MsgConfigService;
import com.yeshi.fanli.service.inter.msg.MsgDeviceReadStateService;
import com.yeshi.fanli.service.inter.msg.MsgOtherDetailService;
import com.yeshi.fanli.service.inter.msg.UserMsgReadStateService;
import com.yeshi.fanli.service.inter.msg.UserSystemMsgService;
import com.yeshi.fanli.service.inter.order.msg.MsgOrderDetailService;
import com.yeshi.fanli.service.inter.push.DeviceActiveService;
import com.yeshi.fanli.service.inter.push.PushGoodsService;
import com.yeshi.fanli.service.inter.user.UserCustomSettingsService;
import com.yeshi.fanli.service.inter.user.UserInfoExtraService;
import com.yeshi.fanli.service.inter.user.UserInfoService;
import com.yeshi.fanli.service.inter.user.invite.MsgInviteDetailService;
import com.yeshi.fanli.service.inter.user.msg.MsgAccountDetailService;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.RedisKeyEnum;
import com.yeshi.fanli.util.RedisManager;
import com.yeshi.fanli.util.StringUtil;
import org.yeshi.utils.TimeUtil;
import com.yeshi.fanli.util.VersionUtil;
import com.yeshi.fanli.util.account.UserUtil;
import com.yeshi.fanli.util.annotation.RequestSerializableByKey;
import com.yeshi.fanli.util.factory.CommonGoodsFactory;
import com.yeshi.fanli.util.factory.msg.UserMsgVOFactory;
import com.yeshi.fanli.util.taobao.TaoKeApiUtil;
import com.yeshi.fanli.vo.msg.UserCommonMsgVO;
import com.yeshi.fanli.vo.msg.UserHomeMsgVO;
import com.yeshi.fanli.vo.msg.UserMsgCenter;
import com.yeshi.fanli.vo.msg.UserMsgVO;
import com.yeshi.fanli.vo.msg.UserSystemMsgVO;
import com.yeshi.fanli.vo.user.UserSettingsVO;
import net.sf.json.JSONObject;
@Controller
@RequestMapping("api/v1/user/msg")
public class UserMsgController {
    @Resource
    private MsgOrderDetailService msgOrderDetailService;
    @Resource
    private MsgMoneyDetailService msgMoneyDetailService;
    @Resource
    private MsgInviteDetailService msgInviteDetailService;
    @Resource
    private MsgAccountDetailService msgAccountDetailService;
    @Resource
    private MsgOtherDetailService msgOtherDetailService;
    @Resource
    private UserMsgReadStateService userMsgReadStateService;
    @Resource
    private RecommendUserGoodsService recommendUserGoodsService;
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private UserSystemMsgService userSystemMsgService;
    @Resource
    private CommonGoodsService commonGoodsService;
    @Resource
    private QualityFactoryService qualityFactoryService;
    @Resource
    private UserCustomSettingsService userCustomSettingsService;
    @Resource
    private RedisManager redisManager;
    @Resource
    private SpecialService specialService;
    @Resource
    private JumpDetailV2Service jumpDetailV2Service;
    @Resource
    private PushGoodsService pushGoodsService;
    @Resource
    private DeviceActiveService deviceActiveService;
    @Resource
    private MsgConfigService msgConfigService;
    @Resource
    private MsgDeviceReadStateService msgDeviceReadStateService;
    @Resource
    private UserInfoExtraService userInfoExtraService;
    @Resource
    private ConfigService configService;
    // 消息的类型
    final static String MSG_TYPE_ORDER = "order";
    final static String MSG_TYPE_MONEY = "money";
    final static String MSG_TYPE_ACCOUNT = "account";
    final static String MSG_TYPE_INVITE = "invite";
    final static String MSG_TYPE_OTHER = "other";
    /**
     * 获取消息列表
     *
     * @param acceptData
     * @param uid
     * @param page
     * @param type
     * @param out
     */
    @RequestMapping(value = "getMsgList", method = RequestMethod.POST)
    public void getMsgList(AcceptData acceptData, Long uid, int page, String type, PrintWriter out) {
        if (uid == null) {
            out.print(JsonUtil.loadFalseResult(1, "用户未登录"));
            return;
        }
        if (StringUtil.isNullOrEmpty(type)) {
            out.print(JsonUtil.loadFalseResult(2, "请上传type"));
            return;
        }
        List<UserMsgVO> list = new ArrayList<>();
        long count = 0;
        switch (type) {
            case MSG_TYPE_ORDER:
                userMsgReadStateService.readOrderMsg(uid);
                List<MsgOrderDetail> detailList = msgOrderDetailService.listMsgOrderDetail(uid, page);
                count = msgOrderDetailService.countMsgOrderDetail(uid);
                if (detailList != null)
                    for (MsgOrderDetail detail : detailList) {
                        JSONObject params = new JSONObject();
                        params.put("orderNo", detail.getOrderId());
                        if (detail.getType() == MsgTypeOrderTypeEnum.invite || detail.getType() == MsgTypeOrderTypeEnum.orderInvite)
                            params.put("orderHideNo", UserUtil.filterOrderId(detail.getOrderId()));
                        UserMsgVO msgVO = UserMsgVOFactory.create(detail, jumpDetailV2Service.getByTypeCache("order_search",acceptData.getSystem()), params);
                        msgVO.setType(MSG_TYPE_ORDER);
                        list.add(msgVO);
                    }
                break;
            case MSG_TYPE_MONEY:
                userMsgReadStateService.readMoneyMsg(uid);
                List<MsgMoneyDetail> detailList1 = msgMoneyDetailService.listMsgMoneyDetail(uid, page);
                count = msgMoneyDetailService.countMsgMoneyDetail(uid);
                if (detailList1 != null)
                    for (MsgMoneyDetail detail : detailList1) {
                        UserMsgVO msgVO = UserMsgVOFactory.create(detail);
                        msgVO.setType(MSG_TYPE_MONEY);
                        list.add(msgVO);
                    }
                break;
            case MSG_TYPE_ACCOUNT:
                userMsgReadStateService.readAccountMsg(uid);
                List<MsgAccountDetail> detailList2 = msgAccountDetailService.listMsgAccountDetail(uid, page);
                count = msgAccountDetailService.countMsgAccountDetail(uid);
                if (detailList2 != null)
                    for (MsgAccountDetail detail : detailList2) {
                        UserMsgVO msgVO = UserMsgVOFactory.create(detail);
                        msgVO.setType(MSG_TYPE_ACCOUNT);
                        list.add(msgVO);
                    }
                break;
            case MSG_TYPE_INVITE:
                userMsgReadStateService.readInviteMsg(uid);
                List<MsgInviteDetail> detailList3 = msgInviteDetailService.listMsgInviteDetail(uid, page);
                count = msgInviteDetailService.countMsgInviteDetail(uid);
                if (detailList3 != null)
                    for (MsgInviteDetail detail : detailList3) {
                        UserMsgVO vo = UserMsgVOFactory.create(detail);
                        if (vo != null) {
                            vo.setType(MSG_TYPE_INVITE);
                            list.add(vo);
                        } else {
                            count--;
                        }
                    }
                break;
            case MSG_TYPE_OTHER:
                userMsgReadStateService.readOtherMsg(uid);
                List<MsgOtherDetail> detailList4 = msgOtherDetailService.listMsgOtherDetail(uid, page);
                count = msgOtherDetailService.countMsgOtherDetail(uid);
                if (detailList4 != null)
                    for (MsgOtherDetail detail : detailList4) {
                        UserMsgVO vo = UserMsgVOFactory.create(detail);
                        if (vo != null) {
                            vo.setType(MSG_TYPE_OTHER);
                            list.add(vo);
                        } else {
                            count--;
                        }
                    }
                break;
        }
        GsonBuilder builder = new GsonBuilder();
        builder = getTimeDescJsonBuilder(builder);
        JSONObject root = new JSONObject();
        root.put("data", builder.create().toJson(list));
        root.put("count", count);
        out.print(JsonUtil.loadTrueResult(root));
    }
    /**
     * 获取消息未读数
     *
     * @param acceptData
     * @param uid
     * @param out
     */
    @RequestSerializableByKey(key = "#acceptData.device")
    @RequestMapping(value = "getUnReadMsgCount", method = RequestMethod.POST)
    public void getUnReadMsgCount(AcceptData acceptData, Long uid, PrintWriter out) {
        GsonBuilder androidBuilder = new GsonBuilder().registerTypeAdapter(Integer.class,
                new JsonSerializer<Integer>() {
                    @Override
                    public JsonElement serialize(Integer value, Type theType, JsonSerializationContext context) {
                        if (value == null) {
                            return new JsonPrimitive("0");
                        } else {
                            if (value >= 100)
                                return new JsonPrimitive("99+");
                            else
                                return new JsonPrimitive(value);
                        }
                    }
                });
        if (uid == null) {
            // 如果用户未登录就读取设备消息
            UserMsgUnReadNum num = new UserMsgUnReadNum();
            num.setTypeAccount(0);
            num.setTypeInvite(0);
            num.setTypeMoney(0);
            num.setTypeOrder(0);
            num.setTypeOther(0);
            num.setTypeScore(0);
            num.setTypeSystem(0);
            JSONObject data = null;
            if ("android".equalsIgnoreCase(acceptData.getPlatform())) {
                data = JSONObject
                        .fromObject(androidBuilder.excludeFieldsWithoutExposeAnnotation().create().toJson(num));
            } else {
                data = JSONObject.fromObject(JsonUtil.getApiCommonGson().toJson(num));
            }
            data.put("totalCount", 0);
            try {
                UserSettingsVO vo = userCustomSettingsService.getMySettings(uid);
                if (vo != null && vo.getNoNewsRedDot() != null && vo.getNoNewsRedDot() == 1) {
                    data.put("totalCount", 0);
                }
            } catch (UserCustomSettingsException e) {
            }
            if (VersionUtil.greaterThan_1_5_50(acceptData.getPlatform(), acceptData.getVersion())) {
                int totalCount = msgDeviceReadStateService.getUnReadCount(acceptData.getDevice(),
                        "android".equalsIgnoreCase(acceptData.getPlatform()) ? 1 : 2, MsgDeviceReadState.TYPE_KEFU);
                data.put("totalCount", totalCount);
            }
            data.put("mineCount", 0);
            out.print(JsonUtil.loadTrueResult(data));
            return;
        }
        UserMsgUnReadNum num = userMsgReadStateService.getReadStateByUid(uid);
        int totalCount = num.getTypeAccount() + num.getTypeInvite() + num.getTypeMoney() + num.getTypeOrder()
                + num.getTypeScore() + num.getTypeSystem() + num.getTypeOther();
        // 1.5.50及以后的版本需要添加设备未读消息
        if (VersionUtil.greaterThan_1_5_50(acceptData.getPlatform(), acceptData.getVersion())) {
            totalCount += msgDeviceReadStateService.getUnReadCount(acceptData.getDevice(),
                    "android".equalsIgnoreCase(acceptData.getPlatform()) ? 1 : 2, MsgDeviceReadState.TYPE_KEFU);
        }
        JSONObject data = null;
        if ("android".equalsIgnoreCase(acceptData.getPlatform())) {
            data = JSONObject.fromObject(androidBuilder.excludeFieldsWithoutExposeAnnotation().create().toJson(num));
        } else {
            data = JSONObject.fromObject(JsonUtil.getApiCommonGson().toJson(num));
        }
        data.put("totalCount", totalCount);
        // "我的"选项角标
        int welfareCenterNews = 0;
        if (uid != null) {
            UserInfoExtra userInfoExtra = userInfoExtraService.getUserInfoExtra(uid);
            if (userInfoExtra != null) {
                if (userInfoExtra.getCouponNews() != null) {
                    welfareCenterNews = userInfoExtra.getCouponNews();
                }
            }
        }
        data.put("mineCount", welfareCenterNews);
        try {
            UserSettingsVO vo = userCustomSettingsService.getMySettings(uid);
            if (vo != null && vo.getNoNewsRedDot() != null && vo.getNoNewsRedDot() == 1) {
                data.put("totalCount", 0);
            }
        } catch (UserCustomSettingsException e) {
            e.printStackTrace();
        }
        out.print(JsonUtil.loadTrueResult(data));
    }
    private String getTimeDesc(Date nowDate, Date targetDate) {
        Calendar now = Calendar.getInstance();
        now.setTime(nowDate);
        if (TimeUtil.getGernalTime(targetDate.getTime(), "yyyy-MM-dd")
                .equalsIgnoreCase(TimeUtil.getGernalTime(now.getTimeInMillis(), "yyyy-MM-dd"))) {
            return "今天 " + TimeUtil.getGernalTime(targetDate.getTime(), "HH:mm");
        } else if (TimeUtil.getGernalTime(targetDate.getTime(), "yyyy-MM-dd")
                .equalsIgnoreCase(TimeUtil.getGernalTime(now.getTimeInMillis() - 1000 * 60 * 60 * 24L, "yyyy-MM-dd"))) {
            return "昨天 " + TimeUtil.getGernalTime(targetDate.getTime(), "HH:mm");
        } else {
            return TimeUtil.getGernalTime(targetDate.getTime(), "yyyy.MM.dd HH:mm");
        }
    }
    private GsonBuilder getTimeDescJsonBuilder(GsonBuilder builder) {
        builder = builder.registerTypeAdapter(Date.class, new JsonSerializer<Date>() {
            @Override
            public JsonElement serialize(Date value, Type theType, JsonSerializationContext context) {
                if (value == null) {
                    return new JsonPrimitive("");
                } else {
                    Calendar now = Calendar.getInstance();
                    return new JsonPrimitive(getTimeDesc(new Date(now.getTimeInMillis()), value));
                }
            }
        }).registerTypeAdapter(BigDecimal.class, new JsonSerializer<BigDecimal>() {
            @Override
            public JsonElement serialize(BigDecimal value, Type theType, JsonSerializationContext context) {
                if (value == null) {
                    return new JsonPrimitive("0");
                } else {
                    return new JsonPrimitive(BigDecimalUtil.getWithNoZera(value).toString());
                }
            }
        });
        return builder;
    }
    private void addRecommendGoods(Long uid, String device, String imei, String idfa) {
        TaoBaoSearchResult result = TaoKeApiUtil.guessDeviceLike(1, 50, imei, idfa, "");
        if (result != null && result.getTaoBaoGoodsBriefs() != null) {
            for (int i = 0; i < result.getTaoBaoGoodsBriefs().size(); i++) {
                if (result.getTaoBaoGoodsBriefs().get(i).getCouponAmount() == null
                        || result.getTaoBaoGoodsBriefs().get(i).getCouponAmount().compareTo(new BigDecimal(0)) <= 0) {
                    result.getTaoBaoGoodsBriefs().remove(i);
                    i--;
                }
            }
            // 随机几个
            int count = (int) (Math.random() * 3) + 1;
            Set<Integer> positionList = new HashSet<>();
            for (int i = 0; i < count; i++)
                if (result.getTaoBaoGoodsBriefs().size() > 0) {
                    positionList.add((int) (result.getTaoBaoGoodsBriefs().size() * Math.random()));
                }
            if (positionList != null && positionList.size() > 0) {
                List<CommonGoods> goodsList = new ArrayList<>();
                for (Integer p : positionList) {
                    TaoBaoGoodsBrief goodsB = result.getTaoBaoGoodsBriefs().get(p);
                    try {
                        CommonGoods cgoods = commonGoodsService
                                .addOrUpdateCommonGoods(CommonGoodsFactory.create(goodsB));
                        goodsList.add(cgoods);
                    } catch (CommonGoodsException e) {
                        e.printStackTrace();
                    }
                }
                try {
                    recommendUserGoodsService.addRecommend(uid, device, "", goodsList);
                } catch (RecommendUserGoodsException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    private void addRecommendGoods(Long uid, String device) {
        List<QualityFactory> qfList = qualityFactoryService.listByMinSalesCountOrderByCreateTimeDesc(10000, 1, 20);
        if (qfList != null && qfList != null) {
            for (int i = 0; i < qfList.size(); i++) {
                if (qfList.get(i).getTaoBaoGoodsBrief().getCouponAmount() == null
                        || qfList.get(i).getTaoBaoGoodsBrief().getCouponAmount().compareTo(new BigDecimal(0)) <= 0) {
                    qfList.remove(i);
                    i--;
                }
            }
            // 随机几个
            int count = (int) (Math.random() * 3) + 1;
            Set<Integer> positionList = new HashSet<>();
            for (int i = 0; i < count; i++)
                if (qfList.size() > 0) {
                    positionList.add((int) (qfList.size() * Math.random()));
                }
            if (positionList != null && positionList.size() > 0) {
                List<CommonGoods> goodsList = new ArrayList<>();
                for (Integer p : positionList) {
                    TaoBaoGoodsBrief goodsB = qfList.get(p).getTaoBaoGoodsBrief();
                    try {
                        CommonGoods cgoods = commonGoodsService
                                .addOrUpdateCommonGoods(CommonGoodsFactory.create(goodsB));
                        goodsList.add(cgoods);
                    } catch (CommonGoodsException e) {
                        e.printStackTrace();
                    }
                }
                try {
                    recommendUserGoodsService.addRecommend(uid, device, "", goodsList);
                } catch (RecommendUserGoodsException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /**
     * 获取首页消息
     *
     * @param acceptData
     * @param uid
     * @param page
     * @param out
     */
    @RequestMapping(value = "getHomeMsgList", method = RequestMethod.POST)
    public void getHomeMsgList(AcceptData acceptData, Long uid, int page, HttpSession session, PrintWriter out) {
        if (uid != null && uid == 0)
            uid = null;
        if (uid != null)
            userSystemMsgService.syncSystemZNX(uid);
        String device = acceptData.getDevice();
        if (device == null || device.trim().length() == 0) {
            out.print(JsonUtil.loadFalseResult("设备号不能为空"));
            return;
        }
        if (page == 1) {
            if (uid != null)
                recommendUserGoodsService.syncDeviceAndUid(uid, acceptData.getDevice());
            boolean canAdd = false;
            int hour = Calendar.getInstance().get(Calendar.HOUR);
            RecommendUserGoods goods = recommendUserGoodsService.getLatestRecommendUserGoodsByDevice(device);
            if (goods == null) {
                canAdd = true;
            } else {
                // 是否和上次间隔时间足够
                if (System.currentTimeMillis() - goods.getCreateTime().getTime() >= 1000 * 60 * 60 * 4L) {
                    canAdd = true;
                }
            }
            // String key = "recommend-goods-user-" + uid;
            String key = RedisKeyEnum.getRedisKey(RedisKeyEnum.recommendGoodsUser, device);
            if (Constant.IS_OUTNET) {
                if (canAdd && StringUtil.isNullOrEmpty(redisManager.getCommonString(key))) {
                    if (Constant.IS_OUTNET)
                        redisManager.cacheCommonString(key, "1", 20);
                    if (hour < 12)
                        addRecommendGoods(uid, device);
                    else
                        addRecommendGoods(uid, device, acceptData.getImei(), acceptData.getIdfa());
                    session.removeAttribute("recommendgoods");
                }
            } else {
                if (canAdd) {
                    if (hour < 12)
                        addRecommendGoods(uid, device);
                    else
                        addRecommendGoods(uid, device, acceptData.getImei(), acceptData.getIdfa());
                }
            }
        }
        List<UserHomeMsgVO> volist = new ArrayList<>();
        List<RecommendUserGoods> list = recommendUserGoodsService.listRecommendGoodsByDevice(device, page,
                Constant.PAGE_SIZE);
        long count = recommendUserGoodsService.countRecommendGoodsByDevice(device);
        Date now = new Date();
        for (RecommendUserGoods goods : list) {
            UserHomeMsgVO vo = new UserHomeMsgVO();
            vo.setContent(goods.getRecommendDesc());
            vo.setCreateTime(getTimeDesc(now, goods.getCreateTime()));
            if (goods.getGoodsList().size() == 1)
                vo.setType(UserHomeMsgVO.TYPE_GOODS_1);
            else if (goods.getGoodsList().size() == 2)
                vo.setType(UserHomeMsgVO.TYPE_GOODS_2);
            else if (goods.getGoodsList().size() == 3)
                vo.setType(UserHomeMsgVO.TYPE_GOODS_3);
            List<TaoBaoGoodsBrief> goodsList = new ArrayList<>();
            for (CommonGoods cg : goods.getGoodsList()) {
                if (goods.getGoodsList().size() == 1)
                    cg.setPicture(TbImgUtil.getTBSizeImg(
                            StringUtil.isNullOrEmpty(cg.getPictureWhite()) ? cg.getPicture() : cg.getPictureWhite(),
                            400));
                else if (goods.getGoodsList().size() == 2)
                    cg.setPicture(TbImgUtil.getTBSizeImg(
                            StringUtil.isNullOrEmpty(cg.getPictureWhite()) ? cg.getPicture() : cg.getPictureWhite(),
                            320));
                else if (goods.getGoodsList().size() == 3)
                    cg.setPicture(TbImgUtil.getTBSizeImg(
                            StringUtil.isNullOrEmpty(cg.getPictureWhite()) ? cg.getPicture() : cg.getPictureWhite(),
                            220));
                TaoBaoGoodsBrief tbGoods = new TaoBaoGoodsBrief();
                if (cg.getCouponAmount() == null)
                    tbGoods.setCouponAmount(new BigDecimal(0));
                else
                    tbGoods.setCouponAmount(cg.getCouponAmount());
                tbGoods.setAuctionId(cg.getGoodsId());
                tbGoods.setPictUrl(cg.getPicture());
                goodsList.add(tbGoods);
            }
            vo.setGoodsList(goodsList);
            vo.setTitle("猜你喜欢");
            vo.setIcon("http://img.flqapp.com/resource/msg/icon_msg_guess_like.png");
            volist.add(vo);
        }
        Long time = (uid == null ? System.currentTimeMillis() : userInfoService.selectByPKey(uid).getCreatetime());
        if (volist.size() > 0 && volist.size() < Constant.PAGE_SIZE) {
            // 添加欢迎语
            // 创建时间在28号后的才有新人欢迎
            if ((time > TimeUtil.convertToTimeTemp("2019-01-28", "yyyy-MM-dd") || uid == null)) {
                UserHomeMsgVO vo = new UserHomeMsgVO();
                vo.setContent(configService.getValue(ConfigKeyEnum.welcomeMsg, acceptData.getSystem()));
                if (acceptData.getSystem() == SystemEnum.blks)
                    vo.setTitle("新人欢迎");
                else
                    vo.setTitle("欢迎新人");
                vo.setCreateTime(getTimeDesc(now, new Date(time)));
                vo.setType(UserHomeMsgVO.TYPE_WELCOME);
                volist.add(vo);
                count++;
            }
        }
        JSONObject root = new JSONObject();
        root.put("msgList", new Gson().toJson(volist));
        if (page == 1 && uid != null) {
            UserMsgUnReadNum num = userMsgReadStateService.getReadStateByUid(uid);
            UserSystemMsg usm = userSystemMsgService.getLatestUserSystemMsg(uid);
            if (usm != null)
                root.put("systemMsg",
                        new UserSystemMsgVO(usm.getId(), usm.getType().name(), usm.getSolved(), "系统消息", usm.getTitle(),
                                usm.getTimeTag() == 1 ? "http://img.flqapp.com/resource/msg/icon_emergent.png" : "",
                                "http://img.flqapp.com/resource/msg/icon_msg_system.png",
                                getTimeDesc(now, usm.getCreateTime()), num.getTypeSystem()));
        }
        root.put("count", count);
        out.print(JsonUtil.loadTrueResult(root));
    }
    private UserCommonMsgVO getKeFuMsg(AcceptData acceptData) {
        MsgDeviceReadState kefuState = msgDeviceReadStateService.getByDeviceAndPlatformAndType(
                UserCommonMsgVO.TYPE_KEFU, acceptData.getDevice(),
                acceptData.getPlatform().equalsIgnoreCase("android") ? 1 : 2);
        // 人工客服
        UserCommonMsgVO vo = new UserCommonMsgVO("http://img.flqapp.com/resource/msg/icon_kefu.png", "人工客服", new Date(),
                UserCommonMsgVO.TYPE_KEFU, "", false, null, null, 0);
        if (kefuState != null) {
            vo.setUnReadCount(kefuState.getUnReadCount() == null ? 0 : kefuState.getUnReadCount());
            if (!StringUtil.isNullOrEmpty(kefuState.getLatestContent()))
                vo.setLatestMsg(kefuState.getLatestContent());
            if (vo.getUnReadCount() != null && vo.getUnReadCount() > 0)
                vo.setRead(false);
            else
                vo.setRead(true);
            if (kefuState.getLatestContentTime() != null)
                vo.setTime(kefuState.getLatestContentTime());
        } else
            vo.setRead(true);
        if (StringUtil.isNullOrEmpty(vo.getLatestMsg()))
            vo.setLatestMsg("[点击打开人工客服]");
        return vo;
    }
    /**
     * 获取消息列表
     *
     * @param acceptData
     * @param uid
     * @param out
     */
    @RequestSerializableByKey(key = "#acceptData.device")
    @RequestMapping(value = "getHomeMsgListNew", method = RequestMethod.POST)
    public void getHomeMsgListNew(AcceptData acceptData, Long uid, PrintWriter out) {
        if (uid != null && uid == 0)
            uid = null;
        if (uid != null) {
            userSystemMsgService.syncSystemZNX(uid);
        }
        List<UserMsgCenter> listCenter = new ArrayList<>();
        // 单条消息
        List<UserCommonMsgVO> commonMsgList = new ArrayList<>();
        long currentTime = System.currentTimeMillis();
        // 官宣任务
        if (uid != null) {
            MsgCommonDTO guanXuanMsg = msgConfigService.getGuanXuanMsg(acceptData.getSystem());
            if (guanXuanMsg != null && guanXuanMsg.getShow() == true) {
                boolean read = false;
                UserMsgUnReadNum num = userMsgReadStateService.getReadStateByUid(uid);
                if (num != null && (num.getGuanXuanReadTime() != null
                        && guanXuanMsg.getUpdateTime().getTime() < num.getGuanXuanReadTime().getTime()))
                    read = true;
                // 查询是否已读
                if ((guanXuanMsg.getStartTime() != null && currentTime < guanXuanMsg.getStartTime().getTime())
                        || (guanXuanMsg.getEndTime() != null && currentTime > guanXuanMsg.getEndTime().getTime())) {
                    // 不显示
                } else
                    commonMsgList.add(new UserCommonMsgVO(guanXuanMsg.getIcon(), guanXuanMsg.getTitle(),
                            guanXuanMsg.getUpdateTime(), UserCommonMsgVO.TYPE_GUANXUAN, guanXuanMsg.getContent(), read,
                            guanXuanMsg.getJumpDetail(), guanXuanMsg.getParams(), 0));
            }
        }
        // 板栗快省小助手
        MsgCommonDTO zhuShouMsg = msgConfigService.getZhuShouMsg(acceptData.getSystem());
        if (zhuShouMsg != null && zhuShouMsg.getShow() == true) {
            boolean read = false;
            MsgDeviceReadState state = msgDeviceReadStateService.getByDeviceAndPlatformAndType(
                    UserCommonMsgVO.TYPE_ZHUSHOU, acceptData.getDevice(),
                    acceptData.getPlatform().equalsIgnoreCase("android") ? 1 : 2);
            if (state != null && state.getReadTime() != null
                    && zhuShouMsg.getUpdateTime().getTime() < state.getReadTime().getTime())
                read = true;
            // 查询是否已读
            if ((zhuShouMsg.getStartTime() != null && currentTime < zhuShouMsg.getStartTime().getTime())
                    || (zhuShouMsg.getEndTime() != null && currentTime > zhuShouMsg.getEndTime().getTime())) {
                // 不显示
            } else
                commonMsgList.add(new UserCommonMsgVO(zhuShouMsg.getIcon(), zhuShouMsg.getTitle(),
                        zhuShouMsg.getUpdateTime(), UserCommonMsgVO.TYPE_ZHUSHOU, zhuShouMsg.getContent(), read,
                        zhuShouMsg.getJumpDetail(), zhuShouMsg.getParams(), 0));
        }
        // 人工客服
        if (acceptData.getSystem() == SystemEnum.blks)
            commonMsgList.add(getKeFuMsg(acceptData));
        // 推荐记录
        DeviceActive deviceActive = deviceActiveService.getDeviceByDeviceAndPlatform(acceptData.getDevice(),
                acceptData.getDevice(), acceptData.getPlatform());
        if (deviceActive != null) {
            // 设备注册时间
            Date createTime = deviceActive.getCreateTime();
            List<PushGoods> list = pushGoodsService.listHistoryByPushTime(0, 1, uid, createTime, acceptData.getSystem());
            if (list != null && list.size() > 0) {
                MsgDeviceReadState state = msgDeviceReadStateService.getByDeviceAndPlatformAndType(
                        UserCommonMsgVO.TYPE_RECOMMEND, acceptData.getDevice(),
                        acceptData.getPlatform().equalsIgnoreCase("android") ? 1 : 2);
                boolean read = false;
                if (state != null && state.getReadTime() != null
                        && list.get(0).getPushTime().getTime() < state.getReadTime().getTime())
                    read = true;
                commonMsgList.add(new UserCommonMsgVO("http://img.flqapp.com/resource/msg/icon_recommend.png", "推荐记录",
                        list.get(0).getPushTime(), UserCommonMsgVO.TYPE_RECOMMEND, list.get(0).getContent(), read,
                        jumpDetailV2Service.getByTypeCache("recommend_list",acceptData.getSystem()), null, 0));
            }
        }
        //
        // list = pushGoodsService.listHistoryByPushTime(0, 1, uid, createTime);
        // 1、活动区域
        int platformCode = Constant.getPlatformCode(acceptData.getPlatform());
        List<Special> listSpecial = specialService.listByPlaceKey("msg_activities", platformCode,
                Integer.parseInt(acceptData.getVersion()), acceptData.getSystem());
        if (listSpecial != null && listSpecial.size() > 0) {
            for (Special special : listSpecial) {
                boolean needLogin = special.isJumpLogin();
                JumpDetailV2 jumpDetail = special.getJumpDetail();
                if (jumpDetail != null) {
                    jumpDetail.setNeedLogin(needLogin);
                    special.setJumpDetail(jumpDetail);
                }
                UserMsgCenter msgCenter = new UserMsgCenter();
                msgCenter.setSpecial(special);
                listCenter.add(msgCenter);
            }
        }
        // 2、消息区域
        if (uid != null && uid > 0) {
            int page = 1;
            List<UserMsgVO> list = new ArrayList<>();
            List<MsgOrderDetail> detailList = msgOrderDetailService.listMsgOrderDetail(uid, page);
            if (detailList != null && detailList.size() > 0) {
                for (MsgOrderDetail detail : detailList) {
                    JSONObject params = new JSONObject();
                    params.put("orderNo", detail.getOrderId());
                    if (detail.getType() == MsgTypeOrderTypeEnum.invite || detail.getType() == MsgTypeOrderTypeEnum.orderInvite)
                        params.put("orderHideNo", UserUtil.filterOrderId(detail.getOrderId()));
                    UserMsgVO userMsgVO = UserMsgVOFactory.create(detail,
                            jumpDetailV2Service.getByTypeCache("order_search",acceptData.getSystem()), params);
                    userMsgVO.setType(MSG_TYPE_ORDER);
                    list.add(userMsgVO);
                }
            }
            List<MsgMoneyDetail> detailList1 = msgMoneyDetailService.listMsgMoneyDetail(uid, page);
            if (detailList1 != null && detailList1.size() > 0) {
                for (MsgMoneyDetail detail : detailList1) {
                    UserMsgVO userMsgVO = UserMsgVOFactory.create(detail);
                    userMsgVO.setType(MSG_TYPE_MONEY);
                    list.add(userMsgVO);
                }
            }
            List<MsgAccountDetail> detailList2 = msgAccountDetailService.listMsgAccountDetail(uid, page);
            if (detailList2 != null && detailList2.size() > 0) {
                for (MsgAccountDetail detail : detailList2) {
                    UserMsgVO userMsgVO = UserMsgVOFactory.create(detail);
                    userMsgVO.setType(MSG_TYPE_ACCOUNT);
                    list.add(userMsgVO);
                }
            }
            List<MsgInviteDetail> detailList3 = msgInviteDetailService.listMsgInviteDetail(uid, page);
            if (detailList3 != null && detailList3.size() > 0) {
                for (MsgInviteDetail detail : detailList3) {
                    UserMsgVO userMsgVO = UserMsgVOFactory.create(detail);
                    if (userMsgVO != null) {
                        userMsgVO.setType(MSG_TYPE_INVITE);
                        list.add(userMsgVO);
                    }
                }
            }
            List<MsgOtherDetail> detailList4 = msgOtherDetailService.listMsgOtherDetail(uid, page);
            if (detailList4 != null && detailList4.size() > 0) {
                for (MsgOtherDetail detail : detailList4) {
                    UserMsgVO userMsgVO = UserMsgVOFactory.create(detail);
                    if (userMsgVO != null) {
                        userMsgVO.setType(MSG_TYPE_OTHER);
                        list.add(userMsgVO);
                    }
                }
            }
            if (list.size() > 0) {
                // 时间排序
                listSort(list);
                if (list.size() >= 20) {
                    list = list.subList(0, 19);
                }
                for (UserMsgVO userMsgVO : list) {
                    UserMsgCenter userMsgCenter = new UserMsgCenter();
                    userMsgCenter.setUserMsg(userMsgVO);
                    listCenter.add(userMsgCenter);
                }
            }
        }
        // 3、添加欢迎语
        Long time = (uid == null ? System.currentTimeMillis() : userInfoService.selectByPKey(uid).getCreatetime());
        // 创建时间在28号后的才有新人欢迎
        if ((time > TimeUtil.convertToTimeTemp("2019-01-28", "yyyy-MM-dd") || uid == null)) {
            Map<String, Object> map = new HashMap<String, Object>();
            if (acceptData.getSystem() == SystemEnum.blks)
                map.put("title", "新人欢迎");
            else
                map.put("title", "欢迎新人");
            map.put("content",
                    configService.getValue(ConfigKeyEnum.welcomeMsg, acceptData.getSystem()));
            map.put("createTime", new Date(time));
            UserMsgCenter msgCenternre = new UserMsgCenter();
            msgCenternre.setWelcomeMsg(map);
            listCenter.add(msgCenternre);
        }
        GsonBuilder builder = new GsonBuilder();
        builder = getTimeDescJsonBuilder(builder);
        JSONObject root = new JSONObject();
        if (uid != null && uid > 0) {
            UserMsgUnReadNum num = userMsgReadStateService.getReadStateByUid(uid);
            UserSystemMsg usm = userSystemMsgService.getLatestUserSystemMsg(uid);
            if (usm != null) {
                // commonMsgList.add(0,new UserCommonMsgVO(icon, "系统消息", time,
                // type, latestMsg, ,
                // jumpDetailV2Service.getByTypeCache("system_msg"), params));
                root.put("systemMsg",
                        new UserSystemMsgVO(usm.getId(), usm.getType().name(), usm.getSolved(), "系统消息", usm.getTitle(),
                                usm.getTimeTag() == 1 ? "http://img.flqapp.com/resource/msg/icon_emergent.png" : "",
                                "http://img.flqapp.com/resource/msg/icon_msg_system.png",
                                getTimeDesc(new Date(), usm.getCreateTime()), num.getTypeSystem()));
            }
        }
        /**
         * 提醒大图
         */
        if (!"douyin".equalsIgnoreCase(acceptData.getChannel())) {
            MsgCommonDTO notify = msgConfigService.getNotifyMsg(acceptData.getSystem());
            if (notify != null && notify.getShow() == true) {
                boolean read = false;
                MsgDeviceReadState state = msgDeviceReadStateService.getByDeviceAndPlatformAndType(
                        UserCommonMsgVO.TYPE_NOTIFY, acceptData.getDevice(),
                        acceptData.getPlatform().equalsIgnoreCase("android") ? 1 : 2);
                if (state != null && state.getReadTime() != null
                        && zhuShouMsg.getUpdateTime().getTime() < state.getReadTime().getTime())
                    read = true;
                if (notify.getJumpDetail() == null)
                    read = true;
                // 查询是否已读
                UserCommonMsgVO vo = new UserCommonMsgVO(notify.getIcon(), notify.getTitle(), notify.getUpdateTime(),
                        UserCommonMsgVO.TYPE_NOTIFY, notify.getContent(), read, notify.getJumpDetail(),
                        notify.getParams(), 0);
                vo.setPicture(notify.getPicture());
                root.put("notifyMsg", builder.create().toJson(vo));
            }
        }
        root.put("list", builder.create().toJson(listCenter));
        root.put("commonList", builder.create().toJson(commonMsgList));
        root.put("count", listCenter.size());
        out.print(JsonUtil.loadTrueResult(root));
    }
    public static void listSort(List<UserMsgVO> list) {
        Collections.sort(list, new Comparator<UserMsgVO>() {
            @Override
            public int compare(UserMsgVO o1, UserMsgVO o2) {
                if (o1.getTime().getTime() > o2.getTime().getTime()) {
                    return -1;
                } else if (o1 == o2) {
                    return 0;
                } else {
                    return 1;
                }
            }
        });
    }
    /**
     * 获取系统消息列表
     *
     * @param acceptData
     * @param uid
     * @param page
     * @param out
     */
    @RequestMapping(value = "getSystemMsgList", method = RequestMethod.POST)
    public void getSystemMsgList(AcceptData acceptData, Long uid, int page, PrintWriter out) {
        if (uid == null) {
            out.print(JsonUtil.loadFalseResult(1, "用户未登录"));
            return;
        }
        List<UserSystemMsgVO> voList = new ArrayList<>();
        List<UserSystemMsg> list = userSystemMsgService.listUserSystemMsg(uid, page, Constant.PAGE_SIZE);
        if (list != null)
            for (UserSystemMsg usm : list) {
                voList.add(new UserSystemMsgVO(usm.getId(), usm.getType().name(), usm.getSolved(), usm.getTitle(),
                        usm.getContent(),
                        usm.getTimeTag() == 1 ? "http://img.flqapp.com/resource/msg/icon_emergent.png" : "", null,
                        usm.getCreateTime().getTime() + "", 0));
            }
        long count = userSystemMsgService.countUserSystemMsg(uid);
        userMsgReadStateService.readUserSystemMsg(uid);
        JSONObject root = new JSONObject();
        root.put("data", voList);
        root.put("count", count);
        out.print(JsonUtil.loadTrueResult(root));
    }
    /**
     * 设置问题已经解决
     *
     * @param acceptData
     * @param uid
     * @param id
     * @param out
     */
    @RequestMapping(value = "setSystemMsgSolved", method = RequestMethod.POST)
    public void setSystemMsgSolved(AcceptData acceptData, Long uid, Long id, PrintWriter out) {
        if (uid == null) {
            out.print(JsonUtil.loadFalseResult(1, "用户未登录"));
            return;
        }
        if (id == null) {
            out.print(JsonUtil.loadFalseResult(2, "消息ID为空"));
            return;
        }
        try {
            userSystemMsgService.setSystemMsgSolved(uid, id);
            out.print(JsonUtil.loadTrueResult(""));
        } catch (UserSystemMsgException e) {
            out.print(JsonUtil.loadFalseResult(e.getCode(), e.getMsg()));
        }
    }
    @RequestMapping(value = "setAllMsgRead", method = RequestMethod.POST)
    public void setAllMsgRead(AcceptData acceptData, Long uid, PrintWriter out) {
        msgDeviceReadStateService.setAllMsgRead(acceptData.getDevice(),
                "android".equalsIgnoreCase(acceptData.getPlatform()) ? 1 : 2);
        if (uid == null) {
            out.print(JsonUtil.loadFalseResult(1, "用户未登录"));
            return;
        }
        // 初始化读取状态
        msgDeviceReadStateService.initReadState(acceptData.getDevice(),
                "android".equalsIgnoreCase(acceptData.getPlatform()) ? 1 : 2, UserCommonMsgVO.TYPE_RECOMMEND);
        msgDeviceReadStateService.initReadState(acceptData.getDevice(),
                "android".equalsIgnoreCase(acceptData.getPlatform()) ? 1 : 2, UserCommonMsgVO.TYPE_ZHUSHOU);
        // 设置设备消息所有已读
        msgDeviceReadStateService.setAllMsgRead(acceptData.getDevice(),
                "android".equalsIgnoreCase(acceptData.getPlatform()) ? 1 : 2);
        UserMsgUnReadNum num = userMsgReadStateService.getReadStateByUid(uid);
        int totalNum = num.getTypeAccount() + num.getTypeInvite() + num.getTypeMoney() + num.getTypeOrder()
                + num.getTypeScore() + num.getTypeSystem() + num.getTypeOther();
        if (totalNum == 0) {
            out.print(JsonUtil.loadFalseResult(1, "没有未读消息"));
            return;
        } else
            userMsgReadStateService.setAllMsgRead(uid);
        out.print(JsonUtil.loadTrueResult(""));
    }
    /**
     * 阅读通用消息
     *
     * @param acceptData
     * @param uid
     * @param out
     */
    @RequestMapping(value = "readCommonMsg", method = RequestMethod.POST)
    public void readCommonMsg(AcceptData acceptData, Long uid, String type, PrintWriter out) {
        if (StringUtil.isNullOrEmpty(type)) {
            out.print(JsonUtil.loadFalseResult(2, "请上传type"));
            return;
        }
        if (type.equalsIgnoreCase(UserCommonMsgVO.TYPE_GUANXUAN)) {
            if (uid != null) {
                UserMsgUnReadNum num = userMsgReadStateService.getReadStateByUid(uid);
                UserMsgUnReadNum update = new UserMsgUnReadNum();
                update.setId(num.getId());
                update.setGuanXuanReadTime(new Date());
                update.setUpdateTime(new Date());
                userMsgReadStateService.updateSelective(update);
            }
        } else if (type.equalsIgnoreCase(UserCommonMsgVO.TYPE_RECOMMEND)) {
            msgDeviceReadStateService.setDeviceMsgRead(UserCommonMsgVO.TYPE_RECOMMEND, acceptData.getDevice(),
                    (acceptData.getPlatform().equalsIgnoreCase("android") ? 1 : 2));
        } else if (type.equalsIgnoreCase(UserCommonMsgVO.TYPE_ZHUSHOU)) {
            msgDeviceReadStateService.setDeviceMsgRead(UserCommonMsgVO.TYPE_ZHUSHOU, acceptData.getDevice(),
                    (acceptData.getPlatform().equalsIgnoreCase("android") ? 1 : 2));
        }
        out.print(JsonUtil.loadTrueResult(""));
    }
    /**
     * 上传最近的客服消息
     *
     * @param acceptData
     * @param content
     * @param out
     */
    @RequestMapping(value = "uploadLatestKeFuMsg", method = RequestMethod.POST)
    public void uploadLatestKeFuMsg(AcceptData acceptData, String content, Long datetime, PrintWriter out) {
        if (StringUtil.isNullOrEmpty(content) || datetime == null) {
            out.print(JsonUtil.loadFalseResult("参数不完整"));
            return;
        }
        msgDeviceReadStateService.addUnreadDeviceMsg(MsgDeviceReadState.TYPE_KEFU, acceptData.getDevice(),
                "android".equalsIgnoreCase(acceptData.getPlatform()) ? 1 : 2, 0, content, new Date(datetime));
        out.print(JsonUtil.loadTrueResult(""));
    }
    /**
     * 删除消息
     *
     * @param acceptData
     * @param type
     * @param id
     * @param out
     */
    @RequestMapping(value = "deleteMsg", method = RequestMethod.POST)
    public void deleteMsg(AcceptData acceptData, String type, Long id, Long uid, PrintWriter out) {
        if (StringUtil.isNullOrEmpty(type) || id == null || uid == null) {
            out.print(JsonUtil.loadFalseResult("参数不完整"));
            return;
        }
        switch (type) {
            case MSG_TYPE_ORDER:
                MsgOrderDetail msgOrderDetail = msgOrderDetailService.selectByPrimaryKey(id);
                if (msgOrderDetail != null && msgOrderDetail.getUser().getId().longValue() == uid.longValue()) {
                    msgOrderDetailService.deleteByPrimaryKey(id);
                }
                break;
            case MSG_TYPE_MONEY:
                MsgMoneyDetail moneyDetail = msgMoneyDetailService.selectByPrimaryKey(id);
                if (moneyDetail != null && moneyDetail.getUser().getId().longValue() == uid.longValue()) {
                    msgMoneyDetailService.deleteByPrimaryKey(id);
                }
                break;
            case MSG_TYPE_ACCOUNT:
                MsgAccountDetail accountDetail = msgAccountDetailService.selectByPrimaryKey(id);
                if (accountDetail != null && accountDetail.getUser().getId().longValue() == uid.longValue()) {
                    msgAccountDetailService.deleteByPrimaryKey(id);
                }
                break;
            case MSG_TYPE_INVITE:
                MsgInviteDetail inviteDetail = msgInviteDetailService.selectByPrimaryKey(id);
                if (inviteDetail != null && inviteDetail.getUser().getId().longValue() == uid.longValue()) {
                    msgInviteDetailService.deleteByPrimaryKey(id);
                }
                break;
            case MSG_TYPE_OTHER:
                MsgOtherDetail otherDetail = msgOtherDetailService.selectByPrimaryKey(id);
                if (otherDetail != null && otherDetail.getUser().getId().longValue() == uid.longValue()) {
                    msgOtherDetailService.deleteByPrimaryKey(id);
                }
                break;
        }
        out.print(JsonUtil.loadTrueResult(""));
    }
}