using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using AutoMapper; using Datory; using GxPress.Common.AppOptions; using GxPress.Common.Exceptions; using GxPress.Common.Tools; using GxPress.Entity.WorkProcess; using GxPress.EnumConst; using GxPress.Repository.Interface; using GxPress.Repository.Interface.WorkProcess; using GxPress.Result.Process; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Options; using ProcessNode = GxPress.Entity.WorkProcess.ProcessNode; namespace GxPress.Repository.Implement.WorkProcess { public partial class ProcessRepository : IProcessRepository { private readonly Repository<Process> _repository; private readonly IMapper _mapper; private readonly IProcessFieldRepository _processFieldRepository; private readonly IProcessGroupRepository _processGroupRepository; private readonly IProcessNodeRepository _processNodeRepository; private readonly IProcessRequestLimitRepository _processRequestLimitRepository; private readonly IRuleConditionRepository _conditionRuleRepository; private readonly IRuleCarbonCopyRepository _ruleCarbonCopyRepository; private readonly IRuleApproverCheckRepository _ruleApproverCheckRepository; private readonly IDepartmentRepository _departmentRepository; private readonly IRoleRepository _roleRepository; private readonly IUserRepository _userRepository; public ProcessRepository(IOptionsMonitor<DatabaseOptions> dbOptionsAccessor, IMapper mapper, IDistributedCache cache, IProcessFieldRepository processFieldRepository, IProcessGroupRepository processGroupRepository, IProcessRequestLimitRepository processRequestLimitRepository, IProcessNodeRepository processNodeRepository, IRuleConditionRepository conditionRuleRepository, IRuleCarbonCopyRepository ruleCarbonCopyRepository, IRuleApproverCheckRepository ruleApproverCheckRepository, IDepartmentRepository departmentRepository, IRoleRepository roleRepository, IUserRepository userRepository) { var databaseType = StringUtils.ToEnum<DatabaseType>(dbOptionsAccessor.CurrentValue.DatabaseType, DatabaseType.MySql); var database = new Database(databaseType, dbOptionsAccessor.CurrentValue.ConnectionString); _repository = new Repository<Process>(database, cache); _mapper = mapper; _processFieldRepository = processFieldRepository; _processGroupRepository = processGroupRepository; _processRequestLimitRepository = processRequestLimitRepository; _processNodeRepository = processNodeRepository; _conditionRuleRepository = conditionRuleRepository; _ruleCarbonCopyRepository = ruleCarbonCopyRepository; _ruleApproverCheckRepository = ruleApproverCheckRepository; _departmentRepository = departmentRepository; _roleRepository = roleRepository; _userRepository = userRepository; } public IDatabase Database => _repository.Database; public string TableName => _repository.TableName; public List<TableColumn> TableColumns => _repository.TableColumns; public string CacheKey(int id) => $"{nameof(ProcessRepository)}:{id}"; public async Task<int> InsertAsync(Process process) { process.Id = 0; return await _repository.InsertAsync(process); } public async Task UpdateAsync(Process process) { await _repository.UpdateAsync(process, Q.CachingSet(CacheKey(process.Id))); } public async Task<Process> GetAsync(int processId) { return await _repository.GetAsync(Q .Where(nameof(Process.Id), processId) // .CachingGet(CacheKey(processId)) ); } public async Task<bool> ExistsAsync(int id) { return await _repository.ExistsAsync(id); } public async Task<IEnumerable<Process>> GetListAsync(string keyword) { var result = await _repository.GetAllAsync(Q .OrderByDesc(nameof(Process.Sort)) .OrderBy(nameof(Process.Id))); foreach (var item in result) item.IconUrl = StringUtils.AddDomain(item.IconUrl); return result; } public async Task<IEnumerable<Process>> GetAllAsync(SqlKata.Query query) { return await _repository.GetAllAsync(query); } public async Task<IEnumerable<Process>> GetListByGroupIdAsync(int groupId) { var result = await _repository.GetAllAsync(Q .Where(nameof(Process.GroupId), groupId) .OrderByDesc(nameof(Process.Sort)) .OrderBy(nameof(Process.Id)) ); foreach (var item in result) item.IconUrl = StringUtils.AddDomain(item.IconUrl); return result; } public async Task<IEnumerable<Process>> GetListByDepartmentIdAsync(int departmentId) { var departmentIds = await GetDepartmentIdsAsync(departmentId, new List<int>()); var processIdList = await _processRequestLimitRepository.GetProcessIdListByDepartmentIdAsync(departmentIds); var result = await _repository.GetAllAsync(Q .WhereIn(nameof(Process.Id), processIdList) .OrWhere(nameof(Process.LimitType), nameof(LimitTypeConst.NoLimit)) .OrderByDesc(nameof(Process.Sort)) .OrderBy(nameof(Process.Id)) ); foreach (var item in result) item.IconUrl = StringUtils.AddDomain(item.IconUrl); return result; } public async Task<List<int>> GetDepartmentIdsAsync(int departmentId, List<int> departmentIds) { var department = await _departmentRepository.GetAsync(departmentId); departmentIds.Add(department.Id); if (department != null && department.ParentId > 0) { department = await _departmentRepository.GetAsync(department.ParentId); departmentIds.Add(department.Id); if (department.ParentId > 0) await GetDepartmentIdsAsync(department.ParentId, departmentIds); } return departmentIds; } public async Task<ProcessBaseInfoResult> GetBaseInfoAsync(int id) { var process = await _repository.GetAsync(id); if (process == null) throw new BusinessException("该流程不存在"); var result = _mapper.Map<ProcessBaseInfoResult>(process); return result; } public async Task<List<ProcessFormSettingResult>> GetFormSettingAsync(int id) { var fields = await _processFieldRepository.GetListAsync(id); var result = _mapper.Map<List<ProcessFormSettingResult>>(fields); return result; } public async Task<ProcessNodeTreeResult> GetNodeTreeAsync(int id) { var nodeList = await _processNodeRepository.GetListAsync(id, 0); return await ListToTreeAsync(nodeList.FirstOrDefault(x => x.ParentId == 0), nodeList); } private async Task<ProcessNodeTreeResult> ListToTreeAsync(ProcessNode node, IEnumerable<ProcessNode> all) { var model = new ProcessNodeTreeResult { Id = node.Id, Name = node.Name, Type = node.Type }; var children = all.Where(m => m.ParentId == model.Id); foreach (var child in children) { model.Children.Add(await ListToTreeAsync(child, all)); } return model; } public async Task<bool> DeleteAsync(int id) { return await _repository.DeleteAsync(Q .Where(nameof(Process.Id), id) .CachingRemove(CacheKey(id)) ) == 1; } } }