Jelajahi Sumber

接收nginx日志入库,注释车辆php页面请求日志入库定时任务

weijianghai 1 bulan lalu
induk
melakukan
03e1f0f458
30 mengubah file dengan 1390 tambahan dan 189 penghapusan
  1. 6 0
      pom.xml
  2. 14 0
      scripts/backup-financialdb.sh
  3. 24 0
      scripts/openresty/conf.d/39201.house-resource-map.conf
  4. 20 0
      scripts/openresty/conf.d/39202.house-report.conf
  5. 19 0
      scripts/openresty/conf.d/39203.car-report.conf
  6. 19 0
      scripts/openresty/conf.d/39204.car-resource-map.conf
  7. 19 0
      scripts/openresty/conf.d/39205.house-data-check.conf
  8. 11 0
      scripts/openresty/conf.d/39206.house-gdc.conf
  9. 208 0
      scripts/openresty/conf.d/8000.conf
  10. 185 0
      scripts/openresty/conf.d/8080.conf
  11. 95 0
      scripts/openresty/conf/nginx.conf
  12. 19 0
      scripts/openresty/conf/ssl/server.crt
  13. 16 0
      scripts/openresty/conf/ssl/server.csr
  14. 28 0
      scripts/openresty/conf/ssl/server.key
  15. 7 0
      scripts/openresty/lua/access.lua
  16. 9 0
      scripts/openresty/lua/body_filter.lua
  17. 76 0
      scripts/openresty/lua/log.lua
  18. 10 0
      scripts/restore-financialdb.sh
  19. 9 0
      scripts/rollback-page.sh
  20. 9 0
      scripts/start-libreoffice.sh
  21. 13 0
      scripts/start-minio.sh
  22. 13 0
      scripts/start-openresty.sh
  23. 11 0
      scripts/update-page.sh
  24. 10 0
      src/main/java/com/nokia/finance/tasks/dao/common/NginxLogDao.java
  25. 67 67
      src/main/java/com/nokia/finance/tasks/dao/common/RequestLogDao.java
  26. 121 121
      src/main/java/com/nokia/finance/tasks/jobs/gdc/car/CarPhpRequestLogJob.java
  27. 138 0
      src/main/java/com/nokia/finance/tasks/pojo/po/common/NginxLogPo.java
  28. 206 0
      src/main/java/com/nokia/finance/tasks/service/common/NginxLogService.java
  29. 4 1
      src/main/resources/application-dev.yml
  30. 4 0
      src/main/resources/application-prod.yml

+ 6 - 0
pom.xml

@@ -124,6 +124,12 @@
             <version>3.5.6</version>
             <version>3.5.6</version>
             <scope>test</scope>
             <scope>test</scope>
         </dependency>
         </dependency>
+        <!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-all</artifactId>
+            <version>4.2.0.Final</version>
+        </dependency>
     </dependencies>
     </dependencies>
 
 
     <dependencyManagement>
     <dependencyManagement>

+ 14 - 0
scripts/backup-financialdb.sh

@@ -0,0 +1,14 @@
+#!/bin/sh
+
+echo "$(date) backup financialdb start"
+export PGPASSWORD='Finance@unicom23'
+backup_dir=/backup/postgres/financialdb/$(date +%Y%m)/$(date +%Y%m%d)/$(date +%Y%m%d%H%M%S)
+mkdir -p "${backup_dir}"
+host='172.16.107.5'
+port='5432'
+username='finance'
+dbname='financialdb'
+jobs='16'
+echo "pg_dump -h ${host} -p ${port} -U ${username} -d ${dbname} -v -O -Fd -j ${jobs} -Z9 -f ${backup_dir}"
+pg_dump -h "${host}" -p "${port}" -U "${username}" -d "${dbname}" -v -O -Fd -j "${jobs}" -Z9 -f "${backup_dir}"
+echo "$(date) backup financialdb end"

+ 24 - 0
scripts/openresty/conf.d/39201.house-resource-map.conf

@@ -0,0 +1,24 @@
+server {
+    listen       39201;
+    listen  [::]:39201;
+    server_name localhost;
+
+    location / {
+        root   /app/house-resource-map/dist;
+        index  index.html index.htm;
+        try_files $uri $uri/ /index.html;
+    }
+    # 后端
+    location /house-car/house/resource-map/api {
+        proxy_pass http://172.16.107.4:39100;
+    }
+    # minio
+    location /house-car/oss {
+        proxy_pass http://172.16.107.4:39000;
+    }
+    # 百度地图
+    location /dugis-baidu/baidumap/jsapi {
+        proxy_pass http://172.16.107.4:39000/house-car/oss/public/dugis-baidu/baidumap/jsapi;
+    }
+
+}

+ 20 - 0
scripts/openresty/conf.d/39202.house-report.conf

@@ -0,0 +1,20 @@
+server {
+    listen       39202;
+    listen  [::]:39202;
+    server_name localhost;
+
+    location / {
+        root   /app/house-report/dist;
+        index  index.html index.htm;
+        try_files $uri $uri/ /index.html;
+    }
+    # 后端
+    location /house-car/house/report/api {
+        proxy_pass http://172.16.107.4:39100;
+    }
+    # minio
+    location /house-car/oss {
+        proxy_pass http://172.16.107.4:39000;
+    }
+}
+

+ 19 - 0
scripts/openresty/conf.d/39203.car-report.conf

@@ -0,0 +1,19 @@
+server {
+    listen       39203;
+    listen  [::]:39203;
+    server_name localhost;
+
+    location / {
+        root   /app/car-report/dist;
+        index  index.html index.htm;
+        try_files $uri $uri/ /index.html;
+    }
+    # 后端
+    location /house-car/car/report/api {
+        proxy_pass http://172.16.107.4:39100;
+    }
+    # minio
+    location /house-car/oss {
+        proxy_pass http://172.16.107.4:39000;
+    }
+}

+ 19 - 0
scripts/openresty/conf.d/39204.car-resource-map.conf

@@ -0,0 +1,19 @@
+server {
+    listen       39204;
+    listen  [::]:39204;
+    server_name localhost;
+
+    location / {
+        root   /app/car-resource-map/dist;
+        index  index.html index.htm;
+        try_files $uri $uri/ /index.html;
+    }
+    # 后端
+    location /house-car/car/resource-map/api {
+        proxy_pass http://172.16.107.4:39100;
+    }
+    # minio
+    location /house-car/oss {
+        proxy_pass http://172.16.107.4:39000;
+    }
+}

+ 19 - 0
scripts/openresty/conf.d/39205.house-data-check.conf

@@ -0,0 +1,19 @@
+server {
+    listen       39205;
+    listen  [::]:39205;
+    server_name localhost;
+
+    location / {
+        root   /app/house-data-check/dist;
+        index  index.html index.htm;
+        try_files $uri $uri/ /index.html;
+    }
+    # 后端
+    location /house-car/house/data-check/api {
+        proxy_pass http://172.16.107.4:39100;
+    }
+    # minio
+    location /house-car/oss {
+        proxy_pass http://172.16.107.4:39000;
+    }
+}

+ 11 - 0
scripts/openresty/conf.d/39206.house-gdc.conf

@@ -0,0 +1,11 @@
+server {
+    listen       39206;
+    listen  [::]:39206;
+    server_name localhost;
+
+    location / {
+        root   /app/house-gdc/dist;
+        index  index.html index.htm;
+        try_files $uri $uri/ /index.html;
+    }
+}

+ 208 - 0
scripts/openresty/conf.d/8000.conf

@@ -0,0 +1,208 @@
+server {
+    listen       8000 ssl;
+    listen  [::]:8000 ssl;
+    server_name localhost;
+
+    ssl_certificate ssl/server.crt;
+    ssl_certificate_key ssl/server.key;
+    ssl_session_timeout 1h;
+    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
+    ssl_protocols TLSv1.2 TLSv1.3;
+    ssl_prefer_server_ciphers on;
+    server_tokens off;
+    proxy_hide_header X-Powered-By;
+    proxy_hide_header Server;
+    #add_header X-Frame-Options SAMEORIGIN;
+    #access_log  /var/log/nginx/host.access.log  main;
+
+    # minio
+    location /house-car/oss {
+        proxy_pass http://172.16.107.4:39000;
+    }
+    
+    # 百度地图
+    location /dugis-baidu/baidumap/jsapi {
+        proxy_pass http://172.16.107.4:39000/house-car/oss/public/dugis-baidu/baidumap/jsapi;
+    }
+
+    # 不动产后端接口
+    location /house-car/house/api {
+        proxy_pass http://172.16.107.4:39100;
+        access_by_lua_file lua/access.lua;
+        body_filter_by_lua_file lua/body_filter.lua;
+        log_by_lua_file lua/log.lua;
+    }
+
+    # 车辆后端接口
+    location /house-car/car/api {
+        proxy_pass http://172.16.107.4:39100;
+        access_by_lua_file lua/access.lua;
+        body_filter_by_lua_file lua/body_filter.lua;
+        log_by_lua_file lua/log.lua;
+    }
+
+    # 不动产资源地图接口
+    location /house-car/house/resource-map/api {
+        proxy_pass http://172.16.107.4:39100;
+        access_by_lua_file lua/access.lua;
+        body_filter_by_lua_file lua/body_filter.lua;
+        log_by_lua_file lua/log.lua;
+    }
+
+    # 不动产资源地图页面
+    location /house-car/house/resource-map {
+        rewrite ^/house-car/house/resource-map/(.*)$ /$1 break;
+        proxy_pass http://172.16.107.4:39201;
+    }
+
+    # 不动产报告页面接口
+    location /house-car/house/report/api {
+        proxy_pass http://172.16.107.4:39100;
+        access_by_lua_file lua/access.lua;
+        body_filter_by_lua_file lua/body_filter.lua;
+        log_by_lua_file lua/log.lua;
+    }
+
+    # 不动产报告页面
+    location /house-car/house/report {
+        rewrite ^/house-car/house/report/(.*)$ /$1 break;
+        proxy_pass http://172.16.107.4:39202;
+    }
+
+    # 车辆报告页面接口
+    location /house-car/car/report/api {
+        proxy_pass http://172.16.107.4:39100;
+        access_by_lua_file lua/access.lua;
+        body_filter_by_lua_file lua/body_filter.lua;
+        log_by_lua_file lua/log.lua;
+    }
+
+    # 车辆报告报告页面
+    location /house-car/car/report {
+        rewrite ^/house-car/car/report/(.*)$ /$1 break;
+        proxy_pass http://172.16.107.4:39203;
+    }
+
+    # 车辆资源地图接口
+    location /house-car/car/resource-map/api {
+        proxy_pass http://172.16.107.4:39100;
+        access_by_lua_file lua/access.lua;
+        body_filter_by_lua_file lua/body_filter.lua;
+        log_by_lua_file lua/log.lua;
+    }
+
+    # 车辆资源地图页面
+    location /house-car/car/resource-map {
+        rewrite ^/house-car/car/resource-map/(.*)$ /$1 break;
+        proxy_pass http://172.16.107.4:39204;
+    }
+
+    # 不动产数据稽查页面接口
+    location /house-car/house/DATA-CHECK/api {
+        proxy_pass http://172.16.107.4:39100;
+        access_by_lua_file lua/access.lua;
+        body_filter_by_lua_file lua/body_filter.lua;
+        log_by_lua_file lua/log.lua;
+    }
+
+    # 不动产数据稽查页面
+    location /house-car/house/DATA-CHECK {
+        rewrite ^/house-car/house/DATA-CHECK/(.*)$ /$1 break;
+        proxy_pass http://172.16.107.4:39205;
+    }
+
+    # 不动产数据稽查页面接口
+    location /house-car/house/data-check/api {
+        proxy_pass http://172.16.107.4:39100;
+        access_by_lua_file lua/access.lua;
+        body_filter_by_lua_file lua/body_filter.lua;
+        log_by_lua_file lua/log.lua;
+    }
+
+    # 不动产数据稽查页面
+    location /house-car/house/data-check {
+        rewrite ^/house-car/house/data-check/(.*)$ /$1 break;
+        proxy_pass http://172.16.107.4:39205;
+    }
+
+    # 不动产gdc接口
+    location /house-car/house/dist/api {
+        proxy_pass http://172.16.107.4:39101;
+        access_by_lua_file lua/access.lua;
+        body_filter_by_lua_file lua/body_filter.lua;
+        log_by_lua_file lua/log.lua;
+    }
+
+    # 不动产gdc页面
+    location /house-car/house/dist {
+        rewrite ^/house-car/house/dist/(.*)$ /$1 break;
+        proxy_pass http://172.16.107.4:39206;
+    }
+
+    #车辆系统
+    location /house-car/car/ {
+        proxy_redirect off;
+        proxy_set_header Host $host:$server_port;
+        proxy_set_header X-Real-IP  $remote_addr;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_pass https://172.16.107.4:8080/;
+        access_by_lua_file lua/access.lua;
+        body_filter_by_lua_file lua/body_filter.lua;
+        log_by_lua_file lua/log.lua;
+     }
+
+     location /house-car/car/assets/ {
+        #    add_header Access-Control-Allow-Origin '*' always;
+        #    add_header Access-Control-Allow-Headers '*';
+        #    add_header Access-Control-Allow-Methods '*';
+        #    add_header Access-Control-Allow-Credentials 'false';
+        #    if ($request_method = 'OPTIONS') {
+        #        return 204;
+        #    }
+        proxy_redirect off;
+        proxy_set_header Host $host:$server_port;
+        proxy_set_header X-Real-IP  $remote_addr;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_pass https://172.16.107.4:8080/assets/;
+     }
+
+     location /assets/ {
+        proxy_redirect off;
+        proxy_set_header Host $host:$server_port;
+        proxy_set_header X-Real-IP  $remote_addr;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_pass https://172.16.107.4:8080/assets/;
+     }
+
+    #error_page  404              /404.html;
+
+    # redirect server error pages to the static page /50x.html
+    #
+    error_page   500 502 503 504  /50x.html;
+    location = /50x.html {
+        root   /usr/share/nginx/html;
+    }
+
+    # proxy the PHP scripts to Apache listening on 172.16.107.4:80
+    #
+    #location ~ \.php$ {
+    #    proxy_pass   http://172.16.107.4;
+    #}
+
+    # pass the PHP scripts to FastCGI server listening on 172.16.107.4:9000
+    #
+    #location ~ \.php$ {
+    #    root           html;
+    #    fastcgi_pass   172.16.107.4:9000;
+    #    fastcgi_index  index.php;
+    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
+    #    include        fastcgi_params;
+    #}
+
+    # deny access to .htaccess files, if Apache's document root
+    # concurs with nginx's one
+    #
+    #location ~ /\.ht {
+    #    deny  all;
+    #}
+}

+ 185 - 0
scripts/openresty/conf.d/8080.conf

@@ -0,0 +1,185 @@
+server {
+    listen       8080 ssl;
+    listen  [::]:8080 ssl;
+    server_name localhost;
+   index index.php index.html index.htm default.php default.htm default.html;    
+   root /app/www/wwwroot/www.valuesys1.com/web;
+
+    ssl_certificate ssl/server.crt;
+    ssl_certificate_key ssl/server.key;
+    ssl_session_timeout 1h;
+    #ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
+    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
+    ssl_protocols TLSv1.2 TLSv1.3;
+    ssl_prefer_server_ciphers on;
+    server_tokens off;
+   
+    proxy_hide_header X-Powered-By;
+    add_header X-Powered-By "";
+    proxy_hide_header Server;
+   add_header X-Frame-Options "SAMEORIGIN";
+
+    add_header X-XSS-Protection "1; mode=block";
+
+    add_header X-Content-Type-Options "nosniff";
+    add_header Set-Cookie "Path=/; HttpOnly; Secure";
+   
+ #车辆系统 
+
+    #PHP-INFO-START  PHP引用配置,可以注释或修改
+    location ~ [^/]\.php(/|$)
+    {
+        try_files $uri =404;
+        fastcgi_pass  127.0.0.1:9000;
+        fastcgi_index index.php;
+        
+	fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
+	fastcgi_param  QUERY_STRING       $query_string;
+	fastcgi_param  REQUEST_METHOD     $request_method;
+	fastcgi_param  CONTENT_TYPE       $content_type;
+	fastcgi_param  CONTENT_LENGTH     $content_length;
+
+	fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
+	fastcgi_param  REQUEST_URI        $request_uri;
+	fastcgi_param  DOCUMENT_URI       $document_uri;
+	fastcgi_param  DOCUMENT_ROOT      $document_root;
+	fastcgi_param  SERVER_PROTOCOL    $server_protocol;
+	fastcgi_param  REQUEST_SCHEME     $scheme;
+	fastcgi_param  HTTPS              $https if_not_empty;
+
+	fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
+	fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
+
+	fastcgi_param  REMOTE_ADDR        $remote_addr;
+	fastcgi_param  REMOTE_PORT        $remote_port;
+	fastcgi_param  SERVER_ADDR        $server_addr;
+	fastcgi_param  SERVER_PORT        $server_port;
+	fastcgi_param  SERVER_NAME        $server_name;
+
+	# PHP only, required if PHP was built with --enable-force-cgi-redirect
+	fastcgi_param  REDIRECT_STATUS    200;
+	set $real_script_name $fastcgi_script_name;
+	if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
+			set $real_script_name $1;
+			set $path_info $2;
+	 }
+	fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;
+	fastcgi_param SCRIPT_NAME $real_script_name;
+	fastcgi_param PATH_INFO $path_info;
+    }
+	
+    #REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效
+    location ~* (runtime|application)/{
+	return 403;
+    }
+    
+    #location /house-car/car/ {
+     #   if (!-e $request_filename){
+      #          rewrite  ^(.*)$  /index.php?s=$1  last;   break;
+      #  }
+    #}
+
+    location / {
+	if (!-e $request_filename){
+     		#rewrite  ^/house-car/car/(.*)$ /index.php?s=$1 last;  break;
+		rewrite  ^(.*)$  /index.php?s=$1  last;   break;
+	}
+     }
+	
+    #REWRITE-END
+
+    #禁止访问的文件或目录
+    location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md)
+    {
+        return 404;
+    }
+
+    #一键申请SSL证书验证目录相关设置
+    location ~ \.well-known{
+        allow all;
+    }
+
+    #禁止在证书验证目录放入敏感文件
+    if ( $uri ~ "^/\.well-known/.*\.(php|jsp|py|js|css|lua|ts|go|zip|tar\.gz|rar|7z|sql|bak)$" ) {
+        return 403;
+    }
+
+    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
+    {
+        expires      30d;
+        error_log /dev/null;
+        access_log /dev/null;
+    }
+
+    location ~ .*\.(js|css)?$
+    {
+        expires      12h;
+        error_log /dev/null;
+        access_log /dev/null;
+    }
+    
+    access_log  /app/www/wwwlogs/www.valuesys1.com.log;
+    error_log  /app/www/wwwlogs/www.valuesys1.com.error.log;
+
+	#location /house-car/car/car/ {
+         #              proxy_redirect off;
+          #              proxy_set_header Host $host:$server_port;
+          #              proxy_set_header X-Real-IP  $remote_addr;
+        #		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        #		proxy_pass http://127.0.0.1:39080/car/;
+    	#       }
+      #location /house-car/car/assets/ {
+    
+       #	add_header Access-Control-Allow-Origin '*' always;
+        #    add_header Access-Control-Allow-Headers '*';
+        #    add_header Access-Control-Allow-Methods '*';
+        #    add_header Access-Control-Allow-Credentials 'false';
+        #    if ($request_method = 'OPTIONS') {
+        #        return 204;
+        #    }
+	#	proxy_redirect off;
+        #                proxy_set_header Host $host:$server_port;
+        #                proxy_set_header X-Real-IP  $remote_addr;
+        #                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+#
+#		proxy_pass http://127.0.0.1:39080/assets/;
+#		}
+
+	
+	
+
+
+
+	
+    #error_page  404              /404.html;
+
+    # redirect server error pages to the static page /50x.html
+    #
+    error_page   500 502 503 504  /50x.html;
+    location = /50x.html {
+        root   /usr/share/nginx/html;
+    }
+
+    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
+    #
+    #location ~ \.php$ {
+    #    proxy_pass   http://127.0.0.1;
+    #}
+
+    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
+    #
+    #location ~ \.php$ {
+    #    root           html;
+    #    fastcgi_pass   127.0.0.1:9000;
+    #    fastcgi_index  index.php;
+    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
+    #    include        fastcgi_params;
+    #}
+
+    # deny access to .htaccess files, if Apache's document root
+    # concurs with nginx's one
+    #
+    #location ~ /\.ht {
+    #    deny  all;
+    #}
+}

+ 95 - 0
scripts/openresty/conf/nginx.conf

@@ -0,0 +1,95 @@
+# nginx.conf  --  docker-openresty
+#
+# This file is installed to:
+#   `/usr/local/openresty/nginx/conf/nginx.conf`
+# and is the file loaded by nginx at startup,
+# unless the user specifies otherwise.
+#
+# It tracks the upstream OpenResty's `nginx.conf`, but removes the `server`
+# section and adds this directive:
+#     `include /etc/nginx/conf.d/*.conf;`
+#
+# The `docker-openresty` file `nginx.vh.default.conf` is copied to
+# `/etc/nginx/conf.d/default.conf`.  It contains the `server section
+# of the upstream `nginx.conf`.
+#
+# See https://github.com/openresty/docker-openresty/blob/master/README.md#nginx-config-files
+#
+
+#user  nobody;
+#worker_processes 1;
+
+# Enables the use of JIT for regular expressions to speed-up their processing.
+pcre_jit on;
+
+
+
+#error_log  logs/error.log;
+#error_log  logs/error.log  notice;
+#error_log  logs/error.log  info;
+
+#pid        logs/nginx.pid;
+
+
+events {
+    worker_connections  1024;
+}
+
+
+http {
+    include       mime.types;
+    default_type  application/octet-stream;
+
+    # Enables or disables the use of underscores in client request header fields.
+    # When the use of underscores is disabled, request header fields whose names contain underscores are marked as invalid and become subject to the ignore_invalid_headers directive.
+    # underscores_in_headers off;
+
+    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
+    #                  '$status $body_bytes_sent "$http_referer" '
+    #                  '"$http_user_agent" "$http_x_forwarded_for"';
+
+    #access_log  logs/access.log  main;
+
+        # Log in JSON Format
+        # log_format nginxlog_json escape=json '{ "timestamp": "$time_iso8601", '
+        # '"remote_addr": "$remote_addr", '
+        #  '"body_bytes_sent": $body_bytes_sent, '
+        #  '"request_time": $request_time, '
+        #  '"response_status": $status, '
+        #  '"request": "$request", '
+        #  '"request_method": "$request_method", '
+        #  '"host": "$host",'
+        #  '"upstream_addr": "$upstream_addr",'
+        #  '"http_x_forwarded_for": "$http_x_forwarded_for",'
+        #  '"http_referrer": "$http_referer", '
+        #  '"http_user_agent": "$http_user_agent", '
+        #  '"http_version": "$server_protocol", '
+        #  '"nginx_access": true }';
+        # access_log /dev/stdout nginxlog_json;
+
+    access_log  logs/access.log  combined;
+
+    # See Move default writable paths to a dedicated directory (#119)
+    # https://github.com/openresty/docker-openresty/issues/119
+    client_body_temp_path /var/run/openresty/nginx-client-body;
+    proxy_temp_path       /var/run/openresty/nginx-proxy;
+    fastcgi_temp_path     /var/run/openresty/nginx-fastcgi;
+    uwsgi_temp_path       /var/run/openresty/nginx-uwsgi;
+    scgi_temp_path        /var/run/openresty/nginx-scgi;
+
+    sendfile        on;
+    #tcp_nopush     on;
+
+    #keepalive_timeout  0;
+    keepalive_timeout  65;
+
+    #gzip  on;
+
+    include /etc/nginx/conf.d/*.conf;
+
+    # Don't reveal OpenResty version to clients.
+    server_tokens off;
+    more_clear_headers 'Server';
+}
+
+include /etc/nginx/conf.d/*.main;

+ 19 - 0
scripts/openresty/conf/ssl/server.crt

@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDEzCCAfsCFBfkrtwn5ofxDJZoFFzdd7ROm5slMA0GCSqGSIb3DQEBCwUAMEUx
+CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl
+cm5ldCBXaWRnaXRzIFB0eSBMdGQwIBcNMjUwMTIxMDE0OTM2WhgPMjEyNDEyMjgw
+MTQ5MzZaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
+VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQCcz9e4v3Zn/aczW+4YQlkxXCsKRrVcjAsCB4Dok/f6Wytv
+LP3GKI8eZTr/ZSz8y22zWp5ZXWpe5QDu2XprCS4Qfy1YR80TKw0Pr7H6ppAdjp3C
+V7s1RFVut02KYQpfzc0V3ArUTSyNpL018le40dew8RUYRG0j0ERSqjhHautfRr+Y
+40hEqVPAhl5Sv7jR/41FBomH6YR54v44FFo66sJfuWwvhvun7DXund9mxX+Ucn3J
+6m3UdX4/3toHt2YwpLqw+DUmdFWErcZsZ2iljdOlp4tMJLfh6KcDicyuBJ/76BoP
+01+oje71Pwot9SJXpRZOp36uEumyZQPaLJQhrrL5AgMBAAEwDQYJKoZIhvcNAQEL
+BQADggEBAEmEV7nPWCgFQEZieKN6qj1QA/9owyYmu2x8YsUq2e+cERdNYXTRRIx1
+6q8dHJJAGh35QPQ3esekqbgffl60GYCv0JX+Kw1DIVQfWOMtu32EpOcacz8Xb8IP
+Wlh+1COnfXNVtmJWiEgPnfGNRwbxY/wcXZHZdG2gI80bNwpy5GrhqIuCW0razagJ
+F00XQINbZdeoShs8fDID/M8h4wsrvnFtl4CuoQvjO9Ad1WOCf8NFQCpP4z1DiP10
+uI1sva41+WpZmC/fWOCz6gkgXMN8r0N7y03Aa3hIol6UbVXZDyv4lziJZi/koK5A
+FeQ1lSQ9zRhl9uC/kPH804VtRtiaCuE=
+-----END CERTIFICATE-----

+ 16 - 0
scripts/openresty/conf/ssl/server.csr

@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICijCCAXICAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx
+ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBAJzP17i/dmf9pzNb7hhCWTFcKwpGtVyMCwIHgOiT
+9/pbK28s/cYojx5lOv9lLPzLbbNanlldal7lAO7ZemsJLhB/LVhHzRMrDQ+vsfqm
+kB2OncJXuzVEVW63TYphCl/NzRXcCtRNLI2kvTXyV7jR17DxFRhEbSPQRFKqOEdq
+619Gv5jjSESpU8CGXlK/uNH/jUUGiYfphHni/jgUWjrqwl+5bC+G+6fsNe6d32bF
+f5RyfcnqbdR1fj/e2ge3ZjCkurD4NSZ0VYStxmxnaKWN06Wni0wkt+HopwOJzK4E
+n/voGg/TX6iN7vU/Ci31IlelFk6nfq4S6bJlA9oslCGusvkCAwEAAaAAMA0GCSqG
+SIb3DQEBCwUAA4IBAQAZOBoMAvSwBWrDiMb5KpLgMFvEOMSWDr9Cu+zq5M7TnGEm
+ktkQN/79qhDRNyrGIOQhJ9oKQZetarGGenlZHfwBC8ctTiWDNbiFOjdMwoih6NOO
+kennfi3ACYi0M84ctdZOxVM5YrRNyghlgepdfTKJRiOuVmyyKk1wlei8VdEVErWp
+5HKbcRSUtZovLPfLMxEUWmfuGssre86JR3DmyoebLWCcqM6UyZmtgGNV2pvEZoVu
+Mltm6dtRv6JsEMJYuAx3Q8k4mTiolOWg+x1xRotaV0Upi7J/fBrOkS9yYdiopN4C
+W3PpaqMcv/2VB1vHByHqkSGY4AAa/DHRziLPCCqs
+-----END CERTIFICATE REQUEST-----

+ 28 - 0
scripts/openresty/conf/ssl/server.key

@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCcz9e4v3Zn/acz
+W+4YQlkxXCsKRrVcjAsCB4Dok/f6WytvLP3GKI8eZTr/ZSz8y22zWp5ZXWpe5QDu
+2XprCS4Qfy1YR80TKw0Pr7H6ppAdjp3CV7s1RFVut02KYQpfzc0V3ArUTSyNpL01
+8le40dew8RUYRG0j0ERSqjhHautfRr+Y40hEqVPAhl5Sv7jR/41FBomH6YR54v44
+FFo66sJfuWwvhvun7DXund9mxX+Ucn3J6m3UdX4/3toHt2YwpLqw+DUmdFWErcZs
+Z2iljdOlp4tMJLfh6KcDicyuBJ/76BoP01+oje71Pwot9SJXpRZOp36uEumyZQPa
+LJQhrrL5AgMBAAECggEAOUvQHJcIopKR5zgt1PtZL6nnqAeR+NDKrOEk/tYiA34Q
+brzXtPHY6Vg/qFXFjFCgMqpntWtmlGnEX4FjM3zVMf3mCZ2iluBiE1s1AsqdWc9k
+YUBBDQN828lqMaenbL37s4MFCfFw2AhbgjycRNGXp/VOqeFGp5FPhYzgp2evvM3A
+bmWKK0D2ikx1hqTgjxncLnZPAqW0KJt7sUW+YKAfW/91AGp9Y4PM5r7DgssO7qHT
+n1FnGTr4V6IIbf4Yyi1RB5ycDpI0Y0Qy+qL19dQbiFXiH4lqvWWH4A33wlNzWYZw
+R1dWNYnTlCFtBw1SaIXQmyiTdW4BNF408iPMkcQ5AQKBgQDPefV8ZhfRpIxMVJTO
+EK+jFxxaI7UuyfZ3TcPTGr+QPQM+rxElM76t1KY0obcIVLzDAGYl6gXdPDJ7Vncw
+kMHfZssAfeXkEDhbbb++VivtVKBPWw9/9+FnYWa/Dp4b7SvuWAlrnfdKUX1MZjnB
+mcaEpn3SH1HgIZMsDMnVBtZ/6QKBgQDBfH6QZi3EGa2nprEdjsMPvjv5ivCh6KGf
+5vE8B7P5HCkBvD+NZLTUNqo4gxazWvwHcuO5JSYU1MehbHCQ4Ku463tmsyMvAc4b
+BOub7u4VTuV3y2noR+7GTFBBbT9/iR/q093oL8qx6wKqFTFztWvd6gFHJTiTAGpt
+o8T8lMZAkQKBgCFqOAJIAxANm1bzzF9/ynnO0A8obxbRCjPev2oxhaa6XNpsoatH
+MS+X7wjM/siFtT0GxGzYywb9mffJTjrxJXhQeuNiY3MetaTsARSrljmMBqGhPdbT
+WmcnBcBBn29J/GhPn3zInTpH85EpaaXnmVRl6B++UZZycdyHVr5LcqJ5AoGAFX7w
+TLidYwj7SwHw8Xi34RrgbOPrwgEnW617pZCxhP6E68VvRhUnJeCA3tBpiDmWgHla
+JWqkJXJST3PNubrMOTooNou2X/WSYVwVlPhhiQp/4eQ+eujq9SrrS6mIgXHJkvxA
+zhfpLAURAbZjDRjdyATEaZQQCfzk1hN4whsBP5ECgYEAgxC2QiU1FhobUDzS/XUy
+LQTuIdEUX7NGG96lWUyFzVlrbCpZZHeo2oNgXinjIAcpDjENyvHl+s8CES5PYrdx
+nV5iXDHws8HV8r61PMbn3hdy1jVSVk6nFBjPhFy+NsuskrzxUOi29XkMctUWI0wa
+T0jNQaahJ77yJA8ul8JQDxA=
+-----END PRIVATE KEY-----

+ 7 - 0
scripts/openresty/lua/access.lua

@@ -0,0 +1,7 @@
+local cjson = require "cjson"
+local args = ngx.req.get_uri_args()
+local request_headers = ngx.req.get_headers()
+if request_headers["token"] or args["token"] or args["data"] or args["amp;data"] then
+    ngx.ctx.log_request = true
+    ngx.req.read_body()
+end

+ 9 - 0
scripts/openresty/lua/body_filter.lua

@@ -0,0 +1,9 @@
+local response_headers = ngx.resp.get_headers()
+local response_content_type = response_headers["content-type"] or ""
+if ngx.ctx.log_request and response_content_type:match("application/json") then
+    local chunk = ngx.arg[1]
+    local eof = ngx.arg[2]
+    if not eof then
+        ngx.ctx.response_body = (ngx.ctx.response_body or "") .. chunk
+    end
+end

+ 76 - 0
scripts/openresty/lua/log.lua

@@ -0,0 +1,76 @@
+if ngx.ctx.log_request then
+    local cjson = require "cjson"
+    local args = ngx.req.get_uri_args()
+    local query_string = ""
+    pcall(function()
+        query_string = cjson.encode(args)
+    end)
+    local request_headers = ngx.req.get_headers()
+    local token = request_headers["token"] or args["token"] or args["data"] or args["amp;data"] or ""
+    local request_content_type = request_headers["content-type"] or ""
+    local response_headers = ngx.resp.get_headers()
+    local response_content_type = response_headers["content-type"] or ""
+    local request_body = ""
+    if request_content_type:match("application/json") then
+        request_body = ngx.var.request_body or ""
+    end
+    local response_body = ""
+    if response_content_type:match("application/json") then
+        response_body = ngx.ctx.response_body or ""
+    end
+    request_headers_json = ""
+    pcall(function()
+        request_headers_json = cjson.encode(request_headers)
+    end)
+    response_headers_json = ""
+    pcall(function()
+        response_headers_json = cjson.encode(response_headers)
+    end)
+    local logger = require "resty.logger.socket"
+    if not logger.initted() then
+        local ok, err = logger.init{
+            host = "127.0.0.1",
+            port = 39876,
+            sock_type = "tcp",
+            flush_limit = 10240,
+            drop_limit = 1048576,
+            timeout = 1000,
+            max_retry_times = 3,
+            retry_interval = 10000
+        }
+        if not ok then
+            ngx.log(ngx.ERR, "Logger初始化失败: ", err)
+            return
+        end
+    end
+    local log_data = {
+        access_time = ngx.var.time_iso8601,
+        status = ngx.var.status,
+        request_time = ngx.var.request_time,
+        uri = ngx.var.uri,
+        query_string = query_string,
+        request_body = request_body,
+        request_headers = request_headers_json,
+        response_headers = response_headers_json,
+        response_body = response_body,
+        token = token,
+        request_method = ngx.var.request_method,
+        scheme = ngx.var.scheme,
+        server_protocol = ngx.var.server_protocol,
+        request_length = ngx.var.request_length,
+        body_bytes_sent = ngx.var.body_bytes_sent,
+        bytes_sent = ngx.var.bytes_sent,
+        http_x_real_ip = ngx.var.http_x_real_ip,
+        http_x_forwarded_for = ngx.var.http_x_forwarded_for,
+        remote_addr = ngx.var.remote_addr
+    }
+    local success, result = pcall(cjson.encode, log_data)
+    if not success then
+        print("JSON编码失败: ", result)
+        return
+    end
+    local bytes, err = logger.log(result .. "\n")
+    if err then
+        ngx.log(ngx.ERR, "日志发送失败: ", err)
+    end
+end

+ 10 - 0
scripts/restore-financialdb.sh

@@ -0,0 +1,10 @@
+#!/bin/sh
+
+export PGPASSWORD='Finance@unicom23'
+backup_dir=$1
+host='172.16.107.5'
+port='5432'
+username='finance'
+dbname='financialdb'
+jobs='16'
+pg_restore -O -c -v -h "${host}" -p "${port}" -U "${username}" -d "${dbname}" -Fd -j "${jobs}" "${backup_dir}"

+ 9 - 0
scripts/rollback-page.sh

@@ -0,0 +1,9 @@
+#!/bin/bash
+
+DIST_BAK="dist-bak"
+DIST="dist"
+
+if [ -d "$DIST_BAK" ]; then
+  rm -rf "$DIST"
+  mv "$DIST_BAK" "$DIST"
+fi

+ 9 - 0
scripts/start-libreoffice.sh

@@ -0,0 +1,9 @@
+#!/bin/bash
+
+docker run --name=libreoffice \
+--restart unless-stopped \
+--security-opt seccomp=unconfined `#optional` \
+-e TZ=Asia/Shanghai \
+-v /app/libreoffice:/app/libreoffice \
+-v /var/run/docker.sock:/var/run/docker.sock \
+-d libreoffice:7.6.7

+ 13 - 0
scripts/start-minio.sh

@@ -0,0 +1,13 @@
+#!/bin/bash
+
+docker run \
+--name minio \
+--network=host \
+--restart=unless-stopped \
+-v minio-data:/data \
+-v /etc/timezone:/etc/timezone:ro \
+-v /etc/localtime:/etc/localtime:ro \
+-e "MINIO_ROOT_USER=admin" \
+-e "MINIO_ROOT_PASSWORD=nrPnZx7Yh5d7vPo8WCrY" \
+-e "MINIO_BROWSER=off" \
+-d minio:RELEASE.2025-01-18T00-31-37Z server /data --address ":39000"

+ 13 - 0
scripts/start-openresty.sh

@@ -0,0 +1,13 @@
+#!/bin/bash
+
+docker run --name openresty \
+--network=host \
+--restart unless-stopped \
+-e TZ='Asia/Shanghai' \
+-v /app/openresty/conf:/usr/local/openresty/nginx/conf \
+-v /app/openresty/conf.d:/etc/nginx/conf.d \
+-v /app/openresty/logs:/usr/local/openresty/nginx/logs \
+-v /app/openresty/lua:/usr/local/openresty/nginx/lua \
+-v /app:/app \
+-v /etc/localtime:/etc/localtime:ro \
+-d openresty:1.27.1.2-bookworm

+ 11 - 0
scripts/update-page.sh

@@ -0,0 +1,11 @@
+#!/bin/bash
+
+ZIP_FILE="dist.zip"
+DIST_DIR="dist"
+DIST_BAK_DIR="dist-bak"
+
+if [ -f "$ZIP_FILE" ]; then
+    rm -rf "$DIST_BAK_DIR"
+    mv "$DIST_DIR" "$DIST_BAK_DIR"
+    unzip "$ZIP_FILE"
+fi

+ 10 - 0
src/main/java/com/nokia/finance/tasks/dao/common/NginxLogDao.java

@@ -0,0 +1,10 @@
+package com.nokia.finance.tasks.dao.common;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.nokia.finance.tasks.pojo.po.common.NginxLogPo;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface NginxLogDao extends BaseMapper<NginxLogPo> {
+
+}

+ 67 - 67
src/main/java/com/nokia/finance/tasks/dao/common/RequestLogDao.java

@@ -1,67 +1,67 @@
-package com.nokia.finance.tasks.dao.common;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.nokia.finance.tasks.pojo.po.common.CarPhpRequestLogPo;
-import com.nokia.finance.tasks.pojo.po.common.RequestLogPo;
-import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.annotations.Select;
-import org.apache.ibatis.annotations.Update;
-
-import java.util.List;
-
-@Mapper
-public interface RequestLogDao extends BaseMapper<RequestLogPo> {
-    /**
-     * 批量插入
-     */
-    @Update("""
-<script>
-insert into common.request_log
-(
-request_time,
-login_id,
-page_url,
-api,
-request_parameters,
-headers,
-app_id,
-time_stamp,
-token,
-expire_time,
-expire_time_stamp
-)
-values
-<foreach collection="list" item="item" index="index" separator=",">
-(
-#{item.requestTime},
-#{item.loginId},
-#{item.pageUrl},
-#{item.api},
-#{item.requestParameters},
-#{item.headers},
-#{item.appId},
-#{item.timeStamp},
-#{item.token},
-#{item.expireTime},
-#{item.expireTimeStamp}
-)
-</foreach>
-</script>
-""")
-    int insertBatch(List<RequestLogPo> list);
-
-    @Select("""
-select
-    to_timestamp(create_time)::timestamp as request_time,
-    query_string
-from
-    car_theme.wz_adminlog
-where create_time >= #{startTime}
-and create_time < #{endTime}
-order by
-    create_time
-""")
-    List<CarPhpRequestLogPo> listCarPhpRequestLog(@Param("startTime") Long startTime,
-                                                  @Param("endTime") Long endTime);
-}
+//package com.nokia.finance.tasks.dao.common;
+//
+//import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+//import com.nokia.finance.tasks.pojo.po.common.CarPhpRequestLogPo;
+//import com.nokia.finance.tasks.pojo.po.common.RequestLogPo;
+//import org.apache.ibatis.annotations.Mapper;
+//import org.apache.ibatis.annotations.Param;
+//import org.apache.ibatis.annotations.Select;
+//import org.apache.ibatis.annotations.Update;
+//
+//import java.util.List;
+//
+//@Mapper
+//public interface RequestLogDao extends BaseMapper<RequestLogPo> {
+//    /**
+//     * 批量插入
+//     */
+//    @Update("""
+//<script>
+//insert into common.request_log
+//(
+//request_time,
+//login_id,
+//page_url,
+//api,
+//request_parameters,
+//headers,
+//app_id,
+//time_stamp,
+//token,
+//expire_time,
+//expire_time_stamp
+//)
+//values
+//<foreach collection="list" item="item" index="index" separator=",">
+//(
+//#{item.requestTime},
+//#{item.loginId},
+//#{item.pageUrl},
+//#{item.api},
+//#{item.requestParameters},
+//#{item.headers},
+//#{item.appId},
+//#{item.timeStamp},
+//#{item.token},
+//#{item.expireTime},
+//#{item.expireTimeStamp}
+//)
+//</foreach>
+//</script>
+//""")
+//    int insertBatch(List<RequestLogPo> list);
+//
+//    @Select("""
+//select
+//    to_timestamp(create_time)::timestamp as request_time,
+//    query_string
+//from
+//    car_theme.wz_adminlog
+//where create_time >= #{startTime}
+//and create_time < #{endTime}
+//order by
+//    create_time
+//""")
+//    List<CarPhpRequestLogPo> listCarPhpRequestLog(@Param("startTime") Long startTime,
+//                                                  @Param("endTime") Long endTime);
+//}

+ 121 - 121
src/main/java/com/nokia/finance/tasks/jobs/gdc/car/CarPhpRequestLogJob.java

@@ -1,121 +1,121 @@
-package com.nokia.finance.tasks.jobs.gdc.car;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.type.TypeFactory;
-import com.nokia.finance.tasks.dao.common.RequestLogDao;
-import com.nokia.finance.tasks.pojo.po.common.CarPhpRequestLogPo;
-import com.nokia.finance.tasks.pojo.po.common.RequestLogPo;
-import com.nokia.finance.tasks.utils.AESUtil;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Service;
-import org.springframework.util.CollectionUtils;
-import org.springframework.util.MultiValueMap;
-import org.springframework.util.StringUtils;
-import org.springframework.web.util.UriComponents;
-import org.springframework.web.util.UriComponentsBuilder;
-
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
-import java.time.LocalDateTime;
-import java.time.ZoneOffset;
-import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
-
-/**
- * 车辆php页面请求日志入库定时任务
- */
-@Slf4j
-@Service
-@RequiredArgsConstructor
-public class CarPhpRequestLogJob {
-    private final RequestLogDao requestLogDao;
-    private final ObjectMapper objectMapper;
-
-    /**
-     * 执行任务
-     */
-    @Scheduled(cron = "0 30 * * * ?")
-    public void runJob() {
-        log.info("执行车辆php页面请求日志入库定时任务");
-        try {
-            CompletableFuture.runAsync(() -> {
-//                LocalDateTime startLocalDateTime = LocalDateTime.of(2024, 3, 23, 0, 0);
-//                LocalDateTime endLocalDateTime = LocalDateTime.of(2024, 3, 25, 18, 0);
-                LocalDateTime now = LocalDateTime.now();
-                LocalDateTime startLocalDateTime = now.minusHours(1).withMinute(0).withSecond(0).withNano(0);
-                LocalDateTime endLocalDateTime = startLocalDateTime.plusHours(1);
-                Long startTime = startLocalDateTime.toEpochSecond(ZoneOffset.ofHours(8));
-                Long endTime = endLocalDateTime.toEpochSecond(ZoneOffset.ofHours(8));
-                List<CarPhpRequestLogPo> carPhpRequestLogPoList = requestLogDao.listCarPhpRequestLog(startTime, endTime);
-                List<RequestLogPo> list = new ArrayList<>();
-                for (CarPhpRequestLogPo carPhpRequestLogPo : carPhpRequestLogPoList) {
-                    try {
-                        LocalDateTime requestTime = carPhpRequestLogPo.getRequestTime();
-                        String queryString = carPhpRequestLogPo.getQueryString();
-                        if (requestTime == null || !StringUtils.hasText(queryString)) {
-                            continue;
-                        }
-                        UriComponents uriComponents = UriComponentsBuilder.fromUriString("?" + queryString).build();
-                        MultiValueMap<String, String> queryParams = uriComponents.getQueryParams();
-                        Map<String, String> singleValueMap = queryParams.toSingleValueMap();
-                        String data = singleValueMap.get("data");
-                        if (!StringUtils.hasText(data)) {
-                            continue;
-                        }
-                        String urlDecodeToken = URLDecoder.decode(data, StandardCharsets.UTF_8);
-                        String decryptToken = AESUtil.decrypt(urlDecodeToken);
-                        Map<String, String> tokenMap = objectMapper.readValue(decryptToken,
-                                TypeFactory.defaultInstance().constructMapType(Map.class, String.class, String.class));
-                        if (!"FINANCE".equals(tokenMap.get("APP_ID"))
-                                || !StringUtils.hasText(tokenMap.get("LOGIN_ID"))
-                                || !StringUtils.hasText(tokenMap.get("TIME_STAMP"))
-                                || !StringUtils.hasText(tokenMap.get("EXPIRE_TIME"))
-                        ) {
-                            continue;
-                        }
-                        LocalDateTime timeStamp = LocalDateTime.parse(tokenMap.get("TIME_STAMP"),
-                                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
-                        int expireTime = Integer.parseInt(tokenMap.get("EXPIRE_TIME"));
-                        LocalDateTime expireTimeStamp = timeStamp.plusSeconds(expireTime);
-                        String loginId = tokenMap.get("LOGIN_ID");
-                        String pageUrl = tokenMap.get("REQUEST_URL");
-                        String api = StringUtils.hasText(singleValueMap.get("type")) ? pageUrl + "?type=" + singleValueMap.get("type") : pageUrl;
-                        Map<String, String> requestParameters = new HashMap<>();
-                        requestParameters.put("request_parameters", objectMapper.writeValueAsString(singleValueMap));
-                        String appId = tokenMap.get("APP_ID");
-                        RequestLogPo requestLogPo = new RequestLogPo();
-                        requestLogPo.setRequestTime(carPhpRequestLogPo.getRequestTime());
-                        requestLogPo.setLoginId(loginId);
-                        requestLogPo.setPageUrl(pageUrl);
-                        requestLogPo.setApi(api);
-                        requestLogPo.setRequestParameters(objectMapper.writeValueAsString(requestParameters));
-                        requestLogPo.setAppId(appId);
-                        requestLogPo.setToken(urlDecodeToken);
-                        requestLogPo.setTimeStamp(timeStamp);
-                        requestLogPo.setExpireTime(expireTime);
-                        requestLogPo.setExpireTimeStamp(expireTimeStamp);
-                        list.add(requestLogPo);
-                    } catch (Exception e) {
-                        log.error("请求日志解析失败: {} -> {}", carPhpRequestLogPo, e, e);
-                    }
-                }
-                if (CollectionUtils.isEmpty(list)) {
-                    return;
-                }
-                requestLogDao.insertBatch(list);
-            }).get(1, TimeUnit.MINUTES);
-        } catch (InterruptedException e) {
-            log.error("线程中断: {}", e, e);
-            Thread.currentThread().interrupt();
-        } catch (Exception e) {
-            log.error(e.toString(), e);
-        }
-    }
-}
+//package com.nokia.finance.tasks.jobs.gdc.car;
+//
+//import com.fasterxml.jackson.databind.ObjectMapper;
+//import com.fasterxml.jackson.databind.type.TypeFactory;
+//import com.nokia.finance.tasks.dao.common.RequestLogDao;
+//import com.nokia.finance.tasks.pojo.po.common.CarPhpRequestLogPo;
+//import com.nokia.finance.tasks.pojo.po.common.RequestLogPo;
+//import com.nokia.finance.tasks.utils.AESUtil;
+//import lombok.RequiredArgsConstructor;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.scheduling.annotation.Scheduled;
+//import org.springframework.stereotype.Service;
+//import org.springframework.util.CollectionUtils;
+//import org.springframework.util.MultiValueMap;
+//import org.springframework.util.StringUtils;
+//import org.springframework.web.util.UriComponents;
+//import org.springframework.web.util.UriComponentsBuilder;
+//
+//import java.net.URLDecoder;
+//import java.nio.charset.StandardCharsets;
+//import java.time.LocalDateTime;
+//import java.time.ZoneOffset;
+//import java.time.format.DateTimeFormatter;
+//import java.util.ArrayList;
+//import java.util.HashMap;
+//import java.util.List;
+//import java.util.Map;
+//import java.util.concurrent.CompletableFuture;
+//import java.util.concurrent.TimeUnit;
+//
+///**
+// * 车辆php页面请求日志入库定时任务
+// */
+//@Slf4j
+//@Service
+//@RequiredArgsConstructor
+//public class CarPhpRequestLogJob {
+//    private final RequestLogDao requestLogDao;
+//    private final ObjectMapper objectMapper;
+//
+//    /**
+//     * 执行任务
+//     */
+//    @Scheduled(cron = "0 30 * * * ?")
+//    public void runJob() {
+//        log.info("执行车辆php页面请求日志入库定时任务");
+//        try {
+//            CompletableFuture.runAsync(() -> {
+////                LocalDateTime startLocalDateTime = LocalDateTime.of(2024, 3, 23, 0, 0);
+////                LocalDateTime endLocalDateTime = LocalDateTime.of(2024, 3, 25, 18, 0);
+//                LocalDateTime now = LocalDateTime.now();
+//                LocalDateTime startLocalDateTime = now.minusHours(1).withMinute(0).withSecond(0).withNano(0);
+//                LocalDateTime endLocalDateTime = startLocalDateTime.plusHours(1);
+//                Long startTime = startLocalDateTime.toEpochSecond(ZoneOffset.ofHours(8));
+//                Long endTime = endLocalDateTime.toEpochSecond(ZoneOffset.ofHours(8));
+//                List<CarPhpRequestLogPo> carPhpRequestLogPoList = requestLogDao.listCarPhpRequestLog(startTime, endTime);
+//                List<RequestLogPo> list = new ArrayList<>();
+//                for (CarPhpRequestLogPo carPhpRequestLogPo : carPhpRequestLogPoList) {
+//                    try {
+//                        LocalDateTime requestTime = carPhpRequestLogPo.getRequestTime();
+//                        String queryString = carPhpRequestLogPo.getQueryString();
+//                        if (requestTime == null || !StringUtils.hasText(queryString)) {
+//                            continue;
+//                        }
+//                        UriComponents uriComponents = UriComponentsBuilder.fromUriString("?" + queryString).build();
+//                        MultiValueMap<String, String> queryParams = uriComponents.getQueryParams();
+//                        Map<String, String> singleValueMap = queryParams.toSingleValueMap();
+//                        String data = singleValueMap.get("data");
+//                        if (!StringUtils.hasText(data)) {
+//                            continue;
+//                        }
+//                        String urlDecodeToken = URLDecoder.decode(data, StandardCharsets.UTF_8);
+//                        String decryptToken = AESUtil.decrypt(urlDecodeToken);
+//                        Map<String, String> tokenMap = objectMapper.readValue(decryptToken,
+//                                TypeFactory.defaultInstance().constructMapType(Map.class, String.class, String.class));
+//                        if (!"FINANCE".equals(tokenMap.get("APP_ID"))
+//                                || !StringUtils.hasText(tokenMap.get("LOGIN_ID"))
+//                                || !StringUtils.hasText(tokenMap.get("TIME_STAMP"))
+//                                || !StringUtils.hasText(tokenMap.get("EXPIRE_TIME"))
+//                        ) {
+//                            continue;
+//                        }
+//                        LocalDateTime timeStamp = LocalDateTime.parse(tokenMap.get("TIME_STAMP"),
+//                                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+//                        int expireTime = Integer.parseInt(tokenMap.get("EXPIRE_TIME"));
+//                        LocalDateTime expireTimeStamp = timeStamp.plusSeconds(expireTime);
+//                        String loginId = tokenMap.get("LOGIN_ID");
+//                        String pageUrl = tokenMap.get("REQUEST_URL");
+//                        String api = StringUtils.hasText(singleValueMap.get("type")) ? pageUrl + "?type=" + singleValueMap.get("type") : pageUrl;
+//                        Map<String, String> requestParameters = new HashMap<>();
+//                        requestParameters.put("request_parameters", objectMapper.writeValueAsString(singleValueMap));
+//                        String appId = tokenMap.get("APP_ID");
+//                        RequestLogPo requestLogPo = new RequestLogPo();
+//                        requestLogPo.setRequestTime(carPhpRequestLogPo.getRequestTime());
+//                        requestLogPo.setLoginId(loginId);
+//                        requestLogPo.setPageUrl(pageUrl);
+//                        requestLogPo.setApi(api);
+//                        requestLogPo.setRequestParameters(objectMapper.writeValueAsString(requestParameters));
+//                        requestLogPo.setAppId(appId);
+//                        requestLogPo.setToken(urlDecodeToken);
+//                        requestLogPo.setTimeStamp(timeStamp);
+//                        requestLogPo.setExpireTime(expireTime);
+//                        requestLogPo.setExpireTimeStamp(expireTimeStamp);
+//                        list.add(requestLogPo);
+//                    } catch (Exception e) {
+//                        log.error("请求日志解析失败: {} -> {}", carPhpRequestLogPo, e, e);
+//                    }
+//                }
+//                if (CollectionUtils.isEmpty(list)) {
+//                    return;
+//                }
+//                requestLogDao.insertBatch(list);
+//            }).get(1, TimeUnit.MINUTES);
+//        } catch (InterruptedException e) {
+//            log.error("线程中断: {}", e, e);
+//            Thread.currentThread().interrupt();
+//        } catch (Exception e) {
+//            log.error(e.toString(), e);
+//        }
+//    }
+//}

+ 138 - 0
src/main/java/com/nokia/finance/tasks/pojo/po/common/NginxLogPo.java

@@ -0,0 +1,138 @@
+package com.nokia.finance.tasks.pojo.po.common;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Data
+@TableName("common.nginx_log")
+public class NginxLogPo {
+
+    /**
+     * 访问时间
+     */
+    private LocalDateTime accessTime;
+
+    /**
+     * 响应状态码
+     */
+    private Integer status;
+
+    /**
+     * 请求处理的总时间(秒,精确到毫秒)
+     */
+    private BigDecimal requestTime;
+
+    /**
+     * 当前处理的URI(不带参数)
+     */
+    private String uri;
+
+    /**
+     * 账号,从token解密
+     */
+    private String loginId;
+
+    /**
+     * 页面url,从token解密
+     */
+    private String pageUrl;
+
+    /**
+     * 应用id,从token解密
+     */
+    private String appId;
+
+    /**
+     * 访问令牌
+     */
+    private String token;
+
+    /**
+     * 时间戳,从token解密
+     */
+    private LocalDateTime timeStamp;
+
+    /**
+     * 过期秒数,从token解密
+     */
+    private Integer expireTime;
+
+    /**
+     * token过期时间
+     */
+    private LocalDateTime expireTimeStamp;
+
+    /**
+     * 请求中的查询参数
+     */
+    private String queryString;
+
+    /**
+     * 请求体内容
+     */
+    private String requestBody;
+
+    /**
+     * 请求头
+     */
+    private String requestHeaders;
+
+    /**
+     * 响应头
+     */
+    private String responseHeaders;
+
+    /**
+     * 响应体内容
+     */
+    private String responseBody;
+
+
+    /**
+     * 请求方法
+     */
+    private String requestMethod;
+
+    /**
+     * 请求协议
+     */
+    private String scheme;
+
+    /**
+     * 请求协议版本
+     */
+    private String serverProtocol;
+
+    /**
+     * 请求的总长度(请求行+头+体)
+     */
+    private Integer requestLength;
+
+    /**
+     * 发送给客户端的响应体字节数(不包含头)
+     */
+    private Integer bodyBytesSent;
+
+    /**
+     * 发送给客户端的总字节数(包括头和体)
+     */
+    private Integer bytesSent;
+
+    /**
+     * 传递客户端真实 IP
+     */
+    private String httpXRealIp;
+
+    /**
+     * 请求路径中的所有代理 IP 和客户端 IP
+     */
+    private String httpXForwardedFor;
+
+    /**
+     * 客户端IP地址
+     */
+    private String remoteAddr;
+}

+ 206 - 0
src/main/java/com/nokia/finance/tasks/service/common/NginxLogService.java

@@ -0,0 +1,206 @@
+package com.nokia.finance.tasks.service.common;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.type.TypeFactory;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.nokia.finance.tasks.dao.common.NginxLogDao;
+import com.nokia.finance.tasks.pojo.po.common.NginxLogPo;
+import com.nokia.finance.tasks.utils.AESUtil;
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.SimpleChannelInboundHandler;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.handler.codec.LineBasedFrameDecoder;
+import io.netty.handler.codec.string.StringDecoder;
+import lombok.Data;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.SmartLifecycle;
+import org.springframework.stereotype.Service;
+
+import java.net.InetSocketAddress;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Map;
+
+/**
+ * 接收nginx日志并记录到数据库
+ */
+@Slf4j
+@Data
+@Service
+@ConfigurationProperties("nginx-log")
+@RequiredArgsConstructor
+public class NginxLogService implements SmartLifecycle {
+    // 定义服务监听的端口号
+    private Integer port;
+    // 定义接收消息的最大长度
+    private Integer maxLength;
+    // 标志变量,用于标识服务是否正在运行
+    private volatile boolean running = false;
+    // Netty 的主事件循环组,用于接收客户端连接
+    private EventLoopGroup parentGroup;
+    // Netty 的子事件循环组,用于处理客户端连接后的数据读写
+    private EventLoopGroup childGroup;
+    // 保存绑定到指定端口的 ChannelFuture 对象
+    private ChannelFuture channelFuture;
+    // 注入的 Mapper 接口,用于操作数据库
+    private final NginxLogDao nginxLogDao;
+
+    /**
+     * 启动方法,初始化并启动 TCP 服务
+     */
+    @Override
+    public void start() {
+        // 初始化主事件循环组和子事件循环组
+        parentGroup = new NioEventLoopGroup();
+        childGroup = new NioEventLoopGroup();
+        try {
+            // 使用 ServerBootstrap 配置并启动 Netty 服务端
+            ServerBootstrap serverBootstrap = new ServerBootstrap()
+                    .group(parentGroup, childGroup) // 设置主从线程组
+                    .channel(NioServerSocketChannel.class) // 指定使用 NIO 通道
+                    .childHandler(new ChannelInitializer<SocketChannel>() { // 配置子通道的处理器
+                        @Override
+                        protected void initChannel(SocketChannel socketChannel) {
+                            // 添加 IP 过滤器,限制只允许本地连接
+                            socketChannel.pipeline().addLast(new IpFilterHandler());
+                            // 添加基于行的帧解码器,限制单行最大长度
+                            socketChannel.pipeline().addLast(new LineBasedFrameDecoder(maxLength));
+                            // 添加字符串解码器,将接收到的字节流转换为字符串
+                            socketChannel.pipeline().addLast(new StringDecoder());
+                            // 添加自定义的业务处理器,处理解析后的日志数据
+                            socketChannel.pipeline().addLast(new SimpleChannelInboundHandler<String>() {
+                                @Override
+                                protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
+                                    // 创建 ObjectMapper 对象,用于 JSON 数据解析
+                                    ObjectMapper mapper = new ObjectMapper();
+                                    // 配置 ObjectMapper 忽略未知字段
+                                    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+                                    // 设置属性命名策略为蛇形命名法
+                                    mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
+                                    // 创建 JavaTimeModule 模块,支持 LocalDateTime 的序列化和反序列化
+                                    JavaTimeModule module = new JavaTimeModule();
+                                    module.addSerializer(LocalDateTime.class,
+                                            new LocalDateTimeSerializer(DateTimeFormatter.ISO_DATE_TIME));
+                                    module.addDeserializer(LocalDateTime.class,
+                                            new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME));
+                                    mapper.registerModule(module);
+                                    // 将接收到的 JSON 字符串解析为 NginxLogPo 对象
+                                    NginxLogPo po = mapper.readValue(s, NginxLogPo.class);
+                                    // 获取日志中的 Token 字段
+                                    String token = po.getToken();
+                                    // 对 Token 进行 URL 解码
+                                    String urlDecodeToken = URLDecoder.decode(token, StandardCharsets.UTF_8);
+                                    // 对解码后的 Token 进行 AES 解密
+                                    String decryptToken = AESUtil.decrypt(urlDecodeToken);
+                                    // 将解密后的 Token 转换为 Map
+                                    Map<String, String> map = mapper.readValue(decryptToken,
+                                            TypeFactory.defaultInstance().constructMapType(Map.class, String.class,
+                                                    String.class));
+                                    // 从 Map 中解析时间戳,并格式化为 LocalDateTime
+                                    LocalDateTime timeStamp = LocalDateTime.parse(map.get("TIME_STAMP"),
+                                            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+                                    // 获取过期时间(秒)
+                                    int expireTime = Integer.parseInt(map.get("EXPIRE_TIME"));
+                                    // 计算过期时间戳
+                                    LocalDateTime expireTimeStamp = timeStamp.plusSeconds(expireTime);
+                                    // 设置 NginxLogPo 对象的其他字段
+                                    po.setLoginId(map.get("LOGIN_ID"));
+                                    po.setPageUrl(map.get("REQUEST_URL"));
+                                    po.setAppId(map.get("APP_ID"));
+                                    po.setToken(urlDecodeToken);
+                                    po.setTimeStamp(timeStamp);
+                                    po.setExpireTime(expireTime);
+                                    po.setExpireTimeStamp(expireTimeStamp);
+                                    // 将日志对象插入数据库
+                                    nginxLogDao.insert(po);
+                                }
+                            });
+                        }
+                    })
+                    .childOption(ChannelOption.SO_KEEPALIVE, true); // 设置保持连接选项
+            // 绑定端口并同步等待绑定完成
+            channelFuture = serverBootstrap.bind(port).sync();
+            // 打印服务启动成功的日志
+            log.info("TCP Server started on port: {}", port);
+        } catch (InterruptedException e) {
+            // 如果发生中断异常,设置线程中断状态并记录错误日志
+            Thread.currentThread().interrupt();
+            log.error(e.toString(), e);
+            // 停止服务
+            stop();
+        }
+    }
+
+    /**
+     * 停止方法,优雅地关闭服务
+     */
+    @Override
+    public void stop() {
+        // 设置运行标志为 false
+        running = false;
+        // 优雅地关闭主事件循环组
+        if (parentGroup != null) {
+            parentGroup.shutdownGracefully();
+        }
+        // 优雅地关闭子事件循环组
+        if (childGroup != null) {
+            childGroup.shutdownGracefully();
+        }
+        // 关闭绑定的 ChannelFuture
+        if (channelFuture != null) {
+            try {
+                channelFuture.channel().closeFuture().sync();
+            } catch (InterruptedException e) {
+                // 如果发生中断异常,设置线程中断状态并记录错误日志
+                Thread.currentThread().interrupt();
+                log.error(e.toString(), e);
+            }
+        }
+    }
+
+    /**
+     * 判断服务是否正在运行
+     *
+     * @return 如果服务正在运行则返回 true,否则返回 false
+     */
+    @Override
+    public boolean isRunning() {
+        return running;
+    }
+
+    /**
+     * 内部类:IP 过滤处理器,限制只允许本地连接
+     */
+    private static class IpFilterHandler extends ChannelInboundHandlerAdapter {
+        @Override
+        public void channelActive(ChannelHandlerContext ctx) throws Exception {
+            // 获取远程客户端的地址
+            InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
+            String hostAddress = remoteAddress.getAddress().getHostAddress();
+            // 如果远程地址不是本地地址,则拒绝连接
+            if (!"127.0.0.1".equals(hostAddress)) {
+                log.warn("Rejected connection from non-local IP: {}", hostAddress);
+                ctx.close();
+                return;
+            }
+            // 调用父类方法,继续处理连接
+            super.channelActive(ctx);
+        }
+    }
+}

+ 4 - 1
src/main/resources/application-dev.yml

@@ -10,7 +10,7 @@ spring:
     username: postgres
     username: postgres
     password: Test!234
     password: Test!234
 #    url: jdbc:postgresql://127.0.0.1:5432/financialdb
 #    url: jdbc:postgresql://127.0.0.1:5432/financialdb
-    url: jdbc:postgresql://192.168.65.128:5432/financialdb
+    url: jdbc:postgresql://192.168.211.128:5432/financialdb
 #    url: jdbc:postgresql://172.16.107.5:5432/financialdb
 #    url: jdbc:postgresql://172.16.107.5:5432/financialdb
 #    username: finance
 #    username: finance
 #    password: Finance@unicom23
 #    password: Finance@unicom23
@@ -208,3 +208,6 @@ house-report:
   document-ftl: document.ftl
   document-ftl: document.ftl
   # document xml路径
   # document xml路径
   document-xml: templates/house/report/docx/word/document.xml
   document-xml: templates/house/report/docx/word/document.xml
+nginx-log:
+  port: 39876
+  max-length: 1048576

+ 4 - 0
src/main/resources/application-prod.yml

@@ -4,6 +4,7 @@ logging:
   level:
   level:
     com:
     com:
       nokia: debug
       nokia: debug
+    com.nokia.finance.tasks.dao.common.NginxLogDao: warn
 spring:
 spring:
   datasource:
   datasource:
     driver-class-name: org.postgresql.Driver
     driver-class-name: org.postgresql.Driver
@@ -199,3 +200,6 @@ house-report:
   document-ftl: document.ftl
   document-ftl: document.ftl
   # document xml路径
   # document xml路径
   document-xml: templates/house/report/docx/word/document.xml
   document-xml: templates/house/report/docx/word/document.xml
+nginx-log:
+  port: 39876
+  max-length: 1048576