using Crm.Core.External.Web.Models; using DG.Core; using Microsoft.AspNetCore.Razor.TagHelpers; using Oracle.ManagedDataAccess.Client; using System; using System.Collections.Generic; using System.Data; using System.Drawing.Imaging; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using System.Transactions; using static Crm.Core.External.Domain.Config.SystemEnums; using static DG.Oracle.EntityFramework.Enums; namespace Crm.Core.External.Domain { internal class CustomerDomain : ICustomerDomain { private readonly ICacheDomain _cacheDomain; private readonly IHttpClient _httpClient; private readonly IConfiguration _configuration; private readonly IOracleRepository _crmRepository; private readonly IMapper _mapper; private readonly SystemConfig _systemConfig; public CustomerDomain(ICacheDomain cacheDomain, IHttpClient httpClient, IConfiguration configuration, IOracleRepository crmRepository, IMapper mapper) { _cacheDomain = cacheDomain; _httpClient = httpClient; _configuration = configuration; _crmRepository = crmRepository; _systemConfig = _configuration.GetSection("SystemConfig").Get(); _mapper = mapper; } public async Task GetWxworkCustomer(decimal eid, string? userid, string? wwappid) { var data = new WxworkCustomerDto { Eid = eid }; data.Appid = await GetAppidByEid(eid); if (!await _cacheDomain.SetApp(_crmRepository, data.Appid)) { throw new ApiException($"当前客服未绑定工号,请绑定后操作!"); } var user = await _crmRepository.GetRepository().Query() .FirstOrDefaultAsync(x => x.APPUSERID == userid && x.APPID == wwappid); var result = await _httpClient.GetAsync>($"{_systemConfig.ZxdCrmUrl}/api/UserInfo?appid={wwappid}_1&appuserid={userid}"); var resid = ""; var unionid = ""; var resids = new List(); if (result.Code == 0) { unionid = !string.IsNullOrEmpty(result.Data.Unionid) ? result.Data.Unionid : userid; resid = !string.IsNullOrEmpty(result.Data.Resid) ? result.Data.Resid : unionid; resid = await _crmRepository.GetRepository().Query() .Where(x => x.RESID == resid) .Select(x => x.CUSTOMERID) .FirstOrDefaultAsync(); resids = await _crmRepository.GetRepository().Query() .Where(x => x.CUSTOMERID == resid) .Select(x => x.RESID ?? "") .ToListAsync(); } if (user == null && !string.IsNullOrEmpty(unionid)) { await CreateWxworkCustomer(data.Appid, resid, eid, wwappid, "", userid, unionid); } // user ??= await CreateWxworkCustomer(data.Appid, resid, eid, wwappid, "", userid, unionid); // 需要显示的工单 var orderTypes = await _crmRepository.GetRepository().Query() .Where(x => x.ISSHOWFOLLOWUP == 1) .Select(x => x.SUBTYPEID) .ToListAsync(); var orders = await _crmRepository.GetRepository().Query() .Include(x => x.ORD_MEMOCONTENT) .Include(x => x.ORD_MEMOSUBTYPE) .Include(x => x.BAS_INNERUSER) .Where(x => resids.Contains(x.RESID)) .Where(x => orderTypes.Contains(x.ORD_MEMOSUBTYPE.SUBTYPEID)) .Select(x => new FollowUpRecordDetailDto { Date = x.CTIME.Value, Description = x.ORD_MEMOCONTENT.STRCONTENT, RecordType = x.ORD_MEMOSUBTYPE.FOLLOWUPNAME, User = x.BAS_INNERUSER.UNAME, Private = x.ORD_MEMOSUBTYPE.ISPRIVATE == 1, Eid = x.BAS_INNERUSER.EID }) .ToListAsync(); var calls = await _crmRepository.GetRepository().Query() .Include(x => x.BAS_INNERUSER) .Where(x => resids.Contains(x.RESID)) .Select(x => new FollowUpRecordDetailDto { Date = x.CTIME, Description = $"{x.TIMELENGTH}秒", RecordType = FollowUpRecordType.电话.GetDescription(), User = x.BAS_INNERUSER.UNAME, Hidden = false, Eid = x.BAS_INNERUSER.EID }) .ToListAsync(); data.FollowUpRecord.Resid = resid; var level = await _cacheDomain.LevelSSO(eid); var eids = new List(); switch (level) { case RoleLevel.Self: eids.Add(eid); break; case RoleLevel.Dept: eids = await _cacheDomain.GetSalesDeptsForEid(eid); break; default: break; } orders.ForEach(x => { x.Hidden = eids.Any() && !eids.Contains(x.Eid); x.Description = x.Hidden && x.Private ? "***" : x.Description; }); data.FollowUpRecord.FollowUpRecordDetails.AddRange(orders); data.FollowUpRecord.FollowUpRecordDetails.AddRange(calls); var capitalList = await _cacheDomain.GetSubComTypeListByComType(data.Appid, ComType.CustomerZJL); var customerCapital = await _crmRepository.GetRepository().Query() .Include(x => x.RES_CUSTOMERDETAIL) .Where(x => x.RESID == resid) .Select(x => x.RES_CUSTOMERDETAIL.AMOUNTTYPEID) .FirstOrDefaultAsync(); data.WxworkCustomerInfo.CustomerCapital = customerCapital; return data; } private async Task GetAppidByEid(decimal eid) { var deptResult = await _httpClient.GetAsync>>($"{_systemConfig.ZxdCrmUrl}/Api/SSO/GetDeptNameByEid?eidList={eid}"); if (deptResult.Code == 0) { return deptResult.Data[0].AppId ?? ""; } else { throw new ApiException($"当前客服获取Appid失败,请稍后操作!"); } } public async Task> GetCapitalSelect(decimal eid) { var appid = await GetAppidByEid(eid); var capitalList = await _cacheDomain.GetSubComTypeListByComType(appid, ComType.CustomerZJL); return capitalList.Select(x => new SelectItem(x.SUBTYPECODE, x.SUBTYPENAME)).ToList(); } public async Task> GetOrderTypes() { return await _crmRepository.GetRepository().Query() .Where(x => x.ISSHOWFOLLOWUP == 1) .Select(x => new OrderTypeDto { Id = x.SUBTYPEID, TypeName = x.FOLLOWUPNAME }).ToListAsync(); } public async Task UpdateCapital(UpdateCapitalDto dto) { await _cacheDomain.SetApp(_crmRepository, dto.Appid); var capitalList = await _cacheDomain.GetSubComTypeListByComType(dto.Appid, ComType.CustomerZJL); var capital = capitalList.FirstOrDefault(x => x.SUBTYPENAME == dto.Capital); if (capital == null) { throw new ApiException($"资金量配置不存在或已删除!"); } var customerDetail = await _crmRepository.GetRepository().Query() .Where(x => x.RESID == dto.Resid) .FirstOrDefaultAsync(); if (customerDetail == null) { throw new ApiException($"客户不存在或已删除!"); } customerDetail.AMOUNTTYPEID = capital.SUBTYPECODE; await _crmRepository.GetRepository().UpdateAsync(customerDetail, x => new { x.AMOUNTTYPEID }); return true; } public async Task CreateCustomerOrder(CreateCustomerOrderDto dto) { var now = DateTime.Now; await _cacheDomain.SetApp(_crmRepository, dto.Appid); var mapDto = new CustomerMapDto() { RESID = dto.Resid, STRCONTENT = dto.Content }; var subTypeid = dto.Typeid; using var transaction = await _crmRepository.BeginTransactionAsync(); try { var subMemoType = await _crmRepository.GetRepository().Query() .Where(x => x.SUBTYPEID == subTypeid) .FirstOrDefaultAsync(); if (subMemoType == null) { throw new Exception("工单小类不合法"); } var memoType = await _crmRepository.GetRepository().Query() .Where(x => x.TYPEID == subMemoType.MEMOTYPEID) .FirstOrDefaultAsync(); if (memoType == null) { throw new Exception("工单大类不合法"); } // 添加企微标签 if (dto.AddTag.HasValue && dto.AddTag.Value) { await AddTag(dto.Resid, subMemoType.FOLLOWUPNAME ?? subMemoType.TYPENAME); } var todayRecord = await _crmRepository.GetRepository().Query() .Where(x => x.RESID == dto.Resid && x.SALESEID == dto.Eid) .OrderByDescending(p => p.TIMESTART).FirstOrDefaultAsync(); if (todayRecord != null) { DateTime? dt = todayRecord.TIMESTART.HasValue ? todayRecord.TIMESTART.Value.AddSeconds(Convert.ToDouble(todayRecord.TIMELENGTH ?? 0)) : (DateTime?)null; if (dt.HasValue && dt.Value > now.AddMinutes(-30)) { mapDto.CALLTIME = todayRecord.TIMESTART; mapDto.CALLTIMEEND = todayRecord.TIMESTART.HasValue ? todayRecord.TIMESTART.Value.AddSeconds(Convert.ToDouble(todayRecord.TIMELENGTH ?? 0)) : (DateTime?)null; mapDto.RECORDID = todayRecord.RECORDID; mapDto.COID = todayRecord.COID; } } ORD_MEMOCONTENT entry = new() { CONTENTID = await _crmRepository.GetSeqAsync(PKIDType.LargeTable), STRCONTENT = dto.Content, CTIME = DateTime.Now }; await _crmRepository.GetRepository().InsertAsync(entry); var userid = await _crmRepository.GetRepository().Query() .Where(x => x.EID == dto.Eid) .Select(x => x.PKID) .FirstOrDefaultAsync(); CACHE_ORD_MEMO cacheOrd = new(); mapDto.INNERUSERID = userid; mapDto.MEMOCONTENTID = entry.CONTENTID; mapDto.MEMOID = await _crmRepository.GetSeqAsync(PKIDType.LargeTable); mapDto.CTIME = entry.CTIME; mapDto.MEMOSTYLEID = subMemoType.MEMOSTYLEID; mapDto.MEMOTYPEID = subMemoType.MEMOTYPEID; mapDto.MEMOSUBTYPEID = subMemoType.SUBTYPEID; mapDto.BUSINESSID = 1; switch (memoType.MEMO_TYPE) { case (int)EnumMemoType.销售工单: ORD_SALEMEMO newModel = _mapper.Map(mapDto); await _crmRepository.GetRepository().InsertAsync(newModel, true); cacheOrd.MEMOID = newModel.MEMOID; break; case (int)EnumMemoType.服务工单: ORD_SERVICEMEMO serviceModel = _mapper.Map(mapDto); await _crmRepository.GetRepository().InsertAsync(serviceModel, true); cacheOrd.MEMOID = serviceModel.MEMOID; break; case (int)EnumMemoType.意向工单: ORD_PURPOSEMEMO purpostModel = _mapper.Map(mapDto); await _crmRepository.GetRepository().InsertAsync(purpostModel, true); cacheOrd.MEMOID = purpostModel.MEMOID; break; case (int)EnumMemoType.特殊订单: ORD_SPECIALMEMO specialModel = _mapper.Map(mapDto); await _crmRepository.GetRepository().InsertAsync(specialModel, true); cacheOrd.MEMOID = specialModel.MEMOID; break; } cacheOrd.MEMOSTYLEID = mapDto.MEMOSTYLEID; cacheOrd.MTYPEID = memoType.MEMO_TYPE; cacheOrd.MEMOCONTENTID = entry.CONTENTID; cacheOrd.MEMOTYPEID = subMemoType.MEMOTYPEID; cacheOrd.MEMOSUBTYPEID = subMemoType.SUBTYPEID; cacheOrd.INNERUSERID = userid; cacheOrd.CTIME = now; cacheOrd.BUSINESSID = 1; cacheOrd.RESID = dto.Resid; await _crmRepository.GetRepository().InsertAsync(cacheOrd); await transaction.CommitAsync(); return true; } catch (Exception ex) { await transaction.RollbackAsync(); await transaction.DisposeAsync(); Log.Error(ex, "创建工单报错!"); throw; } } private async Task AddTag(string? resid, string? tag) { //todo: 添加企微标签 } private async Task CreateWxworkCustomer(string? appid, string? resId, decimal? eid, string? wwappid, string? campaignId, string? appuserid, string? unionid) { await _cacheDomain.SetApp(_crmRepository, appid); var appcode = await _cacheDomain.GetCodeByAppid(appid); var transaction = await _crmRepository.BeginTransactionAsync(); try { if (!await _crmRepository.GetRepository().Query().AnyAsync(x => x.RESID == unionid)) { //插入资源统计表 CACHE_RES_RESOURCE_COUNT ressourceCount = new CACHE_RES_RESOURCE_COUNT { RESID = unionid, }; await _crmRepository.GetRepository().InsertAsync(ressourceCount); } if (!await _crmRepository.GetRepository().Query().AnyAsync(x => x.RESID == unionid)) { RES_CUSTOMER customer = new RES_CUSTOMER { RESID = unionid, CUSTOMERID = string.IsNullOrEmpty(resId)?unionid:resId, CTIME = DateTime.Now, CUSTOMERFROM = campaignId, TYPE = 3 }; await _crmRepository.GetRepository().InsertAsync(customer); } if (!await _crmRepository.GetRepository().Query().AnyAsync(x => x.RESID == unionid)) { RES_CUSTOMERDETAIL customerDetail = new RES_CUSTOMERDETAIL { RESID = unionid }; await _crmRepository.GetRepository().InsertAsync(customerDetail); } var qw = await _crmRepository.GetRepository().FirstOrDefaultAsync(n => n.RESID == unionid && n.APPUSERID == appuserid); if (qw == null) { qw = new RES_CUSTOMERQW { RESID = unionid, APPID = wwappid, APPUSERID = appuserid, CTIME = DateTime.Now, CUSTOMERFROM = campaignId, CREATETIME = DateTime.Now, HHUSERID = "", SCENE = "", SCENENAME = "未明来源", SCENETYPE = 0, SCENETYPENAME = "其他" }; qw = await _crmRepository.GetRepository().InsertAsync(qw); } var qwEid = await _crmRepository.GetRepository().FirstOrDefaultAsync(n => n.RESID == unionid && n.APPUSERID == appuserid); if (qwEid == null) { var innerUser = await _crmRepository.GetRepository().FirstOrDefaultAsync(n => n.EID == eid); qwEid = new RES_CUSTOMERQW_EID { RESID = unionid, APPID = wwappid, APPUSERID = appuserid, CTIME = DateTime.Now, INNERUSERID = innerUser?.PKID, EID = eid, UTIME = DateTime.Now }; await _crmRepository.GetRepository().InsertAsync(qwEid); } await BindWwUserName(resId, unionid, appcode); await transaction.CommitAsync(); return qw; } catch (Exception ex) { await transaction.RollbackAsync(); await transaction.DisposeAsync(); Log.Error(ex, "创建客户信息报错!"); throw; } } /// /// 绑定企业微信 /// /// /// /// private async Task BindWwUserName(string resId, string userId, string? companyCode) { var ret = await UpdateResIdByWwUserName(resId, userId); if (ret) { var host = _systemConfig.DataSyncApiUrl; var url = host + "/api/DataSync"; var data = new { resid = resId, userid = userId, deptcode = companyCode }; var para = new { bidatatype = "Server_WwextUserResid", deptcode = companyCode, jsontext = data.ToJson() }; var result = await _httpClient.PostAsync(url, para); if (!result.Result) { Log.Error("同步到中心点异常:" + para.ToJson()); } } } private async Task UpdateResIdByWwUserName(string resId, string userId) { try { decimal? fromEid = null; decimal? toEid = null; var myRes = await _crmRepository.GetRepository().FirstOrDefaultAsync(p => p.RESID == resId); //如果不是空,说明可以找到分配归属 if (myRes != null) { var user = await _crmRepository.GetRepository().FirstOrDefaultAsync(x => x.PKID == myRes.INNERUSERID); //找到分配归属EID if (user != null) { fromEid = user.EID; } } await UpdateResIdByWwUserName(resId, userId, fromEid, toEid); //给res_customerdetial的isbound是否绑定微信做标记 await UpdateIsBoundByResId(resId); return true; } catch (Exception e) { Log.Error("resid:" + resId + ",错误:" + e.ToString()); return false; } } private async Task UpdateResIdByWwUserName(string resId, string userId, decimal? fromEid = null, decimal? toEid = null) { try { var sql = "select count(*) from ww_extuser_resid where userid=:userid and resid=:resid"; var param = new List() { new OracleParameter() { ParameterName="resid", OracleDbType = OracleDbType.Varchar2, Value=resId }, new OracleParameter() { ParameterName="userid", OracleDbType = OracleDbType.Varchar2, Value=userId } }; var scalar = await _crmRepository.ExecuteSqlCommandAsync(CommandType.Text, sql, param.ToArray()); var isExists = int.Parse(scalar.ToString()); if (isExists > 0) { //已经存在,修改 //var sqlu = "update ww_extuser_resid set userid = :userid where resid = :resid"; //var parau = new List() //{ // new OracleParameter() { ParameterName="resid",OracleType = OracleType.VarChar,Value=resId }, // new OracleParameter() { ParameterName="userid",OracleType = OracleType.VarChar,Value=userId } //}; //OracleHelper.ExecuteNonQuery(CommandType.Text, sqlu, parau.ToArray()); } else { //添加 var sqla = string.Empty; if (fromEid.HasValue && toEid.HasValue) { sqla = "insert into ww_extuser_resid(userid,resid,ctime,fromeid,toeid) values(:userid,:resid,sysdate,:fromeid,:toeid)"; } else { sqla = "insert into ww_extuser_resid(userid,resid,ctime) values(:userid,:resid,sysdate)"; } var paraa = new List() { new OracleParameter() { ParameterName="resid",OracleDbType = OracleDbType.Varchar2,Value=resId }, new OracleParameter() { ParameterName="userid",OracleDbType = OracleDbType.Varchar2,Value=userId } }; if (fromEid.HasValue && toEid.HasValue) { paraa.Add(new OracleParameter() { ParameterName = "fromeid", OracleDbType = OracleDbType.Decimal, Value = fromEid.Value }); paraa.Add(new OracleParameter() { ParameterName = "toeid", OracleDbType = OracleDbType.Decimal, Value = toEid.Value }); } await _crmRepository.ExecuteSqlCommandAsync(CommandType.Text, sqla, paraa.ToArray()); } } catch (Exception ex) { Log.Error(ex, $"更新资源绑定信息报错!{resId},{userId},{fromEid},{toEid}"); throw; } } /// /// 修改客户 绑定状态 /// /// private async Task UpdateIsBoundByResId(string resId) { try { var sql = "update res_customerdetail set IsBound=1 where resid=:resid"; var param = new List() { new OracleParameter() { ParameterName="resid",OracleDbType = OracleDbType.Varchar2,Value=resId } }; var scalar = await _crmRepository.ExecuteSqlCommandAsync(CommandType.Text, sql, param.ToArray()); } catch (Exception ex) { Log.Error(ex, "修改客户绑定状态报错!"); throw; } } } }