yanjinhui
2025-04-03 16faf0baa94bc0e5028233abb23ce5681a50b9dd
完成人脸识别功能
已删除12个文件
已修改6个文件
413 ■■■■ 文件已修改
项目代码/WIDESEAWCS_Server 正式/WIDESEAWCS_Common/BaiDuFaceHelper.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEAWCS_Server 正式/WIDESEAWCS_DTO/SerialPort/UserDTO.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEAWCS_Server 正式/WIDESEAWCS_ISystemServices/ISys_UserService.cs 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEAWCS_Server 正式/WIDESEAWCS_Model/LoginInfo.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEAWCS_Server 正式/WIDESEAWCS_Server/Controllers/System/Sys_UserController.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEAWCS_Server 正式/WIDESEAWCS_Server/wwwroot/image/20250402172104.jpg 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEAWCS_Server 正式/WIDESEAWCS_Server/wwwroot/image/51dcb60a86eb571dca49c55e983918b.jpg 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEAWCS_Server 正式/WIDESEAWCS_Server/wwwroot/image/Snipaste_2025-04-02_14-19-25.png 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEAWCS_Server 正式/WIDESEAWCS_Server/wwwroot/image/about.png 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEAWCS_Server 正式/WIDESEAWCS_Server/wwwroot/image/brand.png 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEAWCS_Server 正式/WIDESEAWCS_Server/wwwroot/image/car.png 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEAWCS_Server 正式/WIDESEAWCS_Server/wwwroot/image/files 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEAWCS_Server 正式/WIDESEAWCS_Server/wwwroot/image/honor.png 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEAWCS_Server 正式/WIDESEAWCS_Server/wwwroot/image/img1.png 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEAWCS_Server 正式/WIDESEAWCS_Server/wwwroot/image/logo.png 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEAWCS_Server 正式/WIDESEAWCS_Server/wwwroot/image/newLogo.png 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEAWCS_Server 正式/WIDESEAWCS_Server/wwwroot/image/微信图片_20250402172104.jpg 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEAWCS_Server 正式/WIDESEAWCS_SystemServices/Sys_UserService.cs 360 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ÏîÄ¿´úÂë/WIDESEAWCS_Server Õýʽ/WIDESEAWCS_Common/BaiDuFaceHelper.cs
@@ -229,17 +229,17 @@
        /// äººè„¸æœç´¢
        /// </summary>
        /// <returns></returns>
        public static SearchResult FaceSearch(string path)
        public static SearchResult FaceSearch(string path,string group_id_list)
        {
            string token = GetAccessToken();
            var imgbase64 = GetFileContentAsBase64(path);
            string host = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/face/delete?access_token=" + token;
            string host = "https://aip.baidubce.com/rest/2.0/face/v3/search?access_token=" + token;
            Encoding encoding = Encoding.Default;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(host);
            request.Method = "POST";
            request.KeepAlive = true;
            String str = "{\"image\":\"" + imgbase64 + "\",\"image_type\":\"BASE64\",\"group_id_list\":\"1\",\"quality_control\":\"LOW\",\"liveness_control\":\"NORMAL\"}";
            String str = "{\"image\":\"" + imgbase64 + "\",\"image_type\":\"BASE64\",\"group_id_list\":\""+ group_id_list + "\",\"quality_control\":\"LOW\",\"liveness_control\":\"NORMAL\"}";
            byte[] buffer = encoding.GetBytes(str);
            request.ContentLength = buffer.Length;
            request.GetRequestStream().Write(buffer, 0, buffer.Length);
@@ -355,6 +355,7 @@
        /// <summary>
        /// ç”¨æˆ·id(由数字、字母、下划线组成),长度限制48B
        /// </summary>
        //public string user_id { get; set;}
        public string user_id { get; set;}
        /// <summary>
        /// ç”¨æˆ·ç»„id(由数字、字母、下划线组成) é•¿åº¦é™åˆ¶48B,删除指定group_id中的user_id信息
ÏîÄ¿´úÂë/WIDESEAWCS_Server Õýʽ/WIDESEAWCS_DTO/SerialPort/UserDTO.cs
@@ -37,4 +37,6 @@
    }
}
ÏîÄ¿´úÂë/WIDESEAWCS_Server Õýʽ/WIDESEAWCS_ISystemServices/ISys_UserService.cs
@@ -80,8 +80,16 @@
        WebResponseContent UpuserData(AddUserDTO addUserDTO);
        WebResponseContent DeleteUserData(DeleteUserImg deleteUserDTO);
        WebResponseContent DeleteUserData(string userAccount);
        /// <summary>
        /// æ¸…理数据库中没有使用的图片
        /// </summary>
        /// <returns></returns>
        WebResponseContent CleanUnusedImages();
        WebResponseContent SaveFaceFiles(IFormCollection files);
    }
}
ÏîÄ¿´úÂë/WIDESEAWCS_Server Õýʽ/WIDESEAWCS_Model/LoginInfo.cs
@@ -16,5 +16,11 @@
        /// äººè„¸è¯†åˆ«
        /// </summary>
        public string? path {  get; set; }
        /// <summary>
        /// ç™¾åº¦äº‘分组face表中的Groupid
        /// </summary>
        //public string? groupid { get; set; }
    }
}
ÏîÄ¿´úÂë/WIDESEAWCS_Server Õýʽ/WIDESEAWCS_Server/Controllers/System/Sys_UserController.cs
@@ -224,9 +224,31 @@
        /// <param name="deleteUserDTO"></param>
        /// <returns></returns>
        [HttpPost, Route("DeleteUserData"), AllowAnonymous]
        public WebResponseContent DeleteUserData([FromBody] DeleteUserImg deleteUserDTO)
        public WebResponseContent DeleteUserData(string userAccount)
        {
            return Service.DeleteUserData(deleteUserDTO);
            return Service.DeleteUserData(userAccount);
        }
        /// <summary>
        /// ç™»å…¥åŽæ¸…除这次全部调用SaveFaceFiles方法的图片
        /// </summary>
        /// <returns></returns>
        [HttpGet,Route("CleanUnusedImages"),AllowAnonymous]
        public WebResponseContent CleanUnusedImages()
        {
            return Service.CleanUnusedImages();
        }
        /// <summary>
        ///人脸登入时调用该方法上传图片
        /// </summary>
        /// <param name="files"></param>
        /// <returns></returns>
        [HttpPost, Route("SaveFaceFiles"), AllowAnonymous]
        public WebResponseContent SaveFaceFiles(IFormCollection files)
        {
            return Service.SaveFaceFiles(files);
        }
    }
ÏîÄ¿´úÂë/WIDESEAWCS_Server Õýʽ/WIDESEAWCS_Server/wwwroot/image/20250402172104.jpg
Binary files differ
ÏîÄ¿´úÂë/WIDESEAWCS_Server Õýʽ/WIDESEAWCS_Server/wwwroot/image/51dcb60a86eb571dca49c55e983918b.jpg
Binary files differ
ÏîÄ¿´úÂë/WIDESEAWCS_Server Õýʽ/WIDESEAWCS_Server/wwwroot/image/Snipaste_2025-04-02_14-19-25.png
Binary files differ
ÏîÄ¿´úÂë/WIDESEAWCS_Server Õýʽ/WIDESEAWCS_Server/wwwroot/image/about.png
Binary files differ
ÏîÄ¿´úÂë/WIDESEAWCS_Server Õýʽ/WIDESEAWCS_Server/wwwroot/image/brand.png
Binary files differ
ÏîÄ¿´úÂë/WIDESEAWCS_Server Õýʽ/WIDESEAWCS_Server/wwwroot/image/car.png
Binary files differ
ÏîÄ¿´úÂë/WIDESEAWCS_Server Õýʽ/WIDESEAWCS_Server/wwwroot/image/files
Binary files differ
ÏîÄ¿´úÂë/WIDESEAWCS_Server Õýʽ/WIDESEAWCS_Server/wwwroot/image/honor.png
Binary files differ
ÏîÄ¿´úÂë/WIDESEAWCS_Server Õýʽ/WIDESEAWCS_Server/wwwroot/image/img1.png
Binary files differ
ÏîÄ¿´úÂë/WIDESEAWCS_Server Õýʽ/WIDESEAWCS_Server/wwwroot/image/logo.png
Binary files differ
ÏîÄ¿´úÂë/WIDESEAWCS_Server Õýʽ/WIDESEAWCS_Server/wwwroot/image/newLogo.png
Binary files differ
ÏîÄ¿´úÂë/WIDESEAWCS_Server Õýʽ/WIDESEAWCS_Server/wwwroot/image/΢ÐÅͼƬ_20250402172104.jpg
Binary files differ
ÏîÄ¿´úÂë/WIDESEAWCS_Server Õýʽ/WIDESEAWCS_SystemServices/Sys_UserService.cs
@@ -21,6 +21,7 @@
using WIDESEAWCS_Common;
using Newtonsoft.Json;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
using System.Security.Policy;
namespace WIDESEAWCS_SystemServices
{
@@ -50,14 +51,121 @@
        }
        //#region åŽŸæœ¬ç™»å…¥
        //public WebResponseContent Login(LoginInfo loginInfo)
        //{
        //    WebResponseContent content = new WebResponseContent();
        //    try
        //    {
        //        // BaseDal.QueryFirst(x => x.UserName == loginInfo.UserName);
        //        string msg = string.Empty;
        //        #region ä¸´æ—¶ä½¿ç”¨
        //        try
        //        {
        //            loginInfo.Password = loginInfo.Password.EncryptDES(AppSecret.User);
        //        }
        //        catch
        //        {
        //        }
        //        #endregion
        //        if (!string.IsNullOrEmpty(loginInfo.path))
        //        {
        //            var gruoid = _faceRecognitionRepository.QueryData().Select(x => x.GroupID).FirstOrDefault();
        //            if (gruoid == null)
        //            {
        //                return new WebResponseContent { Status = false, Message = "没找到该组" };
        //            }
        //            var faceResult = BaiDuFaceHelper.FaceSearch(loginInfo.path, gruoid);
        //            if (faceResult != null && faceResult.error_code == 0)
        //            {
        //                // èŽ·å–æœ€é«˜åŒ¹é…åº¦çš„ç”¨æˆ·
        //                var bestMatch = faceResult.result.user_list.OrderByDescending(u => u.score).FirstOrDefault();//拿第一个最高的
        //                if (bestMatch != null && double.TryParse(bestMatch.score, out double score) && score > 80) // è®¾å®š80分为可信度阈值
        //                {
        //                    //return new WebResponseContent {Status=true,Data = true,Message="识别登入成功" };
        //                }
        //            }
        //            return WebResponseContent.Instance.Error("人脸识别失败,请重试");
        //        }
        //        UserInfo user = BaseDal.GetUserInfo(loginInfo.UserName, loginInfo.Password);
        //        var disbled = BaseDal.QueryFirst(x => x.UserName == loginInfo.UserName);//根据这个用户名来查看用户
        //        if (user != null)
        //        {
        //            object obj = _menuService.GetMenuActionList(user.RoleId);
        //            if (obj is not IEnumerable<object> list)
        //            {
        //                return WebResponseContent.Instance.Error("无登录权限");
        //            }
        //            if (!list.Any())
        //            {
        //                return WebResponseContent.Instance.Error("无登录权限");
        //            }
        //            if (disbled.Enable != 1)
        //            {
        //                return WebResponseContent.Instance.Error("你的账号已被禁用,请联系管理员");
        //            }
        //            string token = JwtHelper.IssueJwt(new TokenModelJwt()
        //            {
        //                UserId = user.UserId,
        //                RoleId = user.RoleId,
        //                UserName = user.UserName,
        //                TenantId = user.TenantId,
        //            });
        //            //登入历史记录
        //            var loghis = new Dt_LoginHistory
        //            {
        //                Account = user.UserName,
        //                TrurName = user.UserTrueName,
        //                CreateDate = DateTime.Now
        //            };
        //            _cacheService.AddOrUpdate(user.UserId.ToString(), token);
        //            _loginHistoryRepository.AddData(loghis);
        //            content = WebResponseContent.Instance.OK(data: new { token, userName = user.UserTrueName, img = user.HeadImageUrl, ID = user.UserId, RoleId = user.RoleId });
        //        }
        //        else
        //        {
        //            content = WebResponseContent.Instance.Error("账号或密码错误");
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        content = WebResponseContent.Instance.Error(ex.Message);
        //    }
        //    return content;
        //}
        //#endregion
        /// <summary>
        /// äººè„¸è¯†åˆ«ç™»å…¥æŽ¥å£
        /// </summary>
        /// <param name="loginInfo"></param>
        /// <returns></returns>
        public WebResponseContent Login(LoginInfo loginInfo)
        {
            WebResponseContent content = new WebResponseContent();
            try
            {
                // BaseDal.QueryFirst(x => x.UserName == loginInfo.UserName);
                string msg = string.Empty;
                //string msg = string.Empty;
                #region ä¸´æ—¶ä½¿ç”¨
                try
@@ -66,46 +174,75 @@
                }
                catch
                {
                }
                #endregion
                // å…ˆèŽ·å–ç”¨æˆ·ä¿¡æ¯
                UserInfo user = null;
                if (!string.IsNullOrEmpty(loginInfo.path))
                {
                    var faceResult = BaiDuFaceHelper.FaceSearch(loginInfo.path);
                    if (faceResult != null && faceResult.error_code == 0)
                    // äººè„¸è¯†åˆ«ç™»å½•
                    var groupId = _faceRecognitionRepository.QueryData().Select(x => x.GroupID).FirstOrDefault();
                    if (groupId == null)
                    {
                        // èŽ·å–æœ€é«˜åŒ¹é…åº¦çš„ç”¨æˆ·
                        var bestMatch = faceResult.result.user_list.OrderByDescending(u => u.score).FirstOrDefault();//拿第一个最高的
                        if (bestMatch != null && double.TryParse(bestMatch.score, out double score) && score > 80) // è®¾å®š80分为可信度阈值
                        {
                            return new WebResponseContent { Data = true };
                        }
                        return WebResponseContent.Instance.Error("没找到该人脸识别分组");
                    }
                    return WebResponseContent.Instance.Error("人脸识别失败,请重试");
                    var faceResult = BaiDuFaceHelper.FaceSearch(loginInfo.path, groupId);
                    if (faceResult != null && faceResult.error_code == 0)
                    {
                        var bestMatch = faceResult.result.user_list.OrderByDescending(u => u.score).FirstOrDefault();
                        string usercount = bestMatch.user_id;
                        if (bestMatch != null && double.TryParse(bestMatch.score, out double score) && score > 80)
                        {
                            //用识别到的 user_id æ¥èŽ·å–ç”¨æˆ·ä¿¡æ¯
                            var faceuser = BaseDal.QueryData(x => x.UserName == usercount).FirstOrDefault(); // èŽ·å–åŒ¹é…çš„ç¬¬ä¸€ä¸ªç”¨æˆ·
                            if (faceuser != null)
                            {
                                // æ‰‹åЍ将 Sys_User æ˜ å°„到 UserInfo
                                user = new UserInfo
                                {
                                    UserId = faceuser.User_Id,
                                    UserName = faceuser.UserName,
                                    UserTrueName = faceuser.UserTrueName,
                                    HeadImageUrl = faceuser.HeadImageUrl,
                                    RoleId = faceuser.Role_Id,
                                    TenantId = faceuser.TenantId,
                                };
                            }
                        }
                        if (user == null)
                        {
                            return WebResponseContent.Instance.Error("人脸识别失败,请重试");
                        }
                        loginInfo.UserName = user.UserName;
                    }
                }
                else
                {
                    UserInfo user = BaseDal.GetUserInfo(loginInfo.UserName, loginInfo.Password);
                    var disbled = BaseDal.QueryFirst(x => x.UserName == loginInfo.UserName);//根据这个用户名来查看用户
                    // å¯†ç ç™»å½•
                    user = BaseDal.GetUserInfo(loginInfo.UserName, loginInfo.Password);
                }
                    // å¦‚果找到用户
                    if (user != null)
                    {
                        object obj = _menuService.GetMenuActionList(user.RoleId);
                        if (obj is not IEnumerable<object> list)
                        {
                            return WebResponseContent.Instance.Error("无登录权限");
                        }
                        if (!list.Any())
                        {
                            return WebResponseContent.Instance.Error("无登录权限");
                        }
                        var disbled = BaseDal.QueryFirst(x => x.UserName == loginInfo.UserName);
                        if (disbled.Enable != 1)
                        {
                            return WebResponseContent.Instance.Error("你的账号已被禁用,请联系管理员");
                        }
                        // èŽ·å–è§’è‰²æƒé™
                        object obj = _menuService.GetMenuActionList(user.RoleId);
                        if (obj is not IEnumerable<object> list || !list.Any())
                        {
                            return WebResponseContent.Instance.Error("无登录权限");
                        }
                        // ç”Ÿæˆ JWT Token
                        string token = JwtHelper.IssueJwt(new TokenModelJwt()
                        {
                            UserId = user.UserId,
@@ -113,27 +250,34 @@
                            UserName = user.UserName,
                            TenantId = user.TenantId,
                        });
                        // è®°å½•登录历史
                        var loghis = new Dt_LoginHistory
                        {
                            Account = user.UserName,
                            TrurName = user.UserTrueName,
                            CreateDate = DateTime.Now
                        };
                        // ä¿å­˜ç”¨æˆ·ç™»å½•信息
                        _cacheService.AddOrUpdate(user.UserId.ToString(), token);
                        _loginHistoryRepository.AddData(loghis);
                        content = WebResponseContent.Instance.OK(data: new { token, userName = user.UserTrueName, img = user.HeadImageUrl, ID = user.UserId, RoleId = user.RoleId });
                        // è¿”回响应
                        content = WebResponseContent.Instance.OK(data: new
                        {
                            token,
                            userName = user.UserTrueName,
                            img = user.HeadImageUrl,
                            ID = user.UserId,
                            RoleId = user.RoleId
                        });
                    }
                    else
                    {
                        content = WebResponseContent.Instance.Error("账号或密码错误");
                    }
                }
            }
            catch (Exception ex)
            {
                content = WebResponseContent.Instance.Error(ex.Message);
@@ -141,6 +285,9 @@
            return content;
        }
        public override WebResponseContent UpdateData(SaveModel saveModel)
        {
@@ -533,6 +680,11 @@
                    return new WebResponseContent { Status = false, Message = "请求数据为空,可能是 JSON è§£æžå¤±è´¥" };
                }
                var list = BaseDal.QueryData(a => a.UserName == addUserDTO.username).FirstOrDefault();
                if (list != null)
                {
                    return new WebResponseContent { Status = false, Message = "账号重复,请重新录入" };
                }
                var face = _faceRecognitionRepository.QueryData().Select(x => x.GroupID).FirstOrDefault(); ;
                var baiduResult = BaiDuFaceHelper.AddUser(new BDUserInfo
                {
@@ -587,45 +739,50 @@
        {
            try
            {
                // 1. æŸ¥è¯¢ç”¨æˆ·
                var sys = BaseDal.QueryData(x => x.User_Id == addUserDTO.id).FirstOrDefault();
                if (sys == null)
                {
                    return new WebResponseContent { Status = false, Message = "没找到该用户" };
                }
                var face = _faceRecognitionRepository.QueryData().Select(x => x.GroupID).FirstOrDefault();
                // åˆ¤æ–­æ˜¯å¦éœ€è¦æ›´æ–°äººè„¸å›¾ç‰‡
                // 2. æŸ¥è¯¢äººè„¸åº“分组 ID
                var faceGroupID = _faceRecognitionRepository.QueryData().Select(x => x.GroupID).FirstOrDefault();
                // 3. åˆ¤æ–­æ˜¯å¦éœ€è¦æ›´æ–°äººè„¸ä¿¡æ¯
                string faceToken = null;
                if (!string.IsNullOrEmpty(addUserDTO.path)) // å¦‚果传了图片路径,才更新人脸信息
                if (!string.IsNullOrEmpty(addUserDTO.path)) // åªæœ‰ä¼ äº†æ–°å›¾ç‰‡ï¼Œæ‰æ›´æ–°äººè„¸ä¿¡æ¯
                {
                    var baiduResult = BaiDuFaceHelper.AddUser(new BDUserInfo
                    {
                        ImgPath = addUserDTO.path,
                        user_id = addUserDTO.username,
                        group_id = face // è¿™é‡Œåº”该填百度人脸库分组
                        group_id = faceGroupID // è¿™é‡Œåº”该填百度人脸库分组
                    });
                    // åˆ¤æ–­ç™¾åº¦è¿”回是否成功
                    // 4. åˆ¤æ–­ç™¾åº¦ API æ˜¯å¦æˆåŠŸ
                    if (baiduResult == null || baiduResult.error_code != 0)
                    {
                        return new WebResponseContent { Status = false, Data = "人脸以存在,不要重复上传:" + baiduResult.error_msg };
                        return new WebResponseContent { Status = false, Message = "该图片也存在,不要重复上传:" + baiduResult.error_msg };
                    }
                    // èŽ·å–æ›´æ–°åŽçš„ Face_token
                    faceToken = baiduResult.result.face_token;
                    // æ›´æ–°æŸ¥è¯¢åˆ°çš„用户数据
                    sys.UserName = addUserDTO.username;
                    sys.UserTrueName = addUserDTO.usertruename;
                    sys.HeadImageUrl = addUserDTO.path; // æ›´æ–°å¤´åƒè·¯å¾„(如果有新路径)
                    // 5. åªæœ‰å½“上传了新图片并成功时,才更新这些字段
                    faceToken = baiduResult.result.face_token;
                    sys.Log_id = baiduResult.log_id;
                    //如果 faceToken ä¸æ˜¯ null,就把 faceToken èµ‹å€¼ç»™ sys.Face_token;否则,保持 sys.Face_token çš„原值不变。
                    sys.Face_token = faceToken ?? sys.Face_token;
                    sys.PhoneNo = addUserDTO.phoneno;
                    sys.Role_Id = addUserDTO.roleid;
                    sys.RoleName = addUserDTO.rolename;
                    sys.Enable = addUserDTO.enable;
                    // æ›´æ–°æ•°æ®åº“
                    BaseDal.UpdateData(sys);
                    sys.HeadImageUrl = addUserDTO.path;
                }
                // 6. æ›´æ–°ç”¨æˆ·å…¶ä»–信息
                sys.UserName = addUserDTO.username;
                sys.UserTrueName = addUserDTO.usertruename;
                sys.Face_token = faceToken ?? sys.Face_token; // åªæœ‰å½“ faceToken æœ‰å€¼æ—¶æ‰æ›´æ–°ï¼Œå¦åˆ™ä¿æŒåŽŸå€¼
                sys.PhoneNo = addUserDTO.phoneno;
                sys.Role_Id = addUserDTO.roleid;
                sys.RoleName = addUserDTO.rolename;
                sys.Enable = addUserDTO.enable;
                // 7. æ›´æ–°æ•°æ®åº“
                BaseDal.UpdateData(sys);
                return new WebResponseContent { Status = true, Data = sys };
            }
@@ -637,24 +794,32 @@
        /// <summary>
        /// åˆ é™¤
        /// </summary>
        /// <param name="deleteUserDTO"></param>
        /// <returns></returns>
        public WebResponseContent DeleteUserData(DeleteUserImg deleteUserDTO)
        public WebResponseContent DeleteUserData(string account)
        {
            try
            {
                string apiResult = BaiDuFaceHelper.DeleteUser(deleteUserDTO);//只要给token和log_id
                // 2. æŸ¥è¯¢äººè„¸åº“分组 ID
                var faceGroupID = _faceRecognitionRepository.QueryData().Select(x => x.GroupID).FirstOrDefault();
                WIDESEAWCS_Common.DeleteUserImg deleteUserImg = new WIDESEAWCS_Common.DeleteUserImg();
                deleteUserImg.group_id = faceGroupID;
                deleteUserImg.user_id = account;
                string apiResult = BaiDuFaceHelper.DeleteUser(deleteUserImg);//只要给token和log_id
                // 2. è§£æžè¿”回结果,判断删除是否成功
                dynamic resultObj = JsonConvert.DeserializeObject(apiResult);
                if (resultObj.error_code == 0)
                {
                   // ç™¾åº¦åˆ é™¤æˆåŠŸåŽï¼Œåˆ é™¤æ•°æ®åº“ä¸­çš„ç”¨æˆ·
                    var user = BaseDal.QueryData(deleteUserDTO.user_id);
                    var user = BaseDal.QueryData(x=>x.UserName== account);
                    if (user != null)
                    {
                        BaseDal.DeleteData(user);
@@ -673,7 +838,88 @@
        }
        public WebResponseContent SaveFaceFiles(IFormCollection files)
        {
            if (files == null || files.Files.Count == 0)
                return new WebResponseContent { Status = false, Message = "请上传文件" };
            // 1. ç¡®ä¿å­˜å‚¨ç›®å½•存在
            string baseDirectory = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "UploadfaceImage");
            if (!Directory.Exists(baseDirectory))
                Directory.CreateDirectory(baseDirectory);
            try
            {
                var file = files.Files[0]; // åªå¤„理第一个文件
                string fileName = file.FileName; // ç›´æŽ¥ä½¿ç”¨å‰ç«¯çš„æ–‡ä»¶å
                string fullFilePath = Path.Combine(baseDirectory, fileName);
                // 2. ä¿å­˜æ–‡ä»¶ï¼ˆå¦‚果存在,则覆盖)
                using (var stream = new FileStream(fullFilePath, FileMode.Create))
                {
                    file.CopyTo(stream);
                }
                // 3. è¿”回文件名
                return new WebResponseContent { Status = true, Message = "文件上传成功", Data = fileName };
            }
            catch (Exception ex)
            {
                return new WebResponseContent { Status = false, Message = "上传文件失败:" + ex.Message };
            }
        }
        /// <summary>
        /// åˆ é™¤æ•°æ®åº“中没有使用的图片
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public WebResponseContent CleanUnusedImages()
        {
            try
            {
                // èŽ·å–æ–‡ä»¶çš„å®Œæ•´è·¯å¾„
                string pathimage = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "UploadfaceImage");
                // å¦‚果文件夹不存在,返回错误信息
                if (!Directory.Exists(pathimage))
                {
                    return new WebResponseContent { Status = false, Message = "图片文件夹不存在" };
                }
                //获取数据库中所有的图片(排除为空) çŽ°åœ¨å›¾ç‰‡åªä¿å­˜äº†æ–‡ä»¶å
                var userImage = BaseDal.QueryData(x => !string.IsNullOrEmpty(x.HeadImageUrl)).Select(x => x.HeadImageUrl).ToList();
                //获取文件夹中所有的图片文件
                var imageFiles = Directory.GetFiles(pathimage).Select(Path.GetFileName).ToList();
                int deletedCount = 0;
                foreach (var file in imageFiles)
                {
                    if (!userImage.Contains(file))
                    {
                        string filePath = Path.Combine(pathimage, file);
                        try
                        {
                            File.Delete(filePath);
                            deletedCount++;
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine($"无法删除文件 {file}: {ex.Message}");
                        }
                    }
                }
                return new WebResponseContent { Status = true, Message = $"清理完成,删除了 {deletedCount} å¼ æœªä½¿ç”¨çš„图片" };
            }
            catch (Exception ex)
            {
                return new WebResponseContent { Status = false, Message = $"清理失败: {ex.Message}" };
            }
        }
    }
}