Kaynağa Gözat

词库同步

devops 2 ay önce
ebeveyn
işleme
7898b36a5e

+ 43 - 0
.gitignore

@@ -0,0 +1,43 @@
+######################################################################
+# Build Tools
+
+.gradle
+/build/
+!gradle/wrapper/gradle-wrapper.jar
+
+target/
+!.mvn/wrapper/maven-wrapper.jar
+
+######################################################################
+# IDE
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+nbproject/private/
+build/*
+nbbuild/
+dist/
+nbdist/
+.nb-gradle/
+
+######################################################################
+# Others
+*.log
+*.xml.versionsBackup
+
+!*/build/*.java
+!*/build/*.html
+!*/build/*.xml

+ 1 - 0
lastSyncTime.txt

@@ -0,0 +1 @@
+1771987795675

+ 2 - 0
ruoyi-admin/src/main/resources/mapper/project/TrsNameWordsMapper.xml

@@ -66,6 +66,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="accord != null">accord,</if>
             <if test="source != null">source,</if>
             <if test="linkurl != null">linkurl,</if>
+            <if test="time != null">time,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="wrongWord != null and wrongWord != ''">#{wrongWord},</if>
@@ -81,6 +82,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="accord != null">#{accord},</if>
             <if test="source != null">#{source},</if>
             <if test="linkurl != null">#{linkurl},</if>
+            <if test="time != null">#{time},</if>
          </trim>
     </insert>
 

+ 2 - 0
ruoyi-admin/src/main/resources/mapper/project/TrsPolicyWordsMapper.xml

@@ -63,6 +63,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="accord != null">accord,</if>
             <if test="source != null">source,</if>
             <if test="linkurl != null">linkurl,</if>
+            <if test="time != null">time,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="wrongWord != null and wrongWord != ''">#{wrongWord},</if>
@@ -77,6 +78,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="accord != null">#{accord},</if>
             <if test="source != null">#{source},</if>
             <if test="linkurl != null">#{linkurl},</if>
+            <if test="time != null">#{time},</if>
          </trim>
     </insert>
 

+ 437 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtilsEx.java

@@ -0,0 +1,437 @@
+package com.ruoyi.common.utils.http;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.ConnectException;
+import java.net.SocketTimeoutException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.cert.X509Certificate;
+import java.util.Map;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import com.ruoyi.common.utils.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.ruoyi.common.constant.Constants;
+
+/**
+ * 增强版HTTP工具类 - 支持自定义Headers
+ */
+public class HttpUtilsEx
+{
+    private static final Logger log = LoggerFactory.getLogger(HttpUtilsEx.class);
+
+    /**
+     * 向指定 URL 发送GET方法的请求(支持自定义Headers)
+     *
+     * @param url 发送请求的 URL
+     * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
+     * @param headers 自定义请求头
+     * @return 所代表远程资源的响应结果
+     */
+    public static String sendGet(String url, String param, Map<String, String> headers)
+    {
+        return sendGet(url, param, headers, Constants.UTF8);
+    }
+
+    /**
+     * 向指定 URL 发送GET方法的请求(支持自定义Headers)
+     *
+     * @param url 发送请求的 URL
+     * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
+     * @param headers 自定义请求头
+     * @param contentType 编码类型
+     * @return 所代表远程资源的响应结果
+     */
+    public static String sendGet(String url, String param, Map<String, String> headers, String contentType)
+    {
+        StringBuilder result = new StringBuilder();
+        BufferedReader in = null;
+        try
+        {
+            String urlNameString = StringUtils.isNotEmpty(param) ? url + "?" + param : url;
+            log.info("sendGet - {}", urlNameString);
+            URL realUrl = new URL(urlNameString);
+            URLConnection connection = realUrl.openConnection();
+
+            // 设置默认请求头
+            connection.setRequestProperty("accept", "*/*");
+            connection.setRequestProperty("connection", "Keep-Alive");
+            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+            connection.setRequestProperty("Accept-Charset", "utf-8");
+            connection.setRequestProperty("contentType", "utf-8");
+
+            // 设置自定义请求头
+            if (headers != null && !headers.isEmpty()) {
+                for (Map.Entry<String, String> entry : headers.entrySet()) {
+                    connection.setRequestProperty(entry.getKey(), entry.getValue());
+                    log.debug("设置请求头: {} = {}", entry.getKey(), entry.getValue());
+                }
+            }
+
+            connection.setConnectTimeout(30000); // 30秒连接超时
+            connection.setReadTimeout(60000);    // 60秒读取超时
+
+            connection.connect();
+            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType));
+            String line;
+            while ((line = in.readLine()) != null)
+            {
+                result.append(line);
+            }
+            log.info("recv - 响应长度: {} 字符", result.length());
+        }
+        catch (ConnectException e)
+        {
+            log.error("调用HttpUtilsEx.sendGet ConnectException, url=" + url + ",param=" + param, e);
+        }
+        catch (SocketTimeoutException e)
+        {
+            log.error("调用HttpUtilsEx.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e);
+        }
+        catch (IOException e)
+        {
+            log.error("调用HttpUtilsEx.sendGet IOException, url=" + url + ",param=" + param, e);
+        }
+        catch (Exception e)
+        {
+            log.error("调用HttpUtilsEx.sendGet Exception, url=" + url + ",param=" + param, e);
+        }
+        finally
+        {
+            try
+            {
+                if (in != null)
+                {
+                    in.close();
+                }
+            }
+            catch (Exception ex)
+            {
+                log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
+            }
+        }
+        return result.toString();
+    }
+
+    /**
+     * 向指定 URL 发送POST方法的请求(支持自定义Headers)
+     *
+     * @param url 发送请求的 URL
+     * @param param 请求参数
+     * @param headers 自定义请求头
+     * @return 所代表远程资源的响应结果
+     */
+    public static String sendPost(String url, String param, Map<String, String> headers)
+    {
+        return sendPost(url, param, headers, Constants.UTF8);
+    }
+
+    /**
+     * 向指定 URL 发送POST方法的请求(支持自定义Headers)
+     *
+     * @param url 发送请求的 URL
+     * @param param 请求参数
+     * @param headers 自定义请求头
+     * @param contentType 编码类型
+     * @return 所代表远程资源的响应结果
+     */
+    public static String sendPost(String url, String param, Map<String, String> headers, String contentType)
+    {
+        PrintWriter out = null;
+        BufferedReader in = null;
+        StringBuilder result = new StringBuilder();
+        try
+        {
+            log.info("sendPost - {}", url);
+            URL realUrl = new URL(url);
+            URLConnection conn = realUrl.openConnection();
+
+            // 设置默认请求头
+            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("Accept-Charset", "utf-8");
+            conn.setRequestProperty("contentType", "utf-8");
+            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+            // 设置自定义请求头
+            if (headers != null && !headers.isEmpty()) {
+                for (Map.Entry<String, String> entry : headers.entrySet()) {
+                    conn.setRequestProperty(entry.getKey(), entry.getValue());
+                    log.debug("设置请求头: {} = {}", entry.getKey(), entry.getValue());
+                }
+            }
+
+            conn.setConnectTimeout(30000); // 30秒连接超时
+            conn.setReadTimeout(60000);    // 60秒读取超时
+            conn.setDoOutput(true);
+            conn.setDoInput(true);
+
+            out = new PrintWriter(conn.getOutputStream());
+            out.print(param);
+            out.flush();
+
+            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), contentType));
+            String line;
+            while ((line = in.readLine()) != null)
+            {
+                result.append(line);
+            }
+            log.info("recv - 响应长度: {} 字符", result.length());
+        }
+        catch (ConnectException e)
+        {
+            log.error("调用HttpUtilsEx.sendPost ConnectException, url=" + url + ",param=" + param, e);
+        }
+        catch (SocketTimeoutException e)
+        {
+            log.error("调用HttpUtilsEx.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e);
+        }
+        catch (IOException e)
+        {
+            log.error("调用HttpUtilsEx.sendPost IOException, url=" + url + ",param=" + param, e);
+        }
+        catch (Exception e)
+        {
+            log.error("调用HttpUtilsEx.sendPost Exception, url=" + url + ",param=" + param, e);
+        }
+        finally
+        {
+            try
+            {
+                if (out != null)
+                {
+                    out.close();
+                }
+                if (in != null)
+                {
+                    in.close();
+                }
+            }
+            catch (IOException ex)
+            {
+                log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
+            }
+        }
+        return result.toString();
+    }
+
+    /**
+     * 向指定 URL 发送POST方法的请求(JSON格式,支持自定义Headers)
+     *
+     * @param url 发送请求的 URL
+     * @param jsonParam JSON格式的请求参数
+     * @param headers 自定义请求头
+     * @return 所代表远程资源的响应结果
+     */
+    public static String sendJsonPost(String url, String jsonParam, Map<String, String> headers)
+    {
+        PrintWriter out = null;
+        BufferedReader in = null;
+        StringBuilder result = new StringBuilder();
+        try
+        {
+            log.info("sendJsonPost - {}", url);
+            URL realUrl = new URL(url);
+            URLConnection conn = realUrl.openConnection();
+
+            // 设置默认请求头
+            conn.setRequestProperty("accept", "application/json");
+            conn.setRequestProperty("connection", "Keep-Alive");
+            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+            conn.setRequestProperty("Accept-Charset", "utf-8");
+            conn.setRequestProperty("contentType", "utf-8");
+            conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
+
+            // 设置自定义请求头
+            if (headers != null && !headers.isEmpty()) {
+                for (Map.Entry<String, String> entry : headers.entrySet()) {
+                    conn.setRequestProperty(entry.getKey(), entry.getValue());
+                    log.debug("设置请求头: {} = {}", entry.getKey(), entry.getValue());
+                }
+            }
+
+            conn.setConnectTimeout(30000); // 30秒连接超时
+            conn.setReadTimeout(60000);    // 60秒读取超时
+            conn.setDoOutput(true);
+            conn.setDoInput(true);
+
+            out = new PrintWriter(conn.getOutputStream());
+            out.print(jsonParam);
+            out.flush();
+
+            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), Constants.UTF8));
+            String line;
+            while ((line = in.readLine()) != null)
+            {
+                result.append(line);
+            }
+            log.info("recv - 响应长度: {} 字符", result.length());
+        }
+        catch (ConnectException e)
+        {
+            log.error("调用HttpUtilsEx.sendJsonPost ConnectException, url=" + url + ",jsonParam=" + jsonParam, e);
+        }
+        catch (SocketTimeoutException e)
+        {
+            log.error("调用HttpUtilsEx.sendJsonPost SocketTimeoutException, url=" + url + ",jsonParam=" + jsonParam, e);
+        }
+        catch (IOException e)
+        {
+            log.error("调用HttpUtilsEx.sendJsonPost IOException, url=" + url + ",jsonParam=" + jsonParam, e);
+        }
+        catch (Exception e)
+        {
+            log.error("调用HttpUtilsEx.sendJsonPost Exception, url=" + url + ",jsonParam=" + jsonParam, e);
+        }
+        finally
+        {
+            try
+            {
+                if (out != null)
+                {
+                    out.close();
+                }
+                if (in != null)
+                {
+                    in.close();
+                }
+            }
+            catch (IOException ex)
+            {
+                log.error("调用in.close Exception, url=" + url + ",jsonParam=" + jsonParam, ex);
+            }
+        }
+        return result.toString();
+    }
+
+    /**
+     * 向指定 URL 发送SSL POST方法的请求(支持自定义Headers)
+     *
+     * @param url 发送请求的 URL
+     * @param param 请求参数
+     * @param headers 自定义请求头
+     * @return 所代表远程资源的响应结果
+     */
+    public static String sendSSLPost(String url, String param, Map<String, String> headers)
+    {
+        StringBuilder result = new StringBuilder();
+        String urlNameString = StringUtils.isNotEmpty(param) ? url + "?" + param : url;
+        try
+        {
+            log.info("sendSSLPost - {}", urlNameString);
+            SSLContext sc = SSLContext.getInstance("SSL");
+            sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom());
+            URL console = new URL(urlNameString);
+            HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
+
+            // 设置默认请求头
+            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("Accept-Charset", "utf-8");
+            conn.setRequestProperty("contentType", "utf-8");
+
+            // 设置自定义请求头
+            if (headers != null && !headers.isEmpty()) {
+                for (Map.Entry<String, String> entry : headers.entrySet()) {
+                    conn.setRequestProperty(entry.getKey(), entry.getValue());
+                    log.debug("设置请求头: {} = {}", entry.getKey(), entry.getValue());
+                }
+            }
+
+            conn.setConnectTimeout(30000); // 30秒连接超时
+            conn.setReadTimeout(60000);    // 60秒读取超时
+            conn.setDoOutput(true);
+            conn.setDoInput(true);
+            conn.setSSLSocketFactory(sc.getSocketFactory());
+            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
+
+            conn.connect();
+            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+            String ret;
+            while ((ret = br.readLine()) != null)
+            {
+                if (ret != null && !ret.trim().isEmpty())
+                {
+                    result.append(new String(ret.getBytes("ISO-8859-1"), Constants.UTF8));
+                }
+            }
+            log.info("recv - 响应长度: {} 字符", result.length());
+            conn.disconnect();
+            br.close();
+        }
+        catch (ConnectException e)
+        {
+            log.error("调用HttpUtilsEx.sendSSLPost ConnectException, url=" + url + ",param=" + param, e);
+        }
+        catch (SocketTimeoutException e)
+        {
+            log.error("调用HttpUtilsEx.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e);
+        }
+        catch (IOException e)
+        {
+            log.error("调用HttpUtilsEx.sendSSLPost IOException, url=" + url + ",param=" + param, e);
+        }
+        catch (Exception e)
+        {
+            log.error("调用HttpUtilsEx.sendSSLPost Exception, url=" + url + ",param=" + param, e);
+        }
+        return result.toString();
+    }
+
+    /**
+     * 构建URL参数
+     */
+    public static String buildParams(Map<String, Object> params) {
+        if (params == null || params.isEmpty()) {
+            return "";
+        }
+
+        StringBuilder paramBuilder = new StringBuilder();
+        for (Map.Entry<String, Object> entry : params.entrySet()) {
+            if (paramBuilder.length() > 0) {
+                paramBuilder.append("&");
+            }
+            paramBuilder.append(entry.getKey()).append("=").append(entry.getValue());
+        }
+        return paramBuilder.toString();
+    }
+
+    private static class TrustAnyTrustManager implements X509TrustManager
+    {
+        @Override
+        public void checkClientTrusted(X509Certificate[] chain, String authType)
+        {
+        }
+
+        @Override
+        public void checkServerTrusted(X509Certificate[] chain, String authType)
+        {
+        }
+
+        @Override
+        public X509Certificate[] getAcceptedIssuers()
+        {
+            return new X509Certificate[] {};
+        }
+    }
+
+    private static class TrustAnyHostnameVerifier implements HostnameVerifier
+    {
+        @Override
+        public boolean verify(String hostname, SSLSession session)
+        {
+            return true;
+        }
+    }
+}

+ 1 - 0
ruoyi-project/src/main/java/com/ruoyi/project/service/ITrsPolicyWordsService.java

@@ -60,4 +60,5 @@ public interface ITrsPolicyWordsService
     public int deleteTrsPolicyWordsById(Long id);
 
     String importWords(List<TrsPolicyWords> wordList, boolean updateSupport);
+
 }

+ 906 - 0
ruoyi-project/src/main/java/com/ruoyi/project/service/TrsWordSyncClientService.java

@@ -0,0 +1,906 @@
+package com.ruoyi.project.service;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.http.HttpUtilsEx;
+import com.ruoyi.project.domain.*;
+import com.ruoyi.project.mapper.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * 词库同步客户端服务 - 包含数据保存到数据库
+ */
+@Service
+public class TrsWordSyncClientService {
+
+    private static final Logger log = LoggerFactory.getLogger(TrsWordSyncClientService.class);
+    private static final int batchSize = 100;
+
+    // 最后同步时间戳文件路径
+    private static final String LAST_SYNC_TIME_FILE = "lastSyncTime.txt";
+    // 默认最后同步时间(2025-01-01 00:00:00)
+    private static final long DEFAULT_LAST_SYNC_TIME = 1770652800000L;
+
+    // 注入各个词库的服务
+    @Autowired
+    private ITrsSensitiveWordsService sensitiveWordsService;
+
+    @Autowired
+    private ITrsDomainWordsService domainWordsService;
+
+    @Autowired
+    private ITrsNameWordsService nameWordsService;
+
+    @Autowired
+    private ITrsPolicyWordsService policyWordsService;
+
+    @Autowired
+    private ITrsTechnicalWordsService technicalWordsService;
+
+    @Autowired
+    private ITrsNamenmgWordsService namenmgWordsService;
+
+    @Autowired
+    private ITrsRegionWordsService regionWordsService;
+
+    /**
+     * 同步词库数据(全量或增量)并保存到数据库
+     */
+//    @Transactional(rollbackFor = Exception.class)
+    public AjaxResult syncWords(String wordType) {
+        boolean syncEnabled = true;
+//        String serverUrl = "https://www.nmg.gov.cn/trsjd/";
+        String serverUrl = "http://localhost:90/nmg";
+        String apiKey = "TRSword123!@#";
+
+        if (!syncEnabled) {
+            log.warn("词库同步功能已禁用");
+            return AjaxResult.error("词库同步功能已禁用");
+        }
+
+        try {
+            // 构建请求URL
+            StringBuilder urlBuilder = new StringBuilder(serverUrl);
+            if (!serverUrl.endsWith("/")) {
+                urlBuilder.append("/");
+            }
+            urlBuilder.append("project/check/sync");
+
+            // 构建请求参数
+            Map<String, Object> params = new HashMap<>();
+            params.put("wordType", wordType);
+
+            // 从文件读取最后同步时间
+            Long lastSyncTimestamp = readLastSyncTime();
+            if (lastSyncTimestamp != null && lastSyncTimestamp > 0) {
+                params.put("lastSyncTime", lastSyncTimestamp);
+                log.info("执行增量同步,词库类型: {},最后同步时间: {}", wordType, new Date(lastSyncTimestamp));
+            } else {
+                log.info("执行全量同步,词库类型: {}", wordType);
+            }
+
+            String url = urlBuilder.toString();
+            String paramStr = HttpUtilsEx.buildParams(params);
+
+            // 构建请求头
+            Map<String, String> headers = new HashMap<>();
+            headers.put("X-API-KEY", apiKey);
+            headers.put("Accept", "application/json");
+
+            log.info("开始同步请求,URL: {}, 参数: {}", url, paramStr);
+
+            // 发送HTTP请求(使用支持Header的HttpUtilsEx)
+            String response = HttpUtilsEx.sendGet(url, paramStr, headers);
+
+            if (StringUtils.isEmpty(response)) {
+                return AjaxResult.error("同步请求失败,服务器无响应");
+            }
+
+            log.debug("收到同步响应: {}", response);
+
+            // 解析响应
+            JSONObject result = JSON.parseObject(response);
+            int code = result.getIntValue("code");
+            String msg = result.getString("msg");
+            Object data = result.get("data");
+
+            if (code == 0 && data != null) {
+                JSONObject dataObj = (JSONObject) data;
+
+                // 更新最后同步时间
+                Long newSyncTime = dataObj.getLong("syncTime");
+                if (newSyncTime != null) {
+                    // 保存到文件
+                    saveLastSyncTime(newSyncTime);
+                    log.info("同步成功,更新时间戳: {}", new Date(newSyncTime));
+                }
+
+                // 处理返回的数据并保存到数据库
+                int totalCount = dataObj.getIntValue("totalCount");
+                String wordTypeName = dataObj.getString("wordTypeName");
+
+                // 保存数据到数据库
+                int savedCount = saveWordsToDatabase(dataObj, wordType);
+
+                log.info("同步完成,词库类型: {},接收数据量: {} 条,保存成功: {} 条",
+                        wordTypeName, totalCount, savedCount);
+
+                Map<String, Object> resultMap = new HashMap<>();
+                resultMap.put("syncTime", newSyncTime);
+                resultMap.put("wordType", wordTypeName);
+                resultMap.put("totalCount", totalCount);
+                resultMap.put("savedCount", savedCount);
+                resultMap.put("message", "同步并保存成功");
+
+                return AjaxResult.success(msg, resultMap);
+            } else {
+                log.error("同步失败,错误信息: {}", msg);
+                return AjaxResult.error(msg);
+            }
+
+        } catch (Exception e) {
+            log.error("词库同步异常", e);
+            return AjaxResult.error("同步异常: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 从文件读取最后同步时间
+     */
+    private Long readLastSyncTime() {
+        try {
+            File file = new File(LAST_SYNC_TIME_FILE);
+            if (!file.exists()) {
+                log.info("最后同步时间文件不存在,使用默认时间");
+                return DEFAULT_LAST_SYNC_TIME;
+            }
+
+            try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
+                String line = reader.readLine();
+                if (StringUtils.isNotEmpty(line)) {
+                    Long timestamp = Long.parseLong(line.trim());
+                    log.info("从文件读取最后同步时间: {}", new Date(timestamp));
+                    return timestamp;
+                }
+            }
+        } catch (Exception e) {
+            log.error("读取最后同步时间失败", e);
+        }
+        return DEFAULT_LAST_SYNC_TIME;
+    }
+
+    /**
+     * 保存最后同步时间到文件
+     */
+    private void saveLastSyncTime(Long timestamp) {
+        try {
+            File file = new File(LAST_SYNC_TIME_FILE);
+            try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
+                writer.write(String.valueOf(timestamp));
+                writer.flush();
+                log.info("保存最后同步时间到文件: {}", new Date(timestamp));
+            }
+        } catch (Exception e) {
+            log.error("保存最后同步时间失败", e);
+        }
+    }
+
+    /**
+     * 保存词库数据到数据库
+     */
+    private int saveWordsToDatabase(JSONObject data, String wordType) {
+        int savedCount = 0;
+
+        try {
+            if ("all".equals(wordType) || wordType == null) {
+                // 保存所有类型的词库数据
+                savedCount += saveSensitiveWords(data.getJSONObject("data").getJSONArray("sensitive"));
+                savedCount += saveDomainWords(data.getJSONObject("data").getJSONArray("domain"));
+                savedCount += saveNameWords(data.getJSONObject("data").getJSONArray("name"));
+                savedCount += savePolicyWords(data.getJSONObject("data").getJSONArray("policy"));
+                savedCount += saveTechnicalWords(data.getJSONObject("data").getJSONArray("technical"));
+                savedCount += saveNamenmgWords(data.getJSONObject("data").getJSONArray("namenmg"));
+                savedCount += saveRegionWords(data.getJSONObject("data").getJSONArray("region"));
+            } else {
+                // 保存指定类型的词库数据
+                switch (wordType.toLowerCase()) {
+                    case "sensitive":
+                        savedCount += saveSensitiveWords(data.getJSONObject("data").getJSONArray("sensitive"));
+                        break;
+                    case "domain":
+                        savedCount += saveDomainWords(data.getJSONObject("data").getJSONArray("domain"));
+                        break;
+                    case "name":
+                        savedCount += saveNameWords(data.getJSONObject("data").getJSONArray("name"));
+                        break;
+                    case "policy":
+                        savedCount += savePolicyWords(data.getJSONObject("data").getJSONArray("policy"));
+                        break;
+                    case "technical":
+                        savedCount += saveTechnicalWords(data.getJSONObject("data").getJSONArray("technical"));
+                        break;
+                    case "namenmg":
+                        savedCount += saveNamenmgWords(data.getJSONObject("data").getJSONArray("namenmg"));
+                        break;
+                    case "region":
+                        savedCount += saveRegionWords(data.getJSONObject("data").getJSONArray("region"));
+                        break;
+                }
+            }
+        } catch (Exception e) {
+            log.error("保存词库数据到数据库失败", e);
+            throw new RuntimeException("保存数据失败: " + e.getMessage(), e);
+        }
+
+        return savedCount;
+    }
+
+    /**
+     * 保存常见错误词库(按wrongWord查询)
+     */
+    private int saveSensitiveWords(JSONArray dataArray) {
+        if (dataArray == null || dataArray.isEmpty()) {
+            return 0;
+        }
+
+        int savedCount = 0;
+        List<TrsSensitiveWords> batchList = new ArrayList<>();
+
+        for (int i = 0; i < dataArray.size(); i++) {
+            JSONObject item = dataArray.getJSONObject(i);
+            TrsSensitiveWords word = new TrsSensitiveWords();
+
+            // 设置字段值
+//            word.setId(item.getLong("id"));
+            word.setWrongWord(item.getString("wrongWord"));
+            word.setCorrectWord(item.getString("correctWord"));
+            word.setErrorType(item.getString("errorType"));
+            word.setErrorGrade(item.getString("errorGrade"));
+            word.setDictType(item.getString("dictType"));
+            word.setFlag(item.getInteger("flag"));
+            word.setStatus(item.getString("status"));
+            word.setTime(item.getDate("time"));
+
+
+            // 处理日期字段
+            Long time = item.getLong("time");
+            if (time != null && time > 0) {
+                word.setTime(new Date(time));
+            }
+
+            Long effectstart = item.getLong("effectstart");
+            if (effectstart != null && effectstart > 0) {
+                word.setEffectstart(new Date(effectstart));
+            }
+
+            Long effectend = item.getLong("effectend");
+            if (effectend != null && effectend > 0) {
+                word.setEffectend(new Date(effectend));
+            }
+
+            batchList.add(word);
+
+            // 批量保存
+            if (batchList.size() >= batchSize) {
+                savedCount += batchInsertSensitiveWords(batchList);
+                batchList.clear();
+            }
+        }
+
+        // 保存剩余数据
+        if (!batchList.isEmpty()) {
+            savedCount += batchInsertSensitiveWords(batchList);
+        }
+
+        log.info("保存常见错误词库 {} 条", savedCount);
+        return savedCount;
+    }
+
+    /**
+     * 批量插入常见错误词库(按wrongWord查询)
+     */
+    @Autowired
+    private TrsSensitiveWordsMapper trsSensitiveWordsMapper;
+    private int batchInsertSensitiveWords(List<TrsSensitiveWords> wordList) {
+        int count = 0;
+        for (TrsSensitiveWords word : wordList) {
+            try {
+                // 按wrongWord查询是否已存在
+                TrsSensitiveWords query = new TrsSensitiveWords();
+                query.setWrongWord(word.getWrongWord());
+                List<TrsSensitiveWords> existingList = trsSensitiveWordsMapper.selectTrsSensitiveWordsList(query);
+
+                if (existingList != null && !existingList.isEmpty()) {
+                    // 更新现有记录
+                    TrsSensitiveWords existing = existingList.get(0);
+                    word.setId(existing.getId());
+                    trsSensitiveWordsMapper.updateTrsSensitiveWords(word);
+                } else {
+                    // 插入新记录
+                    trsSensitiveWordsMapper.insertTrsSensitiveWords(word);
+                }
+                count++;
+            } catch (Exception e) {
+                log.error("保存常见错误词条失败: {}", word.getWrongWord(), e);
+            }
+        }
+        return count;
+    }
+
+    /**
+     * 保存领域常识词库(按wrongWord查询)
+     */
+    private int saveDomainWords(JSONArray dataArray) {
+        if (dataArray == null || dataArray.isEmpty()) {
+            return 0;
+        }
+
+        int savedCount = 0;
+        List<TrsDomainWords> batchList = new ArrayList<>();
+
+        for (int i = 0; i < dataArray.size(); i++) {
+            JSONObject item = dataArray.getJSONObject(i);
+            TrsDomainWords word = new TrsDomainWords();
+
+            // 设置字段值
+//            word.setId(item.getLong("id"));
+            word.setWrongWord(item.getString("wrongWord"));
+            word.setDomainType(item.getString("domainType"));
+            word.setDictType(item.getString("dictType"));
+            word.setFlag(item.getInteger("flag"));
+            word.setStatus(item.getString("status"));
+            word.setTime(item.getDate("time"));
+
+
+            // 处理日期字段
+            Long time = item.getLong("time");
+            if (time != null && time > 0) {
+                word.setTime(new Date(time));
+            }
+
+            Long effectstart = item.getLong("effectstart");
+            if (effectstart != null && effectstart > 0) {
+                word.setEffectstart(new Date(effectstart));
+            }
+
+            Long effectend = item.getLong("effectend");
+            if (effectend != null && effectend > 0) {
+                word.setEffectend(new Date(effectend));
+            }
+
+            batchList.add(word);
+
+            // 批量保存
+            if (batchList.size() >= batchSize) {
+                savedCount += batchInsertDomainWords(batchList);
+                batchList.clear();
+            }
+        }
+
+        if (!batchList.isEmpty()) {
+            savedCount += batchInsertDomainWords(batchList);
+        }
+
+        log.info("保存领域常识词库 {} 条", savedCount);
+        return savedCount;
+    }
+
+
+    @Autowired
+    private TrsDomainWordsMapper trsDomainWordsMapper;
+    private int batchInsertDomainWords(List<TrsDomainWords> wordList) {
+        int count = 0;
+        for (TrsDomainWords word : wordList) {
+            try {
+                // 按wrongWord查询
+                TrsDomainWords query = new TrsDomainWords();
+                query.setWrongWord(word.getWrongWord());
+                List<TrsDomainWords> existingList = trsDomainWordsMapper.selectTrsDomainWordsList(query);
+
+                if (existingList != null && !existingList.isEmpty()) {
+                    TrsDomainWords existing = existingList.get(0);
+                    word.setId(existing.getId());
+                    trsDomainWordsMapper.updateTrsDomainWords(word);
+                } else {
+                    trsDomainWordsMapper.insertTrsDomainWords(word);
+                }
+                count++;
+            } catch (Exception e) {
+                log.error("保存领域常识词条失败: {}", word.getWrongWord(), e);
+            }
+        }
+        return count;
+    }
+
+    /**
+     * 保存人名职务词库(按wrongWord查询)
+     */
+    private int saveNameWords(JSONArray dataArray) {
+        if (dataArray == null || dataArray.isEmpty()) {
+            return 0;
+        }
+
+        int savedCount = 0;
+        List<TrsNameWords> batchList = new ArrayList<>();
+
+        for (int i = 0; i < dataArray.size(); i++) {
+            JSONObject item = dataArray.getJSONObject(i);
+            TrsNameWords word = new TrsNameWords();
+
+            // 设置字段值
+//            word.setId(item.getLong("id"));
+            word.setWrongWord(item.getString("wrongWord"));
+            word.setCountry(item.getString("country"));
+            word.setDutyAll(item.getString("dutyAll"));
+            word.setDutyShort(item.getString("dutyShort"));
+            word.setSort(item.getString("sort"));
+            word.setDictType(item.getString("dictType"));
+            word.setFlag(item.getInteger("flag"));
+            word.setStatus(item.getString("status"));
+            word.setAccord(item.getString("accord"));
+            word.setSource(item.getString("source"));
+            word.setLinkurl(item.getString("linkurl"));
+            word.setTime(item.getDate("time"));
+
+
+            // 处理日期字段
+            Long time = item.getLong("time");
+            if (time != null && time > 0) {
+                word.setTime(new Date(time));
+            }
+
+            Long effectstart = item.getLong("effectstart");
+            if (effectstart != null && effectstart > 0) {
+                word.setEffectstart(new Date(effectstart));
+            }
+
+            Long effectend = item.getLong("effectend");
+            if (effectend != null && effectend > 0) {
+                word.setEffectend(new Date(effectend));
+            }
+
+            batchList.add(word);
+
+            if (batchList.size() >= batchSize) {
+                savedCount += batchInsertNameWords(batchList);
+                batchList.clear();
+            }
+        }
+
+        if (!batchList.isEmpty()) {
+            savedCount += batchInsertNameWords(batchList);
+        }
+
+        log.info("保存人名职务词库 {} 条", savedCount);
+        return savedCount;
+    }
+
+
+    @Autowired
+    private TrsNameWordsMapper trsNameWordsMapper;
+    private int batchInsertNameWords(List<TrsNameWords> wordList) {
+        int count = 0;
+        for (TrsNameWords word : wordList) {
+            try {
+                // 按wrongWord查询
+                TrsNameWords query = new TrsNameWords();
+                query.setWrongWord(word.getWrongWord());
+                List<TrsNameWords> existingList = trsNameWordsMapper.selectTrsNameWordsList(query);
+
+                if (existingList != null && !existingList.isEmpty()) {
+                    TrsNameWords existing = existingList.get(0);
+                    word.setId(existing.getId());
+                    trsNameWordsMapper.updateTrsNameWords(word);
+                } else {
+                    trsNameWordsMapper.insertTrsNameWords(word);
+                }
+                count++;
+            } catch (Exception e) {
+                log.error("保存人名职务词条失败: {}", word.getWrongWord(), e);
+            }
+        }
+        return count;
+    }
+
+    /**
+     * 保存政治常识词库(按wrongWord查询)
+     */
+    private int savePolicyWords(JSONArray dataArray) {
+        if (dataArray == null || dataArray.isEmpty()) {
+            return 0;
+        }
+
+        int savedCount = 0;
+        List<TrsPolicyWords> batchList = new ArrayList<>();
+
+        for (int i = 0; i < dataArray.size(); i++) {
+            JSONObject item = dataArray.getJSONObject(i);
+            TrsPolicyWords word = new TrsPolicyWords();
+
+            // 设置字段值
+//            word.setId(item.getLong("id"));
+            word.setWrongWord(item.getString("wrongWord"));
+            word.setErrorRule(item.getString("errorRule"));
+            word.setErrorType(item.getString("errorType"));
+            word.setErrorGrade(item.getString("errorGrade"));
+            word.setDictType(item.getString("dictType"));
+            word.setFlag(item.getInteger("flag"));
+            word.setStatus(item.getString("status"));
+            word.setAccord(item.getString("accord"));
+            word.setSource(item.getString("source"));
+            word.setLinkurl(item.getString("linkurl"));
+            word.setTime(item.getDate("time"));
+
+
+            // 处理日期字段
+            Long time = item.getLong("time");
+            if (time != null && time > 0) {
+                word.setTime(new Date(time));
+            }
+
+            Long effectstart = item.getLong("effectstart");
+            if (effectstart != null && effectstart > 0) {
+                word.setEffectstart(new Date(effectstart));
+            }
+
+            Long effectend = item.getLong("effectend");
+            if (effectend != null && effectend > 0) {
+                word.setEffectend(new Date(effectend));
+            }
+
+            batchList.add(word);
+
+            if (batchList.size() >= batchSize) {
+                savedCount += batchInsertPolicyWords(batchList);
+                batchList.clear();
+            }
+        }
+
+        if (!batchList.isEmpty()) {
+            savedCount += batchInsertPolicyWords(batchList);
+        }
+
+        log.info("保存政治常识词库 {} 条", savedCount);
+        return savedCount;
+    }
+
+    @Autowired
+    private TrsPolicyWordsMapper trsPolicyWordsMapper;
+    private int batchInsertPolicyWords(List<TrsPolicyWords> wordList) {
+        int count = 0;
+        for (TrsPolicyWords word : wordList) {
+            try {
+                // 按wrongWord查询
+                TrsPolicyWords query = new TrsPolicyWords();
+                query.setWrongWord(word.getWrongWord());
+                List<TrsPolicyWords> existingList = trsPolicyWordsMapper.selectTrsPolicyWordsList(query);
+
+                if (existingList != null && !existingList.isEmpty()) {
+                    TrsPolicyWords existing = existingList.get(0);
+                    word.setId(existing.getId());
+                    trsPolicyWordsMapper.updateTrsPolicyWords(word);
+                } else {
+                    trsPolicyWordsMapper.insertTrsPolicyWords(word);
+                }
+                count++;
+            } catch (Exception e) {
+                log.error("保存政治常识词条失败: {}", word.getWrongWord(), e);
+            }
+        }
+        return count;
+    }
+
+    /**
+     * 保存专业术语词库(按wrongWord查询)
+     */
+    private int saveTechnicalWords(JSONArray dataArray) {
+        if (dataArray == null || dataArray.isEmpty()) {
+            return 0;
+        }
+
+        int savedCount = 0;
+        List<TrsTechnicalWords> batchList = new ArrayList<>();
+
+        for (int i = 0; i < dataArray.size(); i++) {
+            JSONObject item = dataArray.getJSONObject(i);
+            TrsTechnicalWords word = new TrsTechnicalWords();
+
+            // 设置字段值
+//            word.setId(item.getLong("id"));
+            word.setWrongWord(item.getString("wrongWord"));
+            word.setErrorType(item.getString("errorType"));
+            word.setDictType(item.getString("dictType"));
+            word.setFlag(item.getInteger("flag"));
+            word.setStatus(item.getString("status"));
+            word.setAccord(item.getString("accord"));
+            word.setSource(item.getString("source"));
+            word.setLinkurl(item.getString("linkurl"));
+            word.setTime(item.getDate("time"));
+
+
+            // 处理日期字段
+            Long time = item.getLong("time");
+            if (time != null && time > 0) {
+                word.setTime(new Date(time));
+            }
+
+            Long effectstart = item.getLong("effectstart");
+            if (effectstart != null && effectstart > 0) {
+                word.setEffectstart(new Date(effectstart));
+            }
+
+            Long effectend = item.getLong("effectend");
+            if (effectend != null && effectend > 0) {
+                word.setEffectend(new Date(effectend));
+            }
+
+            batchList.add(word);
+
+            if (batchList.size() >= batchSize) {
+                savedCount += batchInsertTechnicalWords(batchList);
+                batchList.clear();
+            }
+        }
+
+        if (!batchList.isEmpty()) {
+            savedCount += batchInsertTechnicalWords(batchList);
+        }
+
+        log.info("保存专业术语词库 {} 条", savedCount);
+        return savedCount;
+    }
+
+
+    @Autowired
+    private TrsTechnicalWordsMapper trsTechnicalWordsMapper;
+    private int batchInsertTechnicalWords(List<TrsTechnicalWords> wordList) {
+        int count = 0;
+        for (TrsTechnicalWords word : wordList) {
+            try {
+                // 按wrongWord查询
+                TrsTechnicalWords query = new TrsTechnicalWords();
+                query.setWrongWord(word.getWrongWord());
+                List<TrsTechnicalWords> existingList = trsTechnicalWordsMapper.selectTrsTechnicalWordsList(query);
+
+                if (existingList != null && !existingList.isEmpty()) {
+                    TrsTechnicalWords existing = existingList.get(0);
+                    word.setId(existing.getId());
+                    trsTechnicalWordsMapper.updateTrsTechnicalWords(word);
+                } else {
+                    trsTechnicalWordsMapper.insertTrsTechnicalWords(word);
+                }
+                count++;
+            } catch (Exception e) {
+                log.error("保存专业术语词条失败: {}", word.getWrongWord(), e);
+            }
+        }
+        return count;
+    }
+
+    /**
+     * 保存内蒙古自治区领导人词库(按wrongWord查询)
+     */
+    private int saveNamenmgWords(JSONArray dataArray) {
+        if (dataArray == null || dataArray.isEmpty()) {
+            return 0;
+        }
+
+        int savedCount = 0;
+        List<TrsNamenmgWords> batchList = new ArrayList<>();
+
+        for (int i = 0; i < dataArray.size(); i++) {
+            JSONObject item = dataArray.getJSONObject(i);
+            TrsNamenmgWords word = new TrsNamenmgWords();
+
+            // 设置字段值
+//            word.setId(item.getLong("id"));
+            word.setWrongWord(item.getString("wrongWord"));
+            word.setCountry(item.getString("country"));
+            word.setDutyAll(item.getString("dutyAll"));
+            word.setDutyShort(item.getString("dutyShort"));
+            word.setSort(item.getString("sort"));
+            word.setDictType(item.getString("dictType"));
+            word.setFlag(item.getInteger("flag"));
+            word.setStatus(item.getString("status"));
+            word.setTime(item.getDate("time"));
+
+
+            // 处理日期字段
+            Long time = item.getLong("time");
+            if (time != null && time > 0) {
+                word.setTime(new Date(time));
+            }
+
+            batchList.add(word);
+
+            if (batchList.size() >= batchSize) {
+                savedCount += batchInsertNamenmgWords(batchList);
+                batchList.clear();
+            }
+        }
+
+        if (!batchList.isEmpty()) {
+            savedCount += batchInsertNamenmgWords(batchList);
+        }
+
+        log.info("保存内蒙古领导人词库 {} 条", savedCount);
+        return savedCount;
+    }
+
+    private int batchInsertNamenmgWords(List<TrsNamenmgWords> wordList) {
+        int count = 0;
+        for (TrsNamenmgWords word : wordList) {
+            try {
+                // 按wrongWord查询
+                TrsNamenmgWords query = new TrsNamenmgWords();
+                query.setWrongWord(word.getWrongWord());
+                List<TrsNamenmgWords> existingList = namenmgWordsService.selectTrsNamenmgWordsList(query);
+
+                if (existingList != null && !existingList.isEmpty()) {
+                    TrsNamenmgWords existing = existingList.get(0);
+                    word.setId(existing.getId());
+                    namenmgWordsService.updateTrsNamenmgWords(word);
+                } else {
+                    namenmgWordsService.insertTrsNamenmgWords(word);
+                }
+                count++;
+            } catch (Exception e) {
+                log.error("保存内蒙古领导人词条失败: {}", word.getWrongWord(), e);
+            }
+        }
+        return count;
+    }
+
+    /**
+     * 保存内蒙古自治区地区词库(按code查询)
+     */
+    private int saveRegionWords(JSONArray dataArray) {
+        if (dataArray == null || dataArray.isEmpty()) {
+            return 0;
+        }
+
+        int savedCount = 0;
+        List<TrsRegionWords> batchList = new ArrayList<>();
+
+        for (int i = 0; i < dataArray.size(); i++) {
+            JSONObject item = dataArray.getJSONObject(i);
+            TrsRegionWords word = new TrsRegionWords();
+
+            // 设置字段值
+//            word.setId(item.getLong("id"));
+            word.setCode(item.getString("code"));
+            word.setName(item.getString("name"));
+            word.setParentCode(item.getString("parentCode"));
+            word.setIsAble(item.getString("isAble"));
+            word.setOrderNum(item.getInteger("orderNum"));
+            word.setBannerName(item.getString("bannerName"));
+            word.setRegionLevel(item.getString("regionLevel"));
+            word.setShortName(item.getString("shortName"));
+            word.setIsDelete(item.getString("isDelete"));
+            word.setStatus(item.getString("status"));
+            word.setTime(item.getDate("time"));
+
+            // 处理日期字段
+            Long time = item.getLong("time");
+            if (time != null && time > 0) {
+                word.setTime(new Date(time));
+            }
+
+            batchList.add(word);
+
+            if (batchList.size() >= batchSize) {
+                savedCount += batchInsertRegionWords(batchList);
+                batchList.clear();
+            }
+        }
+
+        if (!batchList.isEmpty()) {
+            savedCount += batchInsertRegionWords(batchList);
+        }
+
+        log.info("保存内蒙古地区词库 {} 条", savedCount);
+        return savedCount;
+    }
+
+    private int batchInsertRegionWords(List<TrsRegionWords> wordList) {
+        int count = 0;
+        for (TrsRegionWords word : wordList) {
+            try {
+                // 根据code查找现有记录
+                TrsRegionWords query = new TrsRegionWords();
+                query.setCode(word.getCode());
+                List<TrsRegionWords> existingList = regionWordsService.selectTrsRegionWordsList(query);
+
+                if (existingList != null && !existingList.isEmpty()) {
+                    // 更新现有记录
+                    TrsRegionWords existing = existingList.get(0);
+                    word.setId(existing.getId());
+                    regionWordsService.updateTrsRegionWords(word);
+                } else {
+                    // 插入新记录
+                    regionWordsService.insertTrsRegionWords(word);
+                }
+                count++;
+            } catch (Exception e) {
+                log.error("保存内蒙古地区词条失败: {}", word.getName(), e);
+            }
+        }
+        return count;
+    }
+
+    // 其他辅助方法
+    public AjaxResult syncAllWords() {
+        return syncWords("all");
+    }
+
+    public AjaxResult syncSensitiveWords() {
+        return syncWords("sensitive");
+    }
+
+    public AjaxResult syncDomainWords() {
+        return syncWords("domain");
+    }
+
+    public AjaxResult syncNameWords() {
+        return syncWords("name");
+    }
+
+    public AjaxResult syncPolicyWords() {
+        return syncWords("policy");
+    }
+
+    public AjaxResult syncTechnicalWords() {
+        return syncWords("technical");
+    }
+
+    public AjaxResult syncNamenmgWords() {
+        return syncWords("namenmg");
+    }
+
+    public AjaxResult syncRegionWords() {
+        return syncWords("region");
+    }
+
+    /**
+     * 重置同步时间(手动重置文件中的时间)
+     */
+    public AjaxResult resetSync() {
+        try {
+            saveLastSyncTime(DEFAULT_LAST_SYNC_TIME);
+            log.info("同步记录已重置,下次将执行全量同步");
+            return AjaxResult.success("同步记录已重置");
+        } catch (Exception e) {
+            log.error("重置同步时间失败", e);
+            return AjaxResult.error("重置同步时间失败: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 获取当前最后同步时间
+     */
+    public AjaxResult getLastSyncTime() {
+        Long timestamp = readLastSyncTime();
+        Map<String, Object> result = new HashMap<>();
+        result.put("timestamp", timestamp);
+        result.put("timeString", new Date(timestamp));
+        return AjaxResult.success(result);
+    }
+
+    /**
+     * 设置最后同步时间
+     */
+    public AjaxResult setLastSyncTime(Long timestamp) {
+        saveLastSyncTime(timestamp);
+        return AjaxResult.success("设置成功");
+    }
+}

+ 10 - 1
ruoyi-project/src/main/java/com/ruoyi/project/task/TrsTask.java

@@ -3,6 +3,7 @@ package com.ruoyi.project.task;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.project.service.ITrsSiteUpdateService;
 import com.ruoyi.project.service.ITrsSiteconfigService;
+import com.ruoyi.project.service.TrsWordSyncClientService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -20,6 +21,9 @@ public class TrsTask
     @Autowired
     private ITrsSiteUpdateService trsSiteUpdateService;
 
+    @Autowired
+    private TrsWordSyncClientService trssWordSyncClientService;
+
 
     public void trsMultipleParams(String s, Boolean b, Long l, Double d, Integer i)
     {
@@ -31,7 +35,6 @@ public class TrsTask
         System.out.println("执行有参方法:" + params);
         String[] split = params.split(";");
         trsSiteconfigService.doscan(Long.parseLong(split[0]), split[1], split[2]);
-
     }
 
     public void trsurl(String params)
@@ -52,4 +55,10 @@ public class TrsTask
         trsSiteUpdateService.doMonitorInsert();
     }
 
+    public void trsWordSyn(String params)
+    {
+        System.out.println("TRS执行同步词库同步接口");
+        trssWordSyncClientService.syncWords(params);
+    }
+
 }