From 92e704206a64f4256e9fd8e9f738d6d3b4c84155 Mon Sep 17 00:00:00 2001
From: sunpengfei <i@angelzzz.com>
Date: 星期五, 06 六月 2025 17:21:40 +0800
Subject: [PATCH] feat:推广相关接口

---
 LifePayment/LifePayment.Application.Contracts/Promoter/IPromoterService.cs                         |   75 +++
 LifePayment/LifePayment.Domain/LifePay/LifePayChannles.cs                                          |   20 
 LifePayment/LifePayment.Host/LifePaymentServices.Application.Contracts.xml                         |  275 +++++++++++
 LifePayment/LifePayment.HttpApi/LifePay/SyncController.cs                                          |    1 
 LifePayment/LifePayment.Domain.Shared/Enum/LifePay/LifePayChannelConsultationFollowupStatus.cs     |   31 +
 LifePayment/LifePayment.Application.Contracts/Promoter/ChannelConsultationDto.cs                   |  180 +++++++
 LifePayment/LifePayment.Domain/LifePay/LifePayChannelConsultation.cs                               |   95 ++++
 LifePayment/LifePayment.EntityFrameworkCore/LifePaymentServicesDbContext.cs                        |    6 
 LifePayment/LifePayment.HttpApi/LifePay/PromoterController.cs                                      |  124 +++++
 LifePayment/LifePayment.Domain.Shared/Enum/LifePay/LifePayChannelAgentType.cs                      |   29 +
 LifePayment/LifePayment.Application/LifePaymentServicesApplicationModuleAutoMapperProfile.cs       |   10 
 LifePayment/LifePayment.Application/Promoter/PromoterService.cs                                    |  285 ++++++++++++
 LifePayment/LifePayment.EntityFrameworkCore/ModelConfigure/ModelDbContextModelBuilderExtensions.cs |    4 
 LifePayment/LifePayment.Domain/LifePay/LifePayPromoter.cs                                          |   61 ++
 LifePayment/LifePayment.Host/LifePaymentService.HttpApi.xml                                        |   50 ++
 LifePayment/LifePayment.Application.Contracts/Promoter/PromoterDto.cs                              |   89 +++
 16 files changed, 1,333 insertions(+), 2 deletions(-)

diff --git a/LifePayment/LifePayment.Application.Contracts/Promoter/ChannelConsultationDto.cs b/LifePayment/LifePayment.Application.Contracts/Promoter/ChannelConsultationDto.cs
new file mode 100644
index 0000000..92fd780
--- /dev/null
+++ b/LifePayment/LifePayment.Application.Contracts/Promoter/ChannelConsultationDto.cs
@@ -0,0 +1,180 @@
+锘縰sing LifePayment.Domain.Shared;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ZeroD.Util;
+
+namespace LifePayment.Application.Contracts
+{
+    public class GetChannelConsultationsInput : PageInput
+    {
+        /// <summary>
+        /// 鍒涘缓鐨勫紑濮嬫椂闂�
+        /// </summary>
+        public DateTime? StartDate { get; set; }
+
+        /// <summary>
+        /// 鍒涘缓鐨勭粨鏉熸椂闂�
+        /// </summary>
+        public DateTime? EndDate { get; set; }
+
+        /// <summary>
+        /// 鎼滅储鍏抽敭璇�
+        /// </summary>
+        public string SearchKey { get; set; }
+    }
+
+    public class ChannelConsultationDto
+    {
+        /// <summary>
+        /// Id
+        /// </summary>
+        public Guid Id { get; set; }
+
+        /// <summary>
+        /// 鍜ㄨ鏃堕棿
+        /// </summary>
+        public DateTime CreationTime { get; set; }
+
+        /// <summary>
+        /// 鍜ㄨ浜�
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 浠g悊绫诲瀷
+        /// </summary>
+        public LifePayChannelAgentType AgentType { get; set; }
+
+        /// <summary>
+        /// 鑱旂郴鏂瑰紡
+        /// </summary>
+        public string PhoneNumber { get; set; }
+
+        /// <summary>
+        /// 鍏徃鍚嶇О
+        /// </summary>
+        public string CompanyName { get; set; }
+
+        /// <summary>
+        /// 瀹㈡埛璧勬簮
+        /// </summary>
+        public string CustomerResources { get; set; }
+
+        /// <summary>
+        /// ID
+        /// </summary>
+        public string PromoterIdNumber { get; set; }
+
+        /// <summary>
+        /// 鎺ㄥ箍鍛�
+        /// </summary>
+        public string PromoterName { get; set; }
+
+        /// <summary>
+        /// 鑱旂郴鏂瑰紡
+        /// </summary>
+        public string PromoterPhoneNumber { get; set; }
+
+        /// <summary>
+        /// 鍥炶鐘舵��
+        /// </summary>
+        public LifePayChannelConsultationFollowupStatus FollowupStatus { get; set; }
+
+        /// <summary>
+        /// 鏈�杩戝洖璁�
+        /// </summary>
+        public DateTime? LastFollowupTime { get; set; }
+
+        /// <summary>
+        /// 鍥炶璁板綍
+        /// </summary>
+        public string FollowupRemark { get; set; }
+    }
+
+    public class CreateChannelConsultationInput
+    {
+        /// <summary>
+        /// 瀹㈡埛绔敤鎴稩d 濡傛湁
+        /// </summary>
+        public Guid? UserId { get; set; }
+
+        /// <summary>
+        /// 鎺ㄥ箍浜篒d
+        /// </summary>
+        public string IdNumber { get; set; }
+
+        /// <summary>
+        /// 鍜ㄨ浜�
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 浠g悊绫诲瀷
+        /// </summary>
+        public LifePayChannelAgentType? AgentType { get; set; }
+
+        /// <summary>
+        /// 鑱旂郴鏂瑰紡
+        /// </summary>
+        public string PhoneNumber { get; set; }
+
+        /// <summary>
+        /// 鍏徃鍚嶇О
+        /// </summary>
+        public string CompanyName { get; set; }
+
+        /// <summary>
+        /// 瀹㈡埛璧勬簮
+        /// </summary>
+        public string CustomerResources { get; set; }
+    }
+
+    public class CreateChannelConsultationFollowupInput
+    {
+        /// <summary>
+        /// 娓犻亾鍜ㄨId
+        /// </summary>
+        public Guid ChannelConsultationId { get; set; }
+
+        /// <summary>
+        /// 鍥炶鐘舵��
+        /// </summary>
+        public LifePayChannelConsultationFollowupStatus? FollowupStatus { get; set; }
+
+        /// <summary>
+        /// 鍥炶璁板綍
+        /// </summary>
+        public string FollowupRemark { get; set; }
+    }
+
+    public class ChannelConsultationFollowupDto
+    {
+        /// <summary>
+        /// 鍥炶浜篒d
+        /// </summary>
+        public Guid? CreatorId { get; set; }
+
+        /// <summary>
+        /// 鍥炶浜�
+        /// </summary>
+        public string Creator { get; set; }
+
+        /// <summary>
+        /// 鍥炶鐘舵��
+        /// </summary>
+        public LifePayChannelConsultationFollowupStatus? FollowupStatus { get; set; }
+
+        /// <summary>
+        /// 鍥炶璁板綍
+        /// </summary>
+        public string FollowupRemark { get; set; }
+
+        /// <summary>
+        /// 鍜ㄨ鏃堕棿
+        /// </summary>
+        public DateTime CreationTime { get; set; }
+    }
+}
diff --git a/LifePayment/LifePayment.Application.Contracts/Promoter/IPromoterService.cs b/LifePayment/LifePayment.Application.Contracts/Promoter/IPromoterService.cs
new file mode 100644
index 0000000..ff7afbd
--- /dev/null
+++ b/LifePayment/LifePayment.Application.Contracts/Promoter/IPromoterService.cs
@@ -0,0 +1,75 @@
+锘縰sing AutoMapper;
+using LifePayment.Domain.Shared;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Services;
+using Volo.Abp.AutoMapper;
+using Volo.Abp.Users;
+using ZeroD.Util;
+
+namespace LifePayment.Application.Contracts
+{
+    public interface IPromoterService : IApplicationService
+    {
+        #region 鏌ヨ
+
+        /// <summary>
+        /// 鑾峰彇鎺ㄥ箍鍛樺垪琛�
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        Task<PageOutput<PromoterDto>> GetPromoters(GetPromotersInput input);
+
+        /// <summary>
+        /// 鑾峰彇娓犻亾鍜ㄨ鍒楄〃
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        Task<PageOutput<ChannelConsultationDto>> GetChannelConsultation(GetChannelConsultationsInput input);
+
+        /// <summary>
+        /// 鑾峰彇娓犻亾鍜ㄨ鍥炶璁板綍
+        /// </summary>
+        /// <param name="id">娓犻亾鍜ㄨId</param>
+        /// <returns></returns>
+        Task<List<ChannelConsultationFollowupDto>> GetChannelConsultationFollowupList(Guid id);
+
+        #endregion
+
+        #region 鍐欏叆
+
+        /// <summary>
+        /// 鍒涘缓鎴栨洿鏂版帹骞垮憳
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        /// <exception cref="FormatException"></exception>
+        Task<Guid> CreateOrUpdatePromoter(CreateOrUpdatePromoterInput input);
+
+        /// <summary>
+        /// 鐐瑰嚮鏁�+1
+        /// </summary>
+        /// <param name="idnumber"></param>
+        /// <returns></returns>
+        Task SetClickCount(string idnumber);
+
+        /// <summary>
+        /// 鐢宠娓犻亾鍜ㄨ
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        Task<Guid> CreateChannelConsultation(CreateChannelConsultationInput input);
+
+        /// <summary>
+        /// 鏂板鍥炶
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        Task<Guid> CreateChannelConsultationFollowup(CreateChannelConsultationFollowupInput input);
+
+        #endregion
+    }
+}
diff --git a/LifePayment/LifePayment.Application.Contracts/Promoter/PromoterDto.cs b/LifePayment/LifePayment.Application.Contracts/Promoter/PromoterDto.cs
new file mode 100644
index 0000000..9878470
--- /dev/null
+++ b/LifePayment/LifePayment.Application.Contracts/Promoter/PromoterDto.cs
@@ -0,0 +1,89 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ZeroD.Util;
+
+namespace LifePayment.Application.Contracts
+{
+    public class GetPromotersInput : PageInput
+    {
+    }
+
+    public class PromoterDto
+    {
+        /// <summary>
+        /// Id
+        /// </summary>
+        public Guid Id { get; set; }
+
+        /// <summary>
+        /// 鍜ㄨ鏃堕棿
+        /// </summary>
+        public DateTime CreationTime { get; set; }
+
+        /// <summary>
+        /// ID
+        /// </summary>
+        public string IdNumber { get; set; }
+
+        /// <summary>
+        /// 鎺ㄥ箍鍛�
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 鑱旂郴鏂瑰紡
+        /// </summary>
+        public string PhoneNumber { get; set; }
+
+        /// <summary>
+        /// 鐐瑰嚮鏁�
+        /// </summary>
+        public int ClickCount { get; set; }
+
+        /// <summary>
+        /// 鐢宠鏁�
+        /// </summary>
+        public int ApplyCount { get; set; }
+
+        /// <summary>
+        /// 澶囨敞
+        /// </summary>
+        public string Remark { get; set; }
+    }
+
+    public class CreateOrUpdatePromoterInput
+    {
+        /// <summary>
+        /// Id
+        /// </summary>
+        public Guid? Id { get; set; }
+
+        /// <summary>
+        /// 瀹㈡埛绔敤鎴稩d 濡傛湁
+        /// </summary>
+        public Guid? UserId { get; set; }
+
+        /// <summary>
+        /// ID
+        /// </summary>
+        public string IdNumber { get; set; }
+
+        /// <summary>
+        /// 鎺ㄥ箍鍛�
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 鑱旂郴鏂瑰紡
+        /// </summary>
+        public string PhoneNumber { get; set; }
+
+        /// <summary>
+        /// 澶囨敞
+        /// </summary>
+        public string Remark { get; set; }
+    }
+}
diff --git a/LifePayment/LifePayment.Application/LifePaymentServicesApplicationModuleAutoMapperProfile.cs b/LifePayment/LifePayment.Application/LifePaymentServicesApplicationModuleAutoMapperProfile.cs
index 0babb20..8dce535 100644
--- a/LifePayment/LifePayment.Application/LifePaymentServicesApplicationModuleAutoMapperProfile.cs
+++ b/LifePayment/LifePayment.Application/LifePaymentServicesApplicationModuleAutoMapperProfile.cs
@@ -2,6 +2,7 @@
 using LifePayment.Application.Contracts;
 using LifePayment.Application.Contracts.Sync;
 using LifePayment.Domain;
+using LifePayment.Domain.LifePay;
 using LifePayment.Domain.Models;
 
 namespace LifePayment.Application
@@ -27,6 +28,15 @@
             CreateMap<SyncLifePayChannlesRake, SyncLifePayChannlesRake>(MemberList.None);
             CreateMap<SyncLifePayConsumption, SyncLifePayConsumption>(MemberList.None);
             CreateMap<SyncLifePayExpensesReceipts, SyncLifePayExpensesReceipts>(MemberList.None);
+
+
+            CreateMap<LifePayPromoter, PromoterDto>(MemberList.None);
+            CreateMap<CreateOrUpdatePromoterInput, LifePayPromoter>(MemberList.None);
+
+            CreateMap<LifePayChannelConsultation, ChannelConsultationDto>(MemberList.None);
+            CreateMap<CreateChannelConsultationInput, LifePayChannelConsultation>(MemberList.None);
+
+            CreateMap<CreateChannelConsultationFollowupInput, LifePayChannelConsultationFollowup>(MemberList.None);
         }
     }
 }
\ No newline at end of file
diff --git a/LifePayment/LifePayment.Application/Promoter/PromoterService.cs b/LifePayment/LifePayment.Application/Promoter/PromoterService.cs
new file mode 100644
index 0000000..0df452f
--- /dev/null
+++ b/LifePayment/LifePayment.Application/Promoter/PromoterService.cs
@@ -0,0 +1,285 @@
+锘縰sing AutoMapper.QueryableExtensions;
+using LifePayment.Application.Contracts;
+using LifePayment.Domain;
+using LifePayment.Domain.LifePay;
+using LifePayment.Domain.Models;
+using LifePayment.Domain.Shared;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Logging;
+using Nest;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Services;
+using Volo.Abp.AutoMapper;
+using Volo.Abp.Domain.Repositories;
+using ZeroD.Util;
+
+namespace LifePayment.Application.Promoter
+{
+    /// <summary>
+    /// 鎺ㄥ箍鏈嶅姟
+    /// </summary>
+    public class PromoterService : ApplicationService, IPromoterService
+    {
+        private readonly IMapperAccessor mapperAccessor;
+        private readonly ILogger<PromoterService> logger;
+        private readonly IRepository<LifePayPromoter, Guid> lifePayPromoterRepository;
+        private readonly IRepository<LifePayChannelConsultation, Guid> lifePayChannelConsultationRepository;
+        private readonly IRepository<LifePayChannelConsultationFollowup, Guid> lifePayChannelConsultationFollowupRepository;
+        private readonly IRepository<User, Guid> userRepository;
+
+        public PromoterService(
+            IMapperAccessor mapperAccessor,
+            ILogger<PromoterService> logger,
+            IRepository<LifePayPromoter, Guid> lifePayPromoterRepository,
+            IRepository<LifePayChannelConsultation, Guid> lifePayChannelConsultationRepository,
+            IRepository<LifePayChannelConsultationFollowup, Guid> lifePayChannelConsultationFollowupRepository,
+            IRepository<User, Guid> userRepository)
+        {
+            this.mapperAccessor = mapperAccessor;
+            this.logger = logger;
+            this.lifePayPromoterRepository = lifePayPromoterRepository;
+            this.lifePayChannelConsultationRepository = lifePayChannelConsultationRepository;
+            this.lifePayChannelConsultationFollowupRepository = lifePayChannelConsultationFollowupRepository;
+            this.userRepository = userRepository;
+        }
+
+        #region 鏌ヨ
+
+        /// <summary>
+        /// 鑾峰彇鎺ㄥ箍鍛樺垪琛�
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        public async Task<PageOutput<PromoterDto>> GetPromoters(GetPromotersInput input)
+        {
+            var query = lifePayPromoterRepository.Select(it => new PromoterDto
+            {
+                Id = it.Id,
+                CreationTime = it.CreationTime,
+                IdNumber = it.IdNumber,
+                Name = it.Name,
+                PhoneNumber = it.PhoneNumber,
+                ClickCount = it.ClickCount,
+                ApplyCount = it.ApplyCount,
+                Remark = it.Remark,
+            });
+            var result = await query.GetPageResult(input.PageModel);
+            return result;
+        }
+
+        /// <summary>
+        /// 鑾峰彇娓犻亾鍜ㄨ鍒楄〃
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        public async Task<PageOutput<ChannelConsultationDto>> GetChannelConsultation(GetChannelConsultationsInput input)
+        {
+            var query = from cc in lifePayChannelConsultationRepository
+                        join p in lifePayPromoterRepository on cc.PromoterId equals p.Id into pg
+                        from pgd in pg.DefaultIfEmpty()
+                        select new ChannelConsultationDto
+                        {
+                            Id = cc.Id,
+                            CreationTime = cc.CreationTime,
+                            Name = cc.Name,
+                            AgentType = cc.AgentType,
+                            PhoneNumber = cc.PhoneNumber,
+                            CompanyName = cc.CompanyName,
+                            CustomerResources = cc.CustomerResources,
+                            PromoterIdNumber = pgd.IdNumber,
+                            PromoterName = pgd.Name,
+                            PromoterPhoneNumber = pgd.PhoneNumber,
+                            FollowupStatus = cc.FollowupStatus,
+                            LastFollowupTime = cc.LastFollowupTime,
+                            FollowupRemark = cc.FollowupRemark,
+                        };
+            if (input.StartDate.HasValue)
+            {
+                query = query.Where(s => s.CreationTime >= input.StartDate);
+            }
+
+            if (input.EndDate.HasValue)
+            {
+                query = query.Where(s => s.CreationTime <= input.EndDate);
+            }
+
+            if (!string.IsNullOrEmpty(input.SearchKey))
+            {
+                query = query.Where(s =>
+                    s.Name.Contains(input.SearchKey)
+                    || s.PhoneNumber.Contains(input.SearchKey)
+                    || s.Name.Contains(input.SearchKey)
+                    || s.PhoneNumber.Contains(input.SearchKey));
+            }
+
+            var result = await query.GetPageResult(input.PageModel);
+            return result;
+        }
+
+        /// <summary>
+        /// 鑾峰彇娓犻亾鍜ㄨ鍥炶璁板綍
+        /// </summary>
+        /// <param name="id">娓犻亾鍜ㄨId</param>
+        /// <returns></returns>
+        public async Task<List<ChannelConsultationFollowupDto>> GetChannelConsultationFollowupList(Guid id)
+        {
+            var query = from f in lifePayChannelConsultationFollowupRepository
+                        join u in userRepository on f.CreatorId equals u.Id into ug
+                        from ugd in ug.DefaultIfEmpty()
+                        where f.ChannelConsultationId == id
+                        select new ChannelConsultationFollowupDto
+                        {
+                            CreatorId = f.CreatorId,
+                            Creator = ugd.Name,
+                            FollowupStatus = f.FollowupStatus,
+                            FollowupRemark = f.FollowupRemark,
+                            CreationTime = f.CreationTime,
+                        };
+            var list = await query.ToListAsync();
+            return list;
+        }
+
+        #endregion
+
+        #region 鍐欏叆
+
+        /// <summary>
+        /// 鍒涘缓鎴栨洿鏂版帹骞垮憳
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        /// <exception cref="FormatException"></exception>
+        public async Task<Guid> CreateOrUpdatePromoter(CreateOrUpdatePromoterInput input)
+        {
+            CheckExtensions.IfTrueThrowUserFriendlyException(string.IsNullOrWhiteSpace(input.Name), "璇疯緭鍏ユ帹骞夸汉");
+            CheckExtensions.IfTrueThrowUserFriendlyException(string.IsNullOrWhiteSpace(input.PhoneNumber), "璇疯緭鍏ヨ仈绯绘柟寮�");
+            if (string.IsNullOrEmpty(input.IdNumber))
+            {
+                input.IdNumber = BuildIdNumber();
+            }
+            else if (input.Id == null)
+            {
+                var exist = await lifePayPromoterRepository.FirstOrDefaultAsync(it => it.IdNumber == input.IdNumber || it.PhoneNumber == input.PhoneNumber);
+                if (exist != null)
+                {
+                    if (exist.IdNumber == input.IdNumber)
+                    {
+                        throw new FormatException("璇D宸插瓨鍦�");
+                    }
+
+                    if (exist.PhoneNumber == input.PhoneNumber)
+                    {
+                        throw new FormatException("璇ユ墜鏈哄彿宸茬敵璇�");
+                    }
+                }
+            }
+
+            if (input.Id == null)
+            {
+                var entity = new LifePayPromoter();
+                ObjectMapper.Map(input, entity);
+                await lifePayPromoterRepository.InsertAsync(entity);
+                return entity.Id;
+            }
+            else
+            {
+                var entity = await lifePayPromoterRepository.FirstOrDefaultAsync(it => it.Id == input.Id);
+                CheckExtensions.IfTrueThrowUserFriendlyException(entity == null, "璇ユ帹骞垮憳涓嶅瓨鍦�");
+                ObjectMapper.Map(input, entity);
+                await lifePayPromoterRepository.UpdateAsync(entity);
+                return entity.Id;
+            }
+        }
+
+        /// <summary>
+        /// 鐐瑰嚮鏁�+1
+        /// </summary>
+        /// <param name="idnumber"></param>
+        /// <returns></returns>
+        public async Task SetClickCount(string idnumber)
+        {
+            var entity = await lifePayPromoterRepository.FirstOrDefaultAsync(it => it.IdNumber == idnumber);
+            CheckExtensions.IfTrueThrowUserFriendlyException(entity == null, "璇ユ帹骞垮憳涓嶅瓨鍦�");
+            entity.ClickCount++;
+            await lifePayPromoterRepository.UpdateAsync(entity);
+        }
+
+        /// <summary>
+        /// 鐢宠娓犻亾鍜ㄨ
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        public async Task<Guid> CreateChannelConsultation(CreateChannelConsultationInput input)
+        {
+            CheckExtensions.IfTrueThrowUserFriendlyException(string.IsNullOrWhiteSpace(input.Name), "璇疯緭鍏ュ鍚�");
+            CheckExtensions.IfTrueThrowUserFriendlyException(string.IsNullOrWhiteSpace(input.PhoneNumber), "璇疯緭鍏ヨ仈绯绘柟寮�");
+            CheckExtensions.IfTrueThrowUserFriendlyException(input.AgentType == null, "璇烽�夋嫨浠g悊绫诲瀷");
+            CheckExtensions.IfTrueThrowUserFriendlyException(string.IsNullOrWhiteSpace(input.CustomerResources), "璇疯緭鍏ュ鎴疯祫婧�");
+
+            var entity = new LifePayChannelConsultation();
+            ObjectMapper.Map(input, entity);
+
+            if (!string.IsNullOrWhiteSpace(input.IdNumber))
+            {
+                var promoter = await lifePayPromoterRepository.FirstOrDefaultAsync(it => it.IdNumber == input.IdNumber);
+                if (promoter != null)
+                {
+                    entity.PromoterId = promoter.Id;
+                    promoter.ApplyCount++;
+                    await lifePayPromoterRepository.UpdateAsync(promoter);
+                }
+            }
+
+            await lifePayChannelConsultationRepository.InsertAsync(entity);
+
+            return entity.Id;
+        }
+
+        /// <summary>
+        /// 鏂板鍥炶
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        public async Task<Guid> CreateChannelConsultationFollowup(CreateChannelConsultationFollowupInput input)
+        {
+            CheckExtensions.IfTrueThrowUserFriendlyException(input.FollowupStatus == null, "璇烽�夋嫨鍥炶鐘舵��");
+            CheckExtensions.IfTrueThrowUserFriendlyException(string.IsNullOrWhiteSpace(input.FollowupRemark), "璇疯緭鍏ュ洖璁胯褰�");
+
+            var consultation = await lifePayChannelConsultationRepository.FirstOrDefaultAsync(it => it.Id == input.ChannelConsultationId);
+            CheckExtensions.IfTrueThrowUserFriendlyException(consultation == null, "璇ユ笭閬撳挩璇笉瀛樺湪");
+
+            var entity = new LifePayChannelConsultationFollowup();
+            ObjectMapper.Map(input, entity);
+            await lifePayChannelConsultationFollowupRepository.InsertAsync(entity);
+
+            consultation.FollowupRemark = entity.FollowupRemark;
+            consultation.FollowupStatus = entity.FollowupStatus;
+            consultation.LastFollowupTime = entity.CreationTime;
+            await lifePayChannelConsultationRepository.UpdateAsync(consultation);
+
+            return entity.Id;
+        }
+
+        #endregion
+
+        /// <summary>
+        /// 鐢熸垚Id
+        /// </summary>
+        /// <returns></returns>
+        private string BuildIdNumber()
+        {
+            var num = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
+            var exist = lifePayPromoterRepository.Any(it => it.IdNumber == num);
+            if (exist)
+            {
+                return BuildIdNumber();
+            }
+
+            return num;
+        }
+
+    }
+}
diff --git a/LifePayment/LifePayment.Domain.Shared/Enum/LifePay/LifePayChannelAgentType.cs b/LifePayment/LifePayment.Domain.Shared/Enum/LifePay/LifePayChannelAgentType.cs
new file mode 100644
index 0000000..0c3622b
--- /dev/null
+++ b/LifePayment/LifePayment.Domain.Shared/Enum/LifePay/LifePayChannelAgentType.cs
@@ -0,0 +1,29 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LifePayment.Domain.Shared
+{
+    /// <summary>
+    /// 浠g悊绫诲瀷
+    /// </summary>
+    public enum LifePayChannelAgentType
+    {
+        /// <summary>
+        /// 闆跺敭浠g悊
+        /// </summary>
+        RetailAgent = 1,
+
+        /// <summary>
+        /// 鍝佺墝浠g悊
+        /// </summary>
+        BrandAgent = 2,
+
+        /// <summary>
+        /// 鍖哄煙浠g悊
+        /// </summary>
+        AreaAgent = 3
+    }
+}
diff --git a/LifePayment/LifePayment.Domain.Shared/Enum/LifePay/LifePayChannelConsultationFollowupStatus.cs b/LifePayment/LifePayment.Domain.Shared/Enum/LifePay/LifePayChannelConsultationFollowupStatus.cs
new file mode 100644
index 0000000..d7681d8
--- /dev/null
+++ b/LifePayment/LifePayment.Domain.Shared/Enum/LifePay/LifePayChannelConsultationFollowupStatus.cs
@@ -0,0 +1,31 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LifePayment.Domain.Shared
+{
+    public enum LifePayChannelConsultationFollowupStatus
+    {
+        /// <summary>
+        /// 鏈洖璁�
+        /// </summary>
+        None = 0,
+
+        /// <summary>
+        /// 璺熻繘涓�
+        /// </summary>
+        Ing = 1,
+
+        /// <summary>
+        /// 宸叉嫆缁�
+        /// </summary>
+        Refuse = 1,
+
+        /// <summary>
+        /// 宸插紑閫�
+        /// </summary>
+        Open = 1,
+    }
+}
diff --git a/LifePayment/LifePayment.Domain/LifePay/LifePayChannelConsultation.cs b/LifePayment/LifePayment.Domain/LifePay/LifePayChannelConsultation.cs
new file mode 100644
index 0000000..ae37d7c
--- /dev/null
+++ b/LifePayment/LifePayment.Domain/LifePay/LifePayChannelConsultation.cs
@@ -0,0 +1,95 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Volo.Abp.Domain.Entities.Auditing;
+using Volo.Abp;
+using LifePayment.Domain.LifePay;
+using LifePayment.Domain.Shared;
+using LifePayment.Domain.Models;
+
+namespace LifePayment.Domain
+{
+    /// <summary>
+    /// 娓犻亾鍜ㄨ
+    /// </summary>
+    public class LifePayChannelConsultation : FullAuditedEntity<Guid>, IDataUserFilter
+    {
+        /// <summary>
+        /// 鐢ㄦ埛Id
+        /// </summary>
+        public Guid? UserId { get; set; }
+
+        /// <summary>
+        /// 鎺ㄥ箍鍛�
+        /// </summary>
+        public Guid? PromoterId { get; set; }
+
+        /// <summary>
+        /// 鎺ㄥ箍鍛�
+        /// </summary>
+        public LifePayPromoter Promoter { get; set; }
+
+        /// <summary>
+        /// 鍜ㄨ浜�
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 浠g悊绫诲瀷
+        /// </summary>
+        public LifePayChannelAgentType AgentType { get; set; }
+
+        /// <summary>
+        /// 鑱旂郴鏂瑰紡
+        /// </summary>
+        public string PhoneNumber { get; set; }
+
+        /// <summary>
+        /// 鍏徃鍚嶇О
+        /// </summary>
+        public string CompanyName { get; set; }
+
+        /// <summary>
+        /// 瀹㈡埛璧勬簮
+        /// </summary>
+        public string CustomerResources { get; set; }
+
+        /// <summary>
+        /// 鍥炶鐘舵��
+        /// </summary>
+        public LifePayChannelConsultationFollowupStatus FollowupStatus { get; set; }
+
+        /// <summary>
+        /// 鏈�杩戝洖璁�
+        /// </summary>
+        public DateTime? LastFollowupTime { get; set; }
+
+        /// <summary>
+        /// 鍥炶璁板綍
+        /// </summary>
+        public string FollowupRemark { get; set; }
+    }
+
+    /// <summary>
+    /// 娓犻亾鍜ㄨ鍥炶
+    /// </summary>
+    public class LifePayChannelConsultationFollowup : FullAuditedEntity<Guid>, IDataUserFilter
+    {
+        /// <summary>
+        /// 娓犻亾鍜ㄨId
+        /// </summary>
+        public Guid ChannelConsultationId { get; set; }
+
+        /// <summary>
+        /// 鍥炶鐘舵��
+        /// </summary>
+        public LifePayChannelConsultationFollowupStatus FollowupStatus { get; set; }
+
+        /// <summary>
+        /// 鍥炶璁板綍
+        /// </summary>
+        public string FollowupRemark { get; set; }
+    }
+}
diff --git a/LifePayment/LifePayment.Domain/LifePay/LifePayChannles.cs b/LifePayment/LifePayment.Domain/LifePay/LifePayChannles.cs
index e214888..455cd39 100644
--- a/LifePayment/LifePayment.Domain/LifePay/LifePayChannles.cs
+++ b/LifePayment/LifePayment.Domain/LifePay/LifePayChannles.cs
@@ -24,4 +24,24 @@
     public LifePayChannelsStatsEnum Status { get; set; }
 
     public LifePayChannlesTypeEnum ChannlesType { get; set; }
+
+    /// <summary>
+    /// 浠g悊绫诲瀷
+    /// </summary>
+    public LifePayChannelAgentType? AgentType { get; set; }
+
+    /// <summary>
+    /// 鍖哄煙-鐪両d
+    /// </summary>
+    public int? AreaProvinceId { get; set; }
+
+    /// <summary>
+    /// 鍖哄煙-甯侷d
+    /// </summary>
+    public int? AreaCityId { get; set; }
+
+    /// <summary>
+    /// 鎺ㄥ箍鍛業d
+    /// </summary>
+    public Guid? PromoterId { get; set; }
 }
\ No newline at end of file
diff --git a/LifePayment/LifePayment.Domain/LifePay/LifePayPromoter.cs b/LifePayment/LifePayment.Domain/LifePay/LifePayPromoter.cs
new file mode 100644
index 0000000..4c0bba0
--- /dev/null
+++ b/LifePayment/LifePayment.Domain/LifePay/LifePayPromoter.cs
@@ -0,0 +1,61 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Volo.Abp.Domain.Entities.Auditing;
+using Volo.Abp;
+
+namespace LifePayment.Domain.LifePay
+{
+    /// <summary>
+    /// 鎺ㄥ箍鍛�
+    /// </summary>
+    public class LifePayPromoter : FullAuditedEntity<Guid>, IDataUserFilter
+    {
+        public LifePayPromoter()
+        {
+            ChannelConsultations = new HashSet<LifePayChannelConsultation>();
+        }
+
+        /// <summary>
+        /// 鐢ㄦ埛Id
+        /// </summary>
+        public Guid? UserId { get; set; }
+
+        /// <summary>
+        /// ID
+        /// </summary>
+        public string IdNumber { get; set; }
+
+        /// <summary>
+        /// 鎺ㄥ箍鍛�
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 鑱旂郴鏂瑰紡
+        /// </summary>
+        public string PhoneNumber { get; set; }
+
+        /// <summary>
+        /// 鐐瑰嚮鏁�
+        /// </summary>
+        public int ClickCount { get; set; }
+
+        /// <summary>
+        /// 鐢宠鏁�
+        /// </summary>
+        public int ApplyCount { get; set; }
+
+        /// <summary>
+        /// 澶囨敞
+        /// </summary>
+        public string Remark { get; set; }
+
+        /// <summary>
+        /// 娓犻亾鍜ㄨ
+        /// </summary>
+        public ICollection<LifePayChannelConsultation> ChannelConsultations { get; set; }
+    }
+}
diff --git a/LifePayment/LifePayment.EntityFrameworkCore/LifePaymentServicesDbContext.cs b/LifePayment/LifePayment.EntityFrameworkCore/LifePaymentServicesDbContext.cs
index 6daff53..ff2b377 100644
--- a/LifePayment/LifePayment.EntityFrameworkCore/LifePaymentServicesDbContext.cs
+++ b/LifePayment/LifePayment.EntityFrameworkCore/LifePaymentServicesDbContext.cs
@@ -17,6 +17,12 @@
         {
         }
 
+        public virtual DbSet<LifePayPromoter> LifePayPromoter { get; set; }
+
+        public virtual DbSet<LifePayChannelConsultation> LifePayChannelConsultation { get; set; }
+
+        public virtual DbSet<LifePayChannelConsultationFollowup> LifePayChannelConsultationFollowup { get; set; }
+
         public virtual DbSet<LifePayUser> LifePayUser { get; set; }
 
         public virtual DbSet<LifePayOrder> LifePayOrder { get; set; }
diff --git a/LifePayment/LifePayment.EntityFrameworkCore/ModelConfigure/ModelDbContextModelBuilderExtensions.cs b/LifePayment/LifePayment.EntityFrameworkCore/ModelConfigure/ModelDbContextModelBuilderExtensions.cs
index 8d8d90c..0f82608 100644
--- a/LifePayment/LifePayment.EntityFrameworkCore/ModelConfigure/ModelDbContextModelBuilderExtensions.cs
+++ b/LifePayment/LifePayment.EntityFrameworkCore/ModelConfigure/ModelDbContextModelBuilderExtensions.cs
@@ -1,4 +1,6 @@
-锘縰sing LifePayment.Domain.Models;
+锘縰sing LifePayment.Domain;
+using LifePayment.Domain.LifePay;
+using LifePayment.Domain.Models;
 using Microsoft.EntityFrameworkCore;
 using System;
 using System.Collections.Generic;
diff --git a/LifePayment/LifePayment.Host/LifePaymentService.HttpApi.xml b/LifePayment/LifePayment.Host/LifePaymentService.HttpApi.xml
index 808abee..e2a7cca 100644
--- a/LifePayment/LifePayment.Host/LifePaymentService.HttpApi.xml
+++ b/LifePayment/LifePayment.Host/LifePaymentService.HttpApi.xml
@@ -513,6 +513,56 @@
             <param name="input"></param>
             <returns></returns>
         </member>
+        <member name="M:LifePayment.HttpApi.PromoterController.GetPromoters(LifePayment.Application.Contracts.GetPromotersInput)">
+            <summary>
+            鑾峰彇鎺ㄥ箍鍛樺垪琛�
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:LifePayment.HttpApi.PromoterController.GetChannelConsultation(LifePayment.Application.Contracts.GetChannelConsultationsInput)">
+            <summary>
+            鑾峰彇娓犻亾鍜ㄨ鍒楄〃
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:LifePayment.HttpApi.PromoterController.GetChannelConsultationFollowupList(System.Guid)">
+            <summary>
+            鑾峰彇娓犻亾鍜ㄨ鍥炶璁板綍
+            </summary>
+            <param name="id">娓犻亾鍜ㄨId</param>
+            <returns></returns>
+        </member>
+        <member name="M:LifePayment.HttpApi.PromoterController.CreateOrUpdatePromoter(LifePayment.Application.Contracts.CreateOrUpdatePromoterInput)">
+            <summary>
+            鍒涘缓鎴栨洿鏂版帹骞垮憳
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+            <exception cref="T:System.FormatException"></exception>
+        </member>
+        <member name="M:LifePayment.HttpApi.PromoterController.SetClickCount(System.String)">
+            <summary>
+            鐐瑰嚮鏁�+1
+            </summary>
+            <param name="idnumber"></param>
+            <returns></returns>
+        </member>
+        <member name="M:LifePayment.HttpApi.PromoterController.CreateChannelConsultation(LifePayment.Application.Contracts.CreateChannelConsultationInput)">
+            <summary>
+            鐢宠娓犻亾鍜ㄨ
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:LifePayment.HttpApi.PromoterController.CreateChannelConsultationFollowup(LifePayment.Application.Contracts.CreateChannelConsultationFollowupInput)">
+            <summary>
+            鏂板鍥炶
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
         <member name="M:LifePayment.HttpApi.SyncController.SyncFromTest">
             <summary>
             鍚屾娴嬭瘯璁㈠崟鏁版嵁
diff --git a/LifePayment/LifePayment.Host/LifePaymentServices.Application.Contracts.xml b/LifePayment/LifePayment.Host/LifePaymentServices.Application.Contracts.xml
index 333407d..23d2409 100644
--- a/LifePayment/LifePayment.Host/LifePaymentServices.Application.Contracts.xml
+++ b/LifePayment/LifePayment.Host/LifePaymentServices.Application.Contracts.xml
@@ -2112,6 +2112,281 @@
             缁撶畻鏃堕棿
             </summary>
         </member>
+        <member name="P:LifePayment.Application.Contracts.GetChannelConsultationsInput.StartDate">
+            <summary>
+            鍒涘缓鐨勫紑濮嬫椂闂�
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.GetChannelConsultationsInput.EndDate">
+            <summary>
+            鍒涘缓鐨勭粨鏉熸椂闂�
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.GetChannelConsultationsInput.SearchKey">
+            <summary>
+            鎼滅储鍏抽敭璇�
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.ChannelConsultationDto.Id">
+            <summary>
+            Id
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.ChannelConsultationDto.CreationTime">
+            <summary>
+            鍜ㄨ鏃堕棿
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.ChannelConsultationDto.Name">
+            <summary>
+            鍜ㄨ浜�
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.ChannelConsultationDto.AgentType">
+            <summary>
+            浠g悊绫诲瀷
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.ChannelConsultationDto.PhoneNumber">
+            <summary>
+            鑱旂郴鏂瑰紡
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.ChannelConsultationDto.CompanyName">
+            <summary>
+            鍏徃鍚嶇О
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.ChannelConsultationDto.CustomerResources">
+            <summary>
+            瀹㈡埛璧勬簮
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.ChannelConsultationDto.PromoterIdNumber">
+            <summary>
+            ID
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.ChannelConsultationDto.PromoterName">
+            <summary>
+            鎺ㄥ箍鍛�
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.ChannelConsultationDto.PromoterPhoneNumber">
+            <summary>
+            鑱旂郴鏂瑰紡
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.ChannelConsultationDto.FollowupStatus">
+            <summary>
+            鍥炶鐘舵��
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.ChannelConsultationDto.LastFollowupTime">
+            <summary>
+            鏈�杩戝洖璁�
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.ChannelConsultationDto.FollowupRemark">
+            <summary>
+            鍥炶璁板綍
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateChannelConsultationInput.UserId">
+            <summary>
+            瀹㈡埛绔敤鎴稩d 濡傛湁
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateChannelConsultationInput.IdNumber">
+            <summary>
+            鎺ㄥ箍浜篒d
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateChannelConsultationInput.Name">
+            <summary>
+            鍜ㄨ浜�
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateChannelConsultationInput.AgentType">
+            <summary>
+            浠g悊绫诲瀷
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateChannelConsultationInput.PhoneNumber">
+            <summary>
+            鑱旂郴鏂瑰紡
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateChannelConsultationInput.CompanyName">
+            <summary>
+            鍏徃鍚嶇О
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateChannelConsultationInput.CustomerResources">
+            <summary>
+            瀹㈡埛璧勬簮
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateChannelConsultationFollowupInput.ChannelConsultationId">
+            <summary>
+            娓犻亾鍜ㄨId
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateChannelConsultationFollowupInput.FollowupStatus">
+            <summary>
+            鍥炶鐘舵��
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateChannelConsultationFollowupInput.FollowupRemark">
+            <summary>
+            鍥炶璁板綍
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.ChannelConsultationFollowupDto.CreatorId">
+            <summary>
+            鍥炶浜篒d
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.ChannelConsultationFollowupDto.Creator">
+            <summary>
+            鍥炶浜�
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.ChannelConsultationFollowupDto.FollowupStatus">
+            <summary>
+            鍥炶鐘舵��
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.ChannelConsultationFollowupDto.FollowupRemark">
+            <summary>
+            鍥炶璁板綍
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.ChannelConsultationFollowupDto.CreationTime">
+            <summary>
+            鍜ㄨ鏃堕棿
+            </summary>
+        </member>
+        <member name="M:LifePayment.Application.Contracts.IPromoterService.GetPromoters(LifePayment.Application.Contracts.GetPromotersInput)">
+            <summary>
+            鑾峰彇鎺ㄥ箍鍛樺垪琛�
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:LifePayment.Application.Contracts.IPromoterService.GetChannelConsultation(LifePayment.Application.Contracts.GetChannelConsultationsInput)">
+            <summary>
+            鑾峰彇娓犻亾鍜ㄨ鍒楄〃
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:LifePayment.Application.Contracts.IPromoterService.GetChannelConsultationFollowupList(System.Guid)">
+            <summary>
+            鑾峰彇娓犻亾鍜ㄨ鍥炶璁板綍
+            </summary>
+            <param name="id">娓犻亾鍜ㄨId</param>
+            <returns></returns>
+        </member>
+        <member name="M:LifePayment.Application.Contracts.IPromoterService.CreateOrUpdatePromoter(LifePayment.Application.Contracts.CreateOrUpdatePromoterInput)">
+            <summary>
+            鍒涘缓鎴栨洿鏂版帹骞垮憳
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+            <exception cref="T:System.FormatException"></exception>
+        </member>
+        <member name="M:LifePayment.Application.Contracts.IPromoterService.SetClickCount(System.String)">
+            <summary>
+            鐐瑰嚮鏁�+1
+            </summary>
+            <param name="idnumber"></param>
+            <returns></returns>
+        </member>
+        <member name="M:LifePayment.Application.Contracts.IPromoterService.CreateChannelConsultation(LifePayment.Application.Contracts.CreateChannelConsultationInput)">
+            <summary>
+            鐢宠娓犻亾鍜ㄨ
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:LifePayment.Application.Contracts.IPromoterService.CreateChannelConsultationFollowup(LifePayment.Application.Contracts.CreateChannelConsultationFollowupInput)">
+            <summary>
+            鏂板鍥炶
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.PromoterDto.Id">
+            <summary>
+            Id
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.PromoterDto.CreationTime">
+            <summary>
+            鍜ㄨ鏃堕棿
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.PromoterDto.IdNumber">
+            <summary>
+            ID
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.PromoterDto.Name">
+            <summary>
+            鎺ㄥ箍鍛�
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.PromoterDto.PhoneNumber">
+            <summary>
+            鑱旂郴鏂瑰紡
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.PromoterDto.ClickCount">
+            <summary>
+            鐐瑰嚮鏁�
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.PromoterDto.ApplyCount">
+            <summary>
+            鐢宠鏁�
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.PromoterDto.Remark">
+            <summary>
+            澶囨敞
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateOrUpdatePromoterInput.Id">
+            <summary>
+            Id
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateOrUpdatePromoterInput.UserId">
+            <summary>
+            瀹㈡埛绔敤鎴稩d 濡傛湁
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateOrUpdatePromoterInput.IdNumber">
+            <summary>
+            ID
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateOrUpdatePromoterInput.Name">
+            <summary>
+            鎺ㄥ箍鍛�
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateOrUpdatePromoterInput.PhoneNumber">
+            <summary>
+            鑱旂郴鏂瑰紡
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateOrUpdatePromoterInput.Remark">
+            <summary>
+            澶囨敞
+            </summary>
+        </member>
         <member name="P:LifePayment.Application.Contracts.RecordOperateHistoryEto.RelationId">
             <summary>
             鍏宠仈鍏崇郴ID
diff --git a/LifePayment/LifePayment.HttpApi/LifePay/PromoterController.cs b/LifePayment/LifePayment.HttpApi/LifePay/PromoterController.cs
new file mode 100644
index 0000000..becb882
--- /dev/null
+++ b/LifePayment/LifePayment.HttpApi/LifePay/PromoterController.cs
@@ -0,0 +1,124 @@
+锘縰sing AutoMapper;
+using LifePayment.Application.Contracts;
+using LifePayment.Domain.LifePay;
+using LifePayment.Domain.Shared;
+using LifePayment.Domain;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using System;
+using Volo.Abp.AutoMapper;
+using Volo.Abp.Users;
+using ZeroD.Util;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Volo.Abp.AspNetCore.Mvc;
+using ZeroD.Util.Fadd;
+using Volo.Abp.Uow;
+using Nest;
+
+namespace LifePayment.HttpApi
+{
+    [Route("api/[controller]/[action]")]
+    [ApiController]
+    [Authorize]
+    public class PromoterController : AbpController
+    {
+        private readonly IPromoterService promoterService;
+
+        public PromoterController(IPromoterService promoterService)
+        {
+            this.promoterService = promoterService;
+        }
+
+        #region 鏌ヨ
+
+        /// <summary>
+        /// 鑾峰彇鎺ㄥ箍鍛樺垪琛�
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<PageOutput<PromoterDto>> GetPromoters(GetPromotersInput input)
+        {
+            return await promoterService.GetPromoters(input);
+        }
+
+        /// <summary>
+        /// 鑾峰彇娓犻亾鍜ㄨ鍒楄〃
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<PageOutput<ChannelConsultationDto>> GetChannelConsultation(GetChannelConsultationsInput input)
+        {
+            return await promoterService.GetChannelConsultation(input);
+        }
+
+        /// <summary>
+        /// 鑾峰彇娓犻亾鍜ㄨ鍥炶璁板綍
+        /// </summary>
+        /// <param name="id">娓犻亾鍜ㄨId</param>
+        /// <returns></returns>
+        [HttpGet]
+        public async Task<List<ChannelConsultationFollowupDto>> GetChannelConsultationFollowupList(Guid id)
+        {
+            return await promoterService.GetChannelConsultationFollowupList(id);
+        }
+
+        #endregion
+
+        #region 鍐欏叆
+
+        /// <summary>
+        /// 鍒涘缓鎴栨洿鏂版帹骞垮憳
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        /// <exception cref="FormatException"></exception>
+        [HttpPost]
+        [AllowAnonymous]
+        public async Task<Guid> CreateOrUpdatePromoter(CreateOrUpdatePromoterInput input)
+        {
+            return await promoterService.CreateOrUpdatePromoter(input);
+        }
+
+        /// <summary>
+        /// 鐐瑰嚮鏁�+1
+        /// </summary>
+        /// <param name="idnumber"></param>
+        /// <returns></returns>
+        [HttpPost]
+        [AllowAnonymous]
+        public async Task SetClickCount(string idnumber)
+        {
+            await promoterService.SetClickCount(idnumber);
+        }
+
+        /// <summary>
+        /// 鐢宠娓犻亾鍜ㄨ
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        [HttpPost]
+        [UnitOfWork]
+        [AllowAnonymous]
+        public async Task<Guid> CreateChannelConsultation(CreateChannelConsultationInput input)
+        {
+            return await promoterService.CreateChannelConsultation(input);
+        }
+
+        /// <summary>
+        /// 鏂板鍥炶
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        [HttpPost]
+        [UnitOfWork]
+        public async Task<Guid> CreateChannelConsultationFollowup(CreateChannelConsultationFollowupInput input)
+        {
+            return await promoterService.CreateChannelConsultationFollowup(input);
+        }
+
+        #endregion
+    }
+}
diff --git a/LifePayment/LifePayment.HttpApi/LifePay/SyncController.cs b/LifePayment/LifePayment.HttpApi/LifePay/SyncController.cs
index 25df9f8..eb572c2 100644
--- a/LifePayment/LifePayment.HttpApi/LifePay/SyncController.cs
+++ b/LifePayment/LifePayment.HttpApi/LifePay/SyncController.cs
@@ -24,7 +24,6 @@
         /// </summary>
         /// <returns></returns>
         [HttpPost]
-        [AllowAnonymous]
         public Task<List<string>> SyncFromTest()
         {
             return syncService.SyncFromTest();

--
Gitblit v1.9.1