using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Exceptions;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using Siger.ApiQMS.Utility;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.QmsRepository.Repositories.Interface;
using Siger.Middlelayer.QmsRepository.Request;
using Siger.Middlelayer.QmsRepository.Response;
using Siger.Middlelayer.QmsRepository.Entities;
using System.Linq.Expressions;
using Siger.Middlelayer.Repository.Extensions;
using Siger.ApiCommon.Result;
using Siger.Middlelayer.Repository.Paged;
using Siger.Middlelayer.Utility.ImportEntities;
using Siger.Middlelayer.Common.AppSettings;
using System.IO;
using Siger.Middlelayer.Utility.Helpers;
using Siger.ApiCommon.Utilities;
using Siger.Middlelayer.Common.Log;
using Siger.Middlelayer.Repository.Repositories.Interface;
using System.Text;
using Siger.ApiCommon.Filters;
using System.Net.Http;
using System.Net;
using System.Net.Http.Headers;
using Siger.Middlelayer.Repository.Response;

namespace Siger.ApiQMS.Controllers
{
    public class SensorController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IQmsSensorTypeRepository _qmsSensorType;
        private readonly IQmsSensorParameterRepository _qmsSensorParameter;
        private readonly IQmsSensorFileRepository _qmsSensorFile;
        private readonly IQmsSensorDetailRepository _qmsSensorDetail;
        private readonly ISigerProjectLevelSectionRepository _projectLevelSection;
        private readonly ISigerProjectUserRepository _projectUser;
        private readonly ISigerProjectLevelSectionMachineRepository _levelSectionMachine;
        private readonly ISigerProjectMachineRepository _machine;
        private readonly ISigerProjectMachineExtendRepository _machineExtend;
        private readonly ISigerDict _dict;
        private readonly ISigerProjectEmailConfig _projectEmailConfig;

        public SensorController(IUnitOfWork unitOfWork, IQmsSensorTypeRepository qmsSensorType, IQmsSensorParameterRepository qmsSensorParameter, IQmsSensorFileRepository qmsSensorFile
            , ISigerProjectLevelSectionRepository projectLevelSection, ISigerProjectUserRepository projectUser, IQmsSensorDetailRepository qmsSensorDetail,
            ISigerProjectLevelSectionMachineRepository levelSectionMachine, ISigerProjectMachineRepository machine, ISigerProjectMachineExtendRepository machineExtend,
            ISigerDict dict, ISigerProjectEmailConfig projectEmailConfig)
        {
            _unitOfWork = unitOfWork;
            _qmsSensorType = qmsSensorType;
            _qmsSensorParameter = qmsSensorParameter;
            _qmsSensorFile = qmsSensorFile;
            _projectLevelSection = projectLevelSection;
            _projectUser = projectUser;
            _qmsSensorDetail = qmsSensorDetail;
            _levelSectionMachine = levelSectionMachine;
            _machine = machine;
            _machineExtend = machineExtend;
            _dict = dict;
            _projectEmailConfig = projectEmailConfig;
        }
        #region 传感器类型
        /// <summary>
        /// 添加传感器类型
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult AddSensorType([FromBody]RequestSensorTypeData request)
        {
            var fid = IdHelper.Generate<string>();
            var data = _qmsSensorType.Get(f => f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid && f.title.Equals(request.title));
            if (data != null)
            {
                throw new BadRequestException(CommonEnum.RecordExits);
            }
            _qmsSensorType.Insert(new siger_qms_sensor_type
            {
                parentid = request.parentid,
                title = request.title,
                projectid = ProjectId,
                fid = fid
            });
            //插入siger_qms_sensor_file
            foreach (var item in request.file)
            {
                if (!string.IsNullOrEmpty(item.file_name) && !string.IsNullOrEmpty(item.file_url))
                {
                    _qmsSensorFile.Insert(new siger_qms_sensor_file
                    {
                        fid = fid,
                        file_name = item.file_name,
                        file_url = item.file_url,
                        projectid = ProjectId,
                        type = (int)SensorFileType.Template
                    });
                }
            }
            foreach (var item in request.validation_file)
            {
                if (!string.IsNullOrEmpty(item.file_name) && !string.IsNullOrEmpty(item.file_url))
                {
                    _qmsSensorFile.Insert(new siger_qms_sensor_file
                    {
                        fid = fid,
                        file_name = item.file_name,
                        file_url = item.file_url,
                        projectid = ProjectId,
                        type = (int)SensorFileType.Validation
                    });
                }
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 修改传感器类型
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ModifySensorType([FromBody]RequestSensorTypeData request)
        {
            var data = _qmsSensorType.Get(f => f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid && f.id.Equals(request.id));
            var fid = IdHelper.Generate<string>();
            if (data == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            //历史文件置为无效
            if (!string.IsNullOrEmpty(data.fid))
            {
                fid = data.fid;
                var file = _qmsSensorFile.GetList(f => f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid && f.fid.Equals(fid));
                foreach (var item in file)
                {
                    item.status = (int)RowState.Invalid;
                    _qmsSensorFile.Update(item);
                }
            }
            //插入siger_qms_sensor_file
            foreach (var item in request.file)
            {
                if (!string.IsNullOrEmpty(item.file_name) && !string.IsNullOrEmpty(item.file_url))
                {
                    _qmsSensorFile.Insert(new siger_qms_sensor_file
                    {
                        fid = fid,
                        file_name = item.file_name,
                        file_url = item.file_url,
                        projectid = ProjectId,
                        type = (int)SensorFileType.Template
                    });
                }

            }
            foreach (var item in request.validation_file)
            {
                if (!string.IsNullOrEmpty(item.file_name) && !string.IsNullOrEmpty(item.file_url))
                {
                    _qmsSensorFile.Insert(new siger_qms_sensor_file
                    {
                        fid = fid,
                        file_name = item.file_name,
                        file_url = item.file_url,
                        projectid = ProjectId,
                        type = (int)SensorFileType.Validation
                    });
                }
            }
            //修改siger_qms_sensor_type
            data.parentid = request.parentid;
            data.title = request.title;
            _qmsSensorType.Update(data);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 删除传感器类型
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult DeleteSensorType(int id)
        {
            var data = _qmsSensorType.Get(f => f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid && f.id.Equals(id));
            if (data == null)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            //检查是否存在子集
            var son = _qmsSensorType.GetList(f => f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid && f.parentid.Equals(id));
            if (son.Any())
            {
                Logger.WriteLineInfo($"DeleteSensorType{id}你都存在子集了还想删！");
                throw new BadRequestException(QMSEnum.SensorTypeUsed);
            }
            //是否正在使用
            var parameter = _qmsSensorParameter.GetList(f => f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid && f.typeid.Equals(id));
            if (parameter.Any())
            {
                Logger.WriteLineInfo($"DeleteSensorType{id}传感器类型已经被使用了！");
                throw new BadRequestException(QMSEnum.SensorTypeUsed);
            }
            //历史文件置为无效
            if (!string.IsNullOrEmpty(data.fid))
            {
                var file = _qmsSensorFile.GetList(f => f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid && f.fid.Equals(data.fid));
                foreach (var item in file)
                {
                    item.status = (int)RowState.Invalid;
                    _qmsSensorFile.Update(item);
                }
            }
            //修改siger_qms_sensor_type
            data.status = (int)RowState.Invalid;
            _qmsSensorType.Update(data);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 获取传感器类别
        /// </summary>
        /// <param name="parentid">id</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetParentSensorType(int parentid)
        {
            var model = _qmsSensorType.GetList(f => f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid && f.parentid.Equals(parentid)).ToList();
            return new ObjectResult(model);
        }
        /// <summary>
        /// 获取子级类别
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetSonSensorType()
        {
            var model = _qmsSensorType.GetList(f => f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid && !f.parentid.Equals(0)).ToList();
            return new ObjectResult(model);
        }
        /// <summary>
        /// 获取传感器类型
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetSensorType([FromBody]RequestSensorTypeData request)
        {
            var ret = new List<ResponseSensorType>();
            var sensorModel = _qmsSensorType.GetList(f => f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid);
            Expression<Func<siger_qms_sensor_type, bool>> funCommon = f => f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid;
            Expression<Func<siger_qms_sensor_type, bool>> funParent = f => true;
            Expression<Func<siger_qms_sensor_type, bool>> funId = f => true;
            Expression<Func<siger_qms_sensor_type, bool>> funTitle = f => true;
            if (request.parentid != 0)
            {
                funParent = f => f.parentid.Equals(request.parentid);
            }
            if (request.id != 0)
            {
                funId = f => f.id.Equals(request.id);
            }
            if (!string.IsNullOrEmpty(request.title))
            {
                funTitle = f => f.title.Contains(request.title);
            }
            var predicates = funCommon.And(funParent).And(funId).And(funTitle);
            var data = _qmsSensorType.GetPagedList(request.page, request.pagesize, predicates, "parentid");
            foreach (var item in data.Data)
            {
                var temp = Mapper<siger_qms_sensor_type, ResponseSensorType>.Map(item);
                temp.parent = sensorModel.Where(f => f.id.Equals(temp.parentid)).Select(s => s.title).FirstOrDefault() ?? "";
                var fileModel = _qmsSensorFile.GetList(f => f.fid.Equals(temp.fid) && f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid);
                if (fileModel.Any())
                {
                    foreach (var file in fileModel)
                    {
                        if (file.type == (int)SensorFileType.Template)
                        {
                            temp.file.Add(new ResponseSensorFileData
                            {
                                file_name = file.file_name,
                                file_url = file.file_url,
                                id = file.id
                            });
                        }
                        else if (file.type == (int)SensorFileType.Validation)
                        {
                            temp.validation_file.Add(new ResponseSensorFileData
                            {
                                file_name = file.file_name,
                                file_url = file.file_url,
                                id = file.id
                            });
                        }
                    }
                }
                ret.Add(temp);
            }
            return new PagedObjectResult(ret, data.Total, request.page, request.pagesize);
        }
        /// <summary>
        /// 传感器参考规范编辑
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult SetSensorParam([FromBody]RequestSensorTypeParam req)
        {
            if (req.id.Any())
            {
                var model = _qmsSensorType.GetList(f => f.status == (int)RowState.Valid && f.projectid.Equals(ProjectId) && req.id.Contains(f.id));
                if (!model.Any())
                {
                    throw new BadRequestException(CommonEnum.RecordNotFound);
                }
                foreach (var item in model)
                {
                    item.standard_procedure = req.standard_procedure;
                    item.validation_manual = req.validation_manual;
                    _qmsSensorType.Update(item);
                }
            }
            //前台不传id那只能全部更新了！（此处代码不应如此处理！）
            var allids = _qmsSensorType.GetList(f => f.status == (int)RowState.Valid && f.projectid.Equals(ProjectId)).Select(s => s.id).Distinct().ToList();
            foreach (var id in allids)
            {
                var model = _qmsSensorType.Get(f => f.id.Equals(id));
                model.standard_procedure = req.standard_procedure;
                model.validation_manual = req.validation_manual;
                _qmsSensorType.Update(model);
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 查询参考
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetSensorParam(int id)
        {
            var ret = new ResponseSensorParam();
            //前台不传id那只能随便取一条了！（此处代码不应如此处理！）
            if (id == 0)
            {
                var all = _qmsSensorType.Get(f => f.status == (int)RowState.Valid && f.projectid.Equals(ProjectId));
                if (all != null)
                {
                    ret = Mapper<siger_qms_sensor_type, ResponseSensorParam>.Map(all);
                }
                return new ObjectResult(ret);
            }
            var model = _qmsSensorType.Get(f => f.status == (int)RowState.Valid && f.projectid.Equals(ProjectId) && f.id.Equals(id));
            if (model != null)
            {
                ret = Mapper<siger_qms_sensor_type, ResponseSensorParam>.Map(model);
            }
            return new ObjectResult(ret);
        }
        [HttpGet]
        public IActionResult GetSensorTypeTree()
        {
            IQueryable<siger_qms_sensor_type> model = _qmsSensorType.GetList(f => f.status == (int)RowState.Valid && f.projectid.Equals(ProjectId));
            var ret = SensorTypeByid(model, 0);
            return new ObjectResult(ret);
        }

        private List<ResponseSensorTypeTree> SensorTypeByid(IQueryable<siger_qms_sensor_type> model, int id)
        {
            var ret = new List<ResponseSensorTypeTree>();
            var data = model.Where(f => f.parentid.Equals(id)).ToList();
            if (!data.Any())
            {
                return null;
            }
            foreach (var item in data)
            {
                var child = Mapper<siger_qms_sensor_type, ResponseSensorTypeTree>.Map(item);
                child.children = SensorTypeByid(model, item.id);
                ret.Add(child);
            }
            return ret;
        }
        /// <summary>
        /// 下载传感器类型模板
        /// </summary>
        /// <param name="id"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        [HttpGet]
        [NoTokenValidateFilter]
        [NoResultFilter]
        public IActionResult DownloadSensorType(int id, string name)
        {
            var file = _qmsSensorFile.Get(f => f.status == (int)RowState.Valid && f.id.Equals(id));
            if (file == null)
            {
                return new NoContentResult();
            }
            var fileSetting = Config<FileSettings>.Get();
            if (fileSetting == null)
            {
                return new NoContentResult();
            }

            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder);
           
            var url = file.file_url.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
            var length = url.Length;
            var path = Path.Combine(rootDir, url[length - 3], url[length - 2], url[length - 1]);
            if (!System.IO.File.Exists(path))
            {
                return new NoContentResult();
            }
            var filename = file.file_name;
            if (!string.IsNullOrEmpty(name))
            {
                filename = name;
            }
            try
            {
                var stream = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StreamContent(stream) };
                response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
                {
                    FileName = filename
                };
                return File(stream, "application/octet-stream");
            }
            catch
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
        }
        #endregion
        #region 传感器台账
        /// <summary>
        /// 新增传感器台账
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult AddSensorParameter([FromBody]RequestSensorParameterData request)
        {
            var newModel = Mapper<RequestSensorParameterData, siger_qms_sensor_parameter>.Map(request);
            if (request.qualities.Any())
            {
                int i = 0;
                foreach (var item in request.qualities)
                {
                    if (i > 0)
                    {
                        newModel.quality += ",";
                    }
                    newModel.quality += item;
                    i++;
                }
            }
            newModel.sensor_code = _qmsSensorParameter.CreateSensorCode(ProjectId);
            newModel.projectid = ProjectId;
            newModel.cycletime = _qmsSensorParameter.CalTimeStamp((CycleUnit)request.cycle_unit, request.cycle);

            var levelSection =
                _levelSectionMachine.Get(t => t.section_id == newModel.station && t.status == (int)RowState.Valid);
            if (levelSection == null)
            {
                throw new BadRequestException(RequestEnum.MachineNotFound);
            }
            if (!string.IsNullOrWhiteSpace(request.marktime) && DateTime.TryParse(request.marktime, out var dt))
            {
                newModel.mark_time = (int)UnixTimeHelper.ConvertDataTimeLong(dt);
                newModel.nexttime = newModel.cycletime + newModel.mark_time;
                newModel.status = (int)SensorStatus.Normal;
                //下次标定类型
                var restTime = newModel.nexttime - UnixTimeHelper.GetNow();
                if (restTime > newModel.cycletime / 2)
                {
                    newModel.nextmark_type = 1;
                }
            }
            newModel.mid = levelSection.machine_id;
            _qmsSensorParameter.Insert(newModel);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 修改传感器台账
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ModifySensorParameter([FromBody]RequestSensorParameterData request)
        {
            var data = _qmsSensorParameter.Get(f => f.projectid.Equals(ProjectId) && f.status != (int)RowState.Invalid && f.id.Equals(request.id));
            if (data == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            data.station = request.station;
            data.model = request.model;
            data.name = request.name;
            data.range = request.range;
            data.typeid = request.typeid;
            data.cycle = request.cycle;
            data.cycle_unit = request.cycle_unit;
            data.factory_label = request.factory_label;
            data.alarm = request.alarm;
            data.cycletime = _qmsSensorParameter.CalTimeStamp((CycleUnit)request.cycle_unit, request.cycle);
            data.sensor_status = request.sensor_status;
            data.factory_precision = request.factory_precision;
            data.acceptable_precision1 = request.acceptable_precision1;
            data.acceptable_precision2 = request.acceptable_precision2;
            data.acceptable_precision3 = request.acceptable_precision3;
            data.acceptable_precision4 = request.acceptable_precision4;
            data.acceptable_precision5 = request.acceptable_precision5;
            data.mark_place = request.mark_place;
            data.external_system = request.external_system;
            data.bind_manual = request.bind_manual;
            data.validation_manual = request.validation_manual;
            data.standard_procedure1 = request.standard_procedure1;
            data.standard_procedure2 = request.standard_procedure2;
            data.temperature = request.temperature;
            data.remark = request.remark;
            data.humidity = request.humidity;
            data.position = request.position;
            if (!string.IsNullOrWhiteSpace(request.marktime) && DateTime.TryParse(request.marktime, out var dt))
            {
                data.mark_time = (int)UnixTimeHelper.ConvertDataTimeLong(dt);
            }
            //计算新的标定时间
            if (data.mark_time != 0)
            {
                data.nexttime = data.cycletime + data.mark_time;
                //下次标定类型
                var restTime = data.nexttime - UnixTimeHelper.GetNow();
                if (restTime > data.cycletime / 2)
                {
                    data.nextmark_type = 1;
                }
            }
            var quality = string.Empty;
            if (request.qualities.Any())
            {
                int i = 0;
                foreach (var item in request.qualities)
                {
                    if (i > 0)
                    {
                        quality += ",";
                    }
                    quality += item;
                    i++;
                }
            }
            var levelSection = _levelSectionMachine.Get(t => t.section_id == data.station && t.status == (int)RowState.Valid);
            if (levelSection == null || levelSection.machine_id == 0)
            {
                throw new BadRequestException(RequestEnum.MachineNotFound);
            }
            data.mid = levelSection.machine_id;

            data.quality = quality;
            data.calibration_source = request.calibration_source;
            data.sensor1 = request.sensor1;
            data.sensor2 = request.sensor2;
            data.sensor3 = request.sensor3;
            data.sensor4 = request.sensor4;
            data.verification = request.verification;
            data.mark_uid = request.mark_uid;
            _qmsSensorParameter.Update(data);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 删除传感器台账
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult DeleteSensorParameter(int id)
        {
            var data = _qmsSensorParameter.Get(f => f.projectid.Equals(ProjectId) && f.status != (int)RowState.Invalid && f.id.Equals(id));
            if (data == null)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            //查看是否有详情信息
            var detail = _qmsSensorDetail.GetList(f => f.projectid.Equals(ProjectId) && f.status != (int)RowState.Invalid && f.sensor_code.Equals(data.sensor_code));
            if (detail.Any())
            {
                Logger.WriteLineInfo($"DeleteSensorParameter{data.sensor_code}传感器存在标定信息！");
                throw new BadRequestException(QMSEnum.DetailCanNotDelete);
            }
            data.status = (int)RowState.Invalid;
            _qmsSensorParameter.Update(data);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 查询传感器台账
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetSensorParameter([FromBody]RequestSensorMark request)
        {
            var data = GetSensorParameterData(request);
            return new PagedObjectResult(data.Data, data.Total, request.page, request.pagesize);
        }
        /// <summary>
        /// 导出传感器台账
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ExportSensorParameter([FromBody]RequestSensorMark req)
        {
            req.pagesize = 10000;
            req.page = 1;
            var data = GetSensorParameterData(req).Data.ToList();
            var dataList = new List<SensorParameter>();
            data.ForEach(
                da =>
                {
                    var model = Mapper<ResponseSensorParameterData, SensorParameter>.Map(da);
                    model.verification = "否";
                    if (da.verification == 1)
                    {
                        model.verification = "是";
                    }
                    dataList.Add(model);
                }
                );

            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
           
            if (dataList != null && dataList.Any())
            {
                EpPlusExcelHelper<SensorParameter> helper = null;
                try
                {
                    helper = new EpPlusExcelHelper<SensorParameter>();
                    var temporaryFileName = $"传感器台账-{DateTime.Now:yyyyMMddHHmmss}.xlsx";
                    helper.GenerateExcel(dataList, Path.Combine(rootDir, temporaryFileName));
                    return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
                }
                catch (Exception e)
                {
                    Logger.WriteLineError("Export failed, error:" + e);
                    throw new BadRequestException(RequestEnum.ExportFailed);
                }
                finally
                {
                    helper?.Dispose();
                }
            }
            return new ObjectResult(CommonEnum.Succefull);
        }
        /// <summary>
        /// 预览文本文件
        /// </summary>
        /// <param name="file_name"></param>
        /// <param name="file_url"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult PreviewFile(string file_name, string file_url)
        {
            if (string.IsNullOrWhiteSpace(file_name))
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            if (file_name.EndsWith(".txt") == false)
            {
                throw new BadRequestException(RequestEnum.CannotPreviewThisFile);
            }
            var fileSetting = Config<FileSettings>.Get();
            if (fileSetting == null)
            {
                throw new BadRequestException(CommonEnum.ConfigError);
            }
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder);
          

            var url = file_url.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
            if (url.Length != 6)
            {
                throw new BadRequestException(RequestEnum.ErrorFilePath);
            }

            var path = Path.Combine(rootDir, url[3], url[4], url[5]);
            if (!System.IO.File.Exists(path))
            {
                throw new BadRequestException(RequestEnum.ErrorFilePath);
            }

            try
            {
                var lineContent = string.Empty;
                var encoding = FileHelper.GetType(path);
                if (!Equals(encoding, Encoding.UTF8))
                {
                    Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
                    encoding = Encoding.GetEncoding("gb2312");
                }

                var fs = new FileStream(path, FileMode.Open, FileAccess.Read);
                var sr = new StreamReader(fs, encoding);
                while (sr.Peek() != -1)
                {
                    lineContent += sr.ReadLine() + "<br>";
                }
                sr.Close();
                fs.Close();

                return new ObjectResult(lineContent);
            }
            catch
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
        }
        /// <summary>
        /// 根据类别获取传感器信息
        /// </summary>
        /// <param name="typeid"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetSensorByType(int typeid)
        {
            var data = _qmsSensorParameter.GetList(f => f.status != (int)RowState.Invalid && f.projectid.Equals(ProjectId) && f.typeid.Equals(typeid));
            return new ObjectResult(data);
        }
        #endregion
        #region 传感器标定
        /// <summary>
        /// 传感器状态查询
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetSensorStateData([FromBody]RequestSensorMark request)
        {
            var ret = GetSensorParameterData(request);
            return new PagedObjectResult(ret.Data, ret.Total);
        }
        /// <summary>
        /// 传感器状态导出
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ExportSensorStateData([FromBody]RequestSensorMark req)
        {
            req.pagesize = 10000;
            req.page = 1;
            var data = GetSensorParameterData(req).Data.ToList();
            var dataList = new List<SensorMark>();
            data.ForEach(
                da => dataList.Add(Mapper<ResponseSensorParameterData, SensorMark>.Map(da))
                );
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
            if (dataList != null && dataList.Any())
            {
                EpPlusExcelHelper<SensorMark> helper = null;
                try
                {
                    helper = new EpPlusExcelHelper<SensorMark>();
                    var temporaryFileName = $"传感器状态查询-{DateTime.Now:yyyyMMddHHmmss}.xlsx";
                    helper.GenerateExcel(dataList, Path.Combine(rootDir, temporaryFileName));
                    return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
                }
                catch (Exception e)
                {
                    Logger.WriteLineError("Export failed, error:" + e);
                    throw new BadRequestException(RequestEnum.ExportFailed);
                }
                finally
                {
                    helper?.Dispose();
                }
            }
            return new ObjectResult(CommonEnum.Succefull);
        }
        /// <summary>
        /// 根据typeid获取文件信息
        /// </summary>
        /// <param name="typeid"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetSensorFileData(int typeid, int type)
        {
            var typeModel = _qmsSensorType.Get(f => f.status == (int)RowState.Valid && f.projectid.Equals(ProjectId) && f.id.Equals(typeid));
            if (typeModel == null)
            {
                Logger.WriteLineInfo($"GetSensorFileData typeid:{typeid} vaild");
                throw new BadRequestException(CommonEnum.NoData);
            }
            var file = _qmsSensorFile.GetList(f => f.status == (int)RowState.Valid && f.projectid.Equals(ProjectId) && f.fid.Equals(typeModel.fid));
            if (!file.Any())
            {
                Logger.WriteLineInfo($"GetSensorFileData fid:{typeModel.fid} vaild");
                throw new BadRequestException(CommonEnum.NoData);
            }
            var ret = file.Where(f => f.type == type);
            return new ObjectResult(ret);
        }
        /// <summary>
        /// 标定
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult MarkSensor([FromBody]RequestMarkSensor req)
        {
            var model = _qmsSensorParameter.Get(f => f.status != (int)RowState.Invalid && f.projectid.Equals(ProjectId) && f.sensor_code.Equals(req.sensor_code));
            if (model == null)
            {
                throw new BadRequestException(QMSEnum.SensorNotExist);
            }
            //判断标定人
            if (!model.mark_uid.Equals(UserId))
            {
                throw new BadRequestException(QMSEnum.NotMarkUser);
            }
            var fid = IdHelper.Generate<string>();
            var historyfid = IdHelper.Generate<string>();
            var type = (int)SensorFileType.File;
            if (model.nextmark_type == 1)
            {
                type = (int)SensorFileType.ValidationFile;
            }
            //插入siger_qms_sensor_file
            foreach (var item in req.file)
            {
                if (!string.IsNullOrEmpty(item.file_name) && !string.IsNullOrEmpty(item.file_url))
                {
                    _qmsSensorFile.Insert(new siger_qms_sensor_file
                    {
                        fid = fid,
                        file_name = item.file_name,
                        file_url = item.file_url,
                        projectid = ProjectId,
                        type = type
                    });
                }
            }
            foreach (var item in req.history)
            {
                if (!string.IsNullOrEmpty(item.file_name) && !string.IsNullOrEmpty(item.file_url))
                {
                    _qmsSensorFile.Insert(new siger_qms_sensor_file
                    {
                        fid = historyfid,
                        file_name = item.file_name,
                        file_url = item.file_url,
                        projectid = ProjectId,
                        type = (int)SensorFileType.HistoryFile
                    });
                }
            }
            //插入siger_qms_sensor_detail
            var detail = Mapper<RequestMarkSensor, siger_qms_sensor_detail>.Map(req);
            detail.fid = fid;
            detail.uid = UserId;
            detail.projectid = ProjectId;
            detail.status = (int)SensorResult.WaitAudit;
            detail.upload_time = DateTime.Now;
            detail.history_fid = historyfid;
            _qmsSensorDetail.Insert(detail);
            //改状态
            model.status = (int)SensorStatus.Marking;
            model.mark_time = UnixTimeHelper.GetNow();
            model.nexttime = UnixTimeHelper.GetNow() + model.cycletime;
            model.result = req.result;
            model.mark_uid = UserId;
            _qmsSensorParameter.Update(model);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 传感器详情查询
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetSensorDetailData([FromBody]RequestSensorMark request)
        {
            var ret = GetSensorDetail(request);
            return new PagedObjectResult(ret.Data, ret.Total);
        }
        /// <summary>
        /// 删除传感器标定信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult DelteSensorDetailData(int id)
        {
            var data = _qmsSensorDetail.Get(f => f.status == (int)SensorResult.WaitAudit && f.projectid.Equals(ProjectId) && f.id.Equals(id));
            if (data == null)
            {
                throw new BadRequestException(QMSEnum.DetailCanNotDelete);
            }
            //文件删除
            var files = _qmsSensorFile.GetList(f => f.fid.Equals(data.fid) && f.status == (int)RowState.Valid).ToList();
            if (files.Any())
            {
                files.ForEach(f =>
                {
                    f.status = (int)RowState.Invalid;
                    _qmsSensorFile.Update(f);
                });
            }
            //详情信息删除
            data.status = (int)RowState.Invalid;
            _qmsSensorDetail.Update(data);
            //传感器状态更改
            var sensor = _qmsSensorParameter.Get(f => f.status == (int)SensorResult.WaitAudit && f.projectid.Equals(ProjectId) && f.sensor_code.Equals(data.sensor_code));
            if (sensor != null)
            {
                var resttime = sensor.nexttime - sensor.mark_time;
                if (resttime < 0)
                {
                    sensor.status = (int)SensorStatus.OverDue;
                }
                else if (resttime >= 0 && resttime <= 3600 * 24 * 30)
                {
                    sensor.status = (int)SensorStatus.WaitMark;
                }
                else
                {
                    sensor.status = (int)SensorStatus.OverDue;
                }
                _qmsSensorParameter.Update(sensor);
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 修改传感器标定信息
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ModifySensorDetailData([FromBody]RequestMarkSensor req)
        {
            req.projectid = ProjectId;
            req.uid = UserId;
            var ret = ModifySensorDetail(req);
            return ret;
        }

        /// <summary>
        /// 传感器标定明细导出
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ExportSensorDetailData([FromBody]RequestSensorMark req)
        {
            req.pagesize = 10000;
            req.page = 1;
            var data = _qmsSensorDetail.GetDetailData(req, ProjectId).Data.ToList();
            var dataList = new List<SensorDetail>();
            data.ForEach(da =>
            {
                da.reporttime = DateTime.Now.ToStr();
                da.reportname = $"{da.name}_{UnixTimeHelper.GetNow().ToStr()}";
                dataList.Add(Mapper<ResponseSensorReport, SensorDetail>.Map(da));
            });
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
            if (dataList != null && dataList.Any())
            {
                EpPlusExcelHelper<SensorDetail> helper = null;
                try
                {
                    helper = new EpPlusExcelHelper<SensorDetail>();
                    var temporaryFileName = $"传感器标定明细-{DateTime.Now:yyyyMMddHHmmss}.xlsx";
                    helper.GenerateExcel(dataList, Path.Combine(rootDir, temporaryFileName));
                    return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
                }
                catch (Exception e)
                {
                    Logger.WriteLineError("Export failed, error:" + e);
                    throw new BadRequestException(RequestEnum.ExportFailed);
                }
                finally
                {
                    helper?.Dispose();
                }
            }
            return new ObjectResult(CommonEnum.Succefull);
        }

        /// <summary>
        /// 下载标定报告
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult ExportSensorMarkReport(int id)
        {
            var req = new RequestSensorMark
            {
                id = id
            };
            var data = _qmsSensorDetail.GetDetailData(req, ProjectId).Data.ToList();
            var dataList = new List<SensorDetail>();
            data.ForEach(da =>
            {
                da.reporttime = DateTime.Now.ToStr();
                da.reportname = $"{da.name}_{UnixTimeHelper.GetNow().ToStr()}";
                dataList.Add(Mapper<ResponseSensorReport, SensorDetail>.Map(da));
            });

            //模板文件路径
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.MarkTempFileName);
            
            var template = _dict.Get(f => f.status == (int)RowState.Valid && f.projectId.Equals(ProjectId) && f.cat.Equals("MarkTemplate"));
            if (template == null)
            {
                throw new BadRequestException(QMSEnum.TemplateValid);
            }
            if (template.dkey == null)
            {
                throw new BadRequestException(QMSEnum.TemplateValid);
            }
            var templateFile = Path.Combine(rootDir, template.dkey);
            if (dataList != null && dataList.Any())
            {
                //EpPlusExcelHelper<SensorDetail> helper = null;
                NPOIExcelHelper<SensorDetail> helper = null;
                try
                {
                    var name = dataList.First().reportname;
                    helper = new NPOIExcelHelper<SensorDetail>();
                    var temporaryFileName = $"{name}.xls";
                    helper.GenerateExcelByTemplate(dataList, templateFile, Path.Combine(rootDir, temporaryFileName));
                    
                    return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.MarkTempFileName}/{temporaryFileName}");
                }
                catch (Exception e)
                {
                    Logger.WriteLineError("ExportSensorMarkReport failed, error:" + e);
                    throw new BadRequestException(RequestEnum.ExportFailed);
                }
                finally
                {
                    helper?.Dispose();
                }
            }
            return new ObjectResult(CommonEnum.Succefull);
        }

        /// <summary>
        /// 审批传感器标定信息
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [NoTokenValidateFilter]
        [NoResultFilter]
        [HttpPost]
        public IActionResult AuditSensorDetailData([FromBody]RequestApproveSensor req)
        {
            var type = 0;
            var uid = 0;
            var pid = 0;
            var status = 0;
            if (!CheckToken(req.token, ref uid, ref type, ref pid))
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            Expression<Func<siger_qms_sensor_detail, bool>> funCommon = f => f.projectid.Equals(pid) && req.ids.Contains(f.id);
            Expression<Func<siger_qms_sensor_detail, bool>> funType = f => true;
            switch (type)
            {
                case (int)SensorResult.WaitAudit:
                    funType = f => f.status == (int)SensorResult.WaitAudit && f.checkuser.Equals(uid);
                    status = (int)SensorResult.Audit;
                    break;
                case (int)SensorResult.SecondWaitAudit:
                    funType = f => f.status == (int)SensorResult.SecondWaitAudit && f.checkuser2.Equals(uid);
                    status = (int)SensorResult.Audit;
                    break;
                case (int)SensorResult.Audit:
                    funType = f => f.status == (int)SensorResult.Audit && f.approvaluser.Equals(uid);
                    status = (int)SensorResult.Pass;
                    break;
                default:
                    throw new BadRequestException(CommonEnum.Fail);
            }
            var predicates = funCommon.And(funType);
            var data = _qmsSensorDetail.GetList(predicates).ToList();
            if (!data.Any())
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            if (req.result.Equals("通过"))
            {
                foreach (var item in data)
                {
                    //筛选出二次审核的数据
                    if (type == (int)SensorResult.WaitAudit && item.checkuser2 != 0)
                    {
                        status = (int)SensorResult.SecondWaitAudit;
                    }
                    item.status = status;
                    if (type == (int)SensorResult.Audit)
                    {
                        item.approve_time = DateTime.Now;
                    }
                    _qmsSensorDetail.Update(item);
                }
                //如果是审核更新主表
                if (type == (int)SensorResult.Audit)
                {
                    var codes = data.Select(s => s.sensor_code).Distinct().ToList();
                    var sensor = _qmsSensorParameter.GetList(f => f.projectid.Equals(pid) && f.status != (int)RowState.Invalid && codes.Contains(f.sensor_code));
                    foreach (var item in sensor)
                    {
                        item.result = "通过";
                        item.status = (int)SensorStatus.Normal;
                        item.approve_time = UnixTimeHelper.GetNow();
                        if (item.nextmark_type == 1)//下次标定类型为验证的修改状态
                        {
                            item.nextmark_type = 0;
                        }
                        else//此处逻辑在job中也有印证
                        {
                            if (item.verification == 1)//下次标定类型为标定但是开启周期检查的数据
                            {
                                item.nextmark_type = 1;
                            }
                        }
                        //排除周期在30天之内的
                        if (item.cycletime < 30 * 24 * 3600)
                        {
                            item.status = (int)SensorStatus.WaitMark;
                        }
                        _qmsSensorParameter.Update(item);
                    }
                }
            }
            else//未通过
            {
                var codes = data.Select(s => s.sensor_code).Distinct().ToList();
                var sensor = _qmsSensorParameter.GetList(f => f.projectid.Equals(pid) && f.status != (int)RowState.Invalid && codes.Contains(f.sensor_code)).ToList();
                foreach (var item in sensor)
                {
                    var model = _qmsSensorParameter.Get(f => f.id.Equals(item.id));
                    var lasttime = model.nexttime - UnixTimeHelper.GetNow();
                    if (lasttime > 30 * 24 * 3600)
                    {
                        model.status = (int)SensorStatus.Normal;
                    }
                    else if (lasttime < 0)
                    {
                        model.status = (int)SensorStatus.OverDue;
                    }
                    else
                    {
                        model.status = (int)SensorStatus.WaitMark;
                    }
                    if (type == (int)SensorResult.Audit)
                        model.result = "不通过";
                    _qmsSensorParameter.Update(model);
                    SendMail(model.mark_uid, model.name, model.sensor_code, pid);
                }
                status = (int)SensorResult.NotPass;
                foreach (var item in data)
                {
                    item.status = status;
                    _qmsSensorDetail.Update(item);
                }
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(new { ret = 1, msg = 1, data = CommonEnum.Succefull });
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 修改标定信息
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [NoTokenValidateFilter]
        [NoResultFilter]
        [HttpPost]
        public IActionResult ModifySensorData([FromBody]RequestMarkSensor req)
        {
            var type = 0;
            var uid = 0;
            var pid = 0;
            if (!CheckToken(req.token, ref uid, ref type, ref pid))
            {
                throw new BadRequestException(QMSEnum.TokenValid);
            }
            if (type == (int)SensorResult.WaitAudit || type == (int)SensorResult.SecondWaitAudit)
            {
                req.uid = uid;
                req.projectid = pid;
                var ret = ModifySensorDetail(req);
                return new ObjectResult(new { ret = 1, msg = 1, data = ret });
            }
            return new ObjectResult(new { ret = 1, msg = QMSEnum.CannotModify, data = 0 });
        }
        /// <summary>
        /// 审批详情信息获取
        /// </summary>
        /// <param name="token"></param>
        /// <param name="page"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        [HttpGet]
        [NoTokenValidateFilter]
        [NoResultFilter]
        public IActionResult GetSensorDetailByToken(string token, int page, int pagesize)
        {
            var req = new RequestSensorMark
            {
                page = page,
                pagesize = pagesize,
                sensor_code = ""
            };
            var type = 0;
            var uid = 0;
            var pid = 0;
            IPagedCollectionResult<ResponseSensorDetailData> ret;
            if (!CheckToken(token, ref uid, ref type, ref pid))
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            switch (type)
            {
                case (int)SensorResult.WaitAudit:
                    ret = GetSensorDetail(req, SensorResult.WaitAudit, uid, 0, pid);
                    break;
                case (int)SensorResult.SecondWaitAudit:
                    ret = GetSensorDetail(req, SensorResult.SecondWaitAudit, 0, 0, pid, uid);
                    break;
                case (int)SensorResult.Audit:
                    ret = GetSensorDetail(req, SensorResult.Audit, 0, uid, pid);
                    break;
                default:
                    throw new BadRequestException(CommonEnum.NoData);
            }
            return new ObjectResult(new { total = ret.Total, page, pagesize, ret = 1, msg = 1, data = ret.Data });
        }

        /// <summary>
        /// 获取人员信息
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpGet]
        [NoTokenValidateFilter]
        [NoResultFilter]
        public IActionResult GetUserData(string token)
        {
            var type = 0;
            var uid = 0;
            var pid = 0;
            if (!CheckToken(token, ref uid, ref type, ref pid))
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            var userModel = _projectUser.GetList(f => f.status == (int)RowState.Valid && f.projectid.Equals(pid));
            if (!userModel.Any())
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            var ret = new List<ResponseKeyValue>();
            foreach (var item in userModel)
            {
                ret.Add(new ResponseKeyValue(item.mid.ToStr(), item.name));
            }
            return new ObjectResult(new { ret = 1, msg = 1, data = ret });
        }
        #endregion
        /// <summary>
        /// 获取产线信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetLastSection()
        {
            var ret = new List<ResponseKeyValue>();
            var stations = _projectLevelSection.GetAccStation(ProjectId);
            foreach (var item in stations)
            {
                ret.Add(new ResponseKeyValue(item.id.ToStr(), item.title));
            }
            return new ObjectResult(ret);
        }
        /// <summary>
        /// 获取设备信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetMachine(int id)
        {
            var ret = new List<ResponseKeyValue>();
            if (id == 0)
            {
                var machine = _machineExtend.GetList(f => f.status == (int)RowState.Valid).ToList();
                foreach (var item in machine)
                {
                    ret.Add(new ResponseKeyValue(item.machine_id.ToStr(), item.machine_shortname));
                }
            }
            else
            {
                var mids = _levelSectionMachine.GetList(f => f.section_id.Equals(id) && f.status == (int)RowState.Valid).ToList();
                foreach (var item in mids)
                {
                    var machine = _machineExtend.Get(f => f.machine_id.Equals(item.machine_id));
                    if (machine != null)
                    {
                        ret.Add(new ResponseKeyValue(machine.machine_id.ToStr(), machine.machine_shortname));
                    }
                }
            }
            return new ObjectResult(ret);
        }
        /// <summary>
        /// 状态统计
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetSensorState(int sectionid)
        {
            var ret = new ResponseSensorSummary();
            var machineModel = _machineExtend.GetList(f => f.status == (int)RowState.Valid).ToList();
            var seneorModel = _qmsSensorParameter.GetList(f => f.projectid.Equals(ProjectId) && f.status != (int)RowState.Invalid).ToList();
            if (sectionid != 0)
            {
                seneorModel = seneorModel.Where(f => f.station.Equals(sectionid)).ToList();
            }
            ret.Marking = seneorModel.Count(f => f.status == (int)SensorStatus.Marking);
            ret.Normal = seneorModel.Count(f => f.status == (int)SensorStatus.Normal);
            ret.NoSet = seneorModel.Count(f => f.status == (int)SensorStatus.NoSet);
            ret.OverDue = seneorModel.Count(f => f.status == (int)SensorStatus.OverDue);
            ret.WaitMark = seneorModel.Count(f => f.status == (int)SensorStatus.WaitMark);
            var equipmentsids = seneorModel.Select(s => s.mid).Distinct();
            foreach (var item in equipmentsids)
            {
                var sensorData = seneorModel.Where(f => f.mid.Equals(item));
                var eqp = machineModel.FirstOrDefault(f => f.machine_id.Equals(item))?.machine_shortname ?? "";
                if (!string.IsNullOrEmpty(eqp))
                {
                    ret.Equipments.Add(new EquipmentSensor
                    {
                        mid = item,
                        Equipment = eqp,
                        Sensor = Mapper<siger_qms_sensor_parameter, ResponseSensorParameterData>.MapList(sensorData)
                    });
                }
            }
            return new ObjectResult(ret);
        }
        /// <summary>
        /// 看板页面区域获取
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetSensorStateStation()
        {
            var ret = new List<ResponseKeyValue>();
            var stations = _qmsSensorParameter.GetList(f => f.projectid.Equals(ProjectId) && f.status != (int)RowState.Invalid).Select(s => s.station).Distinct().ToList();
            var section = _projectLevelSection.GetList(f => stations.Contains(f.id));
            foreach (var item in section)
            {
                ret.Add(new ResponseKeyValue(item.id.ToStr(), item.title));
            }
            return new ObjectResult(ret);
        }
        /// <summary>
        /// 传感器首页
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetTodoList(int uid)
        {
            var user = uid;
            if (uid == 0)
            {
                user = UserId;
            }
            var ret = new ResponseTodoList();
            var model = _qmsSensorParameter.GetList(f => f.status == (int)SensorStatus.WaitMark && f.projectid.Equals(ProjectId) && f.mark_uid.Equals(user));
            if (model != null && model.Any())
            {
                ret.WaitMark = model.Count();
            }
            var detailModel = _qmsSensorDetail.GetList(f => f.status != (int)RowState.Invalid && f.projectid.Equals(ProjectId));
            if (detailModel != null && detailModel.Any())
            {
                ret.WaitAudit = detailModel.Where(f => f.checkuser.Equals(user) && f.status == (int)SensorResult.WaitAudit).Count();
                ret.SecondWaitAudit = detailModel.Where(f => f.checkuser2.Equals(user) && f.status == (int)SensorResult.SecondWaitAudit).Count();
                ret.Audit = detailModel.Where(f => f.approvaluser.Equals(user) && f.status == (int)SensorResult.Audit).Count();
                ret.AuditToken = MakeToken(UserId, (int)SensorResult.Audit);
                ret.SecondWaitAuditToken = MakeToken(UserId, (int)SensorResult.SecondWaitAudit);
                ret.WaitAuditToken = MakeToken(UserId, (int)SensorResult.WaitAudit);
            }
            return new ObjectResult(ret);
        }
        /// <summary>
        /// 获取临时Token
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetToken(int uid, int type)
        {
            try
            {
                var user = uid;
                if (user == 0)
                {
                    user = UserId;
                }
                var ret = MakeToken(user, type);
                return new ObjectResult(ret);
            }
            catch (Exception ex)
            {
                return new ObjectResult(ex.Message);
            }
        }
        private string MakeToken(int uid, int type)
        {
            try
            {
                var data = new RequestSensorToken
                {
                    uid = uid,
                    type = type,
                    expirationtime = UnixTimeHelper.GetNow() + 24 * 3600
                };
                var model = JsonHelper.SerializerToJsonString(data);
                return CryptoJSHelper.Encrypt(model);
            }
            catch (Exception ex)
            {
                Logger.WriteLineInfo(ex.Message);
                return "";
            }
        }
        private IPagedCollectionResult<ResponseSensorParameterData> GetSensorParameterData(RequestSensorMark request)
        {
            var laststart = (int)UnixTimeHelper.ConvertDataTimeLong(request.lastdtBegin);
            var lastend = (int)UnixTimeHelper.ConvertDataTimeLong(request.lastdtEnd);
            var nextstart = (int)UnixTimeHelper.ConvertDataTimeLong(request.nextdtBegin);
            var nextend = (int)UnixTimeHelper.ConvertDataTimeLong(request.nextdtEnd);
            var ret = new List<ResponseSensorParameterData>();
            var entities = _qmsSensorParameter.GetSensorParameterData(ProjectId, request.typeid, request.sensor_code, request.mid, laststart, lastend, nextstart, nextend, request.page, request.pagesize);
            var userModel = _projectUser.GetList(f => f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid);
            foreach (var item in entities.Data)
            {
                var data = Mapper<siger_qms_sensor_parameter, ResponseSensorParameterData>.Map(item);
                data.parentid = _qmsSensorType.Get(f => f.id.Equals(data.typeid))?.parentid ?? 0;
                data.quality = item.quality;
                data.qualities = item.quality.Split(',');
                data.type = _qmsSensorType.GetSensorTypeString(ProjectId, item.typeid);
                data.machine = _projectLevelSection.GetSectionStringByMid(ProjectId, item.mid);
                data.approvetime = UnixTimeHelper.ConvertStringDateTime(item.approve_time.ToStr()).ToString(ParameterConstant.DateTimeFormat);
                data.nextmarktime = UnixTimeHelper.ConvertStringDateTime(item.nexttime.ToStr()).ToString(ParameterConstant.DateTimeFormat);
                data.marktime = UnixTimeHelper.ConvertStringDateTime(item.mark_time.ToStr()).ToString(ParameterConstant.DateTimeFormat);
                data.state = EnumHelper.GetEnumDesc((SensorStatus)item.status);
                data.cycle_unit_value = EnumHelper.GetEnumDesc((CycleUnit)item.cycle_unit);
                var resttime = UnixTimeHelper.GetTimeBySecond(item.nexttime - UnixTimeHelper.GetNow());
                var dayindex = resttime.IndexOf("天");
                if (dayindex > 0)
                {
                    data.resttime = resttime.Remove(dayindex + 1);
                }
                else
                {
                    data.resttime = "0天";
                }
                data.user = userModel.Where(f => f.mid.Equals(item.mark_uid)).Select(s => s.name).FirstOrDefault() ?? "";
                data.mark_user = userModel.Where(f => f.mid.Equals(item.mark_uid)).Select(s => s.work_code).FirstOrDefault() ?? "";
                if (string.IsNullOrEmpty(item.result))
                {
                    data.result = "";
                }
                if (item.mark_time == 0)
                {
                    data.marktime = "";
                }
                if (item.nexttime == 0)
                {
                    data.nextmarktime = "";
                }
                if (item.approve_time == 0)
                {
                    data.approvetime = "";
                }
                ret.Add(data);
            }
            return new PagedCollectionResult<ResponseSensorParameterData>(ret, entities.Total);
        }

        private IPagedCollectionResult<ResponseSensorDetailData> GetSensorDetail(RequestSensorMark request,
            SensorResult status = SensorResult.Default, int check = 0, int appove = 0, int pid = 0, int check2 = 0)
        {
            var laststart = (int)UnixTimeHelper.ConvertDataTimeLong(request.lastdtBegin);
            var lastend = (int)UnixTimeHelper.ConvertDataTimeLong(request.lastdtEnd);
            var nextstart = (int)UnixTimeHelper.ConvertDataTimeLong(request.nextdtBegin);
            var nextend = (int)UnixTimeHelper.ConvertDataTimeLong(request.nextdtEnd);
            var projectid = pid;
            if (pid == 0)
            {
                projectid = ProjectId;
            }
            var ret = _qmsSensorParameter.GetSensorDetailData(projectid, request.typeid, request.sensor_code, request.mid
                , laststart, lastend, nextstart, nextend, request.page, request.pagesize, (int)status, check, appove, request.model
                , request.id, check2);
            var userModel = _projectUser.GetList(f => f.projectid.Equals(projectid) && f.status == (int)RowState.Valid);
            var data = ret.Data.ToList();
            foreach (var item in data)
            {
                item.type = _qmsSensorType.GetSensorTypeString(projectid, item.typeid);
                item.machine = _projectLevelSection.GetSectionStringByMid(projectid, item.mid);
                item.marktime = UnixTimeHelper.ConvertStringDateTime(item.mark_time.ToStr()).ToString(ParameterConstant.DateTimeFormat);
                item.nextmarktime = UnixTimeHelper.ConvertStringDateTime(item.nexttime.ToStr()).ToString(ParameterConstant.DateTimeFormat);
                item.state = EnumHelper.GetEnumDesc((SensorResult)item.status);
                item.markuser_value = userModel.Where(f => f.mid.Equals(item.markuser)).Select(s => s.name).FirstOrDefault() ?? "";
                item.checkuser_value = userModel.Where(f => f.mid.Equals(item.checkuser)).Select(s => s.name).FirstOrDefault() ?? "";
                item.checkuser2_value = userModel.Where(f => f.mid.Equals(item.checkuser2)).Select(s => s.name).FirstOrDefault() ?? "";
                item.approvaluser_value = userModel.Where(f => f.mid.Equals(item.approvaluser)).Select(s => s.name).FirstOrDefault() ?? "";
                item.user = userModel.Where(f => f.mid.Equals(item.approvaluser)).Select(s => s.name).FirstOrDefault() ?? "";
                if (!string.IsNullOrEmpty(item.fid))
                {
                    var file = _qmsSensorType.GetSensorFile(item.fid);
                    if (file.Any())
                        item.file.AddRange(file);
                }
                if (!string.IsNullOrEmpty(item.history_fid))
                {
                    var file = _qmsSensorType.GetSensorFile(item.history_fid);
                    if (file.Any())
                        item.history.AddRange(file);
                    else
                        item.history.Add(new ResponseSensorFileData
                        {
                            file_name = "",
                            file_url = "",
                            id = 0
                        });
                }
                else
                {
                    //前端无法解析空数组
                    item.history.Add(new ResponseSensorFileData
                    {
                        file_name = "",
                        file_url = "",
                        id = 0
                    });
                }
                if (string.IsNullOrEmpty(item.result))
                {
                    item.result = "";
                }
                if (item.mark_time == 0)
                {
                    item.marktime = "";
                }
                if (item.nexttime == 0)
                {
                    item.nextmarktime = "";
                }
            }
            return new PagedCollectionResult<ResponseSensorDetailData>(data, ret.Total);
        }

        private IActionResult ModifySensorDetail(RequestMarkSensor req)
        {
            var data = _qmsSensorDetail.Get(f => f.projectid.Equals(req.projectid) && f.id.Equals(req.id));
            if (data == null)
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            if (data.status == (int)SensorResult.WaitAudit || data.status == (int)SensorResult.NotPass || data.status == (int)SensorResult.SecondWaitAudit)
            {

                var model = _qmsSensorParameter.Get(f => f.status != (int)RowState.Invalid && f.projectid.Equals(req.projectid) && f.sensor_code.Equals(req.sensor_code));
                if (model == null)
                {
                    throw new BadRequestException(QMSEnum.SensorNotExist);
                }
                var fid = IdHelper.Generate<string>();
                var historyfid = IdHelper.Generate<string>();
                //文件删除
                var files = _qmsSensorFile.GetList(f => f.fid.Equals(data.fid) || f.fid.Equals(data.history_fid) && f.status == (int)RowState.Valid).ToList();
                files.ForEach(f =>
                {
                    f.status = (int)RowState.Invalid;
                    _qmsSensorFile.Update(f);
                });
                //插入siger_qms_sensor_file
                foreach (var item in req.file)
                {
                    _qmsSensorFile.Insert(new siger_qms_sensor_file
                    {
                        fid = fid,
                        file_name = item.file_name,
                        file_url = item.file_url,
                        projectid = req.projectid,
                        type = (int)SensorFileType.File
                    });
                }
                //插入siger_qms_sensor_file
                foreach (var item in req.history)
                {
                    _qmsSensorFile.Insert(new siger_qms_sensor_file
                    {
                        fid = historyfid,
                        file_name = item.file_name,
                        file_url = item.file_url,
                        projectid = req.projectid,
                        type = (int)SensorFileType.ValidationFile
                    });
                }
                //修改
                data.history_result = req.history_result;
                data.result = req.result;
                data.remark = req.remark;
                data.fid = fid;
                data.history_fid = historyfid;
                data.checkuser = req.checkuser;
                data.checkuser2 = req.checkuser2;
                data.supplier = req.supplier;
                data.appearance = req.appearance;
                data.label = req.label;
                data.type = req.type;
                //data.uid = req.uid;
                //data.status = (int)SensorResult.WaitAudit;
                data.projectid = req.projectid;
                data.upload_time = DateTime.Now;
                _qmsSensorDetail.Update(data);
                //更新传感器
                model.mark_uid = req.uid;
                model.mark_time = UnixTimeHelper.GetNow();
                model.nexttime = UnixTimeHelper.GetNow() + model.cycletime;
                model.result = req.result;
                _qmsSensorParameter.Update(model);
                if (_unitOfWork.Commit() > 0)
                {
                    return new ObjectResult(CommonEnum.Succefull);
                }
                throw new BadRequestException(CommonEnum.Fail);
            }
            else
            {
                throw new BadRequestException(QMSEnum.DetailCanNotModify);
            }
        }

        private bool CheckToken(string token, ref int uid, ref int type, ref int pid)
        {
            try
            {
                if (string.IsNullOrEmpty(token))
                {
                    return false;
                }
                token = CryptoJSHelper.Decrypt(token);
                var model = JsonHelper.DeserializerJsonResult<RequestSensorToken>(token);
                uid = model.uid;
                type = model.type;
                var user = _projectUser.Get(f => f.mid.Equals(model.uid) && f.status == (int)RowState.Valid);
                if (user == null)
                {
                    return false;
                }
                pid = user.projectid;
                if (model.expirationtime <= UnixTimeHelper.GetNow())
                {
                    return false;
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        private void SendMail(int mid, string name, string code, int pid)
        {
            var Cfg = _projectEmailConfig.Get(f => f.project == pid && f.status == (int)RowState.Valid);
            if (Cfg == null)
            {
                Logger.WriteLineInfo("你没有维护邮箱！");
                return;
            }
            var user = _projectUser.Get(f => f.mid.Equals(mid) && f.status == (int)RowState.Valid);
            if (user == null || string.IsNullOrEmpty(user.work_email))
            {
                Logger.WriteLineInfo($"{mid}该用户没有邮箱！");
                return;
            }
            if (string.IsNullOrEmpty(user.work_email))
            {
                return;
            }
            var str = $"您提交的{name}【{code}】标定未通过审核，审核人：{user.name}";
            MailHelper.SendMail(Cfg.server, true, Cfg.send, Cfg.code, "Smart Test Lab",
                   Cfg.send, user.work_email, $"{name}【{code}】标定结果未通过", str, new List<string>());
        }
        /// <summary>
        /// skf-app
        /// </summary>
        /// <param name="machineid"></param>
        /// <param name="page"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetLastMarkTime(string machineid, int page, int pagesize)
        {
            var machineId = machineid.ToInt();
            var res = new List<ResponseGetLastMarkTime>();

            Expression<Func<siger_qms_sensor_parameter, bool>> funMachine = t =>
                t.projectid == ProjectId && t.status > (int)RowState.Valid && t.mid == machineId;
            var sensors = _qmsSensorParameter.GetPagedList(page, pagesize, funMachine, "mark_time", true);
            foreach (var sensor in sensors.Data)
            {
                if (sensor.mark_time > 0)
                {
                    res.Add(new ResponseGetLastMarkTime
                    {
                        code = sensor.sensor_code,
                        id = sensor.id,
                        marktime = UnixTimeHelper.ConvertIntDateTime(sensor.mark_time)
                    });
                }
            }
            return new PagedObjectResult(res, sensors.Total, page, pagesize);
        }
    }
}