Compare commits
101
Commits
dd43cf0135
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9afd362de6 | ||
|
|
5b9cf5a538 | ||
|
|
db203d01e1 | ||
|
|
8690824663 | ||
|
|
5ca8148c42 | ||
|
|
e54cafd16b | ||
|
|
c21504993f | ||
|
|
8e90c904ee | ||
|
|
85e60c01bc | ||
|
|
0ce1a57a53 | ||
|
|
c2451be4a2 | ||
|
|
8aa79a46e3 | ||
|
|
654f73aca8 | ||
|
|
a0eeb9c8c4 | ||
|
|
ebbb44b132 | ||
|
|
c94fe5c62f | ||
|
|
ffc9b3d425 | ||
|
|
d9d00cc9fa | ||
|
|
e28be80856 | ||
|
|
db73d606e8 | ||
|
|
7fb76a9d12 | ||
|
|
7437355573 | ||
|
|
65cfef8d02 | ||
|
|
ea2e55787c | ||
|
|
85a4630020 | ||
|
|
5aca5ad39f | ||
|
|
fd88cca4c6 | ||
|
|
cb1e7a2e65 | ||
|
|
ee65be0f93 | ||
|
|
59e1272cdb | ||
|
|
474093d2f2 | ||
|
|
d39aadc98d | ||
|
|
eb3e13c63a | ||
|
|
610c9c31ac | ||
|
|
e38418500d | ||
|
|
b70596cf31 | ||
|
|
5c8071f1f4 | ||
|
|
3bbfe20f84 | ||
|
|
9a5195cb0a | ||
|
|
683f8ac880 | ||
|
|
0b444636a4 | ||
|
|
710672bfc0 | ||
|
|
a92610c2f4 | ||
|
|
c43531c206 | ||
|
|
f1085c0291 | ||
|
|
7860fe088b | ||
|
|
dbcdc02d91 | ||
|
|
d35420bed1 | ||
|
|
7039c1d5eb | ||
|
|
919e0b662b | ||
|
|
498f65dae9 | ||
|
|
797738c240 | ||
|
|
c5c8c536be | ||
|
|
aee911cc20 | ||
|
|
8213e51756 | ||
|
|
751bbe5199 | ||
|
|
a58132e6d8 | ||
|
|
c362d9177f | ||
|
|
e06aeb054c | ||
|
|
ea0077a3e7 | ||
|
|
7ec9c22520 | ||
|
|
5d9ab90ed3 | ||
|
|
f2a3b697d2 | ||
|
|
10611241d1 | ||
|
|
6c27d7c0e5 | ||
|
|
b079f6556c | ||
|
|
6b16bc838c | ||
|
|
a5151aa64a | ||
|
|
43438924e6 | ||
|
|
d9cb455c19 | ||
|
|
480d705255 | ||
|
|
6bd3b7ba60 | ||
|
|
9b010a4998 | ||
|
|
4e6ad0a7dc | ||
|
|
351ce7cb32 | ||
|
|
6dd5b39eca | ||
|
|
c379f00675 | ||
|
|
86fb94f049 | ||
|
|
d03deee97a | ||
|
|
ef203da2cd | ||
|
|
3840701756 | ||
|
|
bedb32e988 | ||
|
|
a61a74340e | ||
|
|
a74aacf255 | ||
|
|
84b14491e2 | ||
|
|
4b9da1b72d | ||
|
|
650c7c47d9 | ||
|
|
60cf47936e | ||
|
|
ecd78d8f6b | ||
|
|
7c3d90c2f8 | ||
|
|
ec7e89f5bb | ||
|
|
a63bd23ced | ||
|
|
4f1025e247 | ||
|
|
439df0d204 | ||
|
|
489460969f | ||
|
|
66385b1ce4 | ||
|
|
425285b837 | ||
|
|
ebe8f4e636 | ||
|
|
a36dc31538 | ||
|
|
6d5033dbd1 | ||
|
|
c2d15699ab |
No files matched your search
+53
-1
@@ -3,6 +3,7 @@ using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace SunlightAggregationManager
|
||||
{
|
||||
@@ -11,7 +12,58 @@ namespace SunlightAggregationManager
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
{
|
||||
base.OnStartup(e);
|
||||
RegisterGlobalExceptionHandlers();
|
||||
}
|
||||
|
||||
private void RegisterGlobalExceptionHandlers()
|
||||
{
|
||||
// 1. 捕获 UI 主线程的未处理异常
|
||||
this.DispatcherUnhandledException += App_DispatcherUnhandledException;
|
||||
|
||||
// 2. 捕获非 UI 线程(后台线程)的未处理异常
|
||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||
|
||||
// 3. 捕获 Task 异步任务中的未观察到的异常
|
||||
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
|
||||
}
|
||||
|
||||
// UI线程异常处理
|
||||
private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
|
||||
{
|
||||
LogAndShowError("UI线程发生异常", e.Exception);
|
||||
|
||||
// 【关键】将 Handled 设为 true,告诉 WPF 该异常已被处理,阻止程序自动闪退
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
// 非UI线程异常处理
|
||||
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
var exception = e.ExceptionObject as Exception;
|
||||
bool isTerminating = e.IsTerminating;
|
||||
|
||||
LogAndShowError($"非UI线程异常 (即将终止: {isTerminating})", exception);
|
||||
|
||||
// 注意:此事件不允许设置 Handled=true,默认情况下致命异常仍会导致程序退出
|
||||
}
|
||||
|
||||
// Task线程异常处理
|
||||
private void TaskScheduler_UnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
|
||||
{
|
||||
LogAndShowError("Task异步任务异常", e.Exception);
|
||||
|
||||
// 标记异常已被观察,防止它被重新抛出导致进程终止
|
||||
e.SetObserved();
|
||||
}
|
||||
|
||||
private void LogAndShowError(string context, Exception ex)
|
||||
{
|
||||
// 在这里记录日志或弹出友好的自定义错误提示窗口
|
||||
MessageBox.Show($"{context}:\n{ex?.Message}", "程序遇到错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
[SYS]
|
||||
Language=zh-CN
|
||||
Name=YZ
|
||||
Enterprise=YONGZHAO
|
||||
[SQL_SERVER]
|
||||
SQL1=192.168.15.248
|
||||
SQL2=BatchDyeingCentral
|
||||
SQL3=SQL SERVER
|
||||
SQL4=sa
|
||||
SQL5=yf888999
|
||||
[NETWORK]
|
||||
TCP=1
|
||||
HTTP=1
|
||||
TLS=0
|
||||
TCP_PORT1=7789
|
||||
TCP_PORT2=7790
|
||||
HTTP_PORT=7791
|
||||
[SERVER]
|
||||
SERVERIP=www.scserverddns.top:7795
|
||||
SERVERNAME=SUNLIGHT
|
||||
SERVERUSER=SUNLIGHT
|
||||
SERRVERPASWORD=SUNLIGHT
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,26 @@
|
||||
|
||||
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;
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
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;
|
||||
@@ -0,0 +1,109 @@
|
||||
|
||||
# This map is not a full koi8-r <> utf8 map: it does not contain
|
||||
# box-drawing and some other characters. Besides this map contains
|
||||
# several koi8-u and Byelorussian letters which are not in koi8-r.
|
||||
# If you need a full and standard map, use contrib/unicode2nginx/koi-utf
|
||||
# map instead.
|
||||
|
||||
charset_map koi8-r utf-8 {
|
||||
|
||||
80 E282AC ; # euro
|
||||
|
||||
95 E280A2 ; # bullet
|
||||
|
||||
9A C2A0 ; #
|
||||
|
||||
9E C2B7 ; # ·
|
||||
|
||||
A3 D191 ; # small yo
|
||||
A4 D194 ; # small Ukrainian ye
|
||||
|
||||
A6 D196 ; # small Ukrainian i
|
||||
A7 D197 ; # small Ukrainian yi
|
||||
|
||||
AD D291 ; # small Ukrainian soft g
|
||||
AE D19E ; # small Byelorussian short u
|
||||
|
||||
B0 C2B0 ; # °
|
||||
|
||||
B3 D081 ; # capital YO
|
||||
B4 D084 ; # capital Ukrainian YE
|
||||
|
||||
B6 D086 ; # capital Ukrainian I
|
||||
B7 D087 ; # capital Ukrainian YI
|
||||
|
||||
B9 E28496 ; # numero sign
|
||||
|
||||
BD D290 ; # capital Ukrainian soft G
|
||||
BE D18E ; # capital Byelorussian short U
|
||||
|
||||
BF C2A9 ; # (C)
|
||||
|
||||
C0 D18E ; # small yu
|
||||
C1 D0B0 ; # small a
|
||||
C2 D0B1 ; # small b
|
||||
C3 D186 ; # small ts
|
||||
C4 D0B4 ; # small d
|
||||
C5 D0B5 ; # small ye
|
||||
C6 D184 ; # small f
|
||||
C7 D0B3 ; # small g
|
||||
C8 D185 ; # small kh
|
||||
C9 D0B8 ; # small i
|
||||
CA D0B9 ; # small j
|
||||
CB D0BA ; # small k
|
||||
CC D0BB ; # small l
|
||||
CD D0BC ; # small m
|
||||
CE D0BD ; # small n
|
||||
CF D0BE ; # small o
|
||||
|
||||
D0 D0BF ; # small p
|
||||
D1 D18F ; # small ya
|
||||
D2 D180 ; # small r
|
||||
D3 D181 ; # small s
|
||||
D4 D182 ; # small t
|
||||
D5 D183 ; # small u
|
||||
D6 D0B6 ; # small zh
|
||||
D7 D0B2 ; # small v
|
||||
D8 D18C ; # small soft sign
|
||||
D9 D18B ; # small y
|
||||
DA D0B7 ; # small z
|
||||
DB D188 ; # small sh
|
||||
DC D18D ; # small e
|
||||
DD D189 ; # small shch
|
||||
DE D187 ; # small ch
|
||||
DF D18A ; # small hard sign
|
||||
|
||||
E0 D0AE ; # capital YU
|
||||
E1 D090 ; # capital A
|
||||
E2 D091 ; # capital B
|
||||
E3 D0A6 ; # capital TS
|
||||
E4 D094 ; # capital D
|
||||
E5 D095 ; # capital YE
|
||||
E6 D0A4 ; # capital F
|
||||
E7 D093 ; # capital G
|
||||
E8 D0A5 ; # capital KH
|
||||
E9 D098 ; # capital I
|
||||
EA D099 ; # capital J
|
||||
EB D09A ; # capital K
|
||||
EC D09B ; # capital L
|
||||
ED D09C ; # capital M
|
||||
EE D09D ; # capital N
|
||||
EF D09E ; # capital O
|
||||
|
||||
F0 D09F ; # capital P
|
||||
F1 D0AF ; # capital YA
|
||||
F2 D0A0 ; # capital R
|
||||
F3 D0A1 ; # capital S
|
||||
F4 D0A2 ; # capital T
|
||||
F5 D0A3 ; # capital U
|
||||
F6 D096 ; # capital ZH
|
||||
F7 D092 ; # capital V
|
||||
F8 D0AC ; # capital soft sign
|
||||
F9 D0AB ; # capital Y
|
||||
FA D097 ; # capital Z
|
||||
FB D0A8 ; # capital SH
|
||||
FC D0AD ; # capital E
|
||||
FD D0A9 ; # capital SHCH
|
||||
FE D0A7 ; # capital CH
|
||||
FF D0AA ; # capital hard sign
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
|
||||
charset_map koi8-r windows-1251 {
|
||||
|
||||
80 88 ; # euro
|
||||
|
||||
95 95 ; # bullet
|
||||
|
||||
9A A0 ; #
|
||||
|
||||
9E B7 ; # ·
|
||||
|
||||
A3 B8 ; # small yo
|
||||
A4 BA ; # small Ukrainian ye
|
||||
|
||||
A6 B3 ; # small Ukrainian i
|
||||
A7 BF ; # small Ukrainian yi
|
||||
|
||||
AD B4 ; # small Ukrainian soft g
|
||||
AE A2 ; # small Byelorussian short u
|
||||
|
||||
B0 B0 ; # °
|
||||
|
||||
B3 A8 ; # capital YO
|
||||
B4 AA ; # capital Ukrainian YE
|
||||
|
||||
B6 B2 ; # capital Ukrainian I
|
||||
B7 AF ; # capital Ukrainian YI
|
||||
|
||||
B9 B9 ; # numero sign
|
||||
|
||||
BD A5 ; # capital Ukrainian soft G
|
||||
BE A1 ; # capital Byelorussian short U
|
||||
|
||||
BF A9 ; # (C)
|
||||
|
||||
C0 FE ; # small yu
|
||||
C1 E0 ; # small a
|
||||
C2 E1 ; # small b
|
||||
C3 F6 ; # small ts
|
||||
C4 E4 ; # small d
|
||||
C5 E5 ; # small ye
|
||||
C6 F4 ; # small f
|
||||
C7 E3 ; # small g
|
||||
C8 F5 ; # small kh
|
||||
C9 E8 ; # small i
|
||||
CA E9 ; # small j
|
||||
CB EA ; # small k
|
||||
CC EB ; # small l
|
||||
CD EC ; # small m
|
||||
CE ED ; # small n
|
||||
CF EE ; # small o
|
||||
|
||||
D0 EF ; # small p
|
||||
D1 FF ; # small ya
|
||||
D2 F0 ; # small r
|
||||
D3 F1 ; # small s
|
||||
D4 F2 ; # small t
|
||||
D5 F3 ; # small u
|
||||
D6 E6 ; # small zh
|
||||
D7 E2 ; # small v
|
||||
D8 FC ; # small soft sign
|
||||
D9 FB ; # small y
|
||||
DA E7 ; # small z
|
||||
DB F8 ; # small sh
|
||||
DC FD ; # small e
|
||||
DD F9 ; # small shch
|
||||
DE F7 ; # small ch
|
||||
DF FA ; # small hard sign
|
||||
|
||||
E0 DE ; # capital YU
|
||||
E1 C0 ; # capital A
|
||||
E2 C1 ; # capital B
|
||||
E3 D6 ; # capital TS
|
||||
E4 C4 ; # capital D
|
||||
E5 C5 ; # capital YE
|
||||
E6 D4 ; # capital F
|
||||
E7 C3 ; # capital G
|
||||
E8 D5 ; # capital KH
|
||||
E9 C8 ; # capital I
|
||||
EA C9 ; # capital J
|
||||
EB CA ; # capital K
|
||||
EC CB ; # capital L
|
||||
ED CC ; # capital M
|
||||
EE CD ; # capital N
|
||||
EF CE ; # capital O
|
||||
|
||||
F0 CF ; # capital P
|
||||
F1 DF ; # capital YA
|
||||
F2 D0 ; # capital R
|
||||
F3 D1 ; # capital S
|
||||
F4 D2 ; # capital T
|
||||
F5 D3 ; # capital U
|
||||
F6 C6 ; # capital ZH
|
||||
F7 C2 ; # capital V
|
||||
F8 DC ; # capital soft sign
|
||||
F9 DB ; # capital Y
|
||||
FA C7 ; # capital Z
|
||||
FB D8 ; # capital SH
|
||||
FC DD ; # capital E
|
||||
FD D9 ; # capital SHCH
|
||||
FE D7 ; # capital CH
|
||||
FF DA ; # capital hard sign
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
|
||||
types {
|
||||
text/html html htm shtml;
|
||||
text/css css;
|
||||
text/xml xml;
|
||||
image/gif gif;
|
||||
image/jpeg jpeg jpg;
|
||||
application/javascript js;
|
||||
application/atom+xml atom;
|
||||
application/rss+xml rss;
|
||||
|
||||
text/mathml mml;
|
||||
text/plain txt;
|
||||
text/vnd.sun.j2me.app-descriptor jad;
|
||||
text/vnd.wap.wml wml;
|
||||
text/x-component htc;
|
||||
|
||||
image/avif avif;
|
||||
image/png png;
|
||||
image/svg+xml svg svgz;
|
||||
image/tiff tif tiff;
|
||||
image/vnd.wap.wbmp wbmp;
|
||||
image/webp webp;
|
||||
image/x-icon ico;
|
||||
image/x-jng jng;
|
||||
image/x-ms-bmp bmp;
|
||||
|
||||
font/woff woff;
|
||||
font/woff2 woff2;
|
||||
|
||||
application/java-archive jar war ear;
|
||||
application/json json;
|
||||
application/mac-binhex40 hqx;
|
||||
application/msword doc;
|
||||
application/pdf pdf;
|
||||
application/postscript ps eps ai;
|
||||
application/rtf rtf;
|
||||
application/vnd.apple.mpegurl m3u8;
|
||||
application/vnd.google-earth.kml+xml kml;
|
||||
application/vnd.google-earth.kmz kmz;
|
||||
application/vnd.ms-excel xls;
|
||||
application/vnd.ms-fontobject eot;
|
||||
application/vnd.ms-powerpoint ppt;
|
||||
application/vnd.oasis.opendocument.graphics odg;
|
||||
application/vnd.oasis.opendocument.presentation odp;
|
||||
application/vnd.oasis.opendocument.spreadsheet ods;
|
||||
application/vnd.oasis.opendocument.text odt;
|
||||
application/vnd.openxmlformats-officedocument.presentationml.presentation
|
||||
pptx;
|
||||
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
|
||||
xlsx;
|
||||
application/vnd.openxmlformats-officedocument.wordprocessingml.document
|
||||
docx;
|
||||
application/vnd.wap.wmlc wmlc;
|
||||
application/wasm wasm;
|
||||
application/x-7z-compressed 7z;
|
||||
application/x-cocoa cco;
|
||||
application/x-java-archive-diff jardiff;
|
||||
application/x-java-jnlp-file jnlp;
|
||||
application/x-makeself run;
|
||||
application/x-perl pl pm;
|
||||
application/x-pilot prc pdb;
|
||||
application/x-rar-compressed rar;
|
||||
application/x-redhat-package-manager rpm;
|
||||
application/x-sea sea;
|
||||
application/x-shockwave-flash swf;
|
||||
application/x-stuffit sit;
|
||||
application/x-tcl tcl tk;
|
||||
application/x-x509-ca-cert der pem crt;
|
||||
application/x-xpinstall xpi;
|
||||
application/xhtml+xml xhtml;
|
||||
application/xspf+xml xspf;
|
||||
application/zip zip;
|
||||
|
||||
application/octet-stream bin exe dll;
|
||||
application/octet-stream deb;
|
||||
application/octet-stream dmg;
|
||||
application/octet-stream iso img;
|
||||
application/octet-stream msi msp msm;
|
||||
|
||||
audio/midi mid midi kar;
|
||||
audio/mpeg mp3;
|
||||
audio/ogg ogg;
|
||||
audio/x-m4a m4a;
|
||||
audio/x-realaudio ra;
|
||||
|
||||
video/3gpp 3gpp 3gp;
|
||||
video/mp2t ts;
|
||||
video/mp4 mp4;
|
||||
video/mpeg mpeg mpg;
|
||||
video/quicktime mov;
|
||||
video/webm webm;
|
||||
video/x-flv flv;
|
||||
video/x-m4v m4v;
|
||||
video/x-mng mng;
|
||||
video/x-ms-asf asx asf;
|
||||
video/x-ms-wmv wmv;
|
||||
video/x-msvideo avi;
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
|
||||
#user nobody;
|
||||
worker_processes 1;
|
||||
|
||||
#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;
|
||||
|
||||
#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;
|
||||
|
||||
sendfile on;
|
||||
#tcp_nopush on;
|
||||
|
||||
#keepalive_timeout 0;
|
||||
keepalive_timeout 65;
|
||||
|
||||
#gzip on;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
#access_log logs/host.access.log main;
|
||||
|
||||
location / {
|
||||
root html;
|
||||
index index.html index.htm;
|
||||
}
|
||||
|
||||
#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 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;
|
||||
#}
|
||||
}
|
||||
|
||||
|
||||
# another virtual host using mix of IP-, name-, and port-based configuration
|
||||
#
|
||||
#server {
|
||||
# listen 8000;
|
||||
# listen somename:8080;
|
||||
# server_name somename alias another.alias;
|
||||
|
||||
# location / {
|
||||
# root html;
|
||||
# index index.html index.htm;
|
||||
# }
|
||||
#}
|
||||
|
||||
|
||||
# HTTPS server
|
||||
#
|
||||
#server {
|
||||
# listen 443 ssl;
|
||||
# server_name localhost;
|
||||
|
||||
# ssl_certificate cert.pem;
|
||||
# ssl_certificate_key cert.key;
|
||||
|
||||
# ssl_session_cache shared:SSL:1m;
|
||||
# ssl_session_timeout 5m;
|
||||
|
||||
# ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
# ssl_prefer_server_ciphers on;
|
||||
|
||||
# location / {
|
||||
# root html;
|
||||
# index index.html index.htm;
|
||||
# }
|
||||
#}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
scgi_param REQUEST_METHOD $request_method;
|
||||
scgi_param REQUEST_URI $request_uri;
|
||||
scgi_param QUERY_STRING $query_string;
|
||||
scgi_param CONTENT_TYPE $content_type;
|
||||
|
||||
scgi_param DOCUMENT_URI $document_uri;
|
||||
scgi_param DOCUMENT_ROOT $document_root;
|
||||
scgi_param SCGI 1;
|
||||
scgi_param SERVER_PROTOCOL $server_protocol;
|
||||
scgi_param REQUEST_SCHEME $scheme;
|
||||
scgi_param HTTPS $https if_not_empty;
|
||||
|
||||
scgi_param REMOTE_ADDR $remote_addr;
|
||||
scgi_param REMOTE_PORT $remote_port;
|
||||
scgi_param SERVER_PORT $server_port;
|
||||
scgi_param SERVER_NAME $server_name;
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
uwsgi_param QUERY_STRING $query_string;
|
||||
uwsgi_param REQUEST_METHOD $request_method;
|
||||
uwsgi_param CONTENT_TYPE $content_type;
|
||||
uwsgi_param CONTENT_LENGTH $content_length;
|
||||
|
||||
uwsgi_param REQUEST_URI $request_uri;
|
||||
uwsgi_param PATH_INFO $document_uri;
|
||||
uwsgi_param DOCUMENT_ROOT $document_root;
|
||||
uwsgi_param SERVER_PROTOCOL $server_protocol;
|
||||
uwsgi_param REQUEST_SCHEME $scheme;
|
||||
uwsgi_param HTTPS $https if_not_empty;
|
||||
|
||||
uwsgi_param REMOTE_ADDR $remote_addr;
|
||||
uwsgi_param REMOTE_PORT $remote_port;
|
||||
uwsgi_param SERVER_PORT $server_port;
|
||||
uwsgi_param SERVER_NAME $server_name;
|
||||
@@ -0,0 +1,126 @@
|
||||
|
||||
# This map is not a full windows-1251 <> utf8 map: it does not
|
||||
# contain Serbian and Macedonian letters. If you need a full map,
|
||||
# use contrib/unicode2nginx/win-utf map instead.
|
||||
|
||||
charset_map windows-1251 utf-8 {
|
||||
|
||||
82 E2809A ; # single low-9 quotation mark
|
||||
|
||||
84 E2809E ; # double low-9 quotation mark
|
||||
85 E280A6 ; # ellipsis
|
||||
86 E280A0 ; # dagger
|
||||
87 E280A1 ; # double dagger
|
||||
88 E282AC ; # euro
|
||||
89 E280B0 ; # per mille
|
||||
|
||||
91 E28098 ; # left single quotation mark
|
||||
92 E28099 ; # right single quotation mark
|
||||
93 E2809C ; # left double quotation mark
|
||||
94 E2809D ; # right double quotation mark
|
||||
95 E280A2 ; # bullet
|
||||
96 E28093 ; # en dash
|
||||
97 E28094 ; # em dash
|
||||
|
||||
99 E284A2 ; # trade mark sign
|
||||
|
||||
A0 C2A0 ; #
|
||||
A1 D18E ; # capital Byelorussian short U
|
||||
A2 D19E ; # small Byelorussian short u
|
||||
|
||||
A4 C2A4 ; # currency sign
|
||||
A5 D290 ; # capital Ukrainian soft G
|
||||
A6 C2A6 ; # borken bar
|
||||
A7 C2A7 ; # section sign
|
||||
A8 D081 ; # capital YO
|
||||
A9 C2A9 ; # (C)
|
||||
AA D084 ; # capital Ukrainian YE
|
||||
AB C2AB ; # left-pointing double angle quotation mark
|
||||
AC C2AC ; # not sign
|
||||
AD C2AD ; # soft hyphen
|
||||
AE C2AE ; # (R)
|
||||
AF D087 ; # capital Ukrainian YI
|
||||
|
||||
B0 C2B0 ; # °
|
||||
B1 C2B1 ; # plus-minus sign
|
||||
B2 D086 ; # capital Ukrainian I
|
||||
B3 D196 ; # small Ukrainian i
|
||||
B4 D291 ; # small Ukrainian soft g
|
||||
B5 C2B5 ; # micro sign
|
||||
B6 C2B6 ; # pilcrow sign
|
||||
B7 C2B7 ; # ·
|
||||
B8 D191 ; # small yo
|
||||
B9 E28496 ; # numero sign
|
||||
BA D194 ; # small Ukrainian ye
|
||||
BB C2BB ; # right-pointing double angle quotation mark
|
||||
|
||||
BF D197 ; # small Ukrainian yi
|
||||
|
||||
C0 D090 ; # capital A
|
||||
C1 D091 ; # capital B
|
||||
C2 D092 ; # capital V
|
||||
C3 D093 ; # capital G
|
||||
C4 D094 ; # capital D
|
||||
C5 D095 ; # capital YE
|
||||
C6 D096 ; # capital ZH
|
||||
C7 D097 ; # capital Z
|
||||
C8 D098 ; # capital I
|
||||
C9 D099 ; # capital J
|
||||
CA D09A ; # capital K
|
||||
CB D09B ; # capital L
|
||||
CC D09C ; # capital M
|
||||
CD D09D ; # capital N
|
||||
CE D09E ; # capital O
|
||||
CF D09F ; # capital P
|
||||
|
||||
D0 D0A0 ; # capital R
|
||||
D1 D0A1 ; # capital S
|
||||
D2 D0A2 ; # capital T
|
||||
D3 D0A3 ; # capital U
|
||||
D4 D0A4 ; # capital F
|
||||
D5 D0A5 ; # capital KH
|
||||
D6 D0A6 ; # capital TS
|
||||
D7 D0A7 ; # capital CH
|
||||
D8 D0A8 ; # capital SH
|
||||
D9 D0A9 ; # capital SHCH
|
||||
DA D0AA ; # capital hard sign
|
||||
DB D0AB ; # capital Y
|
||||
DC D0AC ; # capital soft sign
|
||||
DD D0AD ; # capital E
|
||||
DE D0AE ; # capital YU
|
||||
DF D0AF ; # capital YA
|
||||
|
||||
E0 D0B0 ; # small a
|
||||
E1 D0B1 ; # small b
|
||||
E2 D0B2 ; # small v
|
||||
E3 D0B3 ; # small g
|
||||
E4 D0B4 ; # small d
|
||||
E5 D0B5 ; # small ye
|
||||
E6 D0B6 ; # small zh
|
||||
E7 D0B7 ; # small z
|
||||
E8 D0B8 ; # small i
|
||||
E9 D0B9 ; # small j
|
||||
EA D0BA ; # small k
|
||||
EB D0BB ; # small l
|
||||
EC D0BC ; # small m
|
||||
ED D0BD ; # small n
|
||||
EE D0BE ; # small o
|
||||
EF D0BF ; # small p
|
||||
|
||||
F0 D180 ; # small r
|
||||
F1 D181 ; # small s
|
||||
F2 D182 ; # small t
|
||||
F3 D183 ; # small u
|
||||
F4 D184 ; # small f
|
||||
F5 D185 ; # small kh
|
||||
F6 D186 ; # small ts
|
||||
F7 D187 ; # small ch
|
||||
F8 D188 ; # small sh
|
||||
F9 D189 ; # small shch
|
||||
FA D18A ; # small hard sign
|
||||
FB D18B ; # small y
|
||||
FC D18C ; # small soft sign
|
||||
FD D18D ; # small e
|
||||
FE D18E ; # small yu
|
||||
FF D18F ; # small ya
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
geo2nginx.pl by Andrei Nigmatulin
|
||||
|
||||
The perl script to convert CSV geoip database ( free download
|
||||
at http://www.maxmind.com/app/geoip_country ) to format, suitable
|
||||
for use by the ngx_http_geo_module.
|
||||
|
||||
|
||||
unicode2nginx by Maxim Dounin
|
||||
|
||||
The perl script to convert unicode mappings ( available
|
||||
at http://www.unicode.org/Public/MAPPINGS/ ) to the nginx
|
||||
configuration file format.
|
||||
Two generated full maps for windows-1251 and koi8-r.
|
||||
|
||||
|
||||
vim by Evan Miller
|
||||
|
||||
Syntax highlighting of nginx configuration for vim, to be
|
||||
placed into ~/.vim/.
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
# (c) Andrei Nigmatulin, 2005
|
||||
#
|
||||
# this script provided "as is", without any warranties. use it at your own risk.
|
||||
#
|
||||
# special thanx to Andrew Sitnikov for perl port
|
||||
#
|
||||
# this script converts CSV geoip database (free download at http://www.maxmind.com/app/geoip_country)
|
||||
# to format, suitable for use with nginx_http_geo module (http://sysoev.ru/nginx)
|
||||
#
|
||||
# for example, line with ip range
|
||||
#
|
||||
# "62.16.68.0","62.16.127.255","1041253376","1041268735","RU","Russian Federation"
|
||||
#
|
||||
# will be converted to four subnetworks:
|
||||
#
|
||||
# 62.16.68.0/22 RU;
|
||||
# 62.16.72.0/21 RU;
|
||||
# 62.16.80.0/20 RU;
|
||||
# 62.16.96.0/19 RU;
|
||||
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
while( <STDIN> ){
|
||||
if (/"[^"]+","[^"]+","([^"]+)","([^"]+)","([^"]+)"/){
|
||||
print_subnets($1, $2, $3);
|
||||
}
|
||||
}
|
||||
|
||||
sub print_subnets {
|
||||
my ($a1, $a2, $c) = @_;
|
||||
my $l;
|
||||
while ($a1 <= $a2) {
|
||||
for ($l = 0; ($a1 & (1 << $l)) == 0 && ($a1 + ((1 << ($l + 1)) - 1)) <= $a2; $l++){};
|
||||
print long2ip($a1) . "/" . (32 - $l) . " " . $c . ";\n";
|
||||
$a1 += (1 << $l);
|
||||
}
|
||||
}
|
||||
|
||||
sub long2ip {
|
||||
my $ip = shift;
|
||||
|
||||
my $str = 0;
|
||||
|
||||
$str = ($ip & 255);
|
||||
|
||||
$ip >>= 8;
|
||||
$str = ($ip & 255).".$str";
|
||||
|
||||
$ip >>= 8;
|
||||
$str = ($ip & 255).".$str";
|
||||
|
||||
$ip >>= 8;
|
||||
$str = ($ip & 255).".$str";
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
charset_map koi8-r utf-8 {
|
||||
|
||||
80 E29480 ; # BOX DRAWINGS LIGHT HORIZONTAL
|
||||
81 E29482 ; # BOX DRAWINGS LIGHT VERTICAL
|
||||
82 E2948C ; # BOX DRAWINGS LIGHT DOWN AND RIGHT
|
||||
83 E29490 ; # BOX DRAWINGS LIGHT DOWN AND LEFT
|
||||
84 E29494 ; # BOX DRAWINGS LIGHT UP AND RIGHT
|
||||
85 E29498 ; # BOX DRAWINGS LIGHT UP AND LEFT
|
||||
86 E2949C ; # BOX DRAWINGS LIGHT VERTICAL AND RIGHT
|
||||
87 E294A4 ; # BOX DRAWINGS LIGHT VERTICAL AND LEFT
|
||||
88 E294AC ; # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
|
||||
89 E294B4 ; # BOX DRAWINGS LIGHT UP AND HORIZONTAL
|
||||
8A E294BC ; # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
|
||||
8B E29680 ; # UPPER HALF BLOCK
|
||||
8C E29684 ; # LOWER HALF BLOCK
|
||||
8D E29688 ; # FULL BLOCK
|
||||
8E E2968C ; # LEFT HALF BLOCK
|
||||
8F E29690 ; # RIGHT HALF BLOCK
|
||||
90 E29691 ; # LIGHT SHADE
|
||||
91 E29692 ; # MEDIUM SHADE
|
||||
92 E29693 ; # DARK SHADE
|
||||
93 E28CA0 ; # TOP HALF INTEGRAL
|
||||
94 E296A0 ; # BLACK SQUARE
|
||||
95 E28899 ; # BULLET OPERATOR
|
||||
96 E2889A ; # SQUARE ROOT
|
||||
97 E28988 ; # ALMOST EQUAL TO
|
||||
98 E289A4 ; # LESS-THAN OR EQUAL TO
|
||||
99 E289A5 ; # GREATER-THAN OR EQUAL TO
|
||||
9A C2A0 ; # NO-BREAK SPACE
|
||||
9B E28CA1 ; # BOTTOM HALF INTEGRAL
|
||||
9C C2B0 ; # DEGREE SIGN
|
||||
9D C2B2 ; # SUPERSCRIPT TWO
|
||||
9E C2B7 ; # MIDDLE DOT
|
||||
9F C3B7 ; # DIVISION SIGN
|
||||
A0 E29590 ; # BOX DRAWINGS DOUBLE HORIZONTAL
|
||||
A1 E29591 ; # BOX DRAWINGS DOUBLE VERTICAL
|
||||
A2 E29592 ; # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
|
||||
A3 D191 ; # CYRILLIC SMALL LETTER IO
|
||||
A4 E29593 ; # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
|
||||
A5 E29594 ; # BOX DRAWINGS DOUBLE DOWN AND RIGHT
|
||||
A6 E29595 ; # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
|
||||
A7 E29596 ; # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
|
||||
A8 E29597 ; # BOX DRAWINGS DOUBLE DOWN AND LEFT
|
||||
A9 E29598 ; # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
|
||||
AA E29599 ; # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
|
||||
AB E2959A ; # BOX DRAWINGS DOUBLE UP AND RIGHT
|
||||
AC E2959B ; # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
|
||||
AD E2959C ; # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
|
||||
AE E2959D ; # BOX DRAWINGS DOUBLE UP AND LEFT
|
||||
AF E2959E ; # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
|
||||
B0 E2959F ; # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
|
||||
B1 E295A0 ; # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
|
||||
B2 E295A1 ; # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
|
||||
B3 D081 ; # CYRILLIC CAPITAL LETTER IO
|
||||
B4 E295A2 ; # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
|
||||
B5 E295A3 ; # BOX DRAWINGS DOUBLE VERTICAL AND LEFT
|
||||
B6 E295A4 ; # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
|
||||
B7 E295A5 ; # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
|
||||
B8 E295A6 ; # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
|
||||
B9 E295A7 ; # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
|
||||
BA E295A8 ; # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
|
||||
BB E295A9 ; # BOX DRAWINGS DOUBLE UP AND HORIZONTAL
|
||||
BC E295AA ; # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
|
||||
BD E295AB ; # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
|
||||
BE E295AC ; # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
|
||||
BF C2A9 ; # COPYRIGHT SIGN
|
||||
C0 D18E ; # CYRILLIC SMALL LETTER YU
|
||||
C1 D0B0 ; # CYRILLIC SMALL LETTER A
|
||||
C2 D0B1 ; # CYRILLIC SMALL LETTER BE
|
||||
C3 D186 ; # CYRILLIC SMALL LETTER TSE
|
||||
C4 D0B4 ; # CYRILLIC SMALL LETTER DE
|
||||
C5 D0B5 ; # CYRILLIC SMALL LETTER IE
|
||||
C6 D184 ; # CYRILLIC SMALL LETTER EF
|
||||
C7 D0B3 ; # CYRILLIC SMALL LETTER GHE
|
||||
C8 D185 ; # CYRILLIC SMALL LETTER HA
|
||||
C9 D0B8 ; # CYRILLIC SMALL LETTER I
|
||||
CA D0B9 ; # CYRILLIC SMALL LETTER SHORT I
|
||||
CB D0BA ; # CYRILLIC SMALL LETTER KA
|
||||
CC D0BB ; # CYRILLIC SMALL LETTER EL
|
||||
CD D0BC ; # CYRILLIC SMALL LETTER EM
|
||||
CE D0BD ; # CYRILLIC SMALL LETTER EN
|
||||
CF D0BE ; # CYRILLIC SMALL LETTER O
|
||||
D0 D0BF ; # CYRILLIC SMALL LETTER PE
|
||||
D1 D18F ; # CYRILLIC SMALL LETTER YA
|
||||
D2 D180 ; # CYRILLIC SMALL LETTER ER
|
||||
D3 D181 ; # CYRILLIC SMALL LETTER ES
|
||||
D4 D182 ; # CYRILLIC SMALL LETTER TE
|
||||
D5 D183 ; # CYRILLIC SMALL LETTER U
|
||||
D6 D0B6 ; # CYRILLIC SMALL LETTER ZHE
|
||||
D7 D0B2 ; # CYRILLIC SMALL LETTER VE
|
||||
D8 D18C ; # CYRILLIC SMALL LETTER SOFT SIGN
|
||||
D9 D18B ; # CYRILLIC SMALL LETTER YERU
|
||||
DA D0B7 ; # CYRILLIC SMALL LETTER ZE
|
||||
DB D188 ; # CYRILLIC SMALL LETTER SHA
|
||||
DC D18D ; # CYRILLIC SMALL LETTER E
|
||||
DD D189 ; # CYRILLIC SMALL LETTER SHCHA
|
||||
DE D187 ; # CYRILLIC SMALL LETTER CHE
|
||||
DF D18A ; # CYRILLIC SMALL LETTER HARD SIGN
|
||||
E0 D0AE ; # CYRILLIC CAPITAL LETTER YU
|
||||
E1 D090 ; # CYRILLIC CAPITAL LETTER A
|
||||
E2 D091 ; # CYRILLIC CAPITAL LETTER BE
|
||||
E3 D0A6 ; # CYRILLIC CAPITAL LETTER TSE
|
||||
E4 D094 ; # CYRILLIC CAPITAL LETTER DE
|
||||
E5 D095 ; # CYRILLIC CAPITAL LETTER IE
|
||||
E6 D0A4 ; # CYRILLIC CAPITAL LETTER EF
|
||||
E7 D093 ; # CYRILLIC CAPITAL LETTER GHE
|
||||
E8 D0A5 ; # CYRILLIC CAPITAL LETTER HA
|
||||
E9 D098 ; # CYRILLIC CAPITAL LETTER I
|
||||
EA D099 ; # CYRILLIC CAPITAL LETTER SHORT I
|
||||
EB D09A ; # CYRILLIC CAPITAL LETTER KA
|
||||
EC D09B ; # CYRILLIC CAPITAL LETTER EL
|
||||
ED D09C ; # CYRILLIC CAPITAL LETTER EM
|
||||
EE D09D ; # CYRILLIC CAPITAL LETTER EN
|
||||
EF D09E ; # CYRILLIC CAPITAL LETTER O
|
||||
F0 D09F ; # CYRILLIC CAPITAL LETTER PE
|
||||
F1 D0AF ; # CYRILLIC CAPITAL LETTER YA
|
||||
F2 D0A0 ; # CYRILLIC CAPITAL LETTER ER
|
||||
F3 D0A1 ; # CYRILLIC CAPITAL LETTER ES
|
||||
F4 D0A2 ; # CYRILLIC CAPITAL LETTER TE
|
||||
F5 D0A3 ; # CYRILLIC CAPITAL LETTER U
|
||||
F6 D096 ; # CYRILLIC CAPITAL LETTER ZHE
|
||||
F7 D092 ; # CYRILLIC CAPITAL LETTER VE
|
||||
F8 D0AC ; # CYRILLIC CAPITAL LETTER SOFT SIGN
|
||||
F9 D0AB ; # CYRILLIC CAPITAL LETTER YERU
|
||||
FA D097 ; # CYRILLIC CAPITAL LETTER ZE
|
||||
FB D0A8 ; # CYRILLIC CAPITAL LETTER SHA
|
||||
FC D0AD ; # CYRILLIC CAPITAL LETTER E
|
||||
FD D0A9 ; # CYRILLIC CAPITAL LETTER SHCHA
|
||||
FE D0A7 ; # CYRILLIC CAPITAL LETTER CHE
|
||||
FF D0AA ; # CYRILLIC CAPITAL LETTER HARD SIGN
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
# Convert unicode mappings to nginx configuration file format.
|
||||
|
||||
# You may find useful mappings in various places, including
|
||||
# unicode.org official site:
|
||||
#
|
||||
# http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT
|
||||
# http://www.unicode.org/Public/MAPPINGS/VENDORS/MISC/KOI8-R.TXT
|
||||
|
||||
# Needs perl 5.6 or later.
|
||||
|
||||
# Written by Maxim Dounin, mdounin@mdounin.ru
|
||||
|
||||
###############################################################################
|
||||
|
||||
require 5.006;
|
||||
|
||||
while (<>) {
|
||||
# Skip comments and empty lines
|
||||
|
||||
next if /^#/;
|
||||
next if /^\s*$/;
|
||||
chomp;
|
||||
|
||||
# Convert mappings
|
||||
|
||||
if (/^\s*0x(..)\s*0x(....)\s*(#.*)/) {
|
||||
# Mapping <from-code> <unicode-code> "#" <unicode-name>
|
||||
my $cs_code = $1;
|
||||
my $un_code = $2;
|
||||
my $un_name = $3;
|
||||
|
||||
# Produce UTF-8 sequence from character code;
|
||||
|
||||
my $un_utf8 = join('',
|
||||
map { sprintf("%02X", $_) }
|
||||
unpack("U0C*", pack("U", hex($un_code)))
|
||||
);
|
||||
|
||||
print " $cs_code $un_utf8 ; $un_name\n";
|
||||
|
||||
} else {
|
||||
warn "Unrecognized line: '$_'";
|
||||
}
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
@@ -0,0 +1,130 @@
|
||||
charset_map windows-1251 utf-8 {
|
||||
|
||||
80 D082 ; #CYRILLIC CAPITAL LETTER DJE
|
||||
81 D083 ; #CYRILLIC CAPITAL LETTER GJE
|
||||
82 E2809A ; #SINGLE LOW-9 QUOTATION MARK
|
||||
83 D193 ; #CYRILLIC SMALL LETTER GJE
|
||||
84 E2809E ; #DOUBLE LOW-9 QUOTATION MARK
|
||||
85 E280A6 ; #HORIZONTAL ELLIPSIS
|
||||
86 E280A0 ; #DAGGER
|
||||
87 E280A1 ; #DOUBLE DAGGER
|
||||
88 E282AC ; #EURO SIGN
|
||||
89 E280B0 ; #PER MILLE SIGN
|
||||
8A D089 ; #CYRILLIC CAPITAL LETTER LJE
|
||||
8B E280B9 ; #SINGLE LEFT-POINTING ANGLE QUOTATION MARK
|
||||
8C D08A ; #CYRILLIC CAPITAL LETTER NJE
|
||||
8D D08C ; #CYRILLIC CAPITAL LETTER KJE
|
||||
8E D08B ; #CYRILLIC CAPITAL LETTER TSHE
|
||||
8F D08F ; #CYRILLIC CAPITAL LETTER DZHE
|
||||
90 D192 ; #CYRILLIC SMALL LETTER DJE
|
||||
91 E28098 ; #LEFT SINGLE QUOTATION MARK
|
||||
92 E28099 ; #RIGHT SINGLE QUOTATION MARK
|
||||
93 E2809C ; #LEFT DOUBLE QUOTATION MARK
|
||||
94 E2809D ; #RIGHT DOUBLE QUOTATION MARK
|
||||
95 E280A2 ; #BULLET
|
||||
96 E28093 ; #EN DASH
|
||||
97 E28094 ; #EM DASH
|
||||
99 E284A2 ; #TRADE MARK SIGN
|
||||
9A D199 ; #CYRILLIC SMALL LETTER LJE
|
||||
9B E280BA ; #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
|
||||
9C D19A ; #CYRILLIC SMALL LETTER NJE
|
||||
9D D19C ; #CYRILLIC SMALL LETTER KJE
|
||||
9E D19B ; #CYRILLIC SMALL LETTER TSHE
|
||||
9F D19F ; #CYRILLIC SMALL LETTER DZHE
|
||||
A0 C2A0 ; #NO-BREAK SPACE
|
||||
A1 D08E ; #CYRILLIC CAPITAL LETTER SHORT U
|
||||
A2 D19E ; #CYRILLIC SMALL LETTER SHORT U
|
||||
A3 D088 ; #CYRILLIC CAPITAL LETTER JE
|
||||
A4 C2A4 ; #CURRENCY SIGN
|
||||
A5 D290 ; #CYRILLIC CAPITAL LETTER GHE WITH UPTURN
|
||||
A6 C2A6 ; #BROKEN BAR
|
||||
A7 C2A7 ; #SECTION SIGN
|
||||
A8 D081 ; #CYRILLIC CAPITAL LETTER IO
|
||||
A9 C2A9 ; #COPYRIGHT SIGN
|
||||
AA D084 ; #CYRILLIC CAPITAL LETTER UKRAINIAN IE
|
||||
AB C2AB ; #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
AC C2AC ; #NOT SIGN
|
||||
AD C2AD ; #SOFT HYPHEN
|
||||
AE C2AE ; #REGISTERED SIGN
|
||||
AF D087 ; #CYRILLIC CAPITAL LETTER YI
|
||||
B0 C2B0 ; #DEGREE SIGN
|
||||
B1 C2B1 ; #PLUS-MINUS SIGN
|
||||
B2 D086 ; #CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
|
||||
B3 D196 ; #CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
|
||||
B4 D291 ; #CYRILLIC SMALL LETTER GHE WITH UPTURN
|
||||
B5 C2B5 ; #MICRO SIGN
|
||||
B6 C2B6 ; #PILCROW SIGN
|
||||
B7 C2B7 ; #MIDDLE DOT
|
||||
B8 D191 ; #CYRILLIC SMALL LETTER IO
|
||||
B9 E28496 ; #NUMERO SIGN
|
||||
BA D194 ; #CYRILLIC SMALL LETTER UKRAINIAN IE
|
||||
BB C2BB ; #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
BC D198 ; #CYRILLIC SMALL LETTER JE
|
||||
BD D085 ; #CYRILLIC CAPITAL LETTER DZE
|
||||
BE D195 ; #CYRILLIC SMALL LETTER DZE
|
||||
BF D197 ; #CYRILLIC SMALL LETTER YI
|
||||
C0 D090 ; #CYRILLIC CAPITAL LETTER A
|
||||
C1 D091 ; #CYRILLIC CAPITAL LETTER BE
|
||||
C2 D092 ; #CYRILLIC CAPITAL LETTER VE
|
||||
C3 D093 ; #CYRILLIC CAPITAL LETTER GHE
|
||||
C4 D094 ; #CYRILLIC CAPITAL LETTER DE
|
||||
C5 D095 ; #CYRILLIC CAPITAL LETTER IE
|
||||
C6 D096 ; #CYRILLIC CAPITAL LETTER ZHE
|
||||
C7 D097 ; #CYRILLIC CAPITAL LETTER ZE
|
||||
C8 D098 ; #CYRILLIC CAPITAL LETTER I
|
||||
C9 D099 ; #CYRILLIC CAPITAL LETTER SHORT I
|
||||
CA D09A ; #CYRILLIC CAPITAL LETTER KA
|
||||
CB D09B ; #CYRILLIC CAPITAL LETTER EL
|
||||
CC D09C ; #CYRILLIC CAPITAL LETTER EM
|
||||
CD D09D ; #CYRILLIC CAPITAL LETTER EN
|
||||
CE D09E ; #CYRILLIC CAPITAL LETTER O
|
||||
CF D09F ; #CYRILLIC CAPITAL LETTER PE
|
||||
D0 D0A0 ; #CYRILLIC CAPITAL LETTER ER
|
||||
D1 D0A1 ; #CYRILLIC CAPITAL LETTER ES
|
||||
D2 D0A2 ; #CYRILLIC CAPITAL LETTER TE
|
||||
D3 D0A3 ; #CYRILLIC CAPITAL LETTER U
|
||||
D4 D0A4 ; #CYRILLIC CAPITAL LETTER EF
|
||||
D5 D0A5 ; #CYRILLIC CAPITAL LETTER HA
|
||||
D6 D0A6 ; #CYRILLIC CAPITAL LETTER TSE
|
||||
D7 D0A7 ; #CYRILLIC CAPITAL LETTER CHE
|
||||
D8 D0A8 ; #CYRILLIC CAPITAL LETTER SHA
|
||||
D9 D0A9 ; #CYRILLIC CAPITAL LETTER SHCHA
|
||||
DA D0AA ; #CYRILLIC CAPITAL LETTER HARD SIGN
|
||||
DB D0AB ; #CYRILLIC CAPITAL LETTER YERU
|
||||
DC D0AC ; #CYRILLIC CAPITAL LETTER SOFT SIGN
|
||||
DD D0AD ; #CYRILLIC CAPITAL LETTER E
|
||||
DE D0AE ; #CYRILLIC CAPITAL LETTER YU
|
||||
DF D0AF ; #CYRILLIC CAPITAL LETTER YA
|
||||
E0 D0B0 ; #CYRILLIC SMALL LETTER A
|
||||
E1 D0B1 ; #CYRILLIC SMALL LETTER BE
|
||||
E2 D0B2 ; #CYRILLIC SMALL LETTER VE
|
||||
E3 D0B3 ; #CYRILLIC SMALL LETTER GHE
|
||||
E4 D0B4 ; #CYRILLIC SMALL LETTER DE
|
||||
E5 D0B5 ; #CYRILLIC SMALL LETTER IE
|
||||
E6 D0B6 ; #CYRILLIC SMALL LETTER ZHE
|
||||
E7 D0B7 ; #CYRILLIC SMALL LETTER ZE
|
||||
E8 D0B8 ; #CYRILLIC SMALL LETTER I
|
||||
E9 D0B9 ; #CYRILLIC SMALL LETTER SHORT I
|
||||
EA D0BA ; #CYRILLIC SMALL LETTER KA
|
||||
EB D0BB ; #CYRILLIC SMALL LETTER EL
|
||||
EC D0BC ; #CYRILLIC SMALL LETTER EM
|
||||
ED D0BD ; #CYRILLIC SMALL LETTER EN
|
||||
EE D0BE ; #CYRILLIC SMALL LETTER O
|
||||
EF D0BF ; #CYRILLIC SMALL LETTER PE
|
||||
F0 D180 ; #CYRILLIC SMALL LETTER ER
|
||||
F1 D181 ; #CYRILLIC SMALL LETTER ES
|
||||
F2 D182 ; #CYRILLIC SMALL LETTER TE
|
||||
F3 D183 ; #CYRILLIC SMALL LETTER U
|
||||
F4 D184 ; #CYRILLIC SMALL LETTER EF
|
||||
F5 D185 ; #CYRILLIC SMALL LETTER HA
|
||||
F6 D186 ; #CYRILLIC SMALL LETTER TSE
|
||||
F7 D187 ; #CYRILLIC SMALL LETTER CHE
|
||||
F8 D188 ; #CYRILLIC SMALL LETTER SHA
|
||||
F9 D189 ; #CYRILLIC SMALL LETTER SHCHA
|
||||
FA D18A ; #CYRILLIC SMALL LETTER HARD SIGN
|
||||
FB D18B ; #CYRILLIC SMALL LETTER YERU
|
||||
FC D18C ; #CYRILLIC SMALL LETTER SOFT SIGN
|
||||
FD D18D ; #CYRILLIC SMALL LETTER E
|
||||
FE D18E ; #CYRILLIC SMALL LETTER YU
|
||||
FF D18F ; #CYRILLIC SMALL LETTER YA
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
au BufRead,BufNewFile *.nginx set ft=nginx
|
||||
au BufRead,BufNewFile */etc/nginx/* set ft=nginx
|
||||
au BufRead,BufNewFile */usr/local/nginx/conf/* set ft=nginx
|
||||
au BufRead,BufNewFile nginx.conf set ft=nginx
|
||||
@@ -0,0 +1 @@
|
||||
setlocal commentstring=#\ %s
|
||||
@@ -0,0 +1,11 @@
|
||||
if exists("b:did_indent")
|
||||
finish
|
||||
endif
|
||||
let b:did_indent = 1
|
||||
|
||||
setlocal indentexpr=
|
||||
|
||||
" cindent actually works for nginx' simple file structure
|
||||
setlocal cindent
|
||||
" Just make sure that the comments are not reset as defs would be.
|
||||
setlocal cinkeys-=0#
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,126 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio economic status,
|
||||
nationality, personal appearance, race, caste, color, religion, or sexual
|
||||
identity and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
- Demonstrating empathy and kindness toward other people
|
||||
- Being respectful of differing opinions, viewpoints, and experiences
|
||||
- Giving and gracefully accepting constructive feedback
|
||||
- Accepting responsibility and apologizing to those affected by our mistakes
|
||||
and learning from the experience
|
||||
- Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
- The use of sexualized language or imagery, and sexual attention or advances
|
||||
of any kind
|
||||
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or email address,
|
||||
without their explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards
|
||||
of acceptable behavior and will take appropriate and fair corrective action
|
||||
in response to any behavior that they deem inappropriate, threatening,
|
||||
offensive, or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for
|
||||
moderation decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official email address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
<nginx-oss-community@f5.com>. All complaints will be reviewed and investigated
|
||||
promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external
|
||||
channels like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the
|
||||
[Contributor Covenant](https://www.contributor-covenant.org), version 2.1,
|
||||
available at
|
||||
<https://www.contributor-covenant.org/version/2/1/code_of_conduct.html>.
|
||||
|
||||
Community Impact Guidelines were inspired by
|
||||
[Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/inclusion).
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
<https://www.contributor-covenant.org/faq>. Translations are available at
|
||||
<https://www.contributor-covenant.org/translations>.
|
||||
@@ -0,0 +1,128 @@
|
||||
# Contributing Guidelines
|
||||
|
||||
The following is a set of guidelines for contributing to nginx project.
|
||||
We really appreciate that you are considering contributing!
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Report a Bug](#report-a-bug)
|
||||
- [Suggest a Feature or Enhancement](#suggest-a-feature-or-enhancement)
|
||||
- [Open a Discussion](#open-a-discussion)
|
||||
- [Submit a Pull Request](#submit-a-pull-request)
|
||||
- [Issue Lifecycle](#issue-lifecycle)
|
||||
|
||||
## Report a Bug
|
||||
|
||||
To report a bug, open an issue on GitHub with the label `bug` using the
|
||||
available [bug report issue form](/.github/ISSUE_TEMPLATE/bug_report.yml).
|
||||
Please ensure the bug has not already been reported. **If the bug is a
|
||||
potential security vulnerability, please report it using our
|
||||
[security policy](/SECURITY.md).**
|
||||
|
||||
## Suggest a Feature or Enhancement
|
||||
|
||||
To suggest a feature or enhancement, please create an issue on GitHub with the
|
||||
label `enhancement` using the available
|
||||
[feature request issue form](/.github/ISSUE_TEMPLATE/feature_request.yml).
|
||||
Please ensure the feature or enhancement has not already been suggested.
|
||||
|
||||
## Open a Discussion
|
||||
|
||||
If you want to engage in a conversation with the community and maintainers,
|
||||
we encourage you to use
|
||||
[GitHub Discussions](https://github.com/nginx/nginx/discussions) to discuss
|
||||
the NGINX codebase or the [NGINX Community forum](https://community.nginx.org)
|
||||
to chat anything else NGINX (including troubleshooting).
|
||||
|
||||
## Submit a Pull Request
|
||||
|
||||
Follow this plan to contribute a change to NGINX source code:
|
||||
|
||||
- Fork the NGINX repository
|
||||
- Create a branch
|
||||
- Implement your changes in this branch
|
||||
- Submit a pull request (PR) when your changes are tested and ready for review
|
||||
|
||||
Refer to
|
||||
[NGINX Development Guide](https://nginx.org/en/docs/dev/development_guide.html)
|
||||
for questions about NGINX programming.
|
||||
|
||||
### Formatting Changes
|
||||
|
||||
- Changes should be formatted according to the
|
||||
[code style](https://nginx.org/en/docs/dev/development_guide.html#code_style)
|
||||
used by NGINX; sometimes, there is no clear rule, in which case examine how
|
||||
existing NGINX sources are formatted and mimic this style; changes will more
|
||||
likely be accepted if style corresponds to the surrounding code
|
||||
|
||||
- Keep a clean, concise and meaningful commit history on your branch, rebasing
|
||||
locally and breaking changes logically into commits before submitting a PR
|
||||
|
||||
- Each commit message should have a single-line subject line followed by verbose
|
||||
description after an empty line
|
||||
|
||||
- Limit the subject line to 67 characters, and the rest of the commit message
|
||||
to 76 characters
|
||||
|
||||
- Use subject line prefixes for commits that affect a specific portion of the
|
||||
code; examples include "Upstream:", "QUIC:", or "Core:"; see the commit history
|
||||
to get an idea of the prefixes used
|
||||
|
||||
- If the commit fixes an open issue then you can use the "Closes:" tag/trailer
|
||||
to reference it and have GitHub automatically close it once it's been merged.
|
||||
E.g.:
|
||||
|
||||
`Closes: https://github.com/nginx/nginx/issues/9999`
|
||||
|
||||
That should go at the end of the commit message, separated by a blank line,
|
||||
along with any other tags.
|
||||
|
||||
### Before Submitting
|
||||
|
||||
- The proposed changes should work properly on a wide range of
|
||||
[supported platforms](https://nginx.org/en/index.html#tested_os_and_platforms)
|
||||
|
||||
- Try to make it clear why the suggested change is needed, and provide a use
|
||||
case, if possible
|
||||
|
||||
- Passing your changes through the test suite is a good way to ensure that they
|
||||
do not cause a regression; the repository with tests can be cloned with the
|
||||
following command:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/nginx/nginx-tests.git
|
||||
```
|
||||
|
||||
- Submitting a change implies granting project a permission to use it under the
|
||||
[BSD-2-Clause license](/LICENSE)
|
||||
|
||||
### F5 Contributor License Agreement (CLA)
|
||||
|
||||
F5 requires all contributors to agree to the terms of the F5 CLA
|
||||
(available [here](https://github.com/f5/f5-cla/blob/main/docs/f5_cla.md))
|
||||
before any of their changes can be incorporated into an F5 Open Source
|
||||
repository (even contributions to the F5 CLA itself!).
|
||||
|
||||
If you have not yet agreed to the F5 CLA terms and submit a PR to this
|
||||
repository, a bot will prompt you to view and agree to the F5 CLA.
|
||||
You will have to agree to the F5 CLA terms through a comment in the PR
|
||||
before any of your changes can be merged. Your agreement signature
|
||||
will be safely stored by F5 and no longer be required in future PRs.
|
||||
|
||||
## Issue Lifecycle
|
||||
|
||||
To ensure a balance between work carried out by the NGINX engineering team
|
||||
while encouraging community involvement on this project, we use the following
|
||||
issue lifecycle:
|
||||
|
||||
- A new issue is created by a community member
|
||||
|
||||
- An owner on the NGINX engineering team is assigned to the issue; this
|
||||
owner shepherds the issue through the subsequent stages in the issue lifecycle
|
||||
|
||||
- The owner assigns one or more
|
||||
[labels](https://github.com/nginx/nginx/issues/labels) to the issue
|
||||
|
||||
- The owner, in collaboration with the wider team (product management and
|
||||
engineering), determines what milestone to attach to an issue;
|
||||
generally, milestones correspond to product releases
|
||||
@@ -0,0 +1,24 @@
|
||||
Copyright (C) 2002-2021 Igor Sysoev
|
||||
Copyright (C) 2011-2026 Nginx, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
@@ -0,0 +1,177 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
https://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
@@ -0,0 +1,104 @@
|
||||
PCRE2 Licence
|
||||
=============
|
||||
|
||||
| SPDX-License-Identifier: | BSD-3-Clause WITH PCRE2-exception |
|
||||
|---------|-------|
|
||||
|
||||
PCRE2 is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Releases 10.00 and above of PCRE2 are distributed under the terms of the "BSD"
|
||||
licence, as specified below, with one exemption for certain binary
|
||||
redistributions. The documentation for PCRE2, supplied in the "doc" directory,
|
||||
is distributed under the same terms as the software itself. The data in the
|
||||
testdata directory is not copyrighted and is in the public domain.
|
||||
|
||||
The basic library functions are written in C and are freestanding. Also
|
||||
included in the distribution is a just-in-time compiler that can be used to
|
||||
optimize pattern matching. This is an optional feature that can be omitted when
|
||||
the library is built. The just-in-time compiler is separately licensed under the
|
||||
"2-clause BSD" licence.
|
||||
|
||||
|
||||
COPYRIGHT
|
||||
---------
|
||||
|
||||
### The basic library functions
|
||||
|
||||
Written by: Philip Hazel
|
||||
Email local part: Philip.Hazel
|
||||
Email domain: gmail.com
|
||||
|
||||
Retired from University of Cambridge Computing Service,
|
||||
Cambridge, England.
|
||||
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
Copyright (c) 2007-2024 Philip Hazel
|
||||
All rights reserved.
|
||||
|
||||
### PCRE2 Just-In-Time compilation support
|
||||
|
||||
Written by: Zoltan Herczeg
|
||||
Email local part: hzmester
|
||||
Email domain: freemail.hu
|
||||
|
||||
Copyright (c) 2010-2024 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
### Stack-less Just-In-Time compiler
|
||||
|
||||
Written by: Zoltan Herczeg
|
||||
Email local part: hzmester
|
||||
Email domain: freemail.hu
|
||||
|
||||
Copyright (c) 2009-2024 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
The code in the `deps/sljit` directory has its own LICENSE file.
|
||||
|
||||
### All other contributions
|
||||
|
||||
Many other contributors have participated in the authorship of PCRE2. As PCRE2
|
||||
has never required a Contributor Licensing Agreement, or other copyright
|
||||
assignment agreement, all contributions have copyright retained by each
|
||||
original contributor or their employer.
|
||||
|
||||
|
||||
THE "BSD" LICENCE
|
||||
-----------------
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notices,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notices, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of any
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
EXEMPTION FOR BINARY LIBRARY-LIKE PACKAGES
|
||||
------------------------------------------
|
||||
|
||||
The second condition in the BSD licence (covering binary redistributions) does
|
||||
not apply all the way down a chain of software. If binary package A includes
|
||||
PCRE2, it must respect the condition, but if package B is software that
|
||||
includes package A, the condition is not imposed on package B unless it uses
|
||||
PCRE2 independently.
|
||||
@@ -0,0 +1,232 @@
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/9335b488-ffcc-4157-8364-2370a0b70ad0">
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://github.com/user-attachments/assets/3a7eeb08-1133-47f5-859c-fad4f5a6a013">
|
||||
<img alt="NGINX Banner">
|
||||
</picture>
|
||||
|
||||
[](https://www.repostatus.org/#active)
|
||||
[](https://community.nginx.org)
|
||||
[](/LICENSE)
|
||||
[](/CODE_OF_CONDUCT.md)
|
||||
|
||||
NGINX (pronounced "engine x" or "en-jin-eks") is the world's most popular Web Server, high performance Load Balancer, Reverse Proxy, API Gateway and Content Cache.
|
||||
|
||||
NGINX is free and open source software, distributed under the terms of a simplified [2-clause BSD-like license](LICENSE).
|
||||
|
||||
Enterprise distributions, commercial support and training are available from [F5, Inc](https://www.f5.com/products/nginx).
|
||||
|
||||
> [!IMPORTANT]
|
||||
> The goal of this README is to provide a basic, structured introduction to NGINX for novice users. Please refer to the [full NGINX documentation](https://nginx.org/en/docs/) for detailed information on [installing](https://nginx.org/en/docs/install.html), [building](https://nginx.org/en/docs/configure.html), [configuring](https://nginx.org/en/docs/dirindex.html), [debugging](https://nginx.org/en/docs/debugging_log.html), and more. These documentation pages also contain a more detailed [Beginners Guide](https://nginx.org/en/docs/beginners_guide.html), How-Tos, [Development guide](https://nginx.org/en/docs/dev/development_guide.html), and a complete module and [directive reference](https://nginx.org/en/docs/dirindex.html).
|
||||
|
||||
# Table of contents
|
||||
- [How it works](#how-it-works)
|
||||
- [Modules](#modules)
|
||||
- [Configurations](#configurations)
|
||||
- [Runtime](#runtime)
|
||||
- [Downloading and installing](#downloading-and-installing)
|
||||
- [Stable and Mainline binaries](#stable-and-mainline-binaries)
|
||||
- [Linux binary installation process](#linux-binary-installation-process)
|
||||
- [FreeBSD installation process](#freebsd-installation-process)
|
||||
- [Windows executables](#windows-executables)
|
||||
- [Dynamic modules](#dynamic-modules)
|
||||
- [Getting started with NGINX](#getting-started-with-nginx)
|
||||
- [Installing SSL certificates and enabling TLS encryption](#installing-ssl-certificates-and-enabling-tls-encryption)
|
||||
- [Load Balancing](#load-balancing)
|
||||
- [Rate limiting](#rate-limiting)
|
||||
- [Content caching](#content-caching)
|
||||
- [Building from source](#building-from-source)
|
||||
- [Installing dependencies](#installing-dependencies)
|
||||
- [Cloning the NGINX GitHub repository](#cloning-the-nginx-github-repository)
|
||||
- [Configuring the build](#configuring-the-build)
|
||||
- [Compiling](#compiling)
|
||||
- [Location of binary and installation](#location-of-binary-and-installation)
|
||||
- [Running and testing the installed binary](#running-and-testing-the-installed-binary)
|
||||
- [Asking questions and reporting issues](#asking-questions-and-reporting-issues)
|
||||
- [Contributing code](#contributing-code)
|
||||
- [Additional help and resources](#additional-help-and-resources)
|
||||
- [Changelog](#changelog)
|
||||
- [License](#license)
|
||||
|
||||
# How it works
|
||||
NGINX is installed software with binary packages available for all major operating systems and Linux distributions. See [Tested OS and Platforms](https://nginx.org/en/#tested_os_and_platforms) for a full list of compatible systems.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> While nearly all popular Linux-based operating systems are distributed with a community version of nginx, we highly advise installation and usage of official [packages](https://nginx.org/en/linux_packages.html) or sources from this repository. Doing so ensures that you're using the most recent release or source code, including the latest feature-set, fixes and security patches.
|
||||
|
||||
## Modules
|
||||
NGINX is comprised of individual modules, each extending core functionality by providing additional, configurable features. See "Modules reference" at the bottom of [nginx documentation](https://nginx.org/en/docs/) for a complete list of official modules.
|
||||
|
||||
NGINX modules can be built and distributed as static or dynamic modules. Static modules are defined at build-time, compiled, and distributed in the resulting binaries. See [Dynamic Modules](#dynamic-modules) for more information on how they work, as well as, how to obtain, install, and configure them.
|
||||
|
||||
> [!TIP]
|
||||
> You can issue the following command to see which static modules your NGINX binaries were built with:
|
||||
```bash
|
||||
nginx -V
|
||||
```
|
||||
> See [Configuring the build](#configuring-the-build) for information on how to include specific Static modules into your nginx build.
|
||||
|
||||
## Configurations
|
||||
NGINX is highly flexible and configurable. Provisioning the software is achieved via text-based config file(s) accepting parameters called "[Directives](https://nginx.org/en/docs/dirindex.html)". See [Configuration File's Structure](https://nginx.org/en/docs/beginners_guide.html#conf_structure) for a comprehensive description of how NGINX configuration files work.
|
||||
|
||||
> [!NOTE]
|
||||
> The set of directives available to your distribution of NGINX is dependent on which [modules](#modules) have been made available to it.
|
||||
|
||||
## Runtime
|
||||
Rather than running in a single, monolithic process, NGINX is architected to scale beyond Operating System process limitations by operating as a collection of processes. They include:
|
||||
- A "master" process that maintains worker processes, as well as, reads and evaluates configuration files.
|
||||
- One or more "worker" processes that process data (eg. HTTP requests).
|
||||
|
||||
The number of [worker processes](https://nginx.org/en/docs/ngx_core_module.html#worker_processes) is defined in the configuration file and may be fixed for a given configuration or automatically adjusted to the number of available CPU cores. In most cases, the latter option optimally balances load across available system resources, as NGINX is designed to efficiently distribute work across all worker processes.
|
||||
|
||||
> [!TIP]
|
||||
> Processes synchronize data through shared memory. For this reason, many NGINX directives require the allocation of shared memory zones. As an example, when configuring [rate limiting](https://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req), connecting clients may need to be tracked in a [common memory zone](https://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req_zone) so all worker processes can know how many times a particular client has accessed the server in a span of time.
|
||||
|
||||
# Downloading and installing
|
||||
Follow these steps to download and install precompiled NGINX binaries. You may also choose to [build NGINX locally from source code](#building-from-source).
|
||||
|
||||
## Stable and Mainline binaries
|
||||
NGINX binaries are built and distributed in two versions: stable and mainline. Stable binaries are built from stable branches and only contain critical fixes backported from the mainline version. Mainline binaries are built from the [master branch](https://github.com/nginx/nginx/tree/master) and contain the latest features and bugfixes. You'll need to [decide which is appropriate for your purposes](https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-open-source/#choosing-between-a-stable-or-a-mainline-version).
|
||||
|
||||
## Linux binary installation process
|
||||
The NGINX binary installation process takes advantage of package managers native to specific Linux distributions. For this reason, first-time installations involve adding the official NGINX package repository to your system's package manager. Follow [these steps](https://nginx.org/en/linux_packages.html) to download, verify, and install NGINX binaries using the package manager appropriate for your Linux distribution.
|
||||
|
||||
### Upgrades
|
||||
Future upgrades to the latest version can be managed using the same package manager without the need to manually download and verify binaries.
|
||||
|
||||
## FreeBSD installation process
|
||||
For more information on installing NGINX on FreeBSD system, visit https://nginx.org/en/docs/install.html
|
||||
|
||||
## Windows executables
|
||||
Windows executables for mainline and stable releases can be found on the main [NGINX download page](https://nginx.org/en/download.html). Note that the current implementation of NGINX for Windows is at the Proof-of-Concept stage and should only be used for development and testing purposes. For additional information, please see [nginx for Windows](https://nginx.org/en/docs/windows.html).
|
||||
|
||||
## Dynamic modules
|
||||
NGINX version 1.9.11 added support for [Dynamic Modules](https://nginx.org/en/docs/ngx_core_module.html#load_module). Unlike Static modules, dynamically built modules can be downloaded, installed, and configured after the core NGINX binaries have been built. [Official dynamic module binaries](https://nginx.org/en/linux_packages.html#dynmodules) are available from the same package repository as the core NGINX binaries described in previous steps.
|
||||
|
||||
> [!TIP]
|
||||
> [NGINX JavaScript (njs)](https://github.com/nginx/njs), is a popular NGINX dynamic module that enables the extension of core NGINX functionality using familiar JavaScript syntax.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> If desired, dynamic modules can also be built statically into NGINX at compile time.
|
||||
|
||||
# Getting started with NGINX
|
||||
For a gentle introduction to NGINX basics, please see our [Beginner’s Guide](https://nginx.org/en/docs/beginners_guide.html).
|
||||
|
||||
## Installing SSL certificates and enabling TLS encryption
|
||||
See [Configuring HTTPS servers](https://nginx.org/en/docs/http/configuring_https_servers.html) for a quick guide on how to enable secure traffic to your NGINX installation.
|
||||
|
||||
## Load Balancing
|
||||
For a quick start guide on configuring NGINX as a Load Balancer, please see [Using nginx as HTTP load balancer](https://nginx.org/en/docs/http/load_balancing.html).
|
||||
|
||||
## Rate limiting
|
||||
See our [Rate Limiting with NGINX](https://blog.nginx.org/blog/rate-limiting-nginx) blog post for an overview of core concepts for provisioning NGINX as an API Gateway.
|
||||
|
||||
## Content caching
|
||||
See [A Guide to Caching with NGINX and NGINX Plus](https://blog.nginx.org/blog/nginx-caching-guide) blog post for an overview of how to use NGINX as a content cache (e.g. edge server of a content delivery network).
|
||||
|
||||
# Building from source
|
||||
The following steps can be used to build NGINX from source code available in this repository.
|
||||
|
||||
## Installing dependencies
|
||||
Most Linux distributions will require several dependencies to be installed in order to build NGINX. The following instructions are specific to the `apt` package manager, widely available on most Ubuntu/Debian distributions and their derivatives.
|
||||
|
||||
> [!TIP]
|
||||
> It is always a good idea to update your package repository lists prior to installing new packages.
|
||||
> ```bash
|
||||
> sudo apt update
|
||||
> ```
|
||||
|
||||
### Installing compiler and make utility
|
||||
Use the following command to install the GNU C compiler and Make utility.
|
||||
|
||||
```bash
|
||||
sudo apt install gcc make
|
||||
```
|
||||
|
||||
### Installing dependency libraries
|
||||
|
||||
```bash
|
||||
sudo apt install libpcre3-dev zlib1g-dev
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> This is the minimal set of dependency libraries needed to build NGINX with rewriting and gzip capabilities. Other dependencies may be required if you choose to build NGINX with additional modules. Monitor the output of the `configure` command discussed in the following sections for information on which modules may be missing. For example, if you plan to use SSL certificates to encrypt traffic with TLS, you'll need to install the OpenSSL library. To do so, issue the following command.
|
||||
|
||||
>```bash
|
||||
>sudo apt install libssl-dev
|
||||
|
||||
## Cloning the NGINX GitHub repository
|
||||
Using your preferred method, clone the NGINX repository into your development directory. See [Cloning a GitHub Repository](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) for additional help.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/nginx/nginx.git
|
||||
```
|
||||
|
||||
## Configuring the build
|
||||
Prior to building NGINX, you must run the `configure` script with [appropriate flags](https://nginx.org/en/docs/configure.html). This will generate a Makefile in your NGINX source root directory that can then be used to compile NGINX with [options specified during configuration](https://nginx.org/en/docs/configure.html).
|
||||
|
||||
From the NGINX source code repository's root directory:
|
||||
|
||||
```bash
|
||||
auto/configure
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Configuring the build without any flags will compile NGINX with the default set of options. Please refer to https://nginx.org/en/docs/configure.html for a full list of available build configuration options.
|
||||
|
||||
## Compiling
|
||||
The `configure` script will generate a `Makefile` in the NGINX source root directory upon successful execution. To compile NGINX into a binary, issue the following command from that same directory:
|
||||
|
||||
```bash
|
||||
make
|
||||
```
|
||||
|
||||
## Location of binary and installation
|
||||
After successful compilation, a binary will be generated at `<NGINX_SRC_ROOT_DIR>/objs/nginx`. To install this binary, issue the following command from the source root directory:
|
||||
|
||||
```bash
|
||||
sudo make install
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> The binary will be installed into the `/usr/local/nginx/` directory.
|
||||
|
||||
## Running and testing the installed binary
|
||||
To run the installed binary, issue the following command:
|
||||
|
||||
```bash
|
||||
sudo /usr/local/nginx/sbin/nginx
|
||||
```
|
||||
|
||||
You may test NGINX operation using `curl`.
|
||||
|
||||
```bash
|
||||
curl localhost
|
||||
```
|
||||
|
||||
The output of which should start with:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Welcome to nginx!</title>
|
||||
```
|
||||
|
||||
# Asking questions and reporting issues
|
||||
See our [Support](SUPPORT.md) guidelines for information on how discuss the codebase, ask troubleshooting questions, and report issues.
|
||||
|
||||
# Contributing code
|
||||
Please see the [Contributing](CONTRIBUTING.md) guide for information on how to contribute code.
|
||||
|
||||
# Additional help and resources
|
||||
- See the [NGINX Community Blog](https://blog.nginx.org/) for more tips, tricks and HOW-TOs related to NGINX and related projects.
|
||||
- Access [nginx.org](https://nginx.org/), your go-to source for all documentation, information and software related to the NGINX suite of projects.
|
||||
|
||||
# Changelog
|
||||
See our [changelog](https://nginx.org/en/CHANGES) to keep track of updates.
|
||||
|
||||
# License
|
||||
[2-clause BSD-like license](LICENSE)
|
||||
|
||||
---
|
||||
Additional documentation available at: https://nginx.org/en/docs
|
||||
@@ -0,0 +1,103 @@
|
||||
# Security Policy
|
||||
|
||||
This document provides an overview of security concerns related to nginx
|
||||
deployments, focusing on confidentiality, integrity, availability, and the
|
||||
implications of configurations and misconfigurations.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please report any vulnerabilities via one of the following methods
|
||||
(in order of preference):
|
||||
|
||||
1. [Report a vulnerability](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability)
|
||||
within this repository. We are using the GitHub workflow that allows us to
|
||||
manage vulnerabilities in a private manner and interact with reporters
|
||||
securely.
|
||||
|
||||
2. [Report directly to F5](https://www.f5.com/services/support/report-a-vulnerability).
|
||||
|
||||
3. Report via email to security-alert@nginx.org.
|
||||
This method will be deprecated in the future.
|
||||
|
||||
### Vulnerability Disclosure and Fix Process
|
||||
|
||||
The nginx team expects that all suspected vulnerabilities be reported
|
||||
privately via the
|
||||
[Reporting a Vulnerability](SECURITY.md#reporting-a-vulnerability) guidelines.
|
||||
If a publicly released vulnerability is reported, we
|
||||
may request to handle it according to the private disclosure process.
|
||||
If the reporter agrees, we will follow the private disclosure process.
|
||||
|
||||
Security fixes will be applied to all supported stable releases, as well
|
||||
as the mainline version, as applicable. We recommend using the most recent
|
||||
mainline or stable release of nginx. Fixes are created and tested by the core
|
||||
team using a GitHub private fork for security. If necessary, the reporter
|
||||
may be invited to contribute to the fork and assist with the solution.
|
||||
|
||||
The nginx team is committed to responsible information disclosure with
|
||||
sufficient detail, such as the CVSS score and vector. Privately disclosed
|
||||
vulnerabilities are embargoed by default until the fix is released.
|
||||
Communications and fixes remain private until made public. As nginx is
|
||||
supported by F5, we generally follow the
|
||||
[F5 security vulnerability response policy](https://my.f5.com/manage/s/article/K4602).
|
||||
|
||||
### Vulnerability Disclosure and Fix Service Level Objectives
|
||||
|
||||
- We will acknowledge all vulnerability reports within 1 to 3 days.
|
||||
- Fixes will be developed and released within 90 days from the date of
|
||||
disclosure. If an extension is needed, we will work with the disclosing person.
|
||||
- Publicly disclosed (i.e., Zero-Day vulnerabilities) will be addressed ASAP.
|
||||
|
||||
## Confidentiality, Integrity, and Availability
|
||||
|
||||
### Confidentiality and Integrity
|
||||
|
||||
Vulnerabilities compromising data confidentiality or integrity are considered
|
||||
the highest priority. Any issue leading to unauthorized data access, leaks, or
|
||||
manipulation will trigger the security release process.
|
||||
|
||||
### Availability
|
||||
|
||||
Availability issues must meet the following criteria to trigger the security
|
||||
release process:
|
||||
- Is present in a standard module included with nginx.
|
||||
- Arises from traffic that the module is designed to handle.
|
||||
- Resource exhaustion issues are not mitigated by existing timeout, rate
|
||||
limiting, or buffer size configurations, or applying changes is impractical.
|
||||
- Results in highly asymmetric, extreme resource consumption.
|
||||
|
||||
Availability issues excluded from the security release process:
|
||||
- Local file content or upstream response content resulting only in worker
|
||||
process termination.
|
||||
- Issues with experimental features which result only in availability impact.
|
||||
|
||||
## Trusted Configurations and Misconfigurations
|
||||
|
||||
In nginx, configuration files, modules, certificate/key pairs, nginx JavaScript,
|
||||
and local file content are considered trusted sources. Issues arising from
|
||||
loading or execution of these trusted components are not considered
|
||||
vulnerabilities. Operators are responsible for securing and maintaining the
|
||||
integrity of these sources. Misconfigurations can create vulnerabilities, and
|
||||
operators should implement configurations according to best practices, review
|
||||
them regularly, and apply security updates.
|
||||
|
||||
## Data Plane vs. Control Plane
|
||||
|
||||
The data plane handles traffic through nginx, directly interacting with user
|
||||
data. nginx inherently trusts the content and instructions from upstream
|
||||
servers. The control plane governs configuration, management, and orchestration.
|
||||
Misconfigurations or vulnerabilities in the control plane can cause improper
|
||||
behavior in the data plane.
|
||||
|
||||
## Modules Under Scope
|
||||
|
||||
The policy applies to all nginx modules included in this repository. Security
|
||||
considerations and attack vectors for each module will be identified, with
|
||||
recommended configurations to mitigate risks.
|
||||
|
||||
## Debug Logging and Core Files
|
||||
|
||||
Debug logs and core files produced by nginx may contain un-sanitized data,
|
||||
including sensitive information like client requests, server configurations,
|
||||
and private key material. These artifacts must be handled carefully to avoid
|
||||
exposing confidential data.
|
||||
@@ -0,0 +1,48 @@
|
||||
# Support
|
||||
|
||||
## Ask a Question
|
||||
|
||||
We use GitHub issues for tracking bugs and feature requests
|
||||
related to this project.
|
||||
|
||||
If you don't know how something in the codebase works, are curious if NGINX
|
||||
is capable of achieving your desired functionality or want to discuss the
|
||||
implementation of an existing or in development feature, please start a
|
||||
GitHub discussion!
|
||||
|
||||
## NGINX Specific Questions and/or Issues
|
||||
|
||||
This project isn't the right place to get support for NGINX and/or NGINX
|
||||
troubleshooting questions, but the following resources are available below.
|
||||
Thanks for your understanding!
|
||||
|
||||
### Community Forum
|
||||
|
||||
We have a [community forum](https://community.nginx.org/)!
|
||||
If you have any NGINX specific questions and/or issues,
|
||||
try checking out the [`NGINX category`](https://community.nginx.org/c/projects/nginx/23).
|
||||
For general discussions around anything tangentially NGINX related,
|
||||
check out the [`General Discussion category`](https://community.nginx.org/c/general-discussion/34).
|
||||
Both fellow community members and NGINXers might be able to help you! :)
|
||||
|
||||
### Documentation
|
||||
|
||||
For a comprehensive list of all NGINX directives, check out <https://nginx.org>.
|
||||
|
||||
For a comprehensive list of administration and deployment guides for all
|
||||
NGINX products, check out <https://docs.nginx.com>.
|
||||
|
||||
## Contributing
|
||||
|
||||
Please see the [contributing guide](/CONTRIBUTING.md) for guidelines
|
||||
on how to best contribute to this project.
|
||||
|
||||
## Commercial Support
|
||||
|
||||
Commercial support for this project is available.
|
||||
Please get in touch with [F5 sales](https://www.f5.com/products/get-f5/)
|
||||
or check your contract details for more information!
|
||||
|
||||
## Community Support
|
||||
|
||||
Community support is offered on a best effort basis through any of our active communities.
|
||||
@@ -0,0 +1,20 @@
|
||||
(C) 1995-2026 Jean-loup Gailly and Mark Adler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Jean-loup Gailly Mark Adler
|
||||
jloup@gzip.org madler@alumni.caltech.edu
|
||||
@@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Error</title>
|
||||
<style>
|
||||
html { color-scheme: light dark; }
|
||||
body { width: 35em; margin: 0 auto;
|
||||
font-family: Tahoma, Verdana, Arial, sans-serif; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>An error occurred.</h1>
|
||||
<p>Sorry, the page you are looking for is currently unavailable.<br/>
|
||||
Please try again later.</p>
|
||||
<p>If you are the system administrator of this resource then you should check
|
||||
the error log for details.</p>
|
||||
<p><em>Faithfully yours, nginx.</em></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Welcome to nginx!</title>
|
||||
<style>
|
||||
html { color-scheme: light dark; }
|
||||
body { width: 35em; margin: 0 auto;
|
||||
font-family: Tahoma, Verdana, Arial, sans-serif; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Welcome to nginx!</h1>
|
||||
<p>If you see this page, nginx is successfully installed and working.
|
||||
Further configuration is required for the web server, reverse proxy,
|
||||
API gateway, load balancer, content cache, or other features.</p>
|
||||
|
||||
<p>For online documentation and support please refer to
|
||||
<a href="https://nginx.org/">nginx.org</a>.<br/>
|
||||
To engage with the community please visit
|
||||
<a href="https://community.nginx.org/">community.nginx.org</a>.<br/>
|
||||
For enterprise grade support, professional services, additional
|
||||
security features and capabilities please refer to
|
||||
<a href="https://f5.com/nginx">f5.com/nginx</a>.</p>
|
||||
|
||||
<p><em>Thank you for using nginx.</em></p>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
Binary file not shown.
+5
-1
@@ -24,7 +24,7 @@ namespace SunlightAggregationManager
|
||||
}
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
GlobalLogManager.RegisterTarget(LOG);
|
||||
GlobalLogManager.RegisterTarget(LOG,LogGing.LogGingDATA);
|
||||
|
||||
DataContext = new MainWindowViewModel();
|
||||
}
|
||||
@@ -68,6 +68,7 @@ namespace SunlightAggregationManager
|
||||
{
|
||||
state.Visibility = Visibility.Collapsed;
|
||||
Picture.Visibility = Visibility.Visible;
|
||||
Picture.Content = new View.ServicePage();
|
||||
}
|
||||
private void ListViewItem_MouseLeftButtonUp_log(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
@@ -79,11 +80,13 @@ namespace SunlightAggregationManager
|
||||
{
|
||||
state.Visibility = Visibility.Collapsed;
|
||||
Picture.Visibility = Visibility.Visible;
|
||||
Picture.Content = new View.MachinePage();
|
||||
}
|
||||
private void ListViewItem_MouseLeftButtonUp_extend(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
state.Visibility = Visibility.Collapsed;
|
||||
Picture.Visibility = Visibility.Visible;
|
||||
Picture.Content = new View.ExtendPage();
|
||||
}
|
||||
private void ListViewItem_MouseLeftButtonUp_user(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
@@ -95,6 +98,7 @@ namespace SunlightAggregationManager
|
||||
{
|
||||
state.Visibility = Visibility.Collapsed;
|
||||
Picture.Visibility = Visibility.Visible;
|
||||
Picture.Content = new View.ActionPage();
|
||||
}
|
||||
|
||||
private void ListViewItem_MouseLeftButtonUp_set(object sender, MouseButtonEventArgs e)
|
||||
|
||||
@@ -13,8 +13,10 @@
|
||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="10.0.5" />
|
||||
<PackageReference Include="Net.Codecrete.QrCodeGenerator" Version="2.1.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
<PackageReference Include="System.Data.SqlClient" Version="4.9.1" />
|
||||
<PackageReference Include="TouchSocket" Version="4.2.3" />
|
||||
<PackageReference Include="TouchSocket" Version="4.2.10" />
|
||||
<PackageReference Include="TouchSocket.Http" Version="4.2.10" />
|
||||
<PackageReference Include="vocaluxe.dependencies.netfwtypelib" Version="1.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -36,4 +38,8 @@
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="EX\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace SunlightAggregationManager.UserClass
|
||||
{
|
||||
public class AES
|
||||
{
|
||||
public static string AesEncipher(string Key, string dat) //加密
|
||||
{
|
||||
//压缩
|
||||
byte[] plainBytes = Compress( Encoding.UTF8.GetBytes(dat));
|
||||
|
||||
using var sha256 = System.Security.Cryptography.SHA256.Create();
|
||||
using var aes = System.Security.Cryptography.Aes.Create();
|
||||
|
||||
aes.Key = sha256.ComputeHash(Encoding.UTF8.GetBytes(Key));
|
||||
aes.Mode = CipherMode.CBC;
|
||||
aes.Padding = PaddingMode.PKCS7;
|
||||
aes.GenerateIV(); // 生成随机 IV
|
||||
|
||||
using var enc = aes.CreateEncryptor();
|
||||
byte[] cipherBytes = enc.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
|
||||
|
||||
//将 IV (16字节) 和 密文 拼接成一个完整的字节数组
|
||||
byte[] combinedBytes = new byte[aes.IV.Length + cipherBytes.Length];
|
||||
Buffer.BlockCopy(aes.IV, 0, combinedBytes, 0, aes.IV.Length);
|
||||
Buffer.BlockCopy(cipherBytes, 0, combinedBytes, aes.IV.Length, cipherBytes.Length);
|
||||
|
||||
return Convert.ToBase64String(combinedBytes);
|
||||
}
|
||||
|
||||
public static string AesDecrypt(string Key, string dat)//解密
|
||||
{
|
||||
// 解码Base64
|
||||
byte[] cipherBytes = Convert.FromBase64String(dat);
|
||||
|
||||
using var sha256 = System.Security.Cryptography.SHA256.Create();
|
||||
using var aes = System.Security.Cryptography.Aes.Create();
|
||||
|
||||
aes.Key = sha256.ComputeHash(Encoding.UTF8.GetBytes(Key));
|
||||
aes.Mode = CipherMode.CBC;
|
||||
aes.Padding = PaddingMode.PKCS7;
|
||||
// 从字节数组中提取前 16 字节作为 IV
|
||||
aes.IV = cipherBytes.AsSpan(0, 16).ToArray();
|
||||
using var dec = aes.CreateDecryptor();
|
||||
|
||||
// 解密
|
||||
byte[] bytes = dec.TransformFinalBlock(cipherBytes, 16, cipherBytes.Length - 16);
|
||||
//解压缩并返回
|
||||
return Encoding.UTF8.GetString(Decompress(bytes));
|
||||
}
|
||||
|
||||
// 3. Brotli 压缩辅助方法
|
||||
private static byte[] Compress(byte[] data)
|
||||
{
|
||||
using var output = new MemoryStream();
|
||||
using (var brotli = new BrotliStream(output, CompressionLevel.Optimal))
|
||||
{
|
||||
brotli.Write(data, 0, data.Length);
|
||||
}
|
||||
return output.ToArray();
|
||||
}
|
||||
|
||||
// 4. Brotli 解压辅助方法
|
||||
private static byte[] Decompress(byte[] data)
|
||||
{
|
||||
using var input = new MemoryStream(data);
|
||||
using var brotli = new BrotliStream(input, CompressionMode.Decompress);
|
||||
using var output = new MemoryStream();
|
||||
brotli.CopyTo(output);
|
||||
return output.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,343 @@
|
||||
using SunlightAggregationManager.ViewModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using TouchSocket.Core;
|
||||
using TouchSocket.Http;
|
||||
using TouchSocket.Http.WebSockets;
|
||||
using TouchSocket.Sockets;
|
||||
using static SunlightAggregationManager.UserClass.AsyncTcpServer;
|
||||
|
||||
|
||||
namespace SunlightAggregationManager.UserClass
|
||||
{
|
||||
public class AsyncHttpServer
|
||||
{
|
||||
public static HttpService httpservice = new HttpService();
|
||||
public static async void Configuration(int P1)
|
||||
{
|
||||
await HttpMain(P1);
|
||||
}
|
||||
public static async Task HttpMain(int port1)
|
||||
{
|
||||
NetFwManger.AllowPort(port1, "TCP");//开放端口
|
||||
await httpservice.SetupAsync(new TouchSocketConfig()//加载配置
|
||||
.SetListenIPHosts(port1)
|
||||
.ConfigureContainer(a =>
|
||||
{
|
||||
a.AddConsoleLogger();
|
||||
})
|
||||
.ConfigurePlugins(a =>
|
||||
{
|
||||
a.Add<MyHttpPlug1>();
|
||||
//default插件应该最后添加,其作用是
|
||||
//1、为找不到的路由返回404
|
||||
//2、处理 header 为Option的探视跨域请求。
|
||||
a.UseDefaultHttpServicePlugin();
|
||||
}));
|
||||
await httpservice.StartAsync();
|
||||
Console.WriteLine("HTTP Port:" + port1.ToString());
|
||||
}
|
||||
|
||||
public class MyHttpPlug1 : PluginBase, IHttpPlugin
|
||||
{
|
||||
public async Task OnHttpRequest(IHttpSessionClient client, HttpContextEventArgs e)
|
||||
{
|
||||
#region HttpContext生命周期
|
||||
//var request = e.Context.Request;//http请求体
|
||||
var response = e.Context.Response;//http响应体
|
||||
#endregion
|
||||
|
||||
var bodyString = await e.Context.Request.GetBodyAsync();
|
||||
try
|
||||
{
|
||||
Person? deserializedPerson = JsonSerializer.Deserialize<Person>(bodyString);
|
||||
|
||||
var _user = MainWindowViewModel.Selet_Memory(MainWindowViewModel._userData, "State", "User='" +
|
||||
deserializedPerson?.User + "' and Password ='" + deserializedPerson?.Password + "'");
|
||||
if (_user != null)
|
||||
{
|
||||
string _dat = _user?.ToString() ?? "0";
|
||||
if (_dat != "99")
|
||||
{
|
||||
//行为
|
||||
Dictionary<string, object> myDict = new Dictionary<string, object>();
|
||||
myDict.Add("LinkID", client.Id);
|
||||
myDict.Add("LastLoginIP", deserializedPerson?.IP ?? client.IP);
|
||||
myDict.Add("LastActionTime", DateTime.Now);
|
||||
myDict.Add("Note", deserializedPerson?.Dat ?? "unknown");
|
||||
MainWindowViewModel.Updata_Memory(MainWindowViewModel._userData, "User='" + deserializedPerson?.User + "'", myDict);
|
||||
|
||||
Console.WriteLine("[Log on]User[" + deserializedPerson?.User + "]Note[" + (deserializedPerson?.Dat ?? "unknown") + "]");
|
||||
|
||||
deserializedPerson!.Dat = await Command(deserializedPerson!);
|
||||
var jsdat = JsonSerializer.Serialize(deserializedPerson);
|
||||
|
||||
e.Context.Response.Headers.Add("SUNLIGHT", "SUNLIGHT");
|
||||
e.Context.Response.SetStatus(200, "success");
|
||||
e.Context.Response.SetContent(jsdat);
|
||||
await e.Context.Response.AnswerAsync();
|
||||
}
|
||||
else
|
||||
{//停用账号关闭连接
|
||||
//client.SendAsync("Account Deactivated");
|
||||
e.Context.Response.Headers.Add("SUNLIGHT", "SUNLIGHT");
|
||||
e.Context.Response.SetStatus(200, "success");
|
||||
e.Context.Response.SetContent("Account Deactivated");
|
||||
await e.Context.Response.AnswerAsync();
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //无效账号关闭连接
|
||||
//client.SendAsync("Invalid Account");
|
||||
e.Context.Response.Headers.Add("SUNLIGHT", "SUNLIGHT");
|
||||
e.Context.Response.SetStatus(200, "success");
|
||||
e.Context.Response.SetContent("Invalid Account");
|
||||
await e.Context.Response.AnswerAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{//错误
|
||||
LogGing.ERRDATA(ex);
|
||||
Console.WriteLine("Http:" + ex.ToString());
|
||||
//client.SendAsync("Target instruction parsing error manager will close connection");
|
||||
}
|
||||
|
||||
|
||||
/* if (request.IsGet() && request.UrlEquals("/success"))
|
||||
{
|
||||
//直接响应文字
|
||||
await response
|
||||
.SetStatus(200, "success")
|
||||
.FromText("Success")
|
||||
.AnswerAsync();//直接回应
|
||||
Console.WriteLine("处理/success");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//无法处理,调用下一个插件
|
||||
await e.InvokeNext();*/
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<string> Command(Person deserializedPerson)//
|
||||
{
|
||||
string Command = "", ret = "";
|
||||
|
||||
Dictionary<string, object> data_ = new Dictionary<string, object>();
|
||||
var deserialized = JsonSerializer.Deserialize<Dictionary<string, object>>(deserializedPerson.Dat)!;
|
||||
if (deserialized.TryGetValue("Command", out var val) && val != null) Command = val.ToString()!;
|
||||
if (Command == "Log")//回复请求的信息
|
||||
{
|
||||
DataRow? _user = MainWindowViewModel.Selet_Row(MainWindowViewModel._userData, "User='" +
|
||||
deserializedPerson?.User + "' and Password ='" + deserializedPerson?.Password + "'");
|
||||
|
||||
data_.Add("Enterprise",MainWindowViewModel.Enterprise);
|
||||
data_.Add("Department", _user?.Field<object>("Department") ?? "");
|
||||
data_.Add("Groups", _user?.Field<object>("Groups") ?? "");
|
||||
data_.Add("UserId", _user?.Field<object>("UserID") ?? "");
|
||||
data_.Add("UserName", _user?.Field<object>("Name") ?? "");
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "SysData")//回复请求的信息
|
||||
{
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "ChemicalStatistics")//回复请求的信息
|
||||
{
|
||||
data_.Add("ChemicalStatistics", Newtonsoft.Json.JsonConvert.SerializeObject(MainWindowViewModel.ChemicalStatistics));
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "Info")//回复info请求的信息
|
||||
{
|
||||
var t = ToList(MainWindowViewModel._machines).ToJsonString();
|
||||
//格式化返回信息
|
||||
data_.Add("Info", t);
|
||||
data_.Add("DyeMeasurementNumber", MainWindowViewModel.DyeMeasurementNumber.ToString());
|
||||
data_.Add("ChemicalNumber", MainWindowViewModel.ChemicalNumber.ToString());
|
||||
data_.Add("PowderNumber", MainWindowViewModel.PowderNumber.ToString());
|
||||
data_.Add("DyeDissolveNumber", MainWindowViewModel.DyeDissolveNumber.ToString());
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "Query")//回复Query请求的信息
|
||||
{
|
||||
string s_ = deserialized.GetValue("StartTime").ToString()!;
|
||||
string e_ = deserialized.GetValue("EndTime").ToString()!;
|
||||
string f_ = deserialized.GetValue("Field").ToString()!;
|
||||
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[Dyelots] " + "WHERE CreationTime>'" + s_ + "'and CreationTime<'" + e_ + "'");
|
||||
//格式化返回信息
|
||||
data_.Add("Query", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "QueryDyelot")//回复QueryDyelot请求的信息
|
||||
{
|
||||
string d_ = deserialized.GetValue("DyelotName").ToString()!;
|
||||
string f_ = deserialized.GetValue("Field").ToString()!;
|
||||
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[Dyelots] " + "WHERE Dyelot LIKE '" + d_ + "%'");
|
||||
//格式化返回信息
|
||||
data_.Add("Query", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "QueryDetail")//回复QueryDetail请求的信息
|
||||
{
|
||||
string d_ = deserialized.GetValue("Dyelot").ToString()!;
|
||||
string r_ = deserialized.GetValue("ReDye").ToString()!;
|
||||
string f_ = deserialized.GetValue("Field").ToString()!;
|
||||
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[DyelotsBulkedRecipe] " + "WHERE Dyelot='" + d_ + "'and ReDye='" + r_ + "'");
|
||||
//格式化返回信息
|
||||
data_.Add("QueryDetail", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "Notification")//回复Notification请求的信息
|
||||
{
|
||||
string s_ = deserialized.GetValue("StartTime").ToString()!;
|
||||
string e_ = deserialized.GetValue("EndTime").ToString()!;
|
||||
|
||||
var groups = MainWindowViewModel.Selet_Memory(MainWindowViewModel._userData,
|
||||
"Groups", "User='" + deserializedPerson?.User + "'");
|
||||
|
||||
DataTable resultTable = MainWindowViewModel.SQLiteHelpers.ExecuteDataSet("" +
|
||||
"select * from Notification WHERE Groups='" + groups + "' and Id>'" +
|
||||
s_ + "'", null)?.Tables[0] ?? new DataTable();
|
||||
if (resultTable.Rows.Count == 0) resultTable.Rows.Add();
|
||||
|
||||
//格式化返回信息
|
||||
data_.Add("Notification", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "InfoMachine")//回复InfoMachine请求的信息
|
||||
{
|
||||
string t_ = deserialized.GetValue("Type").ToString()!;
|
||||
string? m_ = null, f_ = "*";
|
||||
|
||||
if (deserialized.TryGetValue("MachinName", out var MachinName) && MachinName != null) m_ = MachinName.ToString();
|
||||
if (deserialized.TryGetValue("Field", out var Field) && Field != null) f_ = Field.ToString();
|
||||
|
||||
if (t_ == "10")
|
||||
{
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[WaitDispenseDyestuff] WHERE DispenseMachine='" + m_ + "'");
|
||||
data_.Add("Type", "10");
|
||||
data_.Add("InfoMachine", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
}
|
||||
else if (t_ == "12")
|
||||
{
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[ShelfInfo] ");
|
||||
data_.Add("Type", "12");
|
||||
data_.Add("InfoMachine", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
}
|
||||
else if (t_ == "20")
|
||||
{
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[WaitChemical] WHERE DispenseMachine='" + m_ + "'");
|
||||
data_.Add("Type", "20");
|
||||
data_.Add("InfoMachine", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
}
|
||||
else
|
||||
{
|
||||
data_.Add("InfoMachine", "");
|
||||
}
|
||||
|
||||
//格式化返回信息
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "InfoMachineHistory")//回复InfoMachineHistory请求的信息
|
||||
{
|
||||
string t_ = deserialized.GetValue("Type").ToString()!;
|
||||
string? m_ = null, f_ = "*";
|
||||
|
||||
if (deserialized.TryGetValue("MachinName", out var MachinName) && MachinName != null) m_ = MachinName.ToString();
|
||||
if (deserialized.TryGetValue("Field", out var Field) && Field != null) f_ = Field.ToString();
|
||||
|
||||
if (t_ == "80")
|
||||
{
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[DyeSolutionHistory] WHERE DispenseStartTime >'" + DateTime.Now.AddDays(-3) +
|
||||
"' and DispenseMachine='" + m_ + "'");
|
||||
data_.Add("Type", "80");
|
||||
data_.Add("InfoMachineHistory", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
}
|
||||
else if (t_ == "82")
|
||||
{
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[inOutRecords] WHERE Createtime >'" + DateTime.Now.AddDays(-3) + "'");
|
||||
data_.Add("Type", "82");
|
||||
data_.Add("InfoMachineHistory", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
}
|
||||
else if (t_ == "90")
|
||||
{
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[DyeSolutionHistory] WHERE DispenseStartTime >'" + DateTime.Now.AddDays(-3) +
|
||||
"' and DispenseMachine='" + m_ + "'");
|
||||
data_.Add("Type", "90");
|
||||
data_.Add("InfoMachineHistory", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
}
|
||||
else
|
||||
{
|
||||
data_.Add("InfoMachineHistory", "");
|
||||
}
|
||||
|
||||
//格式化返回信息
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "InfoMachinePipes")//回复Notification请求的信息
|
||||
{
|
||||
string? m_ = null, f_ = "*";
|
||||
|
||||
if (deserialized.TryGetValue("MachinName", out var MachinName) && MachinName != null) m_ = MachinName.ToString();
|
||||
if (deserialized.TryGetValue("Field", out var Field) && Field != null) f_ = Field.ToString();
|
||||
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[Pipes] WHERE Dispenser='" + m_ + "'");
|
||||
data_.Add("InfoMachinePipes", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
|
||||
//格式化返回信息
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "SETUSER")//回复Notification请求的信息
|
||||
{
|
||||
MainWindowViewModel.Updata_Memory(MainWindowViewModel._userData,
|
||||
"User='" + deserialized.GetValue("USER").ToString()! + "'",
|
||||
deserialized.GetValue("VALUE").ToString(), deserialized.GetValue("KEY").ToString()!);
|
||||
data_.Add("USER", deserialized.GetValue("USER").ToString()!);
|
||||
data_.Add("VALUE", deserialized.GetValue("VALUE").ToString()!);
|
||||
data_.Add("KEY", deserialized.GetValue("KEY").ToString()!);
|
||||
data_.Add("SETUSER", "OK");
|
||||
//格式化返回信息
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static List<Dictionary<string, object?>>? ToList(DataTable table)//datatable转list
|
||||
{
|
||||
if (table == null) return null;
|
||||
|
||||
// 使用 AsEnumerable() 将 DataTable 转换为 IEnumerable<DataRow>
|
||||
// 然后投影为 Dictionary
|
||||
return table.AsEnumerable().Select(row =>
|
||||
table.Columns.Cast<DataColumn>().ToDictionary(
|
||||
col => col.ColumnName,
|
||||
col => {
|
||||
var value = row[col];
|
||||
// 核心修改:如果是数据库空值 DBNull.Value,则转为 C# 的 null,否则保持原值
|
||||
return value == DBNull.Value ? null : value;
|
||||
}
|
||||
)
|
||||
).ToList();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,457 @@
|
||||
using SunlightAggregationManager.UserWindow;
|
||||
using SunlightAggregationManager.ViewModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using TouchSocket.Core;
|
||||
using TouchSocket.Sockets;
|
||||
using static SunlightAggregationManager.UserClass.AsyncTcpServer;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
namespace SunlightAggregationManager.UserClass
|
||||
{
|
||||
public class AsyncTcpClient
|
||||
{
|
||||
public static TouchSocket.Sockets.TcpClient tcpClient = new TouchSocket.Sockets.TcpClient();
|
||||
public static async void Configuration(string ip, string Name, string user, string Password)
|
||||
{
|
||||
await TcpClient(tcpClient, "tcp://"+ip);
|
||||
}
|
||||
|
||||
public static async void TcpTransmit(object Dat)
|
||||
{
|
||||
//发送字符串数据
|
||||
try
|
||||
{
|
||||
await tcpClient.SendAsync(JsonSerializer.Serialize(Dat));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Tcp:" + ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task TcpClient(TouchSocket.Sockets.TcpClient tcpClient, string ip)
|
||||
{
|
||||
|
||||
// 自定义心跳首次延迟60秒开始,之后每30秒执行一次
|
||||
Timer timer = new Timer(TimerCallback, null, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(30));
|
||||
|
||||
tcpClient.Connecting = (client, e) => { return EasyTask.CompletedTask; };//即将连接到服务器,此时已经创建socket,但是还未建立tcp
|
||||
tcpClient.Connected = (client, e) =>
|
||||
{
|
||||
//设定显示状态
|
||||
System.Data.DataRow targetRow =ViewModel.MainWindowViewModel._service.Select("Service = 'Sunlight_Server_Link'").FirstOrDefault()!;
|
||||
if (targetRow != null)
|
||||
{
|
||||
targetRow.BeginEdit();
|
||||
targetRow["Status"] = "Connected";
|
||||
targetRow.EndEdit();
|
||||
}
|
||||
//发送本机信息到转发服务器
|
||||
Dictionary<string, object> myDict = new Dictionary<string, object>();
|
||||
myDict.Add("SERVEREnterprise", MainWindowViewModel.Enterprise);
|
||||
myDict.Add("SERVERMachineName", MainWindowViewModel.MachineName);
|
||||
myDict.Add("SERVERNAME", MainWindowViewModel.SERVERNAME);
|
||||
myDict.Add("SERVERUSER", MainWindowViewModel.SERVERUSER);
|
||||
myDict.Add("SERRVERPASWORD", MainWindowViewModel.SERRVERPASWORD);
|
||||
myDict.Add("MachineVer", MainWindowViewModel.MachineVer);
|
||||
TcpTransmit(myDict);
|
||||
|
||||
Console.WriteLine("Sunlight_Server_Connected");
|
||||
return EasyTask.CompletedTask;
|
||||
};//成功连接到服务器
|
||||
tcpClient.Closing = (client, e) => {
|
||||
System.Data.DataRow targetRow = ViewModel.MainWindowViewModel._service.Select("Service = 'Sunlight_Server_Link'").FirstOrDefault()!;
|
||||
if (targetRow != null)
|
||||
{
|
||||
targetRow.BeginEdit();
|
||||
targetRow["Status"] = "Disconnect";
|
||||
targetRow.EndEdit();
|
||||
}
|
||||
Console.WriteLine("Sunlight_Server_Disconnect");
|
||||
return EasyTask.CompletedTask; };//即将从服务器断开连接。此处仅主动断开才有效。
|
||||
tcpClient.Closed = (client, e) => {
|
||||
System.Data.DataRow targetRow = ViewModel.MainWindowViewModel._service.Select("Service = 'Sunlight_Server_Link'").FirstOrDefault()!;
|
||||
if (targetRow != null)
|
||||
{
|
||||
targetRow.BeginEdit();
|
||||
targetRow["Status"] = "Disconnect";
|
||||
targetRow.EndEdit();
|
||||
}
|
||||
Console.WriteLine("Sunlight_Server_Disconnect");
|
||||
return EasyTask.CompletedTask; };//从服务器断开连接,当连接不成功时不会触发。
|
||||
#region Tcp客户端使用Received异步委托接收数据
|
||||
tcpClient.Received = (client, e) =>
|
||||
{
|
||||
//从服务器收到信息。但是一般byteBlock和requestInfo会根据适配器呈现不同的值。
|
||||
var mes = e.Memory.Span.ToString(Encoding.UTF8);
|
||||
//信息处理暂停心跳定时
|
||||
timer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
|
||||
try
|
||||
{
|
||||
Person? deserializedPerson = JsonSerializer.Deserialize<Person>(mes);
|
||||
string password= AES.AesDecrypt(deserializedPerson?.Terminal!, deserializedPerson?.Password!);
|
||||
|
||||
var _user = MainWindowViewModel.Selet_Memory(MainWindowViewModel._userData, "State", "User='" +
|
||||
deserializedPerson?.User + "' and Password ='" + password + "'");
|
||||
if (_user != null)
|
||||
{
|
||||
string _dat = _user?.ToString() ?? "0";
|
||||
if (_dat != "99")
|
||||
{
|
||||
//行为
|
||||
Dictionary<string, object> myDict = new Dictionary<string, object>();
|
||||
//myDict.Add("LinkID", client.Id);
|
||||
|
||||
//AES解密
|
||||
string dataAES = AES.AesDecrypt(deserializedPerson!.Terminal, deserializedPerson.Dat);
|
||||
Console.WriteLine("[Log on]User[" + deserializedPerson?.User + "]COMMAND[" +
|
||||
Regex.Replace(dataAES, @"\\u[0-9A-Fa-f]{4}", match =>
|
||||
{ return Regex.Unescape(match.Value); }) + "]");
|
||||
|
||||
//记录
|
||||
myDict.Add("LastLoginIP", deserializedPerson?.IP ?? client.IP);
|
||||
myDict.Add("LastActionTime", DateTime.Now);
|
||||
myDict.Add("Note", dataAES ?? "unknown");
|
||||
|
||||
MainWindowViewModel.Updata_Memory(MainWindowViewModel._userData, "User='" +
|
||||
deserializedPerson?.User + "'", myDict);
|
||||
|
||||
CommandC(dataAES ?? "NOT", deserializedPerson!);
|
||||
}
|
||||
else
|
||||
{//停用账号关闭连接
|
||||
client.SendAsync("Account Deactivated");
|
||||
}
|
||||
}
|
||||
else if (password== MainWindowViewModel.SERRVERPASWORD && deserializedPerson?.User== MainWindowViewModel.SERVERUSER)
|
||||
{
|
||||
//行为
|
||||
Dictionary<string, object> myDict = new Dictionary<string, object>();
|
||||
//myDict.Add("LinkID", client.Id);
|
||||
|
||||
//AES解密
|
||||
string dataAES = AES.AesDecrypt(deserializedPerson!.Terminal, deserializedPerson.Dat);
|
||||
Console.WriteLine("[Log on]User[" + deserializedPerson?.User + "]COMMAND[" +
|
||||
Regex.Replace(dataAES, @"\\u[0-9A-Fa-f]{4}", match =>
|
||||
{ return Regex.Unescape(match.Value); }) + "]");
|
||||
|
||||
//记录
|
||||
myDict.Add("LastLoginIP", deserializedPerson?.IP ?? client.IP);
|
||||
myDict.Add("LastActionTime", DateTime.Now);
|
||||
myDict.Add("Note", dataAES ?? "unknown");
|
||||
|
||||
MainWindowViewModel.Updata_Memory(MainWindowViewModel._userData, "User='" +
|
||||
deserializedPerson?.User + "'", myDict);
|
||||
|
||||
CommandC(dataAES ?? "NOT", deserializedPerson!);
|
||||
}
|
||||
else
|
||||
{ //无效账号关闭连接
|
||||
client.SendAsync("Invalid Account");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{//错误
|
||||
Console.WriteLine("Tcp:" + ex.ToString());
|
||||
client.SendAsync("Target instruction parsing error manager will close connection");
|
||||
}
|
||||
finally
|
||||
{//继续心跳定时
|
||||
timer.Change(TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(30));
|
||||
}
|
||||
|
||||
return EasyTask.CompletedTask;
|
||||
};
|
||||
#endregion
|
||||
|
||||
// while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
await tcpClient.SetupAsync(new TouchSocketConfig()
|
||||
.SetSingleStreamDataHandlingAdapter(() => new PeriodPackageAdapter())//以超时周期和包
|
||||
.SetRemoteIPHost(ip)
|
||||
.ConfigurePlugins(a =>
|
||||
{
|
||||
a.UseReconnection<TouchSocket.Sockets.TcpClient>(options =>
|
||||
{
|
||||
options.PollingInterval = TimeSpan.FromSeconds(5);
|
||||
});
|
||||
|
||||
})
|
||||
.ConfigureContainer(a =>
|
||||
{
|
||||
|
||||
}));
|
||||
|
||||
await tcpClient.ConnectAsync();//调用连接,当连接不成功时,会抛出异常。
|
||||
// break;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// tcpClient.Dispose();//清
|
||||
LogGing.ERRDATA(ex);
|
||||
Console.WriteLine("Tcp:" + ex.ToString());
|
||||
// await Task.Delay(TimeSpan.FromMinutes(1));
|
||||
// Console.WriteLine("Tcp:重试连接...");
|
||||
}
|
||||
}
|
||||
}
|
||||
private static void TimerCallback(object? state)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (tcpClient.Online)
|
||||
{
|
||||
tcpClient.SendAsync("SUNLIGHT");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.ToString());
|
||||
LogGing.ERRDATA(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static async void CommandC(string dat, Person person)//
|
||||
{
|
||||
try
|
||||
{
|
||||
string Command = "", ret = "";
|
||||
|
||||
Dictionary<string, object> data_ = new Dictionary<string, object>();
|
||||
var deserialized = JsonSerializer.Deserialize<Dictionary<string, object>>(dat)!;
|
||||
if (deserialized.TryGetValue("Command", out var val) && val != null) Command = val.ToString()!;
|
||||
if (Command == "SysCom")//回复指令的信息
|
||||
{
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
else if (Command == "Log")//回复请求的信息
|
||||
{
|
||||
DataRow? _user = MainWindowViewModel.Selet_Row(MainWindowViewModel._userData, "User='" +
|
||||
person?.User + "'");
|
||||
|
||||
data_.Add("Enterprise", MainWindowViewModel.Enterprise);
|
||||
data_.Add("Department", _user?.Field<object>("Department") ?? "");
|
||||
data_.Add("Groups", _user?.Field<object>("Groups") ?? "");
|
||||
data_.Add("UserId", _user?.Field<object>("UserID") ?? "");
|
||||
data_.Add("UserName", _user?.Field<object>("Name") ?? "");
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
else if (Command == "SysData")//特殊指令数据库查询
|
||||
{
|
||||
string com_ = deserialized.GetValue("Comm").ToString()!;
|
||||
string da_ = deserialized.GetValue("Data").ToString()!;
|
||||
if (com_ == "SYSDB")//本机sqlite数据库
|
||||
{
|
||||
DataTable resultTable = MainWindowViewModel.SQLiteHelpers.ExecuteDataSet(da_, null)?.Tables[0] ?? new DataTable();
|
||||
data_.Add("DB", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
data_.Add("Comm", "SYSDB");
|
||||
data_.Add("Enterprise", MainWindowViewModel.Enterprise);
|
||||
}
|
||||
else if (com_ == "DBCDB")//系统dbc数据库
|
||||
{
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync(da_);
|
||||
data_.Add("DB", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
data_.Add("Comm", "DBCDB");
|
||||
data_.Add("Enterprise", MainWindowViewModel.Enterprise);
|
||||
}
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
else if (Command == "ChemicalStatistics")//回复请求的信息
|
||||
{
|
||||
data_.Add("ChemicalStatistics", Newtonsoft.Json.JsonConvert.SerializeObject(MainWindowViewModel.ChemicalStatistics));
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
else if (Command == "Info")//回复info请求的信息
|
||||
{
|
||||
var t = ToList(MainWindowViewModel._machines).ToJsonString();
|
||||
//格式化返回信息
|
||||
data_.Add("Info", t);
|
||||
data_.Add("DyeMeasurementNumber", MainWindowViewModel.DyeMeasurementNumber.ToString());
|
||||
data_.Add("ChemicalNumber", MainWindowViewModel.ChemicalNumber.ToString());
|
||||
data_.Add("PowderNumber", MainWindowViewModel.PowderNumber.ToString());
|
||||
data_.Add("DyeDissolveNumber", MainWindowViewModel.DyeDissolveNumber.ToString());
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
else if (Command == "Query")//回复Query请求的信息
|
||||
{
|
||||
string s_ = deserialized.GetValue("StartTime").ToString()!;
|
||||
string e_ = deserialized.GetValue("EndTime").ToString()!;
|
||||
string f_ = deserialized.GetValue("Field").ToString()!;
|
||||
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[Dyelots] " + "WHERE CreationTime>'" + s_ + "'and CreationTime<'" + e_ + "'");
|
||||
//格式化返回信息
|
||||
data_.Add("Query", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
else if (Command == "QueryDyelot")//回复QueryDyelot请求的信息
|
||||
{
|
||||
string d_ = deserialized.GetValue("DyelotName").ToString()!;
|
||||
string f_ = deserialized.GetValue("Field").ToString()!;
|
||||
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[Dyelots] " + "WHERE Dyelot LIKE '" + d_ + "%'");
|
||||
//格式化返回信息
|
||||
data_.Add("Query", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
else if (Command == "QueryDetail")//回复QueryDetail请求的信息
|
||||
{
|
||||
string d_ = deserialized.GetValue("Dyelot").ToString()!;
|
||||
string r_ = deserialized.GetValue("ReDye").ToString()!;
|
||||
string f_ = deserialized.GetValue("Field").ToString()!;
|
||||
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[DyelotsBulkedRecipe] " + "WHERE Dyelot='" + d_ + "'and ReDye='" + r_ + "'");
|
||||
//格式化返回信息
|
||||
data_.Add("QueryDetail", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
else if (Command == "Notification")//回复Notification请求的信息
|
||||
{
|
||||
string s_; try { s_ = deserialized.GetValue("StartTime").ToString()!; } catch(Exception) { s_ = "0"; }
|
||||
string e_ = deserialized.GetValue("EndTime").ToString()!;
|
||||
|
||||
var groups = MainWindowViewModel.Selet_Memory(MainWindowViewModel._userData,
|
||||
"Groups", "User='" + person?.User + "'");
|
||||
var department = MainWindowViewModel.Selet_Memory(MainWindowViewModel._userData,
|
||||
"Department", "User='" + person?.User + "'");
|
||||
|
||||
DataTable resultTable = MainWindowViewModel.SQLiteHelpers.ExecuteDataSet("" +
|
||||
"select * from Notification WHERE Groups='" + groups + "'and Department='" +
|
||||
department + "' and Id>'" + s_ + "'", null)?.Tables[0] ?? new DataTable();
|
||||
if(resultTable.Rows.Count==0) resultTable.Rows.Add();
|
||||
|
||||
//格式化返回信息
|
||||
data_.Add("Notification", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
else if (Command == "InfoMachine")//回复InfoMachine请求的信息
|
||||
{
|
||||
string t_ = deserialized.GetValue("Type").ToString()!;
|
||||
string? m_ =null, f_ = "*";
|
||||
|
||||
if (deserialized.TryGetValue("MachinName", out var MachinName) && MachinName != null) m_ = MachinName.ToString();
|
||||
if (deserialized.TryGetValue("Field", out var Field) && Field != null) f_ = Field.ToString();
|
||||
|
||||
if (t_ == "10")
|
||||
{
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[WaitDispenseDyestuff] WHERE DispenseMachine='" + m_ + "'");
|
||||
data_.Add("Type", "10");
|
||||
data_.Add("InfoMachine", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
}
|
||||
else if (t_ == "12")
|
||||
{
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[ShelfInfo] ");
|
||||
data_.Add("Type", "12");
|
||||
data_.Add("InfoMachine", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
}
|
||||
else if (t_ == "20")
|
||||
{
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[WaitChemical] WHERE DispenseMachine='" + m_ + "'");
|
||||
data_.Add("Type", "20");
|
||||
data_.Add("InfoMachine", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
}
|
||||
else
|
||||
{
|
||||
data_.Add("InfoMachine", "");
|
||||
}
|
||||
|
||||
//格式化返回信息
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
else if (Command == "InfoMachineHistory")//回复InfoMachineHistory请求的信息
|
||||
{
|
||||
string t_ = deserialized.GetValue("Type").ToString()!;
|
||||
string? m_ = null, f_ = "*";
|
||||
|
||||
if (deserialized.TryGetValue("MachinName", out var MachinName) && MachinName != null) m_ = MachinName.ToString();
|
||||
if (deserialized.TryGetValue("Field", out var Field) && Field != null) f_ = Field.ToString();
|
||||
|
||||
if (t_ == "80")
|
||||
{
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[DyeSolutionHistory] WHERE DispenseStartTime >'" + DateTime.Now.AddDays(-3)+
|
||||
"' and DispenseMachine='" + m_ + "'");
|
||||
data_.Add("Type", "80");
|
||||
data_.Add("InfoMachineHistory", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
}
|
||||
else if (t_ == "82")
|
||||
{
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[inOutRecords] WHERE Createtime >'" + DateTime.Now.AddDays(-3)+"'");
|
||||
data_.Add("Type", "82");
|
||||
data_.Add("InfoMachineHistory", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
}
|
||||
else if (t_ == "90")
|
||||
{
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[DyeSolutionHistory] WHERE DispenseStartTime >'" + DateTime.Now.AddDays(-3) +
|
||||
"' and DispenseMachine='" + m_ + "'");
|
||||
data_.Add("Type", "90");
|
||||
data_.Add("InfoMachineHistory", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
}
|
||||
else
|
||||
{
|
||||
data_.Add("InfoMachineHistory", "");
|
||||
}
|
||||
|
||||
//格式化返回信息
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
else if (Command == "InfoMachinePipes")//回复Notification请求的信息
|
||||
{
|
||||
string? m_ = null, f_ = "*";
|
||||
|
||||
if (deserialized.TryGetValue("MachinName", out var MachinName) && MachinName != null) m_ = MachinName.ToString();
|
||||
if (deserialized.TryGetValue("Field", out var Field) && Field != null) f_ = Field.ToString();
|
||||
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[Pipes] WHERE Dispenser='" + m_ + "'");
|
||||
data_.Add("InfoMachinePipes", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
|
||||
//格式化返回信息
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
else if (Command == "SETUSER")//回复请求的信息
|
||||
{
|
||||
MainWindowViewModel.Updata_Memory(MainWindowViewModel._userData,
|
||||
"User='" + deserialized.GetValue("USER").ToString()! + "'" ,
|
||||
deserialized.GetValue("VALUE").ToString(), deserialized.GetValue("KEY").ToString()!);
|
||||
data_.Add("USER", deserialized.GetValue("USER").ToString()!);
|
||||
data_.Add("VALUE", deserialized.GetValue("VALUE").ToString()!);
|
||||
data_.Add("KEY", deserialized.GetValue("KEY").ToString()!);
|
||||
data_.Add("SETUSER", "OK");
|
||||
//格式化返回信息
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
//加密回传
|
||||
/*Console.WriteLine("[Log on]User[" + person?.User + "]REPLY[" +
|
||||
Regex.Replace(ret, @"\\u[0-9A-Fa-f]{4}", match =>
|
||||
{ return Regex.Unescape(match.Value); }) + "]");*/
|
||||
|
||||
person!.Dat =AES.AesEncipher( person.Terminal, ret);
|
||||
var jsdat = JsonSerializer.Serialize(person);
|
||||
await tcpClient.SendAsync(jsdat);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogGing.ERRDATA(ex);
|
||||
Console.WriteLine(ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+260
-62
@@ -1,11 +1,17 @@
|
||||
using System;
|
||||
using SunlightAggregationManager.ViewModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Data;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Cryptography.Pkcs;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Windows;
|
||||
using System.Windows.Markup;
|
||||
using System.Xml.Linq;
|
||||
using TouchSocket.Core;
|
||||
using TouchSocket.Sockets;
|
||||
using SunlightAggregationManager.ViewModel;
|
||||
using System.Security.Cryptography.Pkcs;
|
||||
using static SunlightAggregationManager.UserClass.AsyncTcpServer;
|
||||
|
||||
namespace SunlightAggregationManager.UserClass
|
||||
{
|
||||
@@ -15,10 +21,18 @@ namespace SunlightAggregationManager.UserClass
|
||||
{
|
||||
public required string User { get; set; }
|
||||
public required string Password { get; set; }
|
||||
public required string IP { get; set; }
|
||||
public required string Terminal { get; set; }
|
||||
public required string Dat { get; set; }
|
||||
}
|
||||
|
||||
public static async void Configuration(int P1, int P2)
|
||||
{
|
||||
await TcpMain(P1, P2);
|
||||
}
|
||||
|
||||
public static TcpService service = new TcpService();
|
||||
|
||||
public static async Task TcpMain(int port1 ,int port2)
|
||||
{
|
||||
NetFwManger.AllowPort(port1, "TCP");//开放7790端口
|
||||
@@ -26,7 +40,9 @@ namespace SunlightAggregationManager.UserClass
|
||||
//TcpService service = new TcpService();
|
||||
service.Connecting = (client, e) => { return EasyTask.CompletedTask; };//有客户端正在连接
|
||||
service.Connected = (client, e) => {return EasyTask.CompletedTask;};//有客户端成功连接
|
||||
service.Closing = (client, e) => { return EasyTask.CompletedTask; };//有客户端正在断开连接,只有当主动断开时才有效。
|
||||
service.Closing = (client, e) => {
|
||||
Console.WriteLine("[Disconnecting]IP[" + client.IP + "]ID[" + client.Id + "]");
|
||||
return EasyTask.CompletedTask; };//有客户端正在断开连接,只有当主动断开时才有效。
|
||||
service.Closed = (client, e) => {
|
||||
//离线记录
|
||||
Dictionary<string, object> myDictOff = new Dictionary<string, object>();
|
||||
@@ -44,8 +60,8 @@ namespace SunlightAggregationManager.UserClass
|
||||
{
|
||||
Person? deserializedPerson = JsonSerializer.Deserialize<Person>(DAT);
|
||||
|
||||
var _user = MainWindowViewModel.Selet_Memory(MainWindowViewModel._userData, "State", "User='" + deserializedPerson?.User +
|
||||
"' and Password ='" + deserializedPerson?.Password + "'");
|
||||
var _user = MainWindowViewModel.Selet_Memory(MainWindowViewModel._userData, "State", "User='" +
|
||||
deserializedPerson?.User + "' and Password ='" + deserializedPerson?.Password + "'");
|
||||
if (_user != null)
|
||||
{
|
||||
string _dat = _user?.ToString() ?? "0";
|
||||
@@ -55,27 +71,42 @@ namespace SunlightAggregationManager.UserClass
|
||||
{//行为
|
||||
Dictionary<string, object> myDict = new Dictionary<string, object>();
|
||||
myDict.Add("LinkID", client.Id);
|
||||
myDict.Add("LastLoginIP", client.IP);
|
||||
myDict.Add("LastLoginIP", deserializedPerson?.IP ?? client.IP);
|
||||
myDict.Add("LastActionTime", DateTime.Now);
|
||||
myDict.Add("Note", deserializedPerson?.Dat ?? "unknown");
|
||||
MainWindowViewModel.Updata_Memory(MainWindowViewModel._userData, "User='" + deserializedPerson?.User + "'", myDict);
|
||||
|
||||
Console.WriteLine("[Log on]User[" + deserializedPerson?.User + "]Note[" + (deserializedPerson?.Dat ?? "unknown") + "]");
|
||||
Command(deserializedPerson?.Dat ?? "NOT", client.Id, deserializedPerson!);
|
||||
}
|
||||
else
|
||||
{//首次登录记录
|
||||
Dictionary<string, object> myDict = new Dictionary<string, object>();
|
||||
myDict.Add("State", 20);
|
||||
myDict.Add("LinkID", client.Id);
|
||||
myDict.Add("LastLoginIP", client.IP);
|
||||
myDict.Add("LastLoginIP", deserializedPerson?.IP ?? client.IP);
|
||||
myDict.Add("LastLoginTime", DateTime.Now);
|
||||
myDict.Add("LastLoginTerminal", deserializedPerson?.Terminal ?? "unknown device");
|
||||
myDict.Add("LastActionTime", DateTime.Now);
|
||||
myDict.Add("Note", deserializedPerson?.Dat ?? "unknown");
|
||||
MainWindowViewModel.Updata_Memory(MainWindowViewModel._userData, "User='" + deserializedPerson?.User + "'", myDict);
|
||||
|
||||
Console.WriteLine("[Log on]User[" + deserializedPerson?.User + "]IP[" + client.IP +
|
||||
Console.WriteLine("[Log on]User[" + deserializedPerson?.User + "]IP[" + deserializedPerson?.IP ?? client.IP +
|
||||
"]ID[" + client.Id + "]Terminal[" + (deserializedPerson?.Terminal ?? "unknown device") + "]");
|
||||
|
||||
//返回登录信息
|
||||
Dictionary<string, object> login = new Dictionary<string, object>();
|
||||
DataRow? dat = MainWindowViewModel.Selet_Row(MainWindowViewModel._userData,"User='" +
|
||||
deserializedPerson?.User + "' and Password ='" + deserializedPerson?.Password + "'");
|
||||
login.Add("Enterprise", dat?.Field<object>("Enterprise")??"");
|
||||
login.Add("Department", dat?.Field<object>("Department") ?? "");
|
||||
login.Add("Groups", dat?.Field<object>("Groups") ?? "");
|
||||
login.Add("UserId", dat?.Field<object>("UserID") ?? "");
|
||||
login.Add("UserName", dat?.Field<object>("Name") ?? "");
|
||||
|
||||
deserializedPerson!.Dat = JsonSerializer.Serialize(login);
|
||||
var jsdat = JsonSerializer.Serialize(deserializedPerson);
|
||||
client.SendAsync(jsdat);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -109,6 +140,7 @@ namespace SunlightAggregationManager.UserClass
|
||||
}
|
||||
catch (Exception ex)
|
||||
{//错误
|
||||
LogGing.ERRDATA(ex);
|
||||
Console.WriteLine("Tcp:" + ex.ToString());
|
||||
client.SendAsync("Target instruction parsing error manager will close connection");
|
||||
foreach (var item in AsyncTcpServer.service.Clients)
|
||||
@@ -121,18 +153,12 @@ namespace SunlightAggregationManager.UserClass
|
||||
}
|
||||
}
|
||||
|
||||
//string DAT = e.ByteBlock.Span.ToString(Encoding.UTF8).Substring(5);
|
||||
//string SYSDAT = "";// = e.ByteBlock.Span.ToString(Encoding.ASCII).Substring(5);
|
||||
// string SYSKEY = "";
|
||||
// if (DAT.Length >= 16) SYSKEY = DAT.Substring(0, 16);
|
||||
// if (DAT.Length > 16) SYSDAT = DAT.Substring(16);
|
||||
|
||||
|
||||
return EasyTask.CompletedTask;
|
||||
};
|
||||
|
||||
|
||||
await service.SetupAsync(new TouchSocketConfig()//载入配置
|
||||
// .SetMaxBufferSize(1024 * 1024 * 100)
|
||||
// .SetMaxBufferSize(1024 * 1024 * 100)
|
||||
//.SetMinBufferSize(1024 * 1024)
|
||||
.SetListenIPHosts(new IPHost[] { new IPHost(port1), new IPHost(port2) })//同时监听两个地址
|
||||
.ConfigureContainer(a =>//容器的配置顺序应该在最前面
|
||||
@@ -142,67 +168,239 @@ namespace SunlightAggregationManager.UserClass
|
||||
{
|
||||
})
|
||||
);
|
||||
|
||||
await service.StartAsync();//启动
|
||||
|
||||
Console.WriteLine("TCP Port:"+ port1.ToString());
|
||||
Console.WriteLine("TCP Port:"+ port2.ToString());
|
||||
Console.WriteLine("TCP SERVER:START");
|
||||
}
|
||||
}
|
||||
|
||||
class MyTcpService : TcpService<MyTcpSessionClient>
|
||||
{
|
||||
protected override MyTcpSessionClient NewClient()
|
||||
public static async void Command(string dat, string id, Person person)//
|
||||
{
|
||||
return new MyTcpSessionClient();
|
||||
}
|
||||
}
|
||||
|
||||
class MyTcpSessionClient : TcpSessionClient
|
||||
{
|
||||
internal void SetDataHandlingAdapter(SingleStreamDataHandlingAdapter adapter)
|
||||
{
|
||||
base.SetAdapter(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 此插件实现,按照不同端口,使用不同适配器。
|
||||
/// <list type="bullet">
|
||||
/// <item>7789端口:使用"**"结尾的数据</item>
|
||||
/// <item>7790端口:使用"##"结尾的数据</item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
internal class DifferentProtocolPlugin : PluginBase, ITcpConnectingPlugin, ITcpReceivedPlugin
|
||||
{
|
||||
public async Task OnTcpConnecting(ITcpSession client, ConnectingEventArgs e)
|
||||
{
|
||||
if (client is MyTcpSessionClient sessionClient)
|
||||
try
|
||||
{
|
||||
if (sessionClient.ServicePort == 7789)
|
||||
string Command = "", ret = "";
|
||||
|
||||
Dictionary<string, object> data_ = new Dictionary<string, object>();
|
||||
var deserialized = JsonSerializer.Deserialize<Dictionary<string, object>>(dat)!;
|
||||
if (deserialized.TryGetValue("Command", out var val) && val != null) Command = val.ToString()!;
|
||||
if (Command == "Log")//回复请求的信息
|
||||
{
|
||||
sessionClient.SetDataHandlingAdapter(new TerminatorPackageAdapter("**"));
|
||||
DataRow? _user = MainWindowViewModel.Selet_Row(MainWindowViewModel._userData, "User='" +
|
||||
person?.User + "' and Password ='" + person?.Password + "'");
|
||||
|
||||
data_.Add("Enterprise", _user?.Field<object>("Enterprise") ?? "");
|
||||
data_.Add("Department", _user?.Field<object>("Department") ?? "");
|
||||
data_.Add("Groups", _user?.Field<object>("Groups") ?? "");
|
||||
data_.Add("UserId", _user?.Field<object>("UserID") ?? "");
|
||||
data_.Add("UserName", _user?.Field<object>("Name") ?? "");
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
else
|
||||
if (Command == "SysData")//回复请求的信息
|
||||
{
|
||||
sessionClient.SetDataHandlingAdapter(new TerminatorPackageAdapter("##"));
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "ChemicalStatistics")//回复请求的信息
|
||||
{
|
||||
data_.Add("ChemicalStatistics", Newtonsoft.Json.JsonConvert.SerializeObject(MainWindowViewModel.ChemicalStatistics));
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "Info")//回复info请求的信息
|
||||
{
|
||||
var t = ToList(MainWindowViewModel._machines).ToJsonString();
|
||||
//格式化返回信息
|
||||
data_.Add("Info", t);
|
||||
data_.Add("DyeMeasurementNumber", MainWindowViewModel.DyeMeasurementNumber.ToString());
|
||||
data_.Add("ChemicalNumber", MainWindowViewModel.ChemicalNumber.ToString());
|
||||
data_.Add("PowderNumber", MainWindowViewModel.PowderNumber.ToString());
|
||||
data_.Add("DyeDissolveNumber", MainWindowViewModel.DyeDissolveNumber.ToString());
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "Query")//回复Query请求的信息
|
||||
{
|
||||
string s_ = deserialized.GetValue("StartTime").ToString()!;
|
||||
string e_ = deserialized.GetValue("EndTime").ToString()!;
|
||||
string f_ = deserialized.GetValue("Field").ToString()!;
|
||||
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[Dyelots] " + "WHERE CreationTime>'" + s_ + "'and CreationTime<'" + e_ + "'");
|
||||
//格式化返回信息
|
||||
data_.Add("Query", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "QueryDyelot")//回复QueryDyelot请求的信息
|
||||
{
|
||||
string d_ = deserialized.GetValue("DyelotName").ToString()!;
|
||||
string f_ = deserialized.GetValue("Field").ToString()!;
|
||||
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[Dyelots] " + "WHERE Dyelot LIKE '" + d_ + "%'");
|
||||
//格式化返回信息
|
||||
data_.Add("Query", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "QueryDetail")//回复QueryDetail请求的信息
|
||||
{
|
||||
string d_ = deserialized.GetValue("Dyelot").ToString()!;
|
||||
string r_ = deserialized.GetValue("ReDye").ToString()!;
|
||||
string f_ = deserialized.GetValue("Field").ToString()!;
|
||||
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[DyelotsBulkedRecipe] " + "WHERE Dyelot='" + d_ + "'and ReDye='" + r_ + "'");
|
||||
//格式化返回信息
|
||||
data_.Add("QueryDetail", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "Notification")//回复Notification请求的信息
|
||||
{
|
||||
string s_ = deserialized.GetValue("StartTime").ToString()!;
|
||||
string e_ = deserialized.GetValue("EndTime").ToString()!;
|
||||
|
||||
var groups = MainWindowViewModel.Selet_Memory(MainWindowViewModel._userData,
|
||||
"Groups", "User='" + person?.User + "'");
|
||||
|
||||
DataTable resultTable = MainWindowViewModel.SQLiteHelpers.ExecuteDataSet("" +
|
||||
"select * from Notification WHERE Groups='" + groups + "' and Id>'" +
|
||||
s_ + "'", null)?.Tables[0] ?? new DataTable();
|
||||
if (resultTable.Rows.Count == 0) resultTable.Rows.Add();
|
||||
|
||||
//格式化返回信息
|
||||
data_.Add("Notification", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "InfoMachine")//回复InfoMachine请求的信息
|
||||
{
|
||||
string t_ = deserialized.GetValue("Type").ToString()!;
|
||||
string? m_ = null, f_ = "*";
|
||||
|
||||
if (deserialized.TryGetValue("MachinName", out var MachinName) && MachinName != null) m_ = MachinName.ToString();
|
||||
if (deserialized.TryGetValue("Field", out var Field) && Field != null) f_ = Field.ToString();
|
||||
|
||||
if (t_ == "10")
|
||||
{
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[WaitDispenseDyestuff] WHERE DispenseMachine='" + m_ + "'");
|
||||
data_.Add("Type", "10");
|
||||
data_.Add("InfoMachine", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
}
|
||||
else if (t_ == "12")
|
||||
{
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[ShelfInfo] ");
|
||||
data_.Add("Type", "12");
|
||||
data_.Add("InfoMachine", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
}
|
||||
else if (t_ == "20")
|
||||
{
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[WaitChemical] WHERE DispenseMachine='" + m_ + "'");
|
||||
data_.Add("Type", "20");
|
||||
data_.Add("InfoMachine", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
}
|
||||
else
|
||||
{
|
||||
data_.Add("InfoMachine", "");
|
||||
}
|
||||
|
||||
//格式化返回信息
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "InfoMachineHistory")//回复InfoMachineHistory请求的信息
|
||||
{
|
||||
string t_ = deserialized.GetValue("Type").ToString()!;
|
||||
string? m_ = null, f_ = "*";
|
||||
|
||||
if (deserialized.TryGetValue("MachinName", out var MachinName) && MachinName != null) m_ = MachinName.ToString();
|
||||
if (deserialized.TryGetValue("Field", out var Field) && Field != null) f_ = Field.ToString();
|
||||
|
||||
if (t_ == "80")
|
||||
{
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[DyeSolutionHistory] WHERE DispenseStartTime >'" + DateTime.Now.AddDays(-3) +
|
||||
"' and DispenseMachine='" + m_ + "'");
|
||||
data_.Add("Type", "80");
|
||||
data_.Add("InfoMachineHistory", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
}
|
||||
else if (t_ == "82")
|
||||
{
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[inOutRecords] WHERE Createtime >'" + DateTime.Now.AddDays(-3) + "'");
|
||||
data_.Add("Type", "82");
|
||||
data_.Add("InfoMachineHistory", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
}
|
||||
else if (t_ == "90")
|
||||
{
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[DyeSolutionHistory] WHERE DispenseStartTime >'" + DateTime.Now.AddDays(-3) +
|
||||
"' and DispenseMachine='" + m_ + "'");
|
||||
data_.Add("Type", "90");
|
||||
data_.Add("InfoMachineHistory", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
}
|
||||
else
|
||||
{
|
||||
data_.Add("InfoMachineHistory", "");
|
||||
}
|
||||
|
||||
//格式化返回信息
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "InfoMachinePipes")//回复Notification请求的信息
|
||||
{
|
||||
string? m_ = null, f_ = "*";
|
||||
|
||||
if (deserialized.TryGetValue("MachinName", out var MachinName) && MachinName != null) m_ = MachinName.ToString();
|
||||
if (deserialized.TryGetValue("Field", out var Field) && Field != null) f_ = Field.ToString();
|
||||
|
||||
DataTable resultTable = await MainWindowViewModel.dataBase.ExecuteQueryAsync("SELECT " +
|
||||
f_ + " FROM [dbo].[Pipes] WHERE Dispenser='" + m_ + "'");
|
||||
data_.Add("InfoMachinePipes", Newtonsoft.Json.JsonConvert.SerializeObject(resultTable));
|
||||
|
||||
//格式化返回信息
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
if (Command == "SETUSER")//回复Notification请求的信息
|
||||
{
|
||||
MainWindowViewModel.Updata_Memory(MainWindowViewModel._userData,
|
||||
"User='" + deserialized.GetValue("USER").ToString()! + "'",
|
||||
deserialized.GetValue("VALUE").ToString(), deserialized.GetValue("KEY").ToString()!);
|
||||
data_.Add("USER", deserialized.GetValue("USER").ToString()!);
|
||||
data_.Add("VALUE", deserialized.GetValue("VALUE").ToString()!);
|
||||
data_.Add("KEY", deserialized.GetValue("KEY").ToString()!);
|
||||
data_.Add("SETUSER", "OK");
|
||||
//格式化返回信息
|
||||
ret = JsonSerializer.Serialize(data_);
|
||||
}
|
||||
|
||||
person!.Dat = ret.ToString();
|
||||
var jsdat = JsonSerializer.Serialize(person);
|
||||
await service.SendAsync(id, jsdat);
|
||||
}
|
||||
|
||||
await e.InvokeNext();
|
||||
}
|
||||
|
||||
public async Task OnTcpReceived(ITcpSession client, ReceivedDataEventArgs e)
|
||||
{
|
||||
//如果是自定义适配器,此处解析时,可以判断e.RequestInfo的类型
|
||||
|
||||
if (client is ITcpSessionClient sessionClient)
|
||||
catch (Exception ex)
|
||||
{
|
||||
sessionClient.Logger.Info($"{sessionClient.GetIPPort()}收到数据,服务器端口:{sessionClient.ServicePort},数据:{e.Memory.Span.ToString(Encoding.UTF8)}");
|
||||
LogGing.ERRDATA(ex);
|
||||
Console.WriteLine(ex.ToString());
|
||||
}
|
||||
|
||||
await e.InvokeNext();
|
||||
}
|
||||
|
||||
public static List<Dictionary<string, object?>>? ToList(DataTable table)//datatable转list
|
||||
{
|
||||
if (table == null) return null;
|
||||
|
||||
// 使用 AsEnumerable() 将 DataTable 转换为 IEnumerable<DataRow>
|
||||
// 然后投影为 Dictionary
|
||||
return table.AsEnumerable().Select(row =>
|
||||
table.Columns.Cast<DataColumn>().ToDictionary(
|
||||
col => col.ColumnName,
|
||||
col => {
|
||||
var value = row[col];
|
||||
// 核心修改:如果是数据库空值 DBNull.Value,则转为 C# 的 null,否则保持原值
|
||||
return value == DBNull.Value ? null : value;
|
||||
}
|
||||
)
|
||||
).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+95
-4
@@ -2,6 +2,7 @@
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Text;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
@@ -17,8 +18,7 @@ namespace SunlightAggregationManager.UserClass
|
||||
private string DB_IP = null!;
|
||||
private string DB_PASSWORD = null!;
|
||||
|
||||
|
||||
public void Config(string ip, string name, string type, string id, string password)
|
||||
public async void Config(string ip, string name, string type, string id, string password)
|
||||
{
|
||||
DB_IP = ip;
|
||||
DB_ID = id;
|
||||
@@ -26,7 +26,7 @@ namespace SunlightAggregationManager.UserClass
|
||||
DB_TYPE = type;
|
||||
DB_PASSWORD = password;
|
||||
|
||||
_= ConfigAsync();
|
||||
await ConfigAsync();
|
||||
|
||||
}
|
||||
public async Task ConfigAsync()
|
||||
@@ -63,7 +63,8 @@ namespace SunlightAggregationManager.UserClass
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("DataBase Link timeout\n"+ex.ToString());
|
||||
LogGing.ERRDATA(ex);
|
||||
Console.WriteLine("DataBase Link timeout\n"+ ex.Message.ToString());
|
||||
// 失败处理
|
||||
return; // 直接返回,不执行后续代码
|
||||
}
|
||||
@@ -71,6 +72,96 @@ namespace SunlightAggregationManager.UserClass
|
||||
});
|
||||
}
|
||||
|
||||
public async Task<DataTable> ExecuteQueryAsync(string sql)
|
||||
{
|
||||
// 创建一个空的 DataTable 用于存放查询结果
|
||||
DataTable dataTable = new DataTable();
|
||||
|
||||
// 数据库连接字符串构建逻辑
|
||||
var builder = new SqlConnectionStringBuilder
|
||||
{
|
||||
DataSource = DB_IP,
|
||||
InitialCatalog = DB_NAME,
|
||||
IntegratedSecurity = DB_TYPE == "Windows Authentication",
|
||||
TrustServerCertificate = true,
|
||||
ConnectTimeout = 5
|
||||
};
|
||||
|
||||
if (!builder.IntegratedSecurity)
|
||||
{
|
||||
builder.UserID = DB_ID;
|
||||
builder.Password = DB_PASSWORD;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using var conn = new SqlConnection(builder.ConnectionString);
|
||||
await conn.OpenAsync(); // 使用异步方式打开连接<websource>source_group_web_2</websource>
|
||||
|
||||
using (var cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
// 执行查询并将结果直接加载到 DataTable 中
|
||||
using (var reader = await cmd.ExecuteReaderAsync())
|
||||
{
|
||||
dataTable.Load(reader);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogGing.ERRDATA(ex);
|
||||
Console.WriteLine("DataBase Query failed\n" + ex.Message.ToString());
|
||||
}
|
||||
|
||||
return dataTable;
|
||||
}
|
||||
|
||||
public async Task<int> ExecuteQueryAsyncCount(string sql)
|
||||
{
|
||||
// 创建一个空的 DataTable 用于存放查询结果
|
||||
DataTable dataTable = new DataTable();
|
||||
|
||||
// 数据库连接字符串构建逻辑
|
||||
var builder = new SqlConnectionStringBuilder
|
||||
{
|
||||
DataSource = DB_IP,
|
||||
InitialCatalog = DB_NAME,
|
||||
IntegratedSecurity = DB_TYPE == "Windows Authentication",
|
||||
TrustServerCertificate = true,
|
||||
ConnectTimeout = 5
|
||||
};
|
||||
|
||||
if (!builder.IntegratedSecurity)
|
||||
{
|
||||
builder.UserID = DB_ID;
|
||||
builder.Password = DB_PASSWORD;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using var conn = new SqlConnection(builder.ConnectionString);
|
||||
await conn.OpenAsync(); // 使用异步方式打开连接<websource>source_group_web_2</websource>
|
||||
|
||||
using (var cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
// 执行查询并将结果直接加载到 DataTable 中
|
||||
using (var reader = await cmd.ExecuteReaderAsync())
|
||||
{
|
||||
dataTable.Load(reader);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogGing.ERRDATA(ex);
|
||||
Console.WriteLine("DataBase Query failed\n" + ex.Message.ToString());
|
||||
}
|
||||
|
||||
return dataTable.Rows.Count;
|
||||
}
|
||||
|
||||
public void Database(string dat)
|
||||
{
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace SunlightAggregationManager.UserClass
|
||||
{
|
||||
public class GetLocalIP
|
||||
{
|
||||
public static string GetLocalIPv4Address()
|
||||
{
|
||||
// 获取所有网络接口
|
||||
var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
|
||||
|
||||
foreach (var ni in networkInterfaces)
|
||||
{
|
||||
// 筛选条件:
|
||||
// 1. 网卡状态为 Up (已连接)
|
||||
// 2. 排除虚拟网卡、回环网卡、隧道网卡
|
||||
// 3. 支持 IPv4
|
||||
if (ni.OperationalStatus == OperationalStatus.Up &&
|
||||
ni.NetworkInterfaceType != NetworkInterfaceType.Loopback &&
|
||||
ni.NetworkInterfaceType != NetworkInterfaceType.Tunnel &&
|
||||
!ni.Description.Contains("Virtual") && // 排除常见的虚拟网卡描述
|
||||
ni.Supports(NetworkInterfaceComponent.IPv4))
|
||||
{
|
||||
var ipProperties = ni.GetIPProperties();
|
||||
// 获取单播地址(即分配的 IP 地址)
|
||||
var unicastAddresses = ipProperties.UnicastAddresses;
|
||||
|
||||
foreach (var ua in unicastAddresses)
|
||||
{
|
||||
// 筛选出 IPv4 地址,且排除 127.0.0.1 回环地址
|
||||
if (ua.Address.AddressFamily == AddressFamily.InterNetwork && !IPAddress.IsLoopback(ua.Address))
|
||||
{
|
||||
// 优先返回有默认网关的地址(通常是当前正在上网的主网卡)
|
||||
if (ipProperties.GatewayAddresses.Any(g => g.Address.AddressFamily == AddressFamily.InterNetwork))
|
||||
{
|
||||
return ua.Address.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "未找到有效的局域网IPv4地址";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
using SunlightAggregationManager.View;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
namespace SunlightAggregationManager.UserClass
|
||||
{
|
||||
public class LogGing
|
||||
{
|
||||
public class LOGinf
|
||||
{
|
||||
public required string Logpath { get; set; }
|
||||
public required string LogPath { get; set; }
|
||||
public required string Log_time { get; set; }
|
||||
public required object DAT { get; set; }
|
||||
}
|
||||
static Queue<LOGinf> LogGingQueue = new Queue<LOGinf>();
|
||||
static Queue<LOGinf> ERRQueue = new Queue<LOGinf>();
|
||||
static Queue<LOGinf> ExchangeQueue = new Queue<LOGinf>();
|
||||
public static void LogGingDATA(string dat)
|
||||
{
|
||||
LOGinf ginf = new LOGinf
|
||||
{
|
||||
Logpath = System.Environment.CurrentDirectory + "\\Log",//日志文件目录
|
||||
LogPath = "" + System.Environment.CurrentDirectory + "\\Log\\" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt",//日志文件
|
||||
Log_time = "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "]:",
|
||||
DAT = dat
|
||||
};
|
||||
LogGingQueue.Enqueue(ginf);
|
||||
|
||||
if(LogGingQueue.Count==1) LogGingQueueW();
|
||||
}
|
||||
public static async void LogGingQueueW()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
LOGinf inf = LogGingQueue.Dequeue();
|
||||
|
||||
if (Directory.Exists(inf.Logpath))//检查日志路径
|
||||
{
|
||||
if (!File.Exists(inf.LogPath))//检查日志文件并写入启动日志
|
||||
{
|
||||
FileStream fs = new FileStream(inf.LogPath, FileMode.CreateNew, FileAccess.Write);//创建写入文件
|
||||
StreamWriter wr = new StreamWriter(fs);//创建文件
|
||||
wr.WriteLine(inf.Log_time + inf.DAT);
|
||||
wr.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
FileStream fs = new FileStream(inf.LogPath, FileMode.Append, FileAccess.Write);
|
||||
StreamWriter wr = new StreamWriter(fs);//创建文件
|
||||
wr.WriteLine(inf.Log_time + inf.DAT);
|
||||
wr.Close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DirectoryInfo directoryInfo = new DirectoryInfo(inf.Logpath);
|
||||
directoryInfo.Create();//创建日志路径
|
||||
}
|
||||
}
|
||||
catch (Exception ) { }
|
||||
if (LogGingQueue.Count == 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ERRDATA(System.Exception dat)
|
||||
{
|
||||
LOGinf ginf = new LOGinf
|
||||
{
|
||||
Logpath = System.Environment.CurrentDirectory + "\\ERR",//日志文件目录
|
||||
LogPath = "" + System.Environment.CurrentDirectory + "\\ERR\\" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt",//日志文件
|
||||
Log_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
|
||||
DAT = dat
|
||||
};
|
||||
ERRQueue.Enqueue(ginf);
|
||||
|
||||
if (ERRQueue.Count == 1) ERRQueueW();
|
||||
}
|
||||
public static async void ERRQueueW()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
LOGinf inf = ERRQueue.Dequeue();
|
||||
Exception dat = (Exception)inf.DAT;
|
||||
|
||||
if (Directory.Exists(inf.Logpath))//检查日志路径
|
||||
{
|
||||
if (!File.Exists(inf.LogPath))//检查文件并写入
|
||||
{
|
||||
// FileStream fs = new FileStream(log_path, FileMode.CreateNew, FileAccess.Write);//创建文件
|
||||
// StreamWriter wr = new StreamWriter(fs);//创建文件
|
||||
// wr.Close();
|
||||
FileStream fil = new FileStream(inf.LogPath, FileMode.CreateNew, FileAccess.Write);//创建写入文件
|
||||
StreamWriter wfil = new StreamWriter(fil);//创建文件
|
||||
wfil.WriteLine("[" + inf.Log_time + "];[Error] ||" + Environment.NewLine.ToString());
|
||||
wfil.WriteLine("[" + inf.Log_time + "];[Error source] ||" + dat.Source.ToString() + Environment.NewLine.ToString());
|
||||
wfil.WriteLine("[" + inf.Log_time + "];[Error message] ||" + dat.Message.ToString() + Environment.NewLine.ToString());
|
||||
wfil.WriteLine("[" + inf.Log_time + "];[Error area] ||" + dat.StackTrace.ToString());
|
||||
wfil.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
FileStream fs = new FileStream(inf.LogPath, FileMode.Append, FileAccess.Write);//创建写入文件
|
||||
StreamWriter wr = new StreamWriter(fs);//创建文件
|
||||
wr.WriteLine("[" + inf.Log_time + "];[Error] ||" + Environment.NewLine.ToString());
|
||||
wr.WriteLine("[" + inf.Log_time + "];[Error source] ||" + dat.ToString() + Environment.NewLine.ToString());
|
||||
wr.WriteLine("[" + inf.Log_time + "];[Error message] ||" + dat.Message.ToString() + Environment.NewLine.ToString());
|
||||
wr.WriteLine("[" + inf.Log_time + "];[Error area] ||" + dat.ToString());
|
||||
wr.Close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DirectoryInfo directoryInfo = new DirectoryInfo(inf.Logpath);
|
||||
directoryInfo.Create();
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
if (ERRQueue.Count == 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ExchangeDATA(string dat)
|
||||
{
|
||||
string Log_time = DateTime.Now.ToString("yyyy-MM-dd");
|
||||
string logpath = System.Environment.CurrentDirectory + "\\Exchange";//日志文件目录
|
||||
// string logPathtxt = "" + System.Environment.CurrentDirectory + "\\Log\\"+ Log_time + "Log.txt";//日志文件
|
||||
// System.IO.DirectoryInfo log = new System.IO.DirectoryInfo();//生成日志文件目录
|
||||
string log_path = logpath + "\\Exchange" + Log_time + ".txt";
|
||||
string Log_timehms = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
if (Directory.Exists(logpath))//检查日志路径
|
||||
{
|
||||
if (!File.Exists(log_path))//检查文件并写入
|
||||
{
|
||||
// FileStream fs = new FileStream(log_path, FileMode.CreateNew, FileAccess.Write);//创建文件
|
||||
// StreamWriter wr = new StreamWriter(fs);//创建文件
|
||||
// wr.Close();
|
||||
FileStream fil = new FileStream(log_path, FileMode.CreateNew, FileAccess.Write);//创建写入文件
|
||||
StreamWriter wfil = new StreamWriter(fil);//创建文件
|
||||
wfil.WriteLine("[" + Log_timehms + "];[Exchange] ||" + dat);
|
||||
wfil.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
FileStream fs = new FileStream(log_path, FileMode.Append, FileAccess.Write);//创建写入文件
|
||||
StreamWriter wr = new StreamWriter(fs);//创建文件
|
||||
wr.WriteLine("[" + Log_timehms + "];[Exchange] ||" + dat);
|
||||
wr.Close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DirectoryInfo directoryInfo = new DirectoryInfo(logpath);
|
||||
directoryInfo.Create();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+55
-41
@@ -15,61 +15,75 @@ namespace SunlightAggregationManager.UserClass
|
||||
|
||||
public static void AllowPort(int port, string protocol)
|
||||
{
|
||||
|
||||
DelPort(port, protocol);
|
||||
//创建一个INetFwRule对象
|
||||
Type type = Type.GetTypeFromProgID("HNetCfg.FwRule") ?? throw new
|
||||
InvalidOperationException("Failed to retrieve HNetCfg.FwRule type. Ensure the COM component is registered.");
|
||||
INetFwRule? rule = (INetFwRule?)Activator.CreateInstance(type);
|
||||
|
||||
//设置规则的属性
|
||||
rule?.Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW; //允许连接
|
||||
rule?.Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN; //入站规则
|
||||
rule?.Enabled = true; //启用规则
|
||||
rule?.InterfaceTypes = "All"; //适用于所有网络接口
|
||||
rule?.Name = GetName(port, protocol); //规则名称
|
||||
if (protocol.ToLower() == "tcp")
|
||||
try
|
||||
{
|
||||
rule?.Protocol = (int)NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP; //TCP协议
|
||||
DelPort(port, protocol);
|
||||
//创建一个INetFwRule对象
|
||||
Type type = Type.GetTypeFromProgID("HNetCfg.FwRule") ?? throw new
|
||||
InvalidOperationException("Failed to retrieve HNetCfg.FwRule type. Ensure the COM component is registered.");
|
||||
INetFwRule? rule = (INetFwRule?)Activator.CreateInstance(type);
|
||||
|
||||
//设置规则的属性
|
||||
rule?.Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW; //允许连接
|
||||
rule?.Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN; //入站规则
|
||||
rule?.Enabled = true; //启用规则
|
||||
rule?.InterfaceTypes = "All"; //适用于所有网络接口
|
||||
rule?.Name = GetName(port, protocol); //规则名称
|
||||
if (protocol.ToLower() == "tcp")
|
||||
{
|
||||
rule?.Protocol = (int)NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP; //TCP协议
|
||||
}
|
||||
else
|
||||
{
|
||||
rule?.Protocol = (int)NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_UDP; //UDP协议
|
||||
}
|
||||
|
||||
rule?.LocalPorts = "" + port; //本地端口号
|
||||
|
||||
//获取FirewallPolicy对象
|
||||
Type policyType = Type.GetTypeFromProgID("HNetCfg.FwPolicy2") ?? throw new
|
||||
InvalidOperationException("Failed to retrieve HNetCfg.FwRule type. Ensure the COM component is registered.");
|
||||
INetFwPolicy2? policy = (INetFwPolicy2?)Activator.CreateInstance(policyType);
|
||||
|
||||
//将规则添加到防火墙策略中
|
||||
policy?.Rules.Add(rule);
|
||||
Console.WriteLine("Add firewall port:" + port);
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
rule?.Protocol = (int)NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_UDP; //UDP协议
|
||||
Console.WriteLine(ex.ToString());
|
||||
}
|
||||
|
||||
rule?.LocalPorts = "" + port; //本地端口号
|
||||
|
||||
//获取FirewallPolicy对象
|
||||
Type policyType = Type.GetTypeFromProgID("HNetCfg.FwPolicy2") ?? throw new
|
||||
InvalidOperationException("Failed to retrieve HNetCfg.FwRule type. Ensure the COM component is registered.");
|
||||
INetFwPolicy2? policy = (INetFwPolicy2?)Activator.CreateInstance(policyType);
|
||||
|
||||
//将规则添加到防火墙策略中
|
||||
policy?.Rules.Add(rule);
|
||||
}
|
||||
|
||||
public static void DelPort(int port, string protocol)
|
||||
{
|
||||
//获取FirewallPolicy对象
|
||||
Type policyType = Type.GetTypeFromProgID("HNetCfg.FwPolicy2") ?? throw new
|
||||
InvalidOperationException("Failed to retrieve HNetCfg.FwRule type. Ensure the COM component is registered.");
|
||||
INetFwPolicy2? policy = (INetFwPolicy2?)Activator.CreateInstance(policyType);
|
||||
|
||||
//获取现有的规则集合
|
||||
INetFwRules? rules = policy?.Rules;
|
||||
if (rules != null)
|
||||
try
|
||||
{
|
||||
//查找名称的规则并删除它
|
||||
foreach (INetFwRule rule in rules)
|
||||
//获取FirewallPolicy对象
|
||||
Type policyType = Type.GetTypeFromProgID("HNetCfg.FwPolicy2") ?? throw new
|
||||
InvalidOperationException("Failed to retrieve HNetCfg.FwRule type. Ensure the COM component is registered.");
|
||||
INetFwPolicy2? policy = (INetFwPolicy2?)Activator.CreateInstance(policyType);
|
||||
|
||||
//获取现有的规则集合
|
||||
INetFwRules? rules = policy?.Rules;
|
||||
if (rules != null)
|
||||
{
|
||||
if (rule.Name == GetName(port, protocol))
|
||||
//查找名称的规则并删除它
|
||||
foreach (INetFwRule rule in rules)
|
||||
{
|
||||
rules.Remove(rule.Name);
|
||||
Console.WriteLine(@"Firewall rule deleted successfully.");
|
||||
break;
|
||||
if (rule.Name == GetName(port, protocol))
|
||||
{
|
||||
rules.Remove(rule.Name);
|
||||
//Console.WriteLine(@"Firewall rule deleted successfully.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
-8
@@ -10,25 +10,32 @@ namespace SunlightAggregationManager.UserClass
|
||||
public class ControlWriter : TextWriter
|
||||
{
|
||||
private readonly TextBox _textbox;
|
||||
private readonly Action<string> _logGingDataAction;
|
||||
|
||||
public ControlWriter(TextBox textbox)
|
||||
public ControlWriter(TextBox textbox,Action<string> logGingDataAction)
|
||||
{
|
||||
_textbox = textbox;
|
||||
_logGingDataAction = logGingDataAction;
|
||||
}
|
||||
|
||||
public override void Write(char value) => AppendText(DateTime.Now + ": " + value.ToString());
|
||||
public override void Write(string? value) => AppendText(DateTime.Now + ": " + value);
|
||||
public override void WriteLine(string? value) => AppendText(DateTime.Now + ": "+value + Environment.NewLine);
|
||||
public override void Write(char value) => AppendText(DateTime.Now + ": " + value.ToString(), true);
|
||||
public override void Write(string? value) => AppendText(DateTime.Now + ": " + value, true);
|
||||
public override void WriteLine(string? value) => AppendText(DateTime.Now + ": "+value + Environment.NewLine, true);
|
||||
|
||||
private void AppendText(string text)
|
||||
private void AppendText(string text, bool invokeExternalLog)
|
||||
{
|
||||
if (!_textbox.Dispatcher.CheckAccess())
|
||||
{
|
||||
_textbox.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() => AppendText(text)));
|
||||
_textbox.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() => AppendText(text, true)));
|
||||
return;
|
||||
}
|
||||
_textbox.AppendText(text);
|
||||
_textbox.ScrollToEnd();
|
||||
|
||||
if (invokeExternalLog)
|
||||
{
|
||||
_logGingDataAction?.Invoke(text);
|
||||
}
|
||||
}
|
||||
|
||||
public override Encoding Encoding => Encoding.UTF8;
|
||||
@@ -41,10 +48,10 @@ namespace SunlightAggregationManager.UserClass
|
||||
|
||||
// 【核心功能】注册目标 TextBox
|
||||
// 子页面加载时调用这个方法
|
||||
public static void RegisterTarget(TextBox logBox)
|
||||
public static void RegisterTarget(TextBox logBox ,Action<string> logGingDataAction)
|
||||
{
|
||||
// 创建新的 Writer
|
||||
_currentWriter = new ControlWriter(logBox);
|
||||
_currentWriter = new ControlWriter(logBox, logGingDataAction);
|
||||
|
||||
// 【关键】将 Console 的输出重定向到这个 Writer
|
||||
// 这样 Console.WriteLine("...") 就会自动写入到 logBox 中
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
<Window x:Class="SunlightAggregationManager.UserWindow.MachineSet"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:SunlightAggregationManager.UserWindow"
|
||||
xmlns:ConvertMoels="clr-namespace:SunlightAggregationManager.ConvertMoels"
|
||||
xmlns:lang="clr-namespace:SunlightAggregationManager"
|
||||
xmlns:viewmodel="clr-namespace:SunlightAggregationManager.ViewModel"
|
||||
d:DataContext="{d:DesignInstance Type=viewmodel:MainWindowViewModel}"
|
||||
mc:Ignorable="d"
|
||||
Title="MachineSet"
|
||||
Loaded="Window_Loaded"
|
||||
ResizeMode="NoResize"
|
||||
Height="900" Width="1440" MinHeight="900" MinWidth="1440">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="5"/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="100"/>
|
||||
</Grid.RowDefinitions>
|
||||
<GridSplitter Grid.Row="1" Height="5" HorizontalAlignment="Stretch" Background="#FFCECECE"/>
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="500"/>
|
||||
<ColumnDefinition Width="5"/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Stretch" Background="#FFCECECE"/>
|
||||
<Grid Grid.Column="0">
|
||||
<!--用户-->
|
||||
<TextBox x:Name="_Name" Height="30" Margin="105,10,10,100" VerticalAlignment="Top" FontSize="16" MaxLines="1"/>
|
||||
<TextBlock HorizontalAlignment="Left" Height="30" Margin="15,10,0,100" TextWrapping="Wrap"
|
||||
Text="归属信息" VerticalAlignment="Top" Width="85" FontSize="20"/>
|
||||
<TextBox x:Name="_Machine" Height="30" Margin="105,55,10,100" VerticalAlignment="Top" FontSize="16" MaxLines="1"/>
|
||||
<TextBlock HorizontalAlignment="Left" Height="30" Margin="15,55,0,100" TextWrapping="Wrap"
|
||||
Text="设备名称" VerticalAlignment="Top" Width="85" FontSize="20"/>
|
||||
<ComboBox x:Name="GROUP" Height="30" Margin="105,100,10,100" VerticalAlignment="Top" FontSize="16" IsReadOnly="True">
|
||||
<ComboBoxItem Content="200"></ComboBoxItem>
|
||||
<ComboBoxItem Content="202"></ComboBoxItem>
|
||||
<ComboBoxItem Content="242W"></ComboBoxItem>
|
||||
<ComboBoxItem Content="252"></ComboBoxItem>
|
||||
<ComboBoxItem Content="252-2T"></ComboBoxItem>
|
||||
<ComboBoxItem Content="252RB"></ComboBoxItem>
|
||||
<ComboBoxItem Content="252RDRM"></ComboBoxItem>
|
||||
<ComboBoxItem Content="252-2T"></ComboBoxItem>
|
||||
<ComboBoxItem Content="301"></ComboBoxItem>
|
||||
<ComboBoxItem Content="301P"></ComboBoxItem>
|
||||
<ComboBoxItem Content="302"></ComboBoxItem>
|
||||
<ComboBoxItem Content="303"></ComboBoxItem>
|
||||
<ComboBoxItem Content="303PDW"></ComboBoxItem>
|
||||
</ComboBox>
|
||||
<TextBlock HorizontalAlignment="Left" Height="30" Margin="15,100,0,50" TextWrapping="Wrap"
|
||||
Text="系列型号" VerticalAlignment="Top" Width="80" FontSize="20"/>
|
||||
<TextBox x:Name="_IP" Height="30" Margin="105,145,10,100" VerticalAlignment="Top" FontSize="16" MaxLines="1"/>
|
||||
<TextBlock HorizontalAlignment="Left" Height="30" Margin="15,145,0,100" TextWrapping="Wrap"
|
||||
Text="连接IP" VerticalAlignment="Top" Width="85" FontSize="20"/>
|
||||
<TextBox x:Name="_MachineUser" Height="30" Margin="105,190,10,100" VerticalAlignment="Top" FontSize="16" MaxLines="1"/>
|
||||
<TextBlock HorizontalAlignment="Left" Height="30" Margin="15,190,0,100" TextWrapping="Wrap"
|
||||
Text="连接用户" VerticalAlignment="Top" Width="85" FontSize="20"/>
|
||||
<TextBox x:Name="_MachinePassword" Height="30" Margin="105,235,10,100" VerticalAlignment="Top" FontSize="16" MaxLines="1"/>
|
||||
<TextBlock HorizontalAlignment="Left" Height="30" Margin="15,235,0,100" TextWrapping="Wrap"
|
||||
Text="连接密码" VerticalAlignment="Top" Width="85" FontSize="20"/>
|
||||
<TextBox x:Name="_inf" Height="90" Margin="105,280,10,100" VerticalAlignment="Top" FontSize="16" MaxLines="1"/>
|
||||
|
||||
</Grid>
|
||||
<Grid Grid.Column="2" Margin="0">
|
||||
<ScrollViewer Margin="0" VerticalScrollBarVisibility="Auto">
|
||||
<WrapPanel Orientation="Horizontal" x:Name="Capacity" >
|
||||
</WrapPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<!--表-->
|
||||
<DataGrid Grid.Row="2" x:Name="DataGridm" MouseDoubleClick="DataGridm_MouseDoubleClick"
|
||||
SelectionMode="Single" AlternationCount="2" IsReadOnly="True"
|
||||
ItemsSource="{Binding Machines.DefaultView}"
|
||||
AutoGenerateColumns="False" MinColumnWidth="30"
|
||||
HorizontalGridLinesBrush="#FFC9C9C9" VerticalGridLinesBrush="#FFC9C9C9"
|
||||
GridLinesVisibility="All" BorderBrush="{x:Null}"
|
||||
BorderThickness="1,1,1,1" ColumnHeaderHeight="40"
|
||||
HorizontalContentAlignment="Right" Grid.ColumnSpan="2"
|
||||
CanUserResizeRows="False" CanUserAddRows="False"
|
||||
CanUserDeleteRows="False" CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False" CanUserSortColumns="False"
|
||||
HeadersVisibility ="Column" Background="{x:Null}">
|
||||
<DataGrid.RowStyle >
|
||||
<Style TargetType="{x:Type DataGridRow}">
|
||||
<Style.Triggers>
|
||||
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
|
||||
<Setter Property="Background" Value="#FFFFFFFF" />
|
||||
</Trigger>
|
||||
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
|
||||
<Setter Property="Background" Value="#FFF0F0F0" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="False">
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</DataGrid.RowStyle>
|
||||
<DataGrid.CellStyle>
|
||||
<Style TargetType="DataGridCell">
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="MinWidth" Value="20"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter Property="Background" Value="#FFC0C0C0"/>
|
||||
<Setter Property="BorderBrush" Value="#FFC0C0C0"/>
|
||||
<Setter Property="Foreground" Value="#000000"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</DataGrid.CellStyle>
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Width="0" FontSize="26" Binding="{Binding ID}" MaxWidth="0" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.information}" Width="200" FontSize="26"
|
||||
Binding="{Binding Name}" MaxWidth="200" MinWidth="200" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.machine}" Width="200" FontSize="26"
|
||||
Binding="{Binding Machine}" MaxWidth="200" MinWidth="200" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.state}" Width="150" FontSize="26"
|
||||
Binding="{Binding State}" MinWidth="150" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.Mode}" Width="150" FontSize="26"
|
||||
Binding="{Binding Model}" MinWidth="150" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="IP" Width="150" FontSize="26"
|
||||
Binding="{Binding IP}" MinWidth="150" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="用户" Width="150" FontSize="26"
|
||||
Binding="{Binding MachineUser}" MinWidth="150" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="密码" Width="150" FontSize="26"
|
||||
Binding="{Binding MachinePassword}" MinWidth="150" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.information}" Width="*" FontSize="26"
|
||||
Binding="{Binding Information}" MinWidth="200" CanUserReorder="False"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<!--存储按钮-->
|
||||
<Button Grid.Row="3" Content="存储" HorizontalAlignment="Right" Height="50" VerticalAlignment="Center" Width="100" FontSize="30"
|
||||
Click="Button_Preservation" Margin="0,0,200,0">
|
||||
</Button>
|
||||
<!--删除按钮-->
|
||||
<Button Grid.Row="3" Content="删除" HorizontalAlignment="Right" Height="50" VerticalAlignment="Center" Width="100" FontSize="30"
|
||||
Click="Button_Delete" Margin="0,0,50,0">
|
||||
</Button>
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -0,0 +1,96 @@
|
||||
using Microsoft.VisualBasic;
|
||||
using SunlightAggregationManager.ViewModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using System.Xml.Linq;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
namespace SunlightAggregationManager.UserWindow
|
||||
{
|
||||
/// <summary>
|
||||
/// MachineSet.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class MachineSet : Window
|
||||
{
|
||||
private string _id = "";
|
||||
public MachineSet()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void Button_Preservation(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Dictionary<string, object> _new = new Dictionary<string, object>();//缓存函数
|
||||
_new.Add("Name", _Name.Text);
|
||||
_new.Add("Machine", _Machine.Text);
|
||||
_new.Add("Model", GROUP.Text);
|
||||
_new.Add("IP", _IP.Text);
|
||||
_new.Add("MachineUser", _MachineUser.Text);
|
||||
_new.Add("MachinePassword", _MachinePassword.Text);
|
||||
_new.Add("Information", _inf.Text);
|
||||
_new.Add("State", 0);
|
||||
|
||||
var rowdata = MainWindowViewModel.Selet_Memory(MainWindowViewModel._machines, "ID", "ID='" + _id + "'");
|
||||
if (rowdata != null)
|
||||
{
|
||||
MainWindowViewModel.Updata_Memory(MainWindowViewModel._machines, "ID='" + _id + "'", _new);
|
||||
}
|
||||
else
|
||||
{
|
||||
MainWindowViewModel.Insert_Memory(MainWindowViewModel._machines, _new);// 执行插入
|
||||
}
|
||||
DataGridm.ItemsSource = MainWindowViewModel._machines.DefaultView;
|
||||
_Name.Text = null;
|
||||
_Machine.Text = null;
|
||||
_id = "";
|
||||
}
|
||||
|
||||
private void Button_Delete(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
MainWindowViewModel.Delete_Memory(MainWindowViewModel._machines, "ID='" + _id + "'");
|
||||
}
|
||||
catch (Exception) { }
|
||||
finally
|
||||
{
|
||||
DataGridm.ItemsSource = MainWindowViewModel._machines.DefaultView;
|
||||
_Name.Text = null;
|
||||
_Machine.Text = null;
|
||||
_id = "";
|
||||
}
|
||||
}
|
||||
|
||||
private void DataGridm_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
int rownum = DataGridm.SelectedIndex;//获取鼠标选中行并定义变量
|
||||
if (rownum != -1)//判断鼠标定位是否有效
|
||||
{
|
||||
/*定位选中行及指定列单元格文本信息*/
|
||||
_id = (DataGridm.Columns[0].GetCellContent(DataGridm.Items[rownum]) as TextBlock)!.Text.Trim();//定位第列
|
||||
_Name.Text = (DataGridm.Columns[1].GetCellContent(DataGridm.Items[rownum]) as TextBlock)!.Text.Trim();//定位第列
|
||||
_Machine.Text = (DataGridm.Columns[2].GetCellContent(DataGridm.Items[rownum]) as TextBlock)!.Text.Trim();//定位第列
|
||||
GROUP.Text = (DataGridm.Columns[4].GetCellContent(DataGridm.Items[rownum]) as TextBlock)!.Text.Trim();
|
||||
_IP.Text = (DataGridm.Columns[5].GetCellContent(DataGridm.Items[rownum]) as TextBlock)!.Text.Trim();
|
||||
_MachineUser.Text = (DataGridm.Columns[6].GetCellContent(DataGridm.Items[rownum]) as TextBlock)!.Text.Trim();
|
||||
_MachinePassword.Text = (DataGridm.Columns[7].GetCellContent(DataGridm.Items[rownum]) as TextBlock)!.Text.Trim();
|
||||
_inf.Text = (DataGridm.Columns[8].GetCellContent(DataGridm.Items[rownum]) as TextBlock)!.Text.Trim();
|
||||
}
|
||||
}
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DataGridm.ItemsSource = MainWindowViewModel._machines.DefaultView;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
<Window x:Class="SunlightAggregationManager.UserWindow.User"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:SunlightAggregationManager.UserWindow"
|
||||
xmlns:viewmodel="clr-namespace:SunlightAggregationManager.ViewModel"
|
||||
xmlns:lang="clr-namespace:SunlightAggregationManager"
|
||||
mc:Ignorable="d"
|
||||
Loaded="user_Loaded"
|
||||
ResizeMode="NoResize"
|
||||
Title="MAC_SET"
|
||||
Height="900" Width="1440" MinHeight="900" MinWidth="1440"
|
||||
BorderBrush="White" Background="White">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="5"/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="100"/>
|
||||
</Grid.RowDefinitions>
|
||||
<GridSplitter Grid.Row="1" Height="5" HorizontalAlignment="Stretch" Background="#FFCECECE"/>
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition MinWidth="200" MaxWidth="500"/>
|
||||
<ColumnDefinition Width="5"/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Stretch" Background="#FFCECECE"/>
|
||||
<Grid Grid.Column="0">
|
||||
<!--用户-->
|
||||
<TextBox x:Name="_User" Height="30" Margin="105,10,10,100" VerticalAlignment="Top" FontSize="16" MaxLines="1" InputMethod.IsInputMethodEnabled="False" />
|
||||
<TextBlock HorizontalAlignment="Left" Height="30" Margin="15,10,0,100" TextWrapping="Wrap"
|
||||
Text="{x:Static lang:ResourceLanguage.user}" VerticalAlignment="Top" Width="85" FontSize="20"/>
|
||||
<!--名-->
|
||||
<TextBox x:Name="_Name" Height="30" Margin="105,55,10,100" VerticalAlignment="Top" FontSize="16" MaxLines="1" />
|
||||
<TextBlock HorizontalAlignment="Left" Height="30" Margin="15,55,0,100" TextWrapping="Wrap"
|
||||
Text="{x:Static lang:ResourceLanguage.Name}" VerticalAlignment="Top" Width="85" FontSize="20"/>
|
||||
<!--密码-->
|
||||
<TextBox x:Name="Pasword" Height="30" Margin="105,100,10,50" VerticalAlignment="Top" FontSize="16" MaxLines="1" InputMethod.IsInputMethodEnabled="False" />
|
||||
<TextBlock HorizontalAlignment="Left" Height="30" Margin="15,100,0,50" TextWrapping="Wrap"
|
||||
Text="{x:Static lang:ResourceLanguage.Password}" VerticalAlignment="Top" Width="80" FontSize="20"/>
|
||||
<!--部门-->
|
||||
<TextBox x:Name="_Department" Height="30" Margin="105,145,10,50" VerticalAlignment="Top" FontSize="16" MaxLines="1" />
|
||||
<TextBlock HorizontalAlignment="Left" Height="30" Margin="15,145,0,50" TextWrapping="Wrap"
|
||||
Text="{x:Static lang:ResourceLanguage.Department}" VerticalAlignment="Top" Width="80" FontSize="20"/>
|
||||
<!--组-->
|
||||
<ComboBox x:Name="GROUP" Height="30" Margin="105,190,10,100" VerticalAlignment="Top" FontSize="16" IsReadOnly="True">
|
||||
<ComboBoxItem Content="CHIEF"></ComboBoxItem>
|
||||
<ComboBoxItem Content="ENGINEER"></ComboBoxItem>
|
||||
<ComboBoxItem Content="POWERUSER"></ComboBoxItem>
|
||||
<ComboBoxItem Content="USER"></ComboBoxItem>
|
||||
</ComboBox>
|
||||
<TextBlock HorizontalAlignment="Left" Height="30" Margin="15,190,0,50" TextWrapping="Wrap"
|
||||
Text="{x:Static lang:ResourceLanguage.Groups}" VerticalAlignment="Top" Width="80" FontSize="20"/>
|
||||
</Grid>
|
||||
<Grid Grid.Column="2" Margin="0">
|
||||
<ScrollViewer Margin="0" VerticalScrollBarVisibility="Auto">
|
||||
<WrapPanel Orientation="Horizontal" x:Name="Capacity" >
|
||||
</WrapPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<!--表-->
|
||||
<DataGrid Grid.Row="2" x:Name="DataGriduser" MouseDoubleClick="DataGridMac_MouseDoubleClick" SelectionMode="Single" AlternationCount="2" IsReadOnly="True"
|
||||
d:ItemsSource="{d:SampleData ItemCount=999}" AutoGenerateColumns="False" MinColumnWidth="30"
|
||||
HorizontalGridLinesBrush="#FFC9C9C9" VerticalGridLinesBrush="#FFC9C9C9" GridLinesVisibility="All" BorderBrush="{x:Null}"
|
||||
BorderThickness="1,1,1,1" ColumnHeaderHeight="40" HorizontalContentAlignment="Right" Grid.ColumnSpan="2"
|
||||
CanUserResizeRows="False" CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False" CanUserSortColumns="False" HeadersVisibility ="Column" Background="{x:Null}">
|
||||
<DataGrid.RowStyle >
|
||||
<Style TargetType="{x:Type DataGridRow}">
|
||||
<Style.Triggers>
|
||||
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
|
||||
<Setter Property="Background" Value="#FFFFFFFF" />
|
||||
</Trigger>
|
||||
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
|
||||
<Setter Property="Background" Value="#FFF0F0F0" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="False">
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</DataGrid.RowStyle>
|
||||
<DataGrid.CellStyle>
|
||||
<Style TargetType="DataGridCell">
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="MinWidth" Value="20"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter Property="Background" Value="#FFC0C0C0"/>
|
||||
<Setter Property="BorderBrush" Value="#FFC0C0C0"/>
|
||||
<Setter Property="Foreground" Value="#000000"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</DataGrid.CellStyle>
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.user}" Binding="{Binding User}"
|
||||
Width="200" FontSize="15" MaxWidth="200" MinWidth="200" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.Name}" Binding="{Binding Name}"
|
||||
Width="200" FontSize="15" MaxWidth="200" MinWidth="200" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.Password}" Binding="{Binding Password}"
|
||||
Width="200" FontSize="15" MaxWidth="200" MinWidth="200" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.Department}" Binding="{Binding Department}"
|
||||
Width="200" FontSize="15" MaxWidth="200" MinWidth="200" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.Groups}" Binding="{Binding Groups}"
|
||||
Width="200" FontSize="15" MaxWidth="200" MinWidth="200" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Binding="{Binding Capacity}" Width="0" MaxWidth="0" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.LastLoginIP}" Binding="{Binding LastLoginIP}"
|
||||
Width="200" FontSize="15" MaxWidth="200" MinWidth="200" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.LastLoginTime}" Binding="{Binding LastLoginTime}"
|
||||
Width="200" FontSize="15" MaxWidth="200" MinWidth="200" CanUserReorder="False"/>
|
||||
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<!--存储按钮-->
|
||||
<Button Grid.Row="3" Content="存储" HorizontalAlignment="Right" Height="50" VerticalAlignment="Center" Width="100" FontSize="30"
|
||||
Click="Button_Preservation" Margin="0,0,200,0">
|
||||
</Button>
|
||||
<!--删除按钮-->
|
||||
<Button Grid.Row="3" Content="删除" HorizontalAlignment="Right" Height="50" VerticalAlignment="Center" Width="100" FontSize="30"
|
||||
Click="Button_Delete" Margin="0,0,50,0">
|
||||
</Button>
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -0,0 +1,152 @@
|
||||
using SunlightAggregationManager.View;
|
||||
using SunlightAggregationManager.ViewModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace SunlightAggregationManager.UserWindow
|
||||
{
|
||||
/// <summary>
|
||||
/// Machine.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class User : Window
|
||||
{
|
||||
CheckBox[] checkBoxes = new CheckBox[99];
|
||||
string[] strings = new string[8] {"修改系统设置", "修改用户设置",
|
||||
"设备监控","设备控制","远程设置","远程查询","输送信息","历史查询"};
|
||||
public User()
|
||||
{
|
||||
WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void user_Loaded(object sender, RoutedEventArgs e)//打开页面执行
|
||||
{
|
||||
for (int i = 0; i < strings.Length; i++)
|
||||
{
|
||||
checkBoxes[i] = new CheckBox();
|
||||
checkBoxes[i].Content = strings[i].ToString();
|
||||
checkBoxes[i].FontSize = 20;
|
||||
checkBoxes[i].Width = 200;
|
||||
checkBoxes[i].Height = 50;
|
||||
Capacity.Children.Add(checkBoxes[i]);
|
||||
}
|
||||
DataGriduser.ItemsSource = MainWindowViewModel._userData.DefaultView;
|
||||
}
|
||||
|
||||
private void Tb_KeyFloating(object sender, TextCompositionEventArgs e)//输入事件
|
||||
{
|
||||
//Regex re = new Regex("[^0-9.-]+");
|
||||
Regex re = new Regex(@"^[.][0-9]+$|^[0-9]*[.]{0,1}[0-9]*$");// 非负浮点数
|
||||
e.Handled = !re.IsMatch(e.Text);
|
||||
}
|
||||
|
||||
private void DataGridMac_MouseDoubleClick(object sender, MouseButtonEventArgs e)//数据表双击事件
|
||||
{
|
||||
string Capacity_;
|
||||
int rownum = DataGriduser.SelectedIndex;//获取鼠标选中行并定义变量
|
||||
if (rownum != -1)//判断鼠标定位是否有效
|
||||
{
|
||||
/*定位选中行及指定列单元格文本信息*/
|
||||
_Name.Text = (DataGriduser.Columns[1].GetCellContent(DataGriduser.Items[rownum]) as TextBlock)!.Text.Trim();//定位第列
|
||||
_User.Text = (DataGriduser.Columns[0].GetCellContent(DataGriduser.Items[rownum]) as TextBlock)!.Text.Trim();//定位第列
|
||||
GROUP.Text = (DataGriduser.Columns[4].GetCellContent(DataGriduser.Items[rownum]) as TextBlock)!.Text.Trim();
|
||||
Capacity_ = (DataGriduser.Columns[5].GetCellContent(DataGriduser.Items[rownum]) as TextBlock)!.Text.Trim();
|
||||
_Department.Text = (DataGriduser.Columns[3].GetCellContent(DataGriduser.Items[rownum]) as TextBlock)!.Text.Trim();
|
||||
Pasword.Text = (DataGriduser.Columns[2].GetCellContent(DataGriduser.Items[rownum]) as TextBlock)!.Text.Trim();
|
||||
|
||||
if (strings.Length > Capacity_.Length)
|
||||
{
|
||||
for (int i = 0; i < Capacity_.Length; i++)
|
||||
{
|
||||
if (Capacity_.Substring(i, 1) == "1")
|
||||
{
|
||||
checkBoxes[i].IsChecked = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
checkBoxes[i].IsChecked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < strings.Length; i++)
|
||||
{
|
||||
if (Capacity_.Substring(i, 1) == "1")
|
||||
{
|
||||
checkBoxes[i].IsChecked = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
checkBoxes[i].IsChecked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Button_Preservation(object sender, RoutedEventArgs e)//保存按钮事件
|
||||
{
|
||||
Regex re_number = new Regex(@"^[0-9]+(.[0-9]{1,2})?$");//校验用正则表达式有1~2位小数的正实数
|
||||
Regex re_char = new Regex(@"^[A-Za-z0-9\s@()()/+!!_-]+$");//校验用正则表达式由数字,26个英文字母,空白字符和@()()/+!!_-组成的字符串
|
||||
|
||||
string user = _User.Text;
|
||||
string name = _Name.Text;
|
||||
string password = Pasword.Text;
|
||||
string Group = GROUP.Text;
|
||||
string Cap = "";
|
||||
string department = _Department.Text;
|
||||
for (int i = 0; i < strings.Length; i++)
|
||||
{
|
||||
if ((bool)checkBoxes[i].IsChecked!)
|
||||
{
|
||||
Cap = Cap + "1";
|
||||
}
|
||||
else { Cap = Cap + "0"; }
|
||||
}
|
||||
Dictionary<string, object> USER_new = new Dictionary<string, object>();//缓存函数
|
||||
USER_new.Add("User", user);
|
||||
USER_new.Add("Name", name);
|
||||
USER_new.Add("Password", password);
|
||||
USER_new.Add("Groups", Group);
|
||||
USER_new.Add("Capacity", Cap);
|
||||
USER_new.Add("Department", department);
|
||||
USER_new.Add("State", 0);
|
||||
USER_new.Add("Enterprise", MainWindowViewModel.Enterprise);
|
||||
|
||||
var rowdata = MainWindowViewModel.Selet_Memory(MainWindowViewModel._userData, "UserID", "User='" + user + "'");
|
||||
if (rowdata != null)
|
||||
{
|
||||
MainWindowViewModel.Updata_Memory(MainWindowViewModel._userData, "User='" + user + "'", USER_new);
|
||||
}
|
||||
else
|
||||
{
|
||||
MainWindowViewModel.Insert_Memory(MainWindowViewModel._userData, USER_new);// 执行插入
|
||||
}
|
||||
DataGriduser.ItemsSource = MainWindowViewModel._userData.DefaultView;
|
||||
_Name.Text = null;
|
||||
|
||||
}
|
||||
|
||||
private void Button_Delete(object sender, RoutedEventArgs e)//删除按钮事件
|
||||
{
|
||||
try
|
||||
{
|
||||
MainWindowViewModel.Delete_Memory(MainWindowViewModel._userData, "User='" + _User.Text + "'");
|
||||
}
|
||||
catch (Exception) { }
|
||||
finally
|
||||
{
|
||||
DataGriduser.ItemsSource = MainWindowViewModel._userData.DefaultView;
|
||||
_Name.Text = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
<Window x:Class="SunlightAggregationManager.Window.UserSet"
|
||||
<Window x:Class="SunlightAggregationManager.UserWindow.UserSet"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:SunlightAggregationManager.Window"
|
||||
xmlns:local="clr-namespace:SunlightAggregationManager.UserWindow"
|
||||
mc:Ignorable="d"
|
||||
Title="UserSet" Height="450" Width="800" WindowStyle="None" >
|
||||
Title="UserSet" Height="450" Width="800">
|
||||
<Grid>
|
||||
|
||||
</Grid>
|
||||
@@ -10,14 +10,14 @@ using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace SunlightAggregationManager.Window
|
||||
namespace SunlightAggregationManager.UserWindow
|
||||
{
|
||||
/// <summary>
|
||||
/// UserSet.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class UserSet : Window
|
||||
{
|
||||
public UserSet()
|
||||
public UserSet(string id)
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<UserControl x:Class="SunlightAggregationManager.View.ActionPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:SunlightAggregationManager.View"
|
||||
mc:Ignorable="d"
|
||||
Loaded="UserControl_Loaded"
|
||||
d:DesignHeight="720" d:DesignWidth="1080">
|
||||
<Grid>
|
||||
<DataGrid x:Name="CurrentData"
|
||||
IsReadOnly="True"
|
||||
AutoGenerateColumns="True"
|
||||
EnableRowVirtualization="True"
|
||||
EnableColumnVirtualization="True"
|
||||
VirtualizingPanel.IsVirtualizing="True"
|
||||
VirtualizingPanel.VirtualizationMode="Recycling"
|
||||
VirtualizingPanel.ScrollUnit="Pixel" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,36 @@
|
||||
using SunlightAggregationManager.UserClass;
|
||||
using SunlightAggregationManager.ViewModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace SunlightAggregationManager.View
|
||||
{
|
||||
/// <summary>
|
||||
/// ActionPage.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ActionPage : UserControl
|
||||
{
|
||||
public ActionPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void UserControl_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var data =MainWindowViewModel.SQLiteHelpers.ExecuteDataSet(
|
||||
"select * from ActionLog order by Time DESC", null)?.Tables[0] ?? new DataTable();
|
||||
CurrentData.ItemsSource=data.AsDataView();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<UserControl x:Class="SunlightAggregationManager.View.ExtendPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:SunlightAggregationManager.View"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace SunlightAggregationManager.View
|
||||
{
|
||||
/// <summary>
|
||||
/// ExtendPage.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ExtendPage : UserControl
|
||||
{
|
||||
public ExtendPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<UserControl x:Class="SunlightAggregationManager.View.MachinePage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:SunlightAggregationManager.View"
|
||||
xmlns:ConvertMoels="clr-namespace:SunlightAggregationManager.ConvertMoels"
|
||||
xmlns:lang="clr-namespace:SunlightAggregationManager"
|
||||
xmlns:viewmodel="clr-namespace:SunlightAggregationManager.ViewModel"
|
||||
d:DataContext="{d:DesignInstance Type=viewmodel:MainWindowViewModel}"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="720" d:DesignWidth="1080">
|
||||
<Grid>
|
||||
<DataGrid x:Name="DataGridmachines"
|
||||
ItemsSource="{Binding Machines.DefaultView}"
|
||||
SelectionChanged="DataGridmachines_SelectionChanged"
|
||||
SelectionMode="Single"
|
||||
AlternationCount="2"
|
||||
IsReadOnly="True"
|
||||
FontSize="26"
|
||||
Margin="5,5,5,5"
|
||||
AutoGenerateColumns="False"
|
||||
MinColumnWidth="30"
|
||||
HorizontalGridLinesBrush="#FFC9C9C9"
|
||||
VerticalGridLinesBrush="#FFC9C9C9"
|
||||
GridLinesVisibility="All"
|
||||
BorderBrush="#CCCCCC"
|
||||
BorderThickness="1,1,1,1"
|
||||
ColumnHeaderHeight="40"
|
||||
HorizontalContentAlignment="Right"
|
||||
CanUserReorderColumns="False"
|
||||
VerticalContentAlignment="Center">
|
||||
<DataGrid.RowStyle >
|
||||
<Style TargetType="{x:Type DataGridRow}">
|
||||
<Style.Triggers>
|
||||
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
|
||||
<Setter Property="Background" Value="#FFFFFFFF" />
|
||||
<Setter Property="Height" Value="40" />
|
||||
</Trigger>
|
||||
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
|
||||
<Setter Property="Background" Value="#FFF0F0F0" />
|
||||
<Setter Property="Height" Value="40" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="False">
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</DataGrid.RowStyle>
|
||||
<DataGrid.CellStyle>
|
||||
<Style TargetType="DataGridCell">
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="MinWidth" Value="20"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter Property="Background" Value="#FFC0C0C0"/>
|
||||
<Setter Property="BorderBrush" Value="#FFC0C0C0"/>
|
||||
<Setter Property="Foreground" Value="#000000"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</DataGrid.CellStyle>
|
||||
<DataGrid.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="{x:Static lang:ResourceLanguage.information}" Click="MenuItem_information"/>
|
||||
</ContextMenu>
|
||||
</DataGrid.ContextMenu>
|
||||
<DataGrid.Columns>
|
||||
<!--列信息绑定-->
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.information}" Width="200" FontSize="26"
|
||||
Binding="{Binding Name}" MaxWidth="200" MinWidth="200" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.machine}" Width="200" FontSize="26"
|
||||
Binding="{Binding Machine}" MaxWidth="200" MinWidth="200" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.state}" Width="150" FontSize="26"
|
||||
Binding="{Binding State}" MinWidth="150" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.Mode}" Width="150" FontSize="26"
|
||||
Binding="{Binding Model}" MinWidth="150" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="A" Width="150" FontSize="26"
|
||||
Binding="{Binding ModelA}" MinWidth="150" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="B" Width="150" FontSize="26"
|
||||
Binding="{Binding ModelB}" MinWidth="150" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="C" Width="150" FontSize="26"
|
||||
Binding="{Binding ModelC}" MinWidth="150" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="D" Width="150" FontSize="26"
|
||||
Binding="{Binding ModelD}" MinWidth="150" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="E" Width="150" FontSize="26"
|
||||
Binding="{Binding ModelE}" MinWidth="150" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="F" Width="150" FontSize="26"
|
||||
Binding="{Binding ModelF}" MinWidth="150" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.information}" Width="*" FontSize="26"
|
||||
Binding="{Binding Information}" MinWidth="200" CanUserReorder="False"/>
|
||||
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using SunlightAggregationManager.UserWindow;
|
||||
|
||||
namespace SunlightAggregationManager.View
|
||||
{
|
||||
/// <summary>
|
||||
/// MachinePage.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class MachinePage : UserControl
|
||||
{
|
||||
public MachinePage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private string id = "";
|
||||
private void DataGridmachines_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
int rownum = DataGridmachines.SelectedIndex;//获取鼠标选中行并定义变量
|
||||
if (rownum != -1)//判断鼠标定位是否有效
|
||||
{
|
||||
var row_ = DataGridmachines.Columns[0].GetCellContent(DataGridmachines.Items[rownum]);
|
||||
if (row_ is TextBlock textBlock)
|
||||
{
|
||||
id = textBlock.Text;//定位第0列,
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void MenuItem_information(object sender, RoutedEventArgs e)
|
||||
{
|
||||
MachineSet machineSet = new MachineSet();
|
||||
machineSet.Show();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<UserControl x:Class="SunlightAggregationManager.View.ServicePage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:SunlightAggregationManager.View"
|
||||
xmlns:viewmodel="clr-namespace:SunlightAggregationManager.ViewModel"
|
||||
d:DataContext="{d:DesignInstance Type=viewmodel:MainWindowViewModel}"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="720" d:DesignWidth="1080">
|
||||
<Grid>
|
||||
<DataGrid x:Name="DataGridmachinesdata"
|
||||
ItemsSource="{Binding Service.DefaultView}"
|
||||
SelectionMode="Single"
|
||||
AlternationCount="2"
|
||||
IsReadOnly="True"
|
||||
FontSize="26"
|
||||
Margin="5,5,5,5"
|
||||
AutoGenerateColumns="False"
|
||||
MinColumnWidth="30"
|
||||
HorizontalGridLinesBrush="#FFC9C9C9"
|
||||
VerticalGridLinesBrush="#FFC9C9C9"
|
||||
GridLinesVisibility="All"
|
||||
BorderBrush="#CCCCCC"
|
||||
BorderThickness="1,1,1,1"
|
||||
ColumnHeaderHeight="40"
|
||||
HorizontalContentAlignment="Right"
|
||||
CanUserReorderColumns="False"
|
||||
VerticalContentAlignment="Center">
|
||||
<DataGrid.RowStyle >
|
||||
<Style TargetType="{x:Type DataGridRow}">
|
||||
<Style.Triggers>
|
||||
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
|
||||
<Setter Property="Background" Value="#FFFFFFFF" />
|
||||
<Setter Property="Height" Value="40" />
|
||||
</Trigger>
|
||||
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
|
||||
<Setter Property="Background" Value="#FFF0F0F0" />
|
||||
<Setter Property="Height" Value="40" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="False">
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</DataGrid.RowStyle>
|
||||
<DataGrid.CellStyle>
|
||||
<Style TargetType="DataGridCell">
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="MinWidth" Value="20"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter Property="Background" Value="#FFC0C0C0"/>
|
||||
<Setter Property="BorderBrush" Value="#FFC0C0C0"/>
|
||||
<Setter Property="Foreground" Value="#000000"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</DataGrid.CellStyle>
|
||||
|
||||
<DataGrid.Columns>
|
||||
<!--列信息绑定-->
|
||||
<DataGridTextColumn Header="ID" Width="100" FontSize="26"
|
||||
Binding="{Binding ID}" MaxWidth="100" MinWidth="100" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="Status" Width="200" FontSize="26"
|
||||
Binding="{Binding Status}" MaxWidth="200" MinWidth="200" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="Service" Width="*" FontSize="26"
|
||||
Binding="{Binding Service}" MinWidth="200" CanUserReorder="False"/>
|
||||
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,27 @@
|
||||
using SunlightAggregationManager.ViewModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace SunlightAggregationManager.View
|
||||
{
|
||||
/// <summary>
|
||||
/// ServicePage.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ServicePage : UserControl
|
||||
{
|
||||
public ServicePage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,6 @@
|
||||
<Button Content="{x:Static lang:ResourceLanguage.Test}" HorizontalAlignment="Left" Height="35" Margin="370,335,0,0" VerticalAlignment="Top" Width="80" Click="test_Click"/>
|
||||
<TextBlock HorizontalAlignment="Left" Height="40" Margin="10,335,0,0" x:Name="textlog" TextWrapping="Wrap" Text="------------" VerticalAlignment="Top" Width="140" FontSize="20"/>
|
||||
|
||||
|
||||
<CheckBox x:Name="EnableTCP" Content="{x:Static lang:ResourceLanguage.EnableTCP}" HorizontalAlignment="Left" Margin="600,10,0,0" VerticalAlignment="Top" Height="40" Width="300" FontSize="24"
|
||||
Checked="EnableTCP_Checked" Unchecked="EnableTCP_Unchecked"/>
|
||||
<CheckBox x:Name="EnableHTTP" Content="{x:Static lang:ResourceLanguage.EnableHTTP}" HorizontalAlignment="Left" Margin="600,60,0,0" VerticalAlignment="Top" Height="40" Width="300" FontSize="24"
|
||||
|
||||
@@ -39,6 +39,35 @@ namespace SunlightAggregationManager.View
|
||||
TEXT_SQMOD.Text = Configini.IniReadvalue("SQL_SERVER", "SQL3");
|
||||
TEXT_SQLUSER.Text = Configini.IniReadvalue("SQL_SERVER", "SQL4");
|
||||
TEXT_SQLPASWORD.Text = Configini.IniReadvalue("SQL_SERVER", "SQL5");
|
||||
|
||||
|
||||
var tcp = Configini.IniReadvalue("NETWORK", "TCP");
|
||||
if (tcp == "1")
|
||||
{
|
||||
EnableTCP.IsChecked = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
EnableTCP.IsChecked = false;
|
||||
}
|
||||
var http = Configini.IniReadvalue("NETWORK", "HTTP");
|
||||
if (http == "1")
|
||||
{
|
||||
EnableHTTP.IsChecked = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
EnableHTTP.IsChecked = false;
|
||||
}
|
||||
var tls = Configini.IniReadvalue("NETWORK", "TLS");
|
||||
if (tls == "1")
|
||||
{
|
||||
EnableTLS.IsChecked = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
EnableTLS.IsChecked = false;
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@
|
||||
Binding="{Binding LastOfflineTime}" MinWidth="300" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.Groups}" Width="200" FontSize="26"
|
||||
Binding="{Binding Groups}" MinWidth="200" CanUserReorder="False"/>
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.information}" Width="*" FontSize="26"
|
||||
<DataGridTextColumn Header="{x:Static lang:ResourceLanguage.information}" Width="auto" FontSize="26"
|
||||
Binding="{Binding Note}" MinWidth="200" CanUserReorder="False"/>
|
||||
|
||||
</DataGrid.Columns>
|
||||
|
||||
+6
-10
@@ -1,4 +1,5 @@
|
||||
using SunlightAggregationManager.UserClass;
|
||||
using SunlightAggregationManager.UserWindow;
|
||||
using SunlightAggregationManager.ViewModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -40,17 +41,15 @@ namespace SunlightAggregationManager.View
|
||||
if (row_ is TextBlock textBlock)
|
||||
{
|
||||
user_id = textBlock.Text;//定位第0列,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void MenuItem_Information(object sender, RoutedEventArgs e)//信息
|
||||
{
|
||||
|
||||
User userSet =new User();
|
||||
userSet.Show();
|
||||
}
|
||||
|
||||
private async void MenuItem_Offine(object sender, RoutedEventArgs e)//下线
|
||||
@@ -82,9 +81,6 @@ namespace SunlightAggregationManager.View
|
||||
{
|
||||
MainWindowViewModel.Updata_Memory(MainWindowViewModel._userData, "User='" + user_id + "'", "99", "State");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
+7
-3
@@ -1,8 +1,10 @@
|
||||
using Net.Codecrete.QrCodeGenerator;
|
||||
using SunlightAggregationManager.ViewModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
@@ -94,9 +96,11 @@ namespace SunlightAggregationManager.View
|
||||
}
|
||||
|
||||
private void imgQR_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
string text_APP = "TEST"; // 要生成二维码的内容
|
||||
string text_LINK = Configini.IniReadvalue("SYS", "LINK"); // 要生成二维码的内容
|
||||
{
|
||||
string text_APP = "TEST"; //
|
||||
string text_LINK = MainWindowViewModel.MachineIP + ":"+ MainWindowViewModel.MachineIPP1 +
|
||||
"," + MainWindowViewModel.SERVERIP + ":7791/"+ MainWindowViewModel.Enterprise;
|
||||
// 要生成二维码的内容
|
||||
|
||||
imgQR_CREATE(text_APP, imgQR_app);
|
||||
imgQR_CREATE(text_LINK, imgQR_link);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using SunlightAggregationManager.UserClass;
|
||||
using SunlightAggregationManager.View;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
@@ -10,6 +11,7 @@ using System.Reflection.PortableExecutable;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Xml.Linq;
|
||||
|
||||
@@ -25,19 +27,34 @@ namespace SunlightAggregationManager.ViewModel
|
||||
public static string SQLUSER = "";
|
||||
public static string SQLPASWORD = "";
|
||||
public static string MachineName = "SERVER";
|
||||
public static string MachineVer = "1.0.0";
|
||||
public static string MachineIP = "";
|
||||
public static int MachineIPP1 = 7789;
|
||||
public static int MachineIPP2 = 7790;
|
||||
public static int MachineHTTPP = 7791;
|
||||
public static string Enterprise = "";
|
||||
public static string TCP_E = "0";
|
||||
public static string HTTP_E = "0";
|
||||
public static string TLS_E = "0";
|
||||
public static string SERVERIP = "";
|
||||
public static string SERVERNAME = "";
|
||||
public static string SERVERUSER = "";
|
||||
public static string SERRVERPASWORD = "";
|
||||
public static int ChemicalNumber, DyeMeasurementNumber, DyeDissolveNumber, PowderNumber;
|
||||
|
||||
private static Timer? _timer;
|
||||
public static DataTable ChemicalStatistics = new DataTable();
|
||||
public static DataTable DBC_Machines = new DataTable();
|
||||
public static DataBase dataBase = new DataBase();
|
||||
public static UserClass.SqliteHelper SQLiteHelpers = null!; //定义数据库
|
||||
private readonly string DBAddress = Environment.CurrentDirectory + "\\DataBase\\SunlightAggregationManager.db"; //数据库路径
|
||||
|
||||
public static DataTable ActionLog = new DataTable();
|
||||
|
||||
[ObservableProperty]
|
||||
public static DataTable _machines = new DataTable(); //设备表缓存
|
||||
[ObservableProperty]
|
||||
public static DataTable _userData = new DataTable();
|
||||
|
||||
[ObservableProperty]
|
||||
public static DataTable _service = new DataTable();
|
||||
|
||||
public MainWindowViewModel()
|
||||
{
|
||||
@@ -46,12 +63,15 @@ namespace SunlightAggregationManager.ViewModel
|
||||
SQMOD = Configini.IniReadvalue("SQL_SERVER", "SQL3");
|
||||
SQLUSER = Configini.IniReadvalue("SQL_SERVER", "SQL4");
|
||||
SQLPASWORD = Configini.IniReadvalue("SQL_SERVER", "SQL5");
|
||||
|
||||
MachineName = Configini.IniReadvalue("SYS", "Name");
|
||||
|
||||
Enterprise = Configini.IniReadvalue("SYS", "Enterprise");
|
||||
TCP_E = Configini.IniReadvalue("NETWORK", "TCP");
|
||||
HTTP_E = Configini.IniReadvalue("NETWORK", "HTTP");
|
||||
TLS_E = Configini.IniReadvalue("NETWORK", "TLS");
|
||||
SERVERIP = Configini.IniReadvalue("SERVER", "SERVERIP");
|
||||
SERVERNAME = Configini.IniReadvalue("SERVER", "SERVERNAME");
|
||||
SERVERUSER = Configini.IniReadvalue("SERVER", "SERVERUSER");
|
||||
SERRVERPASWORD = Configini.IniReadvalue("SERVER", "SERRVERPASWORD");
|
||||
|
||||
//本地数据库(sqlite)
|
||||
try
|
||||
@@ -62,11 +82,6 @@ namespace SunlightAggregationManager.ViewModel
|
||||
Machines = SQLiteHelpers.ExecuteDataSet("select * from Machines order by ID asc", null)?.Tables[0] ?? new DataTable();
|
||||
ActionLog = (SQLiteHelpers.ExecuteDataSet("select * from ActionLog", null)?.Tables[0] ?? new DataTable()).Clone();
|
||||
// SQLiteHelpers.Close();
|
||||
|
||||
if (UserData.Columns.Contains("UserID"))
|
||||
{
|
||||
UserData.Columns.Remove("UserID");
|
||||
}
|
||||
DataRow[] dataRows = UserData.Select("State<90");
|
||||
foreach (DataRow row in dataRows)
|
||||
{
|
||||
@@ -74,38 +89,125 @@ namespace SunlightAggregationManager.ViewModel
|
||||
row["LinkID"] = 0;
|
||||
}
|
||||
|
||||
|
||||
Machines.RowChanged += Machines_Updata;
|
||||
Machines.RowDeleting += Machines_Updata;
|
||||
UserData.RowChanged += UserData_Updata;//注册userdata表更新事件
|
||||
|
||||
UserData.RowDeleting += UserData_Updata;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.ToString());
|
||||
}
|
||||
|
||||
//运行数据库
|
||||
DataBase dataBase = new DataBase();
|
||||
dataBase.Config(SQLIP, SQLNAME, SQMOD, SQLUSER, SQLPASWORD);
|
||||
//服务信息表
|
||||
//DataTable Service = new DataTable();
|
||||
Service.BeginInit();
|
||||
Service.Columns.Add("ID", typeof(int));
|
||||
Service.Columns.Add("Status", typeof(string));
|
||||
Service.Columns.Add("Service", typeof(string));
|
||||
|
||||
//运行数据库
|
||||
Service.Rows.Add(0, "RUN", "SQL_DataBase_Link");
|
||||
dataBase.Config(SQLIP, SQLNAME, SQMOD, SQLUSER, SQLPASWORD);
|
||||
|
||||
if (TCP_E == "1")//启动tcp(内网直连)
|
||||
{
|
||||
int P1, P2;
|
||||
try
|
||||
{
|
||||
P1 =int.Parse( Configini.IniReadvalue("NETWORK", "TCP_PORT1"));
|
||||
MachineIPP1 = int.Parse(Configini.IniReadvalue("NETWORK", "TCP_PORT1"));
|
||||
}
|
||||
catch (Exception) { P1 = 7789; }
|
||||
catch (Exception) { MachineIPP1 = 7789; }
|
||||
try
|
||||
{
|
||||
P2 = int.Parse(Configini.IniReadvalue("NETWORK", "TCP_PORT2"));
|
||||
MachineIPP2 = int.Parse(Configini.IniReadvalue("NETWORK", "TCP_PORT2"));
|
||||
}
|
||||
catch (Exception) { P2 = 7790; }
|
||||
catch (Exception) { MachineIPP2 = 7790; }
|
||||
|
||||
using var _ = AsyncTcpServer.TcpMain(P1,P2);
|
||||
Service.Rows.Add(1, "RUN", "TCP");
|
||||
AsyncTcpServer.Configuration(MachineIPP1, MachineIPP2);
|
||||
}
|
||||
else
|
||||
{
|
||||
Service.Rows.Add(1, "STOP", "TCP");
|
||||
}
|
||||
if (HTTP_E == "1")//启动tcp(内网直连)
|
||||
{
|
||||
try
|
||||
{
|
||||
MachineHTTPP = int.Parse(Configini.IniReadvalue("NETWORK", "HTTP_PORT"));
|
||||
}
|
||||
catch (Exception) { MachineHTTPP = 7791; }
|
||||
|
||||
Service.Rows.Add(2, "RUN", "HTTP");
|
||||
AsyncHttpServer.Configuration(MachineHTTPP);
|
||||
}
|
||||
else
|
||||
{
|
||||
Service.Rows.Add(2, "STOP", "HTTP");
|
||||
}
|
||||
|
||||
//获取当前IP
|
||||
MachineIP = GetLocalIP.GetLocalIPv4Address().ToString();
|
||||
Console.WriteLine(MachineIP);
|
||||
//连接sunlight服务器
|
||||
Service.Rows.Add(3, "RUN", "Sunlight_Server_Link");
|
||||
AsyncTcpClient.Configuration(SERVERIP + ":7795", SERVERNAME, SERVERUSER, SERRVERPASWORD);
|
||||
|
||||
Service.EndInit();
|
||||
|
||||
|
||||
_timer = new Timer(TimeTask, null, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(30));
|
||||
}
|
||||
|
||||
//Machines操作数据库
|
||||
private void Machines_Updata(object sender, DataRowChangeEventArgs e)
|
||||
{
|
||||
Dictionary<string, object> row_entity = new Dictionary<string, object>();
|
||||
Dictionary<string, object> userlog = new Dictionary<string, object>();
|
||||
|
||||
if (e.Action == DataRowAction.Change)
|
||||
{
|
||||
//修改的行回传
|
||||
foreach (DataColumn col in Machines.Columns)
|
||||
{
|
||||
row_entity.Add(col.ColumnName, e.Row.Field<object>(col.ColumnName) ?? DBNull.Value);//传入字段和值(值允许为空)
|
||||
|
||||
if (ActionLog.Columns.Contains(col.ColumnName))//添加到行为记录表
|
||||
{
|
||||
userlog.Add(col.ColumnName, e.Row.Field<object>(col.ColumnName) ?? DBNull.Value);//传入字段和值(值允许为空)
|
||||
}
|
||||
}
|
||||
SQLiteHelpers.Update("Machines", row_entity, "ID='" + e.Row.Field<object>("ID") + "'", null);
|
||||
userlog.Add("Action", "Command");
|
||||
userlog.Add("Time", DateTime.Now.ToString("yyyy-MM-dd dd:HH:mm:ss:fff"));
|
||||
userlog.Add("Note", "Machine = " + e.Row.Field<object>("Machine"));
|
||||
SQLiteHelpers.InsertData("ActionLog", userlog);
|
||||
|
||||
}
|
||||
if (e.Action == DataRowAction.Add)
|
||||
{
|
||||
//添加的行回传
|
||||
foreach (DataColumn col in Machines.Columns)
|
||||
{
|
||||
row_entity.Add(col.ColumnName, e.Row.Field<object>(col.ColumnName) ?? DBNull.Value);//传入字段和值(值允许为空)
|
||||
}
|
||||
SQLiteHelpers.InsertData("Machines", row_entity);
|
||||
userlog.Add("Time", DateTime.Now.ToString("yyyy-MM-dd dd:HH:mm:ss:fff"));
|
||||
userlog.Add("Action", "New Account");
|
||||
userlog.Add("Note", "Machine = " + e.Row.Field<object>("Machine"));
|
||||
SQLiteHelpers.InsertData("ActionLog", userlog);
|
||||
}
|
||||
if (e.Action == DataRowAction.Delete)
|
||||
{
|
||||
//删除的行回传
|
||||
SQLiteHelpers.Delete("Machines", "ID='" + e.Row.Field<object>("ID") + "'", null);
|
||||
userlog.Add("Time", DateTime.Now.ToString("yyyy-MM-dd dd:HH:mm:ss:fff"));
|
||||
userlog.Add("Action", "Delete Account");
|
||||
userlog.Add("Note", "Machine = " + e.Row.Field<object>("Machine"));
|
||||
SQLiteHelpers.InsertData("ActionLog", userlog);
|
||||
}
|
||||
}
|
||||
//UserData操作数据库
|
||||
private void UserData_Updata(object sender, DataRowChangeEventArgs e)
|
||||
{
|
||||
Dictionary<string, object> row_entity = new Dictionary<string, object>();
|
||||
@@ -159,21 +261,82 @@ namespace SunlightAggregationManager.ViewModel
|
||||
SQLiteHelpers.InsertData("ActionLog", userlog);
|
||||
}
|
||||
}
|
||||
|
||||
//数据表操作
|
||||
public static void Insert_Memory(DataTable DB, Dictionary<string, object> Value)//插入数据
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (DB)
|
||||
{
|
||||
DataRow drEmployee = DB.NewRow();
|
||||
drEmployee.BeginEdit();
|
||||
|
||||
public static object? Selet_Memory(DataTable DB, string name, string? key)//查询
|
||||
foreach (KeyValuePair<string, object> kvp in Value)
|
||||
{
|
||||
drEmployee[kvp.Key] = kvp.Value;
|
||||
}
|
||||
drEmployee.EndEdit();
|
||||
DB.Rows.Add(drEmployee);
|
||||
drEmployee.AcceptChanges();
|
||||
// drEmployee.ClearErrors();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Insert_Row:" + ex.ToString());
|
||||
}
|
||||
}
|
||||
public static void Delete_Memory(DataTable DB, string? key)//删除数据
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (DB)
|
||||
{
|
||||
DataRow drEmployee = DB.Select(key).First();
|
||||
object? index = drEmployee.Field<object>(name);
|
||||
return index;
|
||||
drEmployee.Delete();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("SDTD:" + ex.ToString());
|
||||
Console.WriteLine("Delete_Row:" + ex.ToString());
|
||||
}
|
||||
}
|
||||
public static DataRow? Selet_Row(DataTable DB, string? key)//查询
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (DB)
|
||||
{
|
||||
DataRow drEmployee = DB.Select(key).First();
|
||||
return drEmployee;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Selet_Row:" + ex.ToString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public static object? Selet_Memory(DataTable DB, string name, string? key)//查询
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (DB)
|
||||
{
|
||||
DataRow[] dataRows = DB.Select(key);
|
||||
if (dataRows.Count() > 0)
|
||||
{
|
||||
DataRow drEmployee = dataRows.First();
|
||||
object? index = drEmployee.Field<object>(name);
|
||||
return index;
|
||||
}
|
||||
else { return null; }
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Selet_Memory:" + ex.ToString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -227,5 +390,68 @@ namespace SunlightAggregationManager.ViewModel
|
||||
Console.WriteLine("SDTD:" + ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private static int EXTime = 120;
|
||||
private static async void TimeTask(object? state)
|
||||
{
|
||||
if (EXTime == 120)//1小时
|
||||
{
|
||||
EXTask();//统计配送消息
|
||||
EXTime = 0;
|
||||
}
|
||||
|
||||
|
||||
DBC_Machines = await dataBase.ExecuteQueryAsync("SELECT *FROM [BatchDyeingCentral].[dbo].[Machines]");
|
||||
|
||||
EXTime++;
|
||||
|
||||
}
|
||||
private static async void EXTask()
|
||||
{
|
||||
try
|
||||
{
|
||||
string DyelotsBulkedRecipe_sql = "SELECT [ProductCode],[ProductName],SUM(DispenseGrams)" +
|
||||
"as TotalDispenseGrams FROM [BatchDyeingCentral].[dbo].[DyelotsBulkedRecipe] " +
|
||||
"where DispenseEndTime > '" + DateTime.Now.ToString("yyyy-MM-dd") + "' AND DispenseEndTime < '" +
|
||||
DateTime.Now.AddDays(1).ToString("yyyy-MM-dd") + "' GROUP BY [ProductCode],[ProductName] " +
|
||||
"ORDER BY TotalDispenseGrams DESC ";
|
||||
string Dye_sql =
|
||||
"SELECT [Dyelot],[ReDye],[StepNumber] FROM [BatchDyeingCentral].[dbo].[DyelotsBulkedRecipe] " +
|
||||
"where ((DispenseEndTime >= '" + DateTime.Now.ToString("yyyy-MM-dd") + "' AND DispenseEndTime < '" +
|
||||
DateTime.Now.AddDays(1).ToString("yyyy-MM-dd") + "') OR (DispenseTime >= '" + DateTime.Now.ToString("yyyy-MM-dd") +
|
||||
"' AND DispenseTime < '" + DateTime.Now.AddDays(1).ToString("yyyy-MM-dd") + "')) " +
|
||||
"AND ProductType = 1 GROUP BY [Dyelot],[ReDye],[StepNumber];";
|
||||
string Chemical_sql =
|
||||
"SELECT [Dyelot],[ReDye],[StepNumber] FROM [BatchDyeingCentral].[dbo].[DyelotsBulkedRecipe] " +
|
||||
"where ((DispenseEndTime >= '" + DateTime.Now.ToString("yyyy-MM-dd") + "' AND DispenseEndTime < '" +
|
||||
DateTime.Now.AddDays(1).ToString("yyyy-MM-dd") + "') OR (DispenseTime >= '" + DateTime.Now.ToString("yyyy-MM-dd") +
|
||||
"' AND DispenseTime < '" + DateTime.Now.AddDays(1).ToString("yyyy-MM-dd") + "')) " +
|
||||
"AND ProductType = 2 GROUP BY [Dyelot],[ReDye],[StepNumber];";
|
||||
string Powder_sql =
|
||||
"SELECT [Dyelot],[ReDye],[StepNumber] FROM [BatchDyeingCentral].[dbo].[DyelotsBulkedRecipe] " +
|
||||
"where ((DispenseEndTime >= '" + DateTime.Now.ToString("yyyy-MM-dd") + "' AND DispenseEndTime < '" +
|
||||
DateTime.Now.AddDays(1).ToString("yyyy-MM-dd") + "') OR (DispenseTime >= '" + DateTime.Now.ToString("yyyy-MM-dd") +
|
||||
"' AND DispenseTime < '" + DateTime.Now.AddDays(1).ToString("yyyy-MM-dd") + "')) " +
|
||||
"AND ProductType = 3 GROUP BY [Dyelot],[ReDye],[StepNumber];";
|
||||
string DyeDissolve =
|
||||
"SELECT *FROM [BatchDyeingCentral].[dbo].[DyeSolutionHistory] " + "where DispenseEndTime >= '" +
|
||||
DateTime.Now.ToString("yyyy-MM-dd") + "' AND DispenseEndTime < '" + DateTime.Now.AddDays(1).ToString("yyyy-MM-dd") + "'";
|
||||
|
||||
ChemicalStatistics = await dataBase.ExecuteQueryAsync(DyelotsBulkedRecipe_sql);
|
||||
DyeMeasurementNumber = await dataBase.ExecuteQueryAsyncCount(Dye_sql);
|
||||
ChemicalNumber = await dataBase.ExecuteQueryAsyncCount(Chemical_sql);
|
||||
PowderNumber = await dataBase.ExecuteQueryAsyncCount(Powder_sql);
|
||||
DyeDissolveNumber = await dataBase.ExecuteQueryAsyncCount(DyeDissolve);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{//错误处理
|
||||
LogGing.ERRDATA(ex);
|
||||
Console.WriteLine(ex.ToString());
|
||||
}
|
||||
finally {
|
||||
Console.WriteLine("当日染料称量["+ DyeMeasurementNumber+ "]染料输送["+ DyeDissolveNumber + "]" +
|
||||
"助剂输送["+ ChemicalNumber + "]粉体输送["+ PowderNumber + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user