using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Performance.DtoModels;
using Performance.EntityModels.Entity;
using Performance.EntityModels.Other;
using Performance.Services;
using System.Collections.Generic;
using Microsoft.AspNetCore.StaticFiles;
using System;
using System.IO;
using Newtonsoft.Json;
using System.Threading.Tasks;
using Performance.DtoModels.Response;
using Performance.DtoModels.Request;
using static Performance.Services.ExtractExcelService.WriteDataHelper;
using System.Linq;
using Performance.Infrastructure;
using System.ComponentModel;

namespace Performance.Api.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AttendanceController : ControllerBase
    {
        private readonly AttendanceService _attendanceService;
        private ClaimService claim;
        public AttendanceController(
            AttendanceService attendanceService, ClaimService claim
            )
        {
            _attendanceService = attendanceService;
            this.claim = claim;
        }
        /*
         
        per_attendance   考勤-调动记录表 
        per_attendance_type   考勤-考勤类型 
        per_attendance_vacation   考勤-考勤记录表 

        view_attendance  考勤视图

         */

        ///// <summary>
        ///// 查询绩效考勤记录
        ///// </summary>
        ///// <param name="allotId">绩效月ID</param>
        ///// <returns></returns>
        //[HttpGet("GetAttendance/{allotId}")]
        //public ApiResponse<List<AttendanceStatistics>> GetAttendance(int allotId)
        //{
        //    // 查询考勤视图，并按照设计图做格式转换 仅查询开始结束
        //    var userid = claim.GetUserId();
        //    var result = _attendanceService.GetAttendance(allotId, userid);

        //    return result;
        //}

        #region 调动记录

        /// <summary>
        /// 查询绩效调动记录
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <returns></returns>
        [HttpGet("CallIn/{allotId}")]
        public ApiResponse<List<view_attendance>> GetCallIn(int allotId)
        {
            // 查询考勤视图，并按照设计图做格式转换 仅查询调入
            return _attendanceService.GetCallIn(allotId);
        }

        /// <summary>
        /// 返回HandsonTable格式调动记录
        /// </summary>
        /// <returns></returns>
        [HttpGet("CallIn/GetBatch")]
        [ProducesResponseType(typeof(HandsonTable), StatusCodes.Status200OK)]
        public ApiResponse GetBatchCallInHandsonTable(int allotId)
        {
            // 返回HandsonTable格式调动记录
            return new ApiResponse(ResponseType.OK, _attendanceService.GetBatchCallInHandsonTable(allotId));
        }

        /// <summary>
        /// 批量插入调动记录
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="hospitalId"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("CallIn/Batch/{allotId}")]
        public ApiResponse BatchCallIn(int allotId, int hospitalId, SaveCollectData request)
        {
            // obj自己定义结构
            // 批量插入调动记录，插入前需要删除所有后重新插入

            // 需要验证工号和姓名是否与“人员字典”（per_employee）完全匹配，不匹配则返回表格错误提示
            // 需要验证核算组别和核算单元是否与“核算单元及组别”（cof_accounting）完全匹配，不匹配则返回表格错误提示

            // 表格错误提醒参考PersonService.CreatePerson方法
            return _attendanceService.BatchCallIn(allotId, hospitalId, request);
        }
        /// <summary>
        /// 考勤-调动记录表（添加）
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("CallIn/Add")]
        public ApiResponse AttendanceAdd(int allotId, AttendanceData request)
        {
            return _attendanceService.AttendanceAdd(allotId, request);
        }
        /// <summary>
        /// 考勤-调动记录表（修改）
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("CallIn/Update")]
        public ApiResponse AttendanceUpdate(int allotId, AttendanceUpdateData request)
        {
            return _attendanceService.AttendanceUpdate(allotId, request);
        }
        /// <summary>
        /// 考勤-调动记录表（删除）
        /// </summary>
        /// <param name="attendanceId"></param>
        /// <returns></returns>
        [HttpPost("CallIn/Delete")]
        public ApiResponse AttendanceDelete(int attendanceId)
        {
            return _attendanceService.AttendanceDelete(attendanceId);
        }


        /// <summary>
        /// 考勤-调动记录表（全部删除）
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <returns></returns>
        [HttpPost("CallIn/ClearAll")]
        public ApiResponse AttendanceClearAll(int allotId)
        {
            return _attendanceService.AttendanceClearAll(allotId);
        }
        #endregion

        #region 考勤类型
        /// <summary>
        /// 查询绩效考勤类型
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <returns></returns>
        [HttpGet("Type/{allotId},{hospitalId}")]
        public ApiResponse<List<per_attendance_type>> GetAttendanceType(int allotId)
        {
            return _attendanceService.GetAttendanceType(allotId);
        }
        /// <summary>
        /// 新增或修改考勤类型
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="attendanceType"></param>
        /// <returns></returns>
        [HttpPost("Type/Edit/{allotId},{hospitalId}")]
        public ApiResponse<AttendanceType> InsertAttendanceType(int allotId, AttendanceType attendanceType)
        {
            // obj自己定义结构
            return _attendanceService.InsertAttendanceType(allotId, attendanceType);
        }
        /// <summary>
        /// 删除考勤类型
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost("Type/Delete/{id}")]
        public ApiResponse DeleteAttendanceType(int id)
        {
            // 删除前需要验证当前类型是否被使用，如果被使用则禁止删除
            return _attendanceService.DeleteAttendanceType(id);
        }
        #endregion

        #region 考勤记录
        /// <summary>
        /// 返回HandsonTable格式考勤记录
        /// </summary>
        /// <returns></returns>
        [HttpGet("Vacation")]
        [ProducesResponseType(typeof(HandsonTable), StatusCodes.Status200OK)]
        public ApiResponse GetAttendanceVacationHandsonTable(int allotId)
        {
            // 返回HandsonTable格式考勤记录
            return new ApiResponse(ResponseType.OK, _attendanceService.GetAttendanceVacationHandsonTable(allotId));
        }

        /// <summary>
        /// 查询考勤记录
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="hospitalId"></param>
        /// <returns></returns>
        [HttpGet("Vacation/{allotId},{hospitalId}")]
        public ApiResponse<List<RecordAttendcance>> GetAttendanceVacation(int allotId, int hospitalId)
        {
            return _attendanceService.GetAttendanceVacation(allotId);
        }

        /// <summary>
        /// 批量插入考勤记录，插入前需要删除所有后重新插入
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="hospitalId"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("Vacation/Batch/{allotId}")]
        public ApiResponse AttendanceBatch(int allotId, int hospitalId, SaveCollectData request)
        {
            // obj自己定义结构
            // 批量插入考勤记录，插入前需要删除所有后重新插入
            // 需要验证考勤类型是否正确
            // 需要验证工号和姓名是否与“人员字典”（per_employee）完全匹配，不匹配则返回表格错误提示

            // 表格错误提醒参考PersonService.CreatePerson方法
            return _attendanceService.AttendanceBatch(allotId, hospitalId, request);
        }

        //public ApiResponse AttendanceAdd(int allotId, int hospitalId, SaveCollectData request)
        //{

        //    return _attendanceService.AttendanceAdd(allotId, hospitalId, request);
        //}

        /// <summary>
        /// 考勤-考勤记录表（添加）
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("Vacation/Add")]
        public ApiResponse AttendanceVacationAdd(int allotId, AttendanceVacationData request)
        {
            return _attendanceService.AttendanceVacationAdd(allotId, request);
        }
        /// <summary>
        /// 考勤-考勤记录表（修改）
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("Vacation/Update")]
        public ApiResponse AttendanceVacationUpdate(int allotId, AttendanceVacationUpdateData request)
        {
            return _attendanceService.AttendanceVacationUpdate(allotId, request);
        }
        /// <summary>
        /// 考勤-考勤记录表（删除）
        /// </summary>
        /// <param name="attendanceId"></param>
        /// <returns></returns>
        [HttpPost("Vacation/Delete")]
        public ApiResponse AttendanceVacationDelete(int attendanceId)
        {
            return _attendanceService.AttendanceVacationDelete(attendanceId);
        }


        /// <summary>
        /// 考勤-考勤记录表（全部删除）
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <returns></returns>
        [HttpPost("Vacation/ClearAll")]
        public ApiResponse AttendanceVacationClearAll(int allotId)
        {
            return _attendanceService.AttendanceVacationClearAll(allotId);
        }
        #endregion

        /// <summary>
        /// 考勤结果统计
        /// </summary>
        /// <param name="allotId">绩效月ID</param> 
        /// <returns></returns>
        [HttpGet("statistics/{allotId}")]
        public ApiResponse<List<AttendanceStatistics>> GetAttendanceStatistics(int allotId)
        {
            // 返回结果参考接口 employee/apr/getdeptdetail
            var userid = claim.GetUserId();
            return _attendanceService.GetAttendanceStatistics(allotId, userid);
        }


        #region 初始考勤记录下载
        ///// <summary>
        ///// 初始考勤记录下载
        ///// </summary>
        ///// <param name="allotId">绩效月ID</param>
        ///// <returns></returns>
        //[HttpPost]
        //[Route("download/attendance/{allotId}")]
        //public IActionResult DownloadAttendance(int allotId)
        //{
        //    List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>()
        //    {
        //        new ExcelDownloadHeads { Alias = "核算单元名称", Name = nameof(AttendanceStatistics.AccountingUnit) },
        //        new ExcelDownloadHeads { Alias = "科室名称", Name =  nameof(AttendanceStatistics.Department) },
        //        new ExcelDownloadHeads { Alias = "姓名", Name =  nameof(AttendanceStatistics.PersonnelName) },
        //        new ExcelDownloadHeads { Alias = "员工号", Name =  nameof(AttendanceStatistics.PersonnelNumber) },
        //        new ExcelDownloadHeads { Alias = "人员类别", Name =  nameof(AttendanceStatistics.UnitType) },
        //        new ExcelDownloadHeads { Alias = "在科开始时问", Name =  nameof(AttendanceStatistics.BeginDate) },
        //        new ExcelDownloadHeads { Alias = "在科结束时间", Name =  nameof(AttendanceStatistics.EndDate) },
        //    };
        //    var userid = claim.GetUserId();
        //    var result = _attendanceService.GetAttendance(allotId, userid).Data;
        //    var ser = JsonConvert.SerializeObject(result);
        //    var rows = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(ser);

        //    var filepath = _attendanceService.ExcelDownload(rows, "初始考勤记录", allotId, excelDownloadHeads);

        //    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));
        //}

        #endregion

        #region 下载
        /// <summary>
        /// 考勤记录下载
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <returns></returns>
        [HttpPost]
        [Route("download/vacation/{allotId}")]
        public IActionResult DownloadVacation(int allotId)
        {
            List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>()
            {
                new ExcelDownloadHeads { Alias = "姓名", Name = nameof(RecordAttendcance.PersonnelName) },
                new ExcelDownloadHeads { Alias = "员工号", Name = nameof(RecordAttendcance.PersonnelNumber) },
                new ExcelDownloadHeads { Alias = "考勤类型", Name = nameof(RecordAttendcance.AttendanceName) },
                new ExcelDownloadHeads { Alias = "开始时问", Name = nameof(RecordAttendcance.BegDate) },
                new ExcelDownloadHeads { Alias = "结束时间", Name = nameof(RecordAttendcance.EndDate) },
                new ExcelDownloadHeads { Alias = "天数", Name = nameof(RecordAttendcance.Days) },
            };

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

            var filepath = _attendanceService.ExcelDownload(rows, "考勤记录", allotId, excelDownloadHeads);

            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));
        }


        /// <summary>
        /// 调动记录下载
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <returns></returns>
        [HttpPost]
        [Route("download/callin/{allotId}")]
        public IActionResult DownloadCallIn(int allotId)
        {
            List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>()
            {
                new ExcelDownloadHeads { Alias = "姓名", Name = nameof(view_attendance.PersonnelName) },
                new ExcelDownloadHeads { Alias = "员工号", Name = nameof(view_attendance.PersonnelNumber) },
                new ExcelDownloadHeads { Alias = "调入核算单元", Name = nameof(view_attendance.AccountingUnit) },
                new ExcelDownloadHeads { Alias = "调入组别", Name = nameof(view_attendance.UnitType) },
                new ExcelDownloadHeads { Alias = "调入时间", Name = nameof(view_attendance.AttendanceDate) },
            };

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

            var filepath = _attendanceService.ExcelDownload(rows, "调动记录", allotId, excelDownloadHeads);

            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));
        }

        /// <summary>
        /// 生成最终考勤结果下载
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <returns></returns>
        [HttpPost]
        [Route("download/statistics/{allotId}")]
        public IActionResult DownloadStatistics(int allotId)
        {
            List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>()
            {
               new ExcelDownloadHeads { Alias = "核算组别", Name = nameof(AttendanceStatistics.UnitType) },
               new ExcelDownloadHeads { Alias = "核算单元名称", Name = nameof(AttendanceStatistics.AccountingUnit) },
               new ExcelDownloadHeads { Alias = "姓名", Name = nameof(AttendanceStatistics.PersonnelName) },
               new ExcelDownloadHeads { Alias = "员工号", Name = nameof(AttendanceStatistics.PersonnelNumber) },
               new ExcelDownloadHeads { Alias = "在科开始时问", Name = nameof(AttendanceStatistics.BeginDate) },
               new ExcelDownloadHeads { Alias = "在科结束时间", Name = nameof(AttendanceStatistics.EndDate) },
               new ExcelDownloadHeads { Alias = "人员系数", Name = nameof(AttendanceStatistics.PermanentStaff) },
            };
            var type = _attendanceService.GetAttendanceType(allotId);
            foreach (var item in type.Data)
            {
                excelDownloadHeads.Add(new ExcelDownloadHeads() { Alias = item.AttendanceName, Name = item.AttendanceName });
            }
            excelDownloadHeads.Add(new ExcelDownloadHeads() { Alias = "出勤天数", Name = "AttendanceDays" });
            var userid = claim.GetUserId();
            var result = _attendanceService.GetAttendanceStatistics(allotId, userid).Data;

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

            var filepath = _attendanceService.ExcelDownload(rows, "最终考勤结果", allotId, excelDownloadHeads);

            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));
            /*var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Template", "医院人员绩效模板.xlsx");
            var memoryStream = new MemoryStream();
            using (var stream = new FileStream(path, FileMode.Open))
            {
                stream.CopyToAsync(memoryStream).Wait();
            }
            memoryStream.Seek(0, SeekOrigin.Begin);
            var provider = new FileExtensionContentTypeProvider();
            var memi = provider.Mappings[".xlsx"];
            return File(memoryStream, memi, Path.GetFileName(path));*/

        }

        /// <summary>
        /// 科室确认详情(已下发结果展示列表)下载
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="unitType">人员类别</param>
        /// <param name="accountingUnit">核算单元</param>
        /// <returns></returns>
        [HttpPost]
        [Route("download/auditDetail")]
        public IActionResult DownloadAuditDetail(int allotId, string unitType, string accountingUnit, string searchTxet)
        {
            List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>()
            {
               new ExcelDownloadHeads { Alias = "核算组别", Name = nameof(AttendanceStatistics.UnitType) },
               new ExcelDownloadHeads { Alias = "核算单元名称", Name = nameof(AttendanceStatistics.AccountingUnit) },
               new ExcelDownloadHeads { Alias = "姓名", Name = nameof(AttendanceStatistics.PersonnelName) },
               new ExcelDownloadHeads { Alias = "员工号", Name = nameof(AttendanceStatistics.PersonnelNumber) },
               new ExcelDownloadHeads { Alias = "在科开始时问", Name = nameof(AttendanceStatistics.BeginDate) },
               new ExcelDownloadHeads { Alias = "在科结束时间", Name = nameof(AttendanceStatistics.EndDate) },
               new ExcelDownloadHeads { Alias = "人员系数", Name = nameof(AttendanceStatistics.PermanentStaff) },
            };

            var userid = claim.GetUserId();
            var result = _attendanceService.AuditDetail(allotId, unitType, accountingUnit, searchTxet, userid).Data;
            foreach (var item in result.SelectMany(w => w.Detial).Select(w => w.Title).Distinct())
            {
                excelDownloadHeads.Add(new ExcelDownloadHeads() { Alias = item, Name = item });
            }
            excelDownloadHeads.Add(new ExcelDownloadHeads() { Alias = "出勤天数", Name = "AttendanceDays" });

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

            var filepath = _attendanceService.ExcelDownload(rows, "最终考勤结果", allotId, excelDownloadHeads);

            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));
        }
        #endregion

        #region 最终考勤结果
        /// <summary>
        /// 科室确认列表
        /// </summary>
        /// <param name="allotId">绩效Id</param>
        /// <param name="unitType">人员类别</param>
        /// <param name="accountingUnit">核算单元</param>
        /// <param name="state"> 操作类型  全部=0，未确认 = 1,确认 = 2,驳回 = 3,</param>
        /// <returns></returns>
        [HttpPost]
        [Route("issue/audit/list")]
        public ApiResponse<List<AttendanceAuditList>> AuditList(int allotId, string unitType, string accountingUnit, Attendance.State state)
        {

            return _attendanceService.AuditList(allotId, unitType, accountingUnit, state);
        }

        /// <summary>
        /// 科室确认详情(已下发结果展示列表)
        /// </summary>
        /// <param name="allotId">绩效Id</param>
        /// <param name="unitType"> 人员类别</param>
        /// <param name="accountingUnit">核算单元</param>
        /// <param name="searchTxet">搜索文本框（姓名\工号）</param>
        /// <returns></returns>
        [HttpPost]
        [Route("issue/audit/detail")]
        public ApiResponse<List<AttendanceAuditDetail>> AuditDetail(int allotId, string unitType, string accountingUnit, string searchTxet)
        {
            var userid = claim.GetUserId();
            return _attendanceService.AuditDetail(allotId, unitType, accountingUnit, searchTxet, userid);
        }

        /// <summary>
        /// 最终考勤结果下发(预确认显示)
        /// </summary>
        /// <param name="allotId">绩效Id</param>
        /// <param name="unitType">人员类别</param>
        /// <param name="accountingUnit">核算单元</param>
        /// <param name="state"> 操作类型 新增 = 1, 修改 = 2, 删除 = 3,</param>
        /// <returns></returns>
        [HttpPost]
        [Route("issue/check")]
        public ApiResponse<List<PerAttendanceIssueDto>> PreConfirmationDisplay(int allotId, string unitType, string accountingUnit, Attendance.OperationType state)
        {
            var userid = claim.GetUserId();
            return _attendanceService.PreConfirmationDisplay(allotId, userid, unitType, accountingUnit, state);
        }

        /// <summary>
        /// 最终考勤结果下发
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <returns></returns>
        [HttpPost]
        [Route("issue/confirm")]
        public ApiResponse IssueStatistics(int allotId)
        {
            var userid = claim.GetUserId();
            var realName = claim.GetUserClaim(JwtClaimTypes.RealName);
            return _attendanceService.IssueStatistics(allotId, userid, realName);
        }

        /// <summary>
        /// 最终考勤结果驳回或确认无误((批量操作)
        /// </summary>
        /// <param name="attendanceIssueChoose"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("issue/choose")]
        public ApiResponse ChooseStatistics(AttendanceIssueChoose attendanceIssueChoose)
        {
            var userid = claim.GetUserId();
            var realName = claim.GetUserClaim(JwtClaimTypes.RealName);
            return _attendanceService.ChooseStatistics(attendanceIssueChoose, userid, realName);
        }
        #endregion


        #region 考勤上报
        /// <summary>
        /// 科室上报审核列表
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="unitType">核算组别</param>
        /// <param name="accountingUnit">核算单元</param>
        /// <param name="state"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("dept/audit/list")]
        public ApiResponse<List<AttendanceDeptAuditList>> DeptAuditList(int allotId, string unitType, string accountingUnit, int? state = -1)
        {
            return _attendanceService.DeptAuditList(allotId, unitType, accountingUnit, state ?? -1);
        }

        /// <summary>
        /// 科室考勤上报录入状态
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="unitType">核算组别</param>
        /// <returns></returns>
        [HttpPost]
        [Route("dept/state")]
        public ApiResponse<AttendanceDeptState> DeptState(int allotId, string unitType)
        {
            var userid = claim.GetUserId();
            return _attendanceService.DeptState(allotId, userid, unitType);
        }

        /// <summary>
        /// 科室考勤上报录入加载
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <returns></returns>
        [HttpPost]
        [Route("dept/load")]
        public ApiResponse DeptLoad(int allotId)
        {
            var userid = claim.GetUserId();
            var realName = claim.GetUserClaim(JwtClaimTypes.RealName);
            return _attendanceService.DeptLoad(allotId, userid, realName);
        }

        /// <summary>
        /// 科室考勤上报录入保存
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="unitType">核算组别</param>
        /// <param name="datas"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("dept/save")]
        public ApiResponse DeptSave(int allotId, string unitType, [FromBody] List<AttendanceDept> datas)
        {
            var userid = claim.GetUserId();
            var realName = claim.GetUserClaim(JwtClaimTypes.RealName);
            if (!Enum.TryParse(unitType, out UnitType unitType1))
                throw new PerformanceException("核算组别错误");

            return _attendanceService.DeptSave(allotId, datas, unitType, userid, realName);
        }

        /// <summary>
        /// 科室考勤上报录入结果统计
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="unitType">核算组别</param>
        /// <param name="accountingUnit">核算单元</param>
        /// <param name="searchTxet">工号/姓名</param>
        /// <param name="datas"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("dept/compute")]
        public ApiResponse<List<AttendanceDeptReport>> DeptCompute(int allotId, string unitType, string accountingUnit, string searchTxet)
        {
            if (!Enum.TryParse(unitType, out UnitType unitType1))
                throw new PerformanceException("核算组别错误");

            return _attendanceService.DeptComputeReport(allotId, unitType, accountingUnit, searchTxet);
        }

        /// <summary>
        /// 科室考勤上报录入结果统计下载
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="unitType">核算组别</param>
        /// <param name="accountingUnit">核算单元</param>
        /// <param name="searchTxet">工号/姓名</param>
        /// <returns></returns>
        [HttpPost]
        [Route("dept/download/compute")]
        public IActionResult DownloadDeptCompute(int allotId, string unitType, string accountingUnit, string searchTxet)
        {
            if (!Enum.TryParse(unitType, out UnitType unitType1))
                throw new PerformanceException("核算组别错误");
            if (string.IsNullOrEmpty(accountingUnit))
                throw new PerformanceException("核算单元错误");

            List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>()
            {
               new ExcelDownloadHeads { Alias = "核算组别", Name = nameof(AttendanceStatistics.UnitType) },
               new ExcelDownloadHeads { Alias = "核算单元名称", Name = nameof(AttendanceStatistics.AccountingUnit) },
               new ExcelDownloadHeads { Alias = "姓名", Name = nameof(AttendanceStatistics.PersonnelName) },
               new ExcelDownloadHeads { Alias = "员工号", Name = nameof(AttendanceStatistics.PersonnelNumber) },
               new ExcelDownloadHeads { Alias = "人员系数", Name = nameof(AttendanceStatistics.PermanentStaff) },
            };

            var res = _attendanceService.DeptComputeReport(allotId, unitType, accountingUnit, searchTxet);
            var result = (res?.Data == null) ? new List<AttendanceDeptReport>() : res.Data;
            foreach (var item in result.SelectMany(w => w.Detial).Select(w => w.Title).Distinct())
            {
                excelDownloadHeads.Add(new ExcelDownloadHeads() { Alias = item, Name = item });
            }
            excelDownloadHeads.Add(new ExcelDownloadHeads() { Alias = "出勤天数", Name = "AttendanceDays" });

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

            var filepath = _attendanceService.ExcelDownload(rows, "考勤上报统计", allotId, excelDownloadHeads);

            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));
        }

        /// <summary>
        /// 科室考勤上报录入提交
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="unitType">核算组别</param>
        /// <param name="datas"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("dept/submit")]
        public ApiResponse DeptSubmit(int allotId, string unitType, [FromBody] List<AttendanceDept> datas)
        {
            var userid = claim.GetUserId();
            var realName = claim.GetUserClaim(JwtClaimTypes.RealName);
            var saveRes = _attendanceService.DeptSave(allotId, datas, unitType, userid, realName);
            if (saveRes.State != ResponseType.OK)
                return saveRes;

            return _attendanceService.DeptSubmit(allotId, unitType, userid, realName);
        }

        /// <summary>
        /// 科室考勤上报录入撤回
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="unitType">核算组别</param>
        /// <returns></returns>
        [HttpPost]
        [Route("dept/rollback")]
        public ApiResponse DeptRollback(int allotId, string unitType)
        {
            var userid = claim.GetUserId();
            var realName = claim.GetUserClaim(JwtClaimTypes.RealName);
            return _attendanceService.DeptRollback(allotId, unitType, userid, realName);
        }

        /// <summary>
        /// 科室考勤上报结果审核
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="unitType">核算组别</param>
        /// <param name="accountingUnit">核算单元</param>
        /// <param name="audit"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("dept/audit")]
        public ApiResponse DeptAudit(int allotId, string unitType, string accountingUnit, [FromBody] AttendanceDeptAudit audit)
        {
            if (audit == null)
                throw new PerformanceException("审核参数错误");
            if (string.IsNullOrEmpty(unitType) || string.IsNullOrEmpty(accountingUnit))
                throw new PerformanceException("核算单元及组别信息错误");

            var states = new int[] { (int)Attendance.Report.通过, (int)Attendance.Report.驳回, };
            if (!states.Contains(audit.State))
                throw new PerformanceException("暂不支持当前审核模式");

            var realName = claim.GetUserClaim(JwtClaimTypes.RealName);
            return _attendanceService.DeptAudit(allotId, unitType, accountingUnit, audit.State, audit.Remark, realName);
        }

        /// <summary>
        /// 科室考勤上报结果详情
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="unitType">核算组别</param>
        /// <param name="accountingUnit">核算单元</param>
        /// <param name="searchTxet">工号/姓名</param>
        /// <returns></returns>
        [HttpPost]
        [Route("dept/detail")]
        public ApiResponse<AttendanceDeptDetail> DeptDetail(int allotId, string unitType, string accountingUnit, string searchTxet)
        {
            return _attendanceService.DeptDetail(allotId, unitType, accountingUnit, searchTxet);
        }

        /// <summary>
        /// 科室考勤上报结果详情下载
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="unitType">核算组别</param>
        /// <param name="accountingUnit">核算单元</param>
        /// <param name="searchTxet">工号/姓名</param>
        /// <returns></returns>
        [HttpPost]
        [Route("dept/detail/download")]
        public IActionResult DeptDetailDownload(int allotId, string unitType, string accountingUnit, string searchTxet)
        {
            if (!Enum.TryParse(unitType, out UnitType unitType1))
                throw new PerformanceException("核算组别错误");

            var res = _attendanceService.DeptDetail(allotId, unitType, accountingUnit, searchTxet);
            var heads = res.Data.Columns.Select(w => new ExcelDownloadHeads { Alias = w.Title, Name = w.Field }).ToList();
            var rows = JsonHelper.Deserialize<List<Dictionary<string, object>>>(JsonHelper.Serialize(res.Data.Data));

            var filepath = _attendanceService.ExcelDownload(rows, "科室考勤上报结果详情", allotId, heads);

            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));
        }

        /// <summary>
        /// 科室考勤上报汇总统计
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="unitType">核算组别</param>
        /// <param name="accountingUnit">核算单元</param>
        /// <param name="searchTxet">工号/姓名</param>
        /// <returns></returns>
        /// <exception cref="PerformanceException"></exception>
        [HttpPost]
        [Route("dept/report")]
        public ApiResponse<List<AttendanceDeptReport>> DeptReport(int allotId, string unitType, string accountingUnit, string searchTxet)
        {
            return _attendanceService.DeptReport(allotId, unitType, accountingUnit, searchTxet);
        }

        /// <summary>
        /// 科室考勤上报汇总数据刷新
        /// </summary>
        /// <param name="allotId"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("dept/report/refresh")]
        public ApiResponse DeptReportRefresh(int allotId)
        {
            _attendanceService.DeptReportRefresh(allotId, (int)Attendance.Report.通过);
            return new ApiResponse(ResponseType.OK, "刷新成功");
        }

        /// <summary>
        /// 科室考勤上报汇总统计下载
        /// </summary>
        /// <param name="allotId">绩效月ID</param>
        /// <param name="unitType">核算组别</param>
        /// <param name="accountingUnit">核算单元</param>
        /// <param name="searchTxet">工号/姓名</param>
        /// <returns></returns>
        [HttpPost]
        [Route("dept/download/report")]
        public IActionResult DownloadDeptReport(int allotId, string unitType, string accountingUnit, string searchTxet)
        {
            List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>()
            {
               new ExcelDownloadHeads { Alias = "核算组别", Name = nameof(AttendanceStatistics.UnitType) },
               new ExcelDownloadHeads { Alias = "核算单元名称", Name = nameof(AttendanceStatistics.AccountingUnit) },
               new ExcelDownloadHeads { Alias = "姓名", Name = nameof(AttendanceStatistics.PersonnelName) },
               new ExcelDownloadHeads { Alias = "员工号", Name = nameof(AttendanceStatistics.PersonnelNumber) },
               new ExcelDownloadHeads { Alias = "在科开始时问", Name = nameof(AttendanceStatistics.BeginDate) },
               new ExcelDownloadHeads { Alias = "在科结束时间", Name = nameof(AttendanceStatistics.EndDate) },
               new ExcelDownloadHeads { Alias = "人员系数", Name = nameof(AttendanceStatistics.PermanentStaff) },
            };

            var res = _attendanceService.DeptReport(allotId, unitType, accountingUnit, searchTxet);
            var result = (res?.Data == null) ? new List<AttendanceDeptReport>() : res.Data;
            foreach (var item in result.SelectMany(w => w.Detial).Select(w => w.Title).Distinct())
            {
                excelDownloadHeads.Add(new ExcelDownloadHeads() { Alias = item, Name = item });
            }
            excelDownloadHeads.Add(new ExcelDownloadHeads() { Alias = "出勤天数", Name = "AttendanceDays" });

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

            var filepath = _attendanceService.ExcelDownload(rows, "科室上报考勤结果统计", allotId, excelDownloadHeads);

            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));
        }

        #endregion
    }
}