using Furion.DependencyInjection;
using Nirvana.Common;
using Senparc.Weixin.MP;
using Senparc.Weixin.MP.AdvancedAPIs;
using Senparc.Weixin.MP.AdvancedAPIs.OAuth;
using Senparc.Weixin.Open;
using Senparc.Weixin.Open.Containers;
using Senparc.Weixin;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using YBDevice.Entity;
using Furion;
using YBDevice.Core;
using Furion.DistributedIDGenerator;
using DotNetCore.CAP;

namespace YBDevice.NApi.Application.OrdersInfo
{
    /// <summary>
    /// 扫码订单处理
    /// </summary>
    public class OrderService : IOrderService, ITransient
    {
        public static string appId = Config.SenparcWeixinSetting.WeixinAppId;
        public static string appSecret = Config.SenparcWeixinSetting.WeixinAppSecret;

        public static string componentAppid = Config.SenparcWeixinSetting.Component_Appid;
        public static string componentAppSecret = Config.SenparcWeixinSetting.Component_Secret;

        public static string WXURL = Configs.GetString("WXURL");
        private readonly ISqlSugarRepository<YB_Order> repository;
        private readonly SqlSugarClient dbClient;
        private readonly ICapPublisher _capBus;
        public OrderService(ISqlSugarRepository<YB_Order> sqlSugarRepository, ICapPublisher capPublisher)

        {
            repository = sqlSugarRepository;
            dbClient = repository.Context;
            _capBus = capPublisher;
        }

        /// <summary>
        /// 获取可用的订单
        /// </summary>
        /// <param name="equ">设备信息</param>
        /// <param name="userinfo">用户资料</param>
        /// <param name="isdefault">1-获取小程序,2-链接,3-小程序,0-全部</param>
        /// <param name="isbind">是否为绑定处理,true-是</param>
        /// /// <param name="scantype">1-带测量参数的二维码,2-固定贴纸</param>
        /// <returns></returns>
        public async Task<OrderInfo> GetAsync(YB_Device equ, OAuthUserInfo userinfo, int isdefault = 0, bool isbind = false, int scantype = 1)
        {
            try
            {
                //检查设备绑定的订单
                var orderlist = (await dbClient.Ado.UseStoredProcedure().GetDataTableAsync("PROC_GetOrder", new
                {
                    equid = equ.Id,
                    businessid = equ.BusinessId,
                    fansid = userinfo.unionid,
                    isdefault = isdefault,
                    ordertype = isbind ? 3 : 2
                })).ToList<YB_Order>();
                if (orderlist.Count == 0)
                {
                    return null;
                }
                //返回取出的订单,如果订单id为1,则为系统默认关注公众号的订单,如果订单id为2,则为系统默认的打开链接的订单
                var order = orderlist.FirstOrDefault();
                var returndata = new OrderInfo
                {
                    id = order.Id,
                    type = order.Type,
                    isbind = isbind
                };
                var wxfansid = IDGen.NextID();
                //如果是关注公众号
                if (order.Type == (int)OrderType.Office)
                {
                    var office = await dbClient.Queryable<YB_OfficlaAccount>().Where(x => x.authorizer_appid == order.Url && x.type == 1).FirstAsync();
                    if (office == null)
                    {
                        returndata.code = (int)ErrorInfoDesc.wxinfoerror;
                        return returndata;
                    }
                    returndata.appid = office.user_name;
                    //如果是认证的服务号
                    if (office.service_type_info == ServiceType.服务号.ToString()
                        && office.verify_type_info == VerifyType.微信认证.ToString())
                    {
                        //八电极绑定带参二维码格式:yb#1#设备id#粉丝唯一标识
                        var sceneid = $"yb#1#{equ.Id}#{userinfo.unionid}";
                        if (!isbind)
                        {
                            if (await dbClient.Queryable<YB_WXFans>().AnyAsync(x => x.FansId == userinfo.unionid))
                            {
                                wxfansid = await dbClient.Queryable<YB_WXFans>().Where(x => x.FansId == userinfo.unionid).Select(x => x.Id).FirstAsync();
                            }
                            //2-带测量参数的二维码,3-固定贴纸二维码
                            sceneid = scantype == 1 ? $"yb#2#{equ.Id}#{wxfansid}" : $"yb#3#{equ.Id}#{wxfansid}";
                            returndata.WxFansId = wxfansid;
                        }
                        var token = await AuthorizerContainer.TryGetAuthorizerAccessTokenAsync(componentAppid, office.authorizer_appid);
                        var qrresult = await QrCodeApi.CreateAsync(token, 10000, 0, QrCode_ActionName.QR_STR_SCENE, sceneid);
                        if (qrresult.ErrorCodeValue != 0)
                        {
                            returndata.code = (int)ErrorInfoDesc.ercodeerror;
                            return returndata;
                        }
                        returndata.officetype = (int)OfficeType.RZFW;
                        returndata.content = $"https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={qrresult.ticket}";
                    }
                    else if (office.service_type_info == "个人")
                    {
                        //个人回复由第三方插件自动回复
                        returndata.officetype = (int)OfficeType.GR;
                        returndata.content = $"{WXURL}/open/qr/{office.user_name}.jpg";
                    }
                    else
                    {
                        returndata.officetype = (int)OfficeType.FRZ;
                        returndata.vrcode = new Random().Next(100000, 999999).ToString().Substring(1, 4);
                        returndata.content = $"{WXURL}/open/qr/{office.user_name}.jpg";

                    }
                }
                //如果是小程序
                else if (order.Type == (int)OrderType.Mini)
                {
                    var office = await dbClient.Queryable<YB_OfficlaAccount>().Where(x => x.authorizer_appid == order.Url && x.type == 2).FirstAsync();
                    if (office == null)
                    {
                        returndata.code = (int)ErrorInfoDesc.wxinfoerror;
                        return returndata;
                    }
                    returndata.appid = office.user_name;
                    returndata.content = order.Page;
                    returndata.officetype = (int)OfficeType.MINI;

                }
                //如果是链接
                else if (order.Type == (int)OrderType.URL)
                {
                    returndata.content = order.Url;
                }
                else
                {
                    returndata.code = (int)ErrorInfoDesc.develop;
                    return returndata;
                }
                if (isbind)
                {
                    //保存绑定记录
                    await dbClient.Ado.UseStoredProcedure().ExecuteCommandAsync("proc_body_binduser", new
                    {
                        wxfansid = wxfansid,
                        fansid = userinfo.unionid.ToStr(),
                        oldopenid = userinfo.openid,
                        equid = equ.Id,
                        ecode = equ.Ecode,
                        facecode = equ.FacCode,
                        orderid = order.Id,
                        businessid = equ.BusinessId,
                        publicid = returndata.appid,
                        headimgurl = userinfo.headimgurl.ToStr(),
                        nickname = userinfo.nickname.ToStr(),
                        sex = userinfo.sex,
                        city = userinfo.city.ToStr(),
                        province = userinfo.province.ToStr(),
                        country = userinfo.country.ToStr(),
                        language = "",
                        ordertype = order.Type
                    });
                }
                return returndata;
            }
            catch (Exception ex)
            {
                var logger = App.GetService<ILoggerService>();
                //写入异常日志
                var param = $"equ={equ.ToJson()},userinfo={userinfo.ToJson()},isdefault={isdefault},isbind={isbind}";
                logger.AddErrorLogger(ex, param, "获取订单");
                return new OrderInfo
                {
                    code = (int)ErrorInfoDesc.systemerror
                };
            }
        }

        /// <summary>
        /// 获取设备绑定的商户端小程序
        /// </summary>
        /// <param name="equ"></param>
        /// <param name="userinfo"></param>
        /// <returns></returns>
        public async Task<OrderInfo> GetDevMagOrderAsync(YB_Device equ, OAuthUserInfo userinfo)
        {
            //检查设备绑定的订单
            var orderlist = (await dbClient.Ado.UseStoredProcedure().GetDataTableAsync("PROC_GetOrder", new
            {
                equid = equ.Id,
                businessid = equ.BusinessId,
                fansid = userinfo.unionid,
                isdefault = 3,
                ordertype = 1
            })).ToList<YB_Order>();
            if (orderlist.Count == 0)
            {
                return null;
            }
            var order = orderlist.FirstOrDefault();
            var returndata = new OrderInfo
            {
                id = order.Id,
                type = order.Type,
                isbind = false
            };
            var office = await dbClient.Queryable<YB_OfficlaAccount>().Where(x => x.authorizer_appid == order.Url && x.type == 2).FirstAsync();
            if (office == null)
            {
                returndata.code = (int)ErrorInfoDesc.wxinfoerror;
                return returndata;
            }
            returndata.appid = office.user_name;
            returndata.content = order.Page;
            returndata.officetype = (int)OfficeType.MINI;
            returndata.NickName = office.nick_name;
            returndata.HeadImg =  office.head_img.StartsWith("http")?office.head_img:$"{App.Configuration["CDNURL"]}{office.head_img}";
            return returndata;
        }
        /// <summary>
        /// 获取八电极小程序订单
        /// </summary>
        /// <returns></returns>
        public async Task<OrderInfo> GetBodyOrderAsync(YB_Device equ, OAuthUserInfo userinfo)
        {
            var orderlist = (await dbClient.Ado.UseStoredProcedure().GetDataTableAsync("PROC_GetOrder", new
            {
                equid = equ.Id,
                businessid = equ.BusinessId,
                fansid = userinfo.unionid,
                isdefault = 3,
                ordertype = 2,
                scantype = 2
            })).ToList<YB_Order>();
            if (orderlist.Count == 0)
            {
                return null;
            }
            var order = orderlist.FirstOrDefault();
            var returndata = new OrderInfo
            {
                id = order.Id,
                type = order.Type,
                isbind = false
            };
            returndata.WxFansId = (await dbClient.Queryable<YB_WXFans>().FirstAsync(x => x.FansId == userinfo.unionid)).Id;
            var office = await dbClient.Queryable<YB_OfficlaAccount>().Where(x => x.authorizer_appid == order.Url && x.type == 2).FirstAsync();
            if (office == null)
            {
                returndata.code = (int)ErrorInfoDesc.wxinfoerror;
                return returndata;
            }
            returndata.appid = office.user_name;
            returndata.content = order.Page;
            returndata.officetype = (int)OfficeType.MINI;
            returndata.NickName = office.nick_name;
            returndata.HeadImg = office.head_img;
            return returndata;
        }

        /// <summary>
        /// 获取带测量参数的二维码订单
        /// </summary>
        /// <param name="equ">设备信息</param>
        /// <param name="userinfo">用户资料</param>
        /// <param name="ordertype">1-设备管理,2-用户测量,3-用户绑定</param>
        /// <returns></returns>
        public async Task<OrderInfo> GetOrderByTrendAsync(YB_Device equ, OAuthUserInfo userinfo, int ordertype = 2)
        {
            var orderlist = (await dbClient.Ado.UseStoredProcedure().GetDataTableAsync("PROC_GetOrder", new
            {
                equid = equ.Id,
                businessid = equ.BusinessId,
                fansid = userinfo.unionid,
                isdefault = 0,
                ordertype = ordertype,
                scantype = 2
            })).ToList<YB_Order>();
            if (orderlist.Count == 0)
            {
                return null;
            }
            var order = orderlist.FirstOrDefault();
            var returndata = new OrderInfo
            {
                id = order.Id,
                type = order.Type,
                isbind = false
            };
            returndata.WxFansId = (await dbClient.Queryable<YB_WXFans>().FirstAsync(x => x.FansId == userinfo.unionid)).Id;
            //如果是关注公众号
            if (order.Type == (int)OrderType.Office)
            {
                var office = await dbClient.Queryable<YB_OfficlaAccount>().Where(x => x.authorizer_appid == order.Url && x.type == 1).FirstAsync();
                if (office == null)
                {
                    returndata.code = (int)ErrorInfoDesc.wxinfoerror;
                    return returndata;
                }
                returndata.WxFansId = returndata.WxFansId;
                returndata.appid = office.user_name;
                //如果是认证的服务号
                if (office.service_type_info == ServiceType.服务号.ToString()
                    && office.verify_type_info == VerifyType.微信认证.ToString())
                {
                    //测量关注二维码:yb#2#设备id#粉丝ID
                    var sceneid = $"yb#2#{equ.Id}#{returndata.WxFansId}";
                    var token = await AuthorizerContainer.TryGetAuthorizerAccessTokenAsync(componentAppid, office.authorizer_appid);
                    var qrresult = await QrCodeApi.CreateAsync(token, 10000, 0, QrCode_ActionName.QR_STR_SCENE, sceneid);
                    if (qrresult.ErrorCodeValue != 0)
                    {
                        returndata.code = (int)ErrorInfoDesc.ercodeerror;
                        return returndata;
                    }
                    returndata.officetype = (int)OfficeType.RZFW;
                    returndata.content = $"https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={qrresult.ticket}";
                }
                else if (office.service_type_info == "个人")
                {
                    //个人回复由第三方插件自动回复
                    returndata.officetype = (int)OfficeType.GR;
                    returndata.content = $"{WXURL}/open/qr/{office.user_name}.jpg";
                }
                else
                {
                    returndata.officetype = (int)OfficeType.FRZ;
                    returndata.vrcode = new Random().Next(100000, 999999).ToString().Substring(1, 4);
                    returndata.content = $"{WXURL}/open/qr/{office.user_name}.jpg";

                }
            }
            //如果是小程序
            else if (order.Type == (int)OrderType.Mini)
            {
                var office = await dbClient.Queryable<YB_OfficlaAccount>().Where(x => x.authorizer_appid == order.Url && x.type == 2).FirstAsync();
                if (office == null)
                {
                    returndata.code = (int)ErrorInfoDesc.wxinfoerror;
                    return returndata;
                }
                returndata.appid = office.user_name;
                returndata.content = order.Page;
                returndata.NickName = office.nick_name;
                returndata.HeadImg = office.head_img;
                returndata.officetype = (int)OfficeType.MINI;

            }
            //如果是链接
            else if (order.Type == (int)OrderType.URL)
            {
                returndata.content = order.Url;
            }
            else
            {
                returndata.code = (int)ErrorInfoDesc.develop;
                return returndata;
            }
            return returndata;
        }

        /// <summary>
        /// 获取固定贴纸订单
        /// </summary>
        /// <param name="equ">设备信息</param>
        /// <param name="userinfo">用户资料</param>
        /// <param name="ordertype">1-设备管理,2-用户测量,3-用户绑定</param>
        /// <returns></returns>
        public async Task<OrderInfo> GetOrderByStickerAsync(YB_Device equ, OAuthUserInfo userinfo, int ordertype = 2)
        {
            bool isbind = false;
            int isdefault = 0;//1-公众号,2-链接,3-小程序,0-全部
            //如果设备协议符合八电极体重体脂,则查找wifi绑定订单
            if (await dbClient.Queryable<YB_DeviceType>().AnyAsync(x => x.Code == equ.Type && x.ProType == 3))
            {
                isbind = true;
                isdefault = 1;
                ordertype = 3;
            }
            //检查设备绑定的订单
            var orderlist = (await dbClient.Ado.UseStoredProcedure().GetDataTableAsync("PROC_GetOrder", new
            {
                equid = equ.Id,
                businessid = equ.BusinessId,
                fansid = userinfo.unionid,
                isdefault = isdefault,
                ordertype = ordertype,
                scantype = 1
            })).ToList<YB_Order>();
            if (orderlist.Count == 0)
            {
                return null;
            }
            var order = orderlist.FirstOrDefault();
            var returndata = new OrderInfo
            {
                id = order.Id,
                type = order.Type,
                isbind = isbind
            };
            returndata.WxFansId = (await dbClient.Queryable<YB_WXFans>().FirstAsync(x => x.FansId == userinfo.unionid)).Id;
            //如果是关注公众号
            if (order.Type == (int)OrderType.Office)
            {
                var office = await dbClient.Queryable<YB_OfficlaAccount>().Where(x => x.authorizer_appid == order.Url && x.type == 1).FirstAsync();
                if (office == null)
                {
                    returndata.code = (int)ErrorInfoDesc.wxinfoerror;
                    return returndata;
                }
                returndata.appid = office.user_name;
                //如果是认证的服务号
                if (office.service_type_info == ServiceType.服务号.ToString()
                    && office.verify_type_info == VerifyType.微信认证.ToString())
                {
                    //八电极绑定带参二维码格式:yb#1#设备id#粉丝ID
                    var sceneid = $"yb#1#{equ.Id}#{ returndata.WxFansId}";
                    if (!isbind) //针对固定贴纸的关注公众号
                    {
                        sceneid = $"yb#3#{equ.Id}#{ returndata.WxFansId}";
                    }
                    var token = await AuthorizerContainer.TryGetAuthorizerAccessTokenAsync(componentAppid, office.authorizer_appid);
                    var qrresult = await QrCodeApi.CreateAsync(token, 10000, 0, QrCode_ActionName.QR_STR_SCENE, sceneid);
                    if (qrresult.ErrorCodeValue != 0)
                    {
                        returndata.code = (int)ErrorInfoDesc.ercodeerror;
                        return returndata;
                    }
                    returndata.officetype = (int)OfficeType.RZFW;
                    returndata.content = $"https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={qrresult.ticket}";
                }
                else if (office.service_type_info == "个人")
                {
                    //个人回复由第三方插件自动回复
                    returndata.officetype = (int)OfficeType.GR;
                    returndata.content = $"{WXURL}/open/qr/{office.user_name}.jpg";
                }
                else
                {
                    returndata.officetype = (int)OfficeType.FRZ;
                    returndata.vrcode = new Random().Next(100000, 999999).ToString().Substring(1, 4);
                    returndata.content = $"{WXURL}/open/qr/{office.user_name}.jpg";

                }
            }
            //如果是小程序
            else if (order.Type == (int)OrderType.Mini)
            {
                var office = await dbClient.Queryable<YB_OfficlaAccount>().Where(x => x.authorizer_appid == order.Url && x.type == 2).FirstAsync();
                if (office == null)
                {
                    returndata.code = (int)ErrorInfoDesc.wxinfoerror;
                    return returndata;
                }
                returndata.HeadImg = office.head_img;
                returndata.NickName = office.nick_name;
                returndata.appid = office.user_name;
                returndata.content = order.Page;
                returndata.officetype = (int)OfficeType.MINI;

            }
            //如果是链接
            else if (order.Type == (int)OrderType.URL)
            {
                returndata.content = order.Url;
            }
            else
            {
                returndata.code = (int)ErrorInfoDesc.develop;
                return returndata;
            }
            return returndata;
        }
        /// <summary>
        /// 更新八电极推送的消息数据记录
        /// </summary>
        /// <param name="resultid"></param>
        /// <param name="userinfo"></param>
        /// <param name="order"></param>
        /// <returns></returns>
        public async Task UpdateBodyResultAsync(Guid resultid, OAuthUserInfo userinfo, OrderInfo order)
        {
            //如果wxfansid绑定了用户则userid直接赋值
            var account = await dbClient.Queryable<YB_RegUser>().Where(x => x.FansId == order.WxFansId).FirstAsync();
            string fansid = order.WxFansId.ToString();
            int userid = account != null ? account.Id : 0;
            if (await dbClient.Queryable<YB_nUserResult>().AnyAsync(x => x.Id == resultid))
            {
                await dbClient.Updateable<YB_nUserResult>().SetColumns(x => new YB_nUserResult
                {
                    FansId = order.WxFansId,
                    UserId = userid
                }).Where(x => x.Id == resultid).ExecuteCommandAsync();
            }
        }

        /// <summary>
        /// 插入扫码测量记录
        /// </summary>
        /// <param name="equ"></param>
        /// <param name="userinfo"></param>
        /// <param name="height"></param>
        /// <param name="weight"></param>
        /// <param name="type">1-单电阻,2-八电极</param>
        /// <param name="bodyimp"></param>
        /// <param name="leftfootimp"></param>
        /// <param name="rightfootimp"></param>
        /// <param name="lefthandimp"></param>
        /// <param name="righthandimp"></param>
        /// <param name="order"></param>
        /// <returns></returns>
        public async Task InsertResultAsync(YB_Device equ, OAuthUserInfo userinfo, OrderInfo order, decimal height, decimal weight, int type = 1, decimal bodyimp = 0, decimal leftfootimp = 0, decimal rightfootimp = 0, decimal lefthandimp = 0, decimal righthandimp = 0)
        {
            //如果wxfansid绑定了用户则userid直接赋值
            var account = await dbClient.Queryable<YB_RegUser>().Where(x => x.FansId == order.WxFansId).FirstAsync();
            //记录测量记录
            var result = new YB_nResult
            {
                Id = IDGen.NextID(),
                BusinessId = equ.BusinessId,
                CreateTime = DateTime.Now,
                EquId = equ.Id,
                Height = height,
                Imp = bodyimp,
                Weight = weight,
                SourceType = 3,
                DevType = equ.Type,
                LeftArmImp = lefthandimp,
                LeftLegImp = leftfootimp,
                RightArmImp = righthandimp,
                RightLegImp = rightfootimp
            };
            await dbClient.Insertable(result).ExecuteCommandAsync();
            //记录一条分配记录
            var userresult = new YB_nUserResult
            {
                Id = result.Id,
                FamilyId = 0,
                CreateTime = result.CreateTime,
                DevType = equ.Type,
                FansId = order.WxFansId,
                UserId = account != null ? account.Id : 0
            };
            await dbClient.Insertable(userresult).ExecuteCommandAsync();
            //如果是关注公众号,记录扫码结果
            if (order.type == (int)OrderType.Office)
            {
                //记录扫码
                var scanresult = new YB_ScanResult
                {
                    BusinessId = equ.BusinessId,
                    Subscribe = 0,
                    CreateTime = DateTime.Now,
                    EquId = equ.Id,
                    FansId = order.WxFansId.ToString(),
                    Id = result.Id,
                    OrderId = order.id,
                    PublicId = order.appid,
                    TakeTime  =null,
                    Type = equ.Type
                };
                await dbClient.Insertable(scanresult).ExecuteCommandAsync();
                //如果是非认证号,记录健康码
                if (order.officetype == 2)
                {
                    var vrcodedata = new YB_WXMessage
                    {
                        CreateTime = DateTime.Now,
                        EnCode = order.vrcode,
                        Id = IDGen.NextID(),
                        PublicId = order.appid,
                        ResultId = result.Id.ToString(),
                        Type = 1
                    };
                    await dbClient.Insertable(vrcodedata).ExecuteCommandAsync();
                }
            }
            await _capBus.PublishAsync("result.service.updaterealdata", new UpdateRealDataS2SDtO
            {
                IsUserTake = false,
                DevId = equ.Id
            });
            //更新订单展现次数
            await dbClient.Updateable<YB_Order>().SetColumns(x => new YB_Order
            {
                ShowCount = x.ShowCount + 1,
                DayCount = x.DayCount + 1
            }).Where(x => x.Id == order.id).ExecuteCommandAsync();
        }
        /// <summary>
        /// 插入固定二维码扫码记录
        /// </summary>
        /// <param name="equ"></param>
        /// <param name="userinfo"></param>
        /// <param name="order"></param>
        /// <returns></returns>
        public async Task InsertResultAsync(YB_Device equ, OAuthUserInfo userinfo, OrderInfo order)
        {
            //更新订单展现次数
            await dbClient.Updateable<YB_Order>().SetColumns(x => new YB_Order
            {
                ShowCount = x.ShowCount + 1,
                DayCount = x.DayCount + 1
            }).Where(x => x.Id == order.id).ExecuteCommandAsync();

            //如果是关注公众号,记录扫码结果
            if (order.type == (int)OrderType.Office && !order.isbind)
            {
                var scandata = new YB_ScanResult
                {
                    Id = IDGen.NextID(),
                    Subscribe = 0,
                    BusinessId = equ.BusinessId,
                    CreateTime = DateTime.Now,
                    EquId = equ.Id,
                    FansId = order.WxFansId.ToString(),
                    OrderId = order.id,
                    PublicId = order.appid,
                    TakeTime = null,
                    Type = 1
                };
                await dbClient.Insertable(scandata).ExecuteCommandAsync();
                //如果是非认证号,记录健康码
                if (order.officetype == 2)
                {
                    var vrcodedata = new YB_WXMessage
                    {
                        CreateTime = DateTime.Now,
                        EnCode = order.vrcode,
                        Id = IDGen.NextID(),
                        PublicId = order.appid,
                        ResultId = scandata.Id.ToString(),
                        Type = 2
                    };
                    await dbClient.Insertable(vrcodedata).ExecuteCommandAsync();
                }
            }
        }
        /// <summary>
        /// 处理固定贴纸图文链接
        /// </summary>
        /// <param name="appid"></param>
        /// <param name="openid"></param>
        /// <param name="type"></param>
        /// <param name="fansid"></param>
        /// <param name="resultid"></param>
        /// <returns></returns>
        public async Task<OrderInfo> HandlerStickySubscribeAsync(string appid, string openid, int type, string fansid, Guid? resultid)
        {
            //获取记录
            var result = await dbClient.Queryable<YB_ScanResult>().FirstAsync(x => x.Id == resultid.Value);
            //更新关注记录
            if (result != null)
            {
                //如果未计费则进行计费
                if (result.Subscribe == 0)
                {
                    //更新记录
                    await dbClient.Updateable<YB_ScanResult>().SetColumns(x => new YB_ScanResult
                    {
                        Subscribe = 1,
                        TakeTime = DateTime.Now
                    }).Where(x => x.Id == result.Id).ExecuteCommandAsync();

                    //更新订单
                    await dbClient.Updateable<YB_Order>().SetColumns(x => new YB_Order
                    {
                        RealCount = x.RealCount + 1,
                        DayRealCount = x.DayRealCount + 1
                    }).Where(x => x.Id == result.OrderId).ExecuteCommandAsync();

                    //更新设备数据
                    await dbClient.Updateable<YB_EquRealData>().SetColumns(x => new YB_EquRealData
                    {
                        TodayRealCnt = x.TodayRealCnt + 1,
                        TotalRealCnt = x.TotalRealCnt + 1
                    }).Where(x => x.Id == result.EquId).ExecuteCommandAsync();

                    //更新商户数据
                    await dbClient.Updateable<YB_BusinessRealData>().SetColumns(x => new YB_BusinessRealData
                    {
                        TodayRealCnt = x.TodayRealCnt + 1,
                        TotalRealCnt = x.TotalRealCnt + 1
                    }).Where(x => x.BusinessId == result.BusinessId).ExecuteCommandAsync();
                }
                //查询此设备关联的小程序订单
                var orderlist = (await dbClient.Ado.UseStoredProcedure().GetDataTableAsync("PROC_GetOrder", new
                {
                    equid = result.EquId,
                    businessid = result.BusinessId,
                    fansid = fansid,
                    isdefault = 3,
                    ordertype = 2,
                    scantype = 1
                })).ToList<YB_Order>();
                if (orderlist.Count == 0)
                {
                    return null;
                }
                var order = orderlist.FirstOrDefault();
                var returndata = new OrderInfo
                {
                    id = order.Id,
                    type = order.Type,
                    isbind = false
                };
                var office = await dbClient.Queryable<YB_OfficlaAccount>().Where(x => x.authorizer_appid == order.Url && x.type == 2).FirstAsync();
                if (office == null)
                {
                    returndata.code = (int)ErrorInfoDesc.wxinfoerror;
                    return returndata;
                }
                returndata.HeadImg = office.head_img;
                returndata.NickName = office.nick_name;
                returndata.appid = office.user_name;
                returndata.content = order.Page.Contains("?") ? $"{order.Page}&fid={fansid}" : $"{order.Page}?fid={fansid}";
                returndata.officetype = (int)OfficeType.MINI;
                return returndata;
            }
            return null;
        }
        /// <summary>
        /// 处理带参数二维码图文链接
        /// </summary>
        /// <param name="appid"></param>
        /// <param name="openid"></param>
        /// <param name="type"></param>
        /// <param name="fansid"></param>
        /// <param name="resultid"></param>
        public async Task<OrderInfo> HandlerResultSubscribeAsync(string appid, string openid, int type, string fansid, Guid? resultid)
        {
            //获取记录
            var result = await dbClient.Queryable<YB_ScanResult>().FirstAsync(x => x.Id == resultid);
            if (result == null)
            {
                return null;
            }
            //更新关注记录
            //如果未计费则进行计费
            if (result.Subscribe == 0)
            {
                Guid wxfansid = Guid.Parse(fansid);
                if (await dbClient.Queryable<YB_WXFansExt>().AnyAsync(x => x.AppId == appid && x.OpenId == openid))
                {
                    await dbClient.Updateable<YB_WXFansExt>().SetColumns(x => new YB_WXFansExt
                    {
                        Subscribe = 1,
                        SubscribeTime = DateTime.Now,
                        ResultId = wxfansid
                    }).Where(x => x.AppId == appid && x.OpenId == openid).ExecuteCommandAsync();
                }
                else
                {
                    await dbClient.Insertable(new YB_WXFansExt
                    {
                        AppId = appid,
                        Subscribe = 1,
                        SubscribeTime = DateTime.Now,
                        OpenId = openid,
                        ResultId = wxfansid
                    }).ExecuteCommandAsync();
                }
                //更新订单
                await dbClient.Updateable<YB_Order>().SetColumns(x => new YB_Order
                {
                    RealCount = x.RealCount + 1,
                    DayRealCount = x.DayRealCount + 1
                }).Where(x => x.Id == result.OrderId).ExecuteCommandAsync();

                //更新设备数据
                await dbClient.Updateable<YB_EquRealData>().SetColumns(x => new YB_EquRealData
                {
                    TodayRealCnt = x.TodayRealCnt + 1,
                    TotalRealCnt = x.TotalRealCnt + 1
                }).Where(x => x.Id == result.EquId).ExecuteCommandAsync();

                //更新商户数据
                await dbClient.Updateable<YB_BusinessRealData>().SetColumns(x => new YB_BusinessRealData
                {
                    TodayRealCnt = x.TodayRealCnt + 1,
                    TotalRealCnt = x.TotalRealCnt + 1
                }).Where(x => x.BusinessId == result.BusinessId).ExecuteCommandAsync();
            }
            //查询此设备关联的小程序订单
            var orderlist = (await dbClient.Ado.UseStoredProcedure().GetDataTableAsync("PROC_GetOrder", new
            {
                equid = result.EquId,
                businessid = result.BusinessId,
                fansid = fansid,
                isdefault = 3,
                ordertype = 2,
                scantype = 2
            })).ToList<YB_Order>();
            if (orderlist.Count == 0)
            {
                return null;
            }
            var order = orderlist.FirstOrDefault();
            var returndata = new OrderInfo
            {
                id = order.Id,
                type = order.Type,
                isbind = false
            };
            var office = await dbClient.Queryable<YB_OfficlaAccount>().Where(x => x.authorizer_appid == order.Url && x.type == 2).FirstAsync();
            if (office == null)
            {
                returndata.code = (int)ErrorInfoDesc.wxinfoerror;
                return returndata;
            }
            returndata.HeadImg = office.head_img;
            returndata.NickName = office.nick_name;
            returndata.appid = office.user_name;
            returndata.content = order.Page.Contains("?") ? $"{order.Page}&fid={fansid}" : $"{order.Page}?fid={fansid}";
            returndata.officetype = (int)OfficeType.MINI;
            return returndata;
        }

        /// <summary>
        /// 用户事件处理
        /// </summary>
        /// <param name="appid"></param>
        /// <param name="openid"></param>
        /// <param name="type">1-认证的服务号关注事件,2-认证的服务号扫码事件,3-非认证关注事件,4-回复关键字,5-第一次打开落地页,6-非认证扫码事件</param>
        /// <param name="encode">健康码</param>
        /// <param name="equid">设备id</param>
        /// <param name="fansid"></param>
        /// <param name="scantype">1-带测量参数的二维码,2-固定二维码</param>
        /// <returns></returns>
        public async Task<int> SubscribeAsync(string appid, string openid, int type, string encode = "", string equid = "", string fansid = "", int scantype = 1)
        {
            //如果是固定二维码
            var table = await dbClient.Ado.UseStoredProcedure().GetDataTableAsync("proc_updateresult", new
            {
                encode = encode,
                appid = appid,
                equid = equid,
                fansid = fansid,
                openid = openid,
                type = type,
                scantype = scantype
            });
            int devicetype = 1;
            //获取要展示的小程序名称
            if (table.Rows.Count > 0)
            {
                var equlist = DataTableListHelper.ToList<YB_Device>(table);
                if (equlist != null && equlist.Count > 0)
                {
                    var equ = equlist.FirstOrDefault();
                    devicetype = equ.Type;
                }
            }
            return devicetype;
        }

        /// <summary>
        /// 设备状态描述
        /// </summary>
        /// <param name="status">设备状态</param>
        /// <returns></returns>
        private string EquStatusMsg(int status)
            => (status) switch
            {
                _ when status == (int)DeviceStatus.Stop => "设备已停止运行",
                _ when status == (int)DeviceStatus.UnActive => "设备还未激活",
                _ => "正常运行"
            };
    }
}
