编辑 | blame | 历史 | 原始文档


模块划分:

客户端:C --Qt开发界面--跨平台使用

统一的要求:
	功能结构体:
		请求结构体:
			数据头--固定
			数据体--不同模块,不一样
		
		响应结构体:
			数据头
			数据体 
			
		举例:
			enum TypeInfo
			{
				REGISTER_REQ,  // 注册请求
				REGISTER_RES,  // 注册响应
			};
			
			struct Head // 通用
			{
				int type;
				int len;
			};
		以注册为例:

			
			struct RegisterReq
			{
				Head head;
				
				char username[32];
				char password[32];
				char email[32];
				char tel[32];
				char department[32];
				
				RegisterReq()
				{
					head.type = REGISTER_REQ;
					head.len = sizeof(RegisterReq);
				}
			};
			
			struct RegisterRes
			{
				Head head;
				
				char username[32];
				int status;
				
				RegisterRes()
				{
					head.type = REGISTER_RES;
					head.len = sizeof(RegisterRes);
				}
			};

3星	1、注册登录
	注册:
		输入信息:用户名、密码、确认密码、邮箱、手机号、部门
		自动补充的信息:状态、注册时间、默认的权限--在服务端补充
		
		校验:客户端本地校验:用户名、密码、合法字符的判断
			   邮箱、手机号格式的判断、两次密码比较是否一样
			   
			   服务端二次校验:用户名、密码、合法字符的判断
			   服务端判断:用户名是否存在,不存在则写入[用户名唯一]
			   
		安全:密码加密的处理,防止明文传输和明文显示
			 加密算法:双向非对称加密 RSA 公钥--私钥:公钥加密,私钥解密
			 客户端:拿到公钥,加密,放到结构体里面传输密文
			 服务端:用私钥解密,得到密码明文
			 
		公钥、私钥的产生,是在服务端每次随机生成固定长度的一组密钥
			 将公钥发给对应的客户端,私钥在服务端留着用来解密密文
	
			原始内容:123456
				密钥:公钥 xxww99
			加密算法:(2个参数:原始内容,密钥-公钥) --> 返回计算结果:密文:x8sdsdsaxxxxadsadsadsadsda889e21ess
			
			密钥:私钥 uuyy84
			将密文发给另一端之后,解密算法(2个参数:密文,密钥-私钥)--> 明文:123456
			
	登录:
		输入信息:用户名、密码、验证码[可选]
		校验:客户端本地校验:用户名、密码、合法字符的判断
			  服务端二次校验:用户名、密码、合法字符的判断
		安全:密码加密的处理,防止明文传输和明文显示
		
		状态:成功--显示主界面--根据用户拥有的权限,来显示不同的子界面
			  失败--再次登录
			  
	UI美化:QSS样式美化
	--------------------------------------------
	数据库表:用户信息表、角色权限表
	---------------------------------------------
			 
				
	
5星 2、考勤识别、管理、异常处理
	考勤识别:
		AI识别,需要传入图片,将图片放到AI算法里面调用模型进行识别,返回所属的分类,通过分类ID获取数据库里面用户信息表中的用户信息,并且将信息展示到界面上。
		
		获取图片:打开摄像头--获取一张有人脸的照片
				   OpenCV库来打开摄像头并获取人脸照片
				   
				服务端识别:客户端上传图片到服务端,调用服务端AI算法,返回识别结果
				本地识别:需要在客户端机器上部署AI模型,将图片传入调用AI算法识别,拿到分类ID,再把ID发送给服务端,进行数据库查询,拿到查询结果,在客户端UI展示
				
		识别:成功--要记录人脸打开信息:考勤信息表--用户名[id]、考勤时间、考勤设备id
			  失败--提示失败
			  
	管理:
		查询--展示一个特定时间段的考勤统计结果
			  考勤判断:上班时间段--下班时间段
		忘打卡--补打卡次数: 5次/月
		
	异常处理:
		考勤异常:迟到、早退、缺勤、请假-[细分....]
		
		
		
		

4星 3、权限管理
	前提条件:管理员才能管理这个模块
	管理: 先查询到特定用户,再点开特定用户的权限信息,对权限勾选/去勾选,最后提交修改,保存到服务端是数据库
	
	界面:查询条件----用户名、工号、注册时间段、部门、邮箱、手机号等 
		  查询结果展示----用二维表视图展示[MVD]
		  右击菜单--选择特定用户--修改权限、禁用用户[修改状态]
		  修改权限----显示当前选定用户拥有的权限[勾选√],没有的权限不勾
					  修改的话,对选项勾选或去勾选之后,提交修改
					  
	权限:有就是1,无就是0
		admin 管理员 
		export 报表导出 
		log_search 日志查询 
		img_in  图像录入 
		map_mark_change 地图标注修改
		history 历史回放、历史查询
		warning_man 警报管理
		device_man 设备管理
		version_man 客户端版本管理
		
	数据库表: 
		id 角色名 具体的权限...【9个】
		

5星 4、客户端版本更新
	更新方式:增量更新、全量更新
	增量更新:逐版本更新
	全量更新:某个版本的完整更新,就是整个安装包
	
	更新逻辑:比较版本--最新[不更新]
					  --不是最新--更新--比较要要更新文件的大小--选择更新方式
					  
			   增量更新: 循环操作: 当前版本--找到下一个版本要更新的文件--下载--覆盖到客户端本地目录--完成更新--再接着比较版本...
			   
			   全量更新:下载最新版的完整安装包,安装到本地即可
			   
	核心:
		文件传输--大文件--要支持 断点续传--记录一些传输的信息--确认断点位置--续传
		
	数据库表: 版本信息表--读取
			id 当前版本号 依赖版本号[前置版本] 文件名 文件大小 文件MD5 文件S端路径 文件C端路径[相对路径] 状态 产生时间
			
			传输记录表[可选]
			
	界面: 更新进度展示:进度条、详细信息罗列...
		
	更新程序:和主程序要相互独立
			update.exe  client.exe 
			
	版本如何记录?
			配置文件来记录,可以是 version.ini 或 version.xml
			

3星 5、报表导出
		逻辑:提前数据[日志、历史...]--导出到文件: 文档、表格[csv,xlsx]、pdf
		、html--保存到本次磁盘
		
		一、提供接口,让别的模块传参调用
		二、用列表展示已经导出的记录,可预览相应的文件
		


5星 6、实时播放
		逻辑:客户端先获取所有可查看的摄像头信息,形成一个菜单配置[1-4-9-16-25]
			  然后在根据播放视图选择,组合菜单配置形成播放的实时画面
			  
			  播放:要给选好的画面连接,进行多线程的拉流处理--RTSP协议--FFmpeg
			  --拉流过来之后:解码形成图片--在标签上显示
			  
		数据库表: 
			摄像头信息--设备信息表--会包含每个摄像头的url[网址]
		
		数据流:H.265压缩内容,200倍的压缩比,要解压--解码 
			在三方库中已经完成了:FFmpeg库
			
		有2部分的东西:
		1、常规业务
			查询请求--拿到所有可用摄像头的信息
			请求:只需要指定结构体头里面的功能类型值就行
				struct RealtimeShowReq
				{
					Head head;
					RealtimeShowReq()
					{
						head.type = xx; // xx为提前定好的枚举变量
						head.len = sizeof(RealtimeShowReq);
					}
				};
				
			响应:回一个摄像头信息[柔性数组]的响应
				struct VideoInfo
				{
					int id;
					char url[256]; // 拼接好的摄像头网址 协议://ip:port/1/last.ts
					// ...
				};
				
				struct RealtimeShowRes
				{
					Head head;
					VideoInfo vi[0]; // 柔性数组 
				};
			
		2、视频业务
			用FFmpeg去拉rtsp url的地址流数据过来,用FFmpeg来解压缩、解码就行
		
			
		
		
3星 7、系统设置
		客户端的设置:
			样式控制:字体、颜色、外观调整
			国际化的显示:中文、英文、法文...
			快捷键:
			自启动的服务:开机启动
			自动登录:要记录用户名、密码[加密记录]
			......
		
		如何生效:将配置信息保存到xml文件中,启动时加载设置
		

3星 8、日志查询
		查询条件:级别、时间段等
		
		显示结果:用表格显示[MVD的视图]、分页显示--分页算法-将结果分成更小的块来显示,提升性能
				1 2 3 ... 98 99 100  跳转__页[下拉框/编辑框]
				
		导出:调用报表导出接口
		
		
4星 9、图像录入
		用于训练模型,每个新员工都需要采集一些特定数量的图片来训练,训练完了之后,用于识别--考勤等
		
		逻辑:客户端--先把要录入的员工工号输入--确认工号信息正确--再点开摄像头--获取该员工特定数量、视角的照片--上传到服务端特定目录下保存--用于模型训练
		
		界面: 
			通过输入工号--获取员工信息--显示--通过操作员判断正确否
			点一下录入按钮:就会提示分别路哪些视角:正脸、侧脸、眨眼、张嘴等
						每个录完之后,用标签显示一下录到的照片--预览
			确认无误--提交--上传到服务器特定工号目录保存--同时记录到数据库表
			
		数据库表:图片信息表:id、图片名字、路径、所属工号、上传时间、是否已训练...
		
		
5星 10、地图标注-摄像头、设备
		特殊的地方:编译器得使用MSVC的编译器,才能支持浏览器的绘制
					通过绘制的浏览器,加载百度在线地图
		标注:设备的坐标[经度、纬度],设备名称、编号、状态等显示出来
		
		核心:
			QT 和 网页的JS要交互,使用信号槽来交互
			用到的技术 webchannal.js 
			需要额外掌握:HTML、JS代码的编写 [会C/C++,必然能秒懂]
			
		逻辑: 
			显示地图的标注点--去查询设备的经纬度--拿到所有可用设备经纬度--标记到网页地图里
			
			修改标注点:改状态、改名字、调整经纬度等
			
		数据库表: 
			设备信息表  要经度、维度 名字 id 状态 等
			


5星 11、历史回放、历史数据查询分析
		历史回放 -- 回放的是视频内容
			查询特定时间段、特定设备类型、编号---拿到了特定时间段内的视频文件url
			----使用FFmpeg对【RTSP】url 进行拉流--解码显示
			
			操作:
				截图--保存某一帧图片
				快进、后退、暂停、播放等控制视频的操作
		
		历史数据查询分析 -- 查看的是环境信息的历史数据
			需要指定查询条件--时间段、设备等--拿到历史数据--展示到二维表
			--分析[日、周、月、年]:最小值、最大值、平均值、中位数--形成图形、曲线
			--用到QChart库,或者三分库 QCustomPlot来显示更多数据量的图形
		
		结构体里面如何表示内容每次查询都不一样,但是都能拿到:用不定长结构体[柔性数组]
		
		数据库表: 视频信息表、环境信息表......
	
5星 12、实时环境信息展示
		逻辑: 得用一个大屏来实时显示环境信息
			分不同区域来显示,还可以显示别的数据到大屏里面来
			主要是环境信息[温度、湿度、粉尘浓度、施工进度等]
			其他信息:看一下小地图、看一下考勤情况、动态切换一下监控摄像头情况
					  跟具体模块负责人对接,要接口就行
			
		实时环境信息:现场的各种传感器采集而来
					 测试环境--可以模拟数据发送过来
		
		实时信息:通过硬件上传数据之后,到服务端了,给所有在线的客户端转发的
		
		数据库表: 环境信息表:id 设备id 温度 适度 粉尘浓度 
				   施工进度表:id 施工类型 预计工作量  当前完成量  时间 ...
				   
		真假实时:转发为真,轮询为假
		
		
4星 13、警报管理
		针对哪些做出警报的判断?
			温度、湿度、粉尘浓度、施工进度等
			
		要对特定指标进行阈值的管理:可以动态调整阈值--最大、最小值 
		
		发生了警报,怎么处理?
			1、预警--硬件端先触发声、光警报,接着软件部分会给所有在线客户端提示预警信息
			2、解决--控制现场设备,自动调节--失败了--给值班室派单--解决问题
		
		数据库表: 
			阈值信息表、警报信息表
			
		界面: 
			管理阈值的界面--先查询-再修改 
			显示警报的界面--要在主窗口中,所有子模块都能同时看见的位置显示
		
		如何触发:
			数据到了服务端之后,除了实时转发的操作,还要一个预警判断的操作
				发生异常了,同时记录到警报信息表,且给所有在线客户端转发警报提示
			
			
3星 14、设备管理
		设备:摄像头、硬盘录像机、各种工地的设备[资产管理的]
		对设备进行增删改查
		添加:新设备--录入信息--对于外露固定位置的设备,要有安装位置的经纬度
		
		删除:修改设备状态--废弃、不可用、维修、正常
		改:修改已经录入的信息
		查询:查看都有哪些设备
		
		数据库表:设备信息表 
				id 设备类型 名字 序列号 状态 安装时间 经度 维度 负责人



服务端:S 

5星 1、网络搭建、TCP、UDP实现
		确定并发量:1000--5000的并发量来设置
		select + 线程池 
		最终的服务端:在linux平台下运行--Ubuntu 20.3--也可以使用epoll来处理高并发
		
		解耦操作:
			把业务当任务处理,要写一个通用的任务类来表示不同的业务
			
		线程池的实现:先考虑使用C++实现--鸿蒙系统的线程池
		
		还需要确定的:
			1、每个用到网络的模块,要提交:请求结构体、响应结构体 
			2、要给每一个请求、响应结构体,分配枚举类型内容--type--用来区分不同的业务功能
			3、任务类可以使用模板来处理,结合业务抽象类[纯虚函数],定好统一当接口
			4、考虑使用高级的操作--设计模式的选择:工厂模式、观察者模式等
			
		协议相关:
			TCP--心跳检测、粘包处理
			RTSP[udp]--使用Live555框架来支撑rtsp服务即可--开源框架
	


4星 2、数据库搭建
		MySQL数据库--建库--建表
		建库:统一建一个库名: znwl_db
		建表:需要和每一个用到数据库的负责人--对接--要他们的数据库表--整合重复的内容--建表 
		SQL脚本导出:完成建库、建表之后,要导出sql语句,形成一个脚本,其他人使用脚本,本地即可生成一个新的库、表 
		
		封装:提供接口,给其他人使用--作为子服务来使用的
			类--公有的接口--给他人调用
			接口:增删改查的操作--先以sql语句为参数--拿结果集或拿条数
				  升级v2:写一个类来组装sql语句,每一条语句,就是一个对象,较安全
				
				  安全校验:防注入校验--正则匹配
				
				 私有API:自动初始化使用的--实例化对象时,自动把数据库连上
		
		升级:数据库连接池--解决连接复用的问题
				
		备份导出:shell脚本--定时导出--打包--上传到指定的ftp服务器保存
		
		
3星 3、日志封装
		日志作用:用于问题定位的
		级别:常规、调试、警告、错误、致命等
		写到哪里? 文件、数据库表 
			文件:所有级别的记录 -- 超过指定大小之后-- 文件翻滚 -- 换一个文件继续记录 -- 实现文件翻滚算法
			
			数据库表: 警告、错误、致命等重要的级别的日志内容
		
		写日志:同步、异步的选择?---- 异步高效 -- 用队列来缓冲--记录任务
		
		封装:类--提供对应的接口--函数宏[跟级别挂钩]:只需要选择宏,给一个日志描述,其他的自动生成
		
		内容:
			id 级别 时间 日志描述 文件名 函数名 行号 等
			
			内容一式两份,一个写到文件,一个写到数据库表
		
		参考框架:
			log4c  log4cPlus等框架,仅作参考,还是要自己实现封装的功能
			

5星 4、CNN模型搭建
	作用:提供识别功能的模块,
		需要产生一个模型文件,通过训练的方式产生
		对传进来的图片,使用模型去快速匹配到相应的分类,从而实现AI的人脸识别功能
	
	CNN: 卷积神经网络算法:核心过程--卷积--池化--全连接
		 反向训练:随机梯度下降算法
		 
	搭建:神经网络--需要搭建很多层,逐层去计算并处理各种特征--图片特征--能最终快速找到分类--产生:训练好的模型
	
	训练:
		输入:一堆图片特征--都是处理过的图片
		输出:模型文件
	
	识别: 
		输入: 一张图片
			过程:将图片处理之后,去训练好的模型里面,匹配特征,找到分类,返回 
			
		输出: 这张图片对应的所属分类
	
	提供:
		模型文件 
		接口函数
		
	---------------------------------------------
	迁移学习:
		已经训练了一个模型了,再来新员工,如何加到模型里面去
		两种方案:一、加进来之后,重新全部再来一遍
				  二、加进来之后,在已有的基础上,进行二次训练--迁移
	---------------------------------------------
	细节:
		拟合问题:过拟合、欠拟合
		活体检测问题:3维成像效果--立体的方式
					  配合动作来识别
		-----------------------------------------
	技术:
		框架 TensorFlow--谷歌的开源框架
		
		真正的智能体,也就是所谓的通用AI,真正牛逼起来的时候:量子计算机量产的时候
		-----------------------------------------
	
	
	
4星 5、图像管理
		图像--人脸照片
					用来直接训练的图片--采集好的
					识别产生的单张照片--识别时保存的
					
		分类:用工号来作为子目录,保存每个员工的人脸照片
		什么时候创建子目录?
			注册成功的时候,产生了员工id,此时就可以触发--调用接口来创建子目录
		接口:传进来一个工号[字符串],会到图像根目录去创建这个工号子目录
		
		对于用于不同功能的图片,记录的时候,可以加上标志--训练否
		
		接口:删除已经无用的照片--不再用于训练的照片、有干扰的照片
	
		【是否要用界面显示对应子目录下的照片,并进行相应的操作--查询、修改】
	
4星 6、模型数据预处理
		处理的是照片,要把原始的照片--处理--变成矩阵特征
		处理方式:向量化、灰度化、二值化、浮点归一化、降噪等处理方式
		原理:图片中的每一个像素点,体现的都是RGB的颜色值 (255,255,255)
		使用的框架:OpenCV 
		
3星 7、配置管理
		作用:使得服务端,不需要再进行二次编码,特别是一些参数要变的时候:ip、port、路径......
		
		配置信息存放:xml文件来保存,如:config.xml 
		内容: 
			socket:ip、port 
			MySQL: host、user、password、db、port等
			log: 文件翻滚--大小限定,存放的路径、是否启动异步模式
			图片存放:根目录
			配置服务的启动方式:冷启动、热启动
			内容提供方式:饿汉=0、懒汉=1
			客户端文件版本存放:根目录
		
		解析库:tinyxml2    使用三方库的头文件和源文件就可以搞定
		
		提供内容的方式:
			在主函数中第一个加载起来
			饿汉式:一开始就全局所有的内容--可以使用全局变量来存储最新的内容
			懒汉式:需要时,再提供--提供函数接口,调用--返回结果
		
		启动方案:
			定时监控配置内容是否发生变化,变化了,要随时做出相应的重启服务
			定时监控:使用一条子线程,间隔10秒读一下xml配置文件和上一次的数据对比
					  有变化了,就按配置的方式启动
		
5星 8、客户端文件版本管理
		权限--版本管理权限
		获取版本号:查询到所有版本号,放到一个下拉框中展示
		添加已经变化的文件:-- 增量更新
			专门的UI界面:
				选择文件的本地路径
				版本号[规则],依赖版本号
				服务端的存放路径,客户端的存放路径
				二维表:点击添加文件之后,会将上述的内容,写到表格中
					当添加完所有变化的文件之后
					
					再点击提交按钮,上传到服务端,文件存到磁盘对应目录[服务端的存放路径],相应的信息写到数据库表
					
		技术:	文件上传、断点续传 
		文件打包:所有文件打包成一个安装包,作为全量更新的安装包
		
		数据库表:版本信息表--写入	
			
		
		
3星 9、视频存储管理
		先铺垫一下:视频文件在哪里?
		存在硬盘录像机里面
		
		摄像头--数据线--硬盘录像机[存视频文件]--软件服务端--MySQL数据库[存信息]
													|
												  客户端
												  
		管理视频文件:
			连上每一个硬盘录像机--查看对应的摄像头目录下都有哪些视频文件
			还可以调整一下摄像头对应的文件夹名字--默认是摄像头id
			
		动作:查询、修改 
			 增加--是摄像头的事情
			 
		[还可以加上UI来显示,操作会更加方便]
		
		设置覆盖周期:只会保存多久的视频--30天、60天...
		设置每个视频文件的时长:5min,10min......
			
		品牌:
			海康威视、大华、宇视科技等[全国前三]

4星 10、活体检测处理
4星 11、推送、通知管理
		本质:群发,给所有在线的客户端群发的
		什么时候发? 有新通知的时候,群发 
			群发之后,要记录每一个已经发过的账号信息
			如果后面在登录,要判断是否已经发过某一条通知,没发过的接着发,发过的不要再发了
			
		推送记录表:id、用户名、通知id、发送时间、状态
		通知信息表: id、通知标题、通知内容、创建时间、状态、用户id
		
		管理通知:
			增删改查 
			最好是用一个ui界面管理一下相关的通知
			
		保证所有登录成功的用户,都能收到一次最新的通知
		【参考邮件系统】
		
		通知:还可以有推送的记录,以及阅读的状态:未读、已读
			  
		

==================================================================================
		业务分离:只要是自己业务相关的,不管在客户端还是服务端,		  都要写代码去实现
		
		前后分离:分界线是:前端(客户端),后端(服务端)
				  前端只做前端的业务
				  后端只做后端的业务
				   前后的业务通信,需要商量好特定的格式
		---------------------------------------
		业务分离: 必须得2个端的开发语言一样
		
		前后分离: 2个端开发的语言不一样时,就得使用
		---------------------------------------
		现在的项目:采用业务分离的方式
==============================================================================================
		合代码的一些细节:
		
		1、客户端的代码合并
			A、保证所有模块使用同一个套接字,这样收包的时候,就统一在一个地方了
			
			B、模块对应的类名,一定要根据功能来命名,不允许使用默认的名字
			
			C、合代码的原则:尽量少修改的原则,只需要在主模块添加适当的代码为主
				子模块的功能保持不动
				
			D、合代码之后,保证原有的功能不会被修改,且不影响其他模块的使用
			
		
		
		2、服务端的代码合并
			A、自己的子服务模块要先合并好,是一种被动调用的方式
			
			B、客户端的业务要合到服务端来时,要用类的方式来合并[xx.h,xx.cpp]