智慧保安后台管理-外网项目备份
1. 保安员新增异步推送数据至群访用户表
2. 会员标记接口新增,会员标记成功,则创建会员记录和会员题库记录(包含120道题目)
3. web 端考试开始,查询题目判断用户是否为会员,如果为会员则从会员题库获取当前人员的考试题目(从120道题中随机抽取60道)
21 files modified
4 files added
1009 ■■■■■ changed files
src/main/java/org/springblade/common/config/AsyncConfig.java 35 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/common/config/FtpConfig.java 11 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/common/utils/HttpClientUtils.java 593 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/common/utils/HttpReqUtil.java 44 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/exam/mapper/ExamPaperMapper.java 7 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/exam/mapper/ExamPaperMapper.xml 11 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/exam/mapper/ExamSubjectChoicesMapper.java 6 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/exam/mapper/ExamSubjectChoicesMapper.xml 7 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/exam/service/ExamSubjectChoicesService.java 6 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/exam/service/impl/ExamPaperServiceImpl.java 49 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/exam/service/impl/ExamSubjectChoicesServiceImpl.java 9 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/system/controller/UserController.java 16 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/system/dto/UserDTO.java 48 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/system/service/MyAsyncService.java 48 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/training/controller/TrainingRegistrationController.java 29 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/training/entity/TrainingRegistration.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/vip/entity/UserVip.java 2 ●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/vip/entity/VipTopic.java 8 ●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/vip/mapper/VipTopicMapper.xml 4 ●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/vip/service/UserVipService.java 8 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/vip/service/VipTopicService.java 8 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/vip/service/impl/UserVipServiceImpl.java 22 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/vip/service/impl/VipTopticServiceImpl.java 31 ●●●●● patch | view | raw | blame | history
src/main/resources/application-dev.yml 1 ●●●● patch | view | raw | blame | history
src/main/resources/application-test.yml 1 ●●●● patch | view | raw | blame | history
src/main/java/org/springblade/common/config/AsyncConfig.java
New file
@@ -0,0 +1,35 @@
package org.springblade.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
/**
 * 异步处理配置文件
 * @author zhongrj
 * @since 2022-02-22
 */
@EnableAsync
public class AsyncConfig {
    @Bean
    public TaskExecutor executor(){
        ThreadPoolTaskExecutor executor=new ThreadPoolTaskExecutor();
        //核心线程数
        executor.setCorePoolSize(10);
        //最大线程数
        executor.setMaxPoolSize(20);
        //队列大小
        executor.setQueueCapacity(1000);
        //线程最大空闲时间
        executor.setKeepAliveSeconds(300);
        executor.setThreadNamePrefix("fsx-Executor-");
        //指定用于新创建的线程名称的前缀。
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //返回
        return executor;
    }
}
src/main/java/org/springblade/common/config/FtpConfig.java
@@ -73,6 +73,13 @@
    public static String password;
    /**
     * 群访群控接口调用基础url
     */
    public static String qfqkBaseApiUrl;
    public void setSqlConnect(String sqlConnect) {
        FtpConfig.sqlConnect = sqlConnect;
    }
@@ -116,4 +123,8 @@
    public void setPassword(String password) {
        FtpConfig.password = password;
    }
    public void setQfqkBaseApiUrl(String qfqkBaseApiUrl) {
        FtpConfig.qfqkBaseApiUrl = qfqkBaseApiUrl;
    }
}
src/main/java/org/springblade/common/utils/HttpClientUtils.java
New file
@@ -0,0 +1,593 @@
package org.springblade.common.utils;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;
import com.alibaba.fastjson.JSON;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.*;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import sun.misc.BASE64Encoder;
import javax.net.ssl.SSLContext;
public class HttpClientUtils {
    /**
     * 执行有参GET请求
     *
     * @param url
     * @param params
     * @return
     */
    public static String doGet(String url, Map<String, String> params) {
//获取httpclient客户端
        CloseableHttpClient httpclient = HttpClients.createDefault();
        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            URIBuilder builder = new URIBuilder(url);
            if (null != params) {
                for (String key : params.keySet()) {
                    builder.setParameter(key, params.get(key));
                }
            }
            HttpGet get = new HttpGet(builder.build());
            response = httpclient.execute(get);
            System.out.println(response.getStatusLine());
            if (200 == response.getStatusLine().getStatusCode()) {
                HttpEntity entity = response.getEntity();
                resultString = EntityUtils.toString(entity, "utf-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != response) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpclient) {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return resultString;
    }
    /**
     * 执行有参GET请求,带请求头
     *
     * @param url 请求url
     * @param params 参数
     * @param key 请求头Key
     * @param secretKey 秘钥
     * @return
     */
    public static String doGetHeader(String url, String key, String secretKey,Map<String, String> params) {
//获取httpclient客户端
        CloseableHttpClient httpclient = HttpClients.createDefault();
        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            URIBuilder builder = new URIBuilder(url);
            if (null != params) {
                for (String keys : params.keySet()) {
                    builder.addParameter(keys,params.get(keys));
//builder.setParameter(keys, params.get(keys));
                }
            }
            HttpGet httpGet = new HttpGet(builder.build());
//设置请求头
            httpGet.addHeader(key,secretKey);
// 传输的类型
            httpGet.addHeader("Content-Type", "application/x-www-form-urlencoded");
//执行Http请求调用
            response = httpclient.execute(httpGet);
//判断是否请求成功返回
            if (200 == response.getStatusLine().getStatusCode()) {
                HttpEntity entity = response.getEntity();
                resultString = EntityUtils.toString(entity, "utf-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != response) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpclient) {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return resultString;
    }
    /**
     * 执行有参GET请求,带请求头,接收图片流
     *
     * @param url 请求url
     * @param params 参数
     * @param key 请求头Key
     * @param secretKey 秘钥
     * @return
     */
    public static String doGetHeaderPictureBase64(String url, String key, String secretKey,Map<String, String> params) {
//获取httpclient客户端
        CloseableHttpClient httpclient = HttpClients.createDefault();
        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            URIBuilder builder = new URIBuilder(url);
            if (null != params) {
                for (String keys : params.keySet()) {
                    builder.addParameter(keys,params.get(keys));
                }
            }
            HttpGet httpGet = new HttpGet(builder.build());
//设置请求头
            httpGet.addHeader(key,secretKey);
// 传输的类型
            httpGet.addHeader("Content-Type", "application/x-www-form-urlencoded");
//执行Http请求调用
            response = httpclient.execute(httpGet);
// 将返回的图片或者文件转化成字节数组的形式
            byte[] data = EntityUtils.toByteArray(response.getEntity());
            BASE64Encoder encoder = new BASE64Encoder();
//String imageBase64 = "data:image/png;base64," + encoder.encodeBuffer(data).trim();
            return encoder.encodeBuffer(data).trim().replaceAll("\n", "").replaceAll("\r", "").replaceAll(" ", "");//删除 \r\n
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != response) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpclient) {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return resultString;
    }
    /**
     * 执行无参GET请求
     *
     * @param url
     * @return
     */
    public static String doGet(String url) {
        return doGet(url, null);
    }
    /**
     * 执行有参POST请求
     *
     * @param url
     * @param params
     * @return
     */
    public static String doPost(String url, Map<String, String> params) {
/**
 * 在4.0及以上httpclient版本中,post需要指定重定向的策略,如果不指定则按默认的重定向策略。
 *
 * 获取httpclient客户端
 */
        CloseableHttpClient httpclient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build();
        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            HttpPost post = new HttpPost(url);
            List<NameValuePair> paramaters = new ArrayList<>();
            if (null != params) {
                for (String key : params.keySet()) {
                    paramaters.add(new BasicNameValuePair(key, params.get(key)));
                }
// 构造一个form表单式的实体
                UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(paramaters);
// 将请求实体设置到httpPost对象中
                post.setEntity(formEntity);
            }
/**
 * HTTP/1.1 403 Forbidden
 *   原因:
 *      有些网站,设置了反爬虫机制
 *   解决的办法:
 *      设置请求头,伪装浏览器
 */
            post.addHeader("user-agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
            response = httpclient.execute(post);
            System.out.println(response.getStatusLine());
            if (200 == response.getStatusLine().getStatusCode()) {
                HttpEntity entity = response.getEntity();
                resultString = EntityUtils.toString(entity, "utf-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != response) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpclient) {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return resultString;
    }
    public static String doPost(String url) {
        return doPost(url, null);
    }
    public static void main(String[] args) {
        Map<String, String> params = new HashMap<>();
        params.put("scope", "project");
        params.put("q", "数据库");
//
//    System.out.println(doGet("http://www.baidu.com/s",params));
        /**
         * 有一部分网站,禁止爬虫技术访问网站。
         *
         * 解决方案:
         *    伪装浏览器
         *    post.addHeader("user-agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
         */
        System.out.println(doPost("http://www.oschina.net/search", params));
    }
    /**
     * post 请求 header 带 秘钥
     * @param url
     * @param appKey
     * @param appKeyValue
     * @param map
     * @return
     */
    public static String httpPost(String url, String appKey, String appKeyValue, Map<String, String> map) {
// 返回body
        String body = null;
// 获取连接客户端工具
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse httpResponse = null;
// 2、创建一个HttpPost请求
        HttpPost post = new HttpPost(url);
// 5、设置header信息
        /**header中通用属性*/
//        post.setHeader("Accept", "*/*");
//        post.setHeader("Accept-Encoding", "gzip, deflate");
//        post.setHeader("Cache-Control", "no-cache");
//        post.setHeader("Connection", "keep-alive");
        post.setHeader("Content-Type", "application/json;charset=UTF-8");
/**业务参数*/
        post.setHeader(appKey, appKeyValue);
// 设置参数
        if (map != null) {
            try {
                StringEntity entity1 = new StringEntity(JSON.toJSONString(map), "UTF-8");
                entity1.setContentEncoding("UTF-8");
                entity1.setContentType("json/form-data");
                post.setEntity(entity1);
// 7、执行post请求操作,并拿到结果
                httpResponse = httpClient.execute(post);
// 获取结果实体
                HttpEntity entity = httpResponse.getEntity();
                if (entity != null) {
// 按指定编码转换结果实体为String类型
                    body = EntityUtils.toString(entity, "UTF-8");
                }
                try {
                    httpResponse.close();
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return body;
    }
    public static SSLContext createIgnoreVerifySSL() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
        SSLContext sc = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
            public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                return true;
            }
        }).build();
        return sc;
    }
    //适用于post请求并传送form-data数据(同样适用于post的Raw类型的application-json格式)
    public static String postParams(String url, String appKey, String appKeyValue, Map<String, String> map) {
        SSLContext sslcontext = null;
        try {
            sslcontext = createIgnoreVerifySSL();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
// 设置协议http和https对应的处理socket链接工厂的对象
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
            .register("http", PlainConnectionSocketFactory.INSTANCE)
            .register("https", new SSLConnectionSocketFactory(sslcontext))
            .build();
        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
//创建自定义的httpclient对象
        CloseableHttpClient client = HttpClients.custom().setConnectionManager(connManager).build();
        HttpPost post = new HttpPost(url);
        post.setHeader(appKey, appKeyValue);
        CloseableHttpResponse res = null;
        try {
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            Set<String> keySet = map.keySet();
            for (String key : keySet) {
                nvps.add(new BasicNameValuePair(key, map.get(key)));
            }
            post.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
            res = client.execute(post);
            HttpEntity entity = res.getEntity();
            return EntityUtils.toString(entity, "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                res.close();
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "";
    }
    //适用于post请求并传送form-data数据(同样适用于post的Raw类型的application-json格式)
    public static String postParams(String url, Map<String, Object> map) {
        SSLContext sslcontext = null;
        try {
            sslcontext = createIgnoreVerifySSL();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
// 设置协议http和https对应的处理socket链接工厂的对象
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
            .register("http", PlainConnectionSocketFactory.INSTANCE)
            .register("https", new SSLConnectionSocketFactory(sslcontext))
            .build();
        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
//创建自定义的httpclient对象
        CloseableHttpClient client = HttpClients.custom().setConnectionManager(connManager).build();
        HttpPost post = new HttpPost(url);
//        post.setHeader(appKey, appKeyValue);
        CloseableHttpResponse res = null;
        try {
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            Set<String> keySet = map.keySet();
            for (String key : keySet) {
                nvps.add(new BasicNameValuePair(key, map.get(key).toString()));
            }
            post.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
            res = client.execute(post);
            HttpEntity entity = res.getEntity();
            return EntityUtils.toString(entity, "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                res.close();
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "";
    }
    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url    发送请求的 URL
     * @param params 请求的参数集合
     * @return 远程资源的响应结果
     */
    @SuppressWarnings("unused")
    public static String sendPost(String url, Map<String, String> params) {
        OutputStreamWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        try {
            URL realUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
// 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
// POST方法
            conn.setRequestMethod("POST");
// 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            conn.connect();
// 获取URLConnection对象对应的输出流
            out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
// 发送请求参数
            if (params != null) {
                StringBuilder param = new StringBuilder();
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    if (param.length() > 0) {
                        param.append("&");
                    }
                    param.append(entry.getKey());
                    param.append("=");
                    param.append(entry.getValue());
// System.out.println(entry.getKey()+":"+entry.getValue());
                }
// System.out.println("param:"+param.toString());
                out.write(param.toString());
            }
// flush输出流的缓冲
            out.flush();
// 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
// 使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result.toString();
    }
    /**
     * json  body
     * @param url
     * @param json
     * @return
     * @throws IOException
     */
    public static String httpPostWithjson(String url, String json) throws IOException {
        String result = "";
        HttpPost httpPost = new HttpPost(url);
        CloseableHttpClient httpClient = HttpClients.createDefault();
        try {
            BasicResponseHandler handler = new BasicResponseHandler();
            StringEntity entity = new StringEntity(json, "utf-8");//解决中文乱码问题
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            result = httpClient.execute(httpPost, handler);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }
}
src/main/java/org/springblade/common/utils/HttpReqUtil.java
@@ -107,6 +107,21 @@
        return postJson(url, json, header);
    }
    public String doPostJsons(String url, Map<String, Object> params, Map<String, String> header) throws Exception {
        String json = null;
        if (params != null && !params.isEmpty()) {
            for (Iterator<Entry<String, Object>> it = params.entrySet().iterator(); it.hasNext();) {
                Entry<String, Object> entry = (Entry<String, Object>) it.next();
                Object object = entry.getValue();
                if (object == null) {
                    it.remove();
                }
            }
            json = JSON.toJSONString(params);
        }
        return postJsons(url, json, header);
    }
    public String doPostJson(String url, String json) throws Exception {
        return doPostJson(url, json, null);
    }
@@ -144,6 +159,35 @@
        return body;
    }
    private String postJsons(String url, String json, Map<String, String> header) throws Exception {
        String body = null;
        try {
            // Post请求
            LOG.debug(" protocol: POST");
            LOG.debug("      url: " + url);
            HttpPost httpPost = new HttpPost(url.trim());
            // 设置参数
            LOG.debug("   params: " + json);
            httpPost.setEntity(new StringEntity(json, ContentType.DEFAULT_TEXT.withCharset(charset)));
            httpPost.setHeader(new BasicHeader("Content-Type", "application/json"));
            LOG.debug("     type: JSON");
            // 设置Header
            if (header != null && !header.isEmpty()) {
                LOG.debug("   header: " + JSON.toJSONString(header));
                for (Iterator<Entry<String, String>> it = header.entrySet().iterator(); it.hasNext();) {
                    Entry<String, String> entry = (Entry<String, String>) it.next();
                    httpPost.setHeader(new BasicHeader(entry.getKey(), entry.getValue()));
                }
            }
            // 发送请求,获取返回数据
            body = execute(httpPost);
        } catch (Exception e) {
            throw e;
        }
        LOG.debug("  result: " + body);
        return body;
    }
    /**
     * get请求
     */
src/main/java/org/springblade/modules/exam/mapper/ExamPaperMapper.java
@@ -159,4 +159,11 @@
     * @return
     */
    List<ExamScoreVO> getExamScoreList(@Param("examScore") ExamScoreVO examScoreVO);
    /**
     * 去除随机的题目
     * @param radio
     * @return
     */
    List<ExamSubjectChoicesVO> queryRandomSubjectList(@Param("list") List<String> radio,@Param("number") Integer number);
}
src/main/java/org/springblade/modules/exam/mapper/ExamPaperMapper.xml
@@ -534,4 +534,15 @@
        ) aa,(select @i:=0) bb
    </select>
    <select id="queryRandomSubjectList" resultType="org.springblade.modules.exam.vo.ExamSubjectChoicesVO">
        select * from (
            select * from exam_subject_choices
            where id in
            <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
                #{item}
            </foreach>
        ) a ORDER BY RAND() LIMIT #{number}
    </select>
</mapper>
src/main/java/org/springblade/modules/exam/mapper/ExamSubjectChoicesMapper.java
@@ -47,4 +47,10 @@
     * @return
     */
    int removeBySubjectId(@Param("id")Long id);
    /**
     * 随机查询题库120道
     * @return
     */
    List<String> getExamSubjectChoicesList();
}
src/main/java/org/springblade/modules/exam/mapper/ExamSubjectChoicesMapper.xml
@@ -82,4 +82,11 @@
    <delete id="removeBySubjectId">
        delete from exam_subject_option where subject_choices_id = #{id}
    </delete>
    <select id="getExamSubjectChoicesList" resultType="java.lang.String" >
        SELECT id FROM ( SELECT * FROM exam_subject_choices WHERE choices_type = 0 ORDER BY RAND( ) LIMIT 50 ) a UNION ALL
        SELECT id FROM ( SELECT * FROM exam_subject_choices WHERE choices_type = 1 ORDER BY RAND( ) LIMIT 20 ) b UNION ALL
        SELECT id FROM ( SELECT * FROM exam_subject_choices WHERE choices_type = 2 ORDER BY RAND( ) LIMIT 40 ) c UNION ALL
        SELECT id FROM ( SELECT * FROM exam_subject_choices WHERE choices_type = 3 ORDER BY RAND( ) LIMIT 10 ) d
    </select>
</mapper>
src/main/java/org/springblade/modules/exam/service/ExamSubjectChoicesService.java
@@ -62,4 +62,10 @@
     * @return
     */
    Integer getAnswerResult(Long preSubJectId, String preResult,Long scoreId);
    /**
     * 随机查询题库120道
     * @return
     */
    List<String> getExamSubjectChoicesList();
}
src/main/java/org/springblade/modules/exam/service/impl/ExamPaperServiceImpl.java
@@ -18,6 +18,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import liquibase.pro.packaged.L;
import org.springblade.common.utils.TimeSwitchUtil;
import org.springblade.core.mp.support.Condition;
import org.springblade.modules.apply.entity.Apply;
@@ -27,6 +28,8 @@
import org.springblade.modules.exam.vo.*;
import org.springblade.modules.training.entity.TrainingRegistration;
import org.springblade.modules.training.service.TrainingRegistrationService;
import org.springblade.modules.vip.entity.VipTopic;
import org.springblade.modules.vip.service.VipTopicService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -43,7 +46,7 @@
public class ExamPaperServiceImpl extends ServiceImpl<ExamPaperMapper, ExamPaper> implements ExamPaperService {
    @Autowired
    private ExamExaminationSubjectService examExaminationSubjectService;
    private VipTopicService vipTopicService;
    @Autowired
    private ExamAnswerRecordService examAnswerRecordService;
@@ -53,6 +56,9 @@
    @Autowired
    private ExamScoreService examScoreService;
    @Autowired
    private TrainingRegistrationService trainingRegistrationService;
@@ -111,8 +117,45 @@
    public List<ExamSubjectChoicesVO> queryRandomSubject(ExamPaperVO paper) {
        //保存题目信息
        if (null!=paper.getScoreId()){
            //随机分类信息
            List<ExamSubjectChoicesVO> examSubjectChoicesVOS = baseMapper.queryRandomSubject(paper);
            //查询该保安员是否为会员
            ExamScore score = examScoreService.getById(paper.getScoreId());
            TrainingRegistration trainingRegistration = trainingRegistrationService.getById(score.getApplyId());
            List<ExamSubjectChoicesVO> examSubjectChoicesVOS = new ArrayList<>();
            if (null!=trainingRegistration.getVipStatus()){
                //如果是会员,从会员库里取题目
                if (trainingRegistration.getVipStatus().equals(1)){
                    //查询该vip 用户的 vip 库,从该120题中取出题目
                    VipTopic vipTopic = new VipTopic();
                    vipTopic.setUserId(Long.parseLong(score.getUserId()));
                    vipTopic.setApplyId(score.getApplyId());
                    VipTopic topic = vipTopicService.getOne(Condition.getQueryWrapper(vipTopic));
                    if (null!=topic){
                        List<String> list = Arrays.asList(topic.getTopicIds().split(","));
//                        System.out.println("list.size() = " + list.size());
                        List<String> radio = list.subList(0, 49);
                        List<String> checkbox = list.subList(50, 69);
                        List<String> judge = list.subList(70, 109);
                        List<String> sort = list.subList(110, 119);
                        //随机题目
                        List<ExamSubjectChoicesVO> radioRandomSubjectList = baseMapper.queryRandomSubjectList(radio,25);
                        List<ExamSubjectChoicesVO> checkboxRandomSubjectList = baseMapper.queryRandomSubjectList(checkbox,10);
                        List<ExamSubjectChoicesVO> judgeRandomSubjectList = baseMapper.queryRandomSubjectList(judge,20);
                        List<ExamSubjectChoicesVO> sortRandomSubjectList = baseMapper.queryRandomSubjectList(sort,5);
                        //合并集合数据
                        examSubjectChoicesVOS.addAll(radioRandomSubjectList);
                        examSubjectChoicesVOS.addAll(checkboxRandomSubjectList);
                        examSubjectChoicesVOS.addAll(judgeRandomSubjectList);
                        examSubjectChoicesVOS.addAll(sortRandomSubjectList);
                    }
                }else {
                    //随机分类信息
                    examSubjectChoicesVOS = baseMapper.queryRandomSubject(paper);
                }
            }else {
                //随机分类信息
                examSubjectChoicesVOS = baseMapper.queryRandomSubject(paper);
            }
//            long before = System.currentTimeMillis();
            List<ExamExaminationSubject> list = new ArrayList<>();
            examSubjectChoicesVOS.forEach(examSubjectChoicesVO -> {
src/main/java/org/springblade/modules/exam/service/impl/ExamSubjectChoicesServiceImpl.java
@@ -393,4 +393,13 @@
            "," + "'" + examAnswerRecord.getScoreId() + "'" + ")";
        FtpUtil.sqlFileUpload(s);
    }
    /**
     * 随机查询题库120道
     * @return
     */
    @Override
    public List<String> getExamSubjectChoicesList() {
        return baseMapper.getExamSubjectChoicesList();
    }
}
src/main/java/org/springblade/modules/system/controller/UserController.java
@@ -31,6 +31,7 @@
import io.swagger.annotations.ApiParam;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import net.sf.json.JSONObject;
import org.apache.commons.codec.Charsets;
import org.springblade.common.cache.DictCache;
import org.springblade.common.config.FtpConfig;
@@ -38,6 +39,8 @@
import org.springblade.common.excel.CustomCellWriteHeightConfig;
import org.springblade.common.excel.CustomCellWriteWeightConfig;
import org.springblade.common.excel.RowWriteHandler;
import org.springblade.common.utils.HttpClientUtils;
import org.springblade.common.utils.HttpReqUtil;
import org.springblade.common.utils.ImageUtils;
import org.springblade.common.utils.arg;
import org.springblade.core.cache.utils.CacheUtil;
@@ -68,6 +71,7 @@
import org.springblade.modules.securitypaper.service.SecurityPaperService;
import org.springblade.modules.signinrecords.entity.SignInRecords;
import org.springblade.modules.signinrecords.service.SignInRecordsService;
import org.springblade.modules.system.dto.UserDTO;
import org.springblade.modules.system.entity.Dept;
import org.springblade.modules.system.entity.Role;
import org.springblade.modules.system.entity.User;
@@ -76,11 +80,13 @@
import org.springblade.modules.system.service.IDeptService;
import org.springblade.modules.system.service.IRoleService;
import org.springblade.modules.system.service.IUserService;
import org.springblade.modules.system.service.MyAsyncService;
import org.springblade.modules.system.vo.DeptVO;
import org.springblade.modules.system.vo.UserVO;
import org.springblade.modules.system.wrapper.UserWrapper;
import org.springblade.modules.training.entity.TrainingRegistration;
import org.springblade.modules.training.service.TrainingRegistrationService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@@ -134,6 +140,8 @@
    private final SecurityPaperService securityPaperService;
    private final MyAsyncService myAsyncService;
    /**
     * 查询单条
@@ -1211,6 +1219,14 @@
            user.setAvatar(FtpConfig.ip + user.getAvatar().substring(26));
        }
        //数据推送
        //1.群访群控数据推送(异步)
        if (status) {
            myAsyncService.qfqkUserSave(user);
        }
        //2.内网数据推送
        String s = "insert into blade_user(" +
            "id,tenant_id,account,password,name,real_name,avatar,email,phone,sex," +
            "role_id,dept_id,cardid,nativePlace,nation,fingerprint,education," +
src/main/java/org/springblade/modules/system/dto/UserDTO.java
New file
@@ -0,0 +1,48 @@
package org.springblade.modules.system.dto;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import lombok.Data;
import java.io.Serializable;
/**
 * 用户数据推送 DTO
 * @author zhongrj
 * @since 2022-02-22
 */
@Data
public class UserDTO implements Serializable {
    private Long id;
    private String account;
    /**
     * 密码
     */
    private String password;
    private String realName;
    private String avatar;
    private String email;
    private String phone;
    private Integer sex;
    private String roleId;
    private Integer status;
    private Integer isDeleted;
    private String examinationType;
    private String examinationMx;
    private String jurisdiction;
    private String cardid;
}
src/main/java/org/springblade/modules/system/service/MyAsyncService.java
New file
@@ -0,0 +1,48 @@
package org.springblade.modules.system.service;
import net.sf.json.JSONObject;
import org.springblade.common.utils.HttpClientUtils;
import org.springblade.modules.system.dto.UserDTO;
import org.springblade.modules.system.entity.User;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.io.IOException;
import static org.springblade.common.config.FtpConfig.qfqkBaseApiUrl;
@Service
public class MyAsyncService {
    /**
     * 用户新增
     * @param user
     */
    @Async
    public void qfqkUserSave(User user) {
//        System.out.println("进入异步方法----------------------");
//        try {
//            Thread.sleep(30000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        String requestUrl = qfqkBaseApiUrl + "/blade-user/securitySaves";
        UserDTO userDTO = new UserDTO();
        userDTO.setAccount(user.getAccount());
        userDTO.setCardid(user.getCardid());
        userDTO.setPassword(user.getPassword());
        userDTO.setSex(user.getSex());
        userDTO.setStatus(user.getStatus());
        userDTO.setPhone(user.getPhone());
        userDTO.setIsDeleted(user.getIsDeleted());
        userDTO.setRealName(user.getRealName());
        //装换为 json
        JSONObject jsonObject = JSONObject.fromObject(userDTO);
        //发送请求
        try {
            HttpClientUtils.httpPostWithjson(requestUrl,jsonObject.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
src/main/java/org/springblade/modules/training/controller/TrainingRegistrationController.java
@@ -31,6 +31,9 @@
import org.springblade.modules.training.excel.TrainingRegistrationImporter;
import org.springblade.modules.training.service.TrainingRegistrationService;
import org.springblade.modules.training.vo.TrainingRegistrationVo;
import org.springblade.modules.vip.service.UserVipService;
import org.springblade.modules.vip.service.VipTopicService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@@ -55,6 +58,10 @@
    private final IUserService userService;
    private final ExamPaperService examPaperService;
    private final UserVipService userVipService;
    private final VipTopicService vipTopicService;
    /**
     * 自定义分页
@@ -714,4 +721,26 @@
        }
        return null;
    }
    /**
     * 是否为会员标记
     * @param trainingRegistration
     * @return
     */
    @PostMapping("/vipSign")
    @Transactional(rollbackFor = Exception.class)
    public R vipSign(@RequestBody TrainingRegistration trainingRegistration){
        //新增会员记录
        userVipService.insertUserVipInfo(trainingRegistration);
        //新增会员题库记录
        vipTopicService.insertVipTopicInfo(trainingRegistration);
        //内网报名信息同步
        String s1 =
            "update sys_training_registration set vip_status = " + "'" + trainingRegistration.getVipStatus() + "'"
                + " " + "where id = " + "'" + trainingRegistration.getId() + "'";
        FtpUtil.sqlFileUpload(s1);
        //更新并返回数据
        return R.data(trainingRegistrationService.updateById(trainingRegistration));
    }
}
src/main/java/org/springblade/modules/training/entity/TrainingRegistration.java
@@ -121,4 +121,9 @@
    @TableField("audit_status")
    private Integer auditStatus;
    /**
     * vip 状态,是否为vip 1:是  2:否
     */
    private Integer vipStatus;
}
src/main/java/org/springblade/modules/vip/entity/UserVip.java
@@ -64,7 +64,7 @@
    /**
     * 报名id
     */
    private Integer applyId;
    private Long applyId;
src/main/java/org/springblade/modules/vip/entity/VipTopic.java
@@ -28,9 +28,9 @@
    private Long id;
    /**
     * 用户会员id
     * 用户id
     */
    private Long userVipId;
    private Long userId;
    /**
     * 题目id
@@ -44,6 +44,10 @@
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    /**
     * 报名id
     */
    private Long applyId;
}
src/main/java/org/springblade/modules/vip/mapper/VipTopicMapper.xml
@@ -6,8 +6,8 @@
    <select id="selectVipTopicPage" resultType="org.springblade.modules.vip.vo.VipTopicVO">
        select * from sys_vip_topic
        where 1=1
        <if test="vipTopic.userVipId!=null">
            and user_vip_id =#{vipTopic.userVipId}
        <if test="vipTopic.userId!=null">
            and user_id =#{vipTopic.userId}
        </if>
    </select>
src/main/java/org/springblade/modules/vip/service/UserVipService.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import org.apache.ibatis.annotations.Param;
import org.springblade.modules.training.entity.TrainingRegistration;
import org.springblade.modules.vip.entity.UserVip;
import org.springblade.modules.vip.vo.UserVipVO;
@@ -23,4 +24,11 @@
     * @return
     */
    IPage<UserVipVO> selectUserVipPage(IPage<UserVipVO> page, @Param("userVipVO") UserVipVO userVipVO);
    /**
     * 新增会员信息
     * @param trainingRegistration
     * @return
     */
    boolean insertUserVipInfo(TrainingRegistration trainingRegistration);
}
src/main/java/org/springblade/modules/vip/service/VipTopicService.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import org.apache.ibatis.annotations.Param;
import org.springblade.modules.training.entity.TrainingRegistration;
import org.springblade.modules.vip.entity.VipTopic;
import org.springblade.modules.vip.vo.VipTopicVO;
@@ -23,4 +24,11 @@
     * @return
     */
    IPage<VipTopicVO> selectVipTopicPage(IPage<VipTopicVO> page, @Param("vipTopicVO") VipTopicVO vipTopicVO);
    /**
     * 新增会员题库
     * @param trainingRegistration
     * @return
     */
    boolean insertVipTopicInfo(TrainingRegistration trainingRegistration);
}
src/main/java/org/springblade/modules/vip/service/impl/UserVipServiceImpl.java
@@ -3,11 +3,14 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springblade.modules.training.entity.TrainingRegistration;
import org.springblade.modules.vip.entity.UserVip;
import org.springblade.modules.vip.mapper.UserVipMapper;
import org.springblade.modules.vip.service.UserVipService;
import org.springblade.modules.vip.vo.UserVipVO;
import org.springframework.stereotype.Service;
import java.util.Date;
/**
 *  用户会员服务实现类
@@ -29,4 +32,23 @@
    public IPage<UserVipVO> selectUserVipPage(IPage<UserVipVO> page, UserVipVO userVip) {
        return page.setRecords(baseMapper.selectUserVipPage(page, userVip));
    }
    /**
     * 新增会员信息
     * @param trainingRegistration  报名信息对象
     * @since 2022-02-22
     * @return
     */
    @Override
    public boolean insertUserVipInfo(TrainingRegistration trainingRegistration) {
        //1.创建用户会员对象
        UserVip userVip = new UserVip();
        //2.数据封装
        userVip.setApplyId(trainingRegistration.getId());
        userVip.setCreateTime(new Date());
        userVip.setUpdateTime(new Date());
        userVip.setUserId(Long.parseLong(trainingRegistration.getUserId()));
        //3.返回
        return this.save(userVip);
    }
}
src/main/java/org/springblade/modules/vip/service/impl/VipTopticServiceImpl.java
@@ -3,11 +3,18 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springblade.modules.exam.service.ExamSubjectChoicesService;
import org.springblade.modules.training.entity.TrainingRegistration;
import org.springblade.modules.vip.entity.VipTopic;
import org.springblade.modules.vip.mapper.VipTopicMapper;
import org.springblade.modules.vip.service.VipTopicService;
import org.springblade.modules.vip.vo.VipTopicVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
 *  用户会员题库服务实现类
@@ -18,6 +25,9 @@
@Service
public class VipTopticServiceImpl extends ServiceImpl<VipTopicMapper, VipTopic> implements VipTopicService {
    @Autowired
    private ExamSubjectChoicesService examSubjectChoicesService;
    /**
     * 自定义分页查询用户会员数据
     * @param page
@@ -28,4 +38,25 @@
    public IPage<VipTopicVO> selectVipTopicPage(IPage<VipTopicVO> page, VipTopicVO vipTopic) {
        return page.setRecords(baseMapper.selectVipTopicPage(page, vipTopic));
    }
    /**
     * 新增会员题库
     * @param trainingRegistration
     * @return
     */
    @Override
    public boolean insertVipTopicInfo(TrainingRegistration trainingRegistration) {
        //1. 创建会员题库对象
        VipTopic vipTopic = new VipTopic();
        //2. 随机查询120道题目信息,只要题目 id 集合即可
        List<String> list = examSubjectChoicesService.getExamSubjectChoicesList();
        //3. 数据处理,封装
        String collect = list.stream().collect(Collectors.joining(","));
        vipTopic.setTopicIds(collect);
        vipTopic.setApplyId(trainingRegistration.getId());
        vipTopic.setCreateTime(new Date());
        vipTopic.setUserId(Long.parseLong(trainingRegistration.getUserId()));
        //4. 新增并返回
        return this.save(vipTopic);
    }
}
src/main/resources/application-dev.yml
@@ -50,6 +50,7 @@
  jsonUrl: /home/zhongsong/anbao/
  username: root
  password: ZHba@0112
  qfqkBaseApiUrl : http://223.82.109.183:2082/api
#第三方登陆
social:
src/main/resources/application-test.yml
@@ -50,6 +50,7 @@
  jsonUrl: D:\\anbao\\
  username: root
  password: ZHba@0112
  qfqkBaseApiUrl : http://localhost:83
#第三方登陆
social: