From 2dffeebb60078f6ee1d59ac327c0ecce3fd200e9 Mon Sep 17 00:00:00 2001
From: lingling <kety1122@163.com>
Date: 星期一, 17 三月 2025 17:44:03 +0800
Subject: [PATCH] 添加后端用户逻辑

---
 LifePayment/LifePayment.Application.Contracts/User/IAccountService.cs                        |    7 
 LifePayment/LifePayment.Host/appsettings.json                                                |   24 
 LifePayment/LifePayment.Host/LifePaymentServices.Application.Contracts.xml                   |  245 +++++++++
 LifePayment/LifePayment.Host/LifePaymentServiceHostModule.cs                                 |   15 
 LifePayment/LifePayment.HttpApi/LifePay/AccountController.cs                                 |    9 
 LifePayment/LifePayment.Application/User/AccountService.cs                                   |  152 +++++
 LifePayment/LifePayment.Domain/Common/UserRole.cs                                            |   20 
 LifePayment/LifePayment.Application.Contracts/User/IUserRoleService.cs                       |   26 +
 LifePayment/LifePayment.Application/LifePaymentServicesApplicationModuleAutoMapperProfile.cs |    1 
 LifePayment/LifePayment.Application.Contracts/User/QrCodeLogin.cs                            |   70 ++
 LifePayment/LifePayment.Domain/Common/User.cs                                                |  189 +++++++
 LifePayment/LifePayment.Application/User/UserRoleService.cs                                  |  167 ++++++
 LifePayment/LifePayment.Application.Contracts/User/CreateBackClientUserInput.cs              |  225 +++++++++
 LifePayment/LifePayment.HttpApi/LifePay/UserRoleController.cs                                |  183 +++++++
 LifePayment/LifePayment.Domain/Common/Role.cs                                                |   38 +
 LifePayment/LifePayment.Host/LifePaymentService.HttpApi.xml                                  |   63 ++
 LifePayment/LifePayment.Domain.Shared/Enum/LifePay/EnterpriseTypeEnum.cs                     |   51 ++
 17 files changed, 1,473 insertions(+), 12 deletions(-)

diff --git a/LifePayment/LifePayment.Application.Contracts/User/CreateBackClientUserInput.cs b/LifePayment/LifePayment.Application.Contracts/User/CreateBackClientUserInput.cs
new file mode 100644
index 0000000..d1f3f9e
--- /dev/null
+++ b/LifePayment/LifePayment.Application.Contracts/User/CreateBackClientUserInput.cs
@@ -0,0 +1,225 @@
+锘縰sing System;
+using System.Collections.Generic;
+using ZeroD.Util;
+
+namespace LifePayment.Application.Contracts
+{
+    public class CreateBackClientUserInput
+    {
+        /// <summary>
+        /// 鍚嶇О
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 鎵嬫満鍙�
+        /// </summary>
+        public string PhoneNumber { get; set; }
+
+        /// <summary>
+        /// 璐︽埛
+        /// </summary>
+        public string UserName { get; set; }
+
+        public string Remark { get; set; }
+
+        /// <summary>
+        /// 瑙掕壊
+        /// </summary>
+        public string[] RoleNames { get; set; }
+
+        /// <summary>
+        /// 缁勭粐鏋舵瀯鍏徃id
+        /// </summary>
+        public Guid? CompanyOrgId { get; set; }
+
+        /// <summary>
+        /// 缁勭粐鏋舵瀯閮ㄩ棬id
+        /// </summary>
+        public Guid? DepartmentOrgId { get; set; }
+    }
+
+    public class CreateOrUpdateRoleInput : CreateBaseRoleInput
+    {
+        /// <summary>
+        /// 瑙掕壊Id
+        /// </summary>
+        public Guid Id { get; set; }
+    }
+
+    public class CreateBaseRoleInput
+    {
+        /// <summary>
+        /// 鍚嶇О
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 鎺掑簭
+        /// </summary>
+        public int Sequence { get; set; }
+
+        /// <summary>
+        /// 閮ㄩ棬Id
+        /// </summary>
+        public int DepartmentId { get; set; }
+
+        /// <summary>
+        /// 鏁版嵁鑼冨洿 鍏ㄩ儴鏁版嵁100 涓汉鏁版嵁 10
+        /// </summary>
+        public int DataRange { get; set; }
+
+        /// <summary>
+        /// 澶囨敞
+        /// </summary>
+        public string Remark { get; set; }
+    }
+
+    public class UpdateBackClientUserInput : CreateBackClientUserInput
+    {
+        /// <summary>
+        /// 鐢ㄦ埛Id
+        /// </summary>
+        public Guid Id { get; set; }
+    }
+
+    public class RoleEnableOrForbidInput
+    {
+        /// <summary>
+        /// 瑙掕壊Id
+        /// </summary>
+        public Guid Id { get; set; }
+
+        /// <summary>
+        /// 鍚敤锛歵rue锛岀鐢細false
+        /// </summary>
+        public bool IsEnable { get; set; }
+
+        [System.Text.Json.Serialization.JsonIgnore]
+        public string Name { get; set; } = "Name";
+    }
+
+    public class UserDto
+    {
+        /// <summary>
+        /// 鐢ㄦ埛Id
+        /// </summary>
+        public Guid Id { get; set; }
+
+        /// <summary>
+        /// 鐧诲綍鐢ㄦ埛鍚嶏紙璐﹀彿锛�
+        /// </summary>
+        public string UserName { get; set; }
+
+        /// <summary>
+        /// 鍚嶇О
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 鐢ㄦ埛鎵嬫満鍙�
+        /// </summary>
+        public string PhoneNumber { get; set; }
+
+        /// <summary>
+        /// 璐︽埛鏄惁閿佷綇锛堟槸鍚︾鐢級
+        /// </summary>
+        public bool IsLocked { get; set; }
+
+        /// <summary>
+        /// 瑙掕壊淇℃伅
+        /// </summary>
+        public IEnumerable<RoleDto> Roles { get; set; }
+
+        /// <summary>
+        /// 澶囨敞
+        /// </summary>
+        public string Remark { get; set; }
+
+        /// <summary>
+        /// 缁勭粐鏋舵瀯鍏徃id
+        /// </summary>
+        public Guid? CompanyOrgId { get; set; }
+
+        /// <summary>
+        /// 缁勭粐鏋舵瀯閮ㄩ棬id
+        /// </summary>
+        public Guid? DepartmentOrgId { get; set; }
+    }
+
+    public class GetBackClientUsersInput : PageInput
+    {
+        /// <summary>
+        /// 璐︽埛鏄惁閿佷綇锛堟槸鍚︾鐢級
+        /// </summary>
+        public bool? IsLocked { get; set; }
+
+        /// <summary>
+        /// 鏌ヨ鏉′欢锛氬悕绉�/璐﹀彿
+        /// </summary>
+        public string QueryCondition { get; set; }
+    }
+
+    public class RoleDto
+    {
+        /// <summary>
+        /// 瑙掕壊Id
+        /// </summary>
+        public Guid Id { get; set; }
+
+        /// <summary>
+        /// 瑙掕壊鍚�
+        /// </summary>
+        public string Name { get; set; }
+    }
+
+    public class RoleInfo
+    {
+        /// <summary>
+        /// 瑙掕壊Id
+        /// </summary>
+        public Guid Id { get; set; }
+
+        /// <summary>
+        /// 鍚嶇О
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 鎺掑簭
+        /// </summary>
+        public int Sequence { get; set; }
+
+        /// <summary>
+        /// 鏄惁鍙敤
+        /// </summary>
+        public bool IsEnable { get; set; } = true;
+
+        /// <summary>
+        /// 閮ㄩ棬Id
+        /// </summary>
+        public int DepartmentId { get; set; }
+
+        /// <summary>
+        /// 鏁版嵁鑼冨洿 鍏ㄩ儴鏁版嵁锛�100   涓汉鏁版嵁锛�10
+        /// </summary>
+        public int DataRange { get; set; }
+        /// <summary>
+        /// 璐﹀彿鏁伴噺
+        /// </summary>
+        public int UserCount { get; set; }
+
+        /// <summary>
+        /// 澶囨敞
+        /// </summary>
+        public string Remark { get; set; }
+    }
+
+    public class GetRolesInput : PageInput
+    {
+        /// <summary>
+        /// 鏌ヨ鏉′欢锛氳鑹插悕绉�
+        /// </summary>
+        public string QueryCondition { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/LifePayment/LifePayment.Application.Contracts/User/IAccountService.cs b/LifePayment/LifePayment.Application.Contracts/User/IAccountService.cs
index d090533..407c707 100644
--- a/LifePayment/LifePayment.Application.Contracts/User/IAccountService.cs
+++ b/LifePayment/LifePayment.Application.Contracts/User/IAccountService.cs
@@ -2,13 +2,13 @@
 using System.Threading.Tasks;
 using Volo.Abp;
 using Volo.Abp.Application.Services;
+using Volo.Abp.Identity.Application.Contracts.Account;
+using Volo.Abp.IdentityModel;
 
 namespace LifePayment.Application.Contracts
 {
     public interface IAccountService : IApplicationService
     {
-
-
         #region life pay
         Task<WxMiniAppIndentityInfo> GetLifePayWxIndentity(string code);
 
@@ -21,6 +21,9 @@
         /// <exception cref="UserFriendlyException"></exception>
         Task<Guid> LifePayPhoneMesssageCodeLogin(LifePayPhoneMesssageCodeLoginInput input);
 
+        Task<IdentityModelTokenCacheItem> GetTokenForWeb(AccessRequestDto accessRequestDto, string webClientIp);
+
+        Task<Guid> CreateAccount(CreateAccountInput input, bool isSend = false, bool isAdminCreate = false, string password = null);
         #endregion
     }
 }
\ No newline at end of file
diff --git a/LifePayment/LifePayment.Application.Contracts/User/IUserRoleService.cs b/LifePayment/LifePayment.Application.Contracts/User/IUserRoleService.cs
new file mode 100644
index 0000000..d6c047b
--- /dev/null
+++ b/LifePayment/LifePayment.Application.Contracts/User/IUserRoleService.cs
@@ -0,0 +1,26 @@
+锘縰sing System;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Services;
+using ZeroD.Util;
+
+namespace LifePayment.Application.Contracts
+{
+    public interface IUserRoleService : IApplicationService
+    {
+        Task<PageOutput<UserDto>> GetBackClientUsers(GetBackClientUsersInput input);
+
+        Task<int> UpdateBackClientUser(UpdateBackClientUserInput input);
+
+        Task<int> DeleteBackClientUser(Guid id);
+
+        Task<Guid> CreateRole(CreateOrUpdateRoleInput input);
+
+        Task<PageOutput<RoleInfo>> GetRoles(GetRolesInput input);
+
+        Task<int> UpdateRole(CreateOrUpdateRoleInput input);
+
+        Task<int> RoleEnableOrForbid(Guid id, bool isEnable);
+
+        Task<int> DeleteRole(Guid id);
+    }
+}
\ No newline at end of file
diff --git a/LifePayment/LifePayment.Application.Contracts/User/QrCodeLogin.cs b/LifePayment/LifePayment.Application.Contracts/User/QrCodeLogin.cs
index 200721f..de67ea7 100644
--- a/LifePayment/LifePayment.Application.Contracts/User/QrCodeLogin.cs
+++ b/LifePayment/LifePayment.Application.Contracts/User/QrCodeLogin.cs
@@ -1,6 +1,8 @@
 锘縰sing LifePayment.Domain.Shared;
+using System;
 using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
+using ZeroD.Util;
 
 namespace LifePayment.Application.Contracts
 {
@@ -39,4 +41,72 @@
         /// </summary>
         public string UnionId { get; set; }
     }
+
+    public class CreateAccountInput
+    {
+        /// <summary>
+        /// 鍚嶇О
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 鐢ㄦ埛鍚�
+        /// </summary>
+        [RegularExpression(LifePaymentConstant.RegularExpression.UserNameEx, ErrorMessage = "璐﹀彿鏍煎紡涓嶆纭�")]
+        public string UserName { get; set; }
+        /// <summary>
+        /// 澶囨敞
+        /// </summary>
+        public string Remark { get; set; }
+
+        /// <summary>
+        /// 鎵嬫満鍙�
+        /// </summary>
+        public string PhoneNumber { get; set; }
+
+        /// <summary>
+        /// 鐢ㄦ埛绔疘d
+        /// </summary>
+        public string ClientId { get; set; } = Constant.ClientType.Back;
+
+        /// <summary>
+        /// 瑙掕壊
+        /// </summary>
+        public string[] RoleNames { get; set; }
+
+        /// <summary>
+        /// 灏忕▼搴廜penId
+        /// </summary>
+        public string OpenId { get; set; }
+
+        ///// <summary>
+        ///// 鑱旂郴浜�
+        ///// </summary>
+        // public string Contact { get; set; }
+
+        /// <summary>
+        /// 浼佷笟鍚嶇О
+        /// </summary>
+        public string EnterpriseName { get; set; }
+
+        /// <summary>
+        /// 浼佷笟绫诲瀷
+        /// </summary>
+        public EnterpriseTypeEnum? AuthType { get; set; }
+
+        /// <summary>
+        /// MatchMaking灏忕▼搴廜penId
+        /// </summary>
+        public string MatchMakingOpenId { get; set; }
+
+        /// <summary>
+        /// 缁勭粐鏋舵瀯鍏徃id
+        /// </summary>
+        public Guid? CompanyOrgId { get; set; }
+
+        /// <summary>
+        /// 缁勭粐鏋舵瀯閮ㄩ棬id
+        /// </summary>
+        public Guid? DepartmentOrgId { get; set; }
+    }
 }
\ No newline at end of file
diff --git a/LifePayment/LifePayment.Application/LifePaymentServicesApplicationModuleAutoMapperProfile.cs b/LifePayment/LifePayment.Application/LifePaymentServicesApplicationModuleAutoMapperProfile.cs
index 0b8c311..68e9053 100644
--- a/LifePayment/LifePayment.Application/LifePaymentServicesApplicationModuleAutoMapperProfile.cs
+++ b/LifePayment/LifePayment.Application/LifePaymentServicesApplicationModuleAutoMapperProfile.cs
@@ -13,7 +13,6 @@
 
             CreateMap<CreateLifePayOrderInput, LifePayOrder>(MemberList.None);
 
-
             CreateMap<CreateEditPayChannelsInput, LifePayChannles>(MemberList.None);
             #endregion
         }
diff --git a/LifePayment/LifePayment.Application/User/AccountService.cs b/LifePayment/LifePayment.Application/User/AccountService.cs
index e38604a..3f8cd2e 100644
--- a/LifePayment/LifePayment.Application/User/AccountService.cs
+++ b/LifePayment/LifePayment.Application/User/AccountService.cs
@@ -1,31 +1,46 @@
-锘縰sing LifePayment.Application.Contracts;
+锘�
+using LifePayment.Application.Contracts;
 using LifePayment.Domain;
 using LifePayment.Domain.Models;
+using LifePayment.Domain.Shared;
 using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
 using System;
 using System.Linq;
 using System.Threading.Tasks;
 using Volo.Abp;
 using Volo.Abp.Application.Services;
 using Volo.Abp.Domain.Repositories;
+using Volo.Abp.Identity;
+using Volo.Abp.Identity.Application.Contracts.Account;
+using Volo.Abp.IdentityModel;
 using ZeroD.Util;
+using static LifePayment.Domain.Shared.LifePaymentConstant;
+
 
 namespace LifePayment.Application
 {
     public class AccountService : ApplicationService, IAccountService
     {
-
         private readonly IWxManager _wxManager;
         private readonly IRepository<LifePayUser, Guid> _lifePayUserRepository;
-
+        private readonly IConfiguration _configuration;
+        private readonly IIdentityModelAuthenticationService _authenticator;
+        private readonly IRepository<User, Guid> _userRepository;
+        private readonly IIdentityUserAppService _identityUserService;
 
         public AccountService(
                IWxManager wxManager,
-               IRepository<LifePayUser, Guid> lifePayUserRepository
-)
+               IConfiguration configuration,
+               IIdentityModelAuthenticationService authenticator,
+               IIdentityUserAppService identityUserService,
+               IRepository<LifePayUser, Guid> lifePayUserRepository)
         {
+            _configuration = configuration;
             _wxManager = wxManager;
+            _identityUserService = identityUserService;
             _lifePayUserRepository = lifePayUserRepository;
+            _authenticator = authenticator;
         }
 
         #region 鏌ヨ
@@ -90,10 +105,135 @@
             return lifeUser.Id;
         }
 
+        public async Task<IdentityModelTokenCacheItem> GetTokenForWeb(AccessRequestDto accessRequestDto, string webClientIp)
+        {
+            IdentityClientConfiguration config = new IdentityClientConfiguration
+            {
+                UserName = accessRequestDto.UserName,
+                UserPassword = accessRequestDto.UserPassword,
+                GrantType = accessRequestDto.GrantType == 1 ? "password" : "client_credentials",
+                ClientId = accessRequestDto.ClientId,
+                ClientSecret = "1q2w3e*",
+                Authority = _configuration["AuthServer:Authority"],
+                Scope = accessRequestDto.Scope + " offline_access",
+            };
+            var result = await _authenticator.GetAccessTokenAsync(config);
+            var user = await _userRepository.Where(r => r.UserName == accessRequestDto.UserName && !r.IsDeleted).FirstOrDefaultAsync();
+
+            // 璁板綍鏃ュ織
+           // await PublishUserOperateHistoryEvent(LogsSpecies.Login, LogsSpecies.Login, user.Id, user.Id, creatorName: user.Name);
+
+            return result;
+        }
+
+        public async Task<Guid> CreateAccount(CreateAccountInput input, bool isSend, bool isAdminCreate = false, string password = null)
+        {
+            if (input.ClientId == LifePaymentConstant.ClientId.Back)
+            {
+                CheckExtensions.IfTrueThrowUserFriendlyException(!input.CompanyOrgId.HasValue || !input.DepartmentOrgId.HasValue,
+                                                                 "鎵�灞炲叕鍙稿拰閮ㄩ棬涓嶈兘涓虹┖");
+            }
+
+            var any = await _userRepository.Where(x => x.PhoneNumber == input.PhoneNumber && x.ClientId == input.ClientId).AnyAsync();
+            CheckExtensions.IfTrueThrowUserFriendlyException(any,
+                                                             CustomeErrorMessage.PhoneNumberRepeatSaveFail);
+
+            password ??= GlobalRandom.GetRandomPassword();
+
+            var res = await _identityUserService.CreateAsync(new IdentityUserCreateDto
+            {
+                Name = input.Name,
+                PhoneNumber = input.PhoneNumber,
+                UserName = input.UserName,
+                RoleNames = input.RoleNames,
+                ClientId = input.ClientId,
+                Password = password,
+            });
+            var user = await _userRepository.InsertAsync(new User
+            {
+                Id = res.Id,
+                Name = input.Name,
+                UserName = input.UserName,
+                PhoneNumber = input.PhoneNumber,
+                ClientId = input.ClientId,
+                OpenId = input.OpenId,
+                LastLoginTime = DateTime.Now,
+                ContactPhone = input.PhoneNumber,
+                Contact = isAdminCreate ? input.Name : null,
+                EnterpriseName = input.EnterpriseName,
+                AuthType = input.AuthType,
+                Remark = input.Remark,
+                DepartmentOrgId = input.ClientId == LifePaymentConstant.ClientId.Back ? input.DepartmentOrgId : null,
+                CompanyOrgId = input.ClientId == LifePaymentConstant.ClientId.Back ? input.CompanyOrgId : null
+            });
+            //if (input.ClientId == Constant.ClientType.Back)
+            //{
+            //    await _distributedEventBus.PublishAsync(new SendPhoneMessageInput
+            //    {
+            //        Phone = input.PhoneNumber,
+            //        ProviderName = "CreateBackAccount",
+            //        TemplateParams = new
+            //        {
+            //            account = input.UserName,
+            //            pwd = password,
+            //        },
+            //        MessageType = PhoneMessageTypeEnum.Notice
+            //    });
+            //}
+            //else
+            //{
+            //    if (isSend)
+            //    {
+            //        //await _commonManager.SendPhoneMessage(new SendPhoneMessageInput
+            //        //{
+            //        //    Phone = input.PhoneNumber,
+            //        //    ProviderName = "CreateAccount",
+            //        //    TemplateParams = new
+            //        //    {
+            //        //        name = input.Name,
+            //        //        account = input.UserName,
+            //        //        pwd = password,
+            //        //    },
+            //        //});
+
+            //        await _distributedEventBus.PublishAsync(new SendPhoneMessageInput
+            //        {
+            //            Phone = input.PhoneNumber,
+            //            ProviderName = "CreateAccountNotice",
+            //            TemplateParams = new
+            //            {
+            //                account = input.UserName,
+            //                password = password,
+            //            },
+            //            MessageType = PhoneMessageTypeEnum.Notice
+            //        });
+            //    }
+            //}
+
+            var logoption = LogsSpecies.UserRegister;
+            var creatorName = user.Name;
+
+            // 璁板綍鏃ュ織
+            if (isAdminCreate)
+            {
+                logoption = LogsSpecies.Create;
+                creatorName = CurrentUser.Name;
+            }
+
+            //await PublishUserOperateHistoryEvent(logoption, logoption, res.Id, res.Id, creatorName: creatorName);
+
+            #region 娣诲姞IM鐢ㄦ埛
+
+            //await PublishAddTencentUserEvent(user.Id, user.UserName, user.AvatarUrl);
+
+            #endregion
+
+            return res.Id;
+        }
         #endregion
 
         #endregion
 
-     
+
     }
 }
\ No newline at end of file
diff --git a/LifePayment/LifePayment.Application/User/UserRoleService.cs b/LifePayment/LifePayment.Application/User/UserRoleService.cs
new file mode 100644
index 0000000..057e212
--- /dev/null
+++ b/LifePayment/LifePayment.Application/User/UserRoleService.cs
@@ -0,0 +1,167 @@
+锘縰sing LifePayment.Application.Contracts;
+using LifePayment.Domain.Models;
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Volo.Abp;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Domain.Repositories;
+using ZeroD.Util;
+
+namespace HumanResourcesServices.Application
+{
+    public class UserRoleService : ApplicationService, IUserRoleService
+    {
+        private readonly IRepository<User, Guid> _userRepository;
+        private readonly IRepository<Role, Guid> _roleRepository;
+        private readonly IRepository<UserRole, Guid> _userRoleRep;
+
+        public UserRoleService(
+               IRepository<User, Guid> userRepository,
+               IRepository<Role, Guid> roleRepository,
+               IRepository<UserRole, Guid> userRoleRep)
+        {
+            _userRepository = userRepository;
+            _roleRepository = roleRepository;
+            _userRoleRep = userRoleRep;
+        }
+
+        public async Task<PageOutput<UserDto>> GetBackClientUsers(GetBackClientUsersInput input)
+        {
+            var query = _userRepository.Where(s => s.ClientId == Constant.ClientType.Back).Include(i => i.UserRoles).Select(u => new UserDto
+            {
+                Id = u.Id,
+                UserName = u.UserName,
+                Name = u.Name,
+                PhoneNumber = u.PhoneNumber,
+                IsLocked = u.IsLocked ?? default,
+                Roles = from ur in u.UserRoles
+                        from r in _roleRepository.Where(s => s.Id == ur.RoleId)
+                        select new RoleDto
+                        {
+                            Id = r.Id,
+                            Name = r.Name,
+                        },
+                Remark = u.Remark,
+                CompanyOrgId = u.CompanyOrgId,
+                DepartmentOrgId = u.DepartmentOrgId
+            });
+            if (input.IsLocked.HasValue)
+            {
+                query = query.Where(s => s.IsLocked == input.IsLocked);
+            }
+
+            if (!input.QueryCondition.IsNullOrEmpty())
+            {
+                query = query.Where(s => s.UserName.Contains(input.QueryCondition) ||
+                                         s.Name.Contains(input.QueryCondition));
+            }
+
+            var result = await query.GetPageResult(input.PageModel);
+            return result;
+        }
+
+        public async Task<int> UpdateBackClientUser(UpdateBackClientUserInput input)
+        {
+            var entity = await _userRepository.FirstOrDefaultAsync(s => s.Id == input.Id && s.ClientId == Constant.ClientType.Back);
+            if (entity == null)
+            {
+                throw new UserFriendlyException("鏈壘鍒板搴旂敤鎴�");
+            }
+
+            entity.Name = input.Name;
+            entity.PhoneNumber = input.PhoneNumber;
+            entity.UserName = input.UserName;
+            entity.Remark = input.Remark;
+            entity.DepartmentOrgId = input.DepartmentOrgId;
+            entity.CompanyOrgId = input.CompanyOrgId;
+            return Constant.SUCCESS;
+        }
+
+        public async Task<int> DeleteBackClientUser(Guid id)
+        {
+            var entity = await _userRepository.FirstOrDefaultAsync(s => s.Id == id && s.ClientId == Constant.ClientType.Back);
+            if (entity == null)
+            {
+                throw new UserFriendlyException("鏈壘鍒板搴旂敤鎴�");
+            }
+
+            entity.IsDeleted = true;
+            return Constant.SUCCESS;
+        }
+
+        public async Task<Guid> CreateRole(CreateOrUpdateRoleInput input)
+        {
+            var entity = ObjectMapper.Map<CreateOrUpdateRoleInput, Role>(input);
+            return await _roleRepository.InsertAndGetIdAsync(entity);
+        }
+
+        public async Task<PageOutput<RoleInfo>> GetRoles(GetRolesInput input)
+        {
+            var query = _roleRepository.Select(r => new RoleInfo
+            {
+                Id = r.Id,
+                Name = r.Name,
+                Sequence = r.Sequence,
+                IsEnable = r.IsEnable,
+                DepartmentId = r.DepartmentId,
+                DataRange = r.DataRange,
+                Remark = r.Remark,
+            });
+            if (!input.QueryCondition.IsNullOrEmpty())
+            {
+                query = query.Where(s => s.Name.Contains(input.QueryCondition));
+            }
+
+            var result = await query.GetPageResult(input.PageModel);
+            var listrols = new List<UserRole>();
+            if (result.Data.Any())
+            {
+                listrols = await (from ur in _userRoleRep.Where(r => result.Data.Select(d => d.Id).Contains(r.RoleId))
+                                  join u in _userRepository.Where(r => !r.IsDeleted) on ur.UserId equals u.Id
+                                  select ur).ToListAsync();
+            }
+            foreach (var item in result.Data)
+            {
+                item.UserCount = listrols.Where(r => r.RoleId == item.Id).Count();
+            }
+            return result;
+        }
+
+        public async Task<int> UpdateRole(CreateOrUpdateRoleInput input)
+        {
+            var entity = await _roleRepository.FirstOrDefaultAsync(s => s.Id == input.Id);
+            if (entity == null)
+            {
+                throw new UserFriendlyException("鏈壘鍒板搴旇鑹�");
+            }
+
+            entity.Name = input.Name;
+            entity.Sequence = input.Sequence;
+            entity.DepartmentId = input.DepartmentId;
+            entity.DataRange = input.DataRange;
+            entity.Remark = input.Remark;
+            return Constant.SUCCESS;
+        }
+
+        public async Task<int> RoleEnableOrForbid(Guid id, bool isEnable)
+        {
+            var entity = await _roleRepository.FirstOrDefaultAsync(s => s.Id == id);
+            if (entity == null)
+            {
+                throw new UserFriendlyException("鏈壘鍒板搴旇鑹�");
+            }
+
+            entity.IsEnable = isEnable;
+            return Constant.SUCCESS;
+        }
+
+        public async Task<int> DeleteRole(Guid id)
+        {
+            await _roleRepository.DeleteAsync(id);
+            return Constant.SUCCESS;
+        }
+    }
+}
\ No newline at end of file
diff --git a/LifePayment/LifePayment.Domain.Shared/Enum/LifePay/EnterpriseTypeEnum.cs b/LifePayment/LifePayment.Domain.Shared/Enum/LifePay/EnterpriseTypeEnum.cs
new file mode 100644
index 0000000..753797c
--- /dev/null
+++ b/LifePayment/LifePayment.Domain.Shared/Enum/LifePay/EnterpriseTypeEnum.cs
@@ -0,0 +1,51 @@
+锘縰sing System.ComponentModel;
+
+namespace LifePayment.Domain.Shared;
+
+/// <summary>
+/// 浼佷笟绫诲瀷
+/// </summary>
+public enum EnterpriseTypeEnum
+{
+    /// <summary>
+    /// 浜哄姏璧勬簮鍏徃
+    /// </summary>
+    [Description("浜哄姏璧勬簮鍏徃")]
+    HREnterprise = 10,
+
+    /// <summary>
+    /// 鐢叉柟浼佷笟
+    /// </summary>
+    [Description("鐢叉柟浼佷笟")]
+    FirstPartyCompany = 20,
+
+    /// <summary>
+    /// 琛屼笟閰嶅
+    /// </summary>
+    [Description("琛屼笟閰嶅")]
+    IndustryMating = 30,
+
+    /// <summary>
+    /// 琛屼笟鏈烘瀯
+    /// </summary>
+    [Description("琛屼笟鏈烘瀯")]
+    IndustryBody = 40,
+}
+
+/// <summary>
+/// 鎬у埆鏋氫妇
+/// </summary>
+public enum GenderTypeEnum
+{
+    /// <summary>
+    /// 鐢�
+    /// </summary>
+    [Description("鐢�")]
+    Male = 1,
+
+    /// <summary>
+    /// 濂�
+    /// </summary>
+    [Description("濂�")]
+    Female = 2,
+}
diff --git a/LifePayment/LifePayment.Domain/Common/Role.cs b/LifePayment/LifePayment.Domain/Common/Role.cs
new file mode 100644
index 0000000..92a2779
--- /dev/null
+++ b/LifePayment/LifePayment.Domain/Common/Role.cs
@@ -0,0 +1,38 @@
+锘縰sing System;
+using Volo.Abp.Domain.Entities;
+
+namespace LifePayment.Domain.Models
+{
+    public class Role : Entity<Guid>, IAggregateRoot<Guid>
+    {
+        /// <summary>
+        /// 鍚嶇О
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 鎺掑簭
+        /// </summary>
+        public int Sequence { get; set; }
+
+        /// <summary>
+        /// 鏄惁鍙敤
+        /// </summary>
+        public bool IsEnable { get; set; } = true;
+
+        /// <summary>
+        /// 閮ㄩ棬Id
+        /// </summary>
+        public int DepartmentId { get; set; }
+
+        /// <summary>
+        /// 鏁版嵁鑼冨洿 100鍏ㄩ儴鏁版嵁  10涓汉鏁版嵁
+        /// </summary>
+        public int DataRange { get; set; }
+
+        /// <summary>
+        /// 澶囨敞
+        /// </summary>
+        public string Remark { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/LifePayment/LifePayment.Domain/Common/User.cs b/LifePayment/LifePayment.Domain/Common/User.cs
new file mode 100644
index 0000000..92cdc42
--- /dev/null
+++ b/LifePayment/LifePayment.Domain/Common/User.cs
@@ -0,0 +1,189 @@
+锘縰sing LifePayment.Domain.Shared;
+using System;
+using System.Collections.Generic;
+using Volo.Abp;
+using Volo.Abp.Domain.Entities.Auditing;
+
+namespace LifePayment.Domain.Models
+{
+    public partial class User : FullAuditedEntity<Guid>, IDataUserFilter
+    {
+        public User()
+        {
+
+            UserRoles = new HashSet<UserRole>();
+
+        }
+
+        /// <summary>
+        /// 鍚嶇О
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 鐧诲綍鐢ㄦ埛鍚�
+        /// </summary>
+        public string UserName { get; set; }
+        /// <summary>
+        /// 鐢ㄦ埛鎵嬫満鍙�
+        /// </summary>
+        public string PhoneNumber { get; set; }
+        /// <summary>
+        /// 鐢ㄦ埛绔疘d
+        /// </summary>
+        public string ClientId { get; set; }
+        /// <summary>
+        /// 灏忕▼搴廜penId
+        /// </summary>
+        public string OpenId { get; set; }
+        /// <summary>
+        /// 璐︽埛浣欓
+        /// </summary>
+        public decimal Amount { get; set; }
+        /// <summary>
+        /// 璐︽埛鏄惁閿佷綇锛堟槸鍚︾鐢級锛岄粯璁や负0鏈攣浣忓嵆鏈鐢�
+        /// </summary>
+        public bool? IsLocked { get; set; }
+
+        /// <summary>
+        /// 娉ㄥ唽绫诲瀷锛�1涓轰紒涓氾紝2涓轰釜浜�
+        /// </summary>
+        public int Type { get; set; }
+
+        /// <summary>
+        /// 浼佷笟绫诲瀷
+        /// </summary>
+        public EnterpriseTypeEnum? AuthType { get; set; }
+
+        public DateTime? LastLoginTime { get; set; }
+
+        /// <summary>
+        /// 澶囨敞
+        /// </summary>
+        public string Remark { get; set; }
+
+
+        /// <summary>
+        /// 浼佷笟鍚嶇О
+        /// </summary>
+        public string EnterpriseName { get; set; }
+
+        /// <summary>
+        /// 鑱旂郴浜�
+        /// </summary>
+        public string Contact { get; set; }
+
+        /// <summary>
+        /// 鑱旂郴鐢佃瘽
+        /// </summary>
+        public string ContactPhone { get; set; }
+
+        /// <summary>
+        /// 缁戝畾閭鍦板潃
+        /// </summary>
+        public string BindEmailAddress { get; set; }
+
+        /// <summary>
+        /// 涓汉淇℃伅閭鍦板潃
+        /// </summary>
+        public string UserInfoEmailAddress { get; set; }
+
+        /// <summary>
+        /// 鐢ㄦ埛澶村儚鍦板潃
+        /// </summary>
+        public string AvatarUrl { get; set; }
+
+        /// <summary>
+        /// 鎬у埆
+        /// </summary>
+        public GenderTypeEnum? GenderType { get; set; }
+
+        /// <summary>
+        /// 鑱岀О
+        /// </summary>
+        public string JobTitle { get; set; }
+
+        /// <summary>
+        /// 鐪乧ode
+        /// </summary>
+        public int? ProvinceCode { get; set; }
+
+        /// <summary>
+        /// 甯俢ode
+        /// </summary>
+        public int? CityCode { get; set; }
+
+        /// <summary>
+        /// 鍖哄幙code
+        /// </summary>
+        public int? CountyCode { get; set; }
+
+        /// <summary>
+        /// 鐪�
+        /// </summary>
+        public string ProvinceName { get; set; }
+
+        /// <summary>
+        /// 甯�
+        /// </summary>
+        public string CityName { get; set; }
+
+        /// <summary>
+        /// 鍖哄幙
+        /// </summary>
+        public string CountyName { get; set; }
+
+        /// <summary>
+        /// 璇︾粏鍦板潃
+        /// </summary>
+        public string AddressDetail { get; set; }
+
+        /// <summary>
+        /// 绾害
+        /// </summary>
+        public decimal? AddressLatitude { get; set; }
+
+        /// <summary>
+        /// 缁忓害
+        /// </summary>
+        public decimal? AddressLongitude { get; set; }
+
+        /// <summary>
+        /// 寰俊浜岀淮鐮佸浘鐗�
+        /// </summary>
+        public string WxQrCodeUrl { get; set; }
+
+
+
+        /// <summary>
+        /// MatchMaking灏忕▼搴廜penId
+        /// </summary>
+        public string MatchMakingOpenId { get; set; }
+
+        /// <summary>
+        /// im鑵捐鐢ㄦ埛id
+        /// </summary>
+        public string IMTencentUserId { get; set; }
+
+        /// <summary>
+        /// 鎵�灞炲叕鍙竔d
+        /// </summary>
+        public Guid? CompanyOrgId { get; set; }
+
+        /// <summary>
+        /// 鎵�灞為儴闂╥d
+        /// </summary>
+        public Guid? DepartmentOrgId { get; set; }
+
+        /// <summary>
+        /// 浜т笟鍥尯id
+        /// </summary>
+        public Guid? IndustrialParkId { get; set; }
+
+
+
+        public ICollection<UserRole> UserRoles { get; set; }
+
+
+    }
+}
\ No newline at end of file
diff --git a/LifePayment/LifePayment.Domain/Common/UserRole.cs b/LifePayment/LifePayment.Domain/Common/UserRole.cs
new file mode 100644
index 0000000..f6b471f
--- /dev/null
+++ b/LifePayment/LifePayment.Domain/Common/UserRole.cs
@@ -0,0 +1,20 @@
+锘縰sing System;
+using Volo.Abp.Domain.Entities;
+
+namespace LifePayment.Domain.Models
+{
+    public class UserRole : Entity<Guid>
+    {
+        /// <summary>
+        /// 鐢ㄦ埛Id
+        /// </summary>
+        public virtual Guid UserId { get; set; }
+
+        /// <summary>
+        /// 瑙掕壊Id
+        /// </summary>
+        public virtual Guid RoleId { get; set; }
+
+        public virtual User User { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/LifePayment/LifePayment.Host/LifePaymentService.HttpApi.xml b/LifePayment/LifePayment.Host/LifePaymentService.HttpApi.xml
index f672b0d..5211c0f 100644
--- a/LifePayment/LifePayment.Host/LifePaymentService.HttpApi.xml
+++ b/LifePayment/LifePayment.Host/LifePaymentService.HttpApi.xml
@@ -278,6 +278,69 @@
             <param name="input"></param>
             <returns></returns>
         </member>
+        <member name="M:LifePayment.HttpApi.UserRoleController.CreateBackClientUser(LifePayment.Application.Contracts.CreateBackClientUserInput)">
+            <summary>
+            鏂板鍚庡彴绠$悊璐︽埛
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:LifePayment.HttpApi.UserRoleController.GetBackClientUsers(LifePayment.Application.Contracts.GetBackClientUsersInput)">
+            <summary>
+            鍚庡彴绠$悊璐︽埛鍒楄〃
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:LifePayment.HttpApi.UserRoleController.UpdateBackClientUser(LifePayment.Application.Contracts.UpdateBackClientUserInput)">
+            <summary>
+            鍚庡彴绠$悊璐︽埛缂栬緫
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:LifePayment.HttpApi.UserRoleController.DeleteBackClientUser(System.Guid)">
+            <summary>
+            鍒犻櫎鍚庡彴绠$悊璐︽埛
+            </summary>
+            <param name="id">鐢ㄦ埛Id</param>
+            <returns></returns>
+        </member>
+        <member name="M:LifePayment.HttpApi.UserRoleController.CreateRole(LifePayment.Application.Contracts.CreateBaseRoleInput)">
+            <summary>
+            鏂板瑙掕壊
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:LifePayment.HttpApi.UserRoleController.GetRoles(LifePayment.Application.Contracts.GetRolesInput)">
+            <summary>
+            瑙掕壊鍒楄〃
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:LifePayment.HttpApi.UserRoleController.UpdateRole(LifePayment.Application.Contracts.CreateOrUpdateRoleInput)">
+            <summary>
+            瑙掕壊缂栬緫
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:LifePayment.HttpApi.UserRoleController.RoleEnableOrForbid(LifePayment.Application.Contracts.RoleEnableOrForbidInput)">
+            <summary>
+            瑙掕壊鍚敤/绂佺敤
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:LifePayment.HttpApi.UserRoleController.DeleteRole(System.Guid)">
+            <summary>
+            鍒犻櫎瑙掕壊
+            </summary>
+            <param name="id">瑙掕壊Id</param>
+            <returns></returns>
+        </member>
         <member name="M:LifePayment.HttpApi.WxPayNotifyController.WxRechargeNotify(LifePayment.Application.Contracts.WxRechargeNotifyInput)">
             <summary>
             寰俊鏀粯鍥炶皟閫氱煡
diff --git a/LifePayment/LifePayment.Host/LifePaymentServiceHostModule.cs b/LifePayment/LifePayment.Host/LifePaymentServiceHostModule.cs
index adfdb5a..f29bd19 100644
--- a/LifePayment/LifePayment.Host/LifePaymentServiceHostModule.cs
+++ b/LifePayment/LifePayment.Host/LifePaymentServiceHostModule.cs
@@ -54,7 +54,7 @@
 
             //Configure<AliYunSMSSettingOptions>(configuration.GetSection("AliYunSMSSetting"));
             context.Services.AddAutoMapperObjectMapper();
-            ConfigureConventionalControllers();
+            
             context.Services.AddAuthentication("Bearer").AddIdentityServerAuthentication(options =>
             {
                 options.Authority = configuration["AuthServer:Authority"];
@@ -186,10 +186,19 @@
             });
         }
 
-        private void ConfigureConventionalControllers()
+        private void ConfigurePays(ServiceConfigurationContext context, IConfiguration configuration)
         {
+            Configure<WxPayOption>(configuration.GetSection("WxPay"));
+            context.Services.AddHttpClient(LifePaymentConstant.WxPayHttpClientName, config =>
+            {
+                config.Timeout = TimeSpan.FromSeconds(120);
+                config.DefaultRequestHeaders.Add("Connection", "Keep-Alive");
+                config.DefaultRequestHeaders.Add("User-Agent", "Aop4Net");
+                config.DefaultRequestHeaders.Add("Accept", "application/json");
+            });
+            Configure<Config>(configuration.GetSection("AliPay"));
+            PostConfigure<Config>(r => { Factory.SetOptions(r); });
         }
-
 
     }
 }
\ No newline at end of file
diff --git a/LifePayment/LifePayment.Host/LifePaymentServices.Application.Contracts.xml b/LifePayment/LifePayment.Host/LifePaymentServices.Application.Contracts.xml
index 3076291..0e1ce92 100644
--- a/LifePayment/LifePayment.Host/LifePaymentServices.Application.Contracts.xml
+++ b/LifePayment/LifePayment.Host/LifePaymentServices.Application.Contracts.xml
@@ -1298,6 +1298,191 @@
             绾夸笅鏀粯姹囨鏈�鏅氭椂闂�
             </summary>
         </member>
+        <member name="P:LifePayment.Application.Contracts.CreateBackClientUserInput.Name">
+            <summary>
+            鍚嶇О
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateBackClientUserInput.PhoneNumber">
+            <summary>
+            鎵嬫満鍙�
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateBackClientUserInput.UserName">
+            <summary>
+            璐︽埛
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateBackClientUserInput.RoleNames">
+            <summary>
+            瑙掕壊
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateBackClientUserInput.CompanyOrgId">
+            <summary>
+            缁勭粐鏋舵瀯鍏徃id
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateBackClientUserInput.DepartmentOrgId">
+            <summary>
+            缁勭粐鏋舵瀯閮ㄩ棬id
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateOrUpdateRoleInput.Id">
+            <summary>
+            瑙掕壊Id
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateBaseRoleInput.Name">
+            <summary>
+            鍚嶇О
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateBaseRoleInput.Sequence">
+            <summary>
+            鎺掑簭
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateBaseRoleInput.DepartmentId">
+            <summary>
+            閮ㄩ棬Id
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateBaseRoleInput.DataRange">
+            <summary>
+            鏁版嵁鑼冨洿 鍏ㄩ儴鏁版嵁100 涓汉鏁版嵁 10
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateBaseRoleInput.Remark">
+            <summary>
+            澶囨敞
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.UpdateBackClientUserInput.Id">
+            <summary>
+            鐢ㄦ埛Id
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.RoleEnableOrForbidInput.Id">
+            <summary>
+            瑙掕壊Id
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.RoleEnableOrForbidInput.IsEnable">
+            <summary>
+            鍚敤锛歵rue锛岀鐢細false
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.UserDto.Id">
+            <summary>
+            鐢ㄦ埛Id
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.UserDto.UserName">
+            <summary>
+            鐧诲綍鐢ㄦ埛鍚嶏紙璐﹀彿锛�
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.UserDto.Name">
+            <summary>
+            鍚嶇О
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.UserDto.PhoneNumber">
+            <summary>
+            鐢ㄦ埛鎵嬫満鍙�
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.UserDto.IsLocked">
+            <summary>
+            璐︽埛鏄惁閿佷綇锛堟槸鍚︾鐢級
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.UserDto.Roles">
+            <summary>
+            瑙掕壊淇℃伅
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.UserDto.Remark">
+            <summary>
+            澶囨敞
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.UserDto.CompanyOrgId">
+            <summary>
+            缁勭粐鏋舵瀯鍏徃id
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.UserDto.DepartmentOrgId">
+            <summary>
+            缁勭粐鏋舵瀯閮ㄩ棬id
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.GetBackClientUsersInput.IsLocked">
+            <summary>
+            璐︽埛鏄惁閿佷綇锛堟槸鍚︾鐢級
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.GetBackClientUsersInput.QueryCondition">
+            <summary>
+            鏌ヨ鏉′欢锛氬悕绉�/璐﹀彿
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.RoleDto.Id">
+            <summary>
+            瑙掕壊Id
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.RoleDto.Name">
+            <summary>
+            瑙掕壊鍚�
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.RoleInfo.Id">
+            <summary>
+            瑙掕壊Id
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.RoleInfo.Name">
+            <summary>
+            鍚嶇О
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.RoleInfo.Sequence">
+            <summary>
+            鎺掑簭
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.RoleInfo.IsEnable">
+            <summary>
+            鏄惁鍙敤
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.RoleInfo.DepartmentId">
+            <summary>
+            閮ㄩ棬Id
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.RoleInfo.DataRange">
+            <summary>
+            鏁版嵁鑼冨洿 鍏ㄩ儴鏁版嵁锛�100   涓汉鏁版嵁锛�10
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.RoleInfo.UserCount">
+            <summary>
+            璐﹀彿鏁伴噺
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.RoleInfo.Remark">
+            <summary>
+            澶囨敞
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.GetRolesInput.QueryCondition">
+            <summary>
+            鏌ヨ鏉′欢锛氳鑹插悕绉�
+            </summary>
+        </member>
         <member name="M:LifePayment.Application.Contracts.IAccountService.LifePayPhoneMesssageCodeLogin(LifePayment.Application.Contracts.LifePayPhoneMesssageCodeLoginInput)">
             <summary>
             鎵嬫満楠岃瘉鐮佺櫥褰�
@@ -1332,5 +1517,65 @@
             
             </summary>
         </member>
+        <member name="P:LifePayment.Application.Contracts.CreateAccountInput.Name">
+            <summary>
+            鍚嶇О
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateAccountInput.UserName">
+            <summary>
+            鐢ㄦ埛鍚�
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateAccountInput.Remark">
+            <summary>
+            澶囨敞
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateAccountInput.PhoneNumber">
+            <summary>
+            鎵嬫満鍙�
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateAccountInput.ClientId">
+            <summary>
+            鐢ㄦ埛绔疘d
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateAccountInput.RoleNames">
+            <summary>
+            瑙掕壊
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateAccountInput.OpenId">
+            <summary>
+            灏忕▼搴廜penId
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateAccountInput.EnterpriseName">
+            <summary>
+            浼佷笟鍚嶇О
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateAccountInput.AuthType">
+            <summary>
+            浼佷笟绫诲瀷
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateAccountInput.MatchMakingOpenId">
+            <summary>
+            MatchMaking灏忕▼搴廜penId
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateAccountInput.CompanyOrgId">
+            <summary>
+            缁勭粐鏋舵瀯鍏徃id
+            </summary>
+        </member>
+        <member name="P:LifePayment.Application.Contracts.CreateAccountInput.DepartmentOrgId">
+            <summary>
+            缁勭粐鏋舵瀯閮ㄩ棬id
+            </summary>
+        </member>
     </members>
 </doc>
diff --git a/LifePayment/LifePayment.Host/appsettings.json b/LifePayment/LifePayment.Host/appsettings.json
index eec152f..f1862cd 100644
--- a/LifePayment/LifePayment.Host/appsettings.json
+++ b/LifePayment/LifePayment.Host/appsettings.json
@@ -132,5 +132,29 @@
     "CheckPath": false,
     "AppName": "鐢熸椿缂磋垂"
   },
+  "WxPay": {
+    "Mchid": "1679627608",
+    "Url": "https://api.mch.weixin.qq.com",
+    "AppID": "wxf940ff1d35a98493",
+    "APIKey": "NingBoChuangSheng818nbcsxxjsfwyx",
+    "APIPrivateKey": "MIIEpQIBAAKCAQEA7M9w/63JiWRd9p1jAvnwbz52VFLCyG5qQLwZQP1WqD8UpUtuaqpOA0RNuCXJuNjyDpwGJdEU1vOTTEmrSmJ+liMTBC2Am6k15my1mxkaei/3UtzJLxzptLROBkWDz9SIMtuhMA+ychmAgJwuMS6HaDqSvfa9sdBqSkZf7i2ZMOUaZPVr+rsDMjlYlp87MNTJzvPkKjIJdxGhRw0S1O5G3A7Q36zTu5heAnR6+S9MLlW4cWJ1Qn+DxS71oK1K9rHEloEqgBFZC8LFSPD6dJ9ls7kWSy897B2LiArWJW8m/DO5mqNpq+4lTaX9ZGvlOmRRekRX0pM8qbasRZpN9TXNHwIDAQABAoIBAQCpXsCqDYj8XC2cSfrb0Rl25wzIyJyJr/cMr7u8MLV/BgblJisl3QKI8ZxInbZGH9wYON1oxL6L8pAiWvpI7GMvTIy4SzcVnhNv58aH1I+MXqwcts6phJteZCr971AUICT9gvopHsD5PGYdFhcvk+DC2knD1ircd3zd/LF172UGgyWCiyernOWYVdt+1HiO3EQNYpuiS1aTaDzRsxR4UOv8Cjlj5jKxa5Grhe5OwzUmupj48slwVqBgfhbWP70ZzIbFfBbRpMMkcU20v0N6QK2I0GsQ5ZdXnZb9pXWcUfgu8TMvpEiUYlAZOvYmDq/mnXc8epr9YfVTWxwomfvSRcWBAoGBAPiSKqQTzU1XBhJgFU+q8VSDHMz7ZYgZ++Pp9Jxti9jDzThDIxBFWHWCybsaZd0VZmJbDX3lq7G3+n783cXDgWDubdY57wo7nBlhRbf3h3nbS53gzrJ1pfVwIL+rpb3MqvfNnq5ffsO13fpoudI17IaFyyQ3BJwPvLtiWJUvmyBfAoGBAPPjSxf/SLcfP7pBs87gEiOAEi3cGZcwfgQijbdI+7fb3zyHXxE1muiH7VOwcVFJ3GnggQcvH+sG1ChoFG1O4ZYxPlZeANtgVX+HikVIOuddP2nkOf7ogUhhJswS8qBnELjW24+mzBrlOdm4kBvppk9Mya+mmy37uwP0o96IIYtBAoGASMIIBzTgoCW72j8TndksgI9MK9feNUNdzq2ZcvxBtfZCKJjGN6oEpYjd4Y1tiZQM/vcl8Nb8Na3jfa4ogA2k3imMLuuQQ4+FNoyZaqrildGRxama9vOm2zux6kik3/R7isM+Ek5TfZfLXNOwqI4uKIYbGwObrs6QcMztnuVrY8MCgYEAqCSZPicre8zYg9IOZF9JQh5m6iUno3u0NaeY6rcvjBfTdYii+1tovE4SSjOIPJHem0RD0K8lo0Sm+mCfTKkokALNRoAyuQxWhcDtjEx7B83bDWdisKKdl0gblnCtw/aqqbS/1O8bIqPM2ZUMDaJtnZiEKEyGChLWYajFXYOfFMECgYEAv1UxaZDVdge7qulUBtbALmuRE2kl+NZiuTkb9hjvQTD9iKJ8xdxBMvRIHi7m9tm10whDXdYSYMESEeyhEGE2HNoPqr4r8E10aH5GqrsZ6oil5xOB81B6aHksEJG9WIzbMjnKo6KSjx8PxMng9+tlMMmG5kA368dHOxnQxBTcZh4=",
+    "APIPublicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7M9w/63JiWRd9p1jAvnwbz52VFLCyG5qQLwZQP1WqD8UpUtuaqpOA0RNuCXJuNjyDpwGJdEU1vOTTEmrSmJ+liMTBC2Am6k15my1mxkaei/3UtzJLxzptLROBkWDz9SIMtuhMA+ychmAgJwuMS6HaDqSvfa9sdBqSkZf7i2ZMOUaZPVr+rsDMjlYlp87MNTJzvPkKjIJdxGhRw0S1O5G3A7Q36zTu5heAnR6+S9MLlW4cWJ1Qn+DxS71oK1K9rHEloEqgBFZC8LFSPD6dJ9ls7kWSy897B2LiArWJW8m/DO5mqNpq+4lTaX9ZGvlOmRRekRX0pM8qbasRZpN9TXNHwIDAQAB",
+    "SerialNo": "6DDD965D7597FA8280A0715306B86E77A87BA15B",
+    "NotifyUrl": "https://testrlywx.boleyuma.com"
+  },
+  "AliPay": {
+    "Protocol": "https",
+    "GatewayHost": "openapi.alipay.com",
+    "SignType": "RSA2",
+    "AppId": "2021004171602214",
+    "MerchantPrivateKey": "MIIEogIBAAKCAQEAoDrOheetqHkE1RYaNhogP/iHVXEtGZW4A/JJnwpJs+6eLXfpXf/ecuywplDpgc/BXSUEnDaktUwceLXO8vdIf8h0y8yqWwYdgzC0xELYpTroK3dlNiShgVkUEeMXi+n3Mhjp9OVrqieggDI3YGzDBLY4UAWsXCcXnD+r/xIpT8keVMtb/LrUmL5XLvBVcn5MkJTAoeFt18EQXOLFN1+ldpaf9k+iyM2fbgXCc6InNSgHGSHZwhzm9t+cGqNd1ju/nQN9lHwKCDQPMn6cor2lsP1nsEfpHp2vdfNEdccVSRZB/kdtFzXEUpTFznz8+zK2D0Ra+B0G1nSxus9xsD3HmwIDAQABAoIBACQYm2X3J1wIx1npvMXrZNCEgJhzAqH85JOfBY7alnf+jYvYs64FcmuZfsI5ACHKV9lP+ZXniXt+Rfu7mX+Kzb5bvlQbK1WOLx/a3R5JoNy4RI1mPFrSLcAh/S96ZVeTwah7jFkrRfHzM2kt5uPGHLj3BACjBo1METmV7n1r7fqXCus/Eihdo5ah8WOUPPMg8MqLadSnKVgnkzDLEa+8bagN/WgNfg9m4nW3IocEtFmKox3xV938eXpzn6KrgCduyK1Xn3d1PViRDT1QFOqhTCg17j8qDD4xZphH32Vbgq+heURmSMfecmC1u0CEpvFq3WBVxir/VOxk88gqkAzwusECgYEA+x/OjjNYaeOTFxCLtcI6EnerwgisF39rSNVAdSziWO3u8tUhzhHxB1cE5im4f9Qsd+r3Mw7Vu26YHgQn9O/A1QGoU3e0W/0Ckz5iIIJdAqBB279lNN+puYo4lIUfZha00i/R3Sj6eXrKGTwqCPRyHvJUC7biAAUgnqDAPLdPpgkCgYEAo1c3P4saxVqPnGheplud+jpEilp92dwHn9nIsaX0A/ohcYQIes+bKEZHHafn7ksDhidcjrbPMK72PP2HOJOL6D8a2w9zdyZ6jlycV5jiFHB6ywmkJ0517HWAJ6Fl3OsltDrxWHnuiyb/G/2fU1uLsO2U/b7zT9s2zXJzN53ZiYMCgYAmVku9T79eovxwl/kMLXOaICTbgWFsUOp6+vtVKB4B/4jsD3eSsxB9014PGS1ubmC/ieJlLA2bCJ42buH+tZ9VpWQiIfMp2+1Jt0tZtS0n2nlTZ9u2f7K0fZJ3sf8CIdNHBz/dqITciM9TnOi55z+I0+vawfeskxvQu6+9VSrWqQKBgD55voUMhMnVsLZnaUSCKHOsU8kDgb2Rnkzy9QOV8TaQNrh/gurOe481CkB6l4iaopdueMWRgMAjO8XqRw1Jyiqj8Ha3ezeovRm0rIwIyvh8aUs9vc7XAN3Xt5Pw9NBCFOLR5LwtryMEYHFpWcZ9bnnW9bT0k4YI1/ZO/2jXdHxXAoGAQLGrsed0HLWRjGU2rAUvA9Kny6wo+ScUas5IhoAhGMYDDQ8lFbndgnIOMjdXllT9IvmVERMTSMmP2m7+aqKNz3x0kTkg0tIQTLPsaWCjI5G4CDASUPo/jPvcd4h3euclhpuhcU9FMme3R5UhMAZy1bt+1VWPRxRB0gzWi4d7AFQ=",
+    "MerchantCertPath": "Cert/appCertPublicKey_2021004171602214.crt",
+    "AlipayCertPath": "Cert/alipayCertPublicKey_RSA2.crt",
+    "AlipayRootCertPath": "Cert/alipayRootCert.crt",
+    "NotifyUrl": "https://testrlywx.boleyuma.com",
+    "EncryptKey": "jjy8A7hB/1Bkhg+8FtXyyg==",
+    "AlipayPublicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoDrOheetqHkE1RYaNhogP/iHVXEtGZW4A/JJnwpJs+6eLXfpXf/ecuywplDpgc/BXSUEnDaktUwceLXO8vdIf8h0y8yqWwYdgzC0xELYpTroK3dlNiShgVkUEeMXi+n3Mhjp9OVrqieggDI3YGzDBLY4UAWsXCcXnD+r/xIpT8keVMtb/LrUmL5XLvBVcn5MkJTAoeFt18EQXOLFN1+ldpaf9k+iyM2fbgXCc6InNSgHGSHZwhzm9t+cGqNd1ju/nQN9lHwKCDQPMn6cor2lsP1nsEfpHp2vdfNEdccVSRZB/kdtFzXEUpTFznz8+zK2D0Ra+B0G1nSxus9xsD3HmwIDAQAB"
+  },
+
   "AllowedHosts": "*"
 }
\ No newline at end of file
diff --git a/LifePayment/LifePayment.HttpApi/LifePay/AccountController.cs b/LifePayment/LifePayment.HttpApi/LifePay/AccountController.cs
index 804b358..5737e00 100644
--- a/LifePayment/LifePayment.HttpApi/LifePay/AccountController.cs
+++ b/LifePayment/LifePayment.HttpApi/LifePay/AccountController.cs
@@ -9,6 +9,8 @@
 using Volo.Abp;
 using Volo.Abp.AspNetCore.Mvc;
 using Volo.Abp.AspNetCore.WebClientInfo;
+using Volo.Abp.Identity.Application.Contracts.Account;
+using Volo.Abp.IdentityModel;
 
 namespace LifePayment.HttpApi
 {
@@ -69,6 +71,13 @@
             OssSTSHelper ossSTSHelper = new OssSTSHelper(this.ossSettings);
             return ossSTSHelper.GetOssSTS();
         }
+
+        [HttpPost]
+        public async Task<IdentityModelTokenCacheItem> GetTokenForWeb(AccessRequestDto accessRequestDto)
+        {
+            var webClientIp = _webClientInfoProvider.ClientIpAddress;
+            return await _accountService.GetTokenForWeb(accessRequestDto, webClientIp);
+        }
         #endregion
 
 
diff --git a/LifePayment/LifePayment.HttpApi/LifePay/UserRoleController.cs b/LifePayment/LifePayment.HttpApi/LifePay/UserRoleController.cs
new file mode 100644
index 0000000..aec1d39
--- /dev/null
+++ b/LifePayment/LifePayment.HttpApi/LifePay/UserRoleController.cs
@@ -0,0 +1,183 @@
+锘縰sing LifePayment.Application.Contracts;
+using LifePayment.Domain.Shared;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Threading.Tasks;
+using Volo.Abp.AspNetCore.Mvc;
+using Volo.Abp.Identity;
+using ZeroD.Util;
+
+namespace LifePayment.HttpApi
+{
+    [Route("api/[controller]/[action]")]
+    [ApiController]
+    [Authorize]
+    public class UserRoleController : AbpController
+    {
+        private readonly IAccountService _accountService;
+        private readonly IUserRoleService _userRoleService;
+        private readonly IIdentityUserAppService _identityUserService;
+        private readonly IIdentityRoleAppService _identityRoleService;
+
+        public UserRoleController(
+               IAccountService accountService,
+               IUserRoleService userRoleService,
+               IIdentityUserAppService identityUserService,
+               IIdentityRoleAppService identityRoleService)
+        {
+            _accountService = accountService;
+            _userRoleService = userRoleService;
+            _identityUserService = identityUserService;
+            _identityRoleService = identityRoleService;
+        }
+
+        /// <summary>
+        /// 鏂板鍚庡彴绠$悊璐︽埛
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<Guid> CreateBackClientUser(CreateBackClientUserInput input)
+        {
+            return await _accountService.CreateAccount(ObjectMapper.Map<CreateBackClientUserInput, CreateAccountInput>(input), isAdminCreate: true);
+        }
+
+        /// <summary>
+        /// 鍚庡彴绠$悊璐︽埛鍒楄〃
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<PageOutput<UserDto>> GetBackClientUsers(GetBackClientUsersInput input)
+        {
+            return await _userRoleService.GetBackClientUsers(input);
+        }
+
+        /// <summary>
+        /// 鍚庡彴绠$悊璐︽埛缂栬緫
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<int> UpdateBackClientUser(UpdateBackClientUserInput input)
+        {
+            await _identityUserService.UpdateAsync(input.Id, new IdentityUserUpdateDto
+            {
+                Name = input.Name,
+                PhoneNumber = input.PhoneNumber,
+                UserName = input.UserName,
+                RoleNames = input.RoleNames,
+            });
+            return await _userRoleService.UpdateBackClientUser(input);
+        }
+
+        /// <summary>
+        /// 鍒犻櫎鍚庡彴绠$悊璐︽埛
+        /// </summary>
+        /// <param name="id">鐢ㄦ埛Id</param>
+        /// <returns></returns>
+        [HttpGet]
+        public async Task<int> DeleteBackClientUser(Guid id)
+        {
+            await _identityUserService.DeleteAsync(id);
+            return await _userRoleService.DeleteBackClientUser(id);
+        }
+
+        /// <summary>
+        /// 鏂板瑙掕壊
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<Guid> CreateRole(CreateBaseRoleInput input)
+        {
+            if (input.DataRange == LifePaymentConstant.DataRange.PowerPerson)
+            {
+                input.Name = input.Name.Replace(LifePaymentConstant.DataRangePower.PowerPerson, string.Empty) + LifePaymentConstant.DataRangePower.PowerPerson;
+            }
+            else
+            {
+                input.Name = input.Name.Replace(LifePaymentConstant.DataRangePower.PowerAll, string.Empty) + LifePaymentConstant.DataRangePower.PowerAll;
+            }
+
+            var res = await _identityRoleService.CreateAsync(new IdentityRoleCreateDto
+            {
+                Name = input.Name,
+                Sequence = input.Sequence,
+                Note = input.Remark,
+            });
+            var newInput = ObjectMapper.Map<CreateBaseRoleInput, CreateOrUpdateRoleInput>(input);
+            newInput.Id = res.Id;
+            await _userRoleService.CreateRole(newInput);
+            return res.Id;
+        }
+
+        /// <summary>
+        /// 瑙掕壊鍒楄〃
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<PageOutput<RoleInfo>> GetRoles(GetRolesInput input)
+        {
+            return await _userRoleService.GetRoles(input);
+        }
+
+        /// <summary>
+        /// 瑙掕壊缂栬緫
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<int> UpdateRole(CreateOrUpdateRoleInput input)
+        {
+            if (input.DataRange == LifePaymentConstant.DataRange.PowerPerson)
+            {
+                input.Name = input.Name.Replace(LifePaymentConstant.DataRangePower.PowerPerson, string.Empty) + LifePaymentConstant.DataRangePower.PowerPerson;
+            }
+            else
+            {
+                input.Name = input.Name.Replace(LifePaymentConstant.DataRangePower.PowerAll, string.Empty) + LifePaymentConstant.DataRangePower.PowerAll;
+            }
+
+
+            await _identityRoleService.UpdateAsync(input.Id, new IdentityRoleUpdateDto
+            {
+                Name = input.Name,
+                Sequence = input.Sequence,
+                Note = input.Remark,
+            });
+            return await _userRoleService.UpdateRole(input);
+        }
+
+        /// <summary>
+        /// 瑙掕壊鍚敤/绂佺敤
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<int> RoleEnableOrForbid(RoleEnableOrForbidInput input)
+        {
+            await _identityRoleService.UpdateAsync(input.Id, new IdentityRoleUpdateDto
+            {
+                IsSetEnable = true,
+                IsEnable = input.IsEnable,
+                Name = input.Name,
+            });
+            return await _userRoleService.RoleEnableOrForbid(input.Id, input.IsEnable);
+        }
+
+        /// <summary>
+        /// 鍒犻櫎瑙掕壊
+        /// </summary>
+        /// <param name="id">瑙掕壊Id</param>
+        /// <returns></returns>
+        [HttpGet]
+        public async Task<int> DeleteRole(Guid id)
+        {
+            await _identityRoleService.DeleteAsync(id);
+            return await _userRoleService.DeleteRole(id);
+        }
+    }
+}
\ No newline at end of file

--
Gitblit v1.9.1