using FluentValidation.AspNetCore;
using MassTransit;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Performance.DtoModels;
using Performance.EntityModels.Entity;
using Performance.Infrastructure;
using Performance.Repository.Repository;
using Performance.Services;
using Performance.Services.AllotCompute;
using Performance.Services.ExtractExcelService;
using Performance.Services.Queues;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace Performance.Api.Controllers
{
    [Route("api/[controller]")]
    public class AllotController : Controller
    {
        private AllotService _allotService;
        private ResultComputeService _resultComputeService;
        private ConfigService _configService;
        private IWebHostEnvironment _evn;
        private ILogger<AllotController> _logger;
        private ClaimService _claim;
        private readonly DapperService _service;
        private LogManageService _logManageService;
        private readonly TaskService _taskService;
        private readonly CostTransferService costTransferService;
        private readonly PerforPerAllotActionRepository perforPerAllotActionRepository;

        //private IBackgroundTaskQueue _backgroundTaskQueue;
        private IServiceScopeFactory _serviceScopeFactory;

        public AllotController(
            AllotService allotService,
            ResultComputeService resultComputeService,
            ConfigService configService,
            ILogger<AllotController> logger,
            IWebHostEnvironment evn,
            //IBackgroundTaskQueue backgroundTaskQueue,
            IServiceScopeFactory serviceScopeFactory,
            ClaimService claim,
            DapperService service,
            LogManageService logManageService,
            TaskService taskService,
            CostTransferService costTransferService,
            PerforPerAllotActionRepository perforPerAllotActionRepository)
        {
            _allotService = allotService;
            _resultComputeService = resultComputeService;
            _logger = logger;
            _evn = evn;
            _claim = claim;
            _service = service;
            _logManageService = logManageService;
            _taskService = taskService;
            this.costTransferService = costTransferService;
            this.perforPerAllotActionRepository = perforPerAllotActionRepository;
            _configService = configService;
            //_backgroundTaskQueue = backgroundTaskQueue;
            _serviceScopeFactory = serviceScopeFactory;
        }

        /// <summary>
        /// 绩效列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("list")]
        [HttpPost]
        public ApiResponse List([FromBody] AllotRequest request)
        {
            List<AllotResponse> allots = _allotService.GetAllotList(request.HospitalId);
            return new ApiResponse(ResponseType.OK, allots);
        }

        /// <summary>
        /// 生成成功或归档绩效记录
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("list/success")]
        [HttpPost]
        public ApiResponse Success([FromBody] AllotRequest request)
        {
            List<AllotResponse> allots = _allotService.GetSuccAllotList(request.HospitalId);
            return new ApiResponse(ResponseType.OK, allots);
        }

        /// <summary>
        /// 新增绩效
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("insert")]
        [HttpPost]
        public ApiResponse Insert([FromBody] AllotRequest request)
        {
            var userId = _claim.GetUserId();
            var result = _allotService.InsertAllot(request, userId);
            _configService.Copy(result);
            //带出上月划拨记录
            costTransferService.IntoLastTiemData(request.HospitalId.Value, result.ID);

            LogAllotAction(result.ID, result.Path, "创建");

            return new ApiResponse(ResponseType.OK, result);
        }

        /// <summary>
        /// 修改绩效
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("update")]
        [HttpPost]
        public ApiResponse<AllotResponse> Update([CustomizeValidator(RuleSet = "Update"), FromBody] AllotRequest request)
        {
            var result = _allotService.UpdateAllot(request);
            return new ApiResponse<AllotResponse>(ResponseType.OK, result);
        }

        /// <summary>
        /// 删除绩效
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("delete")]
        [HttpPost]
        public ApiResponse Delete([CustomizeValidator(RuleSet = "Delete"), FromBody] AllotRequest request)
        {
            bool result = _allotService.DeleteAllot(request.ID);
            return new ApiResponse(ResponseType.OK);
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        [Route("import")]
        [HttpPost]
        public ApiResponse Import([FromForm] IFormCollection form)
        {
            var allotid = form.ToDictionary().GetValue("allotid", 0);
            if (allotid <= 0)
                return new ApiResponse(ResponseType.Fail, "参数错误", "allotid无效");

            var file = ((FormFileCollection)form.Files).FirstOrDefault();
            if (file == null)
                return new ApiResponse(ResponseType.Fail, "参数错误", "文件无效");

            if (!ExtractHelper.IsXlsxFile(file.FileName))
                return new ApiResponse(ResponseType.Fail, "文件格式错误", "文件暂只支持xlsx文件");

            var allot = _allotService.GetAllot(allotid);
            if (allot == null)
                return new ApiResponse(ResponseType.Fail, "allotid不存在");

            var name = FileHelper.GetFileNameNoExtension(file.FileName) + DateTime.Now.ToString("yyyyMMddHHmmssfff");
            var ext = FileHelper.GetExtension(file.FileName);

            var dpath = Path.Combine(_evn.ContentRootPath, "Files", $"{allot.HospitalId}", $"{allot.Year}{allot.Month.ToString().PadLeft(2, '0')}");
            FileHelper.CreateDirectory(dpath);

            var path = Path.Combine(dpath, $"{name}{ext}");

            using (var stream = file.OpenReadStream())
            {
                byte[] bytes = new byte[stream.Length];
                stream.Read(bytes, 0, bytes.Length);
                if (!FileHelper.CreateFile(path, bytes))
                    return new ApiResponse(ResponseType.Fail, $"{file.FileName}上传失败");
                allot.Path = path;
                allot.States = (int)AllotStates.数据已上传;
                allot.Remark = EnumHelper.GetDescription(AllotStates.数据已上传);
                allot.UploadDate = DateTime.Now;
                allot.Generate = (int)AllotGenerate.Init;
                if (!_allotService.Update(allot))
                    return new ApiResponse(ResponseType.Fail, $"{file.FileName}上传成功，修改状态失败");
                _configService.Clear(allot.ID);

                LogAllotAction(allot.ID, allot.Path, "上传");
            }

            //var email = _claim.GetUserClaim(JwtClaimTypes.Mail);
            //if (allot.States == (int)AllotStates.FileUploaded)
            //    _backgroundTaskQueue.QueueBackgroundWorkItem(async token =>
            //    {
            //        using (var scope = _serviceScopeFactory.CreateScope())
            //        {
            //            var scopedServices = scope.ServiceProvider.GetRequiredService<AllotService>();
            //            scopedServices.Generate(allot, email);
            //            await Task.Delay(TimeSpan.FromSeconds(5), token);
            //        }
            //    });

            return new ApiResponse(ResponseType.OK, true);
        }


        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="allotId"></param>
        /// <returns></returns>
        [Route("ImportExtraction/{allotId}")]
        [HttpPost]
        public ApiResponse ImportExtraction(int allotId)
        {
            var allot = _allotService.GetAllot(allotId);
            if (allot == null)
                return new ApiResponse(ResponseType.Fail, "allotid不存在");

            var extract = allot.ExtractPath.Split("\\").Last();
            var fileName = System.Text.RegularExpressions.Regex.Replace(extract, @"\d", "");
            //var file = ((FormFileCollection)allot.ExtractPath).FirstOrDefault();
            //if (file == null)
            //    return new ApiResponse(ResponseType.Fail, "参数错误", "文件无效");

            var name = FileHelper.GetFileNameNoExtension(fileName) + DateTime.Now.ToString("yyyyMMddHHmmssfff");
            var ext = FileHelper.GetExtension(fileName);
            var dpath = Path.Combine(_evn.ContentRootPath, "Files", $"{allot.HospitalId}", $"{allot.Year}{allot.Month.ToString().PadLeft(2, '0')}");
            FileHelper.CreateDirectory(dpath);

            var path = Path.Combine(dpath, $"{name}{ext}");

            using (var stream = System.IO.File.OpenRead(allot.ExtractPath))
            {
                byte[] bytes = new byte[stream.Length];
                stream.Read(bytes, 0, bytes.Length);
                if (!FileHelper.CreateFile(path, bytes))
                    return new ApiResponse(ResponseType.Fail, $"上传失败");
                allot.Path = path;
                allot.States = (int)AllotStates.数据已上传;
                allot.Remark = EnumHelper.GetDescription(AllotStates.数据已上传);
                allot.UploadDate = DateTime.Now;
                allot.Generate = (int)AllotGenerate.Init;
                allot.IsModifyConfig = 1;
                if (!_allotService.Update(allot))
                    return new ApiResponse(ResponseType.Fail, $"上传成功，修改状态失败");
                _configService.Clear(allot.ID);
            }

            return new ApiResponse(ResponseType.OK);
        }


        /// <summary>
        /// 绩效生成
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("generate")]
        [HttpPost]
        public ApiResponse GenerateAsync([CustomizeValidator(RuleSet = "Delete"), FromBody] AllotRequest request)
        {
            var allot = _allotService.GetAllot(request.ID);
            if (null == allot || string.IsNullOrEmpty(allot.Path))
                throw new PerformanceException("当前绩效记录不存在或没有上传数据文件");

            //if (_evn.IsEnvironment("Localhost"))
            //{
            //    var tasks = _taskService.GetTasks(-1);
            //    var status = new int[] { (int)Background.Status.等待, (int)Background.Status.执行中 };
            //    if (tasks.Any(w => w.Argument == allot.ID.ToString() && w.JobType == (int)Background.JobType.生成测算表 && status.Contains(w.Status)))
            //        return new ApiResponse(ResponseType.OK, "当前绩效正在生成中，请等待生成完成后重新生成");

            //    if (allot.States == (int)AllotStates.Wait)
            //        return new ApiResponse(ResponseType.OK, "当前绩效正在等待生成");

            //    _logManageService.WriteMsg("生成绩效准备中", $"准备生成{allot.Year}-{allot.Month.ToString().PadLeft(2, '0')}月份绩效，请稍等!", 1, allot.ID, "ReceiveMessage", true);
            //    _allotService.UpdateAllotStates(allot.ID, (int)AllotStates.Wait, EnumHelper.GetDescription(AllotStates.Wait), allot.Generate);

            //    _allotService.Generate(allot);
            //}
            //else
            //{

            var tasks = _taskService.GetTasks(-1);
            var status = new int[] { (int)Background.Status.等待, (int)Background.Status.执行中 };
            if (tasks.Any(w => w.Argument == allot.ID.ToString() && w.JobType == (int)Background.JobType.生成测算表 && status.Contains(w.Status)))
                return new ApiResponse(ResponseType.OK, "当前绩效正在生成中，请等待生成完成后重新生成");

            if (allot.States == (int)AllotStates.等待)
                return new ApiResponse(ResponseType.OK, "当前绩效正在等待生成");

            _logManageService.WriteMsg("生成绩效准备中", $"准备生成{allot.Year}-{allot.Month.ToString().PadLeft(2, '0')}月份绩效，请稍等!", 1, allot.ID, "ReceiveMessage", true);
            _allotService.UpdateAllotStates(allot.ID, (int)AllotStates.等待, EnumHelper.GetDescription(AllotStates.等待), allot.Generate);

            //_backgroundTaskQueue.QueueBackgroundWorkItem(async token =>
            //{
            //    using (var scope = _serviceScopeFactory.CreateScope())
            //    {
            //        var scopedServices = scope.ServiceProvider.GetRequiredService<AllotService>();
            //        scopedServices.Generate(allot);
            //        await Task.Delay(TimeSpan.FromSeconds(5), token);
            //    }
            //});

            _taskService.Add(Background.JobType.生成测算表, allot.ID.ToString());
            //}

            _logManageService.WriteMsg("等待绩效生成", $"等待绩效生成{allot.Year}-{allot.Month.ToString().PadLeft(2, '0')}月份绩效!", 1, allot.ID, "ReceiveMessage");
            //_allotService.Generate(allot, email);
            ////BackgroundJob.Enqueue(() => _allotService.Generate(allot, email));
            return new ApiResponse(ResponseType.OK);
        }


        /// <summary>
        /// 绩效生成报表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("genreport")]
        [HttpPost]
        public ApiResponse GenerateReport([CustomizeValidator(RuleSet = "Delete"), FromBody] AllotRequest request)
        {
            var allot = _allotService.GetAllot(request.ID);
            var states = new[] { (int)AllotStates.归档, (int)AllotStates.绩效下发, (int)AllotStates.绩效结果解析成功 };
            if (null == allot || !states.Contains(allot.States))
                throw new PerformanceException("当前绩效暂未生成，无法统计报表数据。");

            //_backgroundTaskQueue.QueueBackgroundWorkItem(async token =>
            //{
            //    using (var scope = _serviceScopeFactory.CreateScope())
            //    {
            //        var scopedServices = scope.ServiceProvider.GetRequiredService<AllotService>();
            //        scopedServices.GenerateReport(allot);
            //        await Task.Delay(TimeSpan.FromSeconds(5), token);
            //    }
            //});
            _taskService.Add(Background.JobType.报表, allot.ID.ToString());

            return new ApiResponse(ResponseType.OK, "统计报表数据任务开始");
        }

        /// <summary>
        /// 验证科室核算单元、工号
        /// </summary>
        /// <param name="allotId"></param>
        /// <returns></returns>
        [Route("accounting/verify/{allotId}")]
        [HttpPost]
        public ApiResponse AccountingVerify([FromRoute] int allotId)
        {
            _allotService.AccoungtingVerify(allotId);
            return new ApiResponse(ResponseType.OK, "数据验证结束，请刷新页面。");
        }

        /*
        [Route("recalculation")]
        [HttpPost]
        public ApiResponse Recalculation([FromBody] RecalculationRequest request)
        {
            if (request.Money.HasValue && request.Money.Value > 0)
                _allotService.Recalculation(request.AllotId, request.Money.Value);
            return new ApiResponse(ResponseType.OK);
        }
        */

        /// <summary>
        /// 重新计算院领导绩效
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("recalculation")]
        [HttpPost]
        public ApiResponse Recalculation([FromBody] RecalculationRequest request)
        {
            if (request.Money.HasValue)
                _allotService.Recalculation(request.AllotId, request.Money.Value);
            return new ApiResponse(ResponseType.OK);
        }

        /// <summary>
        /// 归档绩效记录
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("pigeonhole")]
        [HttpPost]
        public ApiResponse Pigeonhole([CustomizeValidator(RuleSet = "Delete"), FromBody] AllotRequest request)
        {
            var allot = _allotService.GetAllot(request.ID);
            if (null == allot)
                throw new PerformanceException("当前绩效记录不存在或没有上传数据文件");
            _service.Pigeonhole(allot.ID);

            _taskService.Add(Background.JobType.每日汇报表汇总, allot.ID.ToString());

            LogAllotAction(allot.ID, allot.Path, "归档");

            return new ApiResponse(ResponseType.OK);
        }

        /// <summary>
        /// 归档时检索数据是否合格
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("checkrecord")]
        [HttpPost]
        public ApiResponse CheckRecord([CustomizeValidator(RuleSet = "Delete"), FromBody] AllotRequest request)
        {
            var allot = _allotService.GetAllot(request.ID);
            if (null == allot)
                throw new PerformanceException("当前绩效记录不存在或没有上传数据文件");
            var list = _allotService.GetAgainAllotNotSucceed(allot);
            return new ApiResponse(ResponseType.OK, list);
        }

        /// <summary>
        /// 绩效校验结果
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("allotcheckresult")]
        [HttpPost]
        public ApiResponse AllotCheckResult([CustomizeValidator(RuleSet = "Delete"), FromBody] AllotRequest request)
        {
            var allot = _allotService.GetAllot(request.ID);
            if (null == allot)
                throw new PerformanceException("当前绩效记录不存在");
            var list = _allotService.AllotCheckResult(allot);
            return new ApiResponse(ResponseType.OK, list);
        }

        /// <summary>
        /// 绩效历史日志
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("allotlog")]
        [HttpPost]
        public ApiResponse AllotLog([CustomizeValidator(RuleSet = "Delete"), FromBody] AllotRequest request)
        {
            var allot = _allotService.GetAllot(request.ID);
            if (null == allot)
                throw new PerformanceException("当前绩效记录不存在");
            var list = _allotService.AllotLog(allot, 1);
            return new ApiResponse(ResponseType.OK, list);
        }

        /// <summary>
        /// 绩效审核通过，绩效下发
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("issued")]
        [HttpPost]
        public ApiResponse Issued([FromBody] AllotRequest request)
        {
            var allot = _allotService.GetAllot(request.ID);
            if (null == allot)
                throw new PerformanceException("当前绩效记录不存在");

            var res = _allotService.GetCheckBase(request.ID);
            string error = "";
            if (res.CheckEmp.Body?.Any() == true)
                error += "测算表人员信息与「人员字典」无法匹配,";
            if (res.CheckDept.Body?.Any() == true)
                error += "测算表核算单元与「核算单元及组别」信息无法匹配";
            if (!string.IsNullOrEmpty(error))
                throw new PerformanceException(error);

            var seconds = _resultComputeService.GetSeconds(allot);
            if (request.isIssued == 1)
            {
                // 确认下发
                var isIssued = _resultComputeService.IssuedChangeSecond(allot, seconds);
                if (isIssued)
                {
                    _allotService.UpdateAllotStates(allot.ID, (int)AllotStates.绩效下发, EnumHelper.GetDescription(AllotStates.绩效下发));
                    costTransferService.RejectedApplicat(allot.ID);

                    _taskService.Add(Background.JobType.每日汇报表汇总, allot.ID.ToString());

                    LogAllotAction(allot.ID, allot.Path, "下发");

                    return new ApiResponse(ResponseType.OK, "下发成功");
                }
                else
                {
                    return new ApiResponse(ResponseType.Fail, "下发失败");
                }
            }
            else
            {
                // 获取二次分配差异数据 
                var orgChangeSecond = _resultComputeService.GetChangeSecond(seconds);

                if (!string.IsNullOrEmpty(request.SearchQuery))
                    orgChangeSecond = orgChangeSecond?.Where(t => t.Department.Contains(request.SearchQuery)).ToList() ?? new List<IssuedPromptResponse>();
                if (!string.IsNullOrEmpty(request.QueryStatus.ToString()))
                    orgChangeSecond = orgChangeSecond?.Where(t => t.IssueStatus == request.QueryStatus).ToList() ?? new List<IssuedPromptResponse>();

                orgChangeSecond.ForEach(item => item.UnitType = UnitTypeUtil.GetOffice(item.UnitType));
                orgChangeSecond = orgChangeSecond?.OrderBy(t => t.IssueStatus).ToList();
                return new ApiResponse(ResponseType.OK, orgChangeSecond);
            }
        }

        /// <summary>
        /// 查询CheckBase
        /// </summary>
        /// <param name="allotId"></param>
        /// <returns></returns>
        [Route("getCheckBase")]
        [HttpGet]
        public ApiResponse GetCheckBase([FromQuery] int allotId)
        {
            var res = _allotService.GetCheckBase(allotId);
            return new ApiResponse(ResponseType.OK, res);
        }

        /// <summary>
        /// 绩效详情计算公式显示/隐藏
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("update/showformula")]
        [HttpPost]
        public ApiResponse UpdateAllotShowFormula([FromBody] AllotRequest request)
        {
            if (request.ID < 1)
                return new ApiResponse(ResponseType.ParameterError, "绩效信息无效");
            var result = _allotService.UpdateAllotShowFormula(request.ID);
            return new ApiResponse(ResponseType.OK, result);
        }

        /// <summary>
        /// 获取预留金额
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("reserved")]
        [HttpPost]
        public ApiResponse Reserved([FromBody] ReservedRequest request)
        {
            if (request.HospitalId < 1)
                return new ApiResponse(ResponseType.ParameterError, "绩效信息无效");

            var userid = _claim.GetUserId();
            var reserveds = _allotService.GetReserved(request, userid);
            return new ApiResponse(ResponseType.OK, reserveds);
        }

        /// <summary>
        /// 预留金额下载
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("reservedDownload")]
        [HttpPost]
        public IActionResult ReservedDownload([FromBody] ReservedRequest request)
        {
            try
            {
                List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>
                {
                    new ExcelDownloadHeads(){ Alias="年份",Name = nameof(EmployeeReservedDto.Year) },
                    new ExcelDownloadHeads(){ Alias="来源",Name = nameof(EmployeeReservedDto.Source) },
                    new ExcelDownloadHeads(){ Alias="核算单元组别",Name = nameof(EmployeeReservedDto.UnitType) },
                    new ExcelDownloadHeads(){ Alias="核算单元",Name = nameof(EmployeeReservedDto.AccountingUnit) },
                    new ExcelDownloadHeads(){ Alias="人员姓名",Name = nameof(EmployeeReservedDto.EmployeeName) },
                    new ExcelDownloadHeads(){ Alias="人员工号",Name = nameof(EmployeeReservedDto.JobNumber) },
                    new ExcelDownloadHeads(){ Alias="预留金额总计",Name = nameof(EmployeeReservedDto.TotalReseFee) },
                    new ExcelDownloadHeads(){ Alias="实发金额总计",Name = nameof(EmployeeReservedDto.TotalGiveFee) },
                };

                var userid = _claim.GetUserId();
                var result = _allotService.GetReserved(request, userid);

                var ser = JsonConvert.SerializeObject(result);
                var rows = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(ser);

                string name;
                string[] ignoreColumns;
                if (request.Source == 1)
                {
                    name = "预留金额(按人员字典)";
                    ignoreColumns = new string[] { "hospitalid", "source", "newunittype", "newaccountingunit" };
                }
                else
                {
                    name = "预留金额(按发放科室)";
                    ignoreColumns = new string[] { "hospitalid", "newunittype", "newaccountingunit" };
                }
                var filepath = _allotService.ExcelDownload(rows, name, excelDownloadHeads, ignoreColumns);

                var memoryStream = new MemoryStream();
                using (var stream = new FileStream(filepath, FileMode.Open))
                {
                    stream.CopyToAsync(memoryStream).Wait();
                }
                memoryStream.Seek(0, SeekOrigin.Begin);
                var provider = new FileExtensionContentTypeProvider();
                FileInfo fileInfo = new FileInfo(filepath);
                var memi = provider.Mappings[".xlsx"];
                return File(memoryStream, memi, Path.GetFileName(fileInfo.Name));
            }
            catch (Exception ex)
            {
                _logger.LogError(new EventId(10000), ex, "下载异常");
                throw;
            }
        }



        /// <summary>
        /// 下载当前测算表
        /// </summary>
        /// <param name="allotid"></param>
        /// <returns></returns>
        [Route("current/download/{allotid}")]
        [HttpGet]
        [AllowAnonymous]
        public IActionResult DownloadCurrentCalculationTable(int allotid)
        {
            var allot = _allotService.GetAllot(allotid);
            if (null == allot)
                throw new PerformanceException("当前测算表不存在");

            if (string.IsNullOrEmpty(allot.Path))
                throw new PerformanceException("尚未提交测算表");

            if (!FileHelper.IsExistFile(allot.Path))
                throw new PerformanceException("测算表文件路径无效");

            var memoryStream = new MemoryStream();
            using (var stream = new FileStream(allot.Path, FileMode.Open))
            {
                stream.CopyToAsync(memoryStream).Wait();
            }
            memoryStream.Seek(0, SeekOrigin.Begin);
            var provider = new FileExtensionContentTypeProvider();
            FileInfo fileInfo = new FileInfo(allot.Path);
            var memi = provider.Mappings[".xlsx"];
            return File(memoryStream, memi, Path.GetFileName(fileInfo.Name));
        }

        /// <summary>
        /// 查询个人绩效
        /// </summary>
        /// <returns></returns>
        [Route("owner/query")]
        [HttpGet]
        public ApiResponse GetOwnerPerformance()
        {
            var userid = _claim.GetUserId();
            var res = _allotService.GetOwnerPerformance(userid);
            return new ApiResponse(ResponseType.OK, res);
        }

        /// <summary>
        /// H5查询个人绩效
        /// </summary>
        /// <param name="begin">开始月份：2021-03</param>
        /// <param name="end">结束月份：2021-04</param>
        /// <returns></returns>
        [Route("owner/query/mobile")]
        [HttpGet]
        public ApiResponse<List<OwnerMobilePerformanceDto>> GetOwnerMobilePerformance(string begin = "", string end = "")
        {
            var userid = _claim.GetUserId();
            var beginDate = begin.ToTryDateTime();
            var endDate = end.ToTryDateTime();

            if (beginDate == DateTime.MinValue || endDate == DateTime.MinValue)
                throw new PerformanceException("您选择的时间范围无效");

            endDate = endDate.AddMonths(1);
            var dtos = _allotService.GetOwnerMobilePerformance(userid, beginDate, endDate);
            return new ApiResponse<List<OwnerMobilePerformanceDto>>(ResponseType.OK, dtos);
        }

        /// <summary>
        /// 记录创建、下发、归档、上传绩效
        /// </summary>
        private void LogAllotAction(int allotId, string path, string actionName)
        {
            per_allot_action per_Allot_Action = new per_allot_action()
            {
                AllotId = allotId,
                CreateDate = DateTime.Now,
                CreateUser = _claim.GetUserId(),
                FilePath = path ?? "",
                ActionName = actionName
            };

            perforPerAllotActionRepository.Add(per_Allot_Action);
        }
    }
}
