using ASHermed.SinoInterface.Api.ContractModel.App;
using ASHermed.SinoInterface.Api.ContractModel.App.Model;
using ASHermed.SinoInterface.Api.ContractModel.Coupon.Model;
using ASHermed.SinoInterface.Api.IRepository;
using ASHermed.SinoInterface.Api.IRepository.App;
using ASHermed.SinoInterface.Api.IService;
using ASHermed.SinoInterface.ContractModel;
using ASHermed.SinoInterface.Enum.App;
using ASHermed.SinoInterface.IFramework;
using ASHermed.SinoInterface.Tools;
using PoJun.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using ASHermed.SinoInterface.Api.ContractModel.Coupon.Entity;
using ASHermed.SinoInterface.Api.ContractModel;
using System.IO;
using ASHermed.SinoInterface.Tools.Base;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
using ASHermed.SinoInterface.Api.ContractModel.Tencent;
using Microsoft.Extensions.Logging;
using ASHermed.SinoInterface.Api.IService.App;
using ASHermed.SinoInterface.Api.ContractModel.App.RequestForm;
using Microsoft.Extensions.Configuration;
using CustomerInfo = ASHermed.SinoInterface.Api.ContractModel.CustomerInfo;
using ASHermed.SinoInterface.Api.IRepository.Quest;
using ASHermed.SinoInterface.Api.ContractModel.TCTrans;
using System.Collections.Concurrent;
using ASHermed.SinoInterface.Api.ContractModel.App.Entity;
using ASHermed.SinoInterface.Api.ContractModel.SMTP;
using ASHermed.SinoInterface.Api.ContractModel.TCTrans.Input;
using ASHermed.SinoInterface.Api.ContractModel.TCTrans.Output;
using ASHermed.SinoInterface.IFramework.SMTP;
using PatientModel = ASHermed.SinoInterface.Api.ContractModel.App.Model.PatientModel;
using System.Globalization;

namespace ASHermed.SinoInterface.Api.Service
{
    /// <summary>
	/// 用户信息
	/// </summary>
	public class UserService : BaseService, IUserService
    {
        #region 初始化

        /// <summary>
        /// 用户登录服务
        /// </summary>
             //md5 linkingappid 32位小写
        private readonly string LinKingAppid = "6d1c492dd84b49d5a2ee95774bbfd978";
        //md5 linkingsecret 32位小写
        private readonly string LinKingSecret = "9264259f9b6dc3819d14811824982dde";
        private IVerifyCodeLogService _verifyCodeLogService;
        private IPatService _patService;
        private IPubUserInfoService _pubUserInfoService;
        private IPubUserInfoRepository _pubUserInfoRepository;
        private IIntegralFlowService _integralFlowService;
        private IPubMapUserPatRepository _pubMapUserPatRepository;
        private AppConfigurtaion _appConfigurtaion;
        private IDicCouponRepository _dicCouponRepository;
        private IPubCouponFlowService _pubCouponFlowService;
        private ITencentService _tencentService;
        private IPubMapUserTypeService _pubMapUserTypeService;
        private ITCService _tcService;
        private RedisHelperClient _redisHelper;
        private IPubUserAddressRepository _pubUserAddressRepository;
        private IOutArticleCollectRepository _outArticleCollectRepository;
        private IJpushService _jpushService;
        private ITokenService _tokenService;
        private ILinKingService _linKingService;
        private IPubPatInfoRepository _pubPatRepository;
        private IJWTService _jWTService;
        private IOnlineCouponPubUserRepository _onlineCouponPubUserRepository;
        private IOnlineCouponRepository _onlineCouponRepository;
        private HttpClient _httpClient;
        private ICouponService _couponService;
        private IDicDoctorRepository _dicDoctorRepository;
        private IHealthClubRepository _healthClubRepository;
        private IOutMapDocPatRepository _outMapDocPatRepository;
        private IOutMapPatTagService _outMapPatTagService;
        private IPubMapPatuserDocuserRepository _pubMapPatuserDocuserRepository;
        private ICnBaseDistrictRepository _cnBaseDistrictRepository;
        private ILogger<UserService> _logger;
        private IFileService _fileService;
        private IFileRepository _fileRepository;
        private readonly IYouZanService _youZanService;
        private readonly IConfiguration _configuration;
        private IPubQuestDataRepository _pubQuestDataRepository;
        private IOutAptInfoRepository _outAptInfoRepository;
        private readonly IEmailService _emailService;
        private readonly IPubPatTcAbnormalRepository _pubPatTcAbnormalRepository;
        private readonly IHttpClientFactory _httpClientFactory;
        private readonly IAuthorizationService _authorizationService;
        private readonly IPubAuthorizationRepository _pubAuthorizationRepository;

        public UserService(IVerifyCodeLogService verifyCodeLogService, IPubUserInfoService pubUserInfoService, IPubUserInfoRepository pubUserInfoRepository, IPatService patService, IIntegralFlowService integralFlowService, IPubMapUserPatRepository pubMapUserPatRepository, AppConfigurtaion appConfigurtaion, IDicCouponRepository dicCouponRepository, IPubCouponFlowService pubCouponFlowService, ITencentService tencentService, IPubMapUserTypeService pubMapUserTypeService, ITCService arPatService, RedisHelperClient redisHelper, IPubUserAddressRepository pubUserAddressRepository, IOutArticleCollectRepository outArticleCollectRepository, IJpushService jpushService, ITokenService tokenService, ILinKingService linKingService, IPubPatInfoRepository pubPatRepository, IJWTService jWTService, IOnlineCouponPubUserRepository onlineCouponPubUserRepository, IOnlineCouponRepository onlineCouponRepository, IHttpClientFactory httpClientFactory, ICouponService couponService, IDicDoctorRepository dicDoctorRepository, IHealthClubRepository healthClubRepository, IOutMapDocPatRepository outMapDocPatRepository, IOutMapPatTagRepository outMapPatTagRepository, IPubMapPatuserDocuserRepository pubMapPatuserDocuserRepository, ICnBaseDistrictRepository cnBaseDistrictRepository, ILogger<UserService> logger, IFileService fileService, IFileRepository fileRepository, IYouZanService youZanService, IOutMapPatTagService outMapPatTagService, IConfiguration configuration, IPubQuestDataRepository pubQuestDataRepository, IOutAptInfoRepository outAptInfoRepository, IEmailService emailService, IPubPatTcAbnormalRepository pubPatTcAbnormalRepository, IAuthorizationService authorizationService, IPubAuthorizationRepository pubAuthorizationRepository)
        {
            _pubUserInfoService = pubUserInfoService;
            _verifyCodeLogService = verifyCodeLogService;
            _pubUserInfoRepository = pubUserInfoRepository;
            _patService = patService;
            _integralFlowService = integralFlowService;
            _pubMapUserPatRepository = pubMapUserPatRepository;
            _appConfigurtaion = appConfigurtaion;
            _dicCouponRepository = dicCouponRepository;
            _pubCouponFlowService = pubCouponFlowService;
            _tencentService = tencentService;
            _pubMapUserTypeService = pubMapUserTypeService;
            _tcService = arPatService;
            _redisHelper = redisHelper;
            _pubUserAddressRepository = pubUserAddressRepository;
            _outArticleCollectRepository = outArticleCollectRepository;
            _jpushService = jpushService;
            _tokenService = tokenService;
            _linKingService = linKingService;
            _pubPatRepository = pubPatRepository;
            _jWTService = jWTService;
            _onlineCouponPubUserRepository = onlineCouponPubUserRepository;
            _onlineCouponRepository = onlineCouponRepository;
            _httpClient = httpClientFactory.CreateClient(HttpClientConst.AdminBase_CLIENT_NAME);
            _couponService = couponService;
            _dicDoctorRepository = dicDoctorRepository;
            _healthClubRepository = healthClubRepository;
            _outMapDocPatRepository = outMapDocPatRepository;
            _outMapPatTagService = outMapPatTagService;
            _pubMapPatuserDocuserRepository = pubMapPatuserDocuserRepository;
            _cnBaseDistrictRepository = cnBaseDistrictRepository;
            _logger = logger;
            _fileService = fileService;
            _fileRepository = fileRepository;
            _youZanService = youZanService;
            _configuration = configuration;
            _pubQuestDataRepository = pubQuestDataRepository;
            _outAptInfoRepository = outAptInfoRepository;
            _emailService = emailService;
            _pubPatTcAbnormalRepository = pubPatTcAbnormalRepository;
            _httpClientFactory = httpClientFactory;
            _authorizationService = authorizationService;
            _pubAuthorizationRepository = pubAuthorizationRepository;
        }

        #endregion

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="account"></param>
        /// <param name="code"></param>
        /// <param name="identifier"></param>
        /// <param name="openId"></param>
        /// <param name="access_token"></param>
        /// <param name="language"></param>
        /// <returns></returns>
        public BaseResponse<UserToken> Login(string account, string code, string identifier, string openId, string access_token, int language, int source)
        {
            BaseResponse<UserToken> baseRes = new BaseResponse<UserToken>();

            var log = _verifyCodeLogService.CheckCode(account, code);
            if (log > 0)
            {
                Pub_User_Info userInfo = _pubUserInfoService.SelectByIdentifier(identifier);
                if (userInfo != null)
                {
                    userInfo.Identifier = null;
                    _pubUserInfoRepository.UpdatePubUserInfo(userInfo);
                }
                //查询账号是否存在
                UserDetail pubUserInfo = GetUserByAcc(account);
                if (pubUserInfo == null)
                {
                    pubUserInfo = new UserDetail();
                    //不存在，注册
                    //判断用户是邮箱注册还是手机注册
                    if (account.IsPhoneNumber())
                    {
                        //手机注册
                        pubUserInfo.Phone = account;
                    }
                    else
                    {
                        //邮箱注册
                        pubUserInfo.Email = account;
                    }
                    //注册
                    pubUserInfo.IsReg = false;
                    pubUserInfo.RegistrationSource = source;// RegistrationSource.APPPAT;
                    pubUserInfo.IsDeleted = false;
                    pubUserInfo.CreateTime = DateTime.Now;
                    pubUserInfo.IsNew = false;
                    #region 微信注册时获取微信用户信息
                    //微信注册时获取微信用户信息
                    //if (!string.IsNullOrEmpty(access_token) && !string.IsNullOrEmpty(openId))
                    //{
                    //    //授权获取wx用户信息
                    //    Object wxUserInfo = GetWxInfo(openId, access_token);
                    //    //绑定微信
                    //    PubUserInfo openIdUser = pubUserInfoMapper.selectByAppOpenId(openId);
                    //    if (wxUserInfo != null && openIdUser == null)
                    //    {
                    //        Map<String, Object> map = (Map<String, Object>)wxUserInfo;
                    //        if (openId != null && !StringUtils.isNullOrEmpty(openId))
                    //        {
                    //            //微信注册时将昵称、头像修改
                    //            pubUserInfo.setAppOpenid(openId);
                    //            pubUserInfo.setNickName(String.valueOf(map.get("nickName")));
                    //            pubUserInfo.setHeadimg(String.valueOf(map.get("headImg")));
                    //            String sex = String.valueOf(map.get("sex"));
                    //            pubUserInfo.setGender(sex != null && sex.equals("1") ? 1 : 0);
                    //        }
                    //    }
                    //    else
                    //    {
                    //        return RequestResult.failure("该微信已被绑定！");
                    //    }
                    //}
                    #endregion
                    //第一次注册添加设备识别号
                    pubUserInfo.Identifier = identifier;
                    var id = _pubUserInfoRepository.InsertPubUserInfo(TransEntity(pubUserInfo));
                    pubUserInfo.Id = id;
                }
                //将识别号加入
                pubUserInfo.Identifier = identifier;
                //绑定微信
                if (!string.IsNullOrEmpty(openId))
                {
                    Pub_User_Info openIdUser = _pubUserInfoService.SelectByAppOpenId(openId);
                    if (openIdUser == null && string.IsNullOrEmpty(openIdUser.APP_Open_ID))
                    {
                        pubUserInfo.APPOpenId = openId;
                    }
                    else
                    {
                        Pub_User_Info openIdWithPhoneUser = _pubUserInfoService.SelectByAppOpenIdWithPhone(openId, account);
                        if (openIdWithPhoneUser == null)
                        {
                            baseRes.Msg = "该微信已绑定用户";
                            return baseRes;
                        }
                    }
                }
                _pubUserInfoRepository.UpdatePubUserInfo(TransEntity(pubUserInfo));

                var isToken = _redisHelper.KeyExistsAsync("user_" + pubUserInfo.Id);
                if (isToken.Result)
                {
                    _redisHelper.DeleteAsync("user_" + pubUserInfo.Id);
                }
                string token = GetToken("user_" + pubUserInfo.Id);
                UserToken userToken = new UserToken();
                userToken.UserInfo = pubUserInfo;
                userToken.Token = token;
                baseRes.Msg = "成功";
                baseRes.Code = 1;
                baseRes.Data = userToken;
            }
            else
            {
                return new BaseResponse<UserToken>() { Msg = language == 1 ? "未找到验证码" : "Invalid Verification Code" };
            }
            return baseRes;
        }

        public BaseResponse<UserToken> SourceLogin(string account, string code, int language, int source = 0)
        {
            BaseResponse<UserToken> baseRes = new BaseResponse<UserToken>();

            var log = _verifyCodeLogService.CheckCode(account, code);
            //var log = 1;
            if (log > 0)
            {
                //有赞
                if (source == 0)
                {
                    var pubUserInfo = TransModel(_pubUserInfoService.SelectByPhone(account));
                    if (pubUserInfo == null)
                    {
                        pubUserInfo = new UserDetail();
                        pubUserInfo.Phone = account;
                        pubUserInfo.IsReg = false;
                        pubUserInfo.RegistrationSource = 5;// 有赞来源;
                        pubUserInfo.IsDeleted = false;
                        pubUserInfo.CreateTime = DateTime.Now;
                        pubUserInfo.IsNew = false;
                        var id = _pubUserInfoRepository.InsertPubUserInfo(TransEntity(pubUserInfo));
                        pubUserInfo.Id = id;
                    }
                    var isToken = _redisHelper.KeyExistsAsync("user_" + pubUserInfo.Id);
                    if (isToken.Result)
                    {
                        _redisHelper.DeleteAsync("user_" + pubUserInfo.Id);
                    }
                    string token = GetToken("user_" + pubUserInfo.Id);
                    UserToken userToken = new UserToken();
                    userToken.UserInfo = pubUserInfo;
                    userToken.Token = token;
                    baseRes.Msg = "成功";
                    baseRes.Code = 1;
                    baseRes.Data = userToken;
                }
            }
            else
            {
                return new BaseResponse<UserToken>() { Msg = language == 1 ? "未找到验证码" : "Invalid Verification Code" };
            }
            return baseRes;
        }


        public string GetToken(string userId)
        {
            if (string.IsNullOrEmpty(userId))
            {
                return null;
            }
            string tokenStr = _jWTService.JavaSign(userId);
            _redisHelper.Set(userId, tokenStr, TimeSpan.FromSeconds(7 * 24 * 60 * 60));// 
            return tokenStr;
        }

        public UserDetail GetUserByAcc(string acc)
        {
            Pub_User_Info pubUserInfo = _pubUserInfoService.SelectByPhone(acc);
            if (pubUserInfo == null)
            {
                pubUserInfo = _pubUserInfoService.SelectByEmail(acc);
                if (null == pubUserInfo)
                {
                    return null;
                }
            }

            UserDetail user = TransModel(pubUserInfo);

            Pub_Map_User_Type userType = _pubUserInfoService.SelectUserTypeByPhone(pubUserInfo.Phone);
            if (userType != null)
            {
                user.userType = userType.User_Type;
            }
            return user;
        }

        private UserDetail TransModel(Pub_User_Info pubUserInfo)
        {
            if (pubUserInfo == null)
            {
                return null;
            }
            UserDetail user = new UserDetail();
            user.Id = pubUserInfo.ID;
            user.Identifier = pubUserInfo.Identifier;
            user.AndroidId = pubUserInfo.Android_ID;
            user.APPOpenId = pubUserInfo.APP_Open_ID;
            user.IMId = pubUserInfo.IM_ID;

            user.IOSId = pubUserInfo.IOS_ID;
            user.IsDeleted = pubUserInfo.Is_Deleted;
            user.APPLanguage = pubUserInfo.APP_Language;
            user.Birthday = pubUserInfo.Birthday;
            user.City = pubUserInfo.City;

            user.Country = pubUserInfo.Country;
            user.CreateTime = pubUserInfo.Create_Time;
            user.Email = pubUserInfo.Email;
            user.FirstName = pubUserInfo.First_Name;
            user.Gender = pubUserInfo.Gender;

            user.HeadImg = pubUserInfo.HeadImg;
            user.IsReg = pubUserInfo.Is_Reg;
            user.IsNew = pubUserInfo.Is_New;
            user.LastName = pubUserInfo.Last_Name;
            user.NickName = pubUserInfo.Nick_Name;

            user.Phone = pubUserInfo.Phone;
            user.KeyType = pubUserInfo.Key_Type;
            user.OpenId = pubUserInfo.Open_ID;
            user.Province = pubUserInfo.Province;
            user.RegistrationSource = pubUserInfo.Registration_Source;

            user.TreatmentPassword = pubUserInfo.Treatment_Password;
            user.UpdateTime = pubUserInfo.Update_Time;
            user.Language = pubUserInfo.Language;
            user.IsReadInformed = pubUserInfo.Is_Read_Informed;
            return user;
        }
        private Pub_User_Info TransEntity(UserDetail detail)
        {
            Pub_User_Info user = new Pub_User_Info();
            user.ID = detail.Id;
            user.Identifier = detail.Identifier;
            user.Android_ID = detail.AndroidId;
            user.APP_Open_ID = detail.APPOpenId;
            user.IM_ID = detail.IMId;

            user.IOS_ID = detail.IOSId;
            user.Is_Deleted = detail.IsDeleted;
            user.APP_Language = detail.APPLanguage;
            user.Birthday = detail.Birthday;
            user.City = detail.City;

            user.Country = detail.Country;
            user.Create_Time = detail.CreateTime;
            user.Email = detail.Email;
            user.First_Name = detail.FirstName;
            user.Gender = detail.Gender;

            user.HeadImg = detail.HeadImg;
            user.Is_Reg = detail.IsReg;
            user.Is_New = detail.IsNew;
            user.Last_Name = detail.LastName;
            user.Nick_Name = detail.NickName;

            user.Phone = detail.Phone;
            user.Key_Type = detail.KeyType;
            user.Open_ID = detail.OpenId;
            user.Province = detail.Province;
            user.Registration_Source = detail.RegistrationSource;

            user.Treatment_Password = detail.TreatmentPassword;
            user.Update_Time = detail.UpdateTime;
            user.Language = detail.Language;
            user.Is_Read_Informed = detail.IsReadInformed;
            return user;
        }
        /// <summary>
        /// 用户完善信息
        /// </summary>
        /// <param name="que"></param>
        /// <returns></returns>
        public BaseResponse UpdateUserInfo(UserInfoQuery que)
        {
            BaseResponse res = new BaseResponse();
            bool isCoupon = false;   //用户是否领券
            var userid = que.UserId > 0 ? que.UserId : GetBaseUserInfo().ID;

            que.UserId = userid;
            //判断用户是否存在
            Pub_User_Info pubUserInfo = _pubUserInfoRepository.initLinq().Where(a => a.ID == que.UserId).Single();
            //用户不存在
            if (pubUserInfo == null)
            {
                res.Code = 0;
                res.Msg = "失败";
                return res;
            }
            #region 多对多逻辑修改
            ////判断用户是否已经完善过信息
            //if (!pubUserInfo.Is_Reg)
            //{

            //    //判断用户在his中是否存在
            //    List<Pub_Pat_Info> patList = _patService.GetHisPat(null, que.Phone, que.Birthday);
            //    if (patList != null && patList.Count > 0)
            //    {
            //        //存在，老用户
            //        pubUserInfo.Is_New = false;
            //        //积分流水表
            //        _integralFlowService.PerfectIntegral(pubUserInfo.Phone);
            //        if (patList.Count > 1)
            //        {
            //            foreach (var item in patList)
            //            {
            //                _patService.SaveHisPat(item);
            //            }
            //            //存在多条数据返回多条数据
            //            res.Code = 1;
            //            res.Msg = "成功";
            //            //res.Data = null;
            //            return res;
            //        }
            //        else
            //        {
            //            //只有一条数据，绑定病人并完善数据
            //            _patService.SaveHisPat(patList[0]);
            //            Bind(pubUserInfo.ID, patList[0].Id);
            //        }
            //    }
            //    else
            //    {
            //        //不存在则为新人用户
            //        pubUserInfo.Is_New = true;
            //        //添加一条临时就诊人
            //        Pub_Pat_Info patInfo = new Pub_Pat_Info();
            //        patInfo.Pat_Source = 0;
            //        patInfo.Pat_Name = que.LastName + que.FirstName;
            //        patInfo.Last_Name = que.LastName;
            //        patInfo.First_Name = que.FirstName;
            //        patInfo.Gender = que.Sex;
            //        patInfo.Birthday = que.Birthday;
            //        patInfo.Phone_NO = (pubUserInfo.Phone);
            //        _patService.Add(patInfo, 4, que.Language);
            //    }

            //}
            #endregion
            //判断是否第一次登陆APP
            if (pubUserInfo.Is_New_Login_App == false)
            {
                if (_appConfigurtaion.GetNewCouponsOn == "true")
                {
                    //查询新人券
                    List<Dic_Coupon> couponList = _dicCouponRepository.SelectInId(_appConfigurtaion.GetNewCouponsId);
                    if (couponList != null && couponList.Count > 0)
                    {
                        foreach (var item in couponList)
                        {
                            Pub_Coupon_Flow pubCouponFlow = new Pub_Coupon_Flow();
                            pubCouponFlow.Receiptor_Phone = pubUserInfo.Phone;
                            pubCouponFlow.Coupon_Id = item.Id;
                            pubCouponFlow.Redeem_Code = Common.CreateCode(_appConfigurtaion.GetCodeLen.ToInt());
                            _pubCouponFlowService.AddCouponFlow(pubCouponFlow, item, null);
                        }
                    }
                }
                pubUserInfo.Is_New_Login_App = true;
            }

            //完善信息
            pubUserInfo.Last_Name = que.LastName;
            pubUserInfo.First_Name = que.FirstName;
            pubUserInfo.Nick_Name = que.Language == 2 ? que.FirstName + " " + que.LastName : que.LastName + que.FirstName;
            pubUserInfo.Birthday = que.Birthday;
            pubUserInfo.Gender = que.Sex;
            pubUserInfo.Is_Reg = true;

            if (!string.IsNullOrEmpty(que.HeadImg) && que.HeadImg.IsUrl())
            {
                pubUserInfo.HeadImg = que.HeadImg;
            }

            // 是否更换手机
            if (!string.IsNullOrEmpty(pubUserInfo.Phone) && pubUserInfo.Phone != que.Phone)
            {
                res.Code = 0;
                res.Msg = "操作失败：手机号不能修改";
                return res;
            }
            else
            {
                pubUserInfo.Phone = que.Phone;
            }
            // 是否更换邮箱
            if (!string.IsNullOrEmpty(pubUserInfo.Email) && pubUserInfo.Email != que.Email)
            {
                res.Code = 0;
                res.Msg = "操作失败：邮箱不能修改";
                return res;
            }
            else
            {
                pubUserInfo.Email = que.Email;
            }

            //修改用户信息
            int result = _pubUserInfoRepository.UpdatePubUserInfo(pubUserInfo);
            _tencentService.GetUsersigByPat(pubUserInfo.ID);
            _pubMapUserTypeService.SetUserType(pubUserInfo.Phone, 1);
            //普通用户1
            //判断是否为健康俱乐部会员
            //1.查询是否为健康俱乐部会员
            OutHealthClub healthClub = _healthClubRepository.SelectByPhone(pubUserInfo.Phone);
            if (healthClub != null)
            {
                AddHealthClubMap(healthClub.Phone, healthClub.TagId);
            }

            if (result >= 1)
            {
                res.Code = 1;
                res.Msg = "成功";
                return res;
            }
            res.Code = 0;
            res.Msg = "失败";
            return res;
        }

        public void AddHealthClubMap(string phone, string tagIdList)
        {
            Pub_User_Info pubUserInfo = _pubUserInfoRepository.SelectByPhone(phone);
            if (pubUserInfo != null)
            {
                //添加好友
                //1.查找医生端账号
                //Pub_Doctor_User_Info doctorUserInfo = _dicDoctorRepository.SelectDocListByHealthClub();
                var doctorUserInfo = _dicDoctorRepository.GetSysUserByHealthClub();
                if (doctorUserInfo != null)
                {
                    // 2.将好友添加
                    Out_Map_Doc_Pat mapDocPat = _outMapDocPatRepository.SelectByDocIdWithPatId(doctorUserInfo.Id, pubUserInfo.ID);
                    if (mapDocPat != null)
                    {
                        //已经是好友了，添加标签
                        if (!string.IsNullOrEmpty(tagIdList))
                        {
                            List<string> tagList = tagIdList.Split(',').ToList();
                            if (tagList.Count() > 0)
                            {
                                foreach (var tagId in tagList)
                                {
                                    _outMapPatTagService.SetTag(doctorUserInfo.Id, Convert.ToInt32(tagId), pubUserInfo.ID);
                                }
                            }
                        }
                        return;
                    }
                    else
                    {
                        Pub_Map_Patuser_Docuser mapPatuserDocuser = new Pub_Map_Patuser_Docuser();
                        mapPatuserDocuser.Pat_User_Id = pubUserInfo.ID;
                        mapPatuserDocuser.Doc_User_Id = doctorUserInfo.Id;
                        mapPatuserDocuser.Status = 1;
                        mapPatuserDocuser.Create_Time = DateTime.Now;
                        _pubMapPatuserDocuserRepository.InsertPatuserDocuser(mapPatuserDocuser);

                        mapDocPat = new Out_Map_Doc_Pat();
                        mapDocPat.Doctor_Id = doctorUserInfo.Id;
                        mapDocPat.Pat_Id = pubUserInfo.ID;
                        mapDocPat.Is_Star = 0;
                        mapDocPat.Is_Topping = 0;
                        mapDocPat.Status = 1;
                        mapDocPat.Create_Time = DateTime.Now;
                        _outMapDocPatRepository.InsertOutMapDocPat(mapDocPat);

                        _tencentService.FriendAdd(pubUserInfo.IM_ID, new List<string>() { doctorUserInfo.ImId });
                        //发送一条消息
                        _tencentService.SendFriendMsgOnly(doctorUserInfo.ImId, pubUserInfo.IM_ID, "我们已经互相关注了，快发起会话吧。" + "We have followed each other,let's start chat.");
                        //3.添加患者标签

                        if (!string.IsNullOrEmpty(tagIdList))
                        {
                            List<string> tagList = tagIdList.Split(',').ToList();
                            if (tagList.Count() > 0)
                            {
                                foreach (var tagId in tagList)
                                {
                                    _outMapPatTagService.SetTag(doctorUserInfo.Id, Convert.ToInt32(tagId), pubUserInfo.ID);
                                }
                            }
                        }
                    }
                }
            }
        }


        private void Bind(int userId, int patId, string type = "sino")
        {
            Pub_Map_User_Pat pubMapUserPat = _pubMapUserPatRepository.GetPubUserPat(userId, patId, type);
            if (pubMapUserPat == null)
            {
                pubMapUserPat = new Pub_Map_User_Pat();
                pubMapUserPat.Is_Deleted = false;
                pubMapUserPat.Relation_Ship = 1;
                pubMapUserPat.User_ID = userId;
                pubMapUserPat.Pat_ID = patId;
                _pubMapUserPatRepository.InsertPubMapUserPat(pubMapUserPat);
            }
            else
            {
                pubMapUserPat.Is_Deleted = false;
                pubMapUserPat.Relation_Ship = 1;
                pubMapUserPat.User_ID = userId;
                pubMapUserPat.Pat_ID = patId;
                _pubMapUserPatRepository.UpdatePubMapUserPat(pubMapUserPat);
            }
        }

        /// <summary>
        /// 绑定就诊人
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="patInfo"></param>
        /// <param name="patType"></param>
        /// <param name="language"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public BaseResponse AddPat(int userId, Pub_Pat_Info patInfo, int patType, int language, string code)
        {
            BaseResponse res = new BaseResponse();
            //校验验证码
            var result = _verifyCodeLogService.CheckCode(patInfo.Phone_NO, code);
            if (result == 0)
            {
                res.Code = 0;
                res.Msg = "未找到验证码";
                //验证码不正确返回错误信息
                return res;
            }
            if (patType == 0)
            {
                //添加his患者
                List<PAPerson> patList = _tcService.GetPat(patInfo.Phone_NO, patInfo.Birthday);
                if (patList != null && patList.Count > 0)
                {
                    //性别姓名过滤
                    string gender = patInfo.Gender == 0 ? "Female" : "Male";
                    List<PAPerson> patListNew = patList.FindAll(o => o.PAPERSex.ToLower().Contains(gender.ToLower()) &&
                            o.PAPERName.ToLower() == patInfo.Last_Name.ToLower() &&
                            o.PAPERName2.ToLower() == patInfo.First_Name.ToLower()).ToList();

                    if (patListNew != null && patListNew.Count > 0)
                    {
                        //存在数据添加患者
                        SaveHisPat(patList[0], userId, patInfo);
                        res.Code = 1;
                        res.Msg = "成功";
                        return res;
                    }
                    else
                    {
                        //排除姓名匹配
                        patList = patList.FindAll(o => o.PAPERSex.ToLower().Contains(gender.ToLower())).ToList();
                        if (patList != null && patList.Count > 0)
                        {
                            res.Code = 0;
                            res.Msg = "姓名是否填写错误？";
                            return res;
                        }
                        else
                        {
                            res.Code = 0;
                            res.Msg = "信息填写错误";
                            return res;
                        }
                    }
                }
                else
                {
                    res.Code = 0;
                    res.Msg = "信息填写错误";
                    return res;
                }
            }
            else if (patType == 1)
            {
                //添加临时就诊人
                patInfo.Pat_Name = patInfo.Last_Name + patInfo.Pat_Name;
                patInfo.Pat_Source = 0;//来自PP
                _patService.Add(patInfo, 4, language);
                res.Code = 1;
                res.Msg = "成功";
                return res;
            }
            res.Code = 1;
            res.Msg = "参数错误";
            return res;
        }

        public string GeneralPatAdd(PatAddModel model)
        {
            string errStr = string.Empty;
            //校验验证码
            var result = _verifyCodeLogService.CheckCode(model.PhoneNo, model.Code);
            if (result < 1)
            {
                errStr = model.Language == 1 ? "未找到验证码！" : "Invalid Verification Code";
                return errStr;
            }
            if (string.IsNullOrEmpty(model.Birthday))
            {
                errStr = model.Language == 1 ? "出生日期未填写！" : "Please select birthday";
                return errStr;
            }

            if (string.IsNullOrEmpty(model.CardId))
            {
                errStr = model.Language == 1 ? "证件信息未填写！" : "Please enter ID info";
                return errStr;
            }
            if (string.IsNullOrEmpty(model.Email))
            {
                errStr = model.Language == 1 ? "邮箱未填写！" : "Invalid Email";
                return errStr;
            }
            var asd = model.CardId.Trim().Length;
            if (model.CardType == 1)
            {
                if (model.CardId.Trim().Length != 18 && model.CardId.Trim().Length != 15)
                {
                    errStr = model.Language == 1 ? "证件信息填写不正确！" : "Invalid ID info";
                    return errStr;
                }
            }
            if (!model.PhoneNo.IsPhoneNumber())
            {
                errStr = model.Language == 1 ? "手机号码格式不正确！" : "Invalid phone number ";
                return errStr;
            }

            DateTime dt = DateTime.Parse(model.Birthday);
            if (dt.GetAgeByBirth() < 18)
            {
                if (model.DocumentType <= 0)
                {
                    errStr = model.Language == 1 ? "监护人证件类型未填写！" : "Invalid ID Type";
                    return errStr;
                }
                if (string.IsNullOrEmpty(model.Guardian))
                {
                    errStr = model.Language == 1 ? "监护人姓名未填写！" : "Please enter guardian name";
                    return errStr;
                }
                if (string.IsNullOrEmpty(model.CertificateNumber))
                {
                    errStr = model.Language == 1 ? "监护人证件未填写！" : "Please enter guardian ID info";
                    return errStr;
                }
            }
            Pub_Pat_Info pat_Info = new Pub_Pat_Info();
            pat_Info.Card_ID = model.CardId;
            pat_Info.Card_Type = model.CardType;
            pat_Info.IsDefault = model.IsDefault;
            pat_Info.Guardian = model.Guardian;
            pat_Info.Last_Guardian = model.LastGuardian;
            pat_Info.First_Guardian = model.FirstGuardian;
            pat_Info.Document_Type = model.DocumentType;
            pat_Info.Certificate_Number = model.CertificateNumber;
            pat_Info.Last_Name = model.LastName;
            pat_Info.First_Name = model.FirstName;
            pat_Info.Phone_NO = model.PhoneNo;
            DateTime bredate;
            DateTime.TryParse(model.Birthday, out bredate);
            pat_Info.Birthday = bredate.ToString("yyyy-MM-dd");
            pat_Info.Gender = model.Gender;
            pat_Info.Email = model.Email;

            try
            {
                model.Birthday = Convert.ToDateTime(model.Birthday).ToString("yyyy-MM-dd");
                List<PAPerson> patList = _tcService.GetPat(model.PhoneNo.Trim(), model.Birthday.Trim());
                //判断是否是TC患者
                if (patList != null && patList.Count > 0)
                {//TC患者
                    var pat = _pubPatRepository.SelectByMrn(patList[0].PAPMINo);
                    if (pat != null)
                    {
                        Pub_Map_User_Pat pubMapUserPat = _pubMapUserPatRepository.GetPubUserPat(0, pat.Id, "cigna");
                        if (pubMapUserPat != null)
                        {
                            if (model.Language == 1)
                            {
                                errStr = "该就诊人已被其他账号绑定";
                            }
                            else
                            {
                                errStr = "Patient has been added to another account";
                            }
                            return errStr;
                        }
                    }
                    //性别姓名过滤
                    string gendera = model.Gender == 0 ? "Female" : "Male";
                    List<PAPerson> patListNew = patList.FindAll(o => o.PAPERName.ToLower().Trim() == model.LastName.ToLower().Trim() &&
                            o.PAPERName2.ToLower().Trim() == model.FirstName.ToLower().Trim()).ToList();//o.PAPERSex.ToLower().Contains(gendera.ToLower()) &&

                    if (patListNew != null && patListNew.Count > 0)
                    {
                        //存在数据添加患者
                        int patid = SaveHisPat(patList[0], GetBaseUserInfo().ID, pat_Info, "cigna");
                        return "";
                    }
                    else
                    {
                        errStr = model.Language == 1 ? "姓名是否填写错误！" : "Please check the name entered";
                        return errStr;
                    }
                }
                else
                {//临时就诊人
                    var resp = PatAdd(pat_Info, 4, model.Language);
                    return resp;
                }

            }
            catch (System.Exception ee)
            {
                errStr = ee.Message;
                return errStr;
            }
        }

        public string PatAdd(Pub_Pat_Info patInfo, int relationShip, int language)
        {
            var userId = GetBaseUserInfo().ID;
            if (patInfo.IsDefault == 1)
            {
                _patService.CancelUserDefult(userId);
            }
            if (patInfo.Card_Type == 1)
            {
                patInfo.Nationality = "CN";
            }
            // 新增或修改患者信息
            string patName = _patService.GetPatNameByLanguage(patInfo.Last_Name, patInfo.First_Name, language);
            if (patName != null)
            {
                patInfo.Pat_Name = patName;
            }
            var pat = _pubPatRepository.GetPatByName(patInfo.First_Name, patInfo.Last_Name, patInfo.Phone_NO);//临时就诊人验名字
            if (pat != null)
            {
                patInfo.Id = pat.Id;
                var userPat = _pubMapUserPatRepository.GetPubUserPat(0, pat.Id, "cigna");
                if (userPat != null) //有过就诊人 且有绑定关系   逻辑写的烂的一B 
                {
                    if (language == 1)
                    {
                        return "该就诊人已被其他账号绑定";
                    }
                    else
                    {
                        return "Patient has been added to another account";
                    }
                }
            }
            else
            {
                patInfo.Birthday = Convert.ToDateTime(patInfo.Birthday).ToString("yyyy-MM-dd");
                patInfo.Is_Deleted = false;
                patInfo.Pat_Source = 0;
                var pprid = _pubPatRepository.InsertPubPatInfo(patInfo);
                patInfo.Id = int.Parse(pprid.ToString());
            }
            var pubMapUserPat = new Pub_Map_User_Pat()
            {
                User_ID = userId,
                Pat_ID = patInfo.Id,
                Is_Deleted = false,
                Relation_Ship = relationShip,
                Create_Time = DateTime.Now

            };
            _pubMapUserPatRepository.InsertPubMapUserPat(pubMapUserPat);

            return "";
        }


        public BaseResponse<dynamic> AddPatNew(int? id, string lastName, string firstName, string birthday, int gender, string phoneNo, int patType, string code, int language
            , int CardType, string Card_Id, string Guardian, string LastGuardian, string FirstGuardian, int DocumentType, string CertificateNumber, int IsDefault, string email, string patSource = "sino")
        {
            BaseResponse<dynamic> res = new BaseResponse<dynamic>();
            Pub_Pat_Info pat_Info = new Pub_Pat_Info();
            pat_Info.Card_ID = Card_Id;
            pat_Info.Card_Type = CardType;
            pat_Info.IsDefault = IsDefault;
            pat_Info.Guardian = Guardian;
            pat_Info.Last_Guardian = LastGuardian;
            pat_Info.First_Guardian = FirstGuardian;
            pat_Info.Document_Type = DocumentType;
            pat_Info.Certificate_Number = CertificateNumber;
            pat_Info.Last_Name = lastName;
            pat_Info.First_Name = firstName;
            pat_Info.Phone_NO = phoneNo;
            DateTime bredate;
            DateTime.TryParse(birthday, out bredate);
            pat_Info.Birthday = bredate.ToString("yyyy-MM-dd");
            pat_Info.Gender = gender;
            pat_Info.Email = email;
            //校验验证码
            var result = _verifyCodeLogService.CheckCode(phoneNo, code);
            if (result < 1)
            {
                res.Code = 0;
                res.Msg = "未找到验证码";
                //验证码不正确返回错误信息
                return res;
            }


            if (patType == 0) //确认TC有此人
            {
                //添加his患者
                List<PAPerson> patList = _tcService.GetPat(phoneNo.Trim(), pat_Info.Birthday.Trim());
                if (patList != null && patList.Count > 0)
                {
                    if (!string.IsNullOrEmpty(patList[0].PAPMINo))
                    {
                        var pat = _pubPatRepository.SelectByMrn(patList[0].PAPMINo);
                        if (pat != null)
                        {
                            Pub_Map_User_Pat pubMapUserPat = _pubMapUserPatRepository.GetPubUserPat(0, pat.Id, patSource);
                            if (pubMapUserPat != null)
                            {
                                res.Data = new { patId = 0 };
                                res.Code = 0;
                                if (language == 1)
                                {
                                    res.Msg = "该就诊人已被其他账号绑定";
                                }
                                else
                                {
                                    res.Msg = "Patient has been added to another account";
                                }
                                return res;
                            }
                        }
                    }

                    //性别姓名过滤
                    pat_Info.Last_Name = lastName;
                    pat_Info.First_Name = firstName;
                    string gendera = gender == 0 ? "Female" : "Male";
                    List<PAPerson> patListNew = patList.FindAll(o => o.PAPERName.ToLower().Trim() == lastName.ToLower().Trim() &&
                            o.PAPERName2.ToLower().Trim() == firstName.ToLower().Trim()).ToList();//o.PAPERSex.ToLower().Contains(gendera.ToLower()) &&

                    if (patListNew != null && patListNew.Count > 0)
                    {
                        //存在数据添加患者
                        int patid = SaveHisPat(patList[0], GetBaseUserInfo().ID, pat_Info, patSource);
                        _tcService.UpdatePatientPortalLink("", patList[0].PAPMINo, true);
                        res.Code = 1;
                        res.Msg = "成功";
                        res.Data = new { patId = patid };
                        return res;
                    }
                    else
                    {
                        res.Code = 0;
                        res.Msg = language == 1 ? "请确保信息与线下登记的一致" : "Pls use information registered in clinic";
                        res.Data = new { patId = 0 };
                        return res;
                        ////排除姓名匹配
                        //patList = patList.FindAll(o => o.PAPERSex.ToLower().Contains(gendera.ToLower())).ToList();
                        //if (patList != null && patList.Count > 0)
                        //{
                        //    res.Code = 0;
                        //    res.Msg = "姓名是否填写错误？";
                        //    return res;
                        //}
                        //else
                        //{
                        //    res.Code = 0;
                        //    res.Msg = "信息填写错误";
                        //    return res;
                        //}
                    }
                }
                else
                {
                    res.Code = 0;
                    if (language == 1)
                    {
                        res.Msg = "请确保信息与线下登记的一致";
                    }
                    else
                    {
                        res.Msg = "Pls use information registered in clinic";
                    }
                    return res;
                }
            }
            else if (patType == 1)
            {//保险应该走不到这  所以不加患者来源了
                //添加临时就诊人
                pat_Info.Pat_Name = lastName + firstName;
                pat_Info.Pat_Source = 0;//来自PP
                if (id != null)
                {
                    pat_Info.Id = Convert.ToInt32(id);
                }
                //var pat = _patService.Add(pat_Info, 4, language);
                //res.Data = new { patId = pat.Id };
                //res.Code = 1;
                //res.Msg = "成功";
                return Add(pat_Info, 4, language);
            }

            res.Code = 1;
            res.Msg = "参数错误";
            return res;
        }

        /// <summary>
        /// 企业疫苗预约添加就诊人
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public BaseResponse<dynamic> AddEnterpriseVaccinatedPeople(AddEnterpriseVaccinatedPeopleParam param)
        {
            var patInfo = new Pub_Pat_Info
            {
                IsDefault = 0,
                Pat_Source = 3,

                Last_Name = param.LastName,
                First_Name = param.FirstName,
                Phone_NO = param.PhoneNo,
                Gender = param.Gender,
                Birthday = DateTime.TryParse(param.Birthday, out var bredate)
                    ? bredate.ToString("yyyy-MM-dd")
                    : ""
            };

            var addResult = Add(patInfo, 4, param.Language);

            _logger.LogInformation($"企业疫苗预约添加接种人：{patInfo.ToJson()},添加结果：{addResult.ToJson()}");

            return new BaseResponse<dynamic>
            {
                Code = addResult.Code,
                Msg = addResult.Msg,
                Data = new
                {
                    Id = addResult.Data.patId
                }
            };
        }


        /// <summary>
        /// 这个方法从patService中搬过来的改的  别问我为什么搬
        /// </summary>
        /// <param name="patInfo"></param>
        /// <param name="relationShip"></param>
        /// <param name="language"></param>
        /// <returns></returns>
        public BaseResponse<dynamic> Add(Pub_Pat_Info patInfo, int relationShip, int language)
        {
            BaseResponse<dynamic> ret = new BaseResponse<dynamic>();
            var userId = GetBaseUserInfo().ID;
            if (patInfo.IsDefault == 1)
            {
                _patService.CancelUserDefult(userId);
            }
            if (patInfo.Card_Type == 1)
            {
                patInfo.Nationality = "CN";
            }
            // 新增或修改患者信息
            int patId = patInfo.Id;
            string patName = _patService.GetPatNameByLanguage(patInfo.Last_Name, patInfo.First_Name, language);
            if (patName != null)
            {
                patInfo.Pat_Name = patName;
            }
            var pat = _pubPatRepository.GetPatByName(patInfo.First_Name, patInfo.Last_Name, patInfo.Phone_NO);//临时就诊人验名字shouji
            if (pat != null)
            {
                patInfo.Id = pat.Id;
                var userPat = _pubMapUserPatRepository.GetPubUserPat(0, pat.Id);
                if (userPat != null) //有过就诊人 且有绑定关系   逻辑写的烂的一B 
                {
                    ret.Data = new { patId = 0 };
                    ret.Code = 0;
                    if (language == 1)
                    {
                        ret.Msg = "该就诊人已被其他账号绑定";
                    }
                    else
                    {
                        ret.Msg = "Patient has been added to another account";
                    }
                    return ret;
                }
            }

            Pub_Pat_Info pubPatInfo = _pubPatRepository.SelectById(patInfo.Id);
            if (null == pubPatInfo)
            {
                patInfo.Birthday = Convert.ToDateTime(patInfo.Birthday).ToString("yyyy-MM-dd");
                patInfo.Is_Deleted = false;
                patInfo.Pat_Source = 0;

                var pprid = _pubPatRepository.InsertPubPatInfo(patInfo);
                patInfo.Id = int.Parse(pprid.ToString());
                //_pubPatRepository.InsertPubPatInfo(patInfo);
            }
            else
            {
                patInfo.Birthday = Convert.ToDateTime(patInfo.Birthday).ToString("yyyy-MM-dd");
                patInfo.Id = pubPatInfo.Id;
                var Repository = _pubPatRepository.UpdatePubPatInfo(patInfo);
                //_pubPatRepository.UpdatePubPatInfo(patInfo);
            }

            Pub_Map_User_Pat pubMapUserPat = null;
            if (patId != patInfo.Id)
            {
                // 这里先让原来的关系隐藏
                pubMapUserPat = _pubMapUserPatRepository.GetPubUserPat(userId, patId);
                if (pubMapUserPat != null)
                {
                    pubMapUserPat.Relation_Ship = pubMapUserPat.Relation_Ship | 8;
                    _pubMapUserPatRepository.UpdatePubMapUserPat(pubMapUserPat);
                }
                //_pubMapUserPatRepository.UpdatePubMapUserPat(pubMapUserPat);
            }

            pubMapUserPat = _pubMapUserPatRepository.GetPubUserPat(userId, patInfo.Id);

            if (null == pubMapUserPat)
            {
                pubMapUserPat = new Pub_Map_User_Pat()
                {
                    User_ID = userId,
                    Pat_ID = patInfo.Id,
                    Is_Deleted = false,
                    Relation_Ship = relationShip,
                    Create_Time = DateTime.Now

                };
                _pubMapUserPatRepository.InsertPubMapUserPat(pubMapUserPat);
                //_pubMapUserPatRepository.InsertPubMapUserPat(pubMapUserPat);
            }
            else
            {
                pubMapUserPat.Pat_ID = patInfo.Id;
                pubMapUserPat.User_ID = userId;
                pubMapUserPat.Update_Time = DateTime.Now;
                pubMapUserPat.Relation_Ship = pubMapUserPat.Relation_Ship | relationShip;
                _pubMapUserPatRepository.UpdatePubMapUserPat(pubMapUserPat);
                //_pubMapUserPatRepository.UpdatePubMapUserPat(pubMapUserPat);
            }
            ret.Data = new { patId = patInfo.Id };
            ret.Code = 1;
            ret.Msg = "成功";
            return ret;
        }


        public BaseResponse<bool> IsTCPat(string birthday, string phoneNo)
        {
            BaseResponse<bool> res = new BaseResponse<bool>();
            birthday = Convert.ToDateTime(birthday).ToString("yyyy-MM-dd");
            List<PAPerson> patList = _tcService.GetPat(phoneNo.Trim(), birthday.Trim());
            res.Code = 1;
            res.Msg = "成功";
            if (patList != null && patList.Count > 0)
            {
                res.Data = true;
            }
            else
            {
                res.Data = false;
            }
            return res;
        }
        public BaseResponse DeletePat(int patId)
        {
            BaseResponse res = new BaseResponse();
            Pub_Map_User_Pat pubMapUserPat = _pubMapUserPatRepository.GetUserPat(GetUserInfo().ID, patId);
            if (pubMapUserPat != null)
            {
                pubMapUserPat.Is_Deleted = true;
                _pubMapUserPatRepository.UpdatePubMapUserPat(pubMapUserPat);
                //var pat = _pubPatRepository.SelectById(patId);
                //if (pat != null)//这里不能删除患者  可能会更新重用 
                //{
                //    pat.Is_Deleted = true;
                //    _pubPatRepository.UpdatePubPatInfo(pat);
                //}
                res.Code = 1;
                res.Msg = "成功";
                return res;
            }
            res.Code = 0;
            res.Msg = "失败";
            return res;
        }

        private int SaveHisPat(PAPerson pat, int userId, Pub_Pat_Info info, string type = "sino")
        {
            Pub_Pat_Info patInfo = new Pub_Pat_Info();
            patInfo.Pat_Source = 1;
            patInfo.Is_Deleted = false;
            patInfo.IsDefault = info.IsDefault;
            patInfo.Birthday = pat.PAPERDob.ToString();
            patInfo.Email = pat.PAPEREmail;
            if (string.IsNullOrEmpty(patInfo.Email))
            {
                patInfo.Email = info.Email;
            }
            patInfo.Last_Name = pat.PAPERName;
            patInfo.First_Name = pat.PAPERName2;
            patInfo.Guardian = info.Guardian;
            patInfo.Last_Guardian = info.Last_Guardian;
            patInfo.First_Guardian = info.First_Guardian;
            patInfo.Document_Type = info.Document_Type;
            patInfo.Certificate_Number = info.Certificate_Number;
            patInfo.Card_Type = info.Card_Type;
            patInfo.Card_ID = info.Card_ID;
            if (!string.IsNullOrEmpty(pat.PAPERID))
            {
                patInfo.Card_ID = pat.PAPERID;
            }
            if (string.IsNullOrEmpty(pat.PAPERSex))
            {
                patInfo.Gender = null;
            }
            else
            {
                patInfo.Gender = pat.PAPERSex.ToLower().Contains("female") ? 0 : 1;
            }
            patInfo.Is_Active = pat.PAPMIActive == "Y";
            patInfo.Is_Dead = pat.PAPERDeceased == "Y";
            patInfo.Pat_ID = pat.PAPERRowId;
            patInfo.Pat_MRN = pat.PAPMINo;
            patInfo.Mrn = pat.MRN;
            patInfo.Nationality = pat.PAPERNation;

            string lastName = string.IsNullOrEmpty(pat.PAPERName) ? "" : pat.PAPERName.Trim();
            if (!string.IsNullOrEmpty(lastName) && !lastName.IsChinese())
            {
                patInfo.Pat_Name = pat.PAPERName2 + " " + lastName;
            }
            else
            {
                patInfo.Pat_Name = lastName + pat.PAPERName2;
            }
            if (!string.IsNullOrEmpty(pat.PAPERMobPhone))
            {
                patInfo.Phone_NO = pat.PAPERMobPhone;
            }
            patInfo.Pat_Source = 1;
            int patId = _patService.SaveHisPat(patInfo);
            Bind(userId, patId, type);
            return patId;
        }

        public UserToken GetUser()
        {
            var info = GetBaseUserInfo();
            Pub_User_Info userInfo = _pubUserInfoRepository.initLinq().Where(p => p.ID == info.ID).Single();
            if (userInfo != null)
            {
                UserDetail pubUserInfo = TransModel(userInfo);
                UserToken userToken = new UserToken();
                userToken.UserInfo = pubUserInfo;
                return userToken;
            }
            return null;
        }

        public Pub_User_Info GetUserInfo()
        {
            var info = GetBaseUserInfo();
            Pub_User_Info userInfo = _pubUserInfoRepository.initLinq().Where(p => p.ID == info.ID).Single();

            return userInfo;
        }

        public List<UserAddress> GetUserAddress()
        {
            var info = GetBaseUserInfo();
            //var list = _pubUserAddressRepository.initLinq().Where(p => p.UserId == info.ID && p.IsDelete == false).Select().ToList();
            var list = _pubUserAddressRepository.GetAddress(info.ID, 0);
            if (list != null && list.Count > 1 && list.Find(p => p.IsDefaultAddress == 1) != null)
            {
                var deAdd = list.Find(p => p.IsDefaultAddress == 1);
                list.Remove(deAdd);
                list.Insert(0, deAdd);
            }
            return TransToModelList(list);
        }

        private List<UserAddress> TransToModelList(List<Pub_User_Address> list)
        {
            if (list == null)
            {
                return new List<UserAddress>();
            }
            List<UserAddress> retList = new List<UserAddress>();
            UserAddress add = null;
            foreach (var item in list)
            {
                add = new UserAddress();
                add.Address = item.Address;
                add.Area = item.Area;
                add.AreaId = item.AreaId;
                add.City = item.City;
                add.CityId = item.CityId;
                add.Id = item.Id;
                add.IsDefaultAddress = item.IsDefaultAddress;
                add.Localization = item.Localization;
                add.Province = item.Province;
                add.ProvinceId = item.ProvinceId;
                add.ReceiveName = item.ReceiveName;
                add.ReceivePhone = item.ReceivePhone;
                add.Remark = item.Remark;
                retList.Add(add);
            }
            return retList;
        }
        private UserAddress TransToModel(Pub_User_Address item)
        {
            if (item == null)
            {
                return new UserAddress();
            }
            UserAddress add = new UserAddress();
            add.Address = item.Address;
            add.Area = item.Area;
            add.AreaId = item.AreaId;
            add.City = item.City;
            add.CityId = item.CityId;
            add.Id = item.Id;
            add.IsDefaultAddress = item.IsDefaultAddress;
            add.Localization = item.Localization;
            add.Province = item.Province;
            add.ProvinceId = item.ProvinceId;
            add.ReceiveName = item.ReceiveName;
            add.ReceivePhone = item.ReceivePhone;
            add.Remark = item.Remark;
            return add;
        }
        public UserAddress GetCurAddress(int addId)
        {
            var info = GetBaseUserInfo();
            //var ret = _pubUserAddressRepository.initLinq().Where(p => p.Id == addId && p.IsDelete == false).Single();
            var list = _pubUserAddressRepository.GetAddress(info.ID, addId)?.FirstOrDefault();
            return TransToModel(list);
        }
        public List<Pub_User_Info> GetAllUserInfo()
        {
            return _pubUserInfoRepository.GetAllUserInfo();
        }

        public int GetIMIDForIsRegUser()
        {
            var users = _pubUserInfoRepository.GetIsRegNotHasImIdUser();
            foreach (var item in users)
            {
                _tencentService.GetUsersigByPat(item.ID);
            }
            return 1;
        }

        public int AddUserAddress(UserAddress address)
        {
            Pub_User_Address add = new Pub_User_Address();
            add.Address = address.Address;
            add.Area = address.Area;
            add.AreaId = address.AreaId;
            add.City = address.City;
            add.CityId = address.CityId;
            add.IsDefaultAddress = address.IsDefaultAddress;
            add.Localization = address.Localization;
            add.Province = address.Province;
            add.ProvinceId = address.ProvinceId;
            add.ReceiveName = address.ReceiveName;
            add.ReceivePhone = address.ReceivePhone;
            add.Remark = address.Remark;
            add.CreateTime = DateTime.Now;
            add.IsDelete = false;
            add.UserId = GetBaseUserInfo().ID;
            if (address.IsDefaultAddress == 1)
            {
                _pubUserAddressRepository.ShutOtherDefault(GetBaseUserInfo().ID);
            }
            return _pubUserAddressRepository.InsertPubUserAddress(add);
        }

        public int UpdateUserAddress(UserAddress address)
        {
            Pub_User_Address add = new Pub_User_Address();
            add.Id = address.Id;
            add.Address = address.Address;
            add.Area = address.Area;
            add.AreaId = address.AreaId;
            add.City = address.City;
            add.CityId = address.CityId;
            add.IsDefaultAddress = address.IsDefaultAddress;
            add.Localization = address.Localization;
            add.Province = address.Province;
            add.ProvinceId = address.ProvinceId;
            add.ReceiveName = address.ReceiveName;
            add.ReceivePhone = address.ReceivePhone;
            add.Remark = address.Remark;
            add.UpdateTime = DateTime.Now;
            add.IsDelete = false;
            add.UserId = GetBaseUserInfo().ID;
            if (address.IsDefaultAddress == 1)
            {
                _pubUserAddressRepository.ShutOtherDefault(GetBaseUserInfo().ID);
            }
            return _pubUserAddressRepository.UpdatePubUserAddress(add);
        }
        public int DeleteUserAddress(int addId)
        {

            return _pubUserAddressRepository.DeletePubUserAddress(addId);
        }

        public List<ArticleCollect> GetUserCollerct(string keyWords)
        {
            return _outArticleCollectRepository.GetUserCollerct(GetBaseUserInfo().ID, keyWords);
        }

        public int CancelUserCollerct(int artId)
        {
            return _outArticleCollectRepository.CancelUserCollerct(GetUserInfo().ID, artId);
        }

        public BaseResponse<VideoUserSignResp> GetUserIMKey()
        {
            BaseResponse<VideoUserSignResp> res = new BaseResponse<VideoUserSignResp>();
            var result = _tencentService.GetUsersigByPat(GetBaseUserInfo().ID);
            if (result != null)
            {
                res.Code = 1;
                res.Msg = "获取成功";
                res.Data = result;
            }
            return res;
        }

        public bool TestJpush()
        {
            var res = _jpushService.TestJpush(GetBaseUserInfo().IOS_ID);
            return res;
        }

        public Pub_User_Info SaveKey(int keyType, string key)
        {
            Pub_User_Info userInfo = _pubUserInfoRepository.SelectByPrimaryKey(GetBaseUserInfo().ID);
            if (userInfo != null)
            {
                //修改用户推送KEY
                if (keyType == 1)
                {
                    userInfo.Android_ID = key;
                }
                else
                {
                    userInfo.IOS_ID = key;
                }
                userInfo.Key_Type = keyType;
                userInfo.Update_Time = DateTime.Now;
                _pubUserInfoRepository.UpdatePubUserInfo(userInfo);
            }
            return userInfo;
        }

        public string GetUrl(string orderNo, int language)
        {
            return _linKingService.IFIMTokenGet(orderNo, language);
        }

        public string GetEvaluateUrl(string orderNo)
        {
            return _linKingService.IFIMEvaluateGet(orderNo);
        }

        public string BindUserPat(int patId)
        {
            var openid = string.Empty;
            var pat = _pubUserInfoService.SelectById(patId);
            if (string.IsNullOrEmpty(pat.LinKingOpenId))
            {
                openid = Guid.NewGuid().ToString();
                _pubUserInfoService.UpdatePatByLinKing(openid, patId);
            }
            openid = pat.LinKingOpenId;
            string code = Guid.NewGuid().ToString();
            _redisHelper.StringSet("LinKingPatCodeInterface:" + code, openid, TimeSpan.FromDays(1));
            return code;
        }

        public PatWithRelationShip SelectPatById(int patId)
        {
            var pat = _pubUserInfoService.SelectPatById(patId);
            pat.Age = Tools.Tools.GetAgeByBirth(DateTime.Parse(pat.Birthday));
            return pat;
        }

        public LinKingAccessToken AccessToken(string appid, string secret, string code)
        {
            var key = "LinKingPatCodeInterface:" + code;
            var response = new LinKingAccessToken();
            var redisres = _redisHelper.Get(key);
            if (!string.IsNullOrEmpty(redisres))
            {
                _redisHelper.KeyDelete(key);
                if (appid == LinKingAppid && secret == LinKingSecret)
                {
                    var pat = _pubUserInfoService.SelectByLinKingOpenId(redisres);
                    if (pat != null)
                    {
                        response.access_token = GetToken("pat_" + pat.Id);
                        response.openid = redisres;
                        response.expires_in = "7200";
                        return response;
                    }
                }
                return response;
            }
            return response;
        }

        public LinKingUserDetail UserInfo(LinKingUserRequest request)
        {
            var user = _tokenService.CheckTokenForPat(request.access_token);
            LinKingUserDetail response = new LinKingUserDetail();
            response.name = string.IsNullOrEmpty(user.Pat_Name) ? "" : user.Pat_Name;
            response.openid = user.Id.ToString();
            response.tel = user.Phone_NO;
            response.work_num = user.Id.ToString();
            response.idcard = user.Id_Number;
            return response;
        }

        public VideoUserSignResp GetUserIMID()
        {
            if (GetBaseUserInfo() == null)
            {
                return new VideoUserSignResp();
            }

            var res = _tencentService.GetUsersigByPat(GetBaseUserInfo().ID);
            return res;
        }

        public VideoUserSignResp GetKey()
        {
            var key = _tencentService.GetKey("pat_" + GetBaseUserInfo().ID);
            VideoUserSignResp result = new VideoUserSignResp();
            result.Key = key;
            result.UserId = "pat_" + GetBaseUserInfo().ID;
            return result;
        }

        public bool IsTreatment()
        {
            bool result = false;
            Pub_User_Info userInfo = _pubUserInfoRepository.SelectByPrimaryKey(GetBaseUserInfo().ID);
            if (userInfo != null && userInfo.Treatment_Password != null)
            {
                result = true;
            }
            return result;
        }

        public BaseResponse UpdateTreatment(string password, string code)
        {
            BaseResponse res = new BaseResponse();
            Pub_User_Info pubUserInfo = _pubUserInfoRepository.SelectByPrimaryKey(GetBaseUserInfo().ID);
            if (pubUserInfo != null)
            {
                //校验验证码
                var result = _verifyCodeLogService.CheckCode(pubUserInfo.Phone, code);
                if (1 != result)
                {
                    res.Code = 0;
                    res.Msg = "验证码不正确";
                    //验证码不正确返回错误信息
                    return res;
                }
                else
                {
                    //修改密码
                    //1.加密
                    string md5PassWord = Common.GetMD5(password);
                    //2.修改
                    _pubUserInfoRepository.UpdateTreatment(GetBaseUserInfo().ID, md5PassWord);
                    res.Code = 1;
                    res.Msg = "成功";
                    return res;
                }
            }
            else
            {
                res.Code = 0;
                res.Msg = "失败";
                return res;
            }
        }

        public BaseResponse<string> CheckTreatment(string password)
        {
            BaseResponse<string> res = new BaseResponse<string>();
            string mdPassword = Common.GetMD5(password);
            Pub_User_Info pubUserInfo = _pubUserInfoRepository.SelectByTreatment(GetBaseUserInfo().ID, mdPassword);
            if (pubUserInfo != null)
            {
                string token = _tokenService.SetReport(GetBaseUserInfo().ID);
                if (!string.IsNullOrEmpty(token))
                {
                    res.Code = 1;
                    res.Msg = "成功";
                    res.Data = token;
                    return res;
                }
            }
            res.Code = 0;
            res.Msg = "密码错误";
            return res;
        }
        public string GetLoginToken(string keyWords, string uid)
        {
            if (string.IsNullOrEmpty(keyWords) || keyWords != "SinoOutLogin")
            {
                return "";
            }
            var pubUserInfo = _pubUserInfoRepository.GetUserByUid(uid);
            if (pubUserInfo == null)
            {
                pubUserInfo = new Pub_User_Info();
                //注册
                pubUserInfo.Is_Reg = false;
                pubUserInfo.Registration_Source = 4;
                pubUserInfo.Is_Deleted = false;
                pubUserInfo.Create_Time = DateTime.Now;
                pubUserInfo.Is_New = false;
                pubUserInfo.U_Id = uid;
                pubUserInfo.Nick_Name = "sino用户" + Guid.NewGuid().ToString().Substring(0, 4);
                var id = _pubUserInfoRepository.InsertPubUserInfo(pubUserInfo);
                pubUserInfo.ID = id;
            }
            var isToken = _redisHelper.KeyExistsAsync("user_" + pubUserInfo.ID);
            if (isToken.Result)
            {
                _redisHelper.DeleteAsync("user_" + pubUserInfo.ID);
            }
            string token = GetToken("user_" + pubUserInfo.ID);
            return token;
        }

        public BaseResponse<List<GetReportList>> GetReportList(int patId)
        {
            BaseResponse<List<GetReportList>> response = new BaseResponse<List<GetReportList>>();
            var pat = _pubPatRepository.SelectById(patId);
            var reps = _tcService.GetReportList(pat.Pat_MRN);
            if (reps != null && reps.Count > 0)
            {
                reps = reps.Where(w => !string.IsNullOrEmpty(w.DocumentTypeDesc)).ToList();
                reps = reps.FindAll(p => p.DocumentTypeDesc.ToLower() == "lab report" || p.DocumentTypeDesc.ToLower() == "pacs report");
            }
            response.Data = reps;
            response.Code = 1;
            response.Msg = "成功";
            response.Data.ForEach(w => { w.PatName = pat.Pat_Name; });
            return response;
        }

        public BaseResponse<List<Pub_Sign_Report>> GetSignReportList(int patId, int userid)
        {
            BaseResponse<List<Pub_Sign_Report>> response = new BaseResponse<List<Pub_Sign_Report>>();
            var authpats = _authorizationService.GetUserAuthPats(GetBaseUserInfo().ID, 3);
            if (!authpats.Where(w => w.Id == patId).Any())
            {
                response.Code = 0;
                response.Msg = "您没有权限查看报告";
                return response;
            }
            var report = _pubPatRepository.GetPubSignReportByPatId(patId);
            response.Data = report;
            response.Code = 1;
            response.Msg = "成功";
            return response;
        }

        /// <summary>
        /// 发送体检报告邮件
        /// </summary>
        /// <param name="patId">患者id</param>
        /// <param name="emailAddress">邮件地址</param>
        /// <param name="filePath">文件网络路径</param>
        /// <param name="type">1-体检、检查报告；2-健康评估报告</param>
        /// <param name="language">语言</param>
        /// <returns></returns>
        public async Task<BaseResponse> SendSignReportEmailAsync(int patId, string emailAddress, string filePath, int type, int language)
        {
            //优先使用用户填写的邮箱，如果传过来的邮箱为空，再去数据库查询患者的邮箱
            if (string.IsNullOrEmpty(emailAddress))
            {
                var patInfo = await _pubPatRepository.GetPubPatInfoByIdAsync(patId);

                if (patInfo != null && !string.IsNullOrEmpty(patInfo.Email))
                {
                    emailAddress = patInfo.Email;
                }
                else
                {
                    _logger.LogError($"体检报告邮件发送失败:email路径为空，filePath-{filePath}");
                    return new BaseResponse
                    {
                        Code = 0,
                        Msg = "email格式不正确"
                    };
                }
            }

            if (!emailAddress.IsEmail())
            {
                _logger.LogError($"体检报告邮件发送失败:email格式不正确，email-{emailAddress}");
                return new BaseResponse
                {
                    Code = 0,
                    Msg = "email格式不正确"
                };
            }

            if (string.IsNullOrEmpty(filePath))
            {
                _logger.LogError($"体检报告邮件发送失败:pdf路径为空，email-{emailAddress}");
                return new BaseResponse
                {
                    Code = 0,
                    Msg = "文件路径为空"
                };
            }

            try
            {
                var httpResponseMessage = await _httpClientFactory.CreateClient().GetAsync(filePath);
                if (!httpResponseMessage.IsSuccessStatusCode)
                {
                    _logger.LogError($"体检报告邮件发送失败:获取文件失败，email-{emailAddress},PDF-{filePath},{httpResponseMessage.ReasonPhrase}");
                    return new BaseResponse
                    {
                        Code = 1,
                        Msg = "获取报告文件失败"
                    };
                }

                var stream = await httpResponseMessage.Content.ReadAsStreamAsync();

                var emailSendInput = new EmailSendInput
                {
                    To = new List<string>
                    {
                        emailAddress
                    },
                    Attachments = new Dictionary<string, Stream>
                    {
                        {filePath.Split('/').LastOrDefault()??"体检报告.pdf",stream}
                    }
                };

                switch (language)
                {
                    case 1 when type == 1:
                        emailSendInput.Subject = "【曜影医疗】检验/检查报告";
                        emailSendInput.HtmlBody = "<div>[本邮件由系统自动发送，请勿直接回复]</div><br/><div>您的报告见附件，如有任何问题请使用曜影医疗APP咨询客服小影</div>";
                        break;
                    case 1 when type == 2:
                        emailSendInput.Subject = "【曜影医疗】健康评估报告";
                        emailSendInput.HtmlBody = "<div>[本邮件由系统自动发送，请勿直接回复]</div><br/><div>您的报告见附件，如有任何问题请使用曜影医疗APP咨询客服小影</div>";
                        break;
                    case 2 when type == 1:
                        emailSendInput.Subject = "【SinoUnited Health】Medical Report";
                        emailSendInput.HtmlBody = "<div>[This email was sent automatically, please don't reply]</div><br/><div>Please see attachment for your Medical Report. Any questions please contact Customer Service Ying in SinoUnited Health APP</div>";
                        break;
                    case 2 when type == 2:
                        emailSendInput.Subject = "【SinoUnited Health】Health Evaluation Report";
                        emailSendInput.HtmlBody = "<div>[This email was sent automatically, please don't reply]</div><br/><div>Please see attachment for your report. Any questions please contact Customer Service Ying in SinoUnited Health APP</div>";
                        break;
                }

                await _emailService.SendAsync(emailSendInput);

                _logger.LogInformation($"体检报告邮件发送成功:Email-{emailAddress},PDF-{filePath}");

                return new BaseResponse
                {
                    Code = 1,
                    Msg = "成功"
                };
            }
            catch (System.Exception e)
            {
                _logger.LogError($"体检报告邮件发送失败:收信人:{emailAddress},PDF-{filePath},错误信息:{e.Message}");

                return new BaseResponse
                {
                    Code = 1,
                    Msg = "发送失败"
                };
            }
        }

        public BaseResponse<GetFileContent> GetFileContent(GetReportList request)
        {
            BaseResponse<GetFileContent> response = new BaseResponse<GetFileContent>();
            GetFileContent data = new GetFileContent();
            data.DateCreated = request.DateCreated;
            data.FileDes = request.FileDes;
            data.PatName = request.PatName;
            data.TimeCreated = request.TimeCreated;
            var res = string.Empty;

            var redisvalue = _redisHelper.Get("TCFile:" + request.DocumentID + "_" + request.PID);
            if (string.IsNullOrWhiteSpace(redisvalue))
            {
                res = _tcService.GetFileContent(request.DocumentID, request.PID);
                if (!string.IsNullOrEmpty(res))
                {
                    data.Url = Base64StringToFile(res, request.DocumentID + "_" + request.PID, request.FileType);
                    _redisHelper.Set("TCFile:" + request.DocumentID + "_" + request.PID, data.Url);
                }
            }
            else
            {
                data.Url = redisvalue;
            }
            response.Data = data;
            response.Code = 1;
            response.Msg = "成功";
            return response;
        }

        public BaseResponse<List<CouponUserView>> GetUserConpon(int patId, int language, int apttype, int docId)
        {
            if (!string.IsNullOrEmpty(GetBaseUserInfo().U_Id))
            {
                return new BaseResponse<List<CouponUserView>>() { Code = 1, Msg = "成功" };
            }
            //获取写死的活动
            List<Online_Coupon> couponNames = _couponService.GetCoupons(patId);

            //给用户发送优惠券，用于写死的活动
            _couponService.IssueCoupons(patId, couponNames);

            //同步已过期优惠券状态
            _couponService.SynchronizationCouponStatus(patId);

            //获取用户优惠券
            List<int> patids = new List<int>();
            patids.Add(patId);
            BaseResponse<List<CouponUserView>> response = new BaseResponse<List<CouponUserView>>();
            response.Data = new List<CouponUserView>();
            response.Data = _couponService.GetPatConponForPatId(patids, language);
            //只返回当前预约类型能使用的优惠券
            response.Data = response.Data.Where(w => w.ConponDetail.AptType.Contains(apttype.ToString())).ToList();

            //只返回当前预约医生能使用的优惠券
            for (int i = 0; i < response.Data.Count; i++)
            {
                var pass = _couponService.VerificationCouponDoc(response.Data[i].ConponDetail.DocIds, response.Data[i].ConponDetail.DeptId, docId.ToString(), apttype);
                if (!pass)
                {
                    response.Data[i].IsDelete = true;
                }
                else
                {
                    //只返回优惠券使用时间满足条件的优惠券
                    if (!_couponService.VerificationCouponTime(response.Data[i].CreateTime, response.Data[i].ConponDetail.EffectiveTime, response.Data[i].ConponDetail.EffectiveDateTime))
                    {
                        response.Data[i].IsDelete = true;
                    }
                }
            }
            response.Data = response.Data.Where(w => !w.IsDelete).ToList();

            //现在只有老客户专享优惠这一个优惠券
            //var coupon = _onlineCouponRepository.GetOnlineCouponList(response.Data.Select(w => w.CouponId).ToList(), language);
            //response.Data = response.Data.Where(w => w.CouponId == coupon.Where(f => f.Name == "老客户专享优惠").FirstOrDefault().Id).ToList();

            //获取服务价格  有科室获取对应价格 一一对应
            decimal price = _couponService.GetOrderPrice(apttype, 0, docId, language, "");

            //计算最优价格优惠券
            if (response.Data.Where(w => w.ConponDetail.Type == (int)CouponTypeEnum.Free).Any())
            {
                response.Data.Where(w => w.ConponDetail.Type == (int)CouponTypeEnum.Free).FirstOrDefault().IsOptimalCoupon = true;
            }
            else
            {
                decimal contrastprice = 0M;
                int contrastid = 0;
                foreach (var item in response.Data)
                {
                    bool ret = true;
                    var itemprice = _couponService.CalculationPrice(item, price, out ret);
                    if (contrastprice < itemprice)
                    {
                        if (contrastid == 0)
                        {
                            item.IsOptimalCoupon = true;
                        }
                        else
                        {
                            response.Data.Where(w => w.Id == contrastid).FirstOrDefault().IsOptimalCoupon = false;
                        }
                        contrastprice = itemprice;
                        contrastid = item.Id;
                        item.IsOptimalCoupon = true;
                    }
                }
            }

            //修改免费券的抵扣金额
            foreach (var item in response.Data.Where(w => w.ConponDetail.Type == (int)CouponTypeEnum.Free))
            {
                item.Money = price;
            }

            response.Code = 1;
            response.Msg = "成功";
            return response;
        }

        public string Base64StringToFile(string content, string filename, string filetype)
        {
            if (filename.Length > 40)
            {
                string[] ar = Regex.Split(filename, "_20", RegexOptions.IgnoreCase);
                filename = Guid.NewGuid() + ar[1];
            }
            filename = filename + "." + filetype;
            StringBuilder txtstring = new StringBuilder();
            byte[] array = Encoding.ASCII.GetBytes(content);
            MemoryStream stream1 = new MemoryStream(array);
            System.IO.StreamReader sr = new System.IO.StreamReader(stream1, Encoding.Default);
            String line;
            while ((line = sr.ReadLine()) != null)
            {
                txtstring.Append(line.ToString());
            }
            try
            {
                string strbase64 = txtstring.ToString();
                strbase64 = strbase64.Replace(' ', '+');
                System.IO.MemoryStream stream = new System.IO.MemoryStream(Convert.FromBase64String(strbase64));
                var res = UploadHelper.UploadToStream(stream, filename);
                return res;
            }
            catch (System.Exception e)
            {
            }
            return "";
        }

        public string UpdatePatInfo(PatUpdateModel model)
        {
            var log = _verifyCodeLogService.CheckCode(model.PhoneNo, model.Code);
            if (log > 0)
            {
                if (!string.IsNullOrEmpty(model.FirstGuardian))
                {
                    model.Guardian = model.Language == 1 ? model.LastGuardian + model.FirstGuardian : model.FirstGuardian + model.LastGuardian;
                }
                var ret = _pubPatRepository.UpdatePatInfo(model);
                if (ret > 0)
                {
                    return "";
                }
                else
                {
                    return "fail";
                }
            }
            else
            {
                return model.Language == 1 ? "未找到验证码！" : "Invalid Verification Code"; ;
            }
        }

        public int CignaPerfectUserInfo(CignaUserInfo model)
        {
            model.Id = GetBaseUserInfo().ID;
            if (!string.IsNullOrEmpty(model.Birthday))
            {
                model.Birthday = Convert.ToDateTime(model.Birthday).ToString("yyyy-MM-dd");
            }
            if (!string.IsNullOrEmpty(model.FirstName))
            {
                model.PatName = model.FirstName + model.LastName;
            }
            return _pubUserInfoRepository.CignaPerfectUserInfo(model);
        }

        public BaseResponse<LoginInfo> WXLoginInfo(string encryptedData, string iv, string sessionkey, int language)
        {
            BaseResponse<LoginInfo> res = new BaseResponse<LoginInfo>();
            //解析手机号码
            string telPhone = GetPhoneNumber(encryptedData, iv, sessionkey);
            if (string.IsNullOrEmpty(telPhone))
            {
                _logger.LogInformation("微信第二部" + "手机号码解析失败");
                res.Msg = language == 1 ? "手机号码解析失败" : "Mobile phone number resolution failed";
                return res;
            }
            var userToken = GetUserByPhone(telPhone);
            _logger.LogInformation("微信第二部" + userToken);
            if (!string.IsNullOrEmpty(userToken.Token))
            {
                res.Msg = "success";
                res.Code = 1;
                res.Data = userToken;
            }
            return res;
        }

        public BaseResponse<LoginInfo> WXLoginInfoForToken()
        {
            var user = GetUserInfo();
            BaseResponse<LoginInfo> res = new BaseResponse<LoginInfo>();
            var userToken = GetUserByPhone(user.Phone);
            if (!string.IsNullOrEmpty(userToken.Token))
            {
                res.Msg = "success";
                res.Code = 1;
                res.Data = userToken;
            }
            return res;
        }

        public LoginInfo GetUserByPhone(string phone)
        {
            LoginInfo loginInfo = new LoginInfo();
            //查询账号是否存在
            Pub_User_Info pubUserInfo = _pubUserInfoService.SelectByPhone(phone);
            if (pubUserInfo == null)
            {
                pubUserInfo = new Pub_User_Info();
                //不存在，注册
                //判断用户是邮箱注册还是手机注册
                if (phone.IsPhoneNumber())
                {
                    //手机注册
                    pubUserInfo.Phone = phone;
                }
                else
                {
                    //邮箱注册
                    pubUserInfo.Email = phone;
                }
                //注册
                pubUserInfo.Is_Reg = false;
                pubUserInfo.Registration_Source = 6;// RegistrationSource.APPPAT;
                pubUserInfo.Is_Deleted = false;
                pubUserInfo.Create_Time = DateTime.Now;
                pubUserInfo.Is_New = false;
                var id = _pubUserInfoRepository.InsertPubUserInfo(pubUserInfo);
                pubUserInfo.ID = id;
            }

            var isToken = _redisHelper.KeyExistsAsync("user_" + pubUserInfo.ID);
            if (isToken.Result)
            {
                _redisHelper.DeleteAsync("user_" + pubUserInfo.ID);
            }
            string token = GetToken("user_" + pubUserInfo.ID);
            loginInfo.Token = token;
            loginInfo.IsReg = pubUserInfo.Is_Reg;
            loginInfo.Phone = pubUserInfo.Phone;
            loginInfo.PatName = pubUserInfo.Nick_Name;
            loginInfo.HeadImg = pubUserInfo.HeadImg;
            return loginInfo;
        }
        private string GetPhoneNumber(string encryptedData, string IV, string Session_key)
        {
            try
            {
                byte[] encryData = Convert.FromBase64String(encryptedData);  // strToToHexByte(text);
                RijndaelManaged rijndaelCipher = new RijndaelManaged();
                rijndaelCipher.Key = Convert.FromBase64String(Session_key); // Encoding.UTF8.GetBytes(AesKey);
                rijndaelCipher.IV = Convert.FromBase64String(IV);// Encoding.UTF8.GetBytes(AesIV);
                rijndaelCipher.Mode = CipherMode.CBC;
                rijndaelCipher.Padding = PaddingMode.PKCS7;
                ICryptoTransform transform = rijndaelCipher.CreateDecryptor();
                byte[] plainText = transform.TransformFinalBlock(encryData, 0, encryData.Length);
                string result = Encoding.Default.GetString(plainText);
                //动态解析result 成对象
                dynamic model = Newtonsoft.Json.Linq.JToken.Parse(result) as dynamic;
                return model.phoneNumber;

            }
            catch (System.Exception ex)
            {
                //MessageBox.Show(ex.Message);
                return "";

            }
        }

        public PatUserInfoResp SelectByimId()
        {
            var userId = GetBaseUserInfo().ID;
            PatUserInfoResp result = _pubUserInfoRepository.SelectByImId(userId, userId.ToString());
            if (result != null && result.UserType == 1)
            {
                OutMapDocPat mapDocPat = _dicDoctorRepository.SelectByDocIdWithPatId(userId, result.Id);
                result.IsBiding = (mapDocPat != null);
            }
            return result;
        }

        public async Task<BaseResponse<dynamic>> GetRelationship()
        {
            BaseResponse<dynamic> res = new BaseResponse<dynamic>();
            var list = _pubUserInfoRepository.GetRelationship();
            res.Data = list;
            res.Code = 1;
            res.Msg = "cg";
            return res;
        }

        public async Task<BaseResponse<dynamic>> GetContactway()
        {
            BaseResponse<dynamic> res = new BaseResponse<dynamic>();
            var list = _pubUserInfoRepository.GetContactway();
            res.Data = list;
            res.Code = 1;
            res.Msg = "cg";
            return res;
        }
        public async Task<BaseResponse<dynamic>> GetHowknow()
        {
            BaseResponse<dynamic> res = new BaseResponse<dynamic>();
            var list = await _pubUserInfoRepository.GetHowknow();
            res.Data = list;
            res.Code = 1;
            res.Msg = "cg";
            return res;
        }


        public string AddNewPat(NewPatModel model)
        {
            _logger.LogInformation("新患者录入AddNewPat: " + model?.ToJson());
            model.Birthday = Convert.ToDateTime(model.Birthday).ToString("yyyy-MM-dd");
            var tcPats = _tcService.GetPat(model.PhoneNo.Trim(), model.Birthday);
            if (tcPats != null && tcPats.Count > 0)
            {
                var tcPat = tcPats.Find(p => p.PAPERName == model.LastName && p.PAPERName2 == model.FirstName);
                if (tcPat != null)
                {//TC有此人 让他去编辑
                    return model.Language == 1 ? "该患者已存在，请联系前台！" : "Patient already existed,  please contact front desk";
                }
            }
            Dictionary<int, string> dicFileType = GetFileFileType(model);
            //把患者推TC
            var quest = TransTCNewPat(model);
            var tcResId = _tcService.AddTcNewPat(quest);
            if (tcResId > 0)
            {
                tcPats = _tcService.GetPat(model.PhoneNo.Trim(), model.Birthday);
                var tcpat = tcPats.Find(p => p.PAPERName == model.LastName && p.PAPERName2 == model.FirstName);
                //传文件
                List<int> ids = GetFileIds(model);
                SendFileToTc(ids, tcpat.PAPERRowId, dicFileType);
                //打标签
                _tcService.UpdatePatientPortalLink("", tcpat.PAPMINo, true);
                var ppPat = _pubPatRepository.GetPatByCondition(model.PhoneNo, model.LastName, model.FirstName);
                if (ppPat == null)
                {//新增患者
                    Pub_Pat_Info pat = TransForm(model);
                    pat.Pat_ID = tcpat.PAPERRowId;
                    pat.Pat_MRN = tcpat.PAPMINo;
                    pat = _fileService.GetFileContentAdd<Pub_Pat_Info>(pat);
                    _pubPatRepository.InsertPubPatInfo(pat);
                }
                else
                {//编辑现有患者 (走这的可能不大)
                    ppPat = TransHasForm(ppPat, model);
                    ppPat.Pat_MRN = tcpat.PAPMINo;
                    ppPat.Pat_ID = tcpat.PAPERRowId;
                    _logger.LogInformation("录入TC新患者,更新PP患者信息: " + ppPat.ToJson());
                    _pubPatRepository.UpdatePubPatInfo(ppPat, 1);
                }

                return "";
            }
            else
            {
                return model.Language == 1 ? "TC操作录入失败" : "TC operation entry failed";
            }
        }

        private List<int> GetTCNoFileId(NewPatModel model)
        {
            List<int> ids = new List<int>();
            var pat = _pubPatRepository.SelectByMrn(model.PatMrn);//绑定就诊人
            if (pat?.IDCardUrlFront != model.IDCardUrlFront)
            {
                var burl = JsonConvert.DeserializeObject<FileContenModel>(model.IDCardUrlFront);
                if (burl != null)
                {
                    var id = burl.Content.FirstOrDefault()?.Id;
                    if (id != null)
                    {
                        ids.Add(id.ToInt());
                    }
                }
            }
            if (pat?.IDCardUrlBack != model.IDCardUrlBack)
            {
                var burl = JsonConvert.DeserializeObject<FileContenModel>(model.IDCardUrlBack);
                if (burl != null)
                {
                    var id = burl.Content.FirstOrDefault()?.Id;
                    if (id != null)
                    {
                        ids.Add(id.ToInt());
                    }
                }
            }

            if (pat?.InsuranceCardUrl != model.InsuranceCardUrl)
            {
                var burl = JsonConvert.DeserializeObject<FileContenModel>(model.InsuranceCardUrl);
                if (burl != null)
                {
                    foreach (var item in burl.Content)
                    {
                        var id = item?.Id;
                        if (id != null)
                        {
                            ids.Add(id.ToInt());
                        }
                    }
                }
            }
            return ids;
        }

        private List<int> GetFileIds(NewPatModel model)
        {
            List<int> list = new List<int>();
            if (!string.IsNullOrEmpty(model.IDCardUrlFront))
            {
                try
                {
                    list.Add(Convert.ToInt32(model.IDCardUrlFront));
                }
                catch (System.Exception)
                {
                }
            }
            if (!string.IsNullOrEmpty(model.IDCardUrlBack))
            {
                try
                {
                    list.Add(Convert.ToInt32(model.IDCardUrlBack));
                }
                catch (System.Exception)
                {
                }
            }
            if (!string.IsNullOrEmpty(model.InsuranceCardUrl))
            {
                try
                {
                    if (model.InsuranceCardUrl.Contains(","))
                    {
                        var ids = model.InsuranceCardUrl.Split(',');
                        foreach (var item in ids)
                        {
                            if (!string.IsNullOrEmpty(item))
                            {
                                list.Add(Convert.ToInt32(item));
                            }
                        }
                    }
                    else
                    {
                        list.Add(Convert.ToInt32(model.InsuranceCardUrl));
                    }

                }
                catch (System.Exception)
                {
                }
            }
            return list;
        }

        private void SendFileToTc(List<int> ids, string rowId, Dictionary<int, string> dicFileType)
        {
            if (ids == null || ids.Count == 0)
            {
                return;
            }
            var files = _fileRepository.GetFilesForContent(ids);
            if (files != null && files.Count > 0)
            {
                foreach (var item in files)
                {
                    var pName = item.FileUrl.Split('\\')?.LastOrDefault();
                    var remark = dicFileType[item.Id];
                    var res = _tcService.CustomCRMPictures(rowId, string.IsNullOrEmpty(remark) ? "新患者录入图片" : remark, pName, item.Content);
                    _logger.LogInformation("SendFileToTc:" + item.Id + "   reb:" + res);
                }
            }
        }

        private CustomCRMPAPerson TransTCRequest(NewPatModel pat)
        {
            CustomCRMPAPerson person = new CustomCRMPAPerson();
            person.PAPERCityCodeDR = "上海市";//小P让改的
            person.PAPERStName = pat.Province + "," + pat.City + "," + pat.LocalAddress;
            person.PAPERDob = pat.Birthday;
            person.PAPEREmail = pat.Email;

            if (!string.IsNullOrEmpty(pat.HowKnowCode))
            {
                person.PAPERHowDidYouLearnUsDR = pat.HowKnowCode;
            }
            else
            {
                var howKnowList = _pubUserInfoRepository.GetHowknow().Result;
                person.PAPERHowDidYouLearnUsDR = howKnowList.Find(p => p.Id == pat.HowKnow).Code;
            }

            person.PAPERID = pat.CardId;
            person.PAPERMobPhone = pat.PhoneNo;
            person.PAPERName = pat.LastName;
            person.PAPERName2 = pat.FirstName;
            person.PAPERName3 = pat.PatName;
            person.PAPERNationDR = _cnBaseDistrictRepository.GetTcNationAll(pat.NationalityId)?.FirstOrDefault()?.TcCode;
            person.PAPERNokCTRLTDR = _pubUserInfoRepository.GetRelationship().Result.Find(p => p.Id == pat.EmergencyRelation)?.Code;
            person.PAPERNokName = pat.EmergencyName;
            person.PAPERNokPhone = pat.EmergencyPhone;
            person.PAPERPreferredContactMethod = _pubUserInfoRepository.GetContactway().Result.Find(p => p.Id == pat.ContactWay)?.Code;
            person.PAPERRowId = pat.RowId;
            person.PAPERSexDR = pat.Gender == 0 ? "F" : "M";
            var tcPatInfo = _tcService.PAPersonEditOpen(pat.RowId);
            if (string.IsNullOrEmpty(tcPatInfo?.PAPERRemark))
            {
                person.PAPERRemark = new List<PAPERRemark>();
            }
            else
            {
                string[] arr = tcPatInfo.PAPERRemark.Split(new string[] { "\r\n" }, StringSplitOptions.None);
                person.PAPERRemark = new List<PAPERRemark>();
                foreach (var item in arr)
                {
                    person.PAPERRemark.Add(new PAPERRemark { PAPERRemarkItem = item });
                }
            }
            if (pat.PayType == 2 && string.IsNullOrEmpty(pat.InsuranceCardUrl))
            {
                person.PAPERRemark.Add(new PAPERRemark { PAPERRemarkItem = "保险照片未上传" });
            }
            person.PAPERRemark.Add(new PAPERRemark { PAPERRemarkItem = "APP自动完善信息" });
            person.PAPERRemark.Add(new PAPERRemark { PAPERRemarkItem = "患者证件已上传至Patient document" });
            return person;
        }

        private TcNewPatModel TransTCNewPat(NewPatModel pat)
        {
            TcNewPatModel person = new TcNewPatModel();
            person.City = "上海市";//小P说写死的
            person.Address = pat.Province + "," + pat.City + "," + pat.LocalAddress;
            person.Birthday = pat.Birthday;
            person.Email = pat.Email;
            var howKnowList = _pubUserInfoRepository.GetHowknow().Result;
            person.HowKnowCode = howKnowList.Find(p => p.Id == pat.HowKnow).Code;
            person.CardId = pat.CardId;
            person.PhoneNo = pat.PhoneNo;
            person.LastName = pat.LastName;
            person.FirstName = pat.FirstName;
            person.Nationality = _cnBaseDistrictRepository.GetTcNationAll(pat.NationalityId)?.FirstOrDefault()?.TcCode;
            person.EmergencyRelationCode = _pubUserInfoRepository.GetRelationship().Result.Find(p => p.Id == pat.EmergencyRelation)?.Code;
            person.EmergencyName = pat.EmergencyName;
            person.EmergencyPhone = pat.EmergencyPhone;
            person.ContactWayCode = _pubUserInfoRepository.GetContactway().Result.Find(p => p.Id == pat.ContactWay)?.Code;
            person.Gender = pat.Gender;
            if (pat.PayType == 2 && string.IsNullOrEmpty(pat.InsuranceCardUrl))
            {
                person.Remark = "保险照片未上传";
            }
            return person;
        }

        private Pub_Pat_Info TransHasForm(Pub_Pat_Info pat, NewPatModel model)
        {
            pat.Birthday = model.Birthday;
            pat.Card_ID = model.CardId;
            pat.Card_Type = model.CardType;
            pat.Certificate_Number = model.CertificateNumber;
            pat.Province = model.Province;
            pat.City = model.City;
            pat.CityId = model.CityId;
            pat.ContactWay = model.ContactWay;
            pat.Document_Type = model.DocumentType;
            pat.Email = model.Email;
            pat.EmergencyName = model.EmergencyName;
            pat.EmergencyPhone = model.EmergencyPhone;
            pat.EmergencyRelation = model.EmergencyRelation + "";
            pat.First_Guardian = model.FirstGuardian;
            pat.First_Name = model.FirstName;
            pat.Gender = model.Gender;
            pat.Guardian = model.Language == 1 ? model.LastGuardian + model.FirstGuardian : model.FirstGuardian + model.LastGuardian;
            pat.HowKnow = model.HowKnow;
            pat.IDCardUrlBack = model.IDCardUrlBack;
            pat.IDCardUrlFront = model.IDCardUrlFront;
            pat.Id_Number = model.CardType == 1 ? model.CardId : "";
            pat.Last_Guardian = model.LastGuardian;
            pat.Last_Name = model.LastName;
            pat.LocalAddress = model.LocalAddress;
            pat.Nationality = _cnBaseDistrictRepository.GetTcNationAll(model.NationalityId)?.FirstOrDefault()?.Name;
            pat.Pat_Name = model.Language == 1 ? model.LastName + model.FirstName : model.FirstName + model.LastName;
            //pat.Pat_Source = 4;
            pat.Phone_NO = model.PhoneNo;
            pat.InsuranceCardUrl = model.InsuranceCardUrl;
            pat.PayType = model.PayType;
            pat.ContactValue = model.Chat;
            return pat;
        }

        private Pub_Pat_Info TransForm(NewPatModel model)
        {
            Pub_Pat_Info pat = new Pub_Pat_Info();
            pat.Id = model.Id;
            pat.Birthday = model.Birthday;
            pat.Card_ID = model.CardId;
            pat.Card_Type = model.CardType;
            pat.Certificate_Number = model.CertificateNumber;
            //var city = _cnBaseDistrictRepository.GetCityById(model.CityId, model.Language);
            //if (city != null)
            //{
            //    pat.City = city.Name;
            //}
            //else
            //{
            //    pat.City = model.CityId+"";
            //}
            pat.Province = model.Province;
            pat.City = model.City;
            pat.CityId = model.CityId;
            pat.ContactWay = model.ContactWay;
            pat.Document_Type = model.DocumentType;
            pat.Email = model.Email;
            pat.EmergencyName = model.EmergencyName;
            pat.EmergencyPhone = model.EmergencyPhone;
            pat.EmergencyRelation = model.EmergencyRelation + "";
            pat.First_Guardian = model.FirstGuardian;
            pat.First_Name = model.FirstName;
            pat.Gender = model.Gender;
            pat.Guardian = model.Language == 1 ? model.LastGuardian + model.FirstGuardian : model.FirstGuardian + model.LastGuardian;
            pat.HowKnow = model.HowKnow;
            pat.IDCardUrlBack = model.IDCardUrlBack;
            pat.IDCardUrlFront = model.IDCardUrlFront;
            pat.Id_Number = model.CardType == 1 ? model.CardId : "";
            pat.Last_Guardian = model.LastGuardian;
            pat.Last_Name = model.LastName;
            pat.LocalAddress = model.LocalAddress;
            //var tcNationList = _cnBaseDistrictRepository.GetTcNationAll();
            pat.Nationality = _cnBaseDistrictRepository.GetTcNationAll(model.NationalityId)?.FirstOrDefault()?.Name;
            pat.Pat_Name = model.Language == 1 ? model.LastName + model.FirstName : model.FirstName + model.LastName;
            pat.Pat_Source = 4;
            pat.Phone_NO = model.PhoneNo;
            pat.PayType = model.PayType;
            pat.InsuranceCardUrl = model.InsuranceCardUrl;
            pat.ContactValue = model.Chat;
            return pat;
        }

        public Dictionary<int, string> GetFileFileType(NewPatModel model)
        {
            Dictionary<int, string> dic = new Dictionary<int, string>();
            if (!string.IsNullOrEmpty(model.IDCardUrlFront))
            {
                dic.Add(model.IDCardUrlFront.ToInt(), model.CardId);
            }
            if (!string.IsNullOrEmpty(model.IDCardUrlBack))
            {
                dic.Add(model.IDCardUrlBack.ToInt(), model.CardId);
            }
            if (!string.IsNullOrEmpty(model.InsuranceCardUrl))
            {
                if (model.InsuranceCardUrl.Contains(","))
                {
                    var arr = model.InsuranceCardUrl.Split(',');
                    foreach (var item in arr)
                    {
                        if (!string.IsNullOrEmpty(item.Trim()))
                        {
                            dic.Add(item.ToInt(), "Insurance");
                        }
                    }
                }
                else
                {
                    dic.Add(model.InsuranceCardUrl.ToInt(), "Insurance");
                }
            }
            return dic;
        }

        public string UpdateNewPat(NewPatModel model)
        {
            _logger.LogInformation("新患者录入UpdateNewPat: " + model?.ToJson());
            model.Birthday = Convert.ToDateTime(model.Birthday).ToString("yyyy-MM-dd");
            Dictionary<int, string> dicFileType = GetFileFileType(model);
            model = _fileService.GetFileContentAdd<NewPatModel>(model);
            var ids = GetTCNoFileId(model);
            var tcPat = _tcService.GetPatient(model.PatMrn.Trim(), "", "")?.FirstOrDefault();
            var tcPatInfo = _tcService.PAPersonEditOpen(tcPat.PAPERRowId.ToInt());
            if (tcPat != null)
            {
                //把患者更新TC
                model.PatName = tcPat.PAPERName3;
                if (model.RowId == 0)
                {
                    model.RowId = Convert.ToInt32(tcPat.PAPERRowId);
                }
                var quest = TransTCRequest(model);
                if (tcPatInfo != null)
                {
                    quest.PAPERCityCodeDR = tcPatInfo.CTCITDesc;
                }
                var tcRes = _tcService.CustomCRMPAPerson(quest);
                if (tcRes)
                {
                    //传文件
                    SendFileToTc(ids, model.RowId + "", dicFileType);
                    var ppPat1 = _pubPatRepository.SelectByMrn(model.PatMrn);//绑定就诊人
                    var ppPat2 = _pubPatRepository.GetPatByCondition(model.PhoneNo, model.LastName, model.FirstName);//临时就诊人
                    if (ppPat1 == null && ppPat2 == null)
                    {
                        //小红: TC有，PP无： 更新TC患者信息；PP新增患者并记录PID，PP患者不与用户关联
                        Pub_Pat_Info pat = TransForm(model);
                        pat.Pat_ID = tcPat.PAPERRowId;
                        pat.Pat_MRN = tcPat.PAPMINo;
                        pat.Mrn = tcPat.MRN;
                        _pubPatRepository.InsertPubPatInfo(pat);
                    }
                    else
                    {
                        //小红: TC有、PP有：更新TC以及PP的患者信息，PP不改变用户关系和绑定关系
                        Pub_Pat_Info ppPat = null;
                        if (ppPat1 != null)
                        {
                            ppPat = ppPat1;
                        }
                        else
                        {
                            ppPat = ppPat2;
                            ppPat.Pat_ID = tcPat.PAPERRowId;
                            ppPat.Pat_MRN = tcPat.PAPMINo;
                            ppPat.Mrn = tcPat.MRN;
                        }
                        Pub_Pat_Info pat = TransHasForm(ppPat, model);
                        _pubPatRepository.UpdatePubPatInfo(pat, 1);
                    }

                    return "";
                }
                else
                {
                    return model.Language == 1 ? "TC操作失败" : "TC operation failed";
                }
            }
            else
            {// TC无 就直接 让他去新增
                return model.Language == 1 ? "TC找不到该患者" : "TC cannot find the patient";
            }
        }

        private object lockflag = new object();
        public List<TcPat> GetTcPatByPhone(string phone)
        {
            ConcurrentBag<TcPat> list = new ConcurrentBag<TcPat>();
            List<PAPerson> patList = _tcService.GetPat(phone.Trim(), string.Empty);
            if (patList != null && patList.Count > 0)
            {
                var pats = _pubPatRepository.SelectPatsByMrn(patList.Select(p => p.PAPMINo).ToList());
                var quests = _pubQuestDataRepository.GetPatsQuest(pats.Select(p => p.Id).ToList());
                var apts = _outAptInfoRepository.GetPhysicalAptInfos(pats.Select(p => p.Id).ToList());
                TcPat tcPat = null;
                Parallel.ForEach(patList, (item) =>
                {
                    lock (lockflag)
                    {
                        tcPat = new TcPat();
                        tcPat.PatMrn = item.PAPMINo;
                        tcPat.RowId = item.PAPERRowId.ToInt();
                        tcPat.Gender = item.PAPERSex.ToLower().Contains("female") ? 0 : 1;
                        var lastName = item.PAPERName;
                        if (!string.IsNullOrEmpty(lastName) && !lastName.IsChinese())
                        {
                            tcPat.PatName = item.PAPERName2 + " " + lastName;
                        }
                        else
                        {
                            tcPat.PatName = lastName + item.PAPERName2;
                        }
                        //var pat = _pubPatRepository.SelectByMrn(tcPat.PatMrn);
                        var pat = pats.Find(p => p.Pat_MRN == tcPat.PatMrn);
                        if (pat != null)
                        {
                            tcPat.Phone = pat.Phone_NO;
                            if (pat.ContactWay > 0 && !string.IsNullOrEmpty(pat.IDCardUrlFront))
                            {
                                tcPat.IsPerf = true;
                            }
                            var apt = apts.Find(p => p.Pat_Id == pat.Id);
                            if (apt != null)
                            {
                                var quest = quests.FindAll(p => p.PatId == pat.Id && p.AptId == apt.Id);
                                if (quest?.Count > 0)
                                {
                                    tcPat.PhysicalId = quest.FirstOrDefault().InfoId;
                                }
                                else
                                {
                                    tcPat.OutAptId = apt.Id;
                                    tcPat.PhysicalId = 0;
                                }
                            }
                            else
                            {
                                tcPat.PhysicalId = -1;
                            }
                        }
                        //TODO 需脱敏
                        tcPat.PatName = tcPat.PatName.NameDesensitization();
                        tcPat.Phone = tcPat.Phone.PhoneDesensitization();
                        list.Add(tcPat);
                    }
                });
            }
            //Parallel.ForEach(list, (item) =>
            //{
            //    //TODO 需脱敏
            //    item.PatName = item.PatName.NameDesensitization();
            //    item.Phone = item.Phone.PhoneDesensitization();
            //});
            return list.ToList().OrderBy(p => p.RowId).ToList();
        }

        public NewPatModel GetNewPat(string mrn)
        {
            var patInfo = _pubPatRepository.SelectByMrn(mrn);

            if (patInfo == null)
            {
                patInfo = _pubPatRepository.SelectAllByMrn(mrn);
            }

            var tcPat = _tcService.GetPatient(mrn, "", "")?.FirstOrDefault();
            if (tcPat == null)
            {
                return new NewPatModel() { Language = 3 };
            }
            if (patInfo == null)
            {
                patInfo = new Pub_Pat_Info();
            }
            var tcPatInfo = _tcService.PAPersonEditOpen(tcPat.PAPERRowId.ToInt());
            NewPatModel model = new NewPatModel();
            model.Mrn = tcPat.MRN;
            model.PatMrn = tcPat.PAPMINo;
            model.Birthday = tcPat.PAPERDob.ToString("yyyy/MM/dd");
            model.CardId = tcPat.PAPERID;
            model.CardType = patInfo.Card_Type;
            model.CardValidity = patInfo.CardValidity;
            model.IsPerfectGuardian = patInfo.EmergencyPhone != null || patInfo.EmergencyName != null;
            //这个字段传给tc的格式是“省+,+市+,+详细地址”，例如：“云南省,丽江市,XX区XXX号”，如果能正常解析出来，就使用这个字段里的“市”
            if (!string.IsNullOrEmpty(tcPatInfo.PAPERStName))
            {
                var tcAddress = tcPatInfo.PAPERStName.Split(',').ToList();
                if (tcAddress.Count == 3)
                {
                    model.City = tcAddress[1];
                }
            }
            else
            {
                model.City = string.IsNullOrEmpty(tcPatInfo.CTCITDesc) ? tcPatInfo.PAPERCityCode : tcPatInfo.CTCITDesc;
            }
            if (string.IsNullOrEmpty(model.City))
            {
                model.City = _cnBaseDistrictRepository.GetCityById(patInfo.CityId, patInfo.Card_Type == 1 ? 1 : 0)?.Name;
            }

            model.CityId = patInfo.CityId;

            var way = _pubUserInfoRepository.GetContactway().Result.Find(p => p.TcShow == tcPatInfo.PAPERPreferredContactMethod);
            if (way != null)
            {
                model.ContactWay = way.Id;
                model.Chat = patInfo.ContactValue;
            }
            model.DocumentType = patInfo.Document_Type;
            model.Email = tcPatInfo.PAPEREmail;
            model.EmergencyName = tcPatInfo.PAPERNokName;
            model.EmergencyPhone = tcPatInfo.PAPERNokPhone;
            var relation = _pubUserInfoRepository.GetRelationship().Result.Find(p => p.TcShow == tcPatInfo.CTRLTDesc);
            if (relation != null)
            {
                model.EmergencyRelation = relation.Id;
            }

            model.GuardianPhone = patInfo.GuardianPhone;
            model.FirstGuardian = patInfo.First_Guardian;
            model.FirstName = tcPat.PAPERName2;
            model.CertificateNumber = patInfo.Certificate_Number;
            model.Gender = tcPat.PAPERSex.ToLower().Contains("female") ? 0 : 1;
            model.Guardian = patInfo.Guardian;
            var howKnow = _pubUserInfoRepository.GetHowknow().Result.Find(p => p.TcShow == tcPatInfo.ASSISDesc);
            if (howKnow != null)
            {
                model.HowKnow = howKnow.Id;
            }
            if (howKnow == null && !string.IsNullOrEmpty(tcPatInfo.ASSISDesc))
            {
                model.HowKnowCode = tcPatInfo.ASSISDesc;
            }
            model.Id = patInfo.Id;
            model.IDCardUrlBack = patInfo.IDCardUrlBack;
            model.IDCardUrlFront = patInfo.IDCardUrlFront;
            model.LastGuardian = patInfo.Last_Guardian;
            model.LastName = tcPat.PAPERName;
            model.PatName = tcPat.PAPERName + tcPat.PAPERName2;
            var address = tcPatInfo.PAPERStName;
            if (!string.IsNullOrEmpty(address) && address.Contains(","))
            {
                model.LocalAddress = address.Split(',').LastOrDefault();
            }
            else
            {
                model.LocalAddress = address;
            }
            var nations = _cnBaseDistrictRepository.GetTcNationAll();
            var nation = nations.Find(p => p.Name == tcPatInfo.CTNATDesc);
            if (nation != null)
            {
                model.NationalityId = nation.Id;
            }
            else
            {
                nation = nations.Find(p => p.Name == patInfo.Nationality);
                if (nation != null)
                {
                    model.NationalityId = nation.Id;
                }
            }
            model.PhoneNo = tcPat.PAPERMobPhone;
            model.RowId = tcPat.PAPERRowId.ToInt();
            model.Province = patInfo.Province;
            var pro = _cnBaseDistrictRepository.GetProvincesByCityId(model.CityId);
            if (pro != null)
            {
                model.ProvinceId = Convert.ToInt32(pro.ID);
            }
            model.PayType = patInfo.PayType;
            model.InsuranceCardUrl = patInfo.InsuranceCardUrl;
            model = _fileService.GetFileContentSelect<NewPatModel>(model);

            //体检获取信息
            var pat = _pubPatRepository.SelectByMrn(mrn);
            if (pat != null)
            {
                if (pat.HowKnow > 0 || !string.IsNullOrEmpty(pat.IDCardUrlFront))
                {
                    model.IsPerf = true;
                }
                var quests = _pubQuestDataRepository.GetPatQuest(pat.Id);
                if (quests?.Count > 0)
                {
                    model.PhysicalId = quests.FirstOrDefault().InfoId;
                }
                else
                {
                    var apt = _outAptInfoRepository.GetPhysicalAptInfo(pat.Id);
                    if (apt != null && apt.Count > 0)
                    {
                        model.PhysicalId = 0;
                        model.OutAptId = apt.OrderBy(p => p.Apt_Time).LastOrDefault().Id;
                    }
                    else
                    {
                        model.PhysicalId = -1;
                    }

                }

                //查询家庭成员关系
                var maps = _pubMapUserPatRepository.GetBind(patInfo.Id);
                if (maps.Any())
                {
                    var map = maps.FirstOrDefault(x => x.User_ID == GetBaseUserInfo()?.ID && x.Pat_ID == pat.Id);
                    model.Ties = map?.Ties ?? default;
                }
            }

            #region 头像显示类型：1-男；2-女；3-小于14岁

            var now = DateTime.Now;
            var age = now.Year - tcPat.PAPERDob.Year;
            if (now.Month < tcPat.PAPERDob.Month || now.Month == tcPat.PAPERDob.Month && now.Day < tcPat.PAPERDob.Day)
            {
                age -= 1;
            }

            if (age > 14)
            {
                model.HeadImgType = tcPat.PAPERSex.Contains("男") ? 1 : 2;
            }
            else
            {
                model.HeadImgType = 3;
            }

            #endregion

            return model;
        }

        public BaseResponse<ReceptionInfo> WXReceptionLogin(string account, string password, string phone, string code)
        {
            BaseResponse<ReceptionInfo> res = new BaseResponse<ReceptionInfo>();
            if (string.IsNullOrEmpty(phone))
            {

                var hashPassword = Common.GetMD5(password);
                var acc = _pubUserInfoRepository.GetReceptionInfoByAcc(account, hashPassword);
                if (acc != null)
                {
                    if (!acc.Platform.Contains("2"))
                    {
                        res.Msg = "该帐号无法登陆小程序";
                        res.Code = 0;
                        return res;
                    }
                    ReceptionInfo info = new ReceptionInfo() { NickName = acc.NickName };
                    res.Code = 1;
                    res.Data = info;
                    res.Msg = "cg";
                }
                else
                {
                    res.Msg = "帐号或密码不正确";
                    res.Code = 0;
                }

            }
            else
            {
                var log = _verifyCodeLogService.CheckCode(phone, code);
                if (log > 0)
                {
                    var acc = _pubUserInfoRepository.GetReceptionInfoByPhone(phone);
                    if (acc != null)
                    {
                        if (!acc.Platform.Contains("2"))
                        {
                            res.Msg = "该帐号无法登陆小程序";
                            res.Code = 0;
                            return res;
                        }
                        ReceptionInfo info = new ReceptionInfo() { NickName = acc.NickName };
                        res.Code = 1;
                        res.Data = info;
                        res.Msg = "cg";
                    }
                    else
                    {
                        res.Msg = "该手机未绑定帐号,请联系管理员";
                        res.Code = 0;
                    }
                }
                else
                {
                    res.Msg = "验证码不正确";
                    res.Code = 0;
                }
            }
            return res;
        }

        public string GetReceptionCode(string type)
        {
            var code = Guid.NewGuid().ToString().Replace("-", ""); ;
            var address = _appConfigurtaion.GetSetViewDomain;
            if (type == "add")
            {
                address += "PerfectInformation?type=add";
                _pubUserInfoRepository.InsertReceptionCode(code);
            }
            if (type == "update")
            {
                address += "PerfectInformation?type=update";
            }
            var pic = Common.MakeQrCode(address + "&v=" + code);

            return "data:image/png;base64," + pic;
        }

        public Pub_ReceptionCode GetPubReceptionCode(string code)
        {
            var rCode = _pubUserInfoRepository.GetPubReceptionCode(code);
            return rCode;
        }

        public int InvalidReceptionCode(string code)
        {
            return _pubUserInfoRepository.InvalidReceptionCode(code);
        }

        public bool CheckPatPhone(string account, string patMrn)
        {
            var pat = _pubPatRepository.SelectByMrn(patMrn);
            if (pat != null)
            {
                return pat.Phone_NO == account;
            }
            return false;
        }
        public int UserComplaint(ComplaintModel model)
        {
            Pub_Complaint userComplaintInfo = new Pub_Complaint();
            userComplaintInfo.ComplaintContent = model.ComplaintContent;
            userComplaintInfo.DocIMID = model.DocIMID;
            userComplaintInfo.UserIMID = model.UserIMID;
            return _pubUserInfoRepository.InsertPubComplaint(userComplaintInfo);
        }

        /// <summary>
        /// 绑定有赞openid，发放“健康俱乐部”权益卡
        /// </summary>
        /// <param name="openId"></param>
        /// <returns></returns>
        public async Task<string> YouZanMatchUserOpenId(string openId)
        {
            _logger.LogInformation("健康俱乐部YouZanMatchUserOpenId:" + openId);

            var youZanCustomerInfoResponse = GetCustomer(openId);
            if (youZanCustomerInfoResponse?.data != null)
            {
                if (GetBaseUserInfo().YZOpenId != openId)
                {
                    //将有赞openid绑定到用户
                    await _pubUserInfoRepository.YouZanMatchUserOpenId(GetBaseUserInfo().ID, openId);
                }

                var isHaveCard = youZanCustomerInfoResponse.data.cards.Exists(x => x.id == YouZanConfig.HealthClubCardId);
                if (GetBaseUserInfo().YZOpenId == openId && isHaveCard)
                {
                    return null;
                }

                return isHaveCard ? null : SendCard(openId);
            }

            if (string.IsNullOrEmpty(GetBaseUserInfo().YZOpenId))
            {
                //将有赞openid绑定到用户
                await _pubUserInfoRepository.YouZanMatchUserOpenId(GetBaseUserInfo().ID, openId);
            }

            _logger.LogInformation($"获取有赞客户基础信息失败，{nameof(YouZanMatchUserOpenId)},openid:{openId},{youZanCustomerInfoResponse?.message}");

            await Task.Delay(1000);

            return SendCard(openId);
        }

        /// <summary>
        /// 查询有赞客户详细信息
        /// </summary>
        /// <param name="yzOpenId">有赞openid</param>
        /// <returns></returns>
        private YouZanResponse<CustomerInfo> GetCustomer(string yzOpenId)
        {
            var getYzCustomerInfoRequest = new CustomerGetRequest
            {
                yz_open_id = yzOpenId,
                fields = "user_base,tags,benefit_cards,benefit_level,benefit_rights,credit,behavior,giftcard,prepaid,coupon,level"
            };
            var yzCustomerInfo = _youZanService.GetYouZanCustomer(getYzCustomerInfoRequest);

            return yzCustomerInfo;
        }

        /// <summary>
        /// 发放权益卡
        /// </summary>
        /// <param name="yzOpenId"></param>
        /// <returns></returns>
        private string SendCard(string yzOpenId)
        {
            //如果没有权益卡，获取权益卡并发放给用户
            var yzGetCardRequest = new GetCard
            {
                page = 1
            };
            var cardsResponse = _youZanService.GetYouZanCard(yzGetCardRequest);
            if (cardsResponse == null || cardsResponse.data.total == 0 || !cardsResponse.data.items.Exists(x => x.card_alias == YouZanConfig.HealthClubCardAlias))
            {
                _logger.LogInformation($"获取有赞权益卡信息失败，{nameof(YouZanMatchUserOpenId)},openid:{yzOpenId},{cardsResponse?.message}");
                return "获取有赞权益卡信息失败";
            }

            var senCardRequest = new SendCardRequest
            {
                @params = new SendCard
                {
                    card_alias = YouZanConfig.HealthClubCardAlias,
                    user = new UserAccount
                    {
                        account_id = yzOpenId,
                        account_type = 5
                    }
                }
            };

            var sendCardResponse = _youZanService.SendYouZanCard(senCardRequest);

            if (sendCardResponse != null)
            {
                ChangeUserPayStatus();
                return null;
            }

            _logger.LogInformation($"有赞权益卡发放失败，{nameof(YouZanMatchUserOpenId)},openid:{yzOpenId}");
            return "有赞权益卡发放失败";
        }

        /// <summary>
        /// 更新用户观看状态
        /// </summary>
        public void ChangeUserPayStatus()
        {
            var user = _pubUserInfoRepository.SelectByPrimaryKey(GetBaseUserInfo().ID);

            if (user == null)
            {
                return;
            }

            if (user.YZWatchMode != 2)
            {
                _pubUserInfoRepository.YouZanRecordWatchMode(user.ID, 1);
            }
        }

        #region 绑定就诊人

        /// <summary>
        /// 获取家庭成员列表
        /// </summary>
        /// <returns></returns>
        public async Task<BaseResponse<List<PatientModel>>> GetFamilyListAsync()
        {
            var userId = GetBaseUserInfo().ID;

            var familyList = await _pubUserInfoRepository.GetFamilyListByUserIdAsync(userId);

            if (!familyList.Any())
            {
                return new BaseResponse<List<PatientModel>>
                {
                    Code = 1,
                    Msg = "操作成功",
                    Data = familyList
                };
            }

            var authorizationInfos = await _pubAuthorizationRepository.GetUserAuthorizationsByPatsAsync(userId, familyList.Select(x => x.PatId).ToList());

            familyList.ForEach(patient =>
            {
                //小程序家庭成员列表需要脱敏后的姓名、手机号字段
                patient.NameDesensitized = patient.Name.Desensitization();
                patient.PhoneNoDesensitized = patient.PhoneNo.HideSensitiveInfo(3, 4);

                //头像显示类型：1-男；2-女；3-小于14岁
                if (patient.Age > 14)
                {
                    patient.HeadImgType = patient.Gender == 1 ? 1 : 2;
                }
                else
                {
                    patient.HeadImgType = 3;
                }

                //本人和未成年不需要授权
                if (patient.Ties == 1 || patient.Age < 18)
                {
                    patient.AuthorizationStatus = 3;
                    patient.AuthorizationDetailIds = "1,2,3,4";
                }
                else
                {
                    var auth = authorizationInfos.Where(x => x.PatId == patient.PatId)
                                                 .OrderByDescending(x => x.AuthorizationValidity)
                                                 .FirstOrDefault();

                    if (auth == null)
                    {
                        return;
                    }

                    var now = DateTime.Now;
                    patient.AuthorizationStatus = auth.Status == 3 && !auth.IsForever && auth.AuthorizationValidity < now ? 5 : auth.Status;
                    patient.AuthorizationDetailIds = auth.Status == 3 && (auth.IsForever || auth.AuthorizationValidity > now) ? auth.ApplyDetailIds : default;
                }
            });

            var mySelf = familyList.FirstOrDefault(x => x.Ties == 1);

            if (mySelf != null)
            {
                //“本人”排第一位
                familyList.Remove(mySelf);
                familyList.Insert(0, mySelf);
            }

            return new BaseResponse<List<PatientModel>>
            {
                Code = 1,
                Msg = "操作成功",
                Data = familyList
            };
        }

        /// <summary>
        /// 获取家庭成员详细信息
        /// </summary>
        /// <param name="patientId"></param>
        /// <returns></returns>
        public async Task<BaseResponse<PatientModel>> GetPatientInfoByIdAsync(int patientId)
        {
            var patient = await _pubUserInfoRepository.GetPatientInfoByIdAsync(GetBaseUserInfo().ID, patientId);

            if (patient != null)
            {
                patient.PhoneNo = patient.PhoneNo?.HideSensitiveInfo(3, 4);
                patient.CardId = patient.CardId?.HideSensitiveInfo(0, 4);

                //头像显示类型：1-男；2-女；3-小于14岁
                if (patient.Age > 14)
                {
                    patient.HeadImgType = patient.Gender == 1 ? 1 : 2;
                }
                else
                {
                    patient.HeadImgType = 3;
                }

                var authorizationInfos = await _pubAuthorizationRepository.GetUserAuthorizationsByPatsAsync(GetBaseUserInfo().ID, new List<int> { patientId });

                patient.NationalityId = (await _cnBaseDistrictRepository.GetNationalityByNameOrCodeAsync(patient.Nationality, patient.Nationality))?.Id ?? 0;

                if (patient.Ties == 1 || patient.Age < 18)
                {
                    patient.AuthorizationStatus = 3;
                    patient.AuthorizationDetailIds = "1,2,3,4";
                }
                else
                {
                    var auth = authorizationInfos.Where(x => x.PatId == patient.PatId)
                                                 .OrderByDescending(x => x.AuthorizationTime)
                                                 .FirstOrDefault();

                    if (auth == null)
                    {
                        return new BaseResponse<PatientModel>
                        {
                            Code = 1,
                            Msg = "操作成功",
                            Data = patient
                        };
                    }

                    var now = DateTime.Now;
                    patient.AuthorizationStatus = auth.Status != 1 && !auth.IsForever && auth.AuthorizationValidity < now && auth.AuthorizationTime != DateTime.MinValue ? 5 : auth.Status;
                    patient.AuthorizationDetailIds = auth.Status == 3 && (auth.IsForever || auth.AuthorizationValidity > now) ? auth.ApplyDetailIds : default;
                }
            }

            return new BaseResponse<PatientModel>
            {
                Code = 1,
                Msg = "操作成功",
                Data = patient
            };
        }

        /// <summary>
        /// 家庭成员是否绑定了本人
        /// </summary> 
        /// <returns></returns>
        public async Task<BaseResponse<bool>> IsBandMyselfAsync()
        {
            var userId = GetBaseUserInfo().ID;

            var result = await _pubUserInfoRepository.IsBandMyselfAsync(userId);

            return new BaseResponse<bool>
            {
                Code = 1,
                Msg = "操作成功",
                Data = result
            };
        }

        /// <summary>
        /// 删除家庭成员
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<BaseResponse> DeletePatientAsync(DeletePatientParam param)
        {
            await _pubUserInfoRepository.DeletePatientAsync(GetBaseUserInfo().ID, param.PatientId);
            _logger.LogInformation($"删除家庭成员:user-{GetBaseUserInfo().ID},pat-{param.PatientId}");

            //var groups = _pubPatRepository.GetGroupsByPat(param.PatientId);
            //if (groups?.Count > 1)
            //{
            //    var group = groups.Find(p => p.UserId == GetBaseUserInfo().ID);
            //    if (group != null)
            //    {
            //        var res = _tencentService.DeleteTencentGroupMember(group.GroupId, GetBaseUserInfo().IM_ID);
            //        if (res.ActionStatus == "OK")
            //        {
            //            _pubPatRepository.DeleteGroupMember(group.Id);
            //        }
            //    }
            //}

            await _pubAuthorizationRepository.RemoveUserAuthorizationAsync(GetBaseUserInfo().ID, param.PatientId);

            _logger.LogInformation($"取消授权:user-{GetBaseUserInfo().ID},pat-{param.PatientId}");

            return new BaseResponse
            {
                Code = 1,
                Msg = "操作成功"
            };
        }
        public async Task<BaseResponse> UnbindPatientAsync(DeletePatientParam param)
        {
            await _pubUserInfoRepository.DeletePatientAsync(param.UserId, param.PatientId);
            _logger.LogInformation($"删除家庭成员:user-{param.UserId},pat-{param.PatientId}");

            await _pubAuthorizationRepository.RemoveUserAuthorizationAsync(param.UserId, param.PatientId);
            _logger.LogInformation($"取消授权:user-{param.UserId},pat-{param.PatientId}");

            return new BaseResponse
            {
                Code = 1,
                Msg = "操作成功"
            };
        }

        /// <summary>
        /// 添加新患者
        /// </summary>
        /// <param name="param"></param>
        /// <param name="language"></param>
        /// <returns></returns>
        public async Task<BaseResponse<AddNewPatientModel>> AddNewPatientAsync(AddNewPatientParam param, int language)
        {
            var response = new BaseResponse<AddNewPatientModel>();

            #region 一个用户最多只能绑10就诊人，并且只能有一个关系为“本人”的就诊人

            var familyCount = await _pubUserInfoRepository.GetFamilyCountAsync(GetBaseUserInfo().ID);
            if (familyCount >= 10)
            {
                response.Code = 0;
                response.Msg = language == 1 ? "最多可添加10个家庭成员" : "You can add up to 10 family members";
                return response;
            }

            var maps = _pubPatRepository.GetMapsByUserId(GetBaseUserInfo().ID);
            if (maps.Any() && maps.Exists(x => x.Ties == 1 && (x.Relation_Ship == 1 || x.Relation_Ship == 2)))
            {
                if (param.FamilyTies == 1)
                {
                    response.Code = 0;
                    response.Msg = "已经绑定过了本人";
                    return response;
                }
            }

            #endregion

            #region 校验验证码

            if (!string.IsNullOrEmpty(param.Code))
            {
                var checkCodeResult = _verifyCodeLogService.CheckCode(param.PhoneNo, param.Code);

                if (checkCodeResult != 1)
                {
                    if (checkCodeResult == -1)
                    {
                        response.Code = 0;
                        response.Msg = language == 1 ? "验证码已失效！" : "Verification Code Expired";
                        return response;
                    }
                    else
                    {
                        response.Code = 0;
                        response.Msg = language == 1 ? "验证码输入不正确！" : "Unvalid verification code";
                        return response;
                    }
                }
            }

            #endregion

            #region 判断证件有效期

            if (!DateTime.TryParse(param.CardValidity, out var cardValidity))
            {
                if (!DateTime.TryParseExact(param.CardValidity, "dd/MM/yyyy", new CultureInfo("en-US"), DateTimeStyles.None, out cardValidity))
                {
                    response.Code = 0;
                    response.Msg = "证件有效期不能为空";
                    return response;
                }
            }

            var now = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));

            if (cardValidity < now)
            {
                response.Code = 0;
                response.Msg = language == 1 ? "证件已过有效期！" : "ID has expired";
                return response;
            }

            #endregion

            #region 校验生日字段

            if (!DateTime.TryParse(param.Birthday, out var birthday))
            {
                if (!DateTime.TryParseExact(param.Birthday, "dd/MM/yyyy", new CultureInfo("en-US"), DateTimeStyles.None, out birthday))
                {
                    response.Code = 0;
                    response.Msg = "生日格式不正确";
                    return response;
                }
            }

            #endregion

            #region 就诊人推tc

            var tcNewPatient = new Pub_Pat_Info
            {
                First_Name = param.FirstName,
                Last_Name = param.LastName,
                Gender = param.Gender,
                Phone_NO = param.PhoneNo,
                Birthday = birthday.ToString("yyyy-MM-dd"),
                Card_ID = param.CardId
            };

            var tcResult = _tcService.AddTcPatInfo(tcNewPatient);

            if (tcResult <= 0)
            {
                _logger.LogInformation($"家庭成员推tc失败：{tcNewPatient.ToJson()}");

                return new BaseResponse<AddNewPatientModel>
                {
                    Code = 50,
                    Msg = "新增失败"
                };
            }

            var tcPatientsOutput = await _tcService.GetPatientAsync(new GetPatientInput
            {
                NID = param.CardId
            });

            var tcPatientByCardId = tcPatientsOutput.Persons.FirstOrDefault();

            #region 文件推tc

            var fileIdList = new List<int>();
            var fileTypes = new Dictionary<int, string>();

            if (!string.IsNullOrEmpty(param.IDCardUrlBack))
            {
                if (int.TryParse(param.IDCardUrlBack, out var idCardUrlBackId))
                {
                    fileIdList.Add(idCardUrlBackId);
                    fileTypes.Add(idCardUrlBackId, param.CardType == 1 || param.CardType == 6 ? "Photo ID-2" : "Photo ID");
                }
            }

            if (!string.IsNullOrEmpty(param.IDCardUrlFront))
            {
                if (int.TryParse(param.IDCardUrlFront, out var idCardUrlFrontId))
                {
                    fileIdList.Add(idCardUrlFrontId);
                    fileTypes.Add(idCardUrlFrontId, param.CardType == 1 || param.CardType == 6 ? "Photo ID-1" : "Photo ID");
                }
            }

            SendFileToTc(fileIdList, tcPatientByCardId?.PAPERRowId, fileTypes);

            #endregion

            //打标签
            _tcService.UpdatePatientPortalLink("", tcPatientByCardId?.PAPMINo, true);

            #endregion

            #region 就诊人保存到数据库  

            var patient = new Pub_Pat_Info
            {
                First_Name = param.FirstName,
                Last_Name = param.LastName,
                Pat_Name = language == 1 ? param.LastName + param.FirstName : param.FirstName + param.LastName,
                Gender = param.Gender,
                Phone_NO = param.PhoneNo,
                Birthday = param.Birthday,
                Card_ID = param.CardId,
                Card_Type = param.CardType,
                CardValidity = param.CardValidity,
                IDCardUrlFront = param.IDCardUrlFront,
                IDCardUrlBack = param.IDCardUrlBack,
                Id_Number = param.CardType == 1 ? param.CardId : "",
                Pat_Source = 4,
                Pat_ID = tcPatientByCardId?.PAPERRowId,
                Pat_MRN = tcPatientByCardId?.PAPMINo,
                Mrn = tcPatientByCardId?.MRN
            };

            patient = _fileService.GetFileContentAdd(patient);
            var patientId = _pubPatRepository.InsertPubPatInfo(patient);

            #endregion

            #region 添加绑定关系

            BindMapTies(null, patientId, param.FamilyTies, language);

            #endregion

            #region 给”本人“添加一个永久授权

            if (param.FamilyTies == 1)
            {
                var auth = new Pub_AuthorizationDto
                {
                    UserId = GetBaseUserInfo().ID,
                    PatId = patientId,
                    Status = 3,
                    CreateTime = DateTime.Now,
                    ApplyDetailIds = "1,2,3,4",
                    ExamineDetailIds = "1,2,3,4",
                    AuthorizationTime = DateTime.Now,
                    AuthorizationValidity = DateTime.Now.AddYears(100),
                    Source = param.Source,
                    IsForever = true,
                    IsOneSelf = true
                };

                _pubAuthorizationRepository.InsertAuthorization(auth);
            }

            #endregion

            _logger.LogInformation($"家庭成员添加成功：{patientId}");

            response.Code = 1;
            response.Msg = "操作成功";
            response.Data = new AddNewPatientModel
            {
                Id = patientId
            };

            return response;
        }

        /// <summary>
        /// 绑定老患者
        /// </summary>
        /// <param name="param"></param>
        /// <param name="language"></param>
        /// <returns></returns> 
        public async Task<BaseResponse<BindOldPatientModel>> BindOldPatientAsync(BindOldPatientParam param, int language)
        {
            #region 一个用户最多只能绑10就诊人，并且只能有一个关系为“本人”的就诊人

            var familyList = await _pubUserInfoRepository.GetFamilyListByUserIdAsync(GetBaseUserInfo().ID);
            if (familyList != null)
            {
                if (familyList.Exists(x => x.Ties == 1) && !familyList.Exists(x => x.TcRowId == param.TcRowId) && param.FamilyTies == 1)
                {
                    return new BaseResponse<BindOldPatientModel>
                    {
                        Code = 0,
                        Msg = language == 1 ? "家庭成员关系仅可添加一个本人，请重新选择" : "Relationship 'Me' already existed, please choos another",
                    };
                }

                if (familyList.Count >= 10 && !familyList.Exists(x => x.TcRowId == param.TcRowId))
                {
                    return new BaseResponse<BindOldPatientModel>
                    {
                        Code = 0,
                        Msg = language == 1 ? "最多可添加10个家庭成员" : "You can add up to 10 family members",
                    };
                }
            }

            #endregion

            #region 判断证件有效期

            if (!DateTime.TryParse(param.CardValidity, out var cardValidity))
            {
                if (!DateTime.TryParseExact(param.CardValidity, "dd/MM/yyyy", new CultureInfo("en-US"), DateTimeStyles.None, out cardValidity))
                {
                    return new BaseResponse<BindOldPatientModel>
                    {
                        Code = 0,
                        Msg = "证件有效期不能为空"
                    };
                }
            }

            var now = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));

            if (cardValidity < now)
            {
                return new BaseResponse<BindOldPatientModel>()
                {
                    Code = 0,
                    Msg = language == 1 ? "证件已过有效期！" : "ID has expired"
                };
            }

            #endregion

            int patientId;
            string patMrn;

            //查询数据库里是否存在
            var patient = _pubPatRepository.SelectByMrn(param.PId);

            if (patient != null)
            {
                patient.Card_ID = param.CardId;
                patient.Card_Type = param.CardType;
                patient.CardValidity = param.CardValidity;
                patient.IDCardUrlFront = param.IDCardUrlFront;
                patient.IDCardUrlBack = param.IDCardUrlBack;
                patient.Id_Number = param.CardType == 1 ? param.CardId : "";
                patient.Pat_ID = param.TcRowId;
                patient.Pat_MRN = param.PId;
                patient.Mrn = param.Mrn;
                patient = _fileService.GetFileContentAdd(patient);
                await _pubPatRepository.UpdatePubPatInfoAsync(patient, 1);
                patientId = patient.Id;
                patMrn = patient.Pat_MRN;
            }
            else
            {
                var getPatientOutput = await _tcService.GetPatientAsync(new GetPatientInput
                {
                    MRN = param.PId
                });

                var tcPatient = getPatientOutput.Persons.FirstOrDefault();

                var newPatient = new Pub_Pat_Info
                {
                    First_Name = tcPatient?.PAPERName2,
                    Last_Name = tcPatient?.PAPERName,
                    Pat_Name = language == 1 ? tcPatient?.PAPERName + tcPatient?.PAPERName2 : tcPatient?.PAPERName2 + tcPatient?.PAPERName,
                    Gender = tcPatient?.PAPERSex.Contains("Female") == true ? 0 : 1,
                    Phone_NO = tcPatient?.PAPERMobPhone,
                    Birthday = tcPatient?.PAPERDob.ToString("yyyy-MM-dd"),
                    Card_ID = param.CardId,
                    Card_Type = param.CardType,
                    CardValidity = param.CardValidity,
                    IDCardUrlFront = param.IDCardUrlFront,
                    IDCardUrlBack = param.IDCardUrlBack,
                    Id_Number = param.CardType == 1 ? param.CardId : "",
                    Pat_Source = 4,
                    Pat_ID = param.TcRowId,
                    Pat_MRN = param.PId,
                    Mrn = param.Mrn
                };

                patient = _fileService.GetFileContentAdd(newPatient);
                patientId = _pubPatRepository.InsertPubPatInfo(patient);
                patMrn = patient.Pat_MRN;
            }

            try
            {
                if (!string.IsNullOrEmpty(patMrn))
                {
                    //打标签
                    _tcService.UpdatePatientPortalLink("", patMrn, true);
                }
            }
            catch (System.Exception e)
            {
              
            }

            #region 更新证件信息（TC没有单独更新证件号的接口，只能全量更新……）

            #region 文件推tc

            var fileIdList = new List<int>();
            var fileTypes = new Dictionary<int, string>();

            if (!string.IsNullOrEmpty(param.IDCardUrlBack))
            {
                if (int.TryParse(param.IDCardUrlBack, out var idCardUrlBackId))
                {
                    fileIdList.Add(idCardUrlBackId);
                    fileTypes.Add(idCardUrlBackId, param.CardType == 1 || param.CardType == 6 ? "Photo ID-2" : "Photo ID");
                }
            }

            if (!string.IsNullOrEmpty(param.IDCardUrlFront))
            {
                if (int.TryParse(param.IDCardUrlFront, out var idCardUrlFrontId))
                {
                    fileIdList.Add(idCardUrlFrontId);
                    fileTypes.Add(idCardUrlFrontId, param.CardType == 1 || param.CardType == 6 ? "Photo ID-1" : "Photo ID");
                }
            }

            SendFileToTc(fileIdList, param.TcRowId, fileTypes);

            #endregion

            var tcRowId = int.TryParse(param.TcRowId, out var rowId) ? rowId : default;
            var tcPatInfoByRowId = _tcService.PAPersonEditOpen(tcRowId);
            if (tcPatInfoByRowId != null)
            {
                var tcPatientByPId = (await _tcService.GetPatientAsync(new GetPatientInput
                {
                    MRN = patient.Pat_MRN
                })).Persons.FirstOrDefault();

                //var howknows = await _pubUserInfoRepository.GetHowknow();
                //var howknow = howknows.FirstOrDefault(w => w.TcShow.ToLower() == tcPatInfoByRowId?.ASSISDesc?.ToLower());

                var updateTcInput = new CustomCRMPAPerson
                {
                    PAPERCityCodeDR = "上海市",//小P让改的
                    PAPERStName = tcPatInfoByRowId.PAPERStName,
                    PAPERDob = tcPatInfoByRowId.PAPERDob,
                    PAPEREmail = tcPatInfoByRowId.PAPEREmail,
                    PAPERHowDidYouLearnUsDR = tcPatInfoByRowId?.ASSISDesc,
                    PAPERID = param.CardId,
                    PAPERMobPhone = tcPatInfoByRowId?.PAPERMobPhone,
                    PAPERName = tcPatInfoByRowId.PAPERName,
                    PAPERName2 = tcPatInfoByRowId.PAPERName2,
                    //PAPERName3 = tcPatientByPId?.PAPERName3,
                    PAPERNationDR = tcPatientByPId?.PAPERNation,
                    PAPERNokCTRLTDR = tcPatInfoByRowId.PAPERNokName,
                    PAPERNokName = tcPatInfoByRowId.PAPERNokName,
                    PAPERNokPhone = tcPatInfoByRowId.PAPERNokPhone,
                    PAPERPreferredContactMethod = tcPatInfoByRowId.PAPERPreferredContactMethod,
                    PAPERRowId = tcRowId,
                    PAPERSexDR = tcPatInfoByRowId.CTSEXDesc.Contains("男") ? "M" : "F",
                    PAPERRemark = new List<PAPERRemark>()
                };

                if (!string.IsNullOrEmpty(tcPatInfoByRowId?.PAPERRemark))
                {
                    var arr = tcPatInfoByRowId.PAPERRemark.Split(new[] { "\r\n" }, StringSplitOptions.None);
                    foreach (var item in arr)
                    {
                        updateTcInput.PAPERRemark.Add(new PAPERRemark { PAPERRemarkItem = item });
                    }
                }

                var updateTcResult = _tcService.CustomCRMPAPerson(updateTcInput);

                if (!updateTcResult)
                {
                    _logger.LogInformation($"绑定就诊人证件信息同步tc失败：param-{param.ToJson()},pullTC-{updateTcInput.ToJson()}");
                    return new BaseResponse<BindOldPatientModel>
                    {
                        Code = 0,
                        Msg = "绑定出错，请联系客服小影"
                    };
                }
            }

            #endregion

            var map = await _pubMapUserPatRepository.GetByUserIdAndPatIdAsync(GetBaseUserInfo().ID, patient.Id);

            if (map == null)
            {
                if (param.FamilyTies == 1)
                {
                    var auth = new Pub_AuthorizationDto
                    {
                        UserId = GetBaseUserInfo().ID,
                        PatId = patientId,
                        Status = 3,
                        CreateTime = DateTime.Now,
                        ApplyDetailIds = "1,2,3,4",
                        ExamineDetailIds = "1,2,3,4",
                        AuthorizationTime = DateTime.Now,
                        AuthorizationValidity = DateTime.Now.AddYears(100),
                        Source = param.Source,
                        IsForever = true,
                        IsOneSelf = true
                    };

                    _pubAuthorizationRepository.InsertAuthorization(auth);
                }
            }
            else
            {
                if (map.Ties == 1)
                {
                    if (param.FamilyTies != 1)
                    {
                        await _pubAuthorizationRepository.RemoveOneSelfAuthorizationAsync(GetBaseUserInfo().ID, patient.Id);
                    }
                }
                else
                {
                    if (param.FamilyTies == 1)
                    {
                        var auth = new Pub_AuthorizationDto
                        {
                            UserId = GetBaseUserInfo().ID,
                            PatId = patientId,
                            Status = 3,
                            CreateTime = DateTime.Now,
                            ApplyDetailIds = "1,2,3,4",
                            ExamineDetailIds = "1,2,3,4",
                            AuthorizationTime = DateTime.Now,
                            AuthorizationValidity = DateTime.Now.AddYears(100),
                            Source = param.Source,
                            IsForever = true,
                            IsOneSelf = true
                        };

                        _pubAuthorizationRepository.InsertAuthorization(auth);
                    }
                }
            }

            BindMapTies(map, patientId, param.FamilyTies, language);

            _logger.LogInformation($"绑定成功：{patientId}");

            var currentPatient = await _pubUserInfoRepository.GetPatientInfoByIdAsync(GetBaseUserInfo().ID, patientId);

            return new BaseResponse<BindOldPatientModel>
            {
                Code = 1,
                Msg = "操作成功",
                Data = new BindOldPatientModel
                {
                    Id = patientId,
                    IsPerfect = currentPatient?.IsPerfect ?? default,
                    IsPerfectGuardian = currentPatient?.IsPerfectGuardian ?? default
                }
            };
        }

        /// <summary>
        /// 绑定家庭成员关系
        /// </summary>
        /// <param name="map"></param>
        /// <param name="patientId"></param>
        /// <param name="familyTies"></param>
        /// <param name="language"></param>
        private void BindMapTies(Pub_Map_User_Pat map, int patientId, int familyTies, int language)
        {
            if (map == null)
            {
                var newMap = new Pub_Map_User_Pat
                {
                    User_ID = GetBaseUserInfo().ID,
                    Pat_ID = patientId,
                    Relation_Ship = 1,
                    Ties = familyTies,
                    Create_Time = DateTime.Now
                };

                _pubMapUserPatRepository.InsertPubMapUserPat(newMap);
            }
            else
            {
                if (map.User_ID == GetBaseUserInfo().ID)
                {
                    map.Relation_Ship = 1;
                    map.Ties = familyTies;
                    map.Update_Time = DateTime.Now;
                    map.Is_Deleted = false;

                    _pubMapUserPatRepository.UpdatePubMapUserPat(map);
                }
                else
                {
                    //var errorMessage = language == 1 ? "该就诊人已被其他用户绑定" : "Patient has been added to another account";
                    //throw new System.Exception(errorMessage);

                    var newMap = new Pub_Map_User_Pat
                    {
                        User_ID = GetBaseUserInfo().ID,
                        Pat_ID = patientId,
                        Relation_Ship = 1,
                        Ties = familyTies,
                        Create_Time = DateTime.Now
                    };

                    _pubMapUserPatRepository.InsertPubMapUserPat(newMap);
                }
            }
        }

        /// <summary>
        /// 添加监护人信息
        /// </summary>
        /// <param name="param"></param> 
        /// <returns></returns>
        public async Task<BaseResponse<AddGuardianModel>> AddGuardianAsync(AddGuardianParam param)
        {
            #region 校验验证码

            if (!string.IsNullOrEmpty(param.Code))
            {
                var checkCodeResult = _verifyCodeLogService.CheckCode(param.GuardianPhone, param.Code);

                if (checkCodeResult != 1)
                {
                    if (checkCodeResult == -1)
                    {
                        return new BaseResponse<AddGuardianModel>
                        {
                            Code = 0,
                            Msg = "验证码失效"
                        };
                    }
                    else
                    {
                        return new BaseResponse<AddGuardianModel>
                        {
                            Code = 0,
                            Msg = "验证码错误"
                        };
                    }
                }
            }

            #endregion

            var patient = _pubPatRepository.SelectById(param.Id);

            if (patient == null)
            {
                return new BaseResponse<AddGuardianModel>
                {
                    Code = 0,
                    Msg = "找不到此患者"
                };
            }

            patient.First_Guardian = param.FirstGuardian;
            patient.Last_Guardian = param.LastGuardian;
            patient.Guardian = param.LastGuardian + param.FirstGuardian;
            patient.GuardianPhone = param.GuardianPhone;
            patient.Document_Type = param.DocumentType;
            patient.Certificate_Number = param.CertificateNumber;

            var result = await _pubPatRepository.UpdatePubPatInfoAsync(patient, 1);
            if (result > 0)
            {
                var currentPatient = await _pubUserInfoRepository.GetPatientInfoByIdAsync(GetBaseUserInfo().ID, patient.Id);
                return new BaseResponse<AddGuardianModel>
                {
                    Code = 1,
                    Msg = "操作成功",
                    Data = new AddGuardianModel
                    {
                        Id = param.Id,
                        IsPerfect = currentPatient?.IsPerfect ?? default
                    }
                };
            }

            _logger.LogInformation($"添加监护人信息失败：{param.ToJson()}");

            return new BaseResponse<AddGuardianModel>
            {
                Code = 0,
                Msg = "添加监护人信息失败"
            };
        }

        /// <summary>
        /// 完善信息
        /// </summary>
        /// <param name="param"></param>
        /// <param name="language"></param>
        /// <returns></returns>
        public async Task<BaseResponse> PerfectInfoAsync(PerfectInfoParam param, int language)
        {
            if (!param.Email.Contains("@"))
            {
                return new BaseResponse
                {
                    Code = 0,
                    Msg = language == 1 ? "邮箱不正确" : "Invalid Email"
                };
            }

            var patient = await _pubPatRepository.GetPubPatInfoByIdAsync(param.Id);

            if (patient == null)
            {
                return new BaseResponse
                {
                    Code = 0,
                    Msg = "患者不存在"
                };
            }

            var tcPatients = await _tcService.GetPatientAsync(new GetPatientInput
            {
                MRN = patient.Pat_MRN
            });

            if (tcPatients.Persons.Any())
            {
                var tcPatient = tcPatients.Persons.FirstOrDefault();

                var tcRowId = int.TryParse(tcPatient?.PAPERRowId, out var rowId) ? rowId : default;

                #region 文件推tc

                var fileIdList = new List<int>();
                var fileTypes = new Dictionary<int, string>();

                if (!string.IsNullOrEmpty(param.InsuranceCardUrl))
                {
                    if (param.InsuranceCardUrl.Contains(","))
                    {
                        var insuranceCardIds = param.InsuranceCardUrl.Split(',');
                        foreach (var insuranceCardId in insuranceCardIds)
                        {
                            if (string.IsNullOrEmpty(insuranceCardId))
                            {
                                continue;
                            }

                            if (!int.TryParse(insuranceCardId, out var fileId))
                            {
                                continue;
                            }

                            fileIdList.Add(fileId);
                            fileTypes.Add(fileId, "Insurance");
                        }
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(param.InsuranceCardUrl))
                        {
                            if (int.TryParse(param.InsuranceCardUrl, out var fileId))
                            {
                                fileIdList.Add(fileId);
                                fileTypes.Add(fileId, "Insurance");
                            }
                        }
                    }
                }

                SendFileToTc(fileIdList, tcPatient?.PAPERRowId, fileTypes);

                #endregion

                var tcPatInfo = _tcService.PAPersonEditOpen(tcRowId);
                //var howknows = await _pubUserInfoRepository.GetHowknow();
                //var howknow = howknows.FirstOrDefault(w => w.TcShow.ToLower() == tcPatInfo?.ASSISDesc?.ToLower());
                var updateTcInput = new CustomCRMPAPerson
                {
                    PAPERCityCodeDR = "上海市",//小P让改的
                    PAPERStName = param.Province + "," + param.City + "," + param.LocalAddress,
                    PAPERDob = tcPatient?.PAPERDob.ToString("yyyy-MM-dd"),
                    PAPEREmail = param.Email,
                    PAPERHowDidYouLearnUsDR = tcPatInfo?.ASSISDesc,
                    PAPERID = tcPatient?.PAPERID,
                    PAPERMobPhone = tcPatient?.PAPERMobPhone,
                    PAPERName = tcPatient?.PAPERName,
                    PAPERName2 = tcPatient?.PAPERName2,
                    //PAPERName3 = tcPatient?.PAPERName3,
                    PAPERNationDR = _cnBaseDistrictRepository.GetTcNationAll(param.NationalityId)?.FirstOrDefault()?.TcCode,
                    PAPERNokCTRLTDR = (await _pubUserInfoRepository.GetRelationship()).Find(p => p.Id == param.EmergencyRelation)?.Code,
                    PAPERNokName = param.EmergencyName,
                    PAPERNokPhone = param.EmergencyPhone,
                    PAPERPreferredContactMethod = (await _pubUserInfoRepository.GetContactway()).Find(p => p.Id == param.ContactWay)?.Code,
                    PAPERRowId = tcRowId,
                    PAPERSexDR = tcPatient != null && tcPatient.PAPERSex.Contains("男") ? "M" : "F",
                    PAPERRemark = new List<PAPERRemark>()
                };

                if (!string.IsNullOrEmpty(tcPatInfo?.PAPERRemark))
                {
                    var arr = tcPatInfo.PAPERRemark.Split(new[] { "\r\n" }, StringSplitOptions.None);
                    foreach (var item in arr)
                    {
                        updateTcInput.PAPERRemark.Add(new PAPERRemark { PAPERRemarkItem = item });
                    }
                }

                if (param.PayType == 2 && string.IsNullOrEmpty(param.InsuranceCardUrl))
                {
                    updateTcInput.PAPERRemark.Add(new PAPERRemark { PAPERRemarkItem = "保险照片未上传" });
                }
                updateTcInput.PAPERRemark.Add(new PAPERRemark { PAPERRemarkItem = "APP自动完善信息" });
                updateTcInput.PAPERRemark.Add(new PAPERRemark { PAPERRemarkItem = "患者证件已上传至Patient document" });

                var updateTcResult = _tcService.CustomCRMPAPerson(updateTcInput);

                if (!updateTcResult)
                {
                    _logger.LogInformation($"完善信息推tc失败：{updateTcInput.ToJson()}");
                    return new BaseResponse
                    {
                        Code = 0,
                        Msg = "完善信息出错，请联系客服小影"
                    };
                }
            }

            patient.Nationality = _cnBaseDistrictRepository.GetTcNationAll(param.NationalityId)?.FirstOrDefault()?.TcCode;
            patient.Email = param.Email;
            patient.CityId = param.CityId;
            patient.Province = param.Province;
            patient.City = param.City;
            patient.LocalAddress = param.LocalAddress;
            patient.EmergencyName = param.EmergencyName;
            patient.EmergencyPhone = param.EmergencyPhone;
            patient.EmergencyRelation = param.EmergencyRelation.ToString();
            //patient.HowKnow = param.HowKnow;
            patient.ContactWay = param.ContactWay;
            patient.ContactValue = param.Chat;
            patient.PayType = param.PayType;
            patient.InsuranceCardUrl = param.InsuranceCardUrl;
            patient = _fileService.GetFileContentAdd(patient);
            var updateResult = await _pubPatRepository.UpdatePubPatInfoAsync(patient, 1);

            if (updateResult >= 1)
            {
                return new BaseResponse
                {
                    Code = 1,
                    Msg = "操作成功"
                };
            }

            _logger.LogInformation($"完善信息失败：{param.ToJson()}");

            return new BaseResponse
            {
                Code = 0,
                Msg = "完善信息出错，请联系客服小影"
            };

        }

        /// <summary>
        /// 根据身份证号或者姓名、性别、出生日期三要素查询tc患者
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<BaseResponse<GetTcPatientModel>> QueryMedicalRecordNoAsync(QueryMedicalRecordNoParam param)
        {
            if (!DateTime.TryParse(param.Birthday, out var birthday))
            {
                return new BaseResponse<GetTcPatientModel>
                {
                    Code = 0,
                    Msg = "时间格式不正确"
                };
            }

            param.Birthday = birthday.ToString("yyyy-MM-dd");

            //按以下优先级顺序查询

            #region 1.证件号

            //1.证件号
            var getPatientOutput = await _tcService.GetPatientAsync(new GetPatientInput
            {
                NID = param.CardId
            });
            if (getPatientOutput.Persons.Any())
            {
                //粟：通过证件号从TC查询出多个就诊人，记录一下
                if (getPatientOutput.Persons.Count > 1)
                {
                    var tcAbnormal = new Pub_Pat_TcAbnormal
                    {
                        UserId = GetBaseUserInfo()?.ID ?? 0,
                        RequestTime = DateTime.Now,
                        NId = param.CardId
                    };

                    await _pubPatTcAbnormalRepository.InsertAsync(tcAbnormal);
                }
                //小红：大于10个前端弹框提示数据异常
                if (getPatientOutput.Persons.Count > 10)
                {
                    return new BaseResponse<GetTcPatientModel>
                    {
                        Code = 1,
                        Msg = "操作成功",
                        Data = new GetTcPatientModel
                        {
                            IsTcAbnormal = true
                        }
                    };
                }

                var patients = MapToTcPatientModel(getPatientOutput.Persons);

                return new BaseResponse<GetTcPatientModel>
                {
                    Code = 1,
                    Msg = "操作成功",
                    Data = new GetTcPatientModel
                    {
                        Count = patients.Count,
                        Patients = patients
                    }
                };
            }

            #endregion

            var sex = 0;
            switch (param.Gender)
            {
                case 0:
                    sex = 2;
                    break;
                case 1:
                    sex = 1;
                    break;
            }

            #region 2.姓名+性别+出示日期+手机号

            //2.姓名+性别+出示日期+手机号
            getPatientOutput = await _tcService.GetPatientAsync(new GetPatientInput
            {
                PAPERName = param.LastName,
                PAPERName2 = param.FirstName,
                DOB = param.Birthday,
                MobilePhone = param.PhoneNo,
                SexId = sex
            });
            if (getPatientOutput.Persons.Any())
            {
                var patients = MapToTcPatientModel(getPatientOutput.Persons);

                return new BaseResponse<GetTcPatientModel>
                {
                    Code = 1,
                    Msg = "操作成功",
                    Data = new GetTcPatientModel
                    {
                        Count = patients.Count,
                        Patients = patients
                    }
                };
            }

            #endregion

            #region 3.姓名+性别+出示日期

            //3.姓名+性别+出示日期
            getPatientOutput = await _tcService.GetPatientAsync(new GetPatientInput
            {
                PAPERName = param.LastName,
                PAPERName2 = param.FirstName,
                DOB = param.Birthday,
                SexId = sex
            });
            if (getPatientOutput.Persons.Any())
            {
                var patients = MapToTcPatientModel(getPatientOutput.Persons);

                return new BaseResponse<GetTcPatientModel>
                {
                    Code = 1,
                    Msg = "操作成功",
                    Data = new GetTcPatientModel
                    {
                        Count = patients.Count,
                        Patients = patients
                    }
                };
            }

            #endregion

            #region 4.性别+出示日期+手机号

            //4.性别+出示日期+手机号
            getPatientOutput = await _tcService.GetPatientAsync(new GetPatientInput
            {
                SexId = sex,
                DOB = param.Birthday,
                MobilePhone = param.PhoneNo
            });
            if (getPatientOutput.Persons.Any())
            {
                var patients = MapToTcPatientModel(getPatientOutput.Persons);

                return new BaseResponse<GetTcPatientModel>
                {
                    Code = 1,
                    Msg = "操作成功",
                    Data = new GetTcPatientModel
                    {
                        Count = patients.Count,
                        Patients = patients
                    }
                };
            }

            #endregion

            #region 5.姓名+出示日期+手机号

            //5.姓名+出示日期+手机号
            getPatientOutput = await _tcService.GetPatientAsync(new GetPatientInput
            {
                PAPERName = param.LastName,
                PAPERName2 = param.FirstName,
                DOB = param.Birthday,
                MobilePhone = param.PhoneNo
            });
            if (getPatientOutput.Persons.Any())
            {
                var patients = MapToTcPatientModel(getPatientOutput.Persons);

                return new BaseResponse<GetTcPatientModel>
                {
                    Code = 1,
                    Msg = "操作成功",
                    Data = new GetTcPatientModel
                    {
                        Count = patients.Count,
                        Patients = patients
                    }
                };
            }

            #endregion

            #region 6.姓名+性别+手机号

            //6.姓名+性别+手机号
            getPatientOutput = await _tcService.GetPatientAsync(new GetPatientInput
            {
                PAPERName = param.LastName,
                PAPERName2 = param.FirstName,
                SexId = sex,
                MobilePhone = param.PhoneNo
            });
            if (getPatientOutput.Persons.Any())
            {
                var patients = MapToTcPatientModel(getPatientOutput.Persons);

                return new BaseResponse<GetTcPatientModel>
                {
                    Code = 1,
                    Msg = "操作成功",
                    Data = new GetTcPatientModel
                    {
                        Count = patients.Count,
                        Patients = patients
                    }
                };
            }

            #endregion

            return new BaseResponse<GetTcPatientModel>
            {
                Code = 1,
                Msg = "无数据",
                Data = new GetTcPatientModel
                {
                    Count = 0,
                    Patients = new List<TcPatientModel>()
                }
            };
        }

        /// <summary>
        /// 校验用户补全tc那边的手机号中间四位
        /// </summary>
        /// <param name="param"></param>
        /// <param name="language"></param>
        /// <returns></returns>
        public async Task<BaseResponse> CheckTcPhoneAsync(CheckTcPhoneParam param, int language)
        {
            var getPatientResult = await _tcService.GetPatientAsync(new GetPatientInput
            {
                MRN = param.PId
            });

            var tcPatient = getPatientResult.Persons.FirstOrDefault();

            var phoneFragment = tcPatient?.PAPERMobPhone.Substring(3, 4);

            if (phoneFragment != param.PhoneFragment.Trim())
            {
                return new BaseResponse
                {
                    Code = 0,
                    Msg = "手机号验证失败"
                };
            }

            return new BaseResponse
            {
                Code = 1,
                Msg = "操作成功"
            };
        }

        /// <summary>
        /// 根据MRN或者PID搜索TC患者
        /// </summary>
        /// <param name="mrnOrPId"></param>
        /// <param name="language"></param>
        /// <returns></returns> 
        public async Task<BaseResponse<List<TcPatientModel>>> GetTcPatientByMrnOrPIdAsync(string mrnOrPId, int language)
        {
            if (string.IsNullOrEmpty(mrnOrPId))
            {
                return new BaseResponse<List<TcPatientModel>>
                {
                    Code = 0,
                    Msg = language == 1 ? "病历号不存在，请重新输入" : "MRN doesn't exist, please enter again"
                };
            }

            mrnOrPId = mrnOrPId.Trim();

            var getPatientResult = new GetPatientOutput();

            var firstInputValue = mrnOrPId.Substring(0, 1);

            //如患者输入的第一个字是P，则通过PID查询TC患者 
            if (firstInputValue == "P" || firstInputValue == "p")
            {
                getPatientResult = await _tcService.GetPatientAsync(new GetPatientInput
                {
                    MRN = $"P{mrnOrPId.Substring(1)}"
                });
            }

            //如患者输入的第一个字是数字，则通过MRN查询TC患者
            if (int.TryParse(firstInputValue, out _))
            {
                getPatientResult = await _tcService.GetPatientAsync(new GetPatientInput
                {
                    TrueMRN = mrnOrPId
                });
            }

            return new BaseResponse<List<TcPatientModel>>
            {
                Code = 1,
                Msg = "操作成功",
                Data = MapToTcPatientModel(getPatientResult.Persons)
            };
        }

        public BaseResponse<List<DicVaccine>> Vaccinelist()
        {
            BaseResponse<List<DicVaccine>> response = new BaseResponse<List<DicVaccine>>();
            response.Data = _outAptInfoRepository.Vaccine();
            response.Code = 1;
            response.Msg = "成功";
            return response;
        }

        private static List<TcPatientModel> MapToTcPatientModel(IEnumerable<PAPerson> persons)
        {
            var tcPatientModels = persons.Select(x =>
            {
                var patient = new TcPatientModel
                {
                    Name = (x.PAPERName + x.PAPERName2)?.Desensitization(),
                    Birthday = x.PAPERDob.ToString("yyyy-MM-dd"),
                    PhoneNoSource = x.PAPERMobPhone,
                    PhoneNo = x.PAPERMobPhone?.HideSensitiveInfo(3, 4),
                    PId = x.PAPMINo,
                    TcRowId = x.PAPERRowId,
                    Mrn = x.MRN
                };

                if (x.PAPERSex.Contains("男") || x.PAPERSex.Contains("Male"))
                {
                    patient.Gender = 1;
                }

                if (x.PAPERSex.Contains("女") || x.PAPERSex.Contains("Female"))
                {
                    patient.Gender = 0;
                }

                #region 头像显示类型：1-男；2-女；3-小于14岁

                var age = x.PAPERDob.GetAgeByBirth();

                if (age > 14)
                {
                    patient.HeadImgType = patient.Gender == 1 ? 1 : 2;
                }
                else
                {
                    patient.HeadImgType = 3;
                }

                #endregion

                return patient;
            })
                .ToList();

            return tcPatientModels;
        }

        #endregion
    }
}
