AppService.cpp 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504
  1. #include "stdafx.h"
  2. #include "AppService.h"
  3. #include <ace/Init_ACE.h>
  4. #include <Simplelog.h>
  5. #include <ODBC/DBConnectPool.h>
  6. #include "MonitorObject.h"
  7. #include "ResistAlarm.h"
  8. #include "httplib.h"
  9. #include <Simplelog.h>
  10. #include <gbk2utf8.h>
  11. #include <HjFunc.h>
  12. #include "TimeSyncServerDlg.h"
  13. #include "315ClientManager.h"
  14. #ifdef _DEBUG
  15. #pragma comment(lib, "HJ_ACE650d.lib")
  16. #pragma message("Automatically linking with aced.dll")
  17. #else
  18. #pragma comment(lib, "HJ_ACE650.lib")
  19. #pragma message("Automatically linking with ace.dll")
  20. #endif
  21. #ifdef _DEBUG
  22. bool g_bLog = true;
  23. #else
  24. bool g_bLog;
  25. #endif // _DEBUG
  26. time_t g_stStart; //程序启动的时间
  27. string g_strExepath; //程序目录
  28. string g_strVersion; //程序版本
  29. uint32_t g_tReminderInterval = 21600;
  30. string g_strMoMp; //监控日志
  31. CMyRWLock g_lockSync; //同步读写锁
  32. bool g_bDataCompression; //历史数据是否压缩
  33. bool g_bExternalData; //是否启用外部数据
  34. CString g_strIniPath;
  35. C315ClientManager *g_p315ClientManager;
  36. void tagFileData::Join()
  37. {
  38. delete this;
  39. }
  40. CAppService::CAppService()
  41. {
  42. CreateDirectory("E:\\DB", NULL);
  43. CSimpleLog::CreateLogDir("E:\\DB\\Log\\");
  44. CSimpleLog::SetFileName("DataServices");
  45. #ifdef DEBUG_202
  46. CSimpleLog::SetDaysNum(7);
  47. #else
  48. CSimpleLog::SetDaysNum(15);
  49. #endif // DEBUG
  50. #ifdef _DEBUG
  51. CSimpleLog::SetLevel(CSimpleLog::debug);
  52. #else
  53. CSimpleLog::SetLevel(CSimpleLog::info);
  54. #endif // _DEBUG
  55. AfxSocketInit();
  56. CSimpleLog::Info("AfxSocketInit");
  57. ACE::init();
  58. CSimpleLog::Info(" ACE::init();");
  59. CString strLog;
  60. strLog.Format(_T("进程ID:%d"), getpid());
  61. CSimpleLog::Info(strLog);
  62. }
  63. CAppService::~CAppService()
  64. {
  65. for (auto& it :m_mapTempTypeData)
  66. {
  67. it.second->Join();
  68. it.second = nullptr;
  69. }
  70. for (auto& it : m_mapTypeData)
  71. {
  72. it.second->Join();
  73. it.second = nullptr;
  74. }
  75. m_mapTempTypeData.clear();
  76. m_mapTypeData.clear();
  77. ACE::fini();
  78. AfxSocketTerm();
  79. }
  80. bool CAppService::Start()
  81. {
  82. SYSTEM_INFO sysinfo;
  83. GetSystemInfo(&sysinfo);
  84. g_strExepath = hjfunc_GetAppDir();
  85. g_strVersion = hjfunc_GetVersion();
  86. auto strPath = CSimpleLog::GetAppDir() + "svg";
  87. if (CSimpleLog::PathFileExistsA(strPath) == FALSE)
  88. CreateDirectory(strPath, nullptr);
  89. strPath = CSimpleLog::GetAppDir() + "refer";
  90. if (CSimpleLog::PathFileExistsA(strPath) == FALSE)
  91. CreateDirectory(strPath, nullptr);
  92. g_strIniPath = m_strIniPath = CSimpleLog::GetAppDir() + "DataServices.ini";
  93. char szTemp[100] = { 0 };
  94. CString m_strDriver = "ODBC Driver 11 for SQL Server";
  95. CString m_strDataSource = "127.0.0.1,21009";
  96. CString m_strCataLog = "RMDB";
  97. CString m_strUserID = "zljc";
  98. CString m_strPassWD = "Zljc123!@#";
  99. int port = 10086;
  100. ::GetPrivateProfileStringA("ODBC", "DRIVER", CStringA(m_strDriver), szTemp, sizeof(szTemp), m_strIniPath);
  101. m_strDriver = CString(szTemp);
  102. ::GetPrivateProfileStringA("ODBC", "SERVER", CStringA(m_strDataSource), szTemp, sizeof(szTemp), m_strIniPath);
  103. m_strDataSource = CString(szTemp);
  104. ::GetPrivateProfileStringA("ODBC", "UID", CStringA(m_strUserID), szTemp, sizeof(szTemp), m_strIniPath);
  105. m_strUserID = CString(szTemp);
  106. ::GetPrivateProfileStringA("ODBC", "PWD", CStringA(m_strPassWD), szTemp, sizeof(szTemp), m_strIniPath);
  107. m_strPassWD = CString(szTemp);
  108. ::GetPrivateProfileStringA("ODBC", "DATABASE", CStringA(m_strCataLog), szTemp, sizeof(szTemp), m_strIniPath);
  109. m_strCataLog = CString(szTemp);
  110. port = ::GetPrivateProfileInt("SET", "port", port, m_strIniPath);
  111. g_tReminderInterval = ::GetPrivateProfileInt("SET", "reminder_interval", g_tReminderInterval, m_strIniPath);
  112. ::GetPrivateProfileString("SET", "momp", "", szTemp, sizeof(szTemp), m_strIniPath);
  113. g_strMoMp = szTemp;
  114. g_bDataCompression = ::GetPrivateProfileInt("SET", "DataCompression", g_bDataCompression, m_strIniPath);
  115. g_bExternalData = ::GetPrivateProfileInt("SET", "ExternalData", g_bExternalData, m_strIniPath);
  116. ::WritePrivateProfileStringA("ODBC", "DRIVER", CStringA(m_strDriver), m_strIniPath);
  117. ::WritePrivateProfileStringA("ODBC", "SERVER", CStringA(m_strDataSource), m_strIniPath);
  118. ::WritePrivateProfileStringA("ODBC", "DATABASE", CStringA(m_strCataLog), m_strIniPath);
  119. ::WritePrivateProfileString("ODBC", "UID", m_strUserID, m_strIniPath);
  120. ::WritePrivateProfileString("ODBC", "PWD", m_strPassWD, m_strIniPath);
  121. ::WritePrivateProfileStringA("SET", "port", (to_string(port) + " #Websocket 端口").c_str(), m_strIniPath);
  122. ::WritePrivateProfileString("SET", "reminder_interval", (to_string(g_tReminderInterval) + " #报警提醒间隔").c_str(), m_strIniPath);
  123. ::WritePrivateProfileString("SET", "momp", g_strMoMp.c_str(), m_strIniPath);
  124. ::WritePrivateProfileString("SET", "DataCompression", to_string(g_bDataCompression).c_str(), m_strIniPath);
  125. ::WritePrivateProfileString("SET", "ExternalData", fmt::format("{} #是否采用外部程序分析数据进行智能判断 默认为0 9.6以上", (int)g_bExternalData).c_str(), m_strIniPath);
  126. //ODBC
  127. if (CDBConnectPool::Instance()->Init(m_strDriver, m_strDataSource, m_strUserID, m_strPassWD, m_strCataLog, 5) == FALSE)
  128. {
  129. ASSERT(0);
  130. CString strLog;
  131. strLog.Format("数据库连接池初始化失败");
  132. TRACE("%s\r\n", strLog);
  133. CSimpleLog::Save(strLog, true, CSimpleLog::error);
  134. return false;
  135. }
  136. //升级
  137. {
  138. CString sql;
  139. BOOL ret;
  140. sql = "SELECT top 1 name1 FROM rm_map";
  141. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  142. if (TRUE != ret)
  143. {
  144. sql = "alter table rm_map add name1 nvarchar(50) default '';";
  145. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  146. sql = "update rm_map set name1 = '' where name1 is null;";
  147. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  148. sql = "alter table rm_map add name2 nvarchar(50) default '';";
  149. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  150. sql = "update rm_map set name2 = '' where name2 is null;";
  151. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  152. sql = "alter table rm_map add name3 nvarchar(50) default '';";
  153. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  154. sql = "update rm_map set name3 = '' where name3 is null;";
  155. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  156. }
  157. //move 记录检查type 索引
  158. {
  159. SYSTEMTIME lastSt;
  160. GetLocalTime(&lastSt);
  161. string table_today = fmt::format("rm_move_{:0>4}{:0>2}", lastSt.wYear, lastSt.wMonth);
  162. sql = fmt::format("IF NOT EXISTS (\
  163. SELECT * FROM(\
  164. SELECT\
  165. i.name AS IndexName,\
  166. OBJECT_NAME(ic.OBJECT_ID) AS TableName,\
  167. COL_NAME(ic.OBJECT_ID, ic.column_id) AS ColumnName\
  168. FROM\
  169. sys.indexes AS i\
  170. INNER JOIN sys.index_columns AS ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id\
  171. WHERE\
  172. OBJECT_NAME(ic.OBJECT_ID) = '{0}') AS tb WHERE tb.IndexName = 'IDX_MO_MP' AND ColumnName = 'type')\
  173. BEGIN\
  174. if exists(select 1\
  175. from sysindexes\
  176. where id = object_id('{0}')\
  177. and name = 'IDX_MO_MP'\
  178. and indid > 0\
  179. and indid < 255)\
  180. drop index {0}.IDX_MO_MP\
  181. create unique clustered index IDX_MO_MP on {0}(\
  182. mo ASC,\
  183. mp ASC,\
  184. show_time ASC,\
  185. type ASC)\
  186. END", table_today).c_str();
  187. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  188. }
  189. sql = "DELETE FROM rm_user WHERE username IN (SELECT username FROM ( SELECT username, COUNT(*) AS TotalCount FROM rm_user GROUP BY username) AS Counts WHERE TotalCount >= 2);";
  190. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  191. sql = "DELETE FROM rm_map WHERE zl_1_loca is null;";
  192. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  193. sql = "if not exists (select 1 from [rm_mo] where [id] = '100000' )\
  194. BEGIN\
  195. INSERT INTO [rm_mo] ([id],[type],[up],[name],[updatetime]) VALUES ('100000' ,'group' ,'100000', '国铁集团',GETDATE());\
  196. END";
  197. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  198. sql = "if not exists (select 1 from [rm_user] where [username] = 'system' )\
  199. BEGIN\
  200. INSERT INTO [dbo].[rm_user]([username] ,[password] ,[name] ,[admin] ,[token] ,[node] ,[enable] ,[mobile] ,[email] ,[mark]) VALUES ('system' ,'Zljc123!@#' ,'系统管理员' ,1 ,'AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA','100000',1,'15305712458','','');\
  201. END";
  202. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  203. sql = "UPDATE rm_alarm SET ack_result = 1,ack_name='system',ack_time=GETDATE() WHERE DATEDIFF(d,occur_time,GETDATE()) > 7 AND ack_result = 0;";
  204. CDBConnectPool::Instance()->DBExecuteSQL(sql);
  205. sql = "UPDATE rm_alarm SET handle_result = 1,handle_name='system',handle_time=GETDATE() WHERE DATEDIFF(d,occur_time,GETDATE()) > 30 AND handle_result = 0";
  206. CDBConnectPool::Instance()->DBExecuteSQL(sql);
  207. sql = "SELECT top 1 module FROM rm_record";
  208. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  209. if (TRUE != ret)
  210. {
  211. sql = "create table rm_record (\
  212. module tinyint not null,\
  213. dura int not null,\
  214. analyze_type tinyint null,\
  215. station nvarchar(50) not null,\
  216. station_name nvarchar(50) not null,\
  217. mo varchar(20) null,\
  218. mo_name varchar(20) null,\
  219. mp varchar(20) null,\
  220. mp_name varchar(20) null,\
  221. start_time bigint not null,\
  222. end_time bigint null,\
  223. time bigint not null,\
  224. name nvarchar(50) not null,\
  225. username varchar(50) null default '',\
  226. opt smallint not null,\
  227. mark nvarchar(200) null default ''\
  228. );\
  229. create clustered index IDX_STATION on rm_record(\
  230. station_name ASC,\
  231. time DESC\
  232. );\
  233. create index IDX_TIME on rm_record(\
  234. time DESC\
  235. );";
  236. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  237. if (ret != TRUE)
  238. CSimpleLog::Error(sql);
  239. }
  240. sql = "select top 1 event_id from rm_alarm";
  241. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  242. if (true != ret)
  243. {
  244. sql = "alter table rm_alarm add event_id char(36) null default newid();\
  245. alter table rm_alarm add rel_id char(36) null default ''; ";
  246. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  247. sql = "UPDATE [rm_alarm] SET [event_id]=NEWID() WHERE [event_id] is null;\
  248. UPDATE [rm_alarm] SET [rel_id]='' WHERE [rel_id] is null;";
  249. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  250. }
  251. sql = " IF NOT EXISTS ( SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID('rm_alarm') AND name = 'IDX_GUID' )\
  252. BEGIN CREATE INDEX IDX_GUID ON rm_alarm(event_id ASC) END";
  253. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  254. sql = " IF NOT EXISTS ( SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID('rm_alarm') AND name = 'IDX_REL_GUID' )\
  255. BEGIN CREATE INDEX IDX_REL_GUID ON rm_alarm(rel_id ASC) END";
  256. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  257. sql = "select top 1 posi from rm_alarm";
  258. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  259. if (true != ret)
  260. {
  261. sql = "alter table rm_alarm add posi tinyint null default 0;";
  262. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  263. sql = "alter table rm_alarm add loworhigh tinyint null default 0;";
  264. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  265. sql = "alter table rm_alarm add referval int null default 0;";
  266. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  267. sql = "alter table rm_alarm add recovery_time datetime null default 0;";
  268. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  269. sql = "update rm_alarm set posi = 0, loworhigh = 0, referval = 0, recovery_time=0 where posi is null;";
  270. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  271. }
  272. sql = "select top 1 sunroof from rm_alarm";
  273. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  274. if (true != ret)
  275. {
  276. sql = "alter table rm_alarm add sunroof tinyint null default 0;";
  277. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  278. sql = "update rm_alarm set sunroof= CASE WHEN (DATEPART(HOUR, occur_time) > 4) THEN 0 ELSE 1 END where sunroof is null;";
  279. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  280. }
  281. sql = " select top 1 zzjno from rm_map";
  282. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  283. if (true != ret)
  284. {
  285. sql = "ALTER TABLE [rm_map] ADD [zzjno] int default 0 ;";
  286. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  287. sql = "WITH CTE AS ( SELECT [zzjno], ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNum FROM [rm_map] ) UPDATE CTE SET [zzjno] = RowNum;\
  288. CREATE UNIQUE INDEX idx_unique_zzjno ON rm_map(zzjno);";
  289. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  290. sql = "ALTER TABLE rm_map add epos INT default 0;";
  291. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  292. sql = "UPDATE rm_map SET epos=0 WHERE epos is null;";
  293. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  294. }
  295. sql = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'rm_map' AND COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') = 1;";
  296. COdbcStatement stmt;
  297. ret = CDBConnectPool::Instance()->DBQuery(stmt, sql);
  298. if (true == ret)
  299. {
  300. if (stmt.FetchNext() == 0)
  301. {
  302. sql = "ALTER TABLE [rm_map] DROP COLUMN [zzjno];";
  303. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  304. sql = "ALTER TABLE [rm_map] ADD [zzjno] int;";
  305. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  306. sql = "WITH CTE AS ( SELECT [zzjno], ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNum FROM [rm_map] ) UPDATE CTE SET [zzjno] = RowNum;\
  307. CREATE UNIQUE INDEX idx_unique_zzjno ON rm_map(zzjno);";
  308. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  309. }
  310. }
  311. sql = " select top 1 install_1 from rm_map";
  312. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  313. if (true != ret)
  314. {
  315. sql = "ALTER TABLE rm_map add install_1 tinyint default 1;ALTER TABLE rm_map add install_2 tinyint default 1;ALTER TABLE rm_map add install_3 tinyint default 1; ";
  316. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  317. sql = "UPDATE rm_map SET install_1=1 WHERE install_1 is null;UPDATE rm_map SET install_2=1 WHERE install_2 is null;UPDATE rm_map SET install_3=1 WHERE install_3 is null;";
  318. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  319. }
  320. //修改rm_deviceinfo表
  321. sql = " select top 1 st0 from rm_deviceinfo";
  322. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  323. if (true != ret)
  324. {
  325. sql = "ALTER TABLE rm_deviceinfo add st0 tinyint default 1;"
  326. "ALTER TABLE rm_deviceinfo add st1 tinyint default 1;"
  327. "ALTER TABLE rm_deviceinfo add st2 tinyint default 1;"
  328. "ALTER TABLE rm_deviceinfo add st3 tinyint default 1;"
  329. "ALTER TABLE rm_deviceinfo add st4 tinyint default 1;"
  330. "ALTER TABLE rm_deviceinfo add st5 tinyint default 1;"
  331. "ALTER TABLE rm_deviceinfo add st6 tinyint default 1;"
  332. "ALTER TABLE rm_deviceinfo add st7 tinyint default 1;"
  333. "ALTER TABLE rm_deviceinfo add st8 tinyint default 1;"
  334. "ALTER TABLE rm_deviceinfo add dt0 tinyint default 0;"
  335. "ALTER TABLE rm_deviceinfo add dt1 tinyint default 0;"
  336. "ALTER TABLE rm_deviceinfo add dt2 tinyint default 0;"
  337. "ALTER TABLE rm_deviceinfo add dt3 tinyint default 0;"
  338. "ALTER TABLE rm_deviceinfo add dt4 tinyint default 0;"
  339. "ALTER TABLE rm_deviceinfo add dt5 tinyint default 0;"
  340. "ALTER TABLE rm_deviceinfo add dt6 tinyint default 0;"
  341. "ALTER TABLE rm_deviceinfo add dt7 tinyint default 0;"
  342. "ALTER TABLE rm_deviceinfo add dt8 tinyint default 0;"
  343. ;
  344. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  345. }
  346. //传感器离线暂时不作为报警 作为设备状态
  347. sql = "UPDATE rm_alarm set recovery_time=GETDATE() WHERE type = 0x21 and recovery_time < '2000'";
  348. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  349. sql = "UPDATE rm_alarm set ack_result=1, ack_name='system',ack_time=GETDATE() WHERE type = 0x21 and ack_result = 0";
  350. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  351. sql = "update rm_alarm_set set conf = REPLACE(conf, 'true', 'false') where type in(1, 2)";
  352. ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  353. }
  354. //end 升级
  355. m_bWork = true;
  356. m_pCreateTableThread = new std::thread(CAppService::ThreadProcCreateTable, (DWORD_PTR)this);
  357. Sleep(10);
  358. if (!CMonitorObjectMng::Instance()->LoadMonitorTree())
  359. {
  360. ASSERT(0);
  361. CSimpleLog::Error("LoadMonitorTree Fail. ");
  362. }
  363. else
  364. {
  365. CMonitorObjectMng::Instance()->LoadHistoryData();
  366. //开启新的websocket
  367. m_mgServer = new CMGWSServer;
  368. if (!m_mgServer->Start(port))
  369. {
  370. ASSERT(0);
  371. CSimpleLog::Error("start mg websocket server fail.");
  372. return false;
  373. }
  374. //m_lwsServer = new CLWSServer;
  375. //if (!m_lwsServer->Start(port + 1))
  376. //{
  377. // assert(0);
  378. // CSimpleLog::Error("start lws server fail.");
  379. // return false;
  380. //}
  381. }
  382. if (!CResistAlarmMng::Instance()->Start(m_strIniPath))
  383. {
  384. CSimpleLog::Error("Alarm Start Fail.");
  385. }
  386. //启动315协议
  387. if (g_p315ClientManager == nullptr) g_p315ClientManager = new C315ClientManager;
  388. if (g_p315ClientManager->Run(m_strIniPath)) CSimpleLog::Info("[315]启动成功!");
  389. else CSimpleLog::Error("[315]启动失败!");
  390. if (!CSuperManager::Instance()->Start(m_strIniPath))
  391. {
  392. ASSERT(0);
  393. CSimpleLog::Error("start Super Manager fail.");
  394. return false;
  395. }
  396. m_pHandle = new CLNHandle;
  397. m_pProactorTask = new CProactorTask;
  398. m_pProactorTask->start(2);
  399. m_pAcceptor = new CLNAcceptor(m_pHandle);
  400. if (m_pAcceptor == nullptr)
  401. {
  402. ASSERT(0);
  403. CSimpleLog::Error("CZHGSAcceptor 创建失败!");
  404. return false;
  405. }
  406. if (m_pAcceptor->listen(51609) == -1)
  407. {
  408. ASSERT(0);
  409. CSimpleLog::Error("CZHGSAcceptor 51609 监听失败!");
  410. return false;
  411. }
  412. m_pUdpSocket = new CUDPSocket;
  413. m_pUdpSocket->SetProtocolHandler(m_pHandle);
  414. if (!m_pUdpSocket->Open(51609, NULL, 0, NULL))
  415. {
  416. ASSERT(0);
  417. CSimpleLog::Error("CUDPSocket 监听失败!");
  418. return false;
  419. }
  420. m_bRun = true;
  421. m_pThreadClearConn = new std::thread(CAppService::ThreadProc, (DWORD_PTR)this);
  422. m_pHttpThread = new std::thread(CAppService::ThreadProcForHTTP10088, (DWORD_PTR)this);
  423. m_pHttpThread2 = new std::thread(CAppService::ThreadProcForHTTP10087, (DWORD_PTR)this);
  424. m_pThreadSpace = new std::thread(CAppService::ThreadProcForSpace, (DWORD_PTR)this);
  425. m_pThreadTime = new std::thread(CAppService::ThreadProcForTime, (DWORD_PTR)this);
  426. m_pThreadSync = new std::thread(CAppService::ThreadProcSync, (DWORD_PTR)this);
  427. time(&g_stStart);
  428. PostMessage(AfxGetApp()->m_pMainWnd->GetSafeHwnd(), WM_START, 0, 0);
  429. CSimpleLog::Info(("start succ.Version:" + g_strVersion).c_str());
  430. SPDLOG_INFO("start succ.Version:{}", g_strVersion);
  431. TRACE("start succ.\r\n");
  432. return true;
  433. }
  434. void CAppService::Stop()
  435. {
  436. CSimpleLog::Info("停止服务");
  437. m_bRun = false;
  438. m_bWork = false;
  439. g_p315ClientManager->Stop();
  440. Sleep(100);
  441. TerminateProcess((HANDLE)-1, 0);
  442. if (m_pThreadSpace)
  443. {
  444. m_pThreadSpace->join();
  445. delete m_pThreadSpace;
  446. m_pThreadSpace = nullptr;
  447. }
  448. if (m_pThreadTime)
  449. {
  450. m_pThreadTime->join();
  451. delete m_pThreadTime;
  452. m_pThreadTime = nullptr;
  453. }
  454. if (m_pThreadClearConn)
  455. {
  456. m_pThreadClearConn->join();
  457. delete m_pThreadClearConn;
  458. m_pThreadClearConn = nullptr;
  459. }
  460. if (m_pCreateTableThread)
  461. {
  462. m_pCreateTableThread->join();
  463. delete m_pCreateTableThread;
  464. m_pCreateTableThread = nullptr;
  465. }
  466. if (m_pHttpThread)
  467. {
  468. m_svr10088.stop();
  469. m_pHttpThread->join();
  470. delete m_pHttpThread;
  471. m_pHttpThread = nullptr;
  472. }
  473. if (m_pHttpThread2)
  474. {
  475. m_svr10087.stop();
  476. m_pHttpThread2->join();
  477. delete m_pHttpThread2;
  478. m_pHttpThread2 = nullptr;
  479. }
  480. if (m_pAcceptor)
  481. {
  482. m_pAcceptor->ClearAllContexts();
  483. delete m_pAcceptor;
  484. m_pAcceptor = nullptr;
  485. }
  486. if (m_pUdpSocket)
  487. {
  488. m_pUdpSocket->Close();
  489. delete m_pUdpSocket;
  490. m_pUdpSocket = nullptr;
  491. }
  492. CResistAlarmMng::Instance()->Stop();
  493. //if (m_lwsServer)
  494. //{
  495. // m_lwsServer->Stop();
  496. // delete m_lwsServer;
  497. // m_lwsServer = nullptr;
  498. //}
  499. if (m_mgServer)
  500. {
  501. m_mgServer->Stop();
  502. delete m_mgServer;
  503. m_mgServer = nullptr;
  504. }
  505. if (m_pHandle)
  506. {
  507. m_pHandle->Close();
  508. delete m_pHandle;
  509. m_pHandle = nullptr;
  510. }
  511. CSuperManager::Instance()->Stop();
  512. CDBConnectPool::Instance()->Clear();
  513. }
  514. BOOL CAppService::FileDataConvertCharData(const uint8_t* filedata, const int filelen, char* strData)
  515. {
  516. if (strData == nullptr) return FALSE;
  517. for (auto i = 0; i < filelen; i++)
  518. sprintf_s(strData + i * 2, 3, "%02X", filedata[i]);
  519. return TRUE;
  520. }
  521. void CAppService::ThreadProc(DWORD_PTR wparam)
  522. {
  523. CAppService* pThis = (CAppService*)wparam;
  524. std::this_thread::sleep_for(std::chrono::seconds(10));
  525. while (pThis->m_bWork)
  526. {
  527. for (size_t i = 0; i < 10; i++)
  528. {
  529. std::this_thread::sleep_for(std::chrono::milliseconds(500));
  530. if (pThis->m_bWork == false) break;
  531. }
  532. pThis->m_pAcceptor->OnClearContext();
  533. for (size_t i = 0; i < 10; i++)
  534. {
  535. std::this_thread::sleep_for(std::chrono::milliseconds(500));
  536. if (pThis->m_bWork == false) break;
  537. }
  538. }
  539. }
  540. #include "HttpPrcess.h"
  541. void CAppService::ThreadProcForHTTP10088(DWORD_PTR pThis)
  542. {
  543. using namespace httplib;
  544. m_svr10088.Post("/data/.*", DealHttpPost);
  545. m_svr10088.Get("/data/.*", DealHttpGet);
  546. m_svr10088.Put("/data/.*", DealHttpPut);
  547. //string strPath = CSimpleLog::GetAppDir();
  548. //auto ret = m_svr.set_mount_point("/", strPath);
  549. //if (!ret) {
  550. // // The specified base directory doesn't exist...
  551. //}
  552. m_svr10088.set_keep_alive_max_count(20);// Default is 5
  553. m_svr10088.set_keep_alive_timeout(300);// Default is 5
  554. auto ret = m_svr10088.listen("0.0.0.0", 10088);
  555. return ;
  556. }
  557. void CAppService::ThreadProcForHTTP10087(DWORD_PTR)
  558. {
  559. using namespace httplib;
  560. m_svr10087.Post("/hist/.*", DealHttpPost);
  561. m_svr10087.Get("/hist/.*", DealHttpGet);
  562. m_svr10087.Put("/hist/.*", DealHttpPut);
  563. //string strPath = CSimpleLog::GetAppDir();
  564. //auto ret = m_svr.set_mount_point("/", strPath);
  565. //if (!ret) {
  566. // // The specified base directory doesn't exist...
  567. //}
  568. m_svr10087.set_keep_alive_max_count(20);// Default is 5
  569. m_svr10087.set_keep_alive_timeout(300);// Default is 5
  570. auto ret = m_svr10087.listen("0.0.0.0", 10087);
  571. return;
  572. }
  573. void CAppService::ThreadProcCreateTable(DWORD_PTR pThis)
  574. {
  575. auto pService = (CAppService*)pThis;
  576. CSimpleLog::Info("ThreadProcCreateTable 线程开始!");
  577. do
  578. {
  579. SYSTEMTIME stNow, stTom, stYest;
  580. GetLocalTime(&stNow);
  581. COleDateTime odt_now(stNow);
  582. COleDateTime odt_tom = odt_now + COleDateTimeSpan(1, 0, 0, 0);
  583. COleDateTime odt_yest = odt_now - COleDateTimeSpan(1, 0, 0, 0);
  584. odt_tom.GetAsSystemTime(stTom);
  585. odt_yest.GetAsSystemTime(stYest);
  586. CString tableName;
  587. CString tableNameTom;
  588. CString tableNameYest;
  589. tableName.Format("rm_resistance_%04d%02d%02d", stNow.wYear, stNow.wMonth, stNow.wDay, stNow.wHour, stNow.wMinute, stNow.wSecond);
  590. tableNameTom.Format("rm_resistance_%04d%02d%02d", stTom.wYear, stTom.wMonth, stTom.wDay, stTom.wHour, stTom.wMinute, stTom.wSecond);
  591. tableNameYest.Format("rm_resistance_%04d%02d%02d", stYest.wYear, stYest.wMonth, stYest.wDay, stYest.wHour, stYest.wMinute, stYest.wSecond);
  592. CString existsql = CString("select top 1 id from sysobjects where name = '") + tableName + "' and type = 'U';";
  593. CString existsqlTom = CString("select top 1 id from sysobjects where name = '") + tableNameTom + "' and type = 'U';";
  594. CString existsqlYest = CString("select top 1 id from sysobjects where name = '") + tableNameYest + "' and type = 'U';";
  595. CString tablesqltoday = CString("create table ") + tableName + " (\n" +
  596. " IMEI varchar(50) not null,\n" +
  597. " acquisitiontime datetime not null,\n" +
  598. " idx tinyint not null,\n" +
  599. " data0 int null,\n" +
  600. " data1 int null,\n" +
  601. " data2 int null\n" +
  602. ");" +
  603. "create unique clustered index IDX_TIME on " + tableName + " (\n" +
  604. "IMEI ASC,\n" +
  605. "acquisitiontime ASC,\n" +
  606. "idx ASC\n" +
  607. ")";
  608. CString tablesqlTom = "create table " + tableNameTom + " (\n" +
  609. " IMEI varchar(50) not null,\n" +
  610. " acquisitiontime datetime not null,\n" +
  611. " idx tinyint not null,\n" +
  612. " data0 int null,\n" +
  613. " data1 int null,\n" +
  614. " data2 int null\n" +
  615. ");" +
  616. "create unique clustered index IDX_TIME on " + tableNameTom + " (\n" +
  617. "IMEI ASC,\n" +
  618. "acquisitiontime ASC,\n" +
  619. "idx ASC\n" +
  620. ")";
  621. CString tableYest = "create table " + tableNameYest + " (\n" +
  622. " IMEI varchar(50) not null,\n" +
  623. " acquisitiontime datetime not null,\n" +
  624. " idx tinyint not null,\n" +
  625. " data0 int null,\n" +
  626. " data1 int null,\n" +
  627. " data2 int null\n" +
  628. ");" +
  629. "create unique clustered index IDX_TIME on " + tableNameYest + " (\n" +
  630. "IMEI ASC,\n" +
  631. "acquisitiontime ASC,\n" +
  632. "idx ASC\n" +
  633. ")";
  634. COdbcStatement stmt;
  635. CDBConnectPool::Instance()->DBQuery(stmt, existsql);
  636. int id = 0;
  637. stmt.BindIntCol(1, &id);
  638. if (stmt.FetchNext() != 0)
  639. {
  640. //不存在
  641. if (!CDBConnectPool::Instance()->DBExecuteSQL(tablesqltoday))
  642. {
  643. CSimpleLog::Error("数据库执行错误:" + tablesqltoday);
  644. }
  645. }
  646. stmt.Close();
  647. COdbcStatement stmtTom;
  648. CDBConnectPool::Instance()->DBQuery(stmtTom, existsqlTom);
  649. stmtTom.BindIntCol(1, &id);
  650. if (stmtTom.FetchNext() != 0)
  651. {
  652. //不存在
  653. if (!CDBConnectPool::Instance()->DBExecuteSQL(tablesqlTom))
  654. {
  655. CSimpleLog::Error("数据库执行错误:" + tablesqlTom);
  656. }
  657. }
  658. stmtTom.Close();
  659. COdbcStatement stmtYest;
  660. CDBConnectPool::Instance()->DBQuery(stmtYest, existsqlYest);
  661. stmtYest.BindIntCol(1, &id);
  662. if (stmtYest.FetchNext() != 0)
  663. {
  664. //不存在
  665. if (!CDBConnectPool::Instance()->DBExecuteSQL(tableYest))
  666. {
  667. CSimpleLog::Error("数据库执行错误:" + tableYest);
  668. }
  669. }
  670. stmtYest.Close();
  671. //temperature
  672. tableName.Format("rm_temphumidity_%04d%02d", stNow.wYear, stNow.wMonth, stNow.wDay, stNow.wHour, stNow.wMinute);
  673. tableNameTom.Format("rm_temphumidity_%04d%02d", stTom.wYear, stTom.wMonth, stTom.wDay, stTom.wHour, stTom.wMinute);
  674. existsql = CString("select top 1 id from sysobjects where name = '") + tableName + "' and type = 'U';";
  675. existsqlTom = CString("select top 1 id from sysobjects where name = '") + tableNameTom + "' and type = 'U';";
  676. tablesqltoday = CString("create table ") + tableName + " (\n" +
  677. " IMEI varchar(50) not null,\n" +
  678. " acquisitiontime datetime not null,\n" +
  679. " temperature int not null,\n" +
  680. " humidity int not null\n" +
  681. ");" +
  682. "create unique clustered index IDX_IMEI on " + tableName + " (\n" +
  683. "IMEI ASC,\n" +
  684. "acquisitiontime ASC\n" +
  685. ")";
  686. CDBConnectPool::Instance()->DBQuery(stmt, existsql);
  687. stmt.BindIntCol(1, &id);
  688. if (stmt.FetchNext() != 0)
  689. {
  690. //不存在
  691. if (!CDBConnectPool::Instance()->DBExecuteSQL(tablesqltoday))
  692. {
  693. CSimpleLog::Error("数据库执行错误:" + tablesqltoday);
  694. }
  695. }
  696. stmt.Close();
  697. if (stNow.wMonth != stTom.wMonth || stNow.wYear != stTom.wYear)
  698. {
  699. CDBConnectPool::Instance()->DBQuery(stmt, existsqlTom);
  700. stmt.BindIntCol(1, &id);
  701. if (stmt.FetchNext() != 0)
  702. {
  703. //不存在
  704. tablesqlTom = CString("create table ") + tableNameTom + " (\n" +
  705. " IMEI varchar(50) not null,\n" +
  706. " acquisitiontime datetime not null,\n" +
  707. " temperature int not null,\n" +
  708. " humidity int not null\n" +
  709. ");" +
  710. "create unique clustered index IDX_IMEI on " + tableNameTom + " (\n" +
  711. "IMEI ASC,\n" +
  712. "acquisitiontime ASC\n" +
  713. ")";
  714. if (!CDBConnectPool::Instance()->DBExecuteSQL(tablesqlTom))
  715. {
  716. CSimpleLog::Error("数据库执行错误:" + tablesqlTom);
  717. }
  718. }
  719. stmt.Close();
  720. }
  721. //扳动记录表
  722. {
  723. SYSTEMTIME lastSt;
  724. memcpy(&lastSt, &stNow, sizeof(SYSTEMTIME));
  725. move_today:
  726. string table_today = fmt::format("rm_move_{:0>4}{:0>2}", lastSt.wYear, lastSt.wMonth);
  727. COdbcStatement stmt;
  728. CDBConnectPool::Instance()->DBQuery(stmt, CString(fmt::format("select top 1 id from sysobjects where name = '{}' and type = 'U'; ", table_today).c_str()));
  729. int id = 0;
  730. stmt.BindIntCol(1, &id);
  731. if (stmt.FetchNext() != 0)
  732. {
  733. CString strSql = fmt::format("create table {0} (\
  734. mo varchar(20) not null,\
  735. mp varchar(20) not null,\
  736. show_time datetime not null,\
  737. start_time datetime null,\
  738. end_time datetime null,\
  739. curr_val int null,\
  740. show_val int not null,\
  741. idx tinyint null,\
  742. posi tinyint not null default(0),\
  743. mark nvarchar(255) null,\
  744. type tinyint not null default(0),\
  745. sunroof tinyint not null default(0),\
  746. );create unique clustered index IDX_MO_MP on {0}(mo ASC,mp ASC,show_time ASC,type ASC);\
  747. create index IDX_TIME on {0} (show_time DESC)", table_today).c_str();
  748. //不存在
  749. if (!CDBConnectPool::Instance()->DBExecuteSQL(strSql))
  750. {
  751. CSimpleLog::Error("数据库执行错误:" + strSql);
  752. }
  753. }
  754. stmt.Close();
  755. if (lastSt.wYear != stTom.wYear || lastSt.wMonth != stTom.wMonth)
  756. {
  757. memcpy(&lastSt, &stTom, sizeof(SYSTEMTIME));
  758. goto move_today;
  759. }
  760. auto move_reserve = ::GetPrivateProfileInt("SET", "move_reserve", 730, pService->m_strIniPath);
  761. if (move_reserve < 90) move_reserve = 90;
  762. ::WritePrivateProfileStringA("SET", "move_reserve", fmt::format("{} 天 #转换过程记录保留天数, 默认730天, 20230701起", move_reserve).c_str(), pService->m_strIniPath);
  763. static bool bExec_rm_move = true;
  764. COleDateTimeSpan dts_delete(move_reserve, 0, 0, 0);
  765. CString sql = "select name from sys.tables where name like 'rm_move_%' ORDER BY name;";
  766. if (CDBConnectPool::Instance()->DBQuery(stmt, sql)) {
  767. char tablename[50];
  768. stmt.BindCharCol(1, tablename, sizeof(tablename));
  769. while (true)
  770. {
  771. memset(tablename, 0, sizeof(tablename));
  772. if (stmt.FetchNext() != 0) {
  773. break;
  774. }
  775. if (strlen(tablename) < 14)
  776. {
  777. assert(0);
  778. continue;
  779. }
  780. COleDateTime dd;
  781. try
  782. {
  783. int year, month;
  784. sscanf_s(tablename, "rm_move_%04d%02d", &year, &month);
  785. dd = COleDateTime(year, month, 1, 0, 0, 0);
  786. }
  787. catch (const std::exception&)
  788. {
  789. assert(0);
  790. continue;
  791. }
  792. if (odt_now - dd > dts_delete)
  793. {
  794. sql.Format(" DROP TABLE %s ", tablename);
  795. CDBConnectPool::Instance()->DBExecuteSQL(sql);
  796. }
  797. else
  798. {
  799. int ret = 0;
  800. if (bExec_rm_move == false) break;
  801. CString qq = CString("SELECT top 1 end_time FROM ") + tablename;
  802. if (CDBConnectPool::Instance()->DBExecuteSQL(qq) == FALSE)
  803. {
  804. qq.Format("ALTER TABLE %s ADD end_time datetime null;", tablename);
  805. CDBConnectPool::Instance()->DBExecuteSQL(qq);
  806. qq.Format("UPDATE %s SET end_time = 0 where end_time is null;", tablename);
  807. CDBConnectPool::Instance()->DBExecuteSQL(qq);
  808. }
  809. qq = CString("SELECT top 1 type FROM ") + tablename;
  810. if (CDBConnectPool::Instance()->DBExecuteSQL(qq) == FALSE)
  811. {
  812. qq.Format("ALTER TABLE %s ADD type tinyint null;", tablename);
  813. CDBConnectPool::Instance()->DBExecuteSQL(qq);
  814. qq.Format("UPDATE %s SET type = 0 where type is null;", tablename);
  815. CDBConnectPool::Instance()->DBExecuteSQL(qq);
  816. }
  817. qq = CString("SELECT top 1 type FROM ") + tablename;
  818. if (CDBConnectPool::Instance()->DBExecuteSQL(qq) == FALSE)
  819. {
  820. qq.Format("ALTER TABLE %s ADD type tinyint null default(0);", tablename);
  821. ret = CDBConnectPool::Instance()->DBExecuteSQL(qq);
  822. qq.Format("UPDATE %s SET type = 0 where type is null;", tablename);
  823. ret = CDBConnectPool::Instance()->DBExecuteSQL(qq);
  824. }
  825. qq = CString("SELECT top 1 sunroof FROM ") + tablename;
  826. if (CDBConnectPool::Instance()->DBExecuteSQL(qq) == FALSE)
  827. {
  828. qq.Format("ALTER TABLE %s ADD sunroof tinyint null default(0);", tablename);
  829. ret = CDBConnectPool::Instance()->DBExecuteSQL(qq);
  830. }
  831. qq.Format("UPDATE %s SET sunroof = CASE WHEN (DATEPART(HOUR, show_time) > 4) THEN 0 ELSE 1 END where sunroof is null;", tablename);
  832. ret = CDBConnectPool::Instance()->DBExecuteSQL(qq);
  833. qq.Format("UPDATE %s set show_val = curr_val where show_val = 0 and type = 2 and curr_val !=0;", tablename); //临时
  834. ret = CDBConnectPool::Instance()->DBExecuteSQL(qq);
  835. }
  836. }
  837. stmt.Close();
  838. bExec_rm_move = false;
  839. }
  840. }
  841. //过车记录表
  842. {
  843. SYSTEMTIME lastSt;
  844. memcpy(&lastSt, &stNow, sizeof(SYSTEMTIME));
  845. pass_today:
  846. string table_today = fmt::format("rm_pass_{:0>4}{:0>2}", lastSt.wYear, lastSt.wMonth);
  847. COdbcStatement stmt;
  848. CDBConnectPool::Instance()->DBQuery(stmt, CString(fmt::format("select top 1 id from sysobjects where name = '{}' and type = 'U'; ", table_today).c_str()));
  849. int id = 0;
  850. stmt.BindIntCol(1, &id);
  851. if (stmt.FetchNext() != 0)
  852. {
  853. CString strSql = fmt::format("create table {0} (\
  854. mo varchar(20) not null,\
  855. mp varchar(20) not null,\
  856. show_time datetime null,\
  857. show_val int not null default(0),\
  858. curr_val int not null,\
  859. start_time datetime not null,\
  860. end_time datetime not null,\
  861. idx tinyint not null,\
  862. shaking int null default 0\
  863. );create unique clustered index IDX_MO_MP on {0}(mo ASC,mp ASC,start_time ASC);", table_today).c_str();
  864. //不存在
  865. if (!CDBConnectPool::Instance()->DBExecuteSQL(strSql))
  866. {
  867. CSimpleLog::Error("数据库执行错误:" + strSql);
  868. }
  869. }
  870. stmt.Close();
  871. if (lastSt.wYear != stTom.wYear || lastSt.wMonth != stTom.wMonth)
  872. {
  873. memcpy(&lastSt, &stTom, sizeof(SYSTEMTIME));
  874. goto pass_today;
  875. }
  876. auto move_reserve = ::GetPrivateProfileInt("SET", "pass_reserve", 730, pService->m_strIniPath);
  877. if (move_reserve < 90) move_reserve = 90;
  878. ::WritePrivateProfileStringA("SET", "pass_reserve", fmt::format("{} 天 #过车过程记录保留天数, 默认730天, 20240601起", move_reserve).c_str(), pService->m_strIniPath);
  879. static bool bExec_rm_pass = true;
  880. COleDateTimeSpan dts_delete(move_reserve, 0, 0, 0);
  881. CString sql = "select name from sys.tables where name like 'rm_pass_%' ORDER BY name;";
  882. if (CDBConnectPool::Instance()->DBQuery(stmt, sql)) {
  883. char tablename[50];
  884. stmt.BindCharCol(1, tablename, sizeof(tablename));
  885. while (true)
  886. {
  887. memset(tablename, 0, sizeof(tablename));
  888. if (stmt.FetchNext() != 0) {
  889. break;
  890. }
  891. if (strlen(tablename) < 14)
  892. {
  893. assert(0);
  894. continue;
  895. }
  896. COleDateTime dd;
  897. try
  898. {
  899. int year, month;
  900. sscanf_s(tablename, "rm_pass_%04d%02d", &year, &month);
  901. dd = COleDateTime(year, month, 1, 0, 0, 0);
  902. }
  903. catch (const std::exception&)
  904. {
  905. assert(0);
  906. continue;
  907. }
  908. if (odt_now - dd > dts_delete)
  909. {
  910. sql.Format(" DROP TABLE %s ", tablename);
  911. CDBConnectPool::Instance()->DBExecuteSQL(sql);
  912. }
  913. else
  914. {
  915. if (bExec_rm_pass == false) break;
  916. //CString qq = CString("SELECT end_time FROM ") + tablename;
  917. //if (CDBConnectPool::Instance()->DBExecuteSQL(qq) == FALSE)
  918. //{
  919. // qq.Format("ALTER TABLE %s ADD end_time datetime null;", tablename);
  920. // CDBConnectPool::Instance()->DBExecuteSQL(qq);
  921. // qq.Format("UPDATE %s SET end_time = 0 where end_time is null;", tablename);
  922. // CDBConnectPool::Instance()->DBExecuteSQL(qq);
  923. //}
  924. //qq = CString("SELECT type FROM ") + tablename;
  925. //if (CDBConnectPool::Instance()->DBExecuteSQL(qq) == FALSE)
  926. //{
  927. // qq.Format("ALTER TABLE %s ADD type tinyint not null default(0);", tablename);
  928. // CDBConnectPool::Instance()->DBExecuteSQL(qq);
  929. // qq.Format("UPDATE %s SET type = 0 where type is null;", tablename);
  930. // CDBConnectPool::Instance()->DBExecuteSQL(qq);
  931. //}
  932. }
  933. }
  934. stmt.Close();
  935. bExec_rm_pass = false;
  936. }
  937. }
  938. ULARGE_INTEGER FreeBytesAvailableToCaller, TotalNumberOfBytes, TotalNumberOfFreeBytes;
  939. if (!GetDiskFreeSpaceEx("E:", &FreeBytesAvailableToCaller,
  940. &TotalNumberOfBytes, &TotalNumberOfFreeBytes))
  941. continue;
  942. auto dwCurLeftDisk = DWORD(FreeBytesAvailableToCaller.QuadPart >> 20);
  943. auto idle_reserve = ::GetPrivateProfileInt("SET", "idle_reserve", 20, pService->m_strIniPath);
  944. if (idle_reserve < 5) idle_reserve = 5;
  945. ::WritePrivateProfileStringA("SET", "idle_reserve", fmt::format("{} GB #E盘闲置空间, 默认20GB, 20230701起", idle_reserve).c_str(), pService->m_strIniPath);
  946. BOOL bClear = (dwCurLeftDisk < idle_reserve * 1024); BOOL bForceClear = (dwCurLeftDisk < 3 * 1024);
  947. auto resist_reserve = ::GetPrivateProfileInt("SET", "resist_reserve", 365, pService->m_strIniPath);
  948. if (resist_reserve < 30) resist_reserve = 30;
  949. ::WritePrivateProfileStringA("SET", "resist_reserve", fmt::format("{} 天 #阻力数据保留天数, 默认365天, 20230701起", resist_reserve).c_str(), pService->m_strIniPath);
  950. auto temp_reserve = ::GetPrivateProfileInt("SET", "temp_reserve", 365, pService->m_strIniPath);
  951. if (temp_reserve < 30) temp_reserve = 30;
  952. ::WritePrivateProfileStringA("SET", "temp_reserve", fmt::format("{} 天 #温湿度数据保留天数, 默认365天, 20230701起", temp_reserve).c_str(), pService->m_strIniPath);
  953. //删除365天前的数据
  954. if (bClear)
  955. {
  956. if (bForceClear) resist_reserve = resist_reserve / 2;
  957. COleDateTimeSpan dts_delete(resist_reserve, 0, 0, 0);
  958. COdbcStatement stmt;
  959. CString sql = "select name from sys.tables where name like 'rm_resistance_%' ORDER BY name;";
  960. if (CDBConnectPool::Instance()->DBQuery(stmt, sql)) {
  961. char tablename[50];
  962. stmt.BindCharCol(1, tablename, sizeof(tablename));
  963. while (true)
  964. {
  965. memset(tablename, 0, sizeof(tablename));
  966. if (stmt.FetchNext() != 0) {
  967. break;
  968. }
  969. if (strlen(tablename) < 22)
  970. {
  971. assert(0);
  972. continue;
  973. }
  974. COleDateTime dd;
  975. try
  976. {
  977. dd = COleDateTime(atoi(CString(tablename + 14, 4)), atoi(CString(tablename + 18, 2)), atoi(CString(tablename + 20, 2)), 0, 0, 0);
  978. }
  979. catch (const std::exception&)
  980. {
  981. assert(0);
  982. continue;
  983. }
  984. if (odt_now - dd > dts_delete)
  985. {
  986. sql.Format(" DROP TABLE [%s] ", tablename);
  987. CDBConnectPool::Instance()->DBExecuteSQL(sql);
  988. }
  989. else
  990. {
  991. break;
  992. }
  993. }
  994. }
  995. }
  996. //删除200天的数据
  997. if (bClear)
  998. {
  999. if (bForceClear) temp_reserve = temp_reserve / 2;
  1000. COleDateTimeSpan dts_delete(temp_reserve, 0, 0, 0);
  1001. COdbcStatement stmt;
  1002. CString sql = "select name from sys.tables where name like 'rm_temphumidity_%';";
  1003. if (CDBConnectPool::Instance()->DBQuery(stmt, sql)) {
  1004. char tablename[50];
  1005. stmt.BindCharCol(1, tablename, sizeof(tablename));
  1006. while (true)
  1007. {
  1008. memset(tablename, 0, sizeof(tablename));
  1009. if (stmt.FetchNext() != 0) {
  1010. break;
  1011. }
  1012. if (strlen(tablename) < 22)
  1013. {
  1014. assert(0);
  1015. continue;
  1016. }
  1017. COleDateTime dd;
  1018. try
  1019. {
  1020. auto a = atoi(CString(tablename + 16, 4));
  1021. auto b = atoi(CString(tablename + 20, 2));
  1022. dd = COleDateTime(atoi(CString(tablename + 16, 4)), atoi(CString(tablename + 20, 2)), 28, 0, 0, 0);
  1023. }
  1024. catch (const std::exception&)
  1025. {
  1026. assert(0);
  1027. continue;
  1028. }
  1029. if (odt_now - dd > dts_delete)
  1030. {
  1031. sql.Format(" DROP TABLE %s ", tablename);
  1032. CDBConnectPool::Instance()->DBExecuteSQL(sql);
  1033. }
  1034. else
  1035. {
  1036. break;
  1037. }
  1038. }
  1039. }
  1040. }
  1041. {
  1042. CTime ctTime(stNow);
  1043. CString sql;
  1044. sql.Format("DELETE rm_record WHERE time < %I64d", (ctTime - CTimeSpan(366, 0, 0, 0)).GetTime());
  1045. auto ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
  1046. }
  1047. //5小时检测一次
  1048. #ifdef _DEBUG
  1049. for (auto i = 0; i < 60; i++)
  1050. #else
  1051. for (auto i = 0; i < 18000; i++)
  1052. #endif // _DEBUG
  1053. if (pService->m_bWork)
  1054. Sleep(1);
  1055. else
  1056. goto l;
  1057. } while (pService->m_bWork);
  1058. l:
  1059. CSimpleLog::Info("ThreadProcCreateTable 线程结束!");
  1060. }
  1061. //获取E盘剩余容量,返回值以GB为单位
  1062. double Get_E_DiskRemainingSpace()
  1063. {
  1064. DWORD64 qwFreeBytes, qwFreeBytesTocaller, qwTotalBytes;
  1065. GetDiskFreeSpaceEx(TEXT("e:"), (PULARGE_INTEGER)&qwFreeBytesTocaller, (PULARGE_INTEGER)&qwTotalBytes, (PULARGE_INTEGER)&qwFreeBytes);
  1066. double RemainingSpace = qwFreeBytes / 1024 / 1024 / 1024;
  1067. return RemainingSpace;
  1068. }
  1069. void CAppService::ThreadProcForSpace(DWORD_PTR param)
  1070. {
  1071. CAppService* pThis = (CAppService*)param;
  1072. //刚开始运行,停止一分钟
  1073. std::this_thread::sleep_for(std::chrono::seconds(20));
  1074. do
  1075. {
  1076. std::this_thread::sleep_for(std::chrono::milliseconds(950));
  1077. auto ttNow = chrono::system_clock::to_time_t(chrono::system_clock::now());
  1078. if (ttNow % pThis->m_nInterval) continue;
  1079. if (ttNow == pThis->m_tmLastSpaceTime) continue;
  1080. pThis->m_tmLastSpaceTime = ttNow;
  1081. auto e_disk_space = Get_E_DiskRemainingSpace();
  1082. if (e_disk_space < 100 && pThis->m_bWork)
  1083. {
  1084. auto json = R"({"cmd":"disk_alarm","code":200,"msg":"磁盘余量告警,还剩 )" + fmt::format("{:.1f}", e_disk_space) + " GB.\"}";
  1085. auto utf = ANSItoUTF8(json);
  1086. pThis->GetMgServer()->SendToAllClient(utf.c_str(), utf.length());
  1087. }
  1088. } while (pThis->m_bWork);
  1089. }
  1090. void CAppService::ThreadProcForTime(DWORD_PTR param)
  1091. {
  1092. CAppService* pThis = (CAppService*)param;
  1093. //刚开始运行,停止一分钟
  1094. std::this_thread::sleep_for(std::chrono::seconds(20));
  1095. do
  1096. {
  1097. std::this_thread::sleep_for(std::chrono::milliseconds(950));
  1098. auto ttNow = chrono::system_clock::to_time_t(chrono::system_clock::now());
  1099. if (ttNow == pThis->m_tmLastSyncTime) continue;
  1100. pThis->m_tmLastSyncTime = ttNow;
  1101. SYSTEMTIME st;
  1102. GetLocalTime(&st);
  1103. if (st.wHour == 0 && st.wMinute == 5 && st.wSecond == 0 && pThis->m_bWork) //每天0点5分, 下发时钟同步
  1104. pThis->GetHandle()->SendTimeAckToAllDevice();
  1105. } while (pThis->m_bWork);
  1106. }
  1107. //半小时同步一次
  1108. void CAppService::ThreadProcSync(DWORD_PTR param)
  1109. {
  1110. CAppService* pThis = (CAppService*)param;
  1111. //刚开始运行,停止一分钟
  1112. Sleep(3000);
  1113. do
  1114. {
  1115. Sleep(950);
  1116. auto ttNow = chrono::system_clock::to_time_t(chrono::system_clock::now());
  1117. if (ttNow - pThis->m_tmLastSyncSuper < pThis->m_nIntervalSync) continue;
  1118. pThis->m_tmLastSyncSuper = ttNow;
  1119. if (CSuperManager::Instance()->GetSuperNum() == 0)
  1120. break;
  1121. uint8_t* pack = nullptr; int len = 0;
  1122. //同步机构数据
  1123. auto packno = CMonitorObjectMng::Instance()->GeneralMoPack(&pack, &len);
  1124. if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_MO, false);
  1125. delete[] pack;
  1126. if (pThis->m_bWork == false)break;
  1127. Sleep(1000);
  1128. //同步设备数据
  1129. packno = CMonitorObjectMng::Instance()->GeneralMpPack(&pack, &len);
  1130. if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_MP, false);
  1131. delete[] pack;
  1132. if (pThis->m_bWork == false)break;
  1133. Sleep(1000);
  1134. //同步svg数据
  1135. if (pThis->m_index % 10 == 0)
  1136. {
  1137. CFileFind filefind;
  1138. string filePath = g_strExepath + "svg\\*.svg";
  1139. bool bFind = filefind.FindFile(filePath.c_str());
  1140. while (bFind) {
  1141. bFind = filefind.FindNextFile();
  1142. CString strFilenName = filefind.GetFileName();//含后缀
  1143. auto strTitle = filefind.GetFileTitle(); //不含后缀
  1144. auto filelen = filefind.GetLength(); //文件长度
  1145. auto strFilePath = filefind.GetFilePath();//全部路径
  1146. auto new_len = sizeof(HJDATAHEAD2) + 2 + 64 + filelen;
  1147. pack = new uint8_t[new_len];
  1148. memset(pack, 0, new_len);
  1149. auto pData = pack + sizeof(HJDATAHEAD2);
  1150. strcpy_s((char*)pData, 50, (char*)(LPCSTR)strTitle);
  1151. CFile file;
  1152. if (file.Open(strFilePath, CFile::modeRead | CFile::typeBinary) == FALSE)
  1153. {
  1154. SPDLOG_ERROR("打开文件{}失败", strFilePath);
  1155. }
  1156. else
  1157. {
  1158. file.Read(pData + 64, filelen);
  1159. file.Close();
  1160. packno = pThis->GetPackNo();
  1161. auto send_len = CHjDataConver::conver_sendpack(pack, pData, 64 + filelen, 0, packno, E_ZL_PROTOCAL::ZL_SVG,
  1162. OR_DATA_INFO(0, 0, 1, 2, OPT_TYPE::OPT_SYNC));
  1163. if (packno) CSuperManager::Instance()->SendPack(pack, send_len, packno, E_ZL_PROTOCAL::ZL_SVG, FALSE);
  1164. SPDLOG_INFO("发送SVG:{} packno:{}) len:{}", strFilePath, packno, send_len);
  1165. }
  1166. delete[] pack;
  1167. pack = nullptr;
  1168. Sleep(5000);
  1169. if (pThis->m_bWork == false)break;
  1170. }
  1171. filefind.Close();
  1172. Sleep(100);
  1173. }
  1174. //同步refer数据
  1175. if (pThis->m_index % 10 == 0)
  1176. {
  1177. CFileFind filefind;
  1178. string filePath = g_strExepath + "refer\\*.json";
  1179. bool bFind = filefind.FindFile(filePath.c_str());
  1180. while (bFind) {
  1181. bFind = filefind.FindNextFile();
  1182. CString strFilenName = filefind.GetFileName();//含后缀
  1183. auto strTitle = filefind.GetFileTitle(); //不含后缀
  1184. auto filelen = filefind.GetLength(); //文件长度
  1185. auto strFilePath = filefind.GetFilePath();//全部路径
  1186. auto new_len = sizeof(HJDATAHEAD2) + 2 + 64 + filelen;
  1187. pack = new uint8_t[new_len];
  1188. memset(pack, 0, new_len);
  1189. auto pData = pack + sizeof(HJDATAHEAD2);
  1190. //CTime lastWriteTime;
  1191. //filefind.GetLastWriteTime(lastWriteTime);
  1192. //*(uint64_t*)(pData) = lastWriteTime.GetTime();
  1193. strcpy_s((char*)pData, 50, (char*)(LPCSTR)strTitle);
  1194. CFile file;
  1195. if (file.Open(strFilePath, CFile::modeRead | CFile::typeBinary) == FALSE)
  1196. {
  1197. SPDLOG_ERROR("打开文件{}失败", strFilePath);
  1198. }
  1199. else
  1200. {
  1201. file.Read(pData + 64, filelen);
  1202. file.Close();
  1203. packno = pThis->GetPackNo();
  1204. auto send_len = CHjDataConver::conver_sendpack(pack, pData, 64 + filelen, 0, packno, E_ZL_PROTOCAL::ZL_REFER,
  1205. OR_DATA_INFO(0, 0, 1, 2, OPT_TYPE::OPT_SYNC));
  1206. if (packno) CSuperManager::Instance()->SendPack(pack, send_len, packno, E_ZL_PROTOCAL::ZL_REFER, false);
  1207. }
  1208. delete[] pack;
  1209. pack = nullptr;
  1210. Sleep(1000);
  1211. if (pThis->m_bWork == false)break;
  1212. }
  1213. filefind.Close();
  1214. Sleep(100);
  1215. }
  1216. //同步扳动数据
  1217. packno = CAppService::GeneralMovePack(&pack, &len);
  1218. if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_MOVE, false);
  1219. delete[] pack;
  1220. pack = nullptr;
  1221. if (pThis->m_bWork == false)break;
  1222. Sleep(1000);
  1223. //同步报警设置
  1224. packno = CResistAlarmMng::Instance()->GeneralAlarmSet(&pack, &len);
  1225. if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_SET, false);
  1226. delete[] pack;
  1227. if (pThis->m_bWork == false)break;
  1228. Sleep(1000);
  1229. //同步未受理报警数据
  1230. packno = CResistAlarmMng::Instance()->GeneralUnAck(&pack, &len);
  1231. if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_UNACK, false);
  1232. delete[] pack;
  1233. if (pThis->m_bWork == false)break;
  1234. Sleep(1000);
  1235. pThis->m_index++;
  1236. } while (pThis->m_bWork);
  1237. }
  1238. CAppService CAppService::obj;
  1239. httplib::Server CAppService::m_svr10088;
  1240. httplib::Server CAppService::m_svr10087;
  1241. uint32_t CAppService::GeneralMovePack(uint8_t** pack, int* len)
  1242. {
  1243. #ifdef _DEBUG
  1244. string table_name = "rm_move_202405";
  1245. string strWhere = "";
  1246. #else
  1247. SYSTEMTIME st;
  1248. GetLocalTime(&st);
  1249. string table_name = fmt::format("rm_move_{:0>4}{:0>2}", st.wYear, st.wMonth);
  1250. string strWhere = " WHERE [show_time] > DATEADD(mi, -35, GETDATE())";
  1251. #endif // _DEBUG
  1252. CString sql = fmt::format("SELECT [mo],[mp],[show_time],[start_time],[end_time],[curr_val],[show_val],[idx],[posi],[mark],[type] FROM {} {}",
  1253. table_name, strWhere).c_str();
  1254. COdbcStatement stmt;
  1255. if (CDBConnectPool::Instance()->DBQuery(stmt, sql))
  1256. {
  1257. int nCol = 1;
  1258. int show_val, curr_val;
  1259. BYTE posi, idx, type;
  1260. char mo[20], mp[10], show_time[25], start_time[25], end_time[25], mark[50];
  1261. stmt.BindCharCol(nCol++, mo, sizeof(mo));
  1262. stmt.BindCharCol(nCol++, mp, sizeof(mp));
  1263. stmt.BindCharCol(nCol++, show_time, sizeof(show_time));
  1264. stmt.BindCharCol(nCol++, start_time, sizeof(start_time));
  1265. stmt.BindCharCol(nCol++, end_time, sizeof(end_time));
  1266. stmt.BindIntCol(nCol++, &curr_val);
  1267. stmt.BindIntCol(nCol++, &show_val);
  1268. stmt.BindTinyIntCol(nCol++, &idx);
  1269. stmt.BindTinyIntCol(nCol++, &posi);
  1270. stmt.BindCharCol(nCol++, mark, sizeof(mark));
  1271. stmt.BindTinyIntCol(nCol++, &type);
  1272. //组装数据
  1273. auto doc = yyjson_mut_doc_new(nullptr);
  1274. auto root = yyjson_mut_arr(doc);
  1275. yyjson_mut_doc_set_root(doc, root);
  1276. int num = 0;
  1277. while (true)
  1278. {
  1279. memset(mo, 0, sizeof(mo));
  1280. memset(mp, 0, sizeof(mp));
  1281. memset(show_time, 0, sizeof(show_time));
  1282. memset(start_time, 0, sizeof(start_time));
  1283. memset(end_time, 0, sizeof(end_time));
  1284. memset(mark, 0, sizeof(mark));
  1285. if (stmt.FetchNext() != 0)
  1286. break;
  1287. //添加数据
  1288. auto obj = yyjson_mut_obj(doc);
  1289. yyjson_mut_arr_add_val(root, obj);
  1290. yyjson_mut_obj_add_strcpy(doc, obj, "mo", mo);
  1291. yyjson_mut_obj_add_strcpy(doc, obj, "mp", mp);
  1292. yyjson_mut_obj_add_strcpy(doc, obj, "show_time", show_time);
  1293. yyjson_mut_obj_add_strcpy(doc, obj, "start_time", start_time);
  1294. yyjson_mut_obj_add_strcpy(doc, obj, "end_time", end_time);
  1295. yyjson_mut_obj_add_strcpy(doc, obj, "mark", mark);
  1296. yyjson_mut_obj_add_int(doc, obj, "curr_val", curr_val);
  1297. yyjson_mut_obj_add_int(doc, obj, "show_val", show_val);
  1298. yyjson_mut_obj_add_int(doc, obj, "idx", idx);
  1299. yyjson_mut_obj_add_int(doc, obj, "posi", posi);
  1300. yyjson_mut_obj_add_int(doc, obj, "type", type);
  1301. num++;
  1302. }
  1303. stmt.Close();
  1304. uint32_t no = 0;
  1305. if (num > 0)
  1306. {
  1307. size_t json_len;
  1308. auto json = yyjson_mut_write(doc, 0, &json_len);
  1309. *len = json_len + sizeof(HJDATAHEAD2) + 2;
  1310. *pack = new uint8_t[*len];
  1311. no = CAppService::Instance()->GetPackNo();
  1312. CHjDataConver::conver_sendpack(*pack, (LPBYTE)json, json_len, 0, no, E_ZL_PROTOCAL::ZL_MOVE,
  1313. OR_DATA_INFO(0, 0, 1, 2, OPT_TYPE::OPT_SYNC));
  1314. free(json);
  1315. }
  1316. yyjson_mut_doc_free(doc);
  1317. return no;
  1318. }
  1319. else
  1320. {
  1321. SPDLOG_ERROR("语句查询错误:{}", sql);
  1322. return 0;
  1323. }
  1324. }