package com.ssj.service.weixin.zuoyb.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ssj.bean.weixin.libmy.domain.LibVip;
import com.ssj.bean.weixin.zyb.domain.*;
import com.ssj.dao.kmt.kmt.dao.KmtQueryDao;
import com.ssj.dao.weixin.zuoyb.dao.ZuoybStudentBgDao;
import com.ssj.framework.basic.utils.DateHelper;
import com.ssj.framework.basic.utils.StringUtils;
import com.ssj.framework.core.common.service.BaseServiceImpl;
import com.ssj.framework.core.persistence.DynamicSpecifications;
import com.ssj.framework.core.persistence.SearchFilter;
import com.ssj.framework.core.security.manager.TokenManager;
import com.ssj.framework.core.util.PropertiesUtil;
import com.ssj.framework.core.util.SystemResourceLocator;
import com.ssj.framework.weixin.util.Collections3;
import com.ssj.service.conch.zyb.constant.SuggestTextUtil;
import com.ssj.service.conch.zyb.model.BgDetails;
import com.ssj.service.conch.zyb.model.BgDetailsFeature;
import com.ssj.service.conch.zyb.model.BgKnow;
import com.ssj.service.conch.zyb.model.Lat;
import com.ssj.service.weixin.library.service.ILibVipService;
import com.ssj.service.weixin.zuoyb.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/** 
 * @author  ZhangCaibao 
 * @version 2017年11月2日 上午11:10:39 
 * 类说明  作业吧报告
 */
@Service
@Transactional
public class ZuoybStudentBgServiceImpl extends BaseServiceImpl<ZuoybStudentBg, String> implements ZuoybStudentBgService {
	private   Logger logger = LoggerFactory.getLogger(this.getClass());
	@Autowired
	private ZuoybStudentBgDao  zuoybStudentBgDao;
	@Autowired
	private ZuoybStudentWorkHowService  zuoybStudentWorkHowService;
	@Autowired
	private ZuoybStudentWorkHowDetailsService  zuoybStudentWorkHowDetailsService;
	
	@Autowired
	private ZuoybStudentWorkService  zuoybStudentWorkService;
	@Autowired
	private ZuoybStudentBgDetailsService  zuoybStudentBgDetailsService;
	
	@Autowired
	private ILibVipService vipService;
	@Autowired
	private ZuoybKnowHowService zuoybKnowHowService;
	@Autowired
	private ZuoybKnowHowDetailsService zuoybKnowHowDetailsService;
	
	@Autowired
	private KmtQueryDao  kmtQueryDao;
	
    @Autowired
    private TokenManager tokenManager;
    

	
	@Override
	public PagingAndSortingRepository<ZuoybStudentBg, String> getDao() {
		return zuoybStudentBgDao;
	}
	@Override
	public Page<ZuoybStudentBg> findByPage(Map<String, Object> params,
			Pageable sp) {
		Map<String, SearchFilter> filters = SearchFilter.parse(params);
		Specification<ZuoybStudentBg> specification = DynamicSpecifications.bySearchFilter(filters.values(), ZuoybStudentBg.class);    
		return  zuoybStudentBgDao.findAll(specification, sp);
	}
	@Override
	public void saveWeeksBg() {
		/**
		 * 旧数据如何处理，
		 * 新的数据，周日执行定时器，
		 */
		Date endDate   =new  Date();
		Date startDate =DateHelper.getNextDay(endDate, -7);
		this.saveWeeksBg(startDate, endDate);
		
	}
	@Override
	public List<ZuoybStudentBgDetails> getBg(String vipId,Date startDate,Date endDate) {
		String start_date =DateHelper.getDate(startDate);
		String end_date =DateHelper.getDate(endDate);
		List<ZuoybStudentWorkHow> workHowList=	zuoybStudentWorkHowService.getStartAndEndWorkHow(vipId, start_date, end_date);
		List<ZuoybStudentBgDetails> detailsList =new ArrayList<ZuoybStudentBgDetails>();
		String [] course = new String[] {"语文","数学","英语"};
		LibVip  vip =vipService.getById(vipId);
		if("二年级".equals(vip.getGrade())||"学前".equals(vip.getGrade())||"一年级".equals(vip.getGrade())){
			course =new String[] {"语文","数学"};
		}
		for (int i = 0; i < course.length; i++) {
			ZuoybStudentBgDetails bg = new  ZuoybStudentBgDetails();
			bg.setStudentBgId("20171105"+i);
			bg.setCourseName(course[i]);
			//添加到set 去重 (已经选好的单元)
			Set<ZuoybStudentWorkHow> workHowSet = new HashSet<ZuoybStudentWorkHow>();
			//存放大纲对应的知识点  (知识点已去重)  
			Map<String,Set<ZuoybStudentWorkHowDetails>> mapDetails = new HashMap<String, Set<ZuoybStudentWorkHowDetails>>();
			//存放大纲对应的知识点图片
			Map<String,Set<ZuoybStudentWorkImg>> mapImg = new HashMap<String, Set<ZuoybStudentWorkImg>>();
			//Integer gouxuanSize=0;//本单元知识点作业，总共勾选多少次，不去重，
			//Integer countiSize=0;//本单元知识点作业，有多少上传图片，去重。
			//计算那个知识点出现的最多，就推荐该知识点。
			Map<ZuoybStudentWorkHowDetails,Integer> howDetailsMap = new HashMap<ZuoybStudentWorkHowDetails,Integer>();
			//计算该大纲下面有多少知识点。
			Map<String,Integer> gouxuanMap = new HashMap<String, Integer>();
			//计算该大纲下面有多少知识点是错题。
			Map<String,Integer> cuotiMap = new HashMap<String, Integer>();
			
			Map<String,Integer> maxMap = new HashMap<String, Integer>();
			
			for (ZuoybStudentWorkHow zuoybStudentWorkHow : workHowList) {
				if(course[i].equals(zuoybStudentWorkHow.getStudentWorkId())){
					ZuoybStudentWorkHow newWorkHow = new  ZuoybStudentWorkHow();
					newWorkHow.setHowId(zuoybStudentWorkHow.getHowId());
					newWorkHow.setHowName(zuoybStudentWorkHow.getHowName());
					newWorkHow.setNum(zuoybStudentWorkHow.getNum());
					workHowSet.add(newWorkHow);
					List<ZuoybStudentWorkHowDetails> workHowDetailsList  = zuoybStudentWorkHow.getWorkHowDetailsList();
					if(workHowDetailsList!=null && workHowDetailsList.size()>0){
						//计算该大纲下面有多少知识点。
						int values =0;
						if(gouxuanMap.containsKey(zuoybStudentWorkHow.getHowId())){
							values = gouxuanMap.get(zuoybStudentWorkHow.getHowId());
						}
						values =values+workHowDetailsList.size();
						gouxuanMap.put(zuoybStudentWorkHow.getHowId(), values);
						
						for (ZuoybStudentWorkHowDetails zuoybStudentWorkHowDetails : workHowDetailsList) {
							ZuoybStudentWorkHowDetails newWorkHowDetails  =new  ZuoybStudentWorkHowDetails();
							newWorkHowDetails.setHowDetailsId(zuoybStudentWorkHowDetails.getHowDetailsId());
							newWorkHowDetails.setName(zuoybStudentWorkHowDetails.getName());
							newWorkHowDetails.setNum(zuoybStudentWorkHowDetails.getNum());
							//暂存howid,下面取值用到
							newWorkHowDetails.setWorkHowId(zuoybStudentWorkHow.getHowId());
							
							Integer value =0;
							if(howDetailsMap.containsKey(newWorkHowDetails)){
								value =howDetailsMap.get(newWorkHowDetails);
							}
							value +=1;
							howDetailsMap.put(newWorkHowDetails, value);
							int max =0;
							if(maxMap.containsKey(zuoybStudentWorkHow.getHowId())){
								max =  maxMap.get(zuoybStudentWorkHow.getHowId());
							}
							 max = value > max ? value : max;
							 maxMap.put(zuoybStudentWorkHow.getHowId(), max);
							
							//计算该大纲下面有多少知识点。去重复。
								Set<ZuoybStudentWorkHowDetails> setHowDetails = new HashSet<ZuoybStudentWorkHowDetails>();
								if(mapDetails.containsKey(zuoybStudentWorkHow.getHowId())){
									setHowDetails = mapDetails.get(zuoybStudentWorkHow.getHowId());
								}
								setHowDetails.add(newWorkHowDetails);
								mapDetails.put(zuoybStudentWorkHow.getHowId(), setHowDetails);
								List<ZuoybStudentWorkImg>  imgList  = zuoybStudentWorkHowDetails.getImgList();
								//当有多个图片时，只取一个。
								if(imgList!=null && imgList.size()>0){
									int cuotiValus =0;
									if(cuotiMap.containsKey(zuoybStudentWorkHow.getHowId())){
										cuotiValus = cuotiMap.get(zuoybStudentWorkHow.getHowId());
									}
									cuotiValus =cuotiValus+workHowDetailsList.size();
									cuotiMap.put(zuoybStudentWorkHow.getHowId(), cuotiValus);
									
									Set<ZuoybStudentWorkImg> imgset = new HashSet<ZuoybStudentWorkImg>();
									if(mapImg.containsKey(zuoybStudentWorkHowDetails.getHowDetailsId())){
										imgset =mapImg.get(zuoybStudentWorkHowDetails.getHowDetailsId());
									}
									 imgset.addAll(imgList);
									mapImg.put(zuoybStudentWorkHowDetails.getHowDetailsId(), imgset);
								}
						}
					}
					
				}
				continue;
			}
			
			
			List<ZuoybStudentWorkHow> newWorkHowList = new ArrayList<ZuoybStudentWorkHow>();
			for( Iterator<ZuoybStudentWorkHow>   it = workHowSet.iterator();  it.hasNext(); ) {               
				ZuoybStudentWorkHow how =it.next();
				Map<String,Object> howMap =new HashMap<String,Object>();
				Set<ZuoybStudentWorkHowDetails> zuoybStudentWorkHowDetails= mapDetails.get(how.getHowId());
				Integer countiSize = cuotiMap.get(how.getHowId());
				
				howMap.put("gouxuanSize", gouxuanMap.get(how.getHowId()));
				howMap.put("countiSize", countiSize!=null ? countiSize : 0 );
			 String jianyi="";
			  int max=maxMap.get(how.getHowId());
			  int jianyiCount =0;
				for (Map.Entry<ZuoybStudentWorkHowDetails, Integer> entry : howDetailsMap.entrySet()) {
					ZuoybStudentWorkHowDetails howDetails = entry.getKey();
					//上面已赋值
					if(how.getHowId().equals(howDetails.getWorkHowId())&&max==entry.getValue()){
						int length = entry.getKey().getName().length();
						if(length>jianyiCount){
							jianyiCount=length;
							jianyi = entry.getKey().getName();
						}
					}
				}
				howMap.put("jianyi", jianyi);
				how.setMap(howMap);
				for (ZuoybStudentWorkHowDetails details : zuoybStudentWorkHowDetails) {
					Set<ZuoybStudentWorkImg> workImg =mapImg.get(details.getHowDetailsId());
					if(workImg!=null&&workImg.size()>0){
					    String yicuo=zuoybStudentBgDao.getYiCuoTi(start_date, end_date, details.getHowDetailsId());
					    details.setYicuo(yicuo);
						List<ZuoybStudentWorkImg> newWorkImg = new ArrayList<ZuoybStudentWorkImg>(workImg);
						details.setImgList(newWorkImg);
					}
					
				}
				if(zuoybStudentWorkHowDetails!=null&&zuoybStudentWorkHowDetails.size()>0){
					List<ZuoybStudentWorkHowDetails> newDetails=new ArrayList<ZuoybStudentWorkHowDetails>(zuoybStudentWorkHowDetails);
					Collections.sort(newDetails, new Comparator<ZuoybStudentWorkHowDetails>() {  
						public int compare(ZuoybStudentWorkHowDetails arg0, ZuoybStudentWorkHowDetails arg1) {  
							return arg0.getNum().compareTo(arg1.getNum()); // 按照id排列  
						}  
					}); 
					how.setWorkHowDetailsList(newDetails);
				}
				newWorkHowList.add(how);
			}
			
			bg.setWorkHowList(newWorkHowList);
			detailsList.add(bg);
		}
		return detailsList;
	}
	@Override
	public void saveStudentBg(ZuoybStudentBg bg,
			List<ZuoybStudentBgDetails> detailsList) {
		  this.save(bg);
		  for (ZuoybStudentBgDetails zuoybStudentBgDetails : detailsList) {
			  zuoybStudentBgDetails.setStudentBgId(bg.getId());
			  zuoybStudentBgDetailsService.save(zuoybStudentBgDetails);
		}
		
	}
	@Override
	public void newSaveMonthBg() {
		/**
		 * 
		 * 每月1号执行上月的数据。
		 */
		Date endDate   =new  Date();
		Date startDate =DateHelper.getLastMonthFirstDay(endDate);//上月的第一天
		endDate =DateHelper.getLastMonthLastDay(endDate);//上月的最后一天
		
		//Date endDate   =new  Date();
	//	Date startDate =DateHelper.getNextDay(endDate, -30);
		
		this.newSaveMonthBg(startDate, endDate);
		
	}
	@Override
	public void newSaveMonthBg(Date startDate ,Date endDate){
		String start_date = DateHelper.getDate(startDate);
		String end_date = DateHelper.getDate(endDate);
		 // 根据图书馆和会员的年级和科目查询知识点
	     //开学的时间。。。
	     String date=SystemResourceLocator.getValue("startschool").toString();
	     String semester= PropertiesUtil.getValue("semester");//下学期
	     try {
			int weekNum =DateHelper.diffWeeks(date,startDate);
			List<LibVip> vipList=vipService.getStartDateAndEndDateValidVip(start_date, end_date);
			for (LibVip libVip : vipList) {
				String grade = libVip.getGrade()!=null?libVip.getGrade():"二年级";
				ZuoybStudentBg  zuoybStudentBg =zuoybStudentBgDao.findByStartDateAndEndDateAndVipId(start_date, end_date, libVip.getId());
				if(zuoybStudentBg!=null) continue;
				zuoybStudentBg = new  ZuoybStudentBg();
				zuoybStudentBg.setCreateDate(endDate);
				zuoybStudentBg.setCreateTime(new Date());
				zuoybStudentBg.setEndDate(endDate);
				zuoybStudentBg.setStartDate(startDate);
				zuoybStudentBg.setVipId(libVip.getId());
				zuoybStudentBg.setWeeks(DateHelper.getMonth(startDate)+"");
				//学习建议
				String  suggest= zuoybStudentBgDao.findStartDateAndEndDateAndVipIdAndSuggest(start_date, end_date, libVip.getId());
				zuoybStudentBg.setSuggest(suggest);
				List<ZuoybStudentBgDetails>  zuoybStudentBgDetailsList = new ArrayList<ZuoybStudentBgDetails>();
				String banben  =libVip.getBanben()!=null?libVip.getBanben()+"":"1";
				Integer gouxuanSize=0;
				Integer cuotiSize=0;
				String [] course ={"语文","数学","英语"};
				for (int i = 0; i < course.length; i++) {
					ZuoybStudentBgDetails  zuoybStudentBgDetails = new ZuoybStudentBgDetails();
					zuoybStudentBgDetails.setCourseName(course[i]);
					zuoybStudentBgDetails.setNum(i);
					//当月的知识点
					if("英语".equals(course[i])){
						banben="2";
					}
					
					
					//查询出所有的模块。
					//当月的所有的模块(从二级知识点获取而来)
					List<ZuoybKnowModule> zuoybKnowModuleList=zuoybKnowHowService.getTheMonthModule("SSJ",course[i], libVip.getGrade()!=null?libVip.getGrade():"二年级", weekNum, semester,banben);
					//当月已经选好的知识点(二级知识点)
					List<ZuoybStudentWorkHowDetails> zuoybStudentWorkHowDetailsList=	zuoybStudentWorkHowDetailsService.getStartAndEndWorkHowAndCourse(libVip.getId(), start_date, end_date,course[i]);
					//大纲对应的知识点勾选的次数
					Map<String,Integer> gouxuanMap =new HashMap<String,Integer>();
					//循环模块
					for (ZuoybKnowModule knowModule : zuoybKnowModuleList) {
						//循环已选好的知识点
						Integer cuoti=0;
						Integer gouxuan=0;
						//添加到set 去重 (已经选好的单元)
						Set<ZuoybStudentWorkHow> workHowSet = new HashSet<ZuoybStudentWorkHow>();
						//存放大纲对应的知识点  (知识点已去重)  
						Map<String,Set<ZuoybStudentWorkHowDetails>> mapHowDetails = new HashMap<String, Set<ZuoybStudentWorkHowDetails>>();
						//存放大纲对应的知识点图片
						Map<String,Set<ZuoybStudentWorkImg>> mapHowDetailsImg = new HashMap<String, Set<ZuoybStudentWorkImg>>();
						
						for (ZuoybStudentWorkHowDetails zuoybStudentWorkHowDetails : zuoybStudentWorkHowDetailsList) {
							//根据选择的知识点所属的模块和当月的模块进行比较
							if(knowModule.getModule().equals(zuoybStudentWorkHowDetails.getModule())){
								gouxuan ++;
								List<ZuoybStudentWorkImg>  studentWorkImgList  = zuoybStudentWorkHowDetails.getImgList();
								////当有多个图片时，只去一个。
								if(studentWorkImgList!=null && studentWorkImgList.size()>0){
									cuoti ++;
									Set<ZuoybStudentWorkImg> imgset = new HashSet<ZuoybStudentWorkImg>();
									if(mapHowDetailsImg.containsKey(zuoybStudentWorkHowDetails.getHowDetailsId())){
										imgset =mapHowDetailsImg.get(zuoybStudentWorkHowDetails.getHowDetailsId());
									}
									imgset.addAll(studentWorkImgList);
									mapHowDetailsImg.put(zuoybStudentWorkHowDetails.getHowDetailsId(), imgset);
									
								}
								
								
								int cuotiValus =0;
								if(gouxuanMap.containsKey(zuoybStudentWorkHowDetails.getWorkHowId())){
									cuotiValus = gouxuanMap.get(zuoybStudentWorkHowDetails.getWorkHowId());
								}
								cuotiValus =cuotiValus+1;
								gouxuanMap.put(zuoybStudentWorkHowDetails.getWorkHowId(), cuotiValus);
								
								//查出单元，
								ZuoybStudentWorkHow	zuoybStudentWorkHow =zuoybStudentWorkHowService.getById(zuoybStudentWorkHowDetails.getWorkHowId());
								ZuoybStudentWorkHow newWorkHow = new  ZuoybStudentWorkHow();
								newWorkHow.setHowId(zuoybStudentWorkHow.getHowId());
								newWorkHow.setHowName(zuoybStudentWorkHow.getHowName());
								newWorkHow.setNum(zuoybStudentWorkHow.getNum());
								workHowSet.add(newWorkHow);
								
								//知识点放入set集合去重
								ZuoybStudentWorkHowDetails  newWorkHowDetails  =new ZuoybStudentWorkHowDetails();
								newWorkHowDetails.setName(zuoybStudentWorkHowDetails.getName());
								newWorkHowDetails.setModule(zuoybStudentWorkHowDetails.getModule());
								newWorkHowDetails.setHowDetailsId(zuoybStudentWorkHowDetails.getHowDetailsId());
								newWorkHowDetails.setNum(zuoybStudentWorkHowDetails.getNum());
								
								//计算该大纲下面有多少知识点。去重复。
								Set<ZuoybStudentWorkHowDetails> setHowDetails = new HashSet<ZuoybStudentWorkHowDetails>();
								if(mapHowDetails.containsKey(zuoybStudentWorkHow.getHowId())){
									setHowDetails = mapHowDetails.get(zuoybStudentWorkHow.getHowId());
								}
								setHowDetails.add(newWorkHowDetails);
								mapHowDetails.put(zuoybStudentWorkHow.getHowId(), setHowDetails);
							}
						}
						
						
						List<ZuoybStudentWorkHow> newWorkHowList = new ArrayList<ZuoybStudentWorkHow>();
						for( Iterator<ZuoybStudentWorkHow>   it = workHowSet.iterator();  it.hasNext(); ) {    
							ZuoybStudentWorkHow zuoybStudentWorkHow =it.next();
							Map<String,Object> howMap =new HashMap<String,Object>();
							List<ZuoybStudentWorkHowDetails> newworkHowDetailsList=  	zuoybStudentWorkHow.getWorkHowDetailsList();
							int cuotiCount=0;
							for (ZuoybStudentWorkHowDetails zuoybStudentWorkHowDetails : newworkHowDetailsList) {
								List<ZuoybStudentWorkImg>  imgList  = zuoybStudentWorkHowDetails.getImgList();
								cuotiCount +=imgList.size(); 
							}
							howMap.put("zuoyeCount", newworkHowDetailsList.size());
							howMap.put("cuotiCount", cuotiCount);
							zuoybStudentWorkHow.setMap(howMap);//存放总体报告中的作业点数，作业错题总数，
							
							Set<ZuoybStudentWorkHowDetails> zuoybStudentWorkHowDetails= mapHowDetails.get(zuoybStudentWorkHow.getHowId());
							
							for (ZuoybStudentWorkHowDetails details : zuoybStudentWorkHowDetails) {
								Set<ZuoybStudentWorkImg> workImg =mapHowDetailsImg.get(details.getHowDetailsId());
								if(workImg!=null&&workImg.size()>0){
									List<ZuoybStudentWorkImg> newWorkImg = new ArrayList<ZuoybStudentWorkImg>(workImg);
									details.setImgList(newWorkImg);
								}
								
							}
							
							if(zuoybStudentWorkHowDetails!=null&&zuoybStudentWorkHowDetails.size()>0){
								List<ZuoybStudentWorkHowDetails> newDetails=new ArrayList<ZuoybStudentWorkHowDetails>(zuoybStudentWorkHowDetails);
								Collections.sort(newDetails, new Comparator<ZuoybStudentWorkHowDetails>() {  
									public int compare(ZuoybStudentWorkHowDetails arg0, ZuoybStudentWorkHowDetails arg1) {  
										return arg0.getNum().compareTo(arg1.getNum()); // 按照id排列  
									}  
								}); 
								zuoybStudentWorkHow.setWorkHowDetailsList(newDetails);
							}
							newWorkHowList.add(zuoybStudentWorkHow);
						}
						
						knowModule.setStudentWorkHowList(newWorkHowList);
						
						double bigDouble = 0;
						if(gouxuan> 0){
							BigDecimal big =new BigDecimal(gouxuan-cuoti).divide(new BigDecimal(gouxuan),2,BigDecimal.ROUND_HALF_UP);
							bigDouble = big.doubleValue();
						}
						knowModule.setHowActive(getHowScaleHtml(bigDouble));
						
					}
					// 勾选的知识点去重。=（需要掌握的知识点）包含图片的知识点
					int howSize=0;
					//各项指标掌握情况（包含点击进去弹出单元和单元下面的知识点）
					//zuoybStudentBgDetails.setKnowModuleList(zuoybKnowModuleList);
					zuoybStudentBgDetails.setKnowModuleJson(JSONObject.toJSONString(zuoybKnowModuleList));
					int memorize=0;//识记
					int cuomemorize=0;//识记
					int understanding=0;//理解
					int cuounderstanding=0;//理解
					int apply=0;//应用
					int cuoapply=0;//应用
					Map<String , Integer> changcuoHowDtailsMap = new HashMap<String, Integer>();//常错的知识点
					for (ZuoybStudentWorkHowDetails zuoybStudentWorkHowDetails : zuoybStudentWorkHowDetailsList) {
							List<ZuoybStudentWorkImg>  imgList  = zuoybStudentWorkHowDetails.getImgList();
							if(imgList!=null && imgList.size()>0){
								howSize++;
								String howDetailsId =zuoybStudentWorkHowDetails.getHowDetailsId();
								if(changcuoHowDtailsMap.containsKey(howDetailsId)){
									Integer changcuo =changcuoHowDtailsMap.get(howDetailsId)+1;
									changcuoHowDtailsMap.put(howDetailsId, changcuo);
								}else{
									changcuoHowDtailsMap.put(howDetailsId, 1);
								}
								
								
							}
							if(zuoybStudentWorkHowDetails.getMemorize()!=null&&zuoybStudentWorkHowDetails.getMemorize()==1){
								memorize++;
								if(imgList!=null && imgList.size()>0){
									cuomemorize++;
								}
							}
							if(zuoybStudentWorkHowDetails.getUnderstanding()!=null&&zuoybStudentWorkHowDetails.getUnderstanding()==1){
								understanding++;
								if(imgList!=null && imgList.size()>0){
									cuounderstanding++;
								}
							}
							if(zuoybStudentWorkHowDetails.getApply()!=null&&zuoybStudentWorkHowDetails.getApply()==1){
								apply++;
								if(imgList!=null && imgList.size()>0){
									cuoapply++;
								}
							}
						}
					zuoybStudentBgDetails.setHowSize(howSize);
					//排序后的常错的知识点
					Map<String , Integer>  newMap=Collections3.sortByValue(changcuoHowDtailsMap);
					List<String> ids  =new ArrayList<String>();
					int num=1;
					for (String in : newMap.keySet()) {
						if(num<=5){
							ids.add(in);
						}
						num++;
					}
					if(ids.size()>0){
						// 本月常错的知识点
						zuoybStudentBgDetails.setThisMonthHowDtailsJson(JSONObject.toJSONString(zuoybKnowHowDetailsService.findByIds(ids)));
					}
					
					
					List<ZuoybStudentBgDetailsFeature> featureList =new ArrayList<ZuoybStudentBgDetailsFeature>(); 
					ZuoybStudentBgDetailsFeature memorizeFeature = new  ZuoybStudentBgDetailsFeature("记忆",memorize,cuomemorize);
					ZuoybStudentBgDetailsFeature understandingFeature = new  ZuoybStudentBgDetailsFeature("理解",understanding,cuounderstanding);
					ZuoybStudentBgDetailsFeature applyFeature = new  ZuoybStudentBgDetailsFeature("运用",apply,cuoapply);
					featureList.add(applyFeature);
					featureList.add(memorizeFeature);
					featureList.add(understandingFeature);
					//本月待加强的知识点
					zuoybStudentBgDetails.setFeatureJson(JSONObject.toJSONString(featureList));
					List<ZuoybKnowHowDetails> KnowHowDetailslist =zuoybKnowHowDetailsService.nextMonthHowDtails("SSJ", course[i], grade, semester, banben,DateHelper.diffWeeks(date,endDate));
					zuoybStudentBgDetails.setNextMonthHowDtailsJson(JSONObject.toJSONString(KnowHowDetailslist));//下月的知识点
					zuoybStudentBgDetailsList.add(zuoybStudentBgDetails);
					
				}
				if(gouxuanSize>0&&(gouxuanSize-cuotiSize)>0){
					BigDecimal gouxuanCount =new BigDecimal(gouxuanSize-cuotiSize).multiply(new BigDecimal("100")).divide(new BigDecimal(gouxuanSize),2, RoundingMode.HALF_UP);
					zuoybStudentBg.setNum(gouxuanCount.intValue());
				}else{
					zuoybStudentBg.setNum(100);
				}
				this.saveStudentBg(zuoybStudentBg, zuoybStudentBgDetailsList);
			}
			//获取
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	     
	}
	private    String getHowScaleHtml(double scale){
		if(scale>=0.8){
			return  "强";
		}else if(scale>=0.6&&scale<0.8){
			return "中";
		}else if(scale>=0&&scale<0.6){
			return "弱";
		}else {
			return "无";
		}
		
	}
	@Override
	public void saveWeeksBg(Date startDate, Date endDate) {
		String start_date = DateHelper.getDate(startDate);
		String end_date = DateHelper.getDate(endDate);
		List<String> vipList=zuoybStudentBgDao.getStartDateAndEndDateValidVipId(start_date, end_date);
		for (String vipId : vipList) {
			ZuoybStudentBg  zuoybStudentBg =zuoybStudentBgDao.findByStartDateAndEndDateAndVipId(start_date, DateHelper.getDate(DateHelper.getNextDay(endDate, -1)), vipId);
			if(zuoybStudentBg!=null) continue;
			
			zuoybStudentBg = new  ZuoybStudentBg();
			zuoybStudentBg.setCreateDate(endDate);
			zuoybStudentBg.setCreateTime(new Date());
			zuoybStudentBg.setEndDate(DateHelper.getNextDay(endDate, -1));
			zuoybStudentBg.setStartDate(startDate);
			zuoybStudentBg.setVipId(vipId);
			//学习建议
			
			String  suggest= zuoybStudentBgDao.findStartDateAndEndDateAndVipIdAndSuggest(start_date, DateHelper.getDate(DateHelper.getNextDay(endDate, -1)), vipId);
			zuoybStudentBg.setSuggest(suggest);
			//各科作业质量统计图
		//	List<Map<String, Object>> zuoyetongjilist =zuoybStudentWorkService.getXqWeekReport(vipId,start_date, end_date);
		//	String zltj=JSONObject.toJSONString(zuoyetongjilist);
		//	zuoybStudentBg.setZltj(zltj);
			Integer gouxuanSize=0;
			Integer cuotiSize=0;
			String [] course ={"语文","数学","英语"};
			//已结保存好的单元
			List<ZuoybStudentWorkHow> workHowList=	zuoybStudentWorkHowService.getStartAndEndWorkHow(vipId, start_date, end_date);
			List<ZuoybStudentBgDetails>  zuoybStudentBgDetailsList = new ArrayList<ZuoybStudentBgDetails>();
			for (int i = 0; i < course.length; i++) {
				ZuoybStudentBgDetails  zuoybStudentBgDetails = new ZuoybStudentBgDetails();
				zuoybStudentBgDetails.setCourseName(course[i]);
				zuoybStudentBgDetails.setNum(i);
				//添加到set 去重 需要掌握的知识点
				Set<ZuoybStudentWorkHow> workHowSet = new HashSet<ZuoybStudentWorkHow>();
				// 勾选的知识点去重。=（需要掌握的知识点）
				Set<ZuoybStudentWorkHowDetails> workHowDetailsSet  = new HashSet<ZuoybStudentWorkHowDetails>();
				
				//存放大纲对应的知识点  (知识点已去重)  key:ZuoybStudentWorkHow.id
				Map<String,Set<ZuoybStudentWorkHowDetails>> mapDetails = new HashMap<String, Set<ZuoybStudentWorkHowDetails>>();
				//有错题的知识点。(已包含图片)（本周的关注点） 也需要去重，图片不去重。
				Map<ZuoybStudentWorkHowDetails,List<ZuoybStudentWorkImg>> cuotiDetailsMap = new HashMap<ZuoybStudentWorkHowDetails, List<ZuoybStudentWorkImg>>();
				for (ZuoybStudentWorkHow zuoybStudentWorkHow : workHowList) {
					if(course[i].equals(zuoybStudentWorkHow.getStudentWorkId())){
						ZuoybStudentWorkHow newWorkHow = new  ZuoybStudentWorkHow();
						newWorkHow.setHowId(zuoybStudentWorkHow.getHowId());
						newWorkHow.setHowName(zuoybStudentWorkHow.getHowName());
						newWorkHow.setNum(zuoybStudentWorkHow.getNum());
						workHowSet.add(newWorkHow);
						List<ZuoybStudentWorkHowDetails> workHowDetailsList  = zuoybStudentWorkHow.getWorkHowDetailsList();
						if(workHowDetailsList!=null && workHowDetailsList.size()>0){
							//勾选的知识点累加
							gouxuanSize +=workHowDetailsList.size();
							for (ZuoybStudentWorkHowDetails zuoybStudentWorkHowDetails : workHowDetailsList) {
								ZuoybStudentWorkHowDetails newWorkHowDetails  =new  ZuoybStudentWorkHowDetails();
								newWorkHowDetails.setHowDetailsId(zuoybStudentWorkHowDetails.getHowDetailsId());
								newWorkHowDetails.setName(zuoybStudentWorkHowDetails.getName());
								newWorkHowDetails.setNum(zuoybStudentWorkHowDetails.getNum());
								//暂存howid,下面取值用到
								newWorkHowDetails.setWorkHowId(zuoybStudentWorkHow.getHowId());
								workHowDetailsSet.add(newWorkHowDetails);//自动加入到set，自动去重  （需要掌握的知识点数，）
								
								Set<ZuoybStudentWorkHowDetails> setHowDetails = new HashSet<ZuoybStudentWorkHowDetails>();
								if(mapDetails.containsKey(zuoybStudentWorkHow.getHowId())){
									setHowDetails.addAll(mapDetails.get(zuoybStudentWorkHow.getHowId()));
								}
								setHowDetails.add(newWorkHowDetails);
								mapDetails.put(zuoybStudentWorkHow.getHowId(), setHowDetails);
								List<ZuoybStudentWorkImg>  imgList  = zuoybStudentWorkHowDetails.getImgList();
								//当有多个图片时，只去一个。
								if(imgList!=null && imgList.size()>0){
									cuotiSize +=1;
									if(cuotiDetailsMap.containsKey(newWorkHowDetails)){
										imgList.addAll(cuotiDetailsMap.get(newWorkHowDetails));
									}
									cuotiDetailsMap.put(newWorkHowDetails, imgList);
								}
							}
						}
					}
				}
				//需要掌握知识点数。
				zuoybStudentBgDetails.setHowSize(workHowDetailsSet.size()>0?workHowDetailsSet.size():0);
				//需要掌握的知识点
				 List<ZuoybStudentWorkHow> newWorkHowList = new ArrayList<ZuoybStudentWorkHow>();
				for( Iterator<ZuoybStudentWorkHow>   it = workHowSet.iterator();  it.hasNext(); ) {
					ZuoybStudentWorkHow how =it.next();
					Set<ZuoybStudentWorkHowDetails> zuoybStudentWorkHowDetails= mapDetails.get(how.getHowId());
					if(zuoybStudentWorkHowDetails!=null&&zuoybStudentWorkHowDetails.size()>0){
						List<ZuoybStudentWorkHowDetails> newDetails=new ArrayList<ZuoybStudentWorkHowDetails>(zuoybStudentWorkHowDetails);
						Collections.sort(newDetails, new Comparator<ZuoybStudentWorkHowDetails>() {  
							public int compare(ZuoybStudentWorkHowDetails arg0, ZuoybStudentWorkHowDetails arg1) {  
								return arg0.getNum().compareTo(arg1.getNum()); // 按照num排列  
							}  
						}); 
						how.setWorkHowDetailsList(newDetails);
					}
					newWorkHowList.add(how);
				}
				if(newWorkHowList.size()>0){
					Collections.sort(newWorkHowList, new Comparator<ZuoybStudentWorkHow>() {  
						public int compare(ZuoybStudentWorkHow arg0, ZuoybStudentWorkHow arg1) {  
							return arg0.getNum().compareTo(arg1.getNum()); // 按照num排列  
						}  
					}); 
					zuoybStudentBgDetails.setKnowHow(JSONObject.toJSONString(newWorkHowList));
				}
				
				List<ZuoybStudentWorkHowDetails> newHowDetailsList = new ArrayList<ZuoybStudentWorkHowDetails>();
				for (Map.Entry<ZuoybStudentWorkHowDetails,List<ZuoybStudentWorkImg>> entry : cuotiDetailsMap.entrySet()) {
					   ZuoybStudentWorkHowDetails zuoybStudentWorkHowDetails= entry.getKey();
					   String yicuo=zuoybStudentBgDao.getYiCuoTi(start_date, end_date, zuoybStudentWorkHowDetails.getHowDetailsId());
					   zuoybStudentWorkHowDetails.setYicuo(yicuo);
					   zuoybStudentWorkHowDetails.setImgList(entry.getValue());
					   newHowDetailsList.add(zuoybStudentWorkHowDetails);
				}
				if(newHowDetailsList.size()>0){
					Collections.sort(newHowDetailsList, new Comparator<ZuoybStudentWorkHowDetails>() {  
						public int compare(ZuoybStudentWorkHowDetails arg0, ZuoybStudentWorkHowDetails arg1) {  
							return arg0.getNum().compareTo(arg1.getNum()); // 按照num排列  
						}  
					}); 
					zuoybStudentBgDetails.setEmphasisKnowHow(JSONObject.toJSONString(newHowDetailsList));
				}
				zuoybStudentBgDetailsList.add(zuoybStudentBgDetails);
			}
			if(gouxuanSize>0&&(gouxuanSize-cuotiSize)>0){
				BigDecimal gouxuanCount =new BigDecimal(gouxuanSize-cuotiSize).multiply(new BigDecimal("100")).divide(new BigDecimal(gouxuanSize),2, RoundingMode.HALF_UP);
				zuoybStudentBg.setNum(gouxuanCount.intValue());
			}else{
				zuoybStudentBg.setNum(100);
			}
			this.saveStudentBg(zuoybStudentBg, zuoybStudentBgDetailsList);
		}
		
	}
	@Override
	public void oldMonth() {
		
		// 9.18
				// 上周日，
				Date endDate   =DateHelper.parseDate("2018-03-26", "yyyy-MM-dd");
				Date startDate =DateHelper.getNextDay(endDate, -7);
				Date data=DateHelper.parseDate("2018-03-01", "yyyy-MM-dd");
				while(true){
					this.saveWeeksBg(startDate, endDate);
					endDate=startDate;
					startDate =DateHelper.getNextDay(endDate, -7);
					if(DateHelper.isInDate(data, startDate, endDate)){
						return;
					}
				}
	}
	

	@Override
	public ZuoybStudentBg newSaveBgVipAndRedis(Date startDate ,Date endDate,String vipId){
		if(vipId==null){
			return null;
		}
		String redisKey="REP_";//前缀
		String key=redisKey+vipId+DateHelper.format(new Date(),"yyyyMMdd");
		
		ZuoybStudentBg  zuoybStudentBg =tokenManager.get(key, ZuoybStudentBg.class);
		if(zuoybStudentBg!=null){
			return zuoybStudentBg;
		}
		LibVip libVip=vipService.getById(vipId);
		if(libVip==null){
			return null;
		}
		String start_date = DateHelper.getDate(startDate);
		String end_date = DateHelper.getDate(endDate);
		 // 根据图书馆和会员的年级和科目查询知识点
		 //开学的时间。。。
	     String date=SystemResourceLocator.getValue("startschool").toString();
	     String semester= PropertiesUtil.getValue("semester").toString();//下学期
	     String banben=libVip.getBanben()!=null ? libVip.getBanben().toString():"2";
	     String grade = libVip.getGrade()!=null?libVip.getGrade():"二年级";
	     
	     try {
	    	 	
				int weekNum =DateHelper.diffWeeks(date,startDate);
				zuoybStudentBg = new  ZuoybStudentBg();
				zuoybStudentBg.setId(UUID.randomUUID().toString());
				zuoybStudentBg.setCreateDate(endDate);
				zuoybStudentBg.setCreateTime(new Date());
				zuoybStudentBg.setEndDate(endDate);
				zuoybStudentBg.setStartDate(startDate);
				zuoybStudentBg.setVipId(vipId);
				zuoybStudentBg.setWeeks(DateHelper.getMonth(startDate)+"");
				//学习建议 (学情分析暂无。)
				String  suggest= zuoybStudentBgDao.findStartDateAndEndDateAndVipIdAndSuggest(start_date, end_date, libVip.getId());
				//zuoybStudentBg.setSuggest(suggest);
				List<ZuoybStudentBgDetails>  zuoybStudentBgDetailsList = new ArrayList<ZuoybStudentBgDetails>();
				
				
				String [] course ={"语文","数学","英语"};
				for (int i = 0; i < course.length; i++) {
					ZuoybStudentBgDetails  zuoybStudentBgDetails = new ZuoybStudentBgDetails();
					//zuoybStudentBgDetails.setId(UUID.randomUUID().toString());
					zuoybStudentBgDetails.setSuggest(suggest);
					zuoybStudentBgDetails.setStudentBgId(zuoybStudentBg.getId());
					zuoybStudentBgDetails.setCourseName(course[i]);
					zuoybStudentBgDetails.setNum(i);
					//当月的所有的模块(从二级知识点获取而来)
					List<ZuoybKnowModule> knowModuleList=zuoybKnowHowService.getTheMonthModule("SSJ",course[i], grade, weekNum, semester,banben);
					//当月已经选好的知识点(二级知识点)
					List<ZuoybStudentWorkHowDetails> workHowDetailsList=	zuoybStudentWorkHowDetailsService.getStartAndEndWorkHowAndCourse(libVip.getId(), start_date, end_date,course[i]);
					
					
					//循环单元
					for (ZuoybKnowModule knowModule : knowModuleList) {
						//循环已选好的知识点
						Integer cuoti=0;//错题一个知识点有多张图片只算一次
						Integer gouxuan=0;//判断勾选了多少知识点
						//添加到set 去重 (已经选好的单元（知识点对应的单元）)
						Set<ZuoybStudentWorkHow> workHowSet = new HashSet<ZuoybStudentWorkHow>();
						//存放大纲对应的知识点  (知识点已去重)  
						Map<String,Set<ZuoybStudentWorkHowDetails>> mapHowDetails = new HashMap<String, Set<ZuoybStudentWorkHowDetails>>();
						//存放大纲对应的知识点图片
						Map<String,Set<ZuoybStudentWorkImg>> mapHowDetailsImg = new HashMap<String, Set<ZuoybStudentWorkImg>>();
						

						//大纲对应的知识点勾选的次数
						Map<String,Integer> gouxuanMap =new HashMap<String,Integer>();//单元对应的知识点总数
						Map<String,Integer> cuotiMap =new HashMap<String,Integer>();//知识点对应的图片总数
						
						//循环当月已经选好的知识点(二级知识点)
						for (ZuoybStudentWorkHowDetails zuoybStudentWorkHowDetails : workHowDetailsList) {
							//根据选择的知识点所属的模块和当月的模块进行比较
							if(knowModule.getModule().equals(zuoybStudentWorkHowDetails.getModule())){
								
								//查出单元，
								ZuoybStudentWorkHow	zuoybStudentWorkHow =zuoybStudentWorkHowService.getById(zuoybStudentWorkHowDetails.getWorkHowId());
								ZuoybStudentWorkHow newWorkHow = new  ZuoybStudentWorkHow();
								newWorkHow.setHowId(zuoybStudentWorkHow.getHowId());
								newWorkHow.setHowName(zuoybStudentWorkHow.getHowName());
								newWorkHow.setNum(zuoybStudentWorkHow.getNum());
								workHowSet.add(newWorkHow);
								
								gouxuan ++;
								//当有多个图片时，只去一个。
								int cuotiValues =0;
								List<ZuoybStudentWorkImg>  studentWorkImgList  = zuoybStudentWorkHowDetails.getImgList();
								if(studentWorkImgList!=null && studentWorkImgList.size()>0){
									cuoti ++;
									Set<ZuoybStudentWorkImg> imgset = new HashSet<ZuoybStudentWorkImg>();
									if(mapHowDetailsImg.containsKey(zuoybStudentWorkHowDetails.getHowDetailsId())){
										imgset =mapHowDetailsImg.get(zuoybStudentWorkHowDetails.getHowDetailsId());
									}
									imgset.addAll(studentWorkImgList);
									mapHowDetailsImg.put(zuoybStudentWorkHowDetails.getHowDetailsId(), imgset);
									
									
									
									
									if(cuotiMap.containsKey(zuoybStudentWorkHow.getHowId())){
										cuotiValues = cuotiMap.get(zuoybStudentWorkHow.getHowId());
									}
									cuotiValues = cuotiValues+studentWorkImgList.size();
								}
								cuotiMap.put(zuoybStudentWorkHow.getHowId(), cuotiValues);
								
								int gouxuanValus =0;
								if(gouxuanMap.containsKey(zuoybStudentWorkHow.getHowId())){
									gouxuanValus = gouxuanMap.get(zuoybStudentWorkHow.getHowId());
								}
								gouxuanValus =gouxuanValus+1;
								gouxuanMap.put(zuoybStudentWorkHow.getHowId(), gouxuanValus);
								
							
								
								
								ZuoybStudentWorkHowDetails  newWorkHowDetails  =new ZuoybStudentWorkHowDetails();
								newWorkHowDetails.setName(zuoybStudentWorkHowDetails.getName());
								newWorkHowDetails.setModule(zuoybStudentWorkHowDetails.getModule());
								newWorkHowDetails.setHowDetailsId(zuoybStudentWorkHowDetails.getHowDetailsId());
								newWorkHowDetails.setNum(zuoybStudentWorkHowDetails.getNum());
								
								//计算该大纲下面有多少知识点。去重复。
								Set<ZuoybStudentWorkHowDetails> setHowDetails = new HashSet<ZuoybStudentWorkHowDetails>();
								if(mapHowDetails.containsKey(zuoybStudentWorkHow.getHowId())){
									setHowDetails = mapHowDetails.get(zuoybStudentWorkHow.getHowId());
								}
								setHowDetails.add(newWorkHowDetails);
								mapHowDetails.put(zuoybStudentWorkHow.getHowId(), setHowDetails);
								
							}
							
						}
						List<ZuoybStudentWorkHow> newWorkHowList = new ArrayList<ZuoybStudentWorkHow>();
						//已经选好的单元循环
						for( Iterator<ZuoybStudentWorkHow>   it = workHowSet.iterator();  it.hasNext(); ) {    
							ZuoybStudentWorkHow zuoybStudentWorkHow =it.next();
							Map<String,Object> howMap =new HashMap<String,Object>();
							Integer  zuoyeCount =gouxuanMap.get(zuoybStudentWorkHow.getHowId());
							Integer  cuotiCount =cuotiMap.get(zuoybStudentWorkHow.getHowId());
							howMap.put("zuoyeCount", zuoyeCount!=null?zuoyeCount:0);//已选知识点总数（单元知识点作业总次数）
							howMap.put("cuotiCount", cuotiCount!=null?cuotiCount:0);//有图片的错题总数（单元知识点错题总数量）
							zuoybStudentWorkHow.setMap(howMap);//存放总体报告中的作业点数，作业错题总数，
							
							Set<ZuoybStudentWorkHowDetails> zuoybStudentWorkHowDetails= mapHowDetails.get(zuoybStudentWorkHow.getHowId());
							
							for (ZuoybStudentWorkHowDetails details : zuoybStudentWorkHowDetails) {
								Set<ZuoybStudentWorkImg> workImg =mapHowDetailsImg.get(details.getHowDetailsId());
								if(workImg!=null&&workImg.size()>0){
									List<ZuoybStudentWorkImg> newWorkImg = new ArrayList<ZuoybStudentWorkImg>(workImg);
									details.setImgList(newWorkImg);
								}
								
							}
							
							if(zuoybStudentWorkHowDetails!=null&&zuoybStudentWorkHowDetails.size()>0){
								List<ZuoybStudentWorkHowDetails> newDetails=new ArrayList<ZuoybStudentWorkHowDetails>(zuoybStudentWorkHowDetails);
								Collections.sort(newDetails, new Comparator<ZuoybStudentWorkHowDetails>() {  
									public int compare(ZuoybStudentWorkHowDetails arg0, ZuoybStudentWorkHowDetails arg1) {  
										return arg0.getNum().compareTo(arg1.getNum()); // 按照id排列  
									}  
								}); 
								zuoybStudentWorkHow.setWorkHowDetailsList(newDetails);
							}
							newWorkHowList.add(zuoybStudentWorkHow);
						}
						
						knowModule.setStudentWorkHowList(newWorkHowList);
						
						double bigDouble = -1;
						if(gouxuan> 0){
							BigDecimal big =new BigDecimal(gouxuan-cuoti).divide(new BigDecimal(gouxuan),2,BigDecimal.ROUND_HALF_UP);
							bigDouble = big.doubleValue();
						}
						knowModule.setHowActive(getHowScaleHtml(bigDouble));
					}
					
					//根据模块查询所有已选择的知识点，然后根据知识点查询出单元，，在用集合封装起来。
					
					//各项指标掌握情况（包含点击进去弹出单元和单元下面的知识点）
					zuoybStudentBgDetails.setKnowModuleList(knowModuleList);
					int memorize=0;//识记
					int cuomemorize=0;//识记
					int understanding=0;//理解
					int cuounderstanding=0;//理解
					int apply=0;//应用
					int cuoapply=0;//应用
					Map<String , Integer> changcuoHowDtailsMap = new HashMap<String, Integer>();//常错的知识点
					for (ZuoybStudentWorkHowDetails zuoybStudentWorkHowDetails : workHowDetailsList) {
							List<ZuoybStudentWorkImg>  imgList  = zuoybStudentWorkHowDetails.getImgList();
							if(imgList!=null && imgList.size()>0){
								String howDetailsId =zuoybStudentWorkHowDetails.getHowDetailsId();
								Integer changcuo = 1;
								if(changcuoHowDtailsMap.containsKey(howDetailsId)){
									 changcuo =changcuoHowDtailsMap.get(howDetailsId)+1;
								}
								changcuoHowDtailsMap.put(howDetailsId, changcuo);
								
								
							}
							if(zuoybStudentWorkHowDetails.getMemorize()!=null&&zuoybStudentWorkHowDetails.getMemorize()==1){
								memorize++;
								if(imgList!=null && imgList.size()>0){
									cuomemorize++;
								}
							}
							if(zuoybStudentWorkHowDetails.getUnderstanding()!=null&&zuoybStudentWorkHowDetails.getUnderstanding()==1){
								understanding++;
								if(imgList!=null && imgList.size()>0){
									cuounderstanding++;
								}
							}
							if(zuoybStudentWorkHowDetails.getApply()!=null&&zuoybStudentWorkHowDetails.getApply()==1){
								apply++;
								if(imgList!=null && imgList.size()>0){
									cuoapply++;
								}
							}
						}
					//排序后的常错的知识点（只取错题最多的5个）
					Map<String , Integer>  newMap=Collections3.sortByValue(changcuoHowDtailsMap);
					List<String> ids  =new ArrayList<String>();
					int num=1;
					for (String in : newMap.keySet()) {
						if(num<=5){
							ids.add(in);
							break;
						}
						num++;
					}
					if(ids.size()>0){
						//常错的知识点
						zuoybStudentBgDetails.setThisMonthHowDtails(zuoybKnowHowDetailsService.findKnowHowDetailsByIds(ids));
					}
					
					
					List<ZuoybStudentBgDetailsFeature> featureList =new ArrayList<ZuoybStudentBgDetailsFeature>(); 
					ZuoybStudentBgDetailsFeature memorizeFeature = new  ZuoybStudentBgDetailsFeature("记忆",memorize,cuomemorize);
					ZuoybStudentBgDetailsFeature understandingFeature = new  ZuoybStudentBgDetailsFeature("理解",understanding,cuounderstanding);
					ZuoybStudentBgDetailsFeature applyFeature = new  ZuoybStudentBgDetailsFeature("运用",apply,cuoapply);
					featureList.add(applyFeature);
					featureList.add(memorizeFeature);
					featureList.add(understandingFeature);
					zuoybStudentBgDetails.setFeatureList(featureList);//本月待加强的知识点
					List<String> knowHowDetailslist =zuoybKnowHowDetailsService.
							nextMonthZuoybHowDtails("SSJ", course[i], grade, semester, banben, DateHelper.diffWeeks(date,endDate));
					zuoybStudentBgDetails.setNextMonthHowDtails(knowHowDetailslist);//下月的知识点
					zuoybStudentBgDetailsList.add(zuoybStudentBgDetails);
				}
				zuoybStudentBg.setBgDetailsList(zuoybStudentBgDetailsList);
				tokenManager.set(key, zuoybStudentBg,  24 * 3600);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return zuoybStudentBg;
	     
	}
	@Override
	public String findTodayVipIdAndSuggest(Date date ,String vipId) {
		String start_date = DateHelper.getDate(date);
		String  suggest= zuoybStudentBgDao.findStartDateAndEndDateAndVipIdAndSuggest(start_date, start_date, vipId);
		return suggest;
	}
	
	
	
	@Override
	public Map<String,Object> newSaveBgVipAndRedisV2(Date startDate, Date endDate,String vipId) {
		Map<String,Object> reqMap=new HashMap<String, Object>();
		LibVip libVip=vipService.getById(vipId);
		if(libVip==null){
			return reqMap;
		}
		
		//会员vip标签
		List<String> tags=new ArrayList<String>();
		if(StringUtils.isNotEmpty(libVip.getTagsCharacter())){
			tags.addAll(Arrays.asList(libVip.getTagsCharacter().split(";")));
		}
		if(StringUtils.isNotEmpty(libVip.getTagsHabit())){
			tags.addAll(Arrays.asList(libVip.getTagsHabit().split(";")));
		}
		reqMap.put("tags", tags);
		
		reqMap.put("imgUrl", libVip.getImgUrl());
		//总体情况(暂时不做给到前端字段)
		List<String> questionList = new ArrayList<String>();
		reqMap.put("questionList", questionList);

		String redisKey="REP_V2_";//新版的前缀，兼容旧版
		String key=redisKey+vipId+DateHelper.format(new Date(),"yyyyMMdd");
		
		List<BgDetails>  zuoybStudentBg =tokenManager.get(key, List.class);
		if(zuoybStudentBg!=null){
			reqMap.put("bgDetailsList", zuoybStudentBg);
			return reqMap;
		}

		List<BgDetails> bgDetailsList=new ArrayList<BgDetails>();
		BgDetails bgDetails=null;
		

		Map<String,List<Map<String, Object>>> reqAllMap=kmtQueryDao.findAllModularLatListMap(vipId);//查出学员近30天所有学过的知识点，包含kmt与作业吧
		Map<String,List<Map<String, Object>>> reqWrongMap=kmtQueryDao.findWrongModularLatListMap(vipId);//查出学员近30天所有错题的知识点，包含kmt与作业吧
		
		Map<String,List<Map<String, Object>>> allReqAllMap=kmtQueryDao.findAllModularLatListMap(null);//查出所有学员近30天所有学过的知识点，包含kmt与作业吧
		Map<String,List<Map<String, Object>>> allReqWrongMap=kmtQueryDao.findWrongModularLatListMap(null);//查出所有学员近30天所有错题的知识点，包含kmt与作业吧
				
		Map<String,List<Map<String, Object>>> reqSkillAllMap=kmtQueryDao.findAllSkillLatListMap(vipId);//查出学员近30天所有学过的技能，只包含kmt
		Map<String,List<Map<String, Object>>> reqSkillWrongMap=kmtQueryDao.findWrongSkillLatListMap(vipId);//查出学员近30天所有学过的技能，只包含kmt
		
		Map<String,List<Map<String, Object>>> allSkillReqAllMap=kmtQueryDao.findAllSkillLatListMap(null);//查出所有学员近30天所有学过的错题技能，只包含kmt
		Map<String,List<Map<String, Object>>> allSkillReqWrongMap=kmtQueryDao.findWrongSkillLatListMap(null);//查出所有学员近30天所有学过的错题技能，只包含kmt

		
	    //语文-----------------------------------
		bgDetails=new BgDetails();
		bgDetails.setCourseName("语文");
		addLatList(libVip,bgDetails,reqAllMap,reqWrongMap,allReqAllMap,allReqWrongMap,reqSkillAllMap,reqSkillWrongMap,allSkillReqAllMap,allSkillReqWrongMap);
		bgKnowInfo(bgDetails, vipId, startDate, endDate); //插入知识点相关信息
		bgDetailsList.add(bgDetails);
		//---------------------------------------
		
		
	    //数学-----------------------------------
		bgDetails=new BgDetails();
		bgDetails.setCourseName("数学");
		addLatList(libVip,bgDetails,reqAllMap,reqWrongMap,allReqAllMap,allReqWrongMap,reqSkillAllMap,reqSkillWrongMap,allSkillReqAllMap,allSkillReqWrongMap);
		bgKnowInfo(bgDetails, vipId, startDate, endDate); //插入知识点相关信息
		bgDetailsList.add(bgDetails);
		//---------------------------------------
		
	    //英语-----------------------------------
		bgDetails=new BgDetails();
		bgDetails.setCourseName("英语");
		addLatList(libVip,bgDetails,reqAllMap,reqWrongMap,allReqAllMap,allReqWrongMap,reqSkillAllMap,reqSkillWrongMap,allSkillReqAllMap,allSkillReqWrongMap);
		bgKnowInfo(bgDetails, vipId, startDate, endDate); //插入知识点相关信息
		bgDetailsList.add(bgDetails);
		//---------------------------------------
		
		reqMap.put("bgDetailsList", bgDetailsList);//放到redis中
		tokenManager.set(key, bgDetailsList,  24 * 3600);
		return reqMap;
	}
	
	private void addLatList(LibVip libVip,BgDetails bgDetails,
			Map<String,List<Map<String, Object>>> reqAllMap,
			Map<String,List<Map<String, Object>>> reqWrongMap,
			Map<String,List<Map<String, Object>>> allReqAllMap,
			Map<String,List<Map<String, Object>>> allReqWrongMap,
			Map<String,List<Map<String, Object>>> reqSkillAllMap,
			Map<String,List<Map<String, Object>>> reqSkillWrongMap,
			Map<String,List<Map<String, Object>>> allSkillReqAllMap,
			Map<String,List<Map<String, Object>>> allSkillReqWrongMap){
		
		List<Lat> modularLatList=null, 
			       skillLatList= null;
	List<Map<String,Object>> 
		allModularLat=null,
			wrongModularLat=null,
			    allAllModularLat=null,
					allWrongModularLat=null,
						allSkillLat=null,
							wrongSkillLat=null,
							    allAllSkillLat=null,
									allWrongSkillLat=null;
		
		
		allModularLat=reqAllMap.get(bgDetails.getCourseName());
		wrongModularLat=reqWrongMap.get(bgDetails.getCourseName());
		
		allAllModularLat=allReqAllMap.get(bgDetails.getCourseName());
		allWrongModularLat=allReqWrongMap.get(bgDetails.getCourseName());
		
		
		allSkillLat=reqSkillAllMap.get(bgDetails.getCourseName());
		wrongSkillLat=reqSkillWrongMap.get(bgDetails.getCourseName());
		
		allAllSkillLat=allSkillReqAllMap.get(bgDetails.getCourseName());
		allWrongSkillLat=allSkillReqWrongMap.get(bgDetails.getCourseName());
		
		
		modularLatList=IntegrationMap(libVip,
				allModularLat==null ? new ArrayList<Map<String,Object>>() : allModularLat,
				wrongModularLat ==null ? new ArrayList<Map<String,Object>>() :wrongModularLat ,
				allAllModularLat  ==null ? new ArrayList<Map<String,Object>>() :allAllModularLat ,
				allWrongModularLat  ==null ? new ArrayList<Map<String,Object>>() :allWrongModularLat );
		skillLatList=IntegrationMap(libVip,
				allSkillLat==null ? new ArrayList<Map<String,Object>>() : allSkillLat,
				wrongSkillLat==null ? new ArrayList<Map<String,Object>>() : wrongSkillLat,
				allAllSkillLat==null ? new ArrayList<Map<String,Object>>() : allAllSkillLat,
				allWrongSkillLat==null ? new ArrayList<Map<String,Object>>() : allWrongSkillLat
				);
		bgDetails.setModularLatList(modularLatList);
		bgDetails.setSkillLatList(skillLatList);
		bgDetails.setModularDiagnosis(getModularDiagnosis(modularLatList));
		bgDetails.setSkillDiagnosis(getSkillDiagnosis(skillLatList));
	}
	
	
	
	private List<Lat>  IntegrationMap(LibVip libVip,
			List<Map<String,Object>> allLat,//单会员
			List<Map<String,Object>> wrongLat,//单会员
			List<Map<String,Object>> allAllLat,//所有会员
			List<Map<String,Object>> allWrongLat){//所有会员
		List<Lat> modularLatList= new ArrayList<Lat>();
		Lat lat=null;
		if(allAllLat!=null && allAllLat.size()>0){
			for (Map<String, Object> allMap : allAllLat) {//整合同一纬度所有的知识点与错题知识点
				if(allWrongLat !=null && allWrongLat.size()>0){
					for (Map<String, Object> wrongMap : allWrongLat) {
						if(allMap.get("name")!=null){
							if(allMap.get("name").equals(wrongMap.get("name"))){
								allMap.put("wrongCount", wrongMap.get("count").toString());
							}
						}

					}
				}

			}
		}
		
		
		if(allLat !=null && allLat.size()>0){
			for (Map<String, Object> allMap : allLat) {//整合同一纬度的知识点与错题知识点
				if(wrongLat !=null && wrongLat.size()>0){
					for (Map<String, Object> wrongMap : wrongLat) {
						if(allMap.get("name") !=null){
							if(allMap.get("name").equals(wrongMap.get("name"))){
								allMap.put("wrongCount", wrongMap.get("count").toString());
								break;
							}
						}
					}

					//如果没有匹配到，则设置为0
					if (allMap.get("wrongCount") == null){
						allMap.put("wrongCount", 0);
					}
				}
				if(allAllLat!=null && allAllLat.size()>0){
					for (Map<String, Object> allAllMap : allAllLat) {
						if(allMap.get("name") !=null){
							if(allMap.get("name").equals(allAllMap.get("name"))){
								allMap.put("allCount", allAllMap.get("count").toString());
								allMap.put("allWrongCount", allAllMap.get("wrongCount")!=null ? allAllMap.get("wrongCount").toString() :0);
								break;
							}
						}
					}

					//如果没有匹配到，则设置为0
					if (allMap.get("allCont") == null){
						allMap.put("allCount", 0);
						allMap.put("allWrongCount", 0);
					}
				}
				
			}
			if(allLat !=null && allLat.size()>0){
				for (Map<String, Object> allMap : allLat) {
					lat=new Lat();
					lat.setName(allMap.get("name")+"");
					lat.setAvgVal((int)((Integer.parseInt(allMap.get("allCount").toString())-Integer.parseInt(allMap.get("allWrongCount").toString()))/(Double.parseDouble(allMap.get("allCount").toString())) * 100 ));
					lat.setVal((int)((Integer.parseInt(allMap.get("count").toString())-Integer.parseInt(allMap.get("wrongCount")!=null ? allMap.get("wrongCount").toString() : "0" ))/(Double.parseDouble(allMap.get("count").toString()))*100));
					lat.setSuggest(SuggestTextUtil.getSuggest(lat.getName(), lat.getVal(), libVip.getGrade()));
					modularLatList.add(lat);
				}
			}
			
		}
		
		return modularLatList;
	}
	
	
	private String getSkillDiagnosis(List<Lat> latList){
		StringBuffer bb=new StringBuffer("");
		List<String> level1=new ArrayList<String>();//熟练掌握
		List<String> level2=new ArrayList<String>();//基本熟练
		List<String> level3=new ArrayList<String>();//不够熟练
		List<String> advantage=new ArrayList<String>();//优势
		List<String> Inferiority=new ArrayList<String>();//劣势
		for (Lat lat : latList) {
			if(lat.getVal()>85){
				level1.add(lat.getName());
			}else if(lat.getVal()>65){
				level2.add(lat.getName());
			}else{
				level3.add(lat.getName());
			}
			if(lat.getAvgVal()>lat.getVal()){
				Inferiority.add(lat.getName());
			}else if(lat.getAvgVal()<lat.getVal()){
				advantage.add(lat.getName());
			}
		}
		if(level1.size()>0){
			bb.append("你已经熟练掌握了"+String.join("、", level1)+"。");
		}
		if(level2.size()>0){
			bb.append("在"+String.join("、", level2)+"在学科技能方面，你已经熟练掌握了");
		}
		if(level3.size()>0){
			bb.append("在"+String.join("、", level3)+"上，你还不够熟练，存在着比较多的失误。");
		}
		if(advantage.size()>0){
			bb.append("另外我们发现，和同龄人相比，你在"+String.join("、", advantage)+"上占有明显优势。");
		}
		if(Inferiority.size()>0){
			bb.append("要注意的是，你的"+String.join("、", Inferiority)+"低于同龄伙伴的平均水平，平时要加强这些知识模块的学习。");
		}
		return StringUtils.isNotEmpty(bb.toString()) ? "在学科技能方面，"+bb.toString() :"";
	}

	private String getModularDiagnosis(List<Lat> latList){
		StringBuffer bb=new StringBuffer("");
		List<String> level1=new ArrayList<String>();//熟练掌握
		List<String> level2=new ArrayList<String>();//基本熟练
		List<String> level3=new ArrayList<String>();//不够熟练
		List<String> advantage=new ArrayList<String>();//优势
		List<String> Inferiority=new ArrayList<String>();//劣势
		for (Lat lat : latList) {
			if(lat.getVal()>85){
				level1.add(lat.getName());
			}else if(lat.getVal()>65){
				level2.add(lat.getName());
			}else{
				level3.add(lat.getName());
			}
			if(lat.getAvgVal()>lat.getVal()){
				Inferiority.add(lat.getName());
			}else if(lat.getAvgVal()<lat.getVal()){
				advantage.add(lat.getName());
			}
		}
		if(level1.size()>0){
			bb.append("发现你已经熟练掌握了"+String.join("、", level1)+"。");
		}
		if(level2.size()>0){
			bb.append("在"+String.join("、", level2)+"上，你能达到基本熟练的水平，能够完成比较基础的题目。");
		}
		if(level3.size()>0){
			bb.append("在"+String.join("、", level3)+"上，你还不够熟练，存在着比较多的失误。");
		}
		if(advantage.size()>0){
			bb.append("另外我们发现，和同龄人相比，你在"+String.join("、", advantage)+"上占有明显优势。");
		}
		if(Inferiority.size()>0){
			bb.append("要注意的是，你的"+String.join("、", Inferiority)+"低于同龄伙伴的平均水平，平时要加强这些知识模块的学习。");
		}
		return StringUtils.isNotEmpty(bb.toString()) ? "根据我们对你的观察，"+bb.toString():"" ;
	}
	
	protected void bgKnowInfo(BgDetails bgDetails,String vipId,Date startDate,Date endDate) {
		int memorize=0;//识记
		int cuomemorize=0;//识记
		int understanding=0;//理解
		int cuounderstanding=0;//理解
		int apply=0;//应用
		int cuoapply=0;//应用
		Map<String , Integer> cuomemorizeMap = new HashMap<String, Integer>();//记忆常错的知识点
		Map<String , Integer> cuounderstandingMap = new HashMap<String, Integer>();//理解的知识点
		Map<String , Integer> cuoapplyMap = new HashMap<String, Integer>();//运用的知识点
		String start_date = DateHelper.getDate(startDate);
		String end_date = DateHelper.getDate(endDate);
		List<ZuoybStudentWorkHowDetails> workHowDetailsList=	zuoybStudentWorkHowDetailsService.getStartAndEndWorkHowAndCourse(vipId, start_date, end_date,bgDetails.getCourseName());
		for (ZuoybStudentWorkHowDetails zuoybStudentWorkHowDetails : workHowDetailsList) {
				List<ZuoybStudentWorkImg>  imgList  = new ArrayList<ZuoybStudentWorkImg>();
				if(zuoybStudentWorkHowDetails.getType()==null || zuoybStudentWorkHowDetails.getType()==2){ //错题
					imgList  = zuoybStudentWorkHowDetails.getImgList();
				}
				String howDetailsId =zuoybStudentWorkHowDetails.getHowDetailsId();
				if(zuoybStudentWorkHowDetails.getMemorize()!=null&&zuoybStudentWorkHowDetails.getMemorize()==1){
					memorize++;
					if(imgList!=null && imgList.size()>0){
						cuomemorize++;
						
						Integer changcuo = 1;
						if(cuomemorizeMap.containsKey(howDetailsId)){
							 changcuo =cuomemorizeMap.get(howDetailsId)+1;
						}
						cuomemorizeMap.put(howDetailsId, changcuo);
					}
				}
				if(zuoybStudentWorkHowDetails.getUnderstanding()!=null&&zuoybStudentWorkHowDetails.getUnderstanding()==1){
					understanding++;
					if(imgList!=null && imgList.size()>0){
						cuounderstanding++;
						Integer changcuo = 1;
						if(cuounderstandingMap.containsKey(howDetailsId)){
							 changcuo =cuounderstandingMap.get(howDetailsId)+1;
						}
						cuounderstandingMap.put(howDetailsId, changcuo);
					}
				}
				if(zuoybStudentWorkHowDetails.getApply()!=null&&zuoybStudentWorkHowDetails.getApply()==1){
					apply++;
					if(imgList!=null && imgList.size()>0){
						Integer changcuo = 1;
						if(cuoapplyMap.containsKey(howDetailsId)){
							 changcuo =cuoapplyMap.get(howDetailsId)+1;
						}
						cuoapplyMap.put(howDetailsId, changcuo);
						cuoapply++;
					}
				}
			}
		
		List<BgDetailsFeature> featureList =new ArrayList<BgDetailsFeature>(); 
		BgDetailsFeature memorizeFeature = new  BgDetailsFeature("记忆",memorize,cuomemorize);
		bgknowGet(memorizeFeature,cuomemorizeMap);
		BgDetailsFeature understandingFeature = new  BgDetailsFeature("理解",understanding,cuounderstanding);
		bgknowGet(understandingFeature,cuounderstandingMap);
		BgDetailsFeature applyFeature = new  BgDetailsFeature("运用",apply,cuoapply);
		bgknowGet(applyFeature,cuoapplyMap);
		featureList.add(applyFeature);
		featureList.add(memorizeFeature);
		featureList.add(understandingFeature);
		bgDetails.setFeatureList(featureList);//本月待加强的知识点
	}

	protected void bgknowGet(BgDetailsFeature detail,Map<String , Integer> map) {
		//排序后的常错的知识点（只取错题最多的5个）
		Map<String , Integer>  newMap=Collections3.sortByValue(map);
		List<String> ids  =new ArrayList<String>();
		int num=1;
		for (String in : newMap.keySet()) {
			if(num<=2){
				ids.add(in);
				break;
			}
			num++;
		}
		if(ids.size()>0){
			//常错的知识点
			List<Object[]> objList = zuoybKnowHowDetailsService.findKnowAndYdslByIds(ids);
			List<BgKnow> knowList = new ArrayList<BgKnow>();
			for(Object[] obj :objList){
				BgKnow know = new BgKnow();
				know.setKnowName(obj[0].toString());
				String ydsl = obj[1]==null?"":obj[1].toString();
				if(!"".equals(ydsl)){
					String[] strarr = ydsl.split("#N");
					know.setAdviceList(Arrays.asList(strarr));
				}
				knowList.add(know);
			}
			detail.setKnowList(knowList);
		}
	}
}
