crm.core/code/Crm.Core.External.Domain/CustomerDomain.cs

549 lines
24 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<CrmDbContext> _crmRepository;
private readonly IMapper _mapper;
private readonly SystemConfig _systemConfig;
public CustomerDomain(ICacheDomain cacheDomain,
IHttpClient httpClient,
IConfiguration configuration,
IOracleRepository<CrmDbContext> crmRepository,
IMapper mapper)
{
_cacheDomain = cacheDomain;
_httpClient = httpClient;
_configuration = configuration;
_crmRepository = crmRepository;
_systemConfig = _configuration.GetSection("SystemConfig").Get<SystemConfig>();
_mapper = mapper;
}
public async Task<WxworkCustomerDto> 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<RES_CUSTOMERQW>().Query()
.FirstOrDefaultAsync(x => x.APPUSERID == userid && x.APPID == wwappid);
var result = await _httpClient.GetAsync<ApiResult<UserInfoDto>>($"{_systemConfig.ZxdCrmUrl}/api/UserInfo?appid={wwappid}_1&appuserid={userid}");
var resid = "";
var unionid = "";
var resids = new List<string>();
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<RES_CUSTOMER>().Query()
.Where(x => x.RESID == resid)
.Select(x => x.CUSTOMERID)
.FirstOrDefaultAsync();
resids = await _crmRepository.GetRepository<RES_CUSTOMER>().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<ORD_MEMOSUBTYPE>().Query()
.Where(x => x.ISSHOWFOLLOWUP == 1)
.Select(x => x.SUBTYPEID)
.ToListAsync();
var orders = await _crmRepository.GetRepository<CACHE_ORD_MEMO>().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<CSVR_CALLRECORD>().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<decimal>();
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<RES_CUSTOMER>().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<string> GetAppidByEid(decimal eid)
{
var deptResult = await _httpClient.GetAsync<ApiResult<List<DeptInfoDto>>>($"{_systemConfig.ZxdCrmUrl}/Api/SSO/GetDeptNameByEid?eidList={eid}");
if (deptResult.Code == 0)
{
return deptResult.Data[0].AppId ?? "";
}
else
{
throw new ApiException($"当前客服获取Appid失败请稍后操作");
}
}
public async Task<List<SelectItem>> 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<List<OrderTypeDto>> GetOrderTypes()
{
return await _crmRepository.GetRepository<ORD_MEMOSUBTYPE>().Query()
.Where(x => x.ISSHOWFOLLOWUP == 1)
.Select(x => new OrderTypeDto
{
Id = x.SUBTYPEID,
TypeName = x.FOLLOWUPNAME
}).ToListAsync();
}
public async Task<bool> 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<RES_CUSTOMERDETAIL>().Query()
.Where(x => x.RESID == dto.Resid)
.FirstOrDefaultAsync();
if (customerDetail == null)
{
throw new ApiException($"客户不存在或已删除!");
}
customerDetail.AMOUNTTYPEID = capital.SUBTYPECODE;
await _crmRepository.GetRepository<RES_CUSTOMERDETAIL>().UpdateAsync(customerDetail, x => new
{
x.AMOUNTTYPEID
});
return true;
}
public async Task<bool> 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<ORD_MEMOSUBTYPE>().Query()
.Where(x => x.SUBTYPEID == subTypeid)
.FirstOrDefaultAsync();
if (subMemoType == null)
{
throw new Exception("工单小类不合法");
}
var memoType = await _crmRepository.GetRepository<ORD_MEMOTYPE>().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<CSVR_TODAYRECORD>().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<ORD_MEMOCONTENT>().InsertAsync(entry);
var userid = await _crmRepository.GetRepository<BAS_INNERUSER>().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<CustomerMapDto, ORD_SALEMEMO>(mapDto);
await _crmRepository.GetRepository<ORD_SALEMEMO>().InsertAsync(newModel, true);
cacheOrd.MEMOID = newModel.MEMOID;
break;
case (int)EnumMemoType.:
ORD_SERVICEMEMO serviceModel = _mapper.Map<CustomerMapDto, ORD_SERVICEMEMO>(mapDto);
await _crmRepository.GetRepository<ORD_SERVICEMEMO>().InsertAsync(serviceModel, true);
cacheOrd.MEMOID = serviceModel.MEMOID;
break;
case (int)EnumMemoType.:
ORD_PURPOSEMEMO purpostModel = _mapper.Map<CustomerMapDto, ORD_PURPOSEMEMO>(mapDto);
await _crmRepository.GetRepository<ORD_PURPOSEMEMO>().InsertAsync(purpostModel, true);
cacheOrd.MEMOID = purpostModel.MEMOID;
break;
case (int)EnumMemoType.:
ORD_SPECIALMEMO specialModel = _mapper.Map<CustomerMapDto, ORD_SPECIALMEMO>(mapDto);
await _crmRepository.GetRepository<ORD_SPECIALMEMO>().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<CACHE_ORD_MEMO>().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<RES_CUSTOMERQW> 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<CACHE_RES_RESOURCE_COUNT>().Query().AnyAsync(x => x.RESID == unionid))
{
//插入资源统计表
CACHE_RES_RESOURCE_COUNT ressourceCount = new CACHE_RES_RESOURCE_COUNT
{
RESID = unionid,
};
await _crmRepository.GetRepository<CACHE_RES_RESOURCE_COUNT>().InsertAsync(ressourceCount);
}
if (!await _crmRepository.GetRepository<RES_CUSTOMER>().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<RES_CUSTOMER>().InsertAsync(customer);
}
if (!await _crmRepository.GetRepository<RES_CUSTOMERDETAIL>().Query().AnyAsync(x => x.RESID == unionid))
{
RES_CUSTOMERDETAIL customerDetail = new RES_CUSTOMERDETAIL
{
RESID = unionid
};
await _crmRepository.GetRepository<RES_CUSTOMERDETAIL>().InsertAsync(customerDetail);
}
var qw = await _crmRepository.GetRepository<RES_CUSTOMERQW>().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<RES_CUSTOMERQW>().InsertAsync(qw);
}
var qwEid = await _crmRepository.GetRepository<RES_CUSTOMERQW_EID>().FirstOrDefaultAsync(n => n.RESID == unionid && n.APPUSERID == appuserid);
if (qwEid == null)
{
var innerUser = await _crmRepository.GetRepository<BAS_INNERUSER>().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<RES_CUSTOMERQW_EID>().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;
}
}
/// <summary>
/// 绑定企业微信
/// </summary>
/// <param name="resId"></param>
/// <param name="userId"></param>
/// <param name="companyCode"></param>
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<RetMsg>(url, para);
if (!result.Result)
{
Log.Error("同步到中心点异常:" + para.ToJson());
}
}
}
private async Task<bool> UpdateResIdByWwUserName(string resId, string userId)
{
try
{
decimal? fromEid = null;
decimal? toEid = null;
var myRes = await _crmRepository.GetRepository<RES_MYALLOCATERES>().FirstOrDefaultAsync(p => p.RESID == resId);
//如果不是空,说明可以找到分配归属
if (myRes != null)
{
var user = await _crmRepository.GetRepository<BAS_INNERUSER>().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<OracleParameter>()
{
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<OracleParameter>()
//{
// 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<OracleParameter>()
{
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;
}
}
/// <summary>
/// 修改客户 绑定状态
/// </summary>
/// <param name="resId"></param>
private async Task UpdateIsBoundByResId(string resId)
{
try
{
var sql = "update res_customerdetail set IsBound=1 where resid=:resid";
var param = new List<OracleParameter>()
{
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;
}
}
}
}