{"id":24881830,"url":"https://github.com/404name/face-check-in-system","last_synced_at":"2025-10-16T00:31:26.076Z","repository":{"id":45824874,"uuid":"398954797","full_name":"404name/face-check-in-system","owner":"404name","description":"基于springboot + jpa + Erupt后台框架开发的综合签到打卡系统，支持人脸识别（百度云），指纹识别（本地指纹仪+websocket），签到数据展示，签到情况微信推送；支持docker-compose一键部署","archived":false,"fork":false,"pushed_at":"2023-04-29T08:50:45.000Z","size":2293,"stargazers_count":17,"open_issues_count":1,"forks_count":10,"subscribers_count":3,"default_branch":"main","last_synced_at":"2023-04-29T10:19:25.396Z","etag":null,"topics":["erupt","java"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/404name.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-08-23T02:49:57.000Z","updated_at":"2023-04-29T08:59:17.000Z","dependencies_parsed_at":"2022-08-19T14:41:34.803Z","dependency_job_id":null,"html_url":"https://github.com/404name/face-check-in-system","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/404name%2Fface-check-in-system","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/404name%2Fface-check-in-system/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/404name%2Fface-check-in-system/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/404name%2Fface-check-in-system/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/404name","download_url":"https://codeload.github.com/404name/face-check-in-system/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":236657994,"owners_count":19184581,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["erupt","java"],"created_at":"2025-02-01T12:13:49.785Z","updated_at":"2025-10-16T00:31:24.731Z","avatar_url":"https://github.com/404name.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003e **2023年4月21日21:06:13** 修复部分bug \u0026 重构补全前端源码\n![12345 (1)](https://user-images.githubusercontent.com/56631419/233643370-873b3fec-122c-4077-a50f-9a25115c8736.gif)\n\n\n# 快速开始\n\u003e 默认账号\n- 管理员 admin admin\n- 默认人脸(手机找个照片然后对着电脑就行)[王思聪、蔡徐坤、马云]\n\n\u003e 项目页面\n1. 管理员界面 http://localhost:8080\n2. 客户端界面 http://localhost:8080/front.html\n3. swagger接口界面 http://localhost:8080/swagger-ui.html#/\n\n\u003e 项目启动\n1. 创建数据库face_sign_in并导入/src/face_sign_in.sql\n2. 修改/src/main/resources/application-dev.yml里面的配置\n3. 对于idea需要配置lombok插件\u0026jdk1.8 | project structure里面level设置成8及以上\n4. 使用idea maven 刷新后右上角启动即可\n\n\u003e 功能使用\n1. 注册人脸：先创建新用户再前往录入界面录入(不能太模糊，也可以使用明星的照片)\n2. 更新人脸：选择已经录入的人脸然后覆盖\n3. 录入访客：后端管理界面手动录入或者excel导入\n4. 推送手机：前往http://pushplus.hxtrip.com/send配置对应的key，去后端管理配置出覆盖\n5. 百度人脸识别：本项目已经接入了我的百度人脸库，如需要自己创建，前往百度控制中心申请覆盖application的配置\n\n\u003e 项目开发\n1. 后端基于erupt框架\n2. 后端管理页面也基于erupt框架自动生成，开发请前往erupt官网阅读文档\n3. 客户端基于uniapp开发，源码打包发布在项目的release里面，将项目导入hbuilder即可直接点击运行，打包后将产物覆盖front文件夹即可\n\n\n# 一 、项目背景及需求分析\n\n\u003e [docker-compose一键部署](https://github.com/404name/face-check-in-system/releases/tag/1.0.0)（仅需下载docker-compose文件夹运行即可）\n\n\u003e 用户在可靠验证下实现简化身份确认\n\n在已有用户数据库基础上\u003cbr /\u003e**传统校验方式：**\n\n1. 直接选择                            ==》 用户 【不安全/不可靠】\n1. 用户名 + 密码 查询数据库 ==》 用户 【麻烦/】\n\n**新型校验方式**\n\n3. 第三方工具、qq/微信扫码 ==》 用户 【没手机时麻烦/不稳定】\n3. 生物特征人脸/指纹识别     ==》 用户 【方便/可靠】\n\n因此基于各家人脸识别框架，选用百度作为接口，围绕其开发此系统；\u003cbr /\u003e![动画.gif](https://cdn.nlark.com/yuque/0/2021/gif/21375831/1629635877393-efa7b1b0-5747-48c8-9539-d9586e479687.gif#clientId=u07d94e27-5409-4\u0026from=drop\u0026id=u41487a33\u0026margin=%5Bobject%20Object%5D\u0026name=%E5%8A%A8%E7%94%BB.gif\u0026originHeight=999\u0026originWidth=1909\u0026originalType=binary\u0026ratio=1\u0026size=1955400\u0026status=done\u0026style=none\u0026taskId=ue5f526a0-8b47-4590-a7c4-60f98f434d8)\u003cbr /\u003e![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629634914296-d0aeb593-56d8-4770-b208-75f52a4690b1.png#clientId=u07d94e27-5409-4\u0026from=paste\u0026id=uf7d21185\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=796\u0026originWidth=1107\u0026originalType=binary\u0026ratio=1\u0026size=671170\u0026status=done\u0026style=none\u0026taskId=ua5c45493-eeb7-45cd-b6b5-f0f8040375e)\n\u003ca name=\"Bm8He\"\u003e\u003c/a\u003e\n\n## ![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629635090716-e2835bc5-395d-4310-bf52-2e36e524c201.png#clientId=u07d94e27-5409-4\u0026from=paste\u0026id=uba50dfaf\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=902\u0026originWidth=1393\u0026originalType=binary\u0026ratio=1\u0026size=302828\u0026status=done\u0026style=none\u0026taskId=u5f4b8529-c6a4-41ee-8d47-acd553fae16)\n\n\u003ca name=\"aw48V\"\u003e\u003c/a\u003e\n\n## ![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629634588232-83fcbedc-78d5-40e6-8578-ad4520b71283.png#clientId=u07d94e27-5409-4\u0026from=paste\u0026id=u52a93c42\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=1024\u0026originWidth=1915\u0026originalType=binary\u0026ratio=1\u0026size=134691\u0026status=done\u0026style=none\u0026taskId=uc99e688e-123b-41b9-a28b-b77367269c0)\n\n![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629634660648-0443dc4b-19d0-432b-91e0-8dcc42f2e45a.png#clientId=u07d94e27-5409-4\u0026from=paste\u0026id=u01a7811e\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=891\u0026originWidth=1656\u0026originalType=binary\u0026ratio=1\u0026size=183209\u0026status=done\u0026style=none\u0026taskId=u344903c1-9d96-4d87-8c0b-059872f030c)\n\u003ca name=\"yn8xY\"\u003e\u003c/a\u003e\n\n# ![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629634701825-6cc32e27-e915-42ba-98e1-5d548ef9fded.png#clientId=u07d94e27-5409-4\u0026from=paste\u0026id=u42f45da9\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=950\u0026originWidth=1923\u0026originalType=binary\u0026ratio=1\u0026size=167276\u0026status=done\u0026style=none\u0026taskId=u6b0c2935-54b0-4628-834a-680a85317f9)\n\n\u003ca name=\"T1Gdr\"\u003e\u003c/a\u003e\n\n# 二、技术栈\n\n\u003e 这是一个前后端兼备的前后台分离全栈项目\n\n- 前台上，PC端选择用主流Vue框架[另一位同学完成]、后台管理采用Erupt框架搭建、web显示采用百度Amis框架及bootstrap完成\n\n\u003cbr /\u003e\n\n- 后端选用主流的Java SpringBoot搭建，使用Schedule完成动态定时任务，使用AOP拦截消息通过pushPlus进行微信推送。\n\n\u003cbr /\u003e\n\n- 其他技术，后台管理依靠框架Erupt进行的快速构建，使用swagger集成api文档。采用百度云人脸识别接口基于百度人脸识别SDK完成本地数据库与云人脸库的对接。\n\n\u003cbr /\u003e\n\n- 此外，为了保障访问的稳定及速率，采用redis对首页常用信息进行缓存，减少了对数据库的查询；采用视图构建表间关系，减少后台对数据库的连表查询，加速响应时间。\n  \u003ca name=\"XS8OG\"\u003e\u003c/a\u003e\n\n# 三、模块介绍\n\n```basic\n【name404.study.face】文件结构\n│  FaceApplication.java\n│\n├─aop                自定义注解实现标记切割\n│      LogAspect.java\n│      WxPush.java\n│\n├─common             公共包、存放公共文件 \n├─config             配置包\n│      CompleteScheduleConfig.java\n│      RedisConfig.java\n│      Swagger2.java\n│\n├─controllers        控制层\n│      FaceController.java\n│      RouteController.java\n│      SignInController.java\n│      UserContorller.java\n│      VisitorContorller.java\n│\n├─dao                Dao层\n│      GroupDao.java\n│      SignLogDao.java\n│      SignLogDetailDao.java\n│      SystemVariablesDao.java\n│      UserDao.java\n│      UserDetailDao.java\n│\n├─entity              数据层\n│      Group.java\n│      SignLog.java\n│      SignLogDetail.java\n│      SystemVariables.java\n│      User.java\n│      UserDetail.java\n│\n├─handler              handler层\n│      FetchHandlerImpl.java\n│      GlobalExceptionHandler.java\n│\n├─service              接口层  \n│  │  BaiduFaceService.java\n│  │  GroupService.java\n│  │  SignLogService.java\n│  │  SystemVariablesService.java\n│  │  UserService.java\n│  │  VisitorService.java\n│  │\n│  └─impl              接口实现层  \n│          BaiduFaceServiceImpl.java\n│          GroupServiceImpl.java\n│          SignLogServiceImpl.java\n│          SystemVariablesServiceImpl.java\n│          UserServiceImpl.java\n│          VisitorServiceImpl.java\n│\n└─utils              工具包\n        Base64Utils.java\n        OkHttpClientUtil.java\n        RedisUtil.java\n        Result.java\n```\n\n\u003ca name=\"y2k5U\"\u003e\u003c/a\u003e\n\n## ![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629633641537-dc066a52-e241-42e8-ad77-a6a893525400.png#clientId=u07d94e27-5409-4\u0026from=paste\u0026id=u1a04b213\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=739\u0026originWidth=936\u0026originalType=binary\u0026ratio=1\u0026size=242572\u0026status=done\u0026style=none\u0026taskId=u5d64a851-0243-48b9-86a1-8b4598a5c74)\n\n\u003ca name=\"qIyQE\"\u003e\u003c/a\u003e\n\n## 数据库模块\n\n\u003e 基础四个表：用户表、用户组别二级表、签到日志、系统变量(用户反馈可有可无)\n\n![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629639599030-a8bffa58-5271-40d3-9765-450f64d28ee3.png#clientId=u07d94e27-5409-4\u0026from=paste\u0026id=u31cd19c0\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=694\u0026originWidth=917\u0026originalType=binary\u0026ratio=1\u0026size=85075\u0026status=done\u0026style=none\u0026taskId=u1c35e0e1-a367-4316-b905-65e86eb46f2)\n\n\u003e 视图部分：使用userDetail + signLogDetail减少后台对数据库的连表查询\n\n数据库字段中存在大量引用[存在user_group二级分类菜单中]，直接返回的内容不方便使用，使用时连表查询，多次太费空间，因此基于视图一次性创建好引用，方便后台直接调用，加速后台响应\n\n```sql\nSELECT\n\t`sign_log`.`id` AS `id`,\n\t`sign_log`.`user_name` AS `user_name`,\n\t`sign_log`.`in_time` AS `in_time`,\n\t`sign_log`.`out_time` AS `out_time`,\n\t`sign_log`.`msg` AS `msg`,\n\t`sign_log`.`date` AS `date`,\n\t`a`.`name` AS `user_group`,\n\t`d`.`name` AS `to_do`,\n\t`b`.`name` AS `class_group`,\n\t`c`.`name` AS `unit_group`,\n\t`sign_log`.`sign_time` AS `sign_time` \nFROM\n\t((((\n\t\t\t\t\t`sign_log`\n\t\t\t\t\tLEFT JOIN `user_group` `a` ON ((\n\t\t\t\t\t\t\t`sign_log`.`user_group` = `a`.`id` \n\t\t\t\t\t\t)))\n\t\t\t\tLEFT JOIN `user_group` `b` ON ((\n\t\t\t\t\t\t`sign_log`.`class_group` = `b`.`id` \n\t\t\t\t\t)))\n\t\t\tLEFT JOIN `user_group` `c` ON ((\n\t\t\t\t\t`sign_log`.`unit_group` = `c`.`id` \n\t\t\t\t)))\n\t\tLEFT JOIN `user_group` `d` ON ((\n\t\t\t`sign_log`.`to_do` = `d`.`id` \n\t)))\n```\n\n![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629639808296-bd6cd8c0-10c3-4c6e-999a-028fb27e8445.png#clientId=u07d94e27-5409-4\u0026from=paste\u0026height=222\u0026id=u1fcf09d2\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=444\u0026originWidth=662\u0026originalType=binary\u0026ratio=1\u0026size=39590\u0026status=done\u0026style=none\u0026taskId=u70319419-8429-40dd-b80b-d2b80a92c94\u0026width=331)![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629639848571-ef812b92-4f6e-4047-a98d-b2e04cd9896b.png#clientId=u07d94e27-5409-4\u0026from=paste\u0026height=292\u0026id=ue1e624e9\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=584\u0026originWidth=460\u0026originalType=binary\u0026ratio=1\u0026size=31039\u0026status=done\u0026style=none\u0026taskId=u129869c2-e005-4c5a-a6d7-c0ab5e9f564\u0026width=230)\n\u003ca name=\"jvyFa\"\u003e\u003c/a\u003e\n\n## 1. 用户模块\n\n[UserService][UserDao]\n\n\u003e 用户基础服务\n\u003e [Dao层接口定义]\n\n**数据库设计**\n\n```sql\nDROP TABLE IF EXISTS `user`;\nCREATE TABLE `user`  (\n  `id` bigint(20) NOT NULL AUTO_INCREMENT,\n  `real_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,\n  `status` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '0',\n  `face_id` int(11) NULL DEFAULT NULL,\n  `user_group` int(11) NULL DEFAULT 5,\n  `now_sign_id` int(11) NULL DEFAULT NULL,\n  `email` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,\n  `telphone` int(11) NULL DEFAULT NULL,\n  `expired_time` datetime NULL DEFAULT NULL,\n  `sign_state` bit(1) NULL DEFAULT b'0',\n  `class_group` bigint(20) NULL DEFAULT 0,\n  `unit_group` bigint(20) NULL DEFAULT 0,\n  PRIMARY KEY (`id`) USING BTREE,\n  INDEX `FK5ixd8ou7x5sln7b00u8qpf7il`(`group_id`) USING BTREE,\n  CONSTRAINT `FK5ixd8ou7x5sln7b00u8qpf7il` FOREIGN KEY (`group_id`) REFERENCES `user_group` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT\n) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT;\n```\n\n**模块效果**\u003cbr /\u003e![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629640214805-810bc71f-0ef2-4073-9b16-fb6709465fcd.png#clientId=u07d94e27-5409-4\u0026from=paste\u0026id=u03b63f9f\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=533\u0026originWidth=1676\u0026originalType=binary\u0026ratio=1\u0026size=84446\u0026status=done\u0026style=none\u0026taskId=uf1f94efe-660c-4136-a38c-96d4b7b1b55)\u003cbr /\u003e**模块流程**\u003cbr /\u003e![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629641271069-f578d389-c010-484f-9192-dc5bcfdf0994.png#clientId=u07d94e27-5409-4\u0026from=paste\u0026height=607\u0026id=u5e1e5029\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=656\u0026originWidth=592\u0026originalType=binary\u0026ratio=1\u0026size=62184\u0026status=done\u0026style=none\u0026taskId=u451dbe8d-c5d0-48fb-867f-43c9f5cd106\u0026width=548)\u003cbr /\u003e\n\n\u003ca name=\"lGnCt\"\u003e\u003c/a\u003e\n\n## 2. 系统变量模块\n\n[SystemVariablesService][SystemVariablesDao]\n\n\u003e 系统变量服务\n\u003e [map存储复杂的系统变量]\n\u003e [通过key获取value的json]\n\u003e [通过对json修改实现变量增删改查]\n\u003e [简化数据库，方便统一处理常量]\n\n**数据库设计**\n\n```sql\n-- ----------------------------\n-- Table structure for system_variables\n-- ----------------------------\nDROP TABLE IF EXISTS `system_variables`;\nCREATE TABLE `system_variables`  (\n  `id` bigint(20) NOT NULL AUTO_INCREMENT,\n  `my_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,\n  `my_value` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,\n  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,\n  PRIMARY KEY (`id`) USING BTREE\n) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT;\n```\n\n**模块流程**\u003cbr /\u003e![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629643271681-4add6a37-2fdd-4065-a01a-5e61d2c83956.png#clientId=u07d94e27-5409-4\u0026from=paste\u0026height=227\u0026id=uc2405ea9\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=453\u0026originWidth=1219\u0026originalType=binary\u0026ratio=1\u0026size=74162\u0026status=done\u0026style=none\u0026taskId=u2bc30a8d-d5ab-4978-9c40-6cd1e1b016f\u0026width=609.5)\u003cbr /\u003e**模块效果**\u003cbr /\u003e![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629640263030-3188ef6a-d590-4fc5-9abe-166f5ef70e2d.png#clientId=u07d94e27-5409-4\u0026from=paste\u0026id=u1e93d4d0\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=681\u0026originWidth=1680\u0026originalType=binary\u0026ratio=1\u0026size=79098\u0026status=done\u0026style=none\u0026taskId=ufc13fa67-23f2-4cf3-904d-f87b168f2c0)\n\u003ca name=\"zwD8x\"\u003e\u003c/a\u003e\n\n## 3. 签到日志模块\n\n[SignLogService][SignLogDao]\n\n\u003e 签到日志服务\n\u003e [基本增删改查]\n\u003e [签到逻辑处理]\n\u003e [Dao层接口]\n\n**数据库设计**\n\n```sql\n-- ----------------------------\n-- Table structure for sign_log\n-- ----------------------------\nDROP TABLE IF EXISTS `sign_log`;\nCREATE TABLE `sign_log`  (\n  `id` bigint(20) NOT NULL AUTO_INCREMENT,\n  `user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,\n  `in_time` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,\n  `msg` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,\n  `out_time` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,\n  `sign_time` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,\n  `to_do` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,\n  `user_group` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,\n  `date` datetime NULL DEFAULT NULL,\n  `from_user_id` bigint(20) NULL DEFAULT NULL,\n  `user_class` bit(1) NULL DEFAULT NULL,\n  `class_group` bigint(20) NULL DEFAULT NULL,\n  `unit_group` bigint(20) NULL DEFAULT NULL,\n  PRIMARY KEY (`id`) USING BTREE\n) ENGINE = InnoDB AUTO_INCREMENT = 90 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT;\n```\n\n**模块流程**\u003cbr /\u003e![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629643031872-46947cd1-26f5-4c59-8938-bdba02db95ee.png#clientId=u07d94e27-5409-4\u0026from=paste\u0026height=615\u0026id=ud3793115\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=680\u0026originWidth=747\u0026originalType=binary\u0026ratio=1\u0026size=86228\u0026status=done\u0026style=none\u0026taskId=ufd548cf3-dd9b-4f4f-9f66-984c0848698\u0026width=676)\u003cbr /\u003e**​**\n\n**模块效果**\u003cbr /\u003e![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629640234717-5bc56a23-c1d7-4b98-9d24-f1dc0d3e0668.png#clientId=u07d94e27-5409-4\u0026from=paste\u0026id=ud2cb6d0a\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=786\u0026originWidth=1656\u0026originalType=binary\u0026ratio=1\u0026size=126445\u0026status=done\u0026style=none\u0026taskId=ucf0aee61-3326-4efc-9595-087ca3d8235)\n\u003ca name=\"qbQ0U\"\u003e\u003c/a\u003e\n\n## 4. 人脸识别模块+反馈模块\n\n[BaiduFaceService]\u003cbr /\u003e**模块流程**\u003cbr /\u003e![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629642857386-be951b78-1cee-4e96-aacd-9c321194b926.png#clientId=u07d94e27-5409-4\u0026from=paste\u0026height=230\u0026id=u31e24dd3\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=459\u0026originWidth=1086\u0026originalType=binary\u0026ratio=1\u0026size=68291\u0026status=done\u0026style=none\u0026taskId=u119260e2-f304-4aef-b5be-c88fd4c76bb\u0026width=543)\u003cbr /\u003e**​**\n\n**模块效果**\n\n\u003e 人脸识别服务\n\u003e [人脸库的增删改查]\n\u003e [人脸库对接本地数据库]\n\n\u003ca name=\"FrINs\"\u003e\u003c/a\u003e\n\n## 5. 二级菜单模块\n\n[GroupService]\n\n\u003e 对于一些杂乱的内容设置二级分类方便统一管理\n\n**数据库设计**\n\n```sql\n-- ----------------------------\n-- Table structure for user_group\n-- ----------------------------\nDROP TABLE IF EXISTS `user_group`;\nCREATE TABLE `user_group`  (\n  `id` bigint(20) NOT NULL AUTO_INCREMENT,\n  `group_class` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,\n  `message` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,\n  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,\n  PRIMARY KEY (`id`) USING BTREE\n) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT;\n```\n\n**模块流程**\u003cbr /\u003e![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629642738184-1889e736-cb4d-41bc-b741-ae63e418d4aa.png#clientId=u07d94e27-5409-4\u0026from=paste\u0026height=289\u0026id=u78b3a377\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=577\u0026originWidth=690\u0026originalType=binary\u0026ratio=1\u0026size=58399\u0026status=done\u0026style=none\u0026taskId=uac804e26-38b9-4ead-9a4e-4fcb7860667\u0026width=345)\u003cbr /\u003e**​**\n\n**模块效果**\u003cbr /\u003e![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629640307165-3ce9b3a0-f267-41d2-825b-bb5957bfc5ea.png#clientId=u07d94e27-5409-4\u0026from=paste\u0026id=uc27be1db\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=633\u0026originWidth=1679\u0026originalType=binary\u0026ratio=1\u0026size=71492\u0026status=done\u0026style=none\u0026taskId=u6abbf1e4-5146-418a-9331-e608211c932)\n\u003ca name=\"flIXa\"\u003e\u003c/a\u003e\n\n## 待开发模块\n\n指纹识别 + 游客模块\n\u003ca name=\"NNPDM\"\u003e\u003c/a\u003e\n\n# 四、技术点介绍\n\n\n\u003ca name=\"TnNbh\"\u003e\u003c/a\u003e\n\n## 1. 百度云人脸识别接入当前系统\n\n\u003e 注册百度云获取AppId ，API KEY Secret key作为密钥\n\n![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629679422656-84f01daa-dc0c-4a1a-849a-f9bb4eb43cb7.png#clientId=ub95780d4-61f9-4\u0026from=paste\u0026height=329\u0026id=ue69b4ccd\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=657\u0026originWidth=1652\u0026originalType=binary\u0026ratio=1\u0026size=58854\u0026status=done\u0026style=none\u0026taskId=u2f13cd4f-0da8-4bfe-8c54-70a8a1d1ef2\u0026width=826)\n\n\u003e 下载SDK对接用户数据库\n\u003e SDK和API区别\n\u003e API：直接面向接口提交http请求\n\u003e SDK：基于JAVA/PYTHON等语言集成一门API的通用函数库，方便直接调用对接\n\n![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629679632473-a401aba7-fed1-47cf-aa3d-e0618053f284.png#clientId=ub95780d4-61f9-4\u0026from=paste\u0026height=473\u0026id=u4ad7af0b\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=946\u0026originWidth=1211\u0026originalType=binary\u0026ratio=1\u0026size=140382\u0026status=done\u0026style=none\u0026taskId=u2b4f4bf1-bb92-42b3-bb90-b4e0aa5d790\u0026width=605.5)\n\n\u003e 引入jar包，初始化client，开始使用\n\n```java\nConfigurationProperties(prefix = \"baidu\")\npublic class BaiduFaceServiceImpl implements BaiduFaceService {\n    private String app_id;\n    private String api_key;\n    private String secret_key;\n    private  AipFace client = null;\n\n    void initClient(){\n        if(client == null){\n            System.out.println(\"初始化百度sdk\");\n            client = new AipFace(app_id, api_key, secret_key);\n        }\n    }\n    \n    ...\n}\n```\n\n\u003ca name=\"cq8HW\"\u003e\u003c/a\u003e\n\n## 2. 可动态修改的定时任务\n\n\u003e 怎么启动\n\n创建配置类\n\n\u003e @Configuration\n\u003e @EnableScheduling \n\u003e public class CompleteScheduleConfig implements SchedulingConfigurer\n\n\u003e 怎么动态：在执行定时任务下一次获取时间不是通过本地查询，而是通过数据库查询后后台拼接形成新的下一次时间\n\n```java\n@Configuration\n@EnableScheduling\npublic class CompleteScheduleConfig implements SchedulingConfigurer {\n\n    @Autowired\n    private SystemVariablesService systemVariablesService;\n    @Autowired\n    private SignLogService signLogService;\n    /**\n     * 执行定时任务.\n     */\n    @Override\n    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {\n        taskRegistrar.addTriggerTask(\n                //1.添加任务内容(Runnable)\n                () -\u003e {\n                    try {\n                        //调用签到模块的定时执行任务\n                        signLogService.scheduleTask();\n                    } catch (ParseException e) {\n                        e.printStackTrace();\n                    }\n                },\n                //2.设置执行周期(Trigger)\n                triggerContext -\u003e {\n                    //2.1 从数据库获取执行周期\n                    String time = systemVariablesService.getKey(SystemVariablesService.getEndTime);\n                    String[] HMS = time.split(\":\");\n                    String cron = HMS[2] + \" \" + HMS[1] +\" \" + HMS[0] +\" * * ?\";\n                    System.out.println(\"【下一次执行时间】\" + cron);\n                    //2.2 合法性校验.\n                    //2.3 返回执行周期(Date)\n                    return new CronTrigger(cron).nextExecutionTime(triggerContext);\n                }\n        );\n    }\n\n}\n```\n\n\u003ca name=\"NVIfO\"\u003e\u003c/a\u003e\n\n## 3. AOP切自定义注解实现微信推送 \n\n\u003e 导入AOP相关的包\n\n\u003e 创建注解作为标记点\n\n```java\nimport java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;//表示运行时开启@Retention(RetentionPolicy.RUNTIME)//表示定义在方法上@Target(ElementType.METHOD)public @interface WxPush {}\n```\n\n\u003e 创建APO层去切割WxPush方法\n\u003e 微信推送：使用pushplus提供的接口直接通过http请求发送\n\u003e\n\u003e 1. 获取自己微信token\n\u003e 1. 使用pushplus提供的接口\n\u003e 1. 通过http工具请求推送\n\n```java\n@Aspect@Componentpublic class LogAspect {    @Autowired    private SystemVariablesService systemVariablesService;    @Autowired    private SignLogService signLogService;    @Autowired    private OkHttpClientUtil okHttpClientUtil;    /**     * 注解切入点     */    @Pointcut(\"@annotation(name404.study.face.aop.WxPush)\")    public void pointCut(){    }\t    @AfterReturning(value = \"pointCut()\",returning = \"result\")    public void wxPush(Object result){        Result res = (Result)result;        //是成功的返回类型        if(res.getStatus() == 200){            // 根据返回结果进行微信推送            String title =\"【每日打卡消息】  当前：\" +toDayMsg.get(\"nowUser\") + \"人\";            String content = (String)res.getData();            content += \"\u003cbr/\u003e\u003cbr/\u003e\";            String startTime =systemVariablesService.getKey(SystemVariablesService.getStartTime);            String endTime = systemVariablesService.getKey(SystemVariablesService.getEndTime);            content += \"[今日打卡时间段] \" + startTime + \"-\" + endTime + \"\u003cbr/\u003e\u003cbr/\u003e\";            content += \"[今日总打卡数] \" +  toDayMsg.get(\"allUser\") + \"\u003cbr/\u003e\";            content += \"[今日当前人数] \" + toDayMsg.get(\"nowUser\") + \"\u003cbr/\u003e\";            content += \"[今日签退人数] \" + toDayMsg.get(\"leaveUser\") + \"\u003cbr/\u003e\";            String url = \"http://pushplus.hxtrip.com/send?token=\"+token+\"\u0026title=\"+title+\"\u0026content=\"+content+\"\u0026template=html\u0026topic=\"+groupId;            okHttpClientUtil.getData(url);        }    }}\n```\n\n\u003e 使用：直接在方法前加上@WxPush即可切割拦截进行结果集的推送了\n\n\u003ca name=\"mka9C\"\u003e\u003c/a\u003e\n\n## 4. 采用redis缓存首页信息优化访问速度\n\n\u003e 导入包导入工具类，创建bean引入配置\n\n```java\n\u003c!-- redis --\u003e\u003cdependency\u003e    \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e    \u003cartifactId\u003espring-boot-starter-data-redis\u003c/artifactId\u003e\u003c/dependency\u003e\n```\n\n\u003e 当作map直接使用提供好的工具包\n\n![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629689070244-cf6dca47-1366-4525-8917-6deb32f8cc71.png#clientId=ub95780d4-61f9-4\u0026from=paste\u0026height=203\u0026id=uc9bcff90\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=405\u0026originWidth=1136\u0026originalType=binary\u0026ratio=1\u0026size=273684\u0026status=done\u0026style=none\u0026taskId=u894bd356-c435-4600-b8d5-b191d82dd0a\u0026width=568)\n\n\u003e 类比mysql数据库\n\u003e 100 访问同一个页面获取100跳信息，要查询100次 100数据的数据库库，数据库承受1w次查询\n\u003e 用redis 第一次查数据库 后面只要信息不变全部查缓存 ，数据库只承受100次查询\n\n原理：\u003cbr /\u003e查：在查询数据库之前判断redisUtil里面存了首页信息没，有就直接返回\u003cbr /\u003e增：没有数据就查询数据库得到的信息存redis\u003cbr /\u003e改：每次数据库修改就清空redis缓存，下次查询就继续执行上面操作\n\u003ca name=\"WGa0g\"\u003e\u003c/a\u003e\n\n## 5. 采用swagger集成api统一访问管理\n\n\u003e 前后台分离\n\u003e 多人合作：jsp不可行，要采用前后台分离\n\u003e SSM：前台的数据一定要有后台先提供，导致开发工期延长\n\u003e 前后端分离：通过简单的数据包装，确保了视图和控制器的分离。只负责分发数据，谁拿不管。可以前后台同时进行，最后对接\n\n统一的数据管理平台 ==》 swagger ==》 方便前台用户阅读 使用\n\n\u003e 引入jar包\n\n```java\n\u003c!-- swagger --\u003e\u003cdependency\u003e    \u003cgroupId\u003eio.springfox\u003c/groupId\u003e    \u003cartifactId\u003espringfox-swagger-ui\u003c/artifactId\u003e    \u003cversion\u003e2.9.2\u003c/version\u003e\u003c/dependency\u003e\u003cdependency\u003e    \u003cgroupId\u003eio.springfox\u003c/groupId\u003e    \u003cartifactId\u003espringfox-swagger2\u003c/artifactId\u003e    \u003cversion\u003e2.9.2\u003c/version\u003e\u003c/dependency\u003e\n```\n\n\u003e 配置config \n\u003e 配置扫描包指定扫描那些controller\n\n```java\n@Configuration@EnableSwagger2//是否开启swagger，正式环境一般是需要关闭的（避免不必要的漏洞暴露！），可根据springboot的多环境配置进行设置@ConditionalOnProperty(name = \"swagger.enable\",  havingValue = \"true\")public class Swagger2 {     // swagger2的配置文件，这里可以配置swagger2的一些基本的内容，比如扫描的包等等     @Bean     public Docket createRestApi() {          return new Docket(DocumentationType.SWAGGER_2)                   .apiInfo(apiInfo())                   .select()                   // 为当前包路径                   .apis(RequestHandlerSelectors.basePackage(\"name404.study.face.controllers\")).paths(PathSelectors.any())                   .build();     }     // 构建 api文档的详细信息函数,注意这里的注解引用的是哪个     private ApiInfo apiInfo() {          return new ApiInfoBuilder()                   // 页面标题                   .title(\"Spring Boot 测试使用 Swagger2 构建RESTful API\")                   // 创建人信息                   .contact(new Contact(\"404name\",  \"yuque.com/404name\",  \"1308964967@qq.com\"))                   // 版本号                   .version(\"1.0\")                   // 描述                   .description(\"API 描述\")                   .build();     }\n```\n\n\u003e \u003cbr /\u003e\n\n![image.png](https://cdn.nlark.com/yuque/0/2021/png/21375831/1629689199976-7c791bb9-3aea-418c-8f05-3a8d78217e19.png#clientId=ub95780d4-61f9-4\u0026from=paste\u0026height=438\u0026id=u5f57a202\u0026margin=%5Bobject%20Object%5D\u0026name=image.png\u0026originHeight=876\u0026originWidth=1908\u0026originalType=binary\u0026ratio=1\u0026size=103990\u0026status=done\u0026style=none\u0026taskId=u1cf5958b-8916-4e63-a8a7-1347ab490aa\u0026width=954)\n\u003ca name=\"J0P7O\"\u003e\u003c/a\u003e\n\n# 五、 不足及后续开发计划\n\n\u003e 已完成基础框架，后台框架，swagger集成api\n\u003e 待开发如下。\n\n\u003ca name=\"YQ52t\"\u003e\u003c/a\u003e\n\n## 访客的接入\n\n- [x] 访客基础服务[增删改查]\n- [x] 访客对接进基础签到服务\n- [x] 访客的导入\n  \u003ca name=\"Svwli\"\u003e\u003c/a\u003e\n\n## 人脸识别模块\n\n- [x] 人脸识别基础服务[增删改查]\n- [ ] 人脸识别的批量导入[难实现，需要格外写算法处理]\n  \u003ca name=\"B2el1\"\u003e\u003c/a\u003e\n\n## 业务需求处理\n\n- [x] 动态增添单位、课题组、事由\n- [ ] 事由的固定处理[实验默认3小时，其他超过30分钟处理为xxx，未达0.5小时按0.5记录]\n- [x] 常见权限失效时间[直接在用户字段设置freeTime]\n- [ ] 可修改默认失效时间[在系统变量里面添加默认实现时间]\n  \u003ca name=\"CUJoa\"\u003e\u003c/a\u003e\n\n## 细节处理\n\n- [ ] 用户登录后提醒权限录入\n- [ ] 其他\n  \u003ca name=\"Bvjmb\"\u003e\u003c/a\u003e\n\n## 指纹识别接入\n\n- [ ] 未开发\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F404name%2Fface-check-in-system","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F404name%2Fface-check-in-system","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F404name%2Fface-check-in-system/lists"}