using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using MadRunFabric.Common;
using Microsoft.AspNetCore.Authorization;
using Api.SignToken;
using Microsoft.Extensions.Logging;
using DistributionApi.IRepositories;
using System.Security.Claims;
using DistributionApi.Models.Input;
using MadRunFabric.Model;
using MadRunFabric.Model.MessageApi;
using Microsoft.Extensions.Configuration;

namespace DistributionApi.Controllers
{
    /// <summary>
    /// 配送工单
    /// </summary>
    [Authorize]
    [ApiVersion("6.0")]
    [Route("api/[controller]")]
    [Produces("application/json")]
    public class DistriWorkOrderController : BaseController
    {
        private readonly ILogger<DistriWorkOrderController> _logger;
        private readonly IConfiguration _configuration;
        private readonly ISys_User_AccountRepository _sys_user_accountRepository;
        private readonly ISignTokenService _signTokenService;
        private readonly IDistri_WorkorderRepository _distri_workorderrepository;
        private readonly IDistri_Workorder_ItemsRepository _distri_workorder_itemsrepository;
        private readonly IDistri_Workorder_EvaluateRepository _distri_workorder_evaluaterepository;
        private readonly IDistri_Workorder_ExceptionRepository _distri_workorder_exceptionrepository;
        private readonly IDistri_Workorder_PlanTaskRepository _distri_workorder_plantaskrepository;
        private readonly ISys_User_AccountRepository _distri_sys_user_accountrepository;
        private readonly IDistri_Workorder_UpdateRecordRepository _distri_workorder_updaterrecordrepository;
        private readonly IWo_Order_User_MapRepository _wo_order_user_maprepository;
        private readonly IWechatService _wechatservice;
        private readonly IDistri_Workorder_OffenceRecordRepository _distri_workorder_offencerecordrepository;
        public DistriWorkOrderController(
           ILogger<DistriWorkOrderController> logger,
            IConfiguration configuration,
            ISys_User_AccountRepository sys_user_accountRepository,
           ISignTokenService signTokenService,
           IDistri_WorkorderRepository distri_workorderrepository,
           IDistri_Workorder_ItemsRepository distri_workorder_itemsrepository,
           IDistri_Workorder_EvaluateRepository distri_workorder_evaluaterepository,
           IDistri_Workorder_ExceptionRepository distri_workorder_exceptionrepository,
           IDistri_Workorder_PlanTaskRepository distri_workorder_plantaskrepository,
           ISys_User_AccountRepository distri_sys_user_accountrepository,
           IDistri_Workorder_UpdateRecordRepository distri_workorder_updaterrecordrepository, 
           IWo_Order_User_MapRepository wo_order_user_maprepository,
           IWechatService wechatservice,
           IDistri_Workorder_OffenceRecordRepository distri_workorder_offencerecordrepository
           )
        {
            _logger = logger;
            _configuration = configuration;
            _sys_user_accountRepository = sys_user_accountRepository;
            _signTokenService = signTokenService;
            _distri_workorderrepository = distri_workorderrepository;
            _distri_workorder_itemsrepository = distri_workorder_itemsrepository;
            _distri_workorder_evaluaterepository = distri_workorder_evaluaterepository;
            _distri_workorder_exceptionrepository = distri_workorder_exceptionrepository;
            _distri_workorder_plantaskrepository = distri_workorder_plantaskrepository;
            _distri_sys_user_accountrepository = distri_sys_user_accountrepository;
            _distri_workorder_updaterrecordrepository = distri_workorder_updaterrecordrepository;
            _wo_order_user_maprepository = wo_order_user_maprepository;
            _wechatservice = wechatservice;
            _distri_workorder_offencerecordrepository = distri_workorder_offencerecordrepository;
        }

        /// <summary>
        /// 获取配送工单列表分页 - 随机工单 和 分送工单 by page
        /// </summary>
        /// <param name="keyword"></param>
        /// <param name="wosorts">工单分类(-1所有1随机工单,2计划工单)</param>
        /// <param name="wostate">配送工单状态:-1所有  0创建工单，1转派或者抢单（待取货）,2已取货（配送中）,3货物异常（异常），4已完结/待评价，5已取消，6挂起 ，9已评价  44已完成 </param>
        /// <param name="stime"></param>
        /// <param name="etime"></param>
        /// <param name="pageindex"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        [HttpGet("getlistbypage")]
        public IActionResult GetListByPageAsync(string keyword, string projectid, string stime, string etime, int datetype = -1, int wosorts = -1, int wostate = -1, int wxstate = -1, int pageindex = 1, int pagesize = 10)
        {
            string rolecode = User.Claims.FirstOrDefault(c => c.Type == "RoleCode").Value;
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;

            //var userstr = _signTokenService.GetUserInfoAsync(usercode).Result;
            //var userinfo = userstr.ToJObject()["data"].ToString().ToObject<UserInfoModel>();
            
            var userinfos = _sys_user_accountRepository.GetUserInfo(usercode);
            var userinfo = JsonHelper.JsonToEntity<UserAccountInfoModel>(userinfos.ToJson());

            //获取当天、本周、本月、本年、累计时间
            if (datetype != -1)
            {
                GetStartEndTime(datetype, out stime, out etime);
            }
            //获取数据
            int recordCount = 0;
            var result = _distri_workorderrepository.GetListsByPage(keyword, projectid, wosorts,wostate, wxstate, stime, etime, rolecode, usercode, userinfo, pageindex, pagesize, out recordCount);
            var obj = new
            {
                rows = result.ToList(),
                total = recordCount
            };
            return Success("获取成功", obj);
        }
       
        /// <summary>
        /// 获取配送工单详情
        /// </summary>
        [HttpGet("getsingle")]
        public async Task<IActionResult> GetSingleAsync(string id, string projectid, int channelcode = 0)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            if (string.IsNullOrEmpty(id))
                return Error("参数错误");
            var dModel = await _distri_workorderrepository.GetSingle(id.Trim());
            var model = _distri_workorderrepository.GetDetails(id);
            if (dModel != null)
            {
                var list_Evalua = await _distri_workorder_evaluaterepository.Get(s => s.woid.Equals(dModel.id) & s.isdelete == 0);
                var list_Item = await _distri_workorder_itemsrepository.Get(s => s.woid.Equals(dModel.id) & s.isdelete == 0);
                var list_Exception = await _distri_workorder_exceptionrepository.Get(s => s.woid.Equals(dModel.id) & s.isdelete == 0 && s.type == 1);
                var list_Offence = await _distri_workorder_offencerecordrepository.Get(s => s.woid.Equals(dModel.id) & s.isdelete == 0);

                #region 标记消息提醒工单（消息提醒，App推送）
                string goodsDetail = "";
                if (channelcode > 0 && (dModel.totype == (int)EnumDistributionTotype.send || dModel.totype == (int)EnumDistributionTotype.assign))
                {
                    if (dModel.wostate == 0 || dModel.wostate == 1)
                    {
                        //维修工单号
                        var listmap = await _wo_order_user_maprepository.Get(x => x.woid == dModel.id && x.wocode == dModel.wocode && x.channelcode == channelcode && x.readby == usercode);
                        var modelmap = listmap.FirstOrDefault();
                        goodsDetail = (dModel.goodslist != null && dModel.goodslist.Count > 0) ? " 配送物品:" + dModel.goodslist.Select(x => x.goodsname).ToJson() : "";
                        if (modelmap == null)
                        {
                            //添加是否已读关系表
                            modelmap = new Wo_Order_User_Map();
                            modelmap.woid = dModel.id;
                            modelmap.wocode = dModel.wocode;
                            modelmap.wostate = dModel.wostate;
                            modelmap.readby = usercode;
                            modelmap.channelcode = channelcode;   //工单类型（枚举EnumOrderState） 维修工单 = 1, 保养工单 = 2, 运行工单 = 3, 超时工单 = 4, 配送工单 = 5
                            modelmap.isread = 1;
                            modelmap.isnotice = 1;
                            modelmap.readtime = DateTime.Now;
                            modelmap.note = (string.IsNullOrEmpty(dModel.detail) ? "" : "配送内容:" + dModel.detail) + goodsDetail; //保养内容
                                                                                                                                                                                                                                                                      // modelmap.note = model.maintaincontent;
                            bool b = await _wo_order_user_maprepository.Add(modelmap);
                        }
                        else
                        {
                            modelmap.isread = 1;
                            modelmap.isnotice = 1;
                            modelmap.note = (string.IsNullOrEmpty(dModel.detail) ? "" : "配送内容:" + dModel.detail) + goodsDetail; //保养内容
                            bool b = await _wo_order_user_maprepository.UpdateOne(modelmap);
                        }
                    }
                }
                #endregion

                List<string> tousertel = new List<string>();
                var userlist = (await _distri_sys_user_accountrepository.Get(x => x.delete_flag == false && x.type != 2)).ToList();
                if (!string.IsNullOrEmpty(projectid))
                    userlist = userlist.Where(x => x.projectlist.Contains(projectid)).ToList();
                if (dModel.touser != null && dModel.touser.Count > 0)
                {
                    tousertel = userlist.Where(y => dModel.touser.Contains(y.usercode)).Select(x => x.mobile).ToList();
                }

                var obj = new
                {
                    model = model,
                    tousertel = tousertel,
                    items = list_Item,
                    evaluate = list_Evalua,
                    exception = list_Exception,
                    offence = list_Offence
                };
                return Success("获取工单成功", obj);
            }
            return Error("获取失败");
        }

        /// <summary>
        /// 判断是否评价 (随机工单) - 在“添加工单”接口之前
        /// </summary>
        [HttpPost("isevaluation")]
        public async Task<IActionResult> IsEvaluationAsync()
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;

            //var userstr = _signTokenService.GetUserInfoAsync(usercode).Result;
            //var userinfo = userstr.ToJObject()["data"].ToString().ToObject<UserInfoModel>();
            
            var userinfos = _sys_user_accountRepository.GetUserInfo(usercode);
            var userinfo = JsonHelper.JsonToEntity<UserAccountInfoModel>(userinfos.ToJson());

            //微信随机工单需要评价，pc，app随机工单不用评价
            if (userinfo.isallproject == 1)
            {
                //微信类型
                if (userinfo.type == 2)
                {
                    //4已完结/待评价 - 发货科室不进行评价不让下单
                    var list = (await _distri_workorderrepository.Get(x => x.channel == 4 && x.wosorts == (int)EnumDistributionWoSorts.random && x.wostate == (int)EnumDistributionState.finish && x.createtby == usercode && x.isdelete == 0)).ToList();
                    if (list != null && list.Count > 0)
                        return Error("有" + list.Count + "条随机工单需进行评价后才能下单，工单:" + list.Select(x => x.wocode).ToString());
                }
            }
            return Success("没有要评价的工单");
        }

        /// <summary>
        /// 添加工单(随机工单，分送工单) 
        /// 1、随机工单根据收货科室拆分工单 2019-04-24 lihai
        /// </summary>
        [HttpPost("add")]
        public async Task<IActionResult> AddAsync(DistriWorkOrderInput input)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;

            //var userstr = _signTokenService.GetUserInfoAsync(usercode).Result;
            //var userinfo = userstr.ToJObject()["data"].ToString().ToObject<UserInfoModel>();
            
            var userinfos = _sys_user_accountRepository.GetUserInfo(usercode);
            var userinfo = JsonHelper.JsonToEntity<UserAccountInfoModel>(userinfos.ToJson());

            #region 判断验证
            if (string.IsNullOrEmpty(input.projectid))
                return Error("请选择项目");
            if (!string.IsNullOrEmpty(input.plantaskid))
            {
                if (input.goodslist == null || input.goodslist.Count <= 0)
                    return Error("请选择物品");
                int goodsnum = input.goodslist.Sum(x => x.num);
                if (goodsnum <= 0)
                    return Error("请填写物品数量");
                if (input.deliverylist == null || input.deliverylist.Count <= 0)
                    return Error("请选择发货地址");
            }
            else {
                if (input.goodslist_chaidan == null || input.goodslist_chaidan.Count <= 0)
                    return Error("请选择物品和发货地址");
                int goodsnum = input.goodslist_chaidan.Sum(x => x.num);
                if (goodsnum <= 0)
                    return Error("请填写物品数量");
            }

            #endregion

            #region model 添加配送工单对象            

            #region 计划工单内容model 判断是否是计划任务工单
            var model_PlanOrder = new Distri_Workorder_PlanTask();
            string res = string.Empty;
            int addnum = 0;         //拆弹个数
            int addnum_total = 0;   //应拆弹个数
            if (!string.IsNullOrEmpty(input.plantaskid))
            {
                var model = new Distri_Workorder();
                model.projectid = input.projectid;
                model.channel = input.channel;
                model.deliverylist = (input.deliverylist != null && input.deliverylist.Count > 0) ? input.deliverylist.Distinct().ToList() : new List<DistributionDddressModel>();
                model.detail = input.detail;
                model.createtby = usercode;
                model.createname = username;
                model.emergencyid = 1;
                model.deliveryname = input.deliveryname;
                model.deliverytel = input.deliverytel;

                //获取工单列表 by plantaskid
                var list_wo = (await _distri_workorderrepository.Get(x => x.isdelete == 0 && x.plantaskid == input.plantaskid)).ToList();
                model_PlanOrder = await _distri_workorder_plantaskrepository.GetSingle(input.plantaskid);
                if (model_PlanOrder == null)
                    return Error("参数错误");
                model.wosorts = (int)EnumDistributionWoSorts.plan;    //工单分类(1随机工单,2计划工单)
                model.plantaskid = input.plantaskid;
                model.planid = model_PlanOrder.planid;
                model.touser = model_PlanOrder.joinuserlist.Distinct().ToList();    //参与人 附加给 所属人
                model.wostate = (int)EnumDistributionState.delivery;
                if (model_PlanOrder.joinuserlist != null && model_PlanOrder.joinuserlist.Count > 0)
                {
                    model.totype = (int)EnumDistributionTotype.send;
                    model.assigtime = DateTime.Now;
                    //model.wostate = (int)EnumDistributionState.delivery;
                }
                //计算计划工单 物品使用数量，并保存
                var list_taskgoods = model_PlanOrder.goodslist;
                if (list_taskgoods != null && list_taskgoods.Count > 0)
                {
                    #region 计算计划工单 物品使用数量
                    List<DistributionGoodsListByTask> list_task = new List<DistributionGoodsListByTask>();
                    foreach (var item_task in list_taskgoods)
                    {
                        //已使用数量初始化
                        int total = 0;
                        int wo_num_total = 0;                        
                        var mode_goods = input.goodslist.FirstOrDefault(x => x.goodsid == item_task.goodsid);
                        if (mode_goods != null)
                            wo_num_total = mode_goods.num;     //提交数量
                        //total = 计划使用数量 + 当前提交数量
                        total = item_task.usednum + wo_num_total;
                        if (total > item_task.num)
                            return Error("操作错误("+ wo_num_total + ")，分送工单添加物品" + mode_goods.goodsname + "数量：" + mode_goods.num + "不能大于计划工单剩余物品" + item_task.goodsname + "剩余数量：" + (item_task.num - item_task.usednum) + "");

                        //修改计划工单物品数量
                        //var model_task = new DistributionGoodsListByTask();
                        //model_task.goodsid = item_task.goodsid;
                        //model_task.goodsname = item_task.goodsname;
                        //model_task.typeid = item_task.typeid;
                        //model_task.isremind = item_task.isremind;
                        //model_task.remark = item_task.remark;
                        //model_task.num = item_task.num;
                        item_task.usednum = total;     //使用数量 - 主要是设置剩余数值 ------- 使用数量 + 当前提交数量
                        list_task.Add(item_task);
                    }
                    model_PlanOrder.goodslist = list_task;
                    ////保存物品数量到计划工单使用数量中
                    //await _distri_workorder_plantaskrepository.UpdateOne(model_PlanOrder);
                    #endregion
                }

                model.receiverlist = (input.receiverlist != null && input.receiverlist.Count > 0) ? input.receiverlist.Distinct().ToList() : new List<DistributionDddressModel>();
                //工单编号
                model.wocode = UniqueData.Gener("", 2);
                //紧急程度
                if (input.goodslist != null && input.goodslist.Count > 0)
                {
                    var list_goods = input.goodslist.Where(x => x.typeid == 2);
                    if (list_goods != null && list_goods.Count() > 0)
                        model.emergencyid = 2;
                }
                //物品列表
                model.goodslist = (input.goodslist != null && input.goodslist.Count > 0) ? input.goodslist : new List<DistributionGoodsList>();model.receiverlist = (input.receiverlist != null && input.receiverlist.Count > 0) ? input.receiverlist.Distinct().ToList() : new List<DistributionDddressModel>();    //input.receiverlist
                
                res = await _distri_workorderrepository.AddRetID(model);
                addnum += 1;

                // 添加工单流程
                int channel = input.channel;
                int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                string str_type = string.IsNullOrEmpty(input.plantaskid) ? "添加随机工单" : "添加分送工单";
                AddItems(res, model.wocode, model.wostate, model.wostate_elevator, channel, islast, "", "", "" + username + str_type, usercode);
                //主管添加工单，且指派
                if (model.wostate == (int)EnumDistributionState.assign)
                {
                    int islasts = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                    AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islasts, input.touser, "", username + "转派工单，工单编号：" + model.wocode, usercode);
                }
            }
            else {
                //微信随机工单需要评价，pc，app随机工单不用评价
                if (userinfo.isallproject == 1)
                {
                    //微信类型
                    if (userinfo.type == 2)
                    {
                        //4已完结/待评价 - 发货科室不进行评价不让下单 - 只限制 科室微信端 - 主管可以提交工单不评价app端
                        var list = (await _distri_workorderrepository.Get(x => x.channel == 4 && x.wosorts == (int)EnumDistributionWoSorts.random && x.wostate == (int)EnumDistributionState.finish && x.createtby == usercode && x.isdelete == 0)).ToList();
                        if (list != null && list.Count > 0)
                            return Error("有" + list.Count + "条随机工单需进行评价后才能下单，工单:" + list.Select(x => x.wocode).ToString());
                    }
                }                

                #region 拆分工单
                var goodslist_chaidan_input = input.goodslist_chaidan;
                var goodsList_chaidan = new List<DistributionGoodsList>();
                // 去重后的楼层科室
                var floorid_list = goodslist_chaidan_input.Select(x => x.floorid).Distinct().ToList();
                //应拆弹个数
                addnum_total = floorid_list.Count;
                foreach (var item in floorid_list)
                {
                    var model = new Distri_Workorder();
                    model.projectid = input.projectid;
                    model.channel = input.channel;
                    model.deliverylist = (input.deliverylist != null && input.deliverylist.Count > 0) ? input.deliverylist.Distinct().ToList() : new List<DistributionDddressModel>();
                    model.detail = input.detail;
                    model.createtby = usercode;
                    model.createname = username;
                    model.emergencyid = 1;
                    model.deliveryname = input.deliveryname;
                    model.deliverytel = input.deliverytel;
                    model.wosorts = (int)EnumDistributionWoSorts.random;    //工单分类(1随机工单,2计划工单)
                    if (!string.IsNullOrEmpty(input.touser))
                    {
                        //主管添加工单，且指派
                        model.touser = new List<string>() { input.touser }; // 转派人/抢单人
                        model.totype = (int)EnumDistributionTotype.send;
                        model.assigtime = DateTime.Now;
                        model.wostate = (int)EnumDistributionState.assign;
                    }

                    // 物品列表 by floorid
                    var goodslist_byfloorid = goodslist_chaidan_input.Where(x => x.floorid == item).ToList();
                    // 物品详情
                    var model_goods = goodslist_byfloorid.FirstOrDefault();
                    // 收货地址
                    var receiverlist = new List<DistributionDddressModel>();
                    var model_receiver = new DistributionDddressModel();
                    if (model_goods != null)
                    {
                        model_receiver.buildingid = model_goods.buildingid;
                        model_receiver.building_name = model_goods.building_name;
                        model_receiver.floorid = model_goods.floorid;
                        model_receiver.floor_name = model_goods.floor_name;
                        model_receiver.department_name = model_goods.department_name;
                        receiverlist.Add(model_receiver);
                    }
                    model.receiverlist = receiverlist;  //(input.receiverlist != null && input.receiverlist.Count > 0) ? input.receiverlist.Distinct().ToList() : new List<DistributionDddressModel>();
                                                        //工单编号
                    model.wocode = UniqueData.Gener("", 2);
                    //紧急程度
                    if (goodslist_byfloorid != null && goodslist_byfloorid.Count > 0)
                    {
                        var list_goods = goodslist_byfloorid.Where(x => x.typeid == 2);
                        if (list_goods != null && list_goods.Count() > 0)
                            model.emergencyid = 2;
                    }
                    //物品列表
                    var goodslist_item = new List<DistributionGoodsList>();
                    foreach (var item_goodslist in goodslist_byfloorid)
                    {
                        var model_goodslist_item = new DistributionGoodsList();
                        model_goodslist_item.goodsid = item_goodslist.goodsid;
                        model_goodslist_item.goodsname = item_goodslist.goodsname;
                        model_goodslist_item.typeid = item_goodslist.typeid;
                        model_goodslist_item.isremind = item_goodslist.isremind;
                        model_goodslist_item.remark = item_goodslist.remark;
                        model_goodslist_item.num = item_goodslist.num;
                        goodslist_item.Add(model_goodslist_item);
                    }
                    model.goodslist = goodslist_item;  //(input.goodslist != null && input.goodslist.Count > 0) ? input.goodslist : new List<DistributionGoodsList>();model.receiverlist = (input.receiverlist != null && input.receiverlist.Count > 0) ? input.receiverlist.Distinct().ToList() : new List<DistributionDddressModel>();    //input.receiverlist
                    res = await _distri_workorderrepository.AddRetID(model);

                    addnum += 1;

                    // 添加工单流程
                    int channel = input.channel;
                    int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                    string str_type = string.IsNullOrEmpty(input.plantaskid) ? "添加随机工单" : "添加分送工单";
                    AddItems(res, model.wocode, model.wostate, model.wostate_elevator, channel, islast, "", "", "" + username + str_type, usercode);
                    //主管添加工单，且指派
                    if (model.wostate == (int)EnumDistributionState.assign)
                    {
                        int islasts = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                        AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islasts, input.touser, "", username + "转派工单，工单编号：" + model.wocode, usercode);
                    }
                }
                #endregion
            }
            //model.emergencyid = input.wosorts == (int)EnumDistributionWoSorts.plan ? 2 : input.emergencyid; //如果计划是紧急分送工单，其他自己选择
            #endregion

            #endregion

            if (!string.IsNullOrEmpty(res))
            {
                _logger.LogDebug("neirong: distributionapi/api/DistriWorkOrder/add 添加工单(随机工单，分送工单)");

                if (!string.IsNullOrEmpty(input.plantaskid))
                {
                    //保存物品数量到计划工单使用数量中
                    await _distri_workorder_plantaskrepository.UpdateOne(model_PlanOrder);
                }         
                
                string addnum_string = string.Empty;
                if (addnum > 1)
                {
                    if (addnum == addnum_total)
                        addnum_string = "(因为配送地址的不同，已拆分" + addnum + "个工单)";
                    else
                        addnum_string = "(因为配送地址的不同，已拆分" + addnum + "个工单，拆分失败" + (addnum_total - addnum) + "个工单)";
                }
                return Success("保存成功"+ addnum_string);
            }
            else
                return Error("保存失败");
        }

        /// <summary>
        /// 修改工单
        /// </summary>
        [HttpPost("update")]
        public async Task<IActionResult> UpdateAsync(DistriWorkOrderInput input)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;

            var model = await _distri_workorderrepository.GetSingle(p => p.id == input.id);
            if (model != null)
            {
                #region 判断验证
                if (string.IsNullOrEmpty(input.projectid))
                    return Error("请选择项目");
                if (input.goodslist == null || input.goodslist.Count <= 0)
                    return Error("请选择物品");
                int goodsnum = input.goodslist.Sum(x => x.num);
                if (goodsnum <= 0)
                    return Error("请填写物品数量");
                if (input.deliverylist == null || input.deliverylist.Count <= 0)
                    return Error("请选择发货地址");
                #endregion

                //操作权限解释 - 下单人在下单后的修改和撤单操作权限是在电梯岗（配送岗）已取货之前均可操作
                var model_Record = new Distri_Workorder_UpdateRecord();
                if (model.wostate >= (int)EnumDistributionState.delivery || model.wostate_elevator >= (int)EnumDistributionState_elevator.delivery)
                {
                    model_Record = await _distri_workorder_updaterrecordrepository.GetSingle(x => x.woid == model.id && x.isagree == 2 && x.isupdate == 0 && x.isupdatetype == 1 && x.isdelete == 0);
                    if (model_Record == null)
                    {
                        //没有申请修改/取消
                        if (model.wostate >= (int)EnumDistributionState.delivery)
                            return Error("配送岗已取货之后不能修改");
                        if (model.wostate >= (int)EnumDistributionState_elevator.delivery)
                            return Error("电梯岗已取货之后不能修改");
                    }
                }

                #region model 添加配送工单对象
                //model.wosorts = input.wosorts;    //工单分类(1随机工单,2计划工单)
                //model.planid = input.planid;
                //model.plantaskid = input.plantaskid;

                //model.emergencyid = input.emergencyid;
                model.emergencyid = 1;
                if (input.goodslist != null && input.goodslist.Count > 0)
                {
                    var list_goods = input.goodslist.Where(x => x.typeid == 2);
                    if (list_goods != null && list_goods.Count() > 0)
                        model.emergencyid = 2;
                }
                model.projectid = input.projectid;
                model.goodslist = (input.goodslist != null && input.goodslist.Count > 0) ? input.goodslist : new List<DistributionGoodsList>();
                model.deliverylist = (input.deliverylist != null && input.deliverylist.Count > 0) ? input.deliverylist : new List<DistributionDddressModel>();
                model.receiverlist = (input.receiverlist != null && input.receiverlist.Count > 0) ? input.receiverlist : new List<DistributionDddressModel>();
                model.detail = input.detail;
                model.deliveryname = input.deliveryname;
                model.deliverytel = input.deliverytel;
                #endregion

                bool b = await _distri_workorderrepository.UpdateOne(model);
                if (b)
                {
                    _logger.LogDebug("neirong: distributionapi/api/DistriWorkOrder/update 修改工单");
                    //更新申请修改/取消表
                    if (model_Record != null)
                    {
                        model_Record.isupdate = 1;
                        await _distri_workorder_updaterrecordrepository.Update(model_Record);
                        _logger.LogDebug("neirong: distributionapi/api/DistriWorkOrder/update 申请修改工单");
                    }

                    int channel = model.channel;
                    int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                    AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islast, "", "", "" + username + "修改随机工单：", usercode);
                    return Success("保存成功");
                }
                return Error("保存失败");
            }
            return Error("参数错误");
        }

        #region 所有我的工单 - 随机工单 和 计划工单 - App
        /// <summary>
        /// 获取工单和计划工单列表分页 by page - 随机工单 和 计划工单 - App
        /// </summary>
        /// <param name="keyword"></param>
        /// <param name="projectid"></param>
        /// <param name="isfinish">-1所有，1未完成，2已完成</param>
        /// <param name="planandorderstate">-1所有 0新任务，1待取货，2配送中</param>
        /// <param name="pageindex"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        [HttpGet("getplanandtasklistbypage")]
        public async Task<IActionResult> GetPlanAndOrderListByPageAsync(string keyword, string projectid, string stime, string etime, int datetype = -1, int isfinish = 1, int wosorts = -1, int wostate = -1, int pageindex = 1, int pagesize = 10)
        {
            string rolecode = User.Claims.FirstOrDefault(c => c.Type == "RoleCode").Value;
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;

            //var userstr = _signTokenService.GetUserInfoAsync(usercode).Result;
            //var userinfo = userstr.ToJObject()["data"].ToString().ToObject<UserInfoModel>();
            
            var userinfos = _sys_user_accountRepository.GetUserInfo(usercode);
            var userinfo = JsonHelper.JsonToEntity<UserAccountInfoModel>(userinfos.ToJson());

            //获取当天、本周、本月、本年、累计时间
            if (datetype != -1)
            {
                GetStartEndTime(datetype, out stime, out etime);
            }
            //获取数据
            int recordCount = 0;
            var result = _distri_workorderrepository.GetPlanAndTaskListByPage(keyword, projectid, isfinish, wosorts, wostate, stime, etime, rolecode, usercode, userinfo, pageindex, pagesize, out recordCount);
            var list = result.ToList();
            var userlist = (await _distri_sys_user_accountrepository.Get(x => x.delete_flag == false && x.type != 2)).ToList();
            if (!string.IsNullOrEmpty(projectid))
                userlist = userlist.Where(x => x.projectlist.Contains(projectid)).ToList();
            foreach (var item in list)
            {
                if (item.touser!=null && item.touser.Count>0)
                {
                    item.tousertel = userlist.Where(y=> item.touser.Contains(y.usercode)).Select(x=>x.mobile).ToList();
                }
            }
            var obj = new
            {
                rows = list.ToList(),
                total = recordCount
            };
            return Success("获取成功", obj);
        }

        /// <summary>
        /// 违规工单列表分页 - 随机工单 by page
        /// </summary>
        /// <param name="keyword"></param>
        /// <param name="stime"></param>
        /// <param name="etime"></param>
        /// <param name="pageindex"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        [HttpGet("getoffencewolistbypage")]
        public IActionResult GetOffenceWOListByPageAsync(string keyword, string projectid, string stime, string etime, int datetype = -1,int isappeal = -1, int pageindex = 1, int pagesize = 10)
        {
            string rolecode = User.Claims.FirstOrDefault(c => c.Type == "RoleCode").Value;
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;

            //var userstr = _signTokenService.GetUserInfoAsync(usercode).Result;
            //var userinfo = userstr.ToJObject()["data"].ToString().ToObject<UserInfoModel>();
            
            var userinfos = _sys_user_accountRepository.GetUserInfo(usercode);
            var userinfo = JsonHelper.JsonToEntity<UserAccountInfoModel>(userinfos.ToJson());

            //获取当天、本周、本月、本年、累计时间
            if (datetype != -1)
            {
                GetStartEndTime(datetype, out stime, out etime);
            }
            //获取数据
            int recordCount = 0;
            var result = _distri_workorderrepository.GetOffenceWOListByPageAsync(keyword, projectid, stime, etime, rolecode, usercode, userinfo, isappeal, pageindex, pagesize, out recordCount);
            var obj = new
            {
                rows = result.ToList(),
                total = recordCount
            };
            return Success("获取成功", obj);
        }

        /// <summary>
        /// 获取当天、本周、本月、本年、累计时间
        /// </summary>
        /// <param name="datetype"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        public void GetStartEndTime(int datetype, out string start, out string end)
        {
            start = string.Empty;
            end = string.Empty;

            var datenow = DateTime.Now;
            var datestart = datenow;
            var dateend = datenow;
            switch (datetype)
            {
                case 0://当天
                    break;
                case 1://本周
                    int n = (int)datenow.DayOfWeek == 0 ? 7 : (int)datenow.DayOfWeek;
                    datestart = datenow.AddDays(1 - n);//本周周一
                    dateend = datestart.AddDays(6);//本周周日
                    break;
                case 2://本月

                    datestart = datenow.AddDays(1 - datenow.Day);  //本月月初  
                    dateend = datestart.AddMonths(1).AddDays(-1);  //本月月末  
                    break;
                case 3://本年
                    datestart = new DateTime(datenow.Year, 1, 1);  //本年年初  
                    dateend = new DateTime(datenow.Year, 12, 31);  //本年年末  
                    break;
                case 4://全部
                    break;
                default:
                    break;
            }
            if (datetype != 4)
            {
                start = datestart.ToString("yyyy-MM-dd");
                end = dateend.ToString("yyyy-MM-dd");
            }
        }
        #endregion

        #region 电梯岗 / 配送岗操作
        //工单状态(0新任务，1已接单（待取货），2已取货（待配送）)

        /// <summary>
        /// 接单 - 电梯岗 - 不用
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost("receivebyelevator")]
        public async Task<IActionResult> UpdateReceiveByElevatorAsync(string id, int channel = 1)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;
            if (string.IsNullOrEmpty(id))
                return Error("参数错误");
            var model = await _distri_workorderrepository.GetSingle(id);
            if (model == null)
                return Error("操作失败");
            #region 未处理工单超限
            int limitmaxcount = _distri_workorderrepository.GetLimitMaxCount(usercode);
            if (limitmaxcount > 0)
                return Error("你已经有" + limitmaxcount + "个未处理工单，已超上限");
            #endregion
            if (model.wostate_elevator == (int)EnumDistributionState_elevator.accept)
                return Error("您已接单");
            if (model.wostate_elevator == (int)EnumDistributionState_elevator.delivery)
                return Error("您已取货");

            model.touser_elevator = usercode;     //电梯岗 - 接单人
            model.wostate_elevator = (int)EnumDistributionState_elevator.accept;    //电梯岗 - 工单状态(0无操作，1已接单（待取货），2已取货（待配送）)
            model.assigtime_elevator = DateTime.Now;
            bool b = await _distri_workorderrepository.UpdateOne(model);
            if (b)
            {
                //if (model.channel == 4 && model.wostate_elevator == (int)EnumDistributionState_elevator.create)
                //{
                //    var model_Dilivery = model.deliverylist.FirstOrDefault();
                //    string content = "取货地址：" + model_Dilivery != null ? model_Dilivery.building_name : "" + model_Dilivery != null ? model_Dilivery.floor_name : "" + " 科室：" + model_Dilivery != null ? model_Dilivery.department_name : ""
                //        + "\n联系人：" + model_Dilivery != null ? model_Dilivery.fullname : ""
                //        + "\n联系电话：" + model_Dilivery != null ? model_Dilivery.mobile : ""
                //        + "\n接单人：" + usercode + "-" + username
                //        + "\n接单时间：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                //    SendWechatMsg(model.wocode, "电梯岗接单成功！", "电梯岗已接单成功，等待配送岗取货", content, model.id, model.createtby);
                //}

                int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator,channel, islast, usercode, "", "电梯岗" + username + "接单", usercode);
                return Success("接单成功");
            }
            return Error("接单失败");
        }
        
        /// <summary>
        /// 取货 - 电梯岗 - 不用
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost("deliverybyelevator")]
        public async Task<IActionResult> UpdateDeliveryByElevatorAsync(string id, int channel = 1)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;
            if (string.IsNullOrEmpty(id))
                return Error("参数错误");
            var model = await _distri_workorderrepository.GetSingle(id);
            if (model == null)
                return Error("操作失败");
            if(model.wostate_elevator == (int)EnumDistributionState_elevator.create)
                return Error("请接单后再取货");
            if (model.wostate_elevator == (int)EnumDistributionState_elevator.delivery)
                return Error("您已取货");

            //model.touser_elevator = usercode;     //电梯岗 - 接单人            
            model.wostate_elevator = (int)EnumDistributionState_elevator.delivery;  //电梯岗 - 工单状态(0无操作，1已接单（待取货），2已取货（待配送）)
            bool b = await _distri_workorderrepository.UpdateOne(model);
            if (b)
            {
                int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islast, usercode, "", "电梯岗" + username + "取货", usercode);
                return Success("取货成功");
            }
            return Error("取货失败");
        }

        /// <summary>
        /// 退单退回 - 电梯岗/配送岗
        /// 1、 当天配送工单已派单，添加退回按钮；
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost("updatebackorder")]
        public async Task<IActionResult> UpdateBackOrderAsync(string id)
        {
            DateTime dt = DateTime.Now;
            
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            string rolecode = User.Claims.FirstOrDefault(c => c.Type == "RoleCode").Value;
            string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;
            #region 验证判断
            if (string.IsNullOrEmpty(id))
                return Error("参数错误");
            var model = await _distri_workorderrepository.GetSingle(id);
            if (model == null)
                return Error("操作失败");
            // 判断添加工单时间是当天的，方可退单
            if (DateTime.Parse(model.createtime.ToString()).Date == DateTime.Parse(dt.ToString()).Date)
                return Error("操作失败，非当天工单不能退单");
            #endregion

            /// 配送岗
            if (rolecode == "SSY_PSG")
            {
                model.touser = new List<string>();     //配送岗 - 转派人/抢单人 - 置空
                model.totype = (int)EnumDistributionTotype.create;
                model.assigtime = new DateTime();
                //配送工单状态:0创建工单，1转派或者抢单（待取货）,2已取货（配送中）,3货物异常（异常），4已完结/待评价，5已取消，6挂起 ，9已评价 
                model.wostate = (int)EnumDistributionState.create;      
            }
            // 电梯岗
            if (rolecode == "SSY_DTG")
            {
                if (model.touser.Contains(usercode))
                {
                    model.touser = new List<string>();     //配送岗 - 转派人/抢单人 - 置空
                    model.totype = (int)EnumDistributionTotype.create;      // 置空
                    model.assigtime = new DateTime();                       // 置空
                    //配送工单状态:0创建工单，1转派或者抢单（待取货）,2已取货（配送中）,3货物异常（异常），4已完结/待评价，5已取消，6挂起 ，9已评价     // 置空
                    model.wostate = (int)EnumDistributionState.create;
                }
                else {
                    model.touser_elevator = "";     //电梯岗 - 接单人 // 置空
                    model.wostate_elevator = (int)EnumDistributionState_elevator.create;    //电梯岗 - 工单状态(0无操作，1已接单（待取货），2已取货（待配送）)  // 置空
                    model.assigtime_elevator = new DateTime();
                }               
            }
            bool bo = await _distri_workorderrepository.UpdateOne(model);

            if (bo)
            {
                int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, model.channel, islast, model.touser.ToJson(), "", "配送岗" + username + "退单：", usercode);
                return Success("退单成功");
            }
            return Error("退单失败");
        }


        /// <summary>
        /// 同意 - 电梯岗 / 配送岗
        /// </summary>
        /// <param name="isupdatetype">申请类型（1需要修改，2需要取消）</param>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost("agree")]
        public async Task<IActionResult> UpdateAgreeAsync(string id, int isupdatetype = 1, int channel = 1)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;

            #region 验证判断
            if (string.IsNullOrEmpty(id))
                return Error("参数错误");
            var model = await _distri_workorderrepository.GetSingle(id);
            if (model == null)
                return Error("操作失败");
            var model_Record = new Distri_Workorder_UpdateRecord();
            model_Record = await _distri_workorder_updaterrecordrepository.GetSingle(x => x.woid == model.id && x.isagree == 0 && x.isupdate == 0 && x.isdelete == 0);
            if (model_Record == null)
                return Error("操作失败");
            int istype = model_Record.isupdatetype;
            #endregion           

            model_Record.isagree = 2;
            bool b = await _distri_workorder_updaterrecordrepository.Update(model_Record);            
            if (b)
            {
                ////if (model.channel == 4){}
                //string str = "";
                //if (model_Record.isupdatetype == 2)
                //{
                //    var model_wo = await _distri_workorderrepository.GetSingle(id);
                //    if (model_wo == null)
                //        return Error("操作失败");
                //    model_wo.wostate = (int)EnumDistributionState.canceled;    //取消
                //    bool b_wo = await _distri_workorderrepository.UpdateOne(model_wo);
                //    if (b_wo)
                //        str = ",且工单已取消";
                //}
                int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islast, usercode, "", "同意修改/取消工单的申请", usercode);
                return Success("同意操作成功");
            }
            return Error("同意操作失败");
        }

        /// <summary>
        /// 不同意 - 电梯岗 / 配送岗
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost("disagree")]
        public async Task<IActionResult> UpdateDisagreeAsync(string id, int channel = 1)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;

            #region 验证判断
            if (string.IsNullOrEmpty(id))
                return Error("参数错误");
            var model = await _distri_workorderrepository.GetSingle(id);
            if (model == null)
                return Error("操作失败");
            var model_Record = new Distri_Workorder_UpdateRecord();
            model_Record = await _distri_workorder_updaterrecordrepository.GetSingle(x => x.woid == model.id && x.isagree == 0 && x.isupdate == 0 && x.isdelete == 0);
            if (model_Record == null)
                return Error("操作失败");
            #endregion

            model_Record.isagree = 1;
            bool b = await _distri_workorder_updaterrecordrepository.Update(model_Record);
            if (b)
            {
                //if (model.channel == 4){}

                int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islast, usercode, "", "不同意修改/取消工单的申请", usercode);
                return Success("不同意操作成功");
            }
            return Error("不同意操作失败");
        }

        
        /// <summary>
        /// 抢单 - 配送岗/电梯岗
        /// </summary>
        /// <param name="id"></param>
        /// <param name="channel"></param>
        /// <returns></returns>
        [HttpPost("receive")]
        public async Task<IActionResult> UpdateReceiveAsync(string id,int channel = 1)
        {
            string rolecode = User.Claims.FirstOrDefault(c => c.Type == "RoleCode").Value;
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;

            //var userstr = _signTokenService.GetUserInfoAsync(usercode).Result;
            //var userinfo = userstr.ToJObject()["data"].ToString().ToObject<UserInfoModel>();
            
            var userinfos = _sys_user_accountRepository.GetUserInfo(usercode);
            var userinfo = JsonHelper.JsonToEntity<UserAccountInfoModel>(userinfos.ToJson());

            #region 验证判断
            if (string.IsNullOrEmpty(id))
                return Error("参数错误");
            var model = await _distri_workorderrepository.GetSingle(id);
            if (model == null)
                return Error("操作失败");
            #endregion        
            // 获取当前角色 - by 排班
            string rolecode_ByUserMap = _distri_workorderrepository.GetUserCodeByClassMap(usercode);

            string rolename = string.Empty;
            // 电梯岗
            if (rolecode_ByUserMap == "SSY_DTG")
            {
                rolename = "电梯岗";
                #region 未处理工单超限
                int limitmaxcount = _distri_workorderrepository.GetLimitMaxCount(usercode);
                if (limitmaxcount > 0)
                    return Error("你已经有" + limitmaxcount + "个未处理工单，已超上限");
                #endregion
                if (model.wostate_elevator == (int)EnumDistributionState_elevator.accept)
                    return Error("您已接单");
                if (model.wostate_elevator == (int)EnumDistributionState_elevator.delivery)
                    return Error("您已取货");

                model.touser_elevator = usercode;     //电梯岗 - 接单人
                model.wostate_elevator = (int)EnumDistributionState_elevator.accept;    //电梯岗 - 工单状态(0无操作，1已接单（待取货），2已取货（待配送）)
                model.assigtime_elevator = DateTime.Now;
            }
            else if (rolecode_ByUserMap == "SSY_PSG")
            {
                rolename = "配送员";
                if (model.wostate == (int)EnumDistributionState.assign)
                    return Error("工单已转派或抢单，无需再抢单");
                if (model.wostate >= (int)EnumDistributionState.delivery)
                    return Error("工单已被取货，无需再抢单");
                //判断此用户下是否有计划任务，如果有不让抢单，没有让抢单
                var listPlanTask = (await _distri_workorder_plantaskrepository.Get(x => x.isdelete == 0 && x.joinuserlist.Contains(usercode) && userinfo.projectlist.Contains(x.projectid) && x.planwostate < (int)EnumDistriWorkOrderPlanWOstate.finish)).ToList();
                if (listPlanTask != null && listPlanTask.Count > 0)
                    return Error("您有计划任务没有完成，不能抢单");
                if (model.wostate == (int)EnumDistributionState.create)
                {
                    model.touser = new List<string>() { usercode };     //配送岗 - 转派人/抢单人
                    model.totype = (int)EnumDistributionTotype.robbery;
                    model.assigtime = DateTime.Now;
                    //配送工单状态:0创建工单，1转派或者抢单（待取货）,2已取货（配送中）,3货物异常（异常），4已完结/待评价，5已取消，6挂起 ，9已评价 
                    model.wostate = (int)EnumDistributionState.assign;
                }
            }
            else {
                return Error("接单失败");
            }
            bool b = await _distri_workorderrepository.UpdateOne(model);
            if (b)
            {
                if (model.channel == 4)
                {
                    var model_Receiver = model.receiverlist.FirstOrDefault();
                    string content = "抢单人：" + usercode + "-" + username
                        + "\n联系电话：" + (userinfo != null ? userinfo.mobile : "")
                        + "\n收货地址：" + (model_Receiver != null ? model_Receiver.building_name : "") + (model_Receiver != null ? model_Receiver.floor_name : "") + " 科室：" + (model_Receiver != null ? model_Receiver.department_name : "")
                        + "\n接单时间：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    _logger.LogError("neirong: " + content);
                    SendWechatMsg(model.wocode, rolename + "抢单成功！", rolename + "已抢单成功，等待配送员取货", content, model.id, model.createtby);
                }

                int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islast, usercode, "", rolename + username + "接单：", usercode);
                return Success("接单成功");
            }
            return Error("接单失败");
        }

        /// <summary>
        /// 指派 - 配送岗 - 指派
        /// </summary>
        /// <param name="id"></param>
        /// <param name="touser"></param>
        /// <param name="wostate"></param>
        /// <param name="channel"></param>
        /// <returns></returns>
        [HttpPost("assign")]
        public async Task<IActionResult> UpdateAssignAsync(string id, string touser,int channel = 1)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;
            //var userstr = _signTokenService.GetUserInfoAsync(usercode).Result;
            //var userinfo = userstr.ToJObject()["data"].ToString().ToObject<UserInfoModel>();
            
            var userinfos = _sys_user_accountRepository.GetUserInfo(usercode);
            var userinfo = JsonHelper.JsonToEntity<UserAccountInfoModel>(userinfos.ToJson());

            #region 验证判断         
            if (string.IsNullOrEmpty(id))
                return Error("参数错误");
            if (string.IsNullOrEmpty(touser))
                return Error("转派的对象不能为空");
            var model = await _distri_workorderrepository.GetSingle(id);
            if (model == null)
                return Error("保存失败");
            #region 未处理工单超限
            int limitmaxcount = _distri_workorderrepository.GetLimitMaxCount(usercode);
            if (limitmaxcount > 0)
                return Error("你已经有" + limitmaxcount + "个未处理工单，已超上限");
            #endregion
            if (model.wostate == (int)EnumDistributionState.assign)
                return Error("工单已转派或已抢单，无需再转派抢单");
            if (model.wostate >= (int)EnumDistributionState.delivery)
                return Error("工单已取货，无需再转派");
            //判断此用户下是否有计划任务，如果有不让抢单，没有让抢单
            var listPlanTask = (await _distri_workorder_plantaskrepository.Get(x => x.isdelete == 0 && x.joinuserlist.Contains(usercode) && userinfo.projectlist.Contains(x.projectid) && x.planwostate < (int)EnumDistriWorkOrderPlanWOstate.finish)).ToList();
            if (listPlanTask != null && listPlanTask.Count > 0)
                return Error("您有计划任务没有完成，不能派单");
            #endregion

            if (model.wostate == (int)EnumDistributionState.create)   // || model.wostate == (int)EnumDistributionState.hangup  || model.wostate == (int)EnumDistributionState.assign
            {
                model.touser = new List<string>() { touser }; // 转派人/抢单人
                model.totype = (int)EnumDistributionTotype.send;
                model.assigtime = DateTime.Now;
                //配送工单状态:0创建工单，1转派或者抢单（待取货）,2已取货（配送中）,3货物异常（异常），4已完结/待评价，5已取消，6挂起 ，9已评价 
                model.wostate = (int)EnumDistributionState.assign;

                var res = await _distri_workorderrepository.UpdateOne(model);

                int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islast, touser, "", username + "转派工单，工单编号：" + model.wocode, usercode);
                return Success("转派工单成功");
            }
            return Error("转派工单失败");
        }

        /// <summary>
        /// 批量转派 - 主管
        /// </summary>
        /// <param name="id"></param>
        /// <param name="touser"></param>
        /// <param name="wostate"></param>
        /// <param name="channel"></param>
        /// <returns></returns>
        [HttpPost("assignmany")]
        public async Task<IActionResult> UpdateAssignManyAsync(string[] ids, string touser, int channel = 1)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;
            //var userstr = _signTokenService.GetUserInfoAsync(usercode).Result;
            //var userinfo = userstr.ToJObject()["data"].ToString().ToObject<UserInfoModel>();
            
            var userinfos = _sys_user_accountRepository.GetUserInfo(usercode);
            var userinfo = JsonHelper.JsonToEntity<UserAccountInfoModel>(userinfos.ToJson());

            if (string.IsNullOrEmpty(touser))
                return Error("转派的对象不能为空");
            #region 未处理工单超限
            int limitmaxcount = _distri_workorderrepository.GetLimitMaxCount(usercode);
            if (limitmaxcount > 0)
                return Error("你已经有" + limitmaxcount + "个未处理工单，已超上限");
            #endregion
            int res = 0;
            if (ids != null && ids.Length > 0)
            {
                foreach (var item in ids)
                {
                    var model = await _distri_workorderrepository.GetSingle(item);
                    if (model != null)
                    {
                        if (model.wostate == (int)EnumDistributionState.create)
                        {
                            model.touser = new List<string>() { touser };
                            model.totype = (int)EnumDistributionTotype.send;
                            model.assigtime = DateTime.Now;
                            //配送工单状态:0创建工单，1转派或者抢单（待取货）,2已取货（配送中）,3货物异常（异常），4已完结/待评价，5已取消，6挂起 ，9已评价 
                            model.wostate = (int)EnumDistributionState.assign;

                            var b = await _distri_workorderrepository.UpdateOne(model);
                            if (b)
                            {
                                int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                                AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islast, touser, "", username + "指派工单，工单编号：" + model.wocode, usercode);
                                res++;
                            }
                        }
                    }
                }
            }
            if (res == ids.Length)
            {
                return Success("转派工单成功");
            }
            else if (res > 0 && res < ids.Length)
            {
                return Error("部分工单转派失败，请稍后重试");
            }
            else
            {
                return Error("转派工单失败");
            }
        }

        /// <summary>
        /// 取货 - 配送岗/电梯岗（无电梯岗取货，需取货）
        /// </summary>
        /// <param name="id"></param>
        /// <param name="channel"></param>
        /// <returns></returns>
        [HttpPost("delivery")]
        public async Task<IActionResult> UpdateDeliveryAsync(string id,int channel = 1)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;

            if (string.IsNullOrEmpty(id))
                return Error("参数错误");
            var model = await _distri_workorderrepository.GetSingle(id);
            if (model == null)
                return Error("操作失败");
            // 获取当前角色 - by 排班
            string rolecode_ByUserMap = _distri_workorderrepository.GetUserCodeByClassMap(usercode);

            string rolename = string.Empty;
            // 电梯岗
            if (rolecode_ByUserMap == "SSY_DTG")
            {
                rolename = "电梯岗";
                if (model.wostate_elevator == (int)EnumDistributionState_elevator.create)
                    return Error("请接单后再取货");
                if (model.wostate_elevator == (int)EnumDistributionState_elevator.delivery)
                    return Error("您已取货");
                //model.touser_elevator = usercode;     //电梯岗 - 接单人            
                model.wostate_elevator = (int)EnumDistributionState_elevator.delivery;  //电梯岗 - 工单状态(0无操作，1已接单（待取货），2已取货（待配送）)               
            }
            else if (rolecode_ByUserMap == "SSY_PSG")
            {
                rolename = "配送员";
                if (model.wostate == (int)EnumDistributionState.delivery)
                    return Error("工单已取货，无需再取货");
                if (model.wostate >= (int)EnumDistributionState.finish)
                    return Error("工单已完结/待评价，无需再取货");
                //配送工单状态:0创建工单，1转派或者抢单（待取货）,2已取货（配送中）,3货物异常（异常），4已完结/待评价，5已取消，6挂起 ，9已评价 
                model.wostate = (int)EnumDistributionState.delivery;
            }
            else
            {
                return Error("接单失败");
            }

            bool b = await _distri_workorderrepository.UpdateOne(model);
            if (b)
            {
                int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islast, usercode, "", rolename + username + "取货", usercode);
                return Success("取货成功");
            }
            return Error("取货失败");
        }

        /// <summary>
        /// 异常 - 配送岗（配送异常/取货异常）
        /// </summary>
        /// <param name="id"></param>
        /// <param name="channel"></param>
        /// <returns></returns>
        [HttpPost("exceptions")]
        public async Task<IActionResult> UpdateExceptionsAsync(string id, List<FileBaseModel> files, string exceptions,int type = 1, int isback_sended = 0, int channel = 1)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;
            if (string.IsNullOrEmpty(id))
                return Error("参数错误");
            //if (string.IsNullOrEmpty(exceptions))
            //    return Error("异常说明不能为空");
            var model = await _distri_workorderrepository.GetSingle(id);
            if (model == null)
                return Error("操作失败");

            var model_ex = new Distri_Workorder_Exception();
            if (type == 1)
            {
                if (model.wostate >= (int)EnumDistributionState.finish && model.wostate == (int)EnumDistributionState.delivery)
                    return Error("工单已完成，不能操作");
                //配送岗 - 转派人/抢单人
                model.dealby = new List<string>() { usercode };
                model.dealtime = DateTime.Now;
                model.isexceptions = 1;
                //配送工单状态:0创建工单，1转派或者抢单（待取货）,2已取货（配送中）,3货物异常（异常），4已完结/待评价，5已取消，6挂起，7取货异常退单，9已评价 
                model.wostate = (int)EnumDistributionState.exceptions;
            }
            else {
                //配送工单状态:0创建工单，1转派或者抢单（待取货）,2已取货（配送中）,3货物异常（异常），4已完结/待评价，5已取消，6挂起，7取货异常退单，9已评价 
                model.wostate = (int)EnumDistributionState.backed;
            }
            bool b = await _distri_workorderrepository.UpdateOne(model);

            if (b)
            {
                model_ex.woid = id;
                model_ex.wocode = model.wocode;
                model_ex.projectid = model.projectid;
                model_ex.type = type;
                model_ex.isback_sended = isback_sended;
                model_ex.files = files;
                model_ex.content = exceptions;
                model_ex.createuser = usercode;
                model_ex.createusername = username;
                model_ex.isdelete = 0;
                model_ex.createtime = DateTime.Now;
                await _distri_workorder_exceptionrepository.Add(model_ex);

                //if (model.channel == 4){}

                int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islast, usercode, "", "配送岗" + usercode + "提交异常"+ (type == 1 ? "送达异常" : "取货异常"), usercode);
                return Success("异常操作成功");
            }
            return Error("异常操作失败");
        }
        

        /// <summary>
        /// 完结 - 签收确认 - 配送岗/主管
        /// </summary>
        /// <param name="id"></param>
        /// <param name="channel"></param>
        /// <returns></returns>
        [HttpPost("finish")]
        public async Task<IActionResult> UpdateFinishAsync(string id, List<FileBaseModel> files, List<FileBaseModel> filesplan, int channel = 1)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;
            string rolecode = User.Claims.FirstOrDefault(c => c.Type == "RoleCode").Value;

            //var userstr = _signTokenService.GetUserInfoAsync(usercode).Result;
            //var userinfo = userstr.ToJObject()["data"].ToString().ToObject<UserInfoModel>();
            
            var userinfos = _sys_user_accountRepository.GetUserInfo(usercode);
            var userinfo = JsonHelper.JsonToEntity<UserAccountInfoModel>(userinfos.ToJson());

            if (string.IsNullOrEmpty(id))
                return Error("参数错误");           
            var model = await _distri_workorderrepository.GetSingle(id);
            if (model == null)
                return Error("操作失败");            
            if (model.wostate >= (int)EnumDistributionState.finish)
                return Error("工单已完结，不能再操作");
            if (model.wostate == (int)EnumDistributionState.delivery || model.wostate == (int)EnumDistributionState.exceptions)
            {
                if (model.wostate == (int)EnumDistributionState.delivery && rolecode != "SSY_ZG")
                {
                    if (model.wosorts == (int)EnumDistributionWoSorts.plan)
                    {
                        if (filesplan == null && filesplan.Count <= 0)
                            return Error("收货人需要拍照");
                        model.planwopic = filesplan;
                    }
                    else
                    {
                        if (files == null && files.Count <= 0)
                            return Error("收货人需要签字");
                        model.signbypic = files;
                    }

                    //配送岗 - 转派人/抢单人
                    model.dealby = new List<string>() { usercode };
                    model.dealtime = DateTime.Now;
                }
                //异常的工单，在主管处可进行确定完结的操作，完结后也算工作量，不参与评价。
                if (model.wostate == (int)EnumDistributionState.exceptions) {
                    model.isexceptions = 0;
                    if (rolecode != "SSY_ZG")
                        return Error("异常工单，只有主管确定完结");
                }                
                //配送工单状态:0创建工单，1转派或者抢单（待取货）,2已取货（配送中）,3货物异常（异常），4已完结/待评价，5已取消，6挂起 ，9已评价 
                model.wostate = (int)EnumDistributionState.finish;
                bool b = await _distri_workorderrepository.UpdateOne(model);

                if (model.channel == 4)
                {
                    var model_Receiver = model.receiverlist.FirstOrDefault();
                    string content = "抢单人：" + usercode + "-" + username
                        + "\n联系电话：" + (userinfo != null ? userinfo.mobile : "")
                        + "\n收货地址：" + (model_Receiver != null ? model_Receiver.building_name : "") + (model_Receiver != null ? model_Receiver.floor_name : "") + " 科室：" + (model_Receiver != null ? model_Receiver.department_name : "")
                        + "\n完结时间：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    SendWechatMsg(model.wocode, "工单完结成功！", "工单已完结成功，等待您的评价", content, model.id, model.createtby);
                }
                int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islast, usercode, "", "" + username + "完结工单", usercode);
                return Success("完结成功");
            }
            return Error("完结失败");
        }

        /// <summary>
        /// 取消 - 配送岗
        /// </summary>
        /// <param name="id"></param>
        /// <param name="channel"></param>
        /// <returns></returns>
        [HttpPost("cancel")]
        public async Task<IActionResult> UpdateCancelAsync(string id, int channel = 1)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;
            string rolecode = User.Claims.FirstOrDefault(c => c.Type == "RoleCode").Value;

            #region 验证判断
            if (string.IsNullOrEmpty(id))
                return Error("参数错误");
            var model = await _distri_workorderrepository.GetSingle(id);
            if (model == null)
                return Error("操作失败");
            #endregion
            //操作权限解释 - 下单人在下单后的修改和撤单操作权限是在电梯岗（配送岗）已取货之前均可操作
            var model_Record = new Distri_Workorder_UpdateRecord();
            if (model.wostate >= (int)EnumDistributionState.delivery || model.wostate >= (int)EnumDistributionState_elevator.delivery)
            {
                model_Record = await _distri_workorder_updaterrecordrepository.GetSingle(x => x.woid == model.id && x.isagree == 2 && x.isupdate == 0 && x.isdelete == 0);
                if (model_Record == null)
                {
                    //没有申请修改/取消
                    if (model.wostate >= (int)EnumDistributionState.delivery)
                        return Error("配送岗已取货之后不能取消");
                    if (model.wostate >= (int)EnumDistributionState_elevator.delivery)
                        return Error("电梯岗已取货之后不能取消");
                }
            }

            //配送岗 - 取消时间
            model.canceltime = DateTime.Now;
            //配送工单状态:0创建工单，1转派或者抢单（待取货）,2已取货（配送中）,3货物异常（异常），4已完结/待评价，5已取消，6挂起 ，9已评价 
            model.wostate = (int)EnumDistributionState.canceled;
            bool b = await _distri_workorderrepository.UpdateOne(model);
            if (b)
            {
                //更新申请修改/取消表
                if (model_Record != null)
                {
                    model_Record.isupdate = 1;
                    await _distri_workorder_updaterrecordrepository.Update(model_Record);
                }

                //if (model.channel == 4){}

                int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islast, usercode, "", "" + username + "取消工单", usercode);
                return Success("取消成功");
            }
            return Error("取消失败");
        }

        /// <summary>
        /// 评价 - 配送岗、科室人员 - 添加配送工单人员
        /// </summary>
        /// <param name="id"></param>
        /// <param name="wocode"></param>
        /// <param name="star"></param>
        /// <param name="evaluate"></param>
        /// <param name="label"></param>
        /// <param name="files"></param>
        /// <param name="channel"></param>
        /// <returns></returns>
        [HttpPost("evaluate")]
        public async Task<IActionResult> UpdateEvaluateAsync(string id, string wocode, int star, string evaluate, List<string> label, List<FileBaseModel> files, int channel = 1)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;
            //string rolecode = User.Claims.FirstOrDefault(c => c.Type == "RoleCode").Value;

            if (string.IsNullOrEmpty(id))
                return Error("参数错误");
            var model = await _distri_workorderrepository.GetSingle(id);
            if (model != null && model.wostate == (int)EnumDistributionState.finish)
            {
                if (model.createtby == usercode)
                {
                    //配送岗 - 评价时间
                    model.evaluatetime = DateTime.Now;
                    //配送工单状态:0创建工单，1转派或者抢单（待取货）,2已取货（配送中）,3货物异常（异常），4已完结/待评价，5已取消，6挂起 ，9已评价 
                    model.wostate = (int)EnumDistributionState.evaluated;
                    model.starnum = star;
                    await _distri_workorderrepository.UpdateOne(model);

                    Distri_Workorder_Evaluate model_ev = new Distri_Workorder_Evaluate();
                    model_ev.woid = id;
                    model_ev.wocode = model.wocode;
                    model_ev.projectid = model.projectid;
                    model_ev.channel = channel;
                    model_ev.evaluate = evaluate;
                    model_ev.label = label;
                    model_ev.starnum = star;
                    model_ev.createuser = usercode;
                    model_ev.createusername = username;
                    model_ev.isdelete = 0;
                    model_ev.createtime = DateTime.Now;
                    await _distri_workorder_evaluaterepository.Add(model_ev);

                    //if (model.channel == 4){}

                    int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                    AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islast, usercode, "", "" + username + "评价工单，分数：" + star * 20 + "（" + star + "星级）", usercode);
                    return Success("评价成功");
                }
                return Error("无权评价");
            }            
            return Error("操作失败");
        }

        /// <summary>
        /// 超时系统评价 - 配送
        /// </summary>
        [AllowAnonymous]
        [HttpPost("distritimeoutevaluate")]
        public async Task<IActionResult> TimeOutEvaluateForDistriAsync(int star = 5, string createusername = "系统", int channel = 5)
        {
            // 获取评价规定时间间隔
            int hour = _distri_workorderrepository.GetEvaluateHour();

            if (hour > 0)
            {
                //处理时间从2019-03-01 00：00：00开始，如果在时间间隔内没有评价，系统自动评价5分
                var lists = await _distri_workorderrepository.Get(x => x.isdelete == 0 && x.wostate == (int)EnumDistributionState.finish
                            && x.dealtime < DateTime.Now.AddHours(-hour));
                            //&& x.dealtime.Value >= DateTime.Parse("2019-03-01 00:00:00"));
                foreach (var model in lists)
                {
                    //配送岗 - 评价时间
                    model.evaluatetime = DateTime.Now;
                    //配送工单状态:0创建工单，1转派或者抢单（待取货）,2已取货（配送中）,3货物异常（异常），4已完结/待评价，5已取消，6挂起 ，9已评价 
                    model.wostate = (int)EnumDistributionState.evaluated;
                    model.starnum = star;
                    await _distri_workorderrepository.UpdateOne(model);

                    Distri_Workorder_Evaluate model_ev = new Distri_Workorder_Evaluate();
                    model_ev.woid = model.wocode;
                    model_ev.wocode = model.wocode;
                    model_ev.projectid = model.projectid;
                    model_ev.channel = channel;
                    model_ev.evaluate = ""; //evaluate;
                    model_ev.label = new List<string>();
                    model_ev.starnum = star;
                    model_ev.createuser = "";
                    model_ev.createusername = createusername;
                    model_ev.isdelete = 0;
                    model_ev.createtime = DateTime.Now;
                    await _distri_workorder_evaluaterepository.Add(model_ev);

                    //if (model.channel == 4){}
                    
                    int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                    AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islast, "", "", "" + createusername + "评价工单，分数：" + star * 20 + "（" + star + "星级）", "");
                    
                }

                return Success("评价成功");
            }
            else
            {
                return Error("未设置时间间隔");
            }
        }


        /// <summary>
        /// 挂起 - 配送岗 - 不用
        /// </summary>
        /// <param name="id"></param>
        /// <param name="channel"></param>
        /// <returns></returns>
        //[HttpPost("hangup")]
        //public async Task<IActionResult> UpdateHangupAsync(string id, int channel = 1)
        //{
        //    string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
        //    string rolecode = User.Claims.FirstOrDefault(c => c.Type == "RoleCode").Value;

        //    if (string.IsNullOrEmpty(id))
        //        return Error("参数错误");
        //    var model = await _distri_workorderrepository.GetSingle(id);
        //    if (model == null)
        //        return Error("操作失败");
        //    //if (model.wostate == (int)EnumDistributionState.hangup)
        //    //    return Error("工单已挂起，不能再操作");

        //    //配送岗 - 取消时间
        //    model.canceltime = DateTime.Now;
        //    //配送工单状态:0创建工单，1转派或者抢单（待取货）,2已取货（配送中）,3货物异常（异常），4已完结/待评价，5已取消，6挂起 ，9已评价 
        //    model.wostate = (int)EnumDistributionState.hangup;

        //    bool b = await _distri_workorderrepository.UpdateOne(model);
        //    if (b)
        //    {
        //        int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
        //        AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islast, usercode, "", "配送岗" + usercode + "取消工单", usercode);
        //        return Success("挂起成功");
        //    }
        //    return Error("挂起失败");
        //}

        /// <summary>
        /// 违规申诉 - 配送岗
        /// </summary>
        /// <param name="id"></param>
        /// <param name="wocode"></param>
        /// <param name="star"></param>
        /// <param name="evaluate"></param>
        /// <param name="label"></param>
        /// <param name="files"></param>
        /// <param name="channel"></param>
        /// <returns></returns>
        [HttpPost("offence")]
        public async Task<IActionResult> UpdateOffenceAsync(string id, string content, int channel = 1)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;

            if (string.IsNullOrEmpty(id))
                return Error("参数错误");
            var model = await _distri_workorderrepository.GetSingle(id);
            if (model != null && model.isoffence == 1)
            {
                var model_offence = (await _distri_workorder_offencerecordrepository.GetSingle(x => x.woid == model.id && x.createby == usercode));
                if (model_offence == null)
                {

                    var model_Offence = new Distri_Workorder_OffenceRecord();
                    model_Offence.woid = id;
                    model_Offence.wocode = model.wocode;
                    model_Offence.channel = channel;
                    model_Offence.content = content;
                    model_Offence.createby = usercode;
                    model_Offence.createtime = DateTime.Now;
                    await _distri_workorder_offencerecordrepository.Add(model_Offence);
                    
                    int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                    AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islast, usercode, "", "配送岗" + username + "违规申诉", usercode);
                    return Success("操作成功");
                }
                return Error("已违规申诉过");
            }
            return Error("操作失败");
        }

        /// <summary>
        /// 审核违规申诉 - 主管
        /// </summary>
        /// <param name="id"></param>
        /// <param name="wocode"></param>
        /// <param name="content"></param>
        /// <param name="isaudit">是否审核通过 1不通过 2通过</param>
        /// <param name="channel"></param>
        /// <returns></returns>
        [HttpPost("auditoffence")]
        public async Task<IActionResult> UpdateAuditOffenceAsync(string id, string content, int isaudit = 1, int channel = 1)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;

            if (string.IsNullOrEmpty(id))
                return Error("参数错误");
            var model = await _distri_workorderrepository.GetSingle(id);
            if (model != null && model.isoffence == 1)
            {
                var model_Offence = (await _distri_workorder_offencerecordrepository.GetSingle(x => x.woid == model.id && model.touser.Contains(x.createby)));
                if (model_Offence != null)
                {
                    model_Offence.isaudit = isaudit;
                    model_Offence.content_rejectreason = content;
                    model_Offence.dealby = usercode;
                    model_Offence.dealtime = DateTime.Now;
                    bool b = await _distri_workorder_offencerecordrepository.UpdateOne(model_Offence);
                    if (b)
                    {
                        if (isaudit == 2)
                        {
                            //是否违规 0否 1是
                            model.isoffence = 0;
                            await _distri_workorderrepository.UpdateOne(model);
                        }
                    }
                    //if (model.channel == 4){}
                    int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                    string str_Isaudit = isaudit == 1 ? "(不通过)" : "(已通过） ";
                    AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islast, usercode, "", "" + username + "审核违规申诉" + str_Isaudit + "", usercode);
                    return Success("操作成功");
                }
                return Error("参数错误，请确认是否是配送岗提交的违规申诉");
            }
            return Error("操作失败");
        }
        #endregion

        /// <summary>
        /// 删除配送工单
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [HttpPost("delete")]
        public async Task<IActionResult> DeleteAsync(string[] ids, int channel = 1)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;

            //使用逻辑删除
            var res = 0;
            if (ids != null && ids.Length > 0)
            {
                foreach (var id in ids)
                {
                    var model = await _distri_workorderrepository.GetSingle(id);
                    model.isdelete = 1;
                    model.deleteby = usercode;
                    model.deletetime = DateTime.Now;
                    if (await _distri_workorderrepository.UpdateOne(model))
                    {
                        #region 删除相关表数据
                        //评价
                        var list_Evaluates = await _distri_workorder_evaluaterepository.Get(p => p.woid == model.id && p.isdelete == 0);
                        foreach (var item_evaluate in list_Evaluates)
                        {
                            item_evaluate.isdelete = 1;
                            item_evaluate.deleteby = usercode;
                            item_evaluate.deletetime = DateTime.Now;
                            await _distri_workorder_evaluaterepository.UpdateOne(item_evaluate);
                        }
                        //工单流程
                        var items = await _distri_workorder_itemsrepository.Get(p => p.woid == model.id && p.isdelete == 0);
                        foreach (var item in items)
                        {
                            item.isdelete = 1;
                            item.deleteby = usercode;
                            item.deletetime = DateTime.Now;
                            await _distri_workorder_itemsrepository.UpdateOne(item);
                        }
                        //异常
                        var list_exceptio = await _distri_workorder_exceptionrepository.Get(p => p.woid == model.id && p.isdelete == 0);
                        foreach (var item in list_exceptio)
                        {
                            item.isdelete = 1;
                            item.deleteby = usercode;
                            item.deletetime = DateTime.Now;
                            await _distri_workorder_exceptionrepository.UpdateOne(item);
                        }
                        //违规
                        var list_offence = await _distri_workorder_offencerecordrepository.Get(p => p.woid == model.id && p.isdelete == 0);
                        foreach (var item in list_offence)
                        {
                            item.isdelete = 1;
                            item.deleteby = usercode;
                            item.deletetime = DateTime.Now;
                            await _distri_workorder_offencerecordrepository.UpdateOne(item);
                        }
                        //修改取消申请
                        var list_updaterrecord = await _distri_workorder_updaterrecordrepository.Get(p => p.woid == model.id && p.isdelete == 0);
                        foreach (var item in list_updaterrecord)
                        {
                            item.isdelete = 1;
                            item.deleteby = usercode;
                            item.deletetime = DateTime.Now;
                            await _distri_workorder_updaterrecordrepository.UpdateOne(item);
                        }
                        #endregion
                        int islast = model.wostate == (int)EnumDistributionState.canceled ? 1 : 0;    //是否最后一步 0否 1是
                        AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islast, usercode, "", username + "取消工单", usercode);
                        res += 1;
                    }
                }
                if (res == ids.Length)
                    return Success("删除成功");
                else if (res > 0 && res < ids.Length)
                    return Error("部分删除失败");
                else
                    return Error("删除失败");
            }
            else
                return Error("请选择要删除的记录");
        }

        #region 科室（下单人）
        /// <summary>
        /// 申请修改/取消 - 下单人
        /// </summary>
        /// <param name="id"></param>
        /// <param name="detail">申请内容</param>
        /// <param name="isupdatetype">申请类型（1需要修改，2需要取消）</param>
        /// <param name="channel"></param>
        /// <returns></returns>
        [HttpPost("apply")]
        public async Task<IActionResult> UpdateApplyAsync(string id,string detail, int isupdatetype = 1, int channel = 1)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            string rolecode = User.Claims.FirstOrDefault(c => c.Type == "RoleCode").Value;

            if (string.IsNullOrEmpty(id))
                return Error("参数错误");
            var model = await _distri_workorderrepository.GetSingle(id);
            if (model == null)
                return Error("操作失败");
            //已取货后修改或者撤单，需要申请
            if (model.wosorts == (int)EnumDistributionWoSorts.plan)
                return Error("计划分送工单不能修改");
            if (model.wostate < (int)EnumDistributionState.delivery)
                return Error("工单配送岗未取货，不需要申请方可修改/取消");
            if (model.wostate < (int)EnumDistributionState_elevator.delivery)
                return Error("工单电梯岗未取货，不需要申请方可修改/取消");

            var model_Record = new Distri_Workorder_UpdateRecord();
            model_Record.woid = model.id;
            model_Record.wocode = model.wocode;
            model_Record.channel = channel;
            model_Record.planid = model.planid;
            model_Record.plantaskid = model.plantaskid;
            model_Record.wotype = model.wosorts;
            model_Record.detail = detail;
            model_Record.isagree = 0;
            model_Record.isupdate = 0;
            model_Record.isupdatetype = isupdatetype;
            model_Record.createby = usercode;
            model_Record.createtime = DateTime.Now;
            bool b = await _distri_workorder_updaterrecordrepository.Add(model_Record);         
            if (b)
            {
                //if (model.channel == 4){}

                int islast = model.wostate == (int)EnumDistributionState.finish ? 1 : 0;    //是否最后一步 0否 1是
                AddItems(model.id, model.wocode, model.wostate, model.wostate_elevator, channel, islast, usercode, "", "" + username + "申请修改/取消工单", usercode);
                return Success("申请修改/取消成功");
            }
            return Error("申请修改/取消失败");
        }

        #endregion

        #region 方法
        /// <summary>
        /// 添加工单记录
        /// </summary>
        /// <param name="wocode">工单编号</param>
        /// <param name="wostate">工单状态</param>
        /// <param name="ishasten">是否催办（0不催办1催办）</param>
        /// <param name="islast">是否最后一步 0否 1是</param>
        /// <param name="touser">指派下一步人员</param>
        /// <param name="todept">指派下一步部门</param>
        /// <param name="detail">处理说明</param>
        /// <param name="usercode">当前操作人</param>
        private async void AddItems(string woid, string wocode, int wostate,int wostate_elevator,int channel, int islast, string touser, string todept, string detail, string usercode)
        {
            try
            {
                #region 更新上一步明细
                if (wostate > 0)
                {
                    var listItem = (await _distri_workorder_itemsrepository.Get(x => x.woid == woid)).OrderByDescending(x => x.createtime);
                    if (listItem.Count() > 0)
                    {
                        var itemmodel = listItem.FirstOrDefault();
                        itemmodel.sureuser = new List<string> { usercode };
                        itemmodel.suretime = DateTime.Now;
                        itemmodel.itemstate = 1;
                        itemmodel.islast = islast;
                        await _distri_workorder_itemsrepository.UpdateOne(itemmodel);
                    }
                }
                #endregion
                #region 添加下一步明细
                var model = new Distri_Workorder_Items();
                model.woid = woid;
                model.wocode = wocode;
                model.wostate = wostate;
                model.itemstate = 0;
                model.isdelete = 0;
                model.createby = usercode;
                model.createtime = DateTime.Now;
                model.detail = detail;
                model.islast = islast;
                model.channel = channel;
                if (wostate < (int)EnumEquipmentRunningState.deal)
                {
                    //model.ishasten = ishasten;
                    #region 创建、转派、抢单
                    model.dealby = new List<string> { touser };
                    #endregion
                }
                else if (wostate == (int)EnumEquipmentRunningState.deal)
                {
                    #region 结单
                    model.dealtime = DateTime.Now;
                    model.dealby = new List<string> { usercode };
                    #endregion
                }
                await _distri_workorder_itemsrepository.Add(model);
                #endregion
            }
            catch (Exception ex)
            {
                _logger.LogDebug("工单日志记录异常", ex);
            }
        }

        #endregion

        #region 微信方法
        /// <summary>
        /// 发送微信模板消息
        /// </summary>
        /// <param name="wocode">工单编号</param>
        /// <param name="title">标题</param>
        /// <param name="content">内容</param>
        /// <param name="url">链接地址</param>
        /// <param name="openid">接收方</param>
        /// <param name="templateid">模板id</param>
        private async void SendWechatMsg(string wocode, string title, string statename, string content, string url, string openid, string templateid = "csH1KSQMz8nMnZhlcH7gpOo1aAIZZLiXecYlhGFzvuE")
        {
            url = "menucode=PSDD&id=" + url;
            var obj = new
            {
                first = new { value = title, color = "#173177" },
                keyword1 = new { value = statename },
                keyword2 = new { value = wocode },
                remark = new { value = content }
            };
            await _wechatservice.SendTemplateMsg(openid, url, obj.ToJson(), templateid);
        }

        ///// <summary>
        ///// 发送微信消息
        ///// </summary>
        ///// <param name="wocode">工单编号</param>
        ///// <param name="title">标题</param>
        ///// <param name="content">内容</param>
        ///// <param name="url">链接地址</param>
        ///// <param name="openid">接收方</param>
        //private async void SendWechatMessage(string wocode, string title, string content, string url, string openid)
        //{
        //    url = "menucode=CKXQ&id=" + url;
        //    content = content + "\n时间：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        //    await _wechatservice.SendNewsMsg(openid, title, content, url);
        //}

        #endregion
    }

}