package com.qxueyou.scc.school.service.impl; import java.net.URL; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.fasterxml.jackson.databind.ObjectMapper; import com.qxueyou.scc.admin.classes.model.ClsClass; //import com.qxueyou.scc.user.model.UserReWeixin; import com.qxueyou.scc.base.model.CacheConstants; //import com.qxueyou.scc.base.model.ONSMsg; import com.qxueyou.scc.base.model.Pager; import com.qxueyou.scc.base.model.Result; //import com.qxueyou.scc.base.service.ICacheService; import com.qxueyou.scc.base.service.impl.CommonAppService; //import com.qxueyou.scc.base.service.impl.CommonONSProducer; import com.qxueyou.scc.base.util.ClientUtils; import com.qxueyou.scc.base.util.CollectionUtils; import com.qxueyou.scc.base.util.CommonUtils; import com.qxueyou.scc.base.util.RSAUtils; import com.qxueyou.scc.base.util.TraceUtils; import com.qxueyou.scc.base.util.UUIDUtils; import com.qxueyou.scc.msg.model.MsgUser; //import com.qxueyou.scc.org.model.Organization; import com.qxueyou.scc.school.dao.SignDAO; import com.qxueyou.scc.school.model.ExportSchSignItem; import com.qxueyou.scc.school.model.SchClassSchedule; import com.qxueyou.scc.school.model.SchClassSubject; import com.qxueyou.scc.school.model.SchScheduleAddress; import com.qxueyou.scc.school.model.SchSign; import com.qxueyou.scc.school.model.SchSignCode; import com.qxueyou.scc.school.model.SchSignItem; import com.qxueyou.scc.school.model.SchSignOrder; import com.qxueyou.scc.school.model.SchSignStatistics; import com.qxueyou.scc.school.model.SignStatisResult; //import com.qxueyou.scc.school.service.IScoreChangeService; import com.qxueyou.scc.school.service.ISignService; import com.qxueyou.scc.user.model.User; import com.qxueyou.scc.user.model.UserRegistration; import com.qxueyou.scc.user.service.IUserService; //import com.qxueyou.scc.weixin.service.IWeixinCommonService; @Service public class SignService extends CommonAppService implements ISignService { private static final String late = "迟到"; private static final String normal = "正常"; private static Logger log = LogManager.getLogger("SignService"); private SignDAO signDAO; // // 签到上大屏 // @Autowired // IMsgVenderService easemobService; // // @Autowired // CommonONSProducer onsProducer; // // @Autowired // ICacheService cacheService; // /** 微信业务操作 **/ // @Autowired // IWeixinCommonService weixinCommonService; @Autowired IUserService userService; // @Autowired // IScoreChangeService scoreChangeService; ObjectMapper mapper = new ObjectMapper(); public SignDAO getSignDAO() { return signDAO; } /** * 依赖注入 * * @param interactDAO */ @Autowired(required = false) public void setSignDAO(@Qualifier("signDAO") SignDAO signDAO) { this.signDAO = signDAO; } @Override public Result insertSign(SchSign sign) { String signId = sign.getSignId(); if(StringUtils.isNoneBlank(signId)){ List lstSchSign = this.find("select s from SchSign s where s.classScheduleId = ? and s.deleteFlag is false and signId <> ?", CollectionUtils.newList(sign.getClassScheduleId(), signId), SchSign.class); if(lstSchSign != null && !lstSchSign.isEmpty()){ return new Result(false, "你选择的课程已经存在签到,请不要重复添加"); } SchSign objSchSign = this.read(SchSign.class, signId); objSchSign.setUpdateId(ClientUtils.getUserId()); objSchSign.setUpdateTime(new Date(System.currentTimeMillis())); objSchSign.setUpdator(ClientUtils.getUserName()); objSchSign.setStartTime(sign.getStartTime()); objSchSign.setEndTime(sign.getEndTime()); objSchSign.setRegisterAllow(sign.getRegisterAllow()); objSchSign.setOutRangeAllow(sign.getOutRangeAllow()); objSchSign.setValidatePhone(sign.getValidatePhone()); objSchSign.setOutRange(sign.getOutRange()); int icount = this.findCount("from SchSignStatistics s where s.signId = ? and s.deleteFlag is false", CollectionUtils.newList(objSchSign.getSignId())); if(icount == 0){ objSchSign.setSignType(sign.getSignType()); objSchSign.setClassScheduleId(sign.getClassScheduleId()); objSchSign.setName(sign.getName()); } save(objSchSign); // cacheService.set(CacheConstants.SCH_SIGN_ID_PREFIX.concat(signId), CacheConstants.SCH_SIGN_ID_TIME, objSchSign); }else{ List lstSchSign = this.find("select s from SchSign s where s.classScheduleId = ? and s.deleteFlag is false", CollectionUtils.newList(sign.getClassScheduleId()), SchSign.class); if(lstSchSign != null && !lstSchSign.isEmpty()){ return new Result(false, "你选择的课程已经存在签到,请不要重复添加"); } // 获取客户端信息 // 设置基本字段 String signCode = generateSignCode(ClientUtils.getClassId()); sign.setCreateId(ClientUtils.getUserId()); sign.setCreateTime(new Date(System.currentTimeMillis())); sign.setCreator(ClientUtils.getUserName()); sign.setDeleteFlag(false); sign.setUpdateId(ClientUtils.getUserId()); sign.setUpdateTime(new Date(System.currentTimeMillis())); sign.setUpdator(ClientUtils.getUserName()); sign.setClassId(ClientUtils.getClassId()); sign.setCourse(ClientUtils.getCourseName()); sign.setCode(signCode); sign.setHisShow(SchSign.SIGN_HIS_SHOW); sign.setActAllow(SchSign.SIGN_ACT_ALLOW); String uuidPwd = UUIDUtils.generateShortUuid(); MsgUser msgUser = new MsgUser(); msgUser.setUserId(UUIDUtils.generateUUID().replace("-", "")); msgUser.setPassword(RSAUtils.encrypt(uuidPwd)); // Result result = easemobService.addUser(msgUser); // if (result.isResult()) { // sign.setNoticeUserId(msgUser.getUserId()); // sign.setNoticePassword(RSAUtils.encrypt(uuidPwd)); // } //添加签到码 SchSignCode signCodeVO = new SchSignCode(); signCodeVO.setCode(signCode); signCodeVO.setClassId(ClientUtils.getClassId()); save(signCodeVO); save(sign); } return new Result(true, sign.getSignId()); } @Override public Result deleteSigns(String[] signIds) { String hql = "update SchSign set deleteFlag = true where signId=?"; return bulkUpdateInLoop(hql, signIds); } /** * 生成签到码 * @param classId 班级ID * @return */ private String generateSignCode(String classId){ String hql = "SELECT s.code FROM SchSignCode s where s.classId=?"; List args = new ArrayList(); args.add(classId); List codes = find(hql, args, String.class); String random = null; do{ random = String.valueOf((int)(Math.random()*9000) + 1000); }while(codes.contains(random)); return random; } @Override public Result insertSignItem(SchSign sign, String signAddress, Date signTime,String userId,String userName) { SchSignItem signItem = new SchSignItem(); // 获取当前用户 signItem.setSignId(sign.getSignId()); signItem.setDeleteFlag(false); signItem.setSignAddress(signAddress); signItem.setSignTime(signTime); signItem.setUserId(userId); signItem.setUserName(userName); // 公用配置 TraceUtils.setCreateTrace(signItem); this.save(signItem); return new Result(true); } @Override /** * 签到 */ public int insertSignOrder(SchSign signVO, Date signTime) { String hql = "from SchSignOrder where deleteFlag is false and signId=? "; // 该堂课已经签到多少位 int signCount = this.findCount(hql, CollectionUtils.newList(signVO.getSignId())); // 签到+1 signCount++; SchSignOrder signOrder = new SchSignOrder(); signOrder.setSignId(signVO.getSignId()); signOrder.setDeleteFlag(false); signOrder.setUserId(ClientUtils.getUserId()); signOrder.setUserName(ClientUtils.getUserName()); signOrder.setSignOrder(signCount); signOrder.setSignTime(signTime); // 公用配置 TraceUtils.setCreateTrace(signOrder); // 保存到db this.save(signOrder); return signCount; } /** * 得到签到明细 * @param signId * @return */ public List getSignItems(String signId){ List listResult = new ArrayList(); if(ClientUtils.getClassId() != null && StringUtils.isNotBlank(signId)){ String classId = ClientUtils.getClassId(); //SQL String strSQL = " SELECT TU.NAME AS userName,TS.START_TIME AS signTime,TS.END_TIME AS endTime FROM " + "(SELECT U.USER_ID,U.NAME FROM USER_REGISTRATION R,USER U WHERE U.USER_ID = R.USER_ID AND U.DELETE_FLAG = 0 AND R.DELETE_FLAG = 0 AND R.CLASS_ID = ? ) TU " + "LEFT JOIN " + "( SELECT S.USER_ID AS USER_ID ,MIN(S.SIGN_TIME) AS START_TIME,MAX(S.SIGN_TIME) AS END_TIME FROM SCH_SIGN_ITEM S " + "WHERE S.SIGN_ID = ? GROUP BY S.USER_ID HAVING COUNT(1) > 1 " + "UNION ALL " + "SELECT T.USER_ID AS USER_ID , " + "CASE WHEN ABS(TIMEDIFF(T.TIME,S.START_TIME)) <= ABS(TIMEDIFF(T.TIME,S.END_TIME)) THEN T.TIME ELSE NULL END START_TIMEM, " + "CASE WHEN ABS(TIMEDIFF(T.TIME,S.START_TIME)) > ABS(TIMEDIFF(T.TIME,S.END_TIME)) THEN T.TIME ELSE NULL END END_TIME " + "FROM SCH_SIGN S , " + "( SELECT S.USER_ID,S.SIGN_ID,MAX(S.SIGN_TIME) AS TIME FROM SCH_SIGN_ITEM S " + "WHERE S.SIGN_ID = ? GROUP BY S.USER_ID,S.SIGN_ID HAVING COUNT(1) = 1 ) T WHERE S.SIGN_ID = T.SIGN_ID " + ")TS " + "ON TS.USER_ID = TU.USER_ID " + "ORDER BY TS.START_TIME IS NULL , TS.START_TIME ASC "; listResult = signDAO.querySignItemList(strSQL, CollectionUtils.newList(classId,signId,signId)); }else{ log.error("查询签到明细失败,参数不正确:cls=".concat(ClientUtils.getClassId()).concat(";signId=").concat(signId)); } return listResult; } /** * 有一个时分秒的问题:只需要检测到分钟:9:00是标准时间 9:00:59 仍然是正常 * @param realTime * @param standardTime * @return */ private String getStartStatus(Date realTime,Date standardTime){ String status = ""; if(null != realTime && null != standardTime){ Date real = DateUtils.truncate(realTime, Calendar.MINUTE); Date standard = DateUtils.truncate(standardTime, Calendar.MINUTE); status = real.compareTo(standard) == 1 ? late :normal; } return status; } /** * 有一个时分秒的问题:只需要检测到分钟: * @param realTime * @param standardTime * @return */ private String getEndStatus(Date realTime,Date standardTime){ String status = ""; if(null != realTime && null != standardTime){ Date real = DateUtils.truncate(realTime, Calendar.MINUTE); Date standard = DateUtils.truncate(standardTime, Calendar.MINUTE); status = real.compareTo(standard) == -1 ? "早退" :normal; } return status; } /** * 插入签到统计信息 */ public SignStatisResult insertSignStatistics(SchSign sign, String signAddress, Date signTime,Short terminalType,String userId,String userName,String mobilePhone, String location) { User user = this.read(User.class, userId); //判断签到类型,1:仅上课签到;2:上下课都需签到 SignStatisResult result = new SignStatisResult(); short signType = sign.getSignType(); if(SchSign.SIGN_TYPE_FIRST == signType){ result = insertSignFirst(sign,signAddress,signTime,terminalType,userId,user.getName(),mobilePhone, location); }else if(SchSign.SIGN_TYPE_ALL == signType){ result = insertSignAll(sign,signAddress,signTime,terminalType,userId,user.getName(),mobilePhone, location); }else if(SchSign.SIGN_TYPE_ACTIVITY == signType){ result = insertActivitySign(sign,signAddress,signTime,terminalType,userId,user.getName(),mobilePhone); } if(result.getSignType() == null){ result.setSignType(Integer.valueOf(signType)); } return result; } /** * 查询签到当天的课次 * * @param signId * @return */ public SchClassSchedule getSchClassSchedule(String signId){ String hql = "select e from SchClassSchedule e, SchSign s, SchClassSubject su where s.signId = ? and su.classSubjectId = e.classSubjectId and su.deleteFlag is false " + " and s.classScheduleId = e.classSubjectId and date(e.startTime) = date(now()) and e.deleteFlag is false"; return this.findUnique(hql, CollectionUtils.newList(signId), SchClassSchedule.class); } /** * 插入签到 * * @param signVO * @param signAddress * @param userId * @param userName * @param mobilePhone * @return */ public SignStatisResult insertSignStatistics(SchSign signVO, String signAddress, String userId, String userName, String mobilePhone, short type){ // 签到时间 Date signTime= new Date(System.currentTimeMillis()); String strAddress = this.getAddress(signAddress); //3. 插入签到统计 SignStatisResult result = this.insertSignStatistics(signVO, strAddress, signTime,type ,userId,userName,mobilePhone, signAddress); if(!result.getResult()){ return new SignStatisResult(false,result.getErrMsg()); } // 2.插入签到历史记录 this.insertSignItem(signVO, signAddress, signTime,ClientUtils.getUserId(),ClientUtils.getUserName()); List schSignStatisticss = this.queryPageLstSignStatistics(result.getSignStatistics(), null, result.getSignType(), signVO.getSignId()); for(SchSignStatistics obj : schSignStatisticss){ obj.setSignType(result.getSignType()); } //查询班主任名字 ClsClass objOrgClass = this.read(ClsClass.class, signVO.getClassId()); result.setSignAddr(strAddress); result.setSignStatisticss(schSignStatisticss); //2015-08-10增加返回是否班级成员 result.setRegFlag(this.queryRegistrationFlag(ClientUtils.getUserId(), signVO.getClassId())); result.setClassCharger(objOrgClass.getClassCharger()); return result; } /** * 根据经纬度获取地址 * @param location * @return */ @SuppressWarnings("rawtypes") private String getAddress(String location){ try { if(StringUtils.isEmpty(location)){ return ""; } Map map = mapper.readValue(new URL("http://api.map.baidu.com/geocoder/v2/?coordtype=wgs84ll&output=json&ak=gy9dG5lb73GIQIQ5w9ebcorY&location="+location), HashMap.class); Map result = (Map) map.get("result"); String formatted_address = result.get("formatted_address").toString(); String sematic_address = result.get("sematic_description").toString(); if(StringUtils.isNotBlank(sematic_address)){ formatted_address = formatted_address.concat("(").concat(sematic_address).concat(")"); } return formatted_address; } catch (Exception e) { log.error(e,e); } return ""; } /** * 活动签到,插入签到统计信息(上课,只有第一次插入记录) * @param sign * @param signAddress * @param signTime * @param terminalType * @return */ private SignStatisResult insertActivitySign(SchSign sign, String signAddress, Date signTime,Short terminalType,String userId,String userName,String mobilePhone){ int signOrder = 0; SignStatisResult result = new SignStatisResult(); //1.查询是否已签到,查询当天签到情况 //获取当天用户是否签到 //1.查询是否已签到,查询当天签到情况 String hql = "from SchSignStatistics where deleteFlag is false and signId = ? and userId = ?"; SchSignStatistics objSchSignStatistics = findUnique(hql,CollectionUtils.newList(sign.getSignId(), userId),SchSignStatistics.class); //第一次保存,以后不更新,已最早时间为准(每次更新最新签到地址) if(null != objSchSignStatistics){ signOrder = objSchSignStatistics.getFirstSignOrder(); objSchSignStatistics.setTerminalType(terminalType); objSchSignStatistics.setStatisticsFlag(SchSignStatistics.STATISTICS_FLAG_YES); objSchSignStatistics.setSignAddress(signAddress); save(objSchSignStatistics); result.setSignStatistics(objSchSignStatistics); }else{ // 已经签到个数 String hql1 = "from SchSignStatistics where deleteFlag is false and signId = ?"; int signCount = findCount(hql1,CollectionUtils.newList(sign.getSignId())); signOrder = signCount + 1; SchSignStatistics obj = new SchSignStatistics(); TraceUtils.setCreateTrace(obj); obj.setSignId(sign.getSignId()); obj.setSignAddress(signAddress); obj.setSignDate(new Date()); obj.setTerminalType(terminalType); obj.setFirstSignOrder(signOrder); obj.setFirstSignTime(signTime); if(normal.equals(getStartStatus(signTime,sign.getStartTime()))){ obj.setFirstSignStatus(SchSignStatistics.SIGN_STATUS_NORMAL); }else{ obj.setFirstSignStatus(SchSignStatistics.SIGN_STATUS_LATE); } obj.setUserId(userId); obj.setStatisticsFlag(SchSignStatistics.STATISTICS_FLAG_YES); obj.setUserName(userName); obj.setMobilePhone(mobilePhone); obj.setInstallFlag(queryInstallFlag(userId)); obj.setRegisteFlag(queryRegistrationFlag(userId,sign.getClassId())); //第一次保存 save(obj); result.setSignStatistics(obj); } result.setSignIndex(signOrder); result.setSignType(SignStatisResult.SIGN_TYPE_ACTIVITY); result.setResult(true); return result; } /** * 是否超过签到限制距离 * * @param signVO * @param signAddress * @return */ private Result isOutofRange(SchSign signVO, String signAddress, SchClassSchedule objSchClassSchedule, boolean activeFlag, SchSignStatistics objSchSignStatistics){ int outRangeAllow = signVO.getOutRangeAllow(); objSchSignStatistics.setStatisticsFlag(SchSignStatistics.STATISTICS_FLAG_YES); if(outRangeAllow == SchSign.SIGN_ACT_ALLOW || signVO.getOutRange() == 0 || SchClassSchedule.SCH_NETWORK.equals(objSchClassSchedule.getMode())){ return new Result(true); } if(StringUtils.isBlank(signAddress)){ return new Result(false, "签到失败,未获取到签到地址,请确认是否开启定位"); } SchScheduleAddress objSchScheduleAddress = this.read(SchScheduleAddress.class, objSchClassSchedule.getAddressId()); if(objSchScheduleAddress == null){ return new Result(false, "签到失败,课程签到地址设置错误,请联系班主任修正签到地址"); } if(StringUtils.isBlank(objSchScheduleAddress.getLatitudeY()) || StringUtils.isBlank(objSchScheduleAddress.getLongitudeX())){ return new Result(false, "签到失败,课程签到地址设置错误,请联系班主任修正签到地址"); } String[] signAddresss = signAddress.split(","); double range = CommonUtils.GetDistance(Double.valueOf(signAddresss[1]), Double.valueOf(signAddresss[0]), Double.valueOf(objSchScheduleAddress.getLongitudeX()), Double.valueOf(objSchScheduleAddress.getLatitudeY())); boolean b = range*1000 lstSchSignStatistics = cacheService.get("SIGN_HISTORY_".concat(sign.getSignId()), List.class); List lstSchSignStatistics=null; int signCount = 0; if(lstSchSignStatistics == null){ String hql1 = "from SchSignStatistics where deleteFlag is false and signId = ? and date(signDate) = date(now())"; // 已经签到个数 signCount = findCount(hql1,CollectionUtils.newList(sign.getSignId())); }else{ signCount = lstSchSignStatistics.size(); } //第一次保存,以后不更新,已最早时间为准(每次更新最新签到地址) if(null == objSchSignStatistics){ //查询课程信息 SchClassSubject objSchClassSubject = this.getCommonDAO().read(SchClassSubject.class, sign.getClassScheduleId()); signOrder = signCount + 1; objSchSignStatistics = new SchSignStatistics(); TraceUtils.setCreateTrace(objSchSignStatistics); objSchSignStatistics.setSignId(sign.getSignId()); objSchSignStatistics.setSignAddress(signAddress); objSchSignStatistics.setSignDate(new Date()); if(objSchClassSubject != null){ objSchSignStatistics.setClassSubjectId(objSchClassSubject.getClassSubjectId()); objSchSignStatistics.setClassSubjectName(objSchClassSubject.getName()); } objSchSignStatistics.setTerminalType(terminalType); objSchSignStatistics.setFirstSignOrder(signOrder); objSchSignStatistics.setFirstSignTime(signTime); if(normal.equals(getStartStatus(signTime,objSchClassSchedule.getStartTime()))){ objSchSignStatistics.setFirstSignStatus(SchSignStatistics.SIGN_STATUS_NORMAL); }else{ objSchSignStatistics.setFirstSignStatus(SchSignStatistics.SIGN_STATUS_LATE); } objSchSignStatistics.setUserId(userId); objSchSignStatistics.setUserName(userName); objSchSignStatistics.setMobilePhone(mobilePhone); objSchSignStatistics.setInstallFlag(queryInstallFlag(userId)); objSchSignStatistics.setRegisteFlag(activeFlag); //第一次保存 } Result isOutofRange = this.isOutofRange(sign, location, objSchClassSchedule, activeFlag, objSchSignStatistics); if(!isOutofRange.isSuccess()){ result.setErrMsg(isOutofRange.getMsg()); result.setResult(false); return result; } if(objSchSignStatistics.getFirstSignOrder() == null){ signOrder = signCount; }else{ signOrder = objSchSignStatistics.getFirstSignOrder(); } if(objSchSignStatistics.getFirstSignTime() == null){ objSchSignStatistics.setFirstSignTime(signTime); if(normal.equals(getStartStatus(signTime,objSchClassSchedule.getStartTime()))){ objSchSignStatistics.setFirstSignStatus(SchSignStatistics.SIGN_STATUS_NORMAL); }else{ objSchSignStatistics.setFirstSignStatus(SchSignStatistics.SIGN_STATUS_LATE); } objSchSignStatistics.setFirstSignOrder(signOrder); } objSchSignStatistics.setTerminalType(terminalType); objSchSignStatistics.setSignAddress(signAddress); objSchSignStatistics.setPosition(location); save(objSchSignStatistics); result.setErrMsg(isOutofRange.getMsg()); result.setSignStatistics(objSchSignStatistics); result.setSignIndex(signOrder); result.setRange(objSchSignStatistics.getOutOfRange()); result.setResult(true); return result; } /** * 获取当天是否已经签到 * * @param signId * @return */ public SchSignStatistics getSchSignStatistics(String signId, String userId){ //1.查询是否已签到,查询当天签到情况 String hql = "from SchSignStatistics where deleteFlag is false and signId = ? and userId = ? and date(signDate) = date(now())"; return findUnique(hql,CollectionUtils.newList(signId, userId),SchSignStatistics.class); } /** * 上下课都需签到时,插入签到统计信息 * 上课签到:调用insertSignFirst() * 下课签到:每次更新,按下课签到时间倒序排列 * @param sign * @param signAddress * @param signTime * @param terminalType * @return */ private SignStatisResult insertSignAll(SchSign sign, String signAddress, Date signTime,Short terminalType,String userId,String userName,String mobilePhone, String location){ SignStatisResult result = new SignStatisResult(); //1.判断当前签到是上课,else:下课签到 //精确到分钟比较 //获取签到码当天签到的课程 SchClassSchedule objSchClassSchedule = this.getSchClassSchedule(sign.getSignId()); if(objSchClassSchedule == null){ result.setErrMsg("今天该课程未开课,不需要签到"); result.setResult(false); return result; } boolean activeFlag = queryActiveflag(userId,sign.getClassId()); if(sign.getRegisterAllow() == 1 && !activeFlag){ result.setErrMsg("签到失败,您还未加入该班级"); result.setResult(false); return result; } Date startDate = DateUtils.truncate(objSchClassSchedule.getStartTime(), Calendar.MINUTE); Date endDate = DateUtils.truncate(objSchClassSchedule.getEndTime(), Calendar.MINUTE); Date signDate = DateUtils.truncate(signTime, Calendar.MINUTE); if((endDate.getTime() + startDate.getTime())/2 >= signDate.getTime()){ result.setSignType(SignStatisResult.SIGN_TYPE_FIRST); //插入上课签到信息 result = insertSignFirst(sign,signAddress,signTime,terminalType,userId,userName,mobilePhone, location); }else{ result.setSignType(SignStatisResult.SIGN_TYPE_LAST); SchSignStatistics obj = this.getSchSignStatistics(sign.getSignId(), userId); if(null != obj){ obj.setLastSignTime(signTime); if(normal.equals(getEndStatus(signTime,objSchClassSchedule.getEndTime()))){ obj.setLastSignStatus(SchSignStatistics.SIGN_STATUS_NORMAL); }else{ obj.setLastSignStatus(SchSignStatistics.SIGN_STATUS_EARLY); } //每次更新 obj.setUserName(userName); obj.setInstallFlag(queryInstallFlag(userId)); obj.setRegisteFlag(activeFlag); obj.setTerminalType(terminalType); obj.setSignAddress(signAddress); obj.setPosition(location); Result isOutofRange = this.isOutofRange(sign, location, objSchClassSchedule, activeFlag, obj); if(!isOutofRange.isSuccess()){ result.setErrMsg(isOutofRange.getMsg()); result.setResult(false); return result; } save(obj); result.setSignStatistics(obj); result.setRange(obj.getOutOfRange()); result.setErrMsg(isOutofRange.getMsg()); }else{ //查询课程信息 SchClassSubject objSchClassSubject = this.getCommonDAO().read(SchClassSubject.class, sign.getClassScheduleId()); //否则第一次下课签到 SchSignStatistics objNew = new SchSignStatistics(); TraceUtils.setCreateTrace(objNew); objNew.setSignId(sign.getSignId()); objNew.setSignAddress(signAddress); objNew.setTerminalType(terminalType); objNew.setLastSignTime(signTime); if(objSchClassSubject != null){ objNew.setClassSubjectId(objSchClassSubject.getClassSubjectId()); objNew.setClassSubjectName(objSchClassSubject.getName()); } objNew.setSignDate(new Date()); if(normal.equals(getEndStatus(signTime,objSchClassSchedule.getEndTime()))){ objNew.setLastSignStatus(SchSignStatistics.SIGN_STATUS_NORMAL); }else{ objNew.setLastSignStatus(SchSignStatistics.SIGN_STATUS_EARLY); } objNew.setInstallFlag(queryInstallFlag(userName)); objNew.setRegisteFlag(activeFlag); objNew.setSignAddress(signAddress); objNew.setPosition(location); objNew.setUserId(userId); objNew.setUserName(userName); objNew.setMobilePhone(mobilePhone); Result isOutofRange = this.isOutofRange(sign, location, objSchClassSchedule, activeFlag, objNew); if(!isOutofRange.isSuccess()){ result.setErrMsg(isOutofRange.getMsg()); result.setResult(false); return result; } //第一次保存 save(objNew); result.setSignStatistics(objNew); result.setRange(objNew.getOutOfRange()); result.setErrMsg(isOutofRange.getMsg()); } } result.setResult(true); return result; } /** * 查询是否安装(通过账号登录记录) */ public boolean queryInstallFlag(String userId){ String hql = "from UserOperate where deleteFlag is false and userId= ? "; int iCount = findCount(hql,CollectionUtils.newList(userId)); return iCount > 0 ? true : false; } /** * 查询是否班级成员(通过账号登录记录) */ public boolean queryRegistrationFlag(String userId,String classId){ String hql = "from UserRegistration where deleteFlag is false and userId= ? and classId = ? "; int iCount = findCount(hql,CollectionUtils.newList(userId,classId)); return iCount > 0 ? true : false; } /** * 查询是否班级激活 */ public boolean queryActiveflag(String userId,String classId){ String hql = "from UserRegistration where deleteFlag is false and userId= ? and classId = ? and status = ?"; int iCount = findCount(hql,CollectionUtils.newList(userId,classId, UserRegistration.STATUS_ACTIVE)); return iCount > 0 ? true : false; } /** * 得到满足要求的签到明细(优化版本) * @param signId * @return */ public List getSimpleSignItems(String signId, String signDate){ return getHandleStatistics(signId, signDate); } /** * 查询 * * @param signId * @param signDate * @return */ public List getNotSignUser(String signId, String signDate){ SchSign objSchSign = this.read(SchSign.class, signId); String strDate = StringUtils.isBlank(signDate)? com.qxueyou.scc.base.util.DateUtils.getToday():signDate; String hql = "select s,u.attribute1 from SchSignStatistics s , User u " + " where s.deleteFlag is false and u.deleteFlag is false and s.userId = u.userId and s.signId = ? and s.statisticsFlag = ? and s.registeFlag is true" + (objSchSign.getSignType() == SchSign.SIGN_TYPE_ACTIVITY?"":" and date(s.signDate) = date('"+strDate+"')")+" order by s.firstSignOrder asc nulls last"; List lstStatistics = this.signDAO.querySchSignStatisticses(hql, CollectionUtils.newList(signId, 2)); //查询,SQL会清晰 String hql0 = " select r.USER_ID as userId,r.user_name as userName,r.mobile_phone as mobilePhone ,case when o.user_id is not null then 1 else 0 end installFlag,u.attribute1 as companyName from user_registration r " + " left join " + " user_operate o " + " on r.USER_ID = o.USER_ID " + " left join user u" + " on u.USER_ID = r.USER_ID" + " WHERE " + " r.USER_ID not in (select user_id from sch_sign_statistics s where s.sign_id = ? and delete_flag = 0"+ (objSchSign.getSignType() == SchSign.SIGN_TYPE_ACTIVITY?"":" and date(s.sign_Date) = date('"+strDate+"')")+") " + " and r.DELETE_FLAG = 0 and r.STATUS = ? and IFNULL(O.DELETE_FLAG,0) = 0 and r.CLASS_ID = ? and date(r.activation_Time) <= date(?)" ; List lstStatistics0 = signDAO.querySignItemListNew(hql0, CollectionUtils.newList(signId,UserRegistration.STATUS_ACTIVE,ClientUtils.getClassId(), strDate)); if(null == lstStatistics || lstStatistics.isEmpty()){ return lstStatistics0; } lstStatistics.addAll(lstStatistics0); return lstStatistics; } /** * 导出(优化版本) * @param signId * @param objSchSign * @return */ public List exportSimpleItems(String signId, String signDate){ //查询列表的数据 List lstStatistics = getHandleStatistics(signId, signDate); List lstExports = new ArrayList(); ExportSchSignItem item = null; for(SchSignStatistics statistics : lstStatistics){ item = new ExportSchSignItem(); item.setInstallFlag("123"); item.setEndStatus(null == statistics.getLastSignStatus() ? "" : getStatusValue(statistics.getLastSignStatus())); item.setEndTime(statistics.getLastSignTime()); item.setInstallFlag(statistics.getInstallValue()); item.setMobilePhone(statistics.getMobilePhone()); item.setRegisteFlag(statistics.getRegisteValue()); item.setSignAddress(statistics.getSignAddress()); item.setSignOrder(statistics.getFirstSignOrder()); item.setSignStatus(null == statistics.getFirstSignStatus() ? "" : getStatusValue(statistics.getFirstSignStatus())); item.setSignTime(statistics.getFirstSignTime()); item.setUserName(statistics.getUserName()); lstExports.add(item); } return lstExports; } private String getStatusValue(short status){ String value = ""; switch(status){ case SchSignStatistics.SIGN_STATUS_NORMAL : value = normal; break; case SchSignStatistics.SIGN_STATUS_LATE : value = late; break; case SchSignStatistics.SIGN_STATUS_EARLY : value = "早退"; break; case SchSignStatistics.SIGN_STATUS_NO : value = "未签到"; break; default: value = "签到异常"; break; } return value; } private List getHandleStatistics(String signId, String signDate){ SchSign objSchSign = this.read(SchSign.class, signId); String strDate = StringUtils.isBlank(signDate)?com.qxueyou.scc.base.util.DateUtils.getToday():signDate; String hql = "select s,u.attribute1 from SchSignStatistics s , User u " + " where s.deleteFlag is false and u.deleteFlag is false and s.userId = u.userId and s.signId = ?" + (objSchSign.getSignType() == SchSign.SIGN_TYPE_ACTIVITY?"":" and s.statisticsFlag = 1 and date(s.signDate) = date('"+strDate+"')")+" order by s.firstSignOrder asc nulls last"; return this.signDAO.querySchSignStatisticses(hql, CollectionUtils.newList(signId)); } @Override public List querySignItemListStat(String hql, List args) { return signDAO.querySignItemListStat(hql, args); } @Override public List querySignItemListCom(String hql, List args) { return signDAO.querySignItemListCom(hql, args); } /** * 签到历史 * @return */ @Override public List> querySignHistory(final String hql, final Pager page, final List args){ return signDAO.querySignHistoryList(hql, page, args); } /** * 微信签到高级设置 * @param sign * @return */ public Result updateSign(SchSign sign) { SchSign objSign = this.read(SchSign.class, sign.getSignId()); if(StringUtils.isNotBlank(sign.getName())){ objSign.setName(sign.getName()); } if(null != sign.getStartTime() && null != sign.getEndTime() ){ objSign.setStartTime(sign.getStartTime()); objSign.setEndTime(sign.getEndTime()); } if(null!=sign.getHisShow()){ objSign.setHisShow(sign.getHisShow()); } if(null!=sign.getActAllow()){ objSign.setActAllow(sign.getActAllow()); } if(null!=sign.getPayAllow()){ objSign.setPayAllow(sign.getPayAllow()); } if(null!=sign.getNameShow()){ objSign.setNameShow(sign.getNameShow()); } if(null!=sign.getPhoneShow()){ objSign.setPhoneShow(sign.getPhoneShow()); } if(null!=sign.getOrgShow()){ objSign.setOrgShow(sign.getOrgShow()); } // 获取客户端信息 objSign.setUpdateId(ClientUtils.getUserId()); objSign.setUpdateTime(new Date(System.currentTimeMillis())); objSign.setUpdator(ClientUtils.getUserName()); save(objSign); //更新缓存 // cacheService.set(CacheConstants.SCH_SIGN_ID_PREFIX.concat(objSign.getSignId()), CacheConstants.SCH_SIGN_ID_TIME, objSign); return new Result(true); } /** * 签到 发送消息,环信替代 * @param signType * @param signIndex * @param signId * @return */ @SuppressWarnings("unused") public Result updateSignMessage(Integer signType,Integer signIndex, String signId, User user){ SchSign schSign = this.getSignFromCacheOrDB(signId); Map extra = new HashMap(); extra.put("title", "签到"); extra.put("userId", user.getUserId()); extra.put("userName", user.getName()); extra.put("userImg", user.getImgPath()); extra.put("mobilePhone", user.getMobilePhone()); extra.put("signIndex", String.valueOf(signIndex)); extra.put("signId", signId); // easemobService.doSendTextMsgToUsers("notice-sys", new String[]{schSign.getNoticeUserId()}, "用户签到", extra); return new Result(true) ; } /** * 初始化签到信息 * @param signId * @param userId * @param initType * @return */ public Result doInitSignDatas(String signId, String userId,int initType){ if( 1 == initType ){ String hql = "from SchSignOrder s where s.signId = ? and s.userId = ? "; List orders = this.find(hql, CollectionUtils.newList(signId,userId), SchSignOrder.class); if(orders.size()>1){ SchSignOrder first = orders.get(0); SchSignOrder second = orders.get(1); first.setDeleteFlag(false); second.setDeleteFlag(true); this.save(first); this.save(second); } }else if( 2 == initType ){ String hql = "from SchSignStatistics s where s.signId = ? and s.userId = ? "; List statisticses = this.find(hql, CollectionUtils.newList(signId,userId), SchSignStatistics.class); if(statisticses.size()>1){ SchSignStatistics first = statisticses.get(0); SchSignStatistics second = statisticses.get(1); first.setDeleteFlag(false); second.setDeleteFlag(true); this.save(first); this.save(second); } } return new Result(true); } /** * 根据课程信息获取签到信息 * * @param strClassSubjectId * @return */ public List querySign(String strClassSubjectId){ String hql = "from SchSign s where s.classScheduleId = ? and s.deleteFlag is false"; return this.find(hql, CollectionUtils.newList(strClassSubjectId), SchSign.class); } /** * 根据课程信息获取签到人员记录 * * @param strClassSubjectId * @return */ public List queryUserSign(String strClassSubjectId){ String hql = "select u from SchSignStatistics u where u.signId in( select s.signId from SchSign s" + " where s.classScheduleId = ? and s.deleteFlag is false) and u.deleteFlag is false and statisticsFlag = ? and date(u.signDate) = date(now())"; return this.find(hql, CollectionUtils.newList(strClassSubjectId, SchSignStatistics.STATISTICS_FLAG_YES), SchSignStatistics.class); } /** * 查询签到历史 * @param hql * @param args * @param page * @return */ @SuppressWarnings("unused") public List queryPageLstSignStatistics(SchSignStatistics objSignStatistics, Pager page,Integer signType,String signId){ String cache = "SIGN_HISTORY_".concat(signId).concat("_").concat(String.valueOf(signType)); // List lstSchSignStatistics = cacheService.get(cache, List.class); List lstSchSignStatistics = null; if(lstSchSignStatistics != null && !lstSchSignStatistics.isEmpty()){ if(!lstSchSignStatistics.contains(objSignStatistics)){ lstSchSignStatistics.add(objSignStatistics); }else if(signType == SignStatisResult.SIGN_TYPE_LAST){ lstSchSignStatistics.set(lstSchSignStatistics.indexOf(objSignStatistics), objSignStatistics); } // cacheService.set(cache, CacheConstants.BUSINESS_DATA_TIME, lstSchSignStatistics); return lstSchSignStatistics; } StringBuffer sb = new StringBuffer(512); // 4.查询签到名次 sb.append("select s, u.imgPath from SchSignStatistics s, User u where "); sb.append(" s.userId=u.userId and s.deleteFlag is false and s.signId = ? "); //根据类型判断排序规则 if(signType == null || SchSign.SIGN_TYPE_ALL == signType){ sb.append(" and date(s.signDate) = date(NOW()) and s.lastSignTime is not null order by s.lastSignTime desc "); }else if(SchSign.SIGN_TYPE_FIRST == signType){ sb.append(" and date(s.signDate) = date(NOW()) and s.firstSignTime is not null order by s.firstSignOrder asc "); }else{ sb.append(" order by s.firstSignTime asc "); } Pager currPage = page ; if( null == currPage ){ currPage = new Pager(); currPage.setPageNum(1); currPage.setPageSize(200); } // 查询并且缓存 List lstData = this.querySignItemListStat(sb.toString(), CollectionUtils.newList(signId)); // cacheService.set(cache, CacheConstants.BUSINESS_DATA_TIME, lstData); return lstData ; } /** * 签到,根据signId得到schSign * @param signId * @return */ @SuppressWarnings("unused") public SchSign getSignFromCacheOrDB(String signId){ // SchSign sign = cacheService.get(CacheConstants.SCH_SIGN_ID_PREFIX.concat(signId), SchSign.class); SchSign sign = null; if( null != sign ){ return sign ; } sign = this.read(SchSign.class, signId); // if(null != sign){ // cacheService.set(CacheConstants.SCH_SIGN_ID_PREFIX.concat(signId), CacheConstants.SCH_SIGN_ID_TIME, sign); // } return sign ; } /** * 签到对应活动,根据signId得到相对应的活动 * @param signId * @return */ // public Activitys getActivityFromCacheOrDB(String signId){ // // Activitys acts = cacheService.get(CacheConstants.SCH_SIGN_ACTIVITY_PREFIX.concat(signId), Activitys.class); // // if( null != acts ){ // return acts ; // } // // String hql = " from Activitys where signId = ? and deleteFlag is false "; // acts = findUnique(hql, CollectionUtils.newList(signId), Activitys.class); // // if(null != acts){ // cacheService.set(CacheConstants.SCH_SIGN_ACTIVITY_PREFIX.concat(signId), CacheConstants.SCH_SIGN_ACTIVITY_TIME, acts); // } // // return acts ; // // } /** * 根据sign得到相对应的机构图像 * @param signId * @return */ public String getOrgLogoFromCacheOrDB(SchSign sign){ // String orgLogo = cacheService.get(CacheConstants.SCH_SIGN_ORG_PREFIX.concat(sign.getSignId()), String.class); // if( null != orgLogo ){ // return orgLogo ; // } // OrgClass cls = read(OrgClass.class, sign.getClassId()); // Organization org = read(Organization.class, cls.getOrgCollegeCourse().getOrganizationId()); // if(null != org && StringUtils.isNotBlank(org.getLogoPath())){ // cacheService.set(CacheConstants.SCH_SIGN_ORG_PREFIX.concat(sign.getSignId()), CacheConstants.SCH_SIGN_ORG_TIME, org.getLogoPath()); // } // return null == org.getLogoPath() ? "" : org.getLogoPath() ; return null; } public Result sendSignQueueMsg(String args){ // 延时一分钟发送 // ONSMsg msg = new ONSMsg(onsProducer.getTopic()); // msg.put("msgType", "SCH_SIGN_QUEUE"); // msg.put("args", args); // // try { // // onsProducer.sendMsg(msg); // return new Result(true); // // } catch (Exception e) { // log.error("call sendSignQueueMsg fail.regId: " , e); // } return new Result(false); } /** * 签到异步处理部分代码 * * @param strArgs json对象 * @return */ @SuppressWarnings("unused") public Result doHandleSignQueueMsg(String strArgs){ if(StringUtils.isEmpty(strArgs)){ return null; } JSONObject args = JSON.parseObject(strArgs); String source = args.getString("source"); String userId = args.getString("userId"); String userName = args.getString("userName"); String signId = args.getString("signId"); String mobilePhone = args.getString("mobilePhone"); String userImg = args.getString("userImg"); Integer signType = args.getInteger("signType"); Integer signIndex = args.getInteger("signIndex"); String inputCode = args.getString("inputCode"); String openId = args.getString("openId"); // if(StringUtils.isNotBlank(inputCode) && StringUtils.isNotBlank(openId)){ // // // 查询并更新绑定关系 // UserReWeixin weixin = weixinCommonService.queryUserReWxByOpenId(openId); // if(weixin == null){ // weixinCommonService.saveUserReWeixin(openId, userId, source); // }else{ // weixinCommonService.updateUserReWeixin(openId, userId, source); // } // } //签到积分 // scoreChangeService.doSign(userId, signId); //签到大屏,发送消息 User user = new User(); user.setName(userName); user.setUserId(userId); user.setMobilePhone(mobilePhone); user.setImgPath(userImg); this.updateSignMessage(signType,signIndex,signId, user); return null ; } /** * 通过openId得到user * @param openId * @return */ public User getUserFromOpenId(String openId){ User user = null; // // 通过openId找user // if(StringUtils.isNotBlank(openId)){ // // // 查询绑定关系 // UserReWeixin weixin = weixinCommonService.queryUserReWxByOpenId(openId); // if (null != weixin) { // user = read(User.class, weixin.getUserId()); // } // } return user; } @SuppressWarnings("unused") @Override public List querySignItemListCom( String hql,List args,Pager page,Integer signType,String signId ) { Pager currPage = page ; if( null == currPage ){ currPage = new Pager(); currPage.setPageNum(1); currPage.setPageSize(200); } String cacheKey = CacheConstants.SCH_SIGN_STATISTICS_FIRST_ACTPAGE_PREFIX.concat(signId).concat("_") .concat(String.valueOf(currPage.getPageNum())).concat("_") .concat(String.valueOf(currPage.getPageSize())); // if(SignStatisResult.SIGN_TYPE_FIRST == signType){ // // 如果满一页取缓存 // Object obj = cacheService.get(cacheKey, Object.class); // if(null != obj ){ // return (List)obj; // } // } // 查询并且缓存 List lstData = signDAO.querySignItemListCom(hql, currPage, args); // 满一页数据缓存 // if(lstData.size() == currPage.getPageSize() ){ // cacheService.set(cacheKey, CacheConstants.SCH_SIGN_STATISTICS_FIRST_ACTPAGE_TIME, lstData); // } // return lstData ; } /** * 未签到统计页面 * * @param signId * @param signDate * @return */ public Result updateFlag(String signStatisticsIds){ if(StringUtils.isBlank(signStatisticsIds)){ return new Result(false, "参数错误"); } this.bulkUpdateInLoop("update SchSignStatistics s set s.statisticsFlag = 1 where s.signStatisticsId = ?", signStatisticsIds.split(",")); List lstSchSignStatistics = this.findByComplexHql("from SchSignStatistics s where s.signStatisticsId in(:signStatisticsIds)", CollectionUtils.newObjectMap("signStatisticsIds", signStatisticsIds.split(",")), SchSignStatistics.class); int firstCount = 0; int lastCount = 0; for(SchSignStatistics objSchSignStatistics : lstSchSignStatistics){ if(objSchSignStatistics.getFirstSignTime() != null){ firstCount ++; } if(objSchSignStatistics.getLastSignTime() != null){ lastCount ++; } } this.bulkUpdate( "update LessionSignStatistics s set s.firstSignUserCount = s.firstSignUserCount + ?,s.lastSignUserCount = s.lastSignUserCount + ?" + " where s.classSubjectId = ? and s.statisticsTime = ?", new Object[]{firstCount, lastCount, lstSchSignStatistics.get(0).getClassSubjectId(), lstSchSignStatistics.get(0).getSignDate()}); return new Result(true); } /** * 班级听课证签到 * * @param signVO * @param userId * @param type * @return */ public SignStatisResult doSignByClassCard(SchSign signVO, String userId){ User user = this.read(User.class, userId); //设置默认不控制距离和只能本班签到 signVO.setRegisterAllow(SchSign.SIGN_ACT_DISALLOW); signVO.setOutRangeAllow(SchSign.SIGN_ACT_ALLOW); //3. 插入签到统计 SignStatisResult result = this.insertSignStatistics(signVO, null, new Date(), SchSignStatistics.TERMINAL_TYPE_WECHAT, userId, user.getName(), user.getMobilePhone(), null); if(!result.getResult()){ return new SignStatisResult(false,result.getErrMsg()); } return result; } }