qinchao 4 gadi atpakaļ
vecāks
revīzija
429266e3b7

+ 15 - 154
examcloud-core-examwork-api-provider/src/main/java/cn/com/qmth/examcloud/core/examwork/api/controller/ExamController.java

@@ -26,7 +26,7 @@ import cn.com.qmth.examcloud.core.basic.api.response.GetOrgResp;
 import cn.com.qmth.examcloud.core.basic.api.response.GetOrgsResp;
 import cn.com.qmth.examcloud.core.examwork.api.controller.bean.CopyExamDomain;
 import cn.com.qmth.examcloud.core.examwork.api.controller.bean.ExamDomain;
-import cn.com.qmth.examcloud.core.examwork.api.controller.bean.ExamIpLimitDomain;
+import cn.com.qmth.examcloud.core.examwork.service.bean.ExamIpLimitInfo;
 import cn.com.qmth.examcloud.core.examwork.api.controller.bean.ExamOrgSettingsDomain;
 import cn.com.qmth.examcloud.core.examwork.api.controller.bean.StudentSpecialSettingsDomain;
 import cn.com.qmth.examcloud.core.examwork.base.enums.ExamProperty;
@@ -43,7 +43,6 @@ import cn.com.qmth.examcloud.core.oe.admin.api.request.CheckExamIsStartedReq;
 import cn.com.qmth.examcloud.core.oe.admin.api.response.CheckExamIsStartedResp;
 import cn.com.qmth.examcloud.support.cache.CacheHelper;
 import cn.com.qmth.examcloud.support.cache.bean.*;
-import cn.com.qmth.examcloud.support.enums.DataCategory;
 import cn.com.qmth.examcloud.support.privilege.PrivilegeDefine;
 import cn.com.qmth.examcloud.support.privilege.PrivilegeManager;
 import cn.com.qmth.examcloud.task.api.DataSyncCloudService;
@@ -62,7 +61,6 @@ import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.fileupload.disk.DiskFileItem;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.*;
 import org.springframework.data.domain.Sort.Direction;
@@ -113,9 +111,6 @@ public class ExamController extends ControllerSupport {
     @Autowired
     ExamStudentRepo examStudentRepo;
 
-    @Autowired
-    ExamIpLimitRepo examIpLimitRepo;
-
     @Autowired
     ExamStudentServiceImpl examStudentService;
 
@@ -1401,102 +1396,39 @@ public class ExamController extends ControllerSupport {
 
     @ApiOperation(value = "ip限制分页",notes = "ip限制分页")
     @GetMapping("ipLimited/page/{curPage}/{pageSize}")
-    public PageInfo<ExamIpLimitDomain> ipLimited(@PathVariable Integer curPage, @PathVariable Integer pageSize,
-                                                 Long examId, Integer limitType, String ip) {
-        PageInfo<ExamIpLimitEntity> pages = examService.pageIpLimited(curPage, pageSize, examId, limitType, ip);
-        PageInfo<ExamIpLimitDomain> pageInfo = new PageInfo<>();
-        List<ExamIpLimitDomain> list = new ArrayList<>();
-        pages.getList().forEach(e->{
-            ExamIpLimitDomain domain = new ExamIpLimitDomain();
-            BeanUtils.copyProperties(e,domain);
-            domain.setExamName(examRepo.getOne(examId).getName());
-            list.add(domain);
-        });
-        pageInfo.setList(list);
-        pageInfo.setTotal(pages.getTotal());
-        return pageInfo;
+    public PageInfo<ExamIpLimitInfo> ipLimited(@PathVariable Integer curPage, @PathVariable Integer pageSize,
+                                               Long examId, Integer limitType, String ip) {
+        return examService.pageIpLimited(curPage, pageSize, examId, limitType, ip);
     }
 
     @ApiOperation(value = "保存ip限制信息",notes = "保存ip限制")
     @PostMapping("ipLimited")
     public void save(String ids, @RequestBody ExamIpLimitEntity entity) {
-
-        //ids不为空,说明是批量设置限制类型
-        if (StringUtils.isNotBlank(ids)) {
-            List<Long> ipIds = getIdsByPath(ids);
-            if(entity.getLimitType()!=null){
-                examIpLimitRepo.updateLimitType(entity.getLimitType(),entity.getExamId(),ipIds);
-            }
-        } else {
-            Long id = entity.getId();
-            Date now = new Date();
-            //新增
-            if (id==null) {
-                entity.setCreationTime(now);
-                examIpLimitRepo.save(entity);
-            } else {
-                //更新
-                Optional<ExamIpLimitEntity> byId = examIpLimitRepo.findById(id);
-                if (byId.isPresent()){
-                    ExamIpLimitEntity ipLimitEntity = byId.get();
-                    if(StringUtils.isNotBlank(entity.getIp())){
-                        ipLimitEntity.setIp(entity.getIp());
-                    }
-                    if(entity.getLimitType()!=null){
-                        ipLimitEntity.setLimitType(entity.getLimitType());
-                    }
-                    ipLimitEntity.setUpdateTime(now);
-                    examIpLimitRepo.save(ipLimitEntity);
-                }
-            }
-
-        }
-
+        examService.saveIpLimit(ids, entity);
     }
 
     @ApiOperation(value = "根据主键删除ip限制",notes = "删除ip限制")
     @DeleteMapping("ipLimited/{ids}")
     public void delete(@PathVariable String ids) {
-        examIpLimitRepo.deleteByIds(getIdsByPath(ids));
-    }
-
-    private List<Long> getIdsByPath(String ids) {
-        return Stream.of(ids.split(",")).map(s -> Long.parseLong(s.trim()))
-                .collect(Collectors.toList());
+        examService.deleteIpLimit(ids);
     }
 
     @ApiOperation(value = "根据考试id批量删除ip限制",notes = "删除ip限制")
     @DeleteMapping("ipLimited/all/{examId}")
     public void delete(@PathVariable Long examId) {
-        examIpLimitRepo.deleteAllByExamId(examId);
+        examService.deleteIpLimit(examId);
     }
 
     @ApiOperation(value = "查询整体控制和学习中心控制",notes = "查询控制")
     @GetMapping("ipLimited/property/{examId}")
     public Map<String,Integer> ipLimitedProperty(@PathVariable Long examId) {
-        Map<String,Integer> map = new HashMap<>();
-        map.put("totalLimit", getExamBooleanProperty(examId,49));
-        map.put("centerLimit",getExamBooleanProperty(examId,50));
-        return map;
+        return examService.getIpLimitedProperty(examId);
     }
 
     @ApiOperation(value = "修改整体控制和学习中心控制",notes = "修改控制")
     @PostMapping("ipLimited/property/{examId}")
-    public void ipLimitedProperty(@PathVariable Long examId, @RequestBody Map<String,Integer> map) {
-        updateExamProperty(examId,49,map.get("totalLimit"));
-        updateExamProperty(examId,50,map.get("centerLimit"));
-    }
-
-    private void updateExamProperty(Long examId, Integer keyId, Object value) {
-        String countSql="select count(1) from ec_e_exam_prop where exam_id ="+examId+" AND key_id="+keyId;
-        Integer count = jdbcTemplate.queryForObject(countSql, Integer.class);
-        if (count==0){
-            String valueSql="insert into ec_e_exam_prop values (null,NOW(),NOW(),"+examId+","+keyId+","+value+")";
-            jdbcTemplate.update(valueSql);
-        } else {
-            String valueSql="update ec_e_exam_prop set value = '"+value+"'where exam_id ="+examId+" AND key_id="+keyId;
-            jdbcTemplate.update(valueSql);
-        }
+    public void ipLimitedProperty(@PathVariable Long examId, @RequestBody Map<String,Object> map) {
+        examService.updateIpLimitedProperty(examId, map);
     }
 
     @ApiOperation(value = "下载ip限制导入模板", notes = "下载导入模板")
@@ -1558,7 +1490,7 @@ public class ExamController extends ControllerSupport {
                 hasError = true;
             }
             Integer type = null;
-            IpLimitType ipLimitType = IpLimitType.formByType(line[1]);
+            IpLimitType ipLimitType = IpLimitType.formByName(line[1]);
             if(ipLimitType==null){
                 msg.append("  不符合格式的限制类型");
                 hasError = true;
@@ -1590,7 +1522,7 @@ public class ExamController extends ControllerSupport {
             map.put("failRecords", failRecords);
             return map;
         } else {
-            examIpLimitRepo.saveAll(list);
+            examService.saveAllIpLimits(list);
         }
         return map;
     }
@@ -1598,27 +1530,7 @@ public class ExamController extends ControllerSupport {
     @ApiOperation(value = "导出Ip限制",notes = "导出Ip限制")
     @GetMapping("ipLimited/export")
     public void export(Long examId, Integer limitType, String ip) {
-        Specification<ExamIpLimitEntity> spec = (root, query, cb) -> {
-            List<Predicate> predicates = new ArrayList<>();
-            if(examId!=null){
-                predicates.add(cb.equal(root.get("examId"), examId));
-            }
-            if(limitType!=null){
-                predicates.add(cb.equal(root.get("limitType"), limitType));
-            }
-            if(StringUtils.isNotBlank(ip)){
-                predicates.add(cb.like(root.get("ip"), "%"+ip+"%"));
-            }
-            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
-        };
-
-
-        long count = examIpLimitRepo.count(spec);
-        if (100000 < count) {
-            throw new StatusException("620200", "数据量过大,无法导出");
-        }
-
-        List<ExamIpLimitEntity> list = examIpLimitRepo.findAll(spec);
+        List<ExamIpLimitEntity> list = examService.findAllIpLimits(examId, limitType, ip);
 
         List<Object[]> datas = Lists.newArrayList();
 
@@ -1655,59 +1567,8 @@ public class ExamController extends ControllerSupport {
     @ApiOperation(value = "检查是否Ip限制",notes = "检查是否Ip限制")
     @GetMapping("ipLimited/{examId}")
     public boolean ipLimited(HttpServletRequest request, @PathVariable Long examId) {
-        //是否开启Ip限制
-        ExamPropertyCacheBean ipLimitProperty = CacheHelper.getExamProperty(examId, "IP_LIMIT");
-        boolean ipLimited = ipLimitProperty!=null && StringUtil.isTrue(ipLimitProperty.getValue());
-        if (ipLimited) {
-            String realIp = request.getHeader("x-forwarded-for");
-            if (StringUtils.isBlank(realIp)) {
-                realIp = request.getHeader("x-real-ip");
-            }
-            realIp = realIp.trim();
-            //整体控制
-            Integer totalLimit = getExamBooleanProperty(examId,49);
-            if (totalLimit == 1) {
-                //在白名单中
-                int count = examIpLimitRepo.countByExamIdAndLimitTypeAndIp(examId,"0",realIp);
-                if (count>0) {
-                    //学习中心访问控制
-                    Integer centerLimit = getExamBooleanProperty(examId,50);
-                    if (centerLimit == 1) {
-                        User accessUser = getAccessUser();
-                        StudentCacheBean studentCache = CacheHelper.getStudent(accessUser.getUserId());
-                        Long orgId = studentCache.getOrgId();
-                        String key = "IP_" + orgId;
-                        String value = redisClient.get(key, String.class);
-                        //机构是否在时间范围内登陆过
-                        if (value != null) {
-                            @SuppressWarnings("unchecked")
-                            Set<String> userKeyList = JsonUtil.fromJson(value, Set.class);
-
-                            for (String userKey : userKeyList) {
-                                User curUser = redisClient.get(userKey, User.class);
-                                if (null != curUser) {
-                                    String clientIp = curUser.getClientIp();
-                                    if (null != clientIp) {
-                                        // IP取前三段
-                                        clientIp = clientIp.substring(0, clientIp.lastIndexOf(".") + 1);
-                                        if (realIp.startsWith(clientIp)) {
-                                            return false;
-                                        }
-                                    }
-                                }
-
-                            }
-                        }
-                    }
-                }
-            } else {
-                //不在黑名单中
-                int count = examIpLimitRepo.countByExamIdAndLimitTypeAndIp(examId,"1",realIp);
-                return count != 0;
-            }
-
-        }
-        return true;
+        User accessUser = getAccessUser();
+        return examService.getIpLimited(request, examId, accessUser);
     }
 
     private Integer getExamBooleanProperty(Long examId, Integer keyId) {

+ 5 - 10
examcloud-core-examwork-dao/src/main/java/cn/com/qmth/examcloud/core/examwork/dao/ExamIpLimitRepo.java

@@ -15,12 +15,7 @@ public interface ExamIpLimitRepo extends JpaRepository<ExamIpLimitEntity, Long>,
 
 	@Query(value = "SELECT count(1) from ec_e_exam_ip_limit t where t.exam_id = ?1 " +
 			"AND t.limit_type = ?2 AND ?3 REGEXP t.ip ",nativeQuery = true)
-	int countByExamIdAndLimitTypeAndIp(Long examId, String limitType, String ip);
-
-	@Transactional
-	@Modifying
-	@Query(value = "delete from ec_e_exam_ip_limit where id in ?1 ",nativeQuery = true)
-    int deleteByIds(List<Long> ipIds);
+	int countByExamIdAndLimitTypeAndIp(Long examId, Integer limitType, String ip);
 
 	@Modifying
 	@Transactional
@@ -28,8 +23,8 @@ public interface ExamIpLimitRepo extends JpaRepository<ExamIpLimitEntity, Long>,
 			" where t.examId = ?2 and t.id in ?3")
 	int updateLimitType(Integer LimitType, Long examId, List<Long> ids);
 
-	@Transactional
-	@Modifying
-	@Query(value = "delete from ec_e_exam_ip_limit where exam_id = ?1 ",nativeQuery = true)
-	void deleteAllByExamId(Long examId);
+	int deleteByIdIn(List<Long> ipIds);
+
+	int deleteAllByExamId(Long examId);
+
 }

+ 7 - 7
examcloud-core-examwork-dao/src/main/java/cn/com/qmth/examcloud/core/examwork/dao/enums/IpLimitType.java

@@ -16,7 +16,7 @@ public enum IpLimitType {
     /**
      * 禁止访问
      */
-    No_Access(1, "允许访问");
+    No_Access(1, "禁止访问");
 
     private Integer id;
 
@@ -50,20 +50,20 @@ public enum IpLimitType {
         if (id == null) {
             return null;
         }
-        for (IpLimitType type : IpLimitType.values()) {
-            if (type.getId().equals(id)) {
-                return type;
+        for (IpLimitType iplimitType : IpLimitType.values()) {
+            if (iplimitType.getId().equals(id)) {
+                return iplimitType;
             }
         }
         return null;
     }
 
-    public static IpLimitType formByType(String type) {
-        if (StringUtils.isBlank(type)) {
+    public static IpLimitType formByName(String name) {
+        if (StringUtils.isBlank(name)) {
             return null;
         }
         for (IpLimitType ipLimitType : IpLimitType.values()) {
-            if (type.equals(ipLimitType.name())) {
+            if (ipLimitType.getName().equals(name)) {
                 return ipLimitType;
             }
         }

+ 84 - 1
examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/ExamService.java

@@ -2,12 +2,15 @@ package cn.com.qmth.examcloud.core.examwork.service;
 
 import cn.com.qmth.examcloud.api.commons.enums.CURD;
 import cn.com.qmth.examcloud.api.commons.exchange.PageInfo;
+import cn.com.qmth.examcloud.api.commons.security.bean.User;
 import cn.com.qmth.examcloud.core.examwork.dao.entity.ExamEntity;
 import cn.com.qmth.examcloud.core.examwork.dao.entity.ExamIpLimitEntity;
 import cn.com.qmth.examcloud.core.examwork.dao.entity.ExamSpecialSettingsEntity;
 import cn.com.qmth.examcloud.core.examwork.service.bean.ExamInfo;
+import cn.com.qmth.examcloud.core.examwork.service.bean.ExamIpLimitInfo;
 import cn.com.qmth.examcloud.core.examwork.service.bean.ExamSpecialSettingsInfo;
 
+import javax.servlet.http.HttpServletRequest;
 import java.io.File;
 import java.util.List;
 import java.util.Map;
@@ -84,5 +87,85 @@ public interface ExamService {
 
     Map<Long, ExamEntity> getExamMapsByIds(Set<Long> examIds);
 
-    PageInfo<ExamIpLimitEntity> pageIpLimited(Integer curPage, Integer pageSize, Long examId, Integer limitType, String ip);
+    /**
+     * Description ip限制分页查询
+     *
+     * @param curPage
+     * @param pageSize
+     * @param examId
+     * @param limitType
+     * @param ip
+     * @return PageInfo<ExamIpLimitInfo>
+     */
+    PageInfo<ExamIpLimitInfo> pageIpLimited(Integer curPage, Integer pageSize, Long examId, Integer limitType, String ip);
+
+    /**
+     * Description ip限制列表查询
+     *
+     * @param examId
+     * @param limitType
+     * @param ip
+     * @return List<ExamIpLimitEntity>
+     */
+    List<ExamIpLimitEntity> findAllIpLimits(Long examId, Integer limitType, String ip);
+
+    /***
+     * Description 查询当前用户当前考试是否被限制
+     *
+     * @param request
+     * @param examId
+     * @param accessUser
+     * @return boolean
+     */
+    boolean getIpLimited(HttpServletRequest request, Long examId, User accessUser);
+
+    /***
+     * Description 保存ip限制信息
+     *
+     * @param ids
+     * @param entity
+     * @return void
+     */
+    void saveIpLimit(String ids, ExamIpLimitEntity entity);
+
+    /***
+     * Description 根据ids批量删除ip限制(格式如:1,2,3)
+     *
+     * @param ids
+     * @return void
+     */
+    void deleteIpLimit(String ids);
+
+    /***
+     * Description 根据考试id批量删除
+     *
+     * @param examId
+     * @return void
+     */
+    void deleteIpLimit(Long examId);
+
+    /***
+     * Description 获取整体控制跟学校中心控制
+     *
+     * @param examId
+     * @return Map<String,Object>
+     */
+    Map<String, Integer> getIpLimitedProperty(Long examId);
+
+    /***
+     * Description 更新整体控制和学习中心控制
+     *
+     * @param examId
+     * @param map
+     * @return void
+     */
+    void updateIpLimitedProperty(Long examId, Map<String, Object> map);
+
+    /***
+     * Description 批量保存ip限制信息
+     *
+     * @param list
+     * @return void
+     */
+    void saveAllIpLimits(List<ExamIpLimitEntity> list);
 }

+ 2 - 2
examcloud-core-examwork-api-provider/src/main/java/cn/com/qmth/examcloud/core/examwork/api/controller/bean/ExamIpLimitDomain.java → examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/bean/ExamIpLimitInfo.java

@@ -1,4 +1,4 @@
-package cn.com.qmth.examcloud.core.examwork.api.controller.bean;
+package cn.com.qmth.examcloud.core.examwork.service.bean;
 
 import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
 
@@ -11,7 +11,7 @@ import java.util.Date;
  * @date 2018年8月17日
  * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
  */
-public class ExamIpLimitDomain implements JsonSerializable {
+public class ExamIpLimitInfo implements JsonSerializable {
 
 	private static final long serialVersionUID = 4009839764353162256L;
 

+ 216 - 3
examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/impl/ExamServiceImpl.java

@@ -3,6 +3,7 @@ package cn.com.qmth.examcloud.core.examwork.service.impl;
 import cn.com.qmth.examcloud.api.commons.enums.CURD;
 import cn.com.qmth.examcloud.api.commons.enums.ExamType;
 import cn.com.qmth.examcloud.api.commons.exchange.PageInfo;
+import cn.com.qmth.examcloud.api.commons.security.bean.User;
 import cn.com.qmth.examcloud.commons.exception.StatusException;
 import cn.com.qmth.examcloud.commons.helpers.DynamicEnum;
 import cn.com.qmth.examcloud.commons.helpers.DynamicEnumManager;
@@ -10,7 +11,9 @@ import cn.com.qmth.examcloud.commons.helpers.poi.ExcelReader;
 import cn.com.qmth.examcloud.commons.util.BooleanUtil;
 import cn.com.qmth.examcloud.commons.util.DateUtil;
 import cn.com.qmth.examcloud.commons.util.DateUtil.DatePatterns;
+import cn.com.qmth.examcloud.commons.util.JsonUtil;
 import cn.com.qmth.examcloud.commons.util.PathUtil;
+import cn.com.qmth.examcloud.commons.util.StringUtil;
 import cn.com.qmth.examcloud.core.basic.api.OrgCloudService;
 import cn.com.qmth.examcloud.core.basic.api.bean.OrgBean;
 import cn.com.qmth.examcloud.core.basic.api.request.GetOrgReq;
@@ -26,13 +29,16 @@ import cn.com.qmth.examcloud.core.examwork.dao.entity.ExamIpLimitEntity;
 import cn.com.qmth.examcloud.core.examwork.dao.entity.ExamOrgPropertyEntity;
 import cn.com.qmth.examcloud.core.examwork.dao.entity.ExamPropertyEntity;
 import cn.com.qmth.examcloud.core.examwork.dao.entity.ExamSpecialSettingsEntity;
+import cn.com.qmth.examcloud.core.examwork.dao.enums.IpLimitType;
 import cn.com.qmth.examcloud.core.examwork.service.ExamService;
 import cn.com.qmth.examcloud.core.examwork.service.ExamStudentService;
 import cn.com.qmth.examcloud.core.examwork.service.bean.ExamInfo;
+import cn.com.qmth.examcloud.core.examwork.service.bean.ExamIpLimitInfo;
 import cn.com.qmth.examcloud.core.examwork.service.bean.ExamSpecialSettingsInfo;
 import cn.com.qmth.examcloud.core.examwork.service.cache.ExamPropertyCache;
 import cn.com.qmth.examcloud.core.examwork.service.cache.ExamSettingsCache;
 import cn.com.qmth.examcloud.support.cache.CacheHelper;
+import cn.com.qmth.examcloud.support.cache.bean.ExamPropertyCacheBean;
 import cn.com.qmth.examcloud.support.cache.bean.StudentCacheBean;
 import cn.com.qmth.examcloud.support.privilege.PrivilegeDefine;
 import cn.com.qmth.examcloud.support.privilege.PrivilegeManager;
@@ -40,6 +46,7 @@ import cn.com.qmth.examcloud.task.api.DataSyncCloudService;
 import cn.com.qmth.examcloud.task.api.request.SyncExamReq;
 import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
 import cn.com.qmth.examcloud.web.helpers.SequenceLockHelper;
+import cn.com.qmth.examcloud.web.redis.RedisClient;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import org.apache.commons.collections.CollectionUtils;
@@ -48,19 +55,23 @@ import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.jpa.domain.Specification;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import javax.persistence.criteria.Predicate;
+import javax.servlet.http.HttpServletRequest;
 import java.io.File;
 import java.util.*;
 import java.util.Map.Entry;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * 类注释
@@ -104,6 +115,9 @@ public class ExamServiceImpl implements ExamService {
     @Autowired
     ExamIpLimitRepo examIpLimitRepo;
 
+    @Autowired
+    RedisClient redisClient;
+
     private static final String[] EXAM_ORG_SETTINGS_EXCEL_HEADER = new String[]{"学习中心ID", "学习中心代码",
             "学习中心名称", "是否可以考试(是/否)", "开始考试时间 yyyy-MM-dd hh:mm:ss", "结束考试时间 yyyy-MM-dd hh:mm:ss"};
 
@@ -828,7 +842,207 @@ public class ExamServiceImpl implements ExamService {
     }
 
     @Override
-    public PageInfo<ExamIpLimitEntity> pageIpLimited(Integer curPage, Integer pageSize, Long examId, Integer limitType, String ip) {
+    public PageInfo<ExamIpLimitInfo> pageIpLimited(Integer curPage, Integer pageSize, Long examId, Integer limitType, String ip) {
+        Specification<ExamIpLimitEntity> spec = getSpec(examId, limitType, ip);
+
+        PageRequest pageRequest = PageRequest.of(curPage, pageSize, Sort.by(Sort.Direction.DESC, "creationTime"));
+        PageInfo<ExamIpLimitEntity> pages = new PageInfo<>(examIpLimitRepo.findAll(spec, pageRequest));
+
+        PageInfo<ExamIpLimitInfo> pageInfo = new PageInfo<>();
+        List<ExamIpLimitInfo> list = new ArrayList<>();
+        pages.getList().forEach(e->{
+            ExamIpLimitInfo domain = new ExamIpLimitInfo();
+            BeanUtils.copyProperties(e,domain);
+            Optional<ExamEntity> byId = examRepo.findById(examId);
+            byId.ifPresent(examEntity -> domain.setExamName(examEntity.getName()));
+            list.add(domain);
+        });
+        pageInfo.setList(list);
+        pageInfo.setTotal(pages.getTotal());
+        return pageInfo;
+    }
+
+    @Override
+    public List<ExamIpLimitEntity> findAllIpLimits(Long examId, Integer limitType, String ip) {
+        Specification<ExamIpLimitEntity> spec = getSpec(examId, limitType, ip);
+        long count = examIpLimitRepo.count(spec);
+        if (100000 < count) {
+            throw new StatusException("620200", "数据量过大,无法导出");
+        }
+        return examIpLimitRepo.findAll(spec);
+    }
+
+    @Override
+    public boolean getIpLimited(HttpServletRequest request, Long examId, User accessUser) {
+        //是否开启Ip限制
+        ExamPropertyCacheBean ipLimitProperty = CacheHelper.getExamProperty(examId, "IP_LIMIT");
+        boolean ipLimited = ipLimitProperty!=null && StringUtil.isTrue(ipLimitProperty.getValue());
+
+        DynamicEnumManager manager = ExamProperty.getDynamicEnumManager();
+        DynamicEnum ipTotalLimit = manager.getByName("IP_TOTAL_LIMIT");
+        DynamicEnum ipCenterLimit = manager.getByName("IP_CENTER_LIMIT");
+
+        if (ipLimited) {
+            String realIp = request.getHeader("x-forwarded-for");
+            if (StringUtils.isBlank(realIp)) {
+                realIp = request.getHeader("x-real-ip");
+            }
+            realIp = realIp.trim();
+            //整体控制
+            Integer totalLimit = getExamLimitProperty(examId, ipTotalLimit.getId(), 0);
+            if (totalLimit == 1) {
+                //在白名单中
+                int count = examIpLimitRepo.countByExamIdAndLimitTypeAndIp(examId, IpLimitType.Has_access.getId(),realIp);
+                if (count>0) {
+                    //学习中心访问控制
+                    Integer centerLimit = getExamLimitProperty(examId,ipCenterLimit.getId(), 0);
+                    if (centerLimit == 1) {
+                        StudentCacheBean studentCache = CacheHelper.getStudent(accessUser.getUserId());
+                        Long orgId = studentCache.getOrgId();
+                        String key = "IP_" + orgId;
+                        String value = redisClient.get(key, String.class);
+                        //机构是否在时间范围内登陆过
+                        if (value != null) {
+                            @SuppressWarnings("unchecked")
+                            Set<String> userKeyList = JsonUtil.fromJson(value, Set.class);
+
+                            for (String userKey : userKeyList) {
+                                User curUser = redisClient.get(userKey, User.class);
+                                if (null != curUser) {
+                                    String clientIp = curUser.getClientIp();
+                                    if (null != clientIp) {
+                                        // IP取前三段
+                                        clientIp = clientIp.substring(0, clientIp.lastIndexOf(".") + 1);
+                                        if (realIp.startsWith(clientIp)) {
+                                            return false;
+                                        }
+                                    }
+                                }
+
+                            }
+                        }
+                    }
+                }
+            } else {
+                //不在黑名单中
+                int count = examIpLimitRepo.countByExamIdAndLimitTypeAndIp(examId,IpLimitType.No_Access.getId(), realIp);
+                return count != 0;
+            }
+
+        }
+        return true;
+    }
+
+    @Override
+    public void saveIpLimit(String ids, ExamIpLimitEntity entity) {
+        //ids不为空,说明是批量设置限制类型
+        if (StringUtils.isNotBlank(ids)) {
+            List<Long> ipIds = getIdsByPath(ids);
+            if(entity.getLimitType()!=null){
+                examIpLimitRepo.updateLimitType(entity.getLimitType(),entity.getExamId(),ipIds);
+            }
+        } else {
+            Long id = entity.getId();
+            Date now = new Date();
+            //新增
+            if (id==null) {
+                entity.setCreationTime(now);
+                examIpLimitRepo.save(entity);
+            } else {
+                //更新
+                Optional<ExamIpLimitEntity> byId = examIpLimitRepo.findById(id);
+                if (byId.isPresent()){
+                    ExamIpLimitEntity ipLimitEntity = byId.get();
+                    if(StringUtils.isNotBlank(entity.getIp())){
+                        ipLimitEntity.setIp(entity.getIp());
+                    }
+                    if(entity.getLimitType()!=null){
+                        ipLimitEntity.setLimitType(entity.getLimitType());
+                    }
+                    ipLimitEntity.setUpdateTime(now);
+                    examIpLimitRepo.save(ipLimitEntity);
+                }
+            }
+
+        }
+    }
+
+    @Override
+    @Transactional
+    public void deleteIpLimit(String ids) {
+        examIpLimitRepo.deleteByIdIn(getIdsByPath(ids));
+    }
+
+    @Override
+    @Transactional
+    public void deleteIpLimit(Long examId) {
+        examIpLimitRepo.deleteAllByExamId(examId);
+    }
+
+    @Override
+    public Map<String, Integer> getIpLimitedProperty(Long examId) {
+        Map<String,Integer> map = new HashMap<>();
+
+        DynamicEnumManager manager = ExamProperty.getDynamicEnumManager();
+        DynamicEnum ipTotalLimit = manager.getByName("IP_TOTAL_LIMIT");
+        DynamicEnum ipCenterLimit = manager.getByName("IP_CENTER_LIMIT");
+
+        map.put("totalLimit", getExamLimitProperty(examId,ipTotalLimit.getId(),0));
+        map.put("centerLimit",getExamLimitProperty(examId,ipCenterLimit.getId(),0));
+        return map;
+    }
+
+    @Override
+    @Transactional
+    public void updateIpLimitedProperty(Long examId, Map<String, Object> map) {
+        DynamicEnumManager manager = ExamProperty.getDynamicEnumManager();
+        DynamicEnum ipTotalLimit = manager.getByName("IP_TOTAL_LIMIT");
+        DynamicEnum ipCenterLimit = manager.getByName("IP_CENTER_LIMIT");
+
+        ExamPropertyEntity totalEntity = examPropertyRepo.findByExamIdAndKeyId(examId, ipTotalLimit.getId());
+        ExamPropertyEntity centerEntity = examPropertyRepo.findByExamIdAndKeyId(examId, ipCenterLimit.getId());
+
+        String totalLimit = map.get("totalLimit").toString();
+        String centerLimit = map.get("centerLimit").toString();
+
+        saveIpLimitEntity(totalEntity,totalLimit,ipTotalLimit,examId);
+        saveIpLimitEntity(centerEntity,centerLimit,ipCenterLimit,examId);
+    }
+
+    private void saveIpLimitEntity(ExamPropertyEntity propertyEntity, String limitValue, DynamicEnum dynamicEnum, Long examId) {
+        Date now = new Date();
+        if (propertyEntity!=null) {
+            propertyEntity.setValue(limitValue);
+            propertyEntity.setUpdateTime(now);
+            examPropertyRepo.save(propertyEntity);
+        } else {
+            ExamPropertyEntity entity = new ExamPropertyEntity();
+            entity.setExamId(examId);
+            entity.setCreationTime(now);
+            entity.setKeyId(dynamicEnum.getId());
+            entity.setValue(limitValue);
+            examPropertyRepo.save(entity);
+        }
+    }
+
+    @Override
+    @Transactional
+    public void saveAllIpLimits(List<ExamIpLimitEntity> list) {
+        examIpLimitRepo.saveAll(list);
+    }
+
+    private List<Long> getIdsByPath(String ids) {
+        return Stream.of(ids.split(",")).map(s -> Long.parseLong(s.trim()))
+                .collect(Collectors.toList());
+    }
+
+    private Integer getExamLimitProperty(Long examId, Long keyId ,Integer defaultValue) {
+        ExamPropertyEntity propertyEntity = examPropertyRepo.findByExamIdAndKeyId(examId, keyId);
+        return propertyEntity != null && StringUtils.isNotBlank(propertyEntity.getValue())
+                ? Integer.valueOf(propertyEntity.getValue()) : defaultValue;
+    }
+
+    private Specification<ExamIpLimitEntity> getSpec(Long examId, Integer limitType, String ip){
         Specification<ExamIpLimitEntity> spec = (root, query, cb) -> {
             List<Predicate> predicates = new ArrayList<>();
             if(examId!=null){
@@ -842,8 +1056,7 @@ public class ExamServiceImpl implements ExamService {
             }
             return cb.and(predicates.toArray(new Predicate[predicates.size()]));
         };
-        PageRequest pageRequest = PageRequest.of(curPage, pageSize, Sort.by(Sort.Direction.DESC, "creationTime"));
-        return new PageInfo<>(examIpLimitRepo.findAll(spec, pageRequest));
+        return spec;
     }
 
 }

+ 1 - 1
examcloud-core-examwork-starter/src/main/resources/application.properties

@@ -1,7 +1,7 @@
 spring.profiles.active=dev
 
 examcloud.startup.startupCode=8001
-examcloud.startup.configCenterHost=192.168.10.39
+examcloud.startup.configCenterHost=localhost
 examcloud.startup.configCenterPort=9999
 examcloud.startup.appCode=E
 

BIN
examcloud-core-examwork-starter/src/main/resources/templates/ipLimitImportTemplate.xlsx