using EyeSoft.Collections.Generic; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using NPOI.SS.Formula.Functions; using NPOI.Util; using OASystem.API.OAMethodLib.DeepSeekAPI; using OASystem.API.OAMethodLib.GenericSearch; using OASystem.Domain.AesEncryption; using OASystem.Domain.Entities.Customer; using OASystem.Domain.Entities.Financial; using OASystem.Domain.Entities.Groups; using OASystem.Domain.ViewModels.Search; using OASystem.Infrastructure.Repositories.CRM; using OASystem.Infrastructure.Repositories.System; using static iTextSharp.text.pdf.AcroFields; namespace OASystem.API.Controllers { /// /// 搜索 /// [Route("api/search")] [ApiController] public class SearchController : ControllerBase { private readonly SqlSugarClient _sqlSugar; private readonly DynamicSearchService _groupSearchService; private readonly DynamicSearchService _clientSearchService; private readonly NewClientDataRepository _clientDataRepository; public SearchController( SqlSugarClient sqlSugar, DynamicSearchService groupSearchService, DynamicSearchService clientSearchService, NewClientDataRepository clientDataRepository ) { _sqlSugar = sqlSugar; _groupSearchService = groupSearchService; _clientSearchService = clientSearchService; _clientDataRepository = clientDataRepository; } /// /// 接团信息 关键字输入提示(单字段) /// /// 关键字 /// [HttpGet("group/{keyword}")] [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)] public async Task GroupKeywordSearch(string keyword) { try { // 验证请求参数 if (string.IsNullOrEmpty(keyword)) { return Ok(JsonView(true, $"暂无数据!")); } var searchRequest = new DynamicSearchRequest { Keyword = keyword, RequireAllSingleChars = true, PageIndex = 1, PageSize = 999999, FieldWeights = new Dictionary { { "TeamName", 10 }, //{ "ClientUnit", 8 }, //{ "ClientName", 6 } }, Filters = new List() { new(){Field = "IsDel",Operator="eq",Value="0" } }, OrderBy = "TeamName", ReturnFields = new List() { "TeamName" } }; // 验证字段配置 var validation = _groupSearchService.ValidateFieldConfig( searchRequest.FieldWeights, searchRequest.ReturnFields); if (!validation.IsValid) { return Ok(JsonView(true, $"暂无数据!{validation.Message}")); } var result = await _groupSearchService.SearchAsync(searchRequest); if (result.Success) { var data = result.Items.Select(x => new { x.Data.Id, x.Data.TeamName }).ToList(); return Ok(JsonView(true, result.Message, data, data.Count)); } return Ok(JsonView(true, result.Message)); } catch (Exception ex) { return Ok(JsonView(true, $"搜索服务暂时不可用!")); } } /// /// 客户资料 关键字输入提示(多字段) /// /// 关键字 /// 关键字 /// [HttpGet("group/{userId}/{keyword}")] [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)] public async Task ClientKeywordSearch(int userId, string keyword) { try { // 验证请求参数 if (string.IsNullOrEmpty(keyword)) { return Ok(JsonView(true, $"暂无数据!")); } //查询有权限的数据 var clientIds = await _sqlSugar .Queryable() .Where(x => x.IsDel == 0 && x.usersId == userId) .Select(x => x.NewClientDataId) .ToListAsync(); if (clientIds == null || clientIds.Count < 1) { return Ok(JsonView(true, $"暂无数据!")); } var data = _sqlSugar.Queryable() .Where(x => x.IsDel == 0 && clientIds.Contains(x.Id)) .OrderByDescending(x => x.CreateTime) .Select(x => new NewClientDataView() { Id = x.Id, Client = x.Client, Contact = x.Contact, Job = x.Job, Telephone = x.Telephone, Location = x.Location, }) .ToList(); int index = 0; data.ForEach(x => { index++; x.RowNumber = index; x.Client = AesEncryptionHelper.Decrypt(x.Client); x.Contact = AesEncryptionHelper.Decrypt(x.Contact); x.Job = AesEncryptionHelper.Decrypt(x.Job); x.Telephone = AesEncryptionHelper.Decrypt(x.Telephone); x.Location = AesEncryptionHelper.Decrypt(x.Location); }); var searchRequest = new DynamicSearchRequest { Keyword = keyword, RequireAllSingleChars = true, PageIndex = 1, PageSize = 999999, FieldWeights = new Dictionary { { "Client", 10 }, { "Contact", 8 }, { "Location", 6 } }, OrderBy = "CreateTime" }; // 验证字段配置 var validation = _clientSearchService.ValidateFieldConfig( searchRequest.FieldWeights, searchRequest.ReturnFields); if (!validation.IsValid) { return Ok(JsonView(true, $"暂无数据!{validation.Message}")); } var result = _clientSearchService.SearchDataSource(searchRequest, data); if (result.Success) { var view = result.Items.Select(x => x.Data).ToList(); int resetIndex = 0; view.ForEach(x => { resetIndex++; x.RowNumber = resetIndex; }); return Ok(JsonView(true, result.Message, view, view.Count)); } return Ok(JsonView(true, "暂无数据")); } catch (Exception ex) { return Ok(JsonView(true, $"搜索服务暂时不可用!")); } } /// /// 客户资料 /// /// 关键字 /// 关键字 /// [HttpGet("ClientKeywordSearch/{userId}/{keyword}")] [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)] public async Task ClientKeywordSearchAll(int userId, string keyword) { try { // 验证请求参数 if (string.IsNullOrEmpty(keyword)) { return Ok(JsonView(true, $"暂无数据!")); } var userIds = _clientDataRepository.GetNewExistClient(userId).Select(x => x.Id).ToList(); //查询有权限的数据(包括负责用户) var clientIds = await _sqlSugar .Queryable() .Where(x => x.IsDel == 0 && userIds.Contains(x.usersId)) .Select(x => x.NewClientDataId) .ToListAsync(); if (clientIds == null || clientIds.Count < 1) { return Ok(JsonView(true, $"暂无数据!")); } var data = _sqlSugar.Queryable() .Where(x => x.IsDel == 0 && clientIds.Contains(x.Id)) .OrderByDescending(x => x.CreateTime) .Select(x => new NewClientDataView() { Id = x.Id, Client = x.Client, Contact = x.Contact, Job = x.Job, Telephone = x.Telephone, Location = x.Location, }) .ToList(); int index = 0; data.ForEach(x => { index++; x.RowNumber = index; x.Client = AesEncryptionHelper.Decrypt(x.Client); x.Contact = AesEncryptionHelper.Decrypt(x.Contact); x.Job = AesEncryptionHelper.Decrypt(x.Job); x.Telephone = AesEncryptionHelper.Decrypt(x.Telephone); x.Location = AesEncryptionHelper.Decrypt(x.Location); }); var searchRequest = new DynamicSearchRequest { Keyword = keyword, RequireAllSingleChars = true, PageIndex = 1, PageSize = 999999, FieldWeights = new Dictionary { { "Client", 10 }, { "Contact", 8 }, { "Location", 6 } }, OrderBy = "CreateTime" }; // 验证字段配置 var validation = _clientSearchService.ValidateFieldConfig( searchRequest.FieldWeights, searchRequest.ReturnFields); if (!validation.IsValid) { return Ok(JsonView(true, $"暂无数据!{validation.Message}")); } var result = _clientSearchService.SearchDataSource(searchRequest, data); if (result.Success) { var view = result.Items.Select(x => x.Data).ToList(); int resetIndex = 0; view.ForEach(x => { resetIndex++; x.RowNumber = resetIndex; }); return Ok(JsonView(true, result.Message, view, view.Count)); } return Ok(JsonView(true, "暂无数据")); } catch (Exception ex) { return Ok(JsonView(true, $"搜索服务暂时不可用!")); } } /// /// 团组、会务流程 关键字输入提示(智能版) /// /// 关键字 /// [HttpGet] [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)] public async Task ProcessKeywordSearch(string keyword) { try { // 验证请求参数 if (string.IsNullOrEmpty(keyword)) { return Ok(JsonView(true, $"暂无数据!")); } var searchRequest = new DynamicSearchRequest { Keyword = keyword, RequireAllSingleChars = true, PageIndex = 1, PageSize = 999999, FieldWeights = new Dictionary { { "TeamName", 10 } }, Filters = new List() { new(){Field = "IsDel",Operator="eq",Value="0" } }, OrderBy = "VisitDate", ReturnFields = new List() { "TeamName" } }; // 验证字段配置 var validation = _groupSearchService.ValidateFieldConfig( searchRequest.FieldWeights, searchRequest.ReturnFields); if (!validation.IsValid) { return Ok(JsonView(true, $"暂无数据!{validation.Message}")); } var result = await _groupSearchService.SearchAsync(searchRequest); if (result.Success) { var data = new List(); foreach (var item in result.Items) { data.Add(new { item.Data.Id, item.Data.TeamName, }); } return Ok(JsonView(true, result.Message, data, data.Count)); } return Ok(JsonView(true, result.Message)); } catch (Exception ex) { return Ok(JsonView(true, $"搜索服务暂时不可用!")); } } /// /// 团组会务成本 关键字输入提示(智能版) /// /// 关键字 /// [HttpGet("ConferenceAffairsKeywordSearch/{keyword}")] [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)] public async Task ConferenceAffairsKeywordSearch(string keyword) { try { // 验证请求参数 if (string.IsNullOrEmpty(keyword)) { return Ok(JsonView(true, $"暂无数据!")); } var hwIds = _sqlSugar.Queryable() .Where(x => x.IsDel == 0 && x.STid == 10 && x.Name.Contains("会务活动")) .Select(x => x.Id) .ToList(); var object_hwIds = hwIds.ConvertAll(x => x); var searchRequest = new DynamicSearchRequest { Keyword = keyword, RequireAllSingleChars = true, PageIndex = 1, PageSize = 999999, FieldWeights = new Dictionary { { "TeamName", 10 } }, Filters = new List() { new(){Field = "IsDel",Operator="eq",Value="0" }, new(){Field = "TeamDid",Operator="in",Values=object_hwIds } }, OrderBy = "VisitDate", ReturnFields = new List() { "TeamName" } }; // 验证字段配置 var validation = _groupSearchService.ValidateFieldConfig( searchRequest.FieldWeights, searchRequest.ReturnFields); if (!validation.IsValid) { return Ok(JsonView(true, $"暂无数据!{validation.Message}")); } var result = await _groupSearchService.SearchAsync(searchRequest); if (result.Success) { var data = new List(); foreach (var item in result.Items) { data.Add(new { item.Data.Id, item.Data.TeamName, }); } return Ok(JsonView(true, result.Message, data, data.Count)); } return Ok(JsonView(true, result.Message)); } catch (Exception ex) { return Ok(JsonView(true, $"搜索服务暂时不可用!")); } } /// /// 团组各项费用录入 关键字输入提示(智能版) /// 76 酒店预订 /// 79 车/导游地接 /// 80 签证 /// 81 邀请/公务活动 /// 82 团组客户保险 /// 85 机票预订 /// 98 其他款项 /// 285 收款退还 /// 1015 超支费用 /// 1081 文档下载 /// 1466 会务相关 /// /// 用户Id /// 费用类型 /// 关键字 /// [HttpGet("GroupFeeKeywordSearch/{userId}/{feeType}/{keyword}")] [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)] public async Task GroupFeeKeywordSearch(int userId, int feeType, string keyword) { try { #region 参数验证 // 基本参数验证 if (userId <= 0) return Ok(JsonView(false, "用户ID必须大于0!")); if (feeType <= 0) return Ok(JsonView(false, "费用类型必须大于0!")); // 验证用户是否存在 var userExists = await _sqlSugar.Queryable() .Where(x => x.IsDel == 0 && x.Id == userId) .AnyAsync(); if (!userExists) { return Ok(JsonView(false, "用户不存在或已被删除")); } // 验证费用类型是否有效 var feeTypeExists = await _sqlSugar.Queryable() .Where(x => x.IsDel == 0 && x.STid == 16 && x.Id == feeType) .AnyAsync(); if (!feeTypeExists) { return Ok(JsonView(false, "无效的费用类型")); } // 验证关键字 if (string.IsNullOrWhiteSpace(keyword)) { return Ok(JsonView(false, "请输入搜索关键字")); } #endregion #region 获取用户有权限的团组ID // 获取用户有权限访问的团组ID列表 var authorizedGroupIds = await _sqlSugar.Queryable() .Where(x => x.IsDel == 0 && x.UId == userId && x.CTId == feeType) .Select(x => x.DIId) .Distinct() .ToListAsync(); if (!authorizedGroupIds.Any()) { return Ok(JsonView(true, "暂无数据", new List(), 0)); } #endregion #region 构建搜索请求 var searchRequest = new DynamicSearchRequest { Keyword = keyword.Trim(), RequireAllSingleChars = true, PageIndex = 1, PageSize = 20, // 限制返回数量,提高性能 FieldWeights = new Dictionary { { "TeamName", 10 } }, Filters = new List { new SearchFilter { Field = "IsDel", Operator = "eq", Value = "0" }, new SearchFilter { Field = "Id", Operator = "in", Values = authorizedGroupIds.ConvertAll(x => x) } }, OrderBy = "VisitDate", // 添加排序方向 ReturnFields = new List { "Id", "TeamName" } // 添加ID字段 }; #endregion #region 字段配置验证 var validation = _groupSearchService.ValidateFieldConfig( searchRequest.FieldWeights, searchRequest.ReturnFields); if (!validation.IsValid) { return Ok(JsonView(false, $"字段配置错误: {validation.Message}")); } #endregion #region 执行搜索 var result = await _groupSearchService.SearchAsync(searchRequest); if (!result.Success) { return Ok(JsonView(false, result.Message ?? "搜索失败")); } if (result.Items == null || !result.Items.Any()) { return Ok(JsonView(true, "未找到匹配的团组", new List(), 0)); } #endregion #region 构建返回数据 var responseData = result.Items .Where(item => item.Data != null) .Select(item => new { Id = item.Data.Id, TeamName = item.Data.TeamName }) .Where(x => !string.IsNullOrWhiteSpace(x.TeamName)) // 过滤空名称 .Distinct() // 去重 .ToList(); #endregion return Ok(JsonView(true, "搜索成功", responseData, responseData.Count)); } catch (Exception ex) { // 记录日志(实际项目中应该使用日志框架) // _logger.LogError(ex, "团组费用关键字搜索失败,用户ID: {UserId}, 费用类型: {FeeType}", userId, feeType); // 生产环境中不要返回详细的错误信息 return Ok(JsonView(false, "搜索服务暂时不可用,请稍后重试")); } } } }