From 05ee79a04f9dbe6f7f42f6656ce00bb657daf170 Mon Sep 17 00:00:00 2001
From: tongfei <244188119@qq.com>
Date: Wed, 18 Oct 2023 10:37:41 +0800
Subject: [PATCH] domian-build
---
src/WMS.Web.Api/wwwroot/WMS.Web.Domain.xml | 968 ++++++++++++++++++
.../IService/Public/IHttpClientService.cs | 17 +
.../IService/Public/ILoginService.cs | 73 ++
.../IService/Public/ISingleDataService.cs | 127 +++
src/WMS.Web.Domain/Mappers/AppMapper.cs | 17 +
src/WMS.Web.Domain/Mappers/MapperList.cs | 56 +
src/WMS.Web.Domain/Options/AppOptions.cs | 39 +
src/WMS.Web.Domain/Options/SoaOptions.cs | 39 +
.../Services/Public/HttpClientService.cs | 230 +++++
.../Services/Public/LoginService.cs | 387 +++++++
.../Services/Public/RedisClientService.cs | 93 ++
.../Services/Public/SingleDataService.cs | 473 +++++++++
src/WMS.Web.Domain/Values/ResultCodes.cs | 13 +
.../Values/Single/SingleAction.cs | 105 ++
.../Values/Single/SingleControllerType.cs | 29 +
.../Values/Single/SingleLoginAction.cs | 42 +
.../Values/Single/SysConfigAction.cs | 186 ++++
src/WMS.Web.Domain/WMS.Web.Domain.csproj | 5 -
18 files changed, 2894 insertions(+), 5 deletions(-)
create mode 100644 src/WMS.Web.Domain/IService/Public/IHttpClientService.cs
create mode 100644 src/WMS.Web.Domain/IService/Public/ILoginService.cs
create mode 100644 src/WMS.Web.Domain/IService/Public/ISingleDataService.cs
create mode 100644 src/WMS.Web.Domain/Mappers/AppMapper.cs
create mode 100644 src/WMS.Web.Domain/Mappers/MapperList.cs
create mode 100644 src/WMS.Web.Domain/Options/AppOptions.cs
create mode 100644 src/WMS.Web.Domain/Options/SoaOptions.cs
create mode 100644 src/WMS.Web.Domain/Services/Public/HttpClientService.cs
create mode 100644 src/WMS.Web.Domain/Services/Public/LoginService.cs
create mode 100644 src/WMS.Web.Domain/Services/Public/RedisClientService.cs
create mode 100644 src/WMS.Web.Domain/Services/Public/SingleDataService.cs
create mode 100644 src/WMS.Web.Domain/Values/ResultCodes.cs
create mode 100644 src/WMS.Web.Domain/Values/Single/SingleAction.cs
create mode 100644 src/WMS.Web.Domain/Values/Single/SingleControllerType.cs
create mode 100644 src/WMS.Web.Domain/Values/Single/SingleLoginAction.cs
create mode 100644 src/WMS.Web.Domain/Values/Single/SysConfigAction.cs
diff --git a/src/WMS.Web.Api/wwwroot/WMS.Web.Domain.xml b/src/WMS.Web.Api/wwwroot/WMS.Web.Domain.xml
index 4edb2f1c..424ad6fc 100644
--- a/src/WMS.Web.Api/wwwroot/WMS.Web.Domain.xml
+++ b/src/WMS.Web.Api/wwwroot/WMS.Web.Domain.xml
@@ -4,5 +4,973 @@
WMS.Web.Domain
+
+
+ 登录服务接口
+
+
+
+
+ 得到单点用户信息
+
+
+
+
+
+
+ 登录退出
+
+
+
+
+
+
+ 刷新token
+
+
+
+
+
+ 单点退出通知token失效
+
+
+
+
+
+
+
+
+ 单点退出通知token失效
+
+
+
+
+
+
+ 获取登录后的信息
+
+
+
+
+
+
+ 单点-在线接口
+
+
+
+
+
+
+ 单点-下线接口
+
+
+
+
+
+
+ 单点数据返回服务接口
+
+
+
+
+ 获取单点数据:根据方法名和公司ID
+
+
+
+
+
+
+
+
+ 获取单点数据:根据方法名和公司ID
+
+
+
+
+
+
+
+
+ 获取单点数据:根据方法名和公司ID
+
+
+
+
+
+
+
+
+ 获取单点数据:根据方法名和公司ID
+
+
+
+
+
+
+
+
+ 根据名字模糊匹配
+
+
+
+
+
+
+
+
+ 获取单点数据集合:泛型-同步
+
+
+
+
+
+
+
+
+ 获取单点数据集合:泛型-异步
+
+
+
+
+
+
+
+
+ 获取单点数据集合:泛型-异步-无缓存
+
+
+
+
+
+
+
+
+ 单点数据:可对接全部接口
+
+ 返回对象
+ 请求对象
+ 方法名称
+ 请求对象
+ 方法名称
+ 控制器名称
+
+
+
+
+ 单点数据:可对接全部接口-无缓存
+
+
+
+
+
+
+
+
+
+
+
+ 获取单点数据:请求对象和接口方法名
+
+
+
+
+
+
+
+
+
+ 获取客户仓库
+
+
+
+
+
+
+
+ mapper映射
+
+
+
+
+ 集合映射
+
+
+
+
+ 映射实体里 集合属性
+
+
+
+
+
+
+
+
+
+
+ 数据库
+
+
+
+
+ redis
+
+
+
+
+ 单点数据请求地址-后端使用接口地址
+
+
+
+
+ redis数据目录
+
+
+
+
+ 数据库类型
+
+
+
+
+ 是否允许缓存
+
+
+
+
+ 单点系统地址
+
+
+
+
+ 应用id
+
+
+
+
+ AppId
+
+
+
+
+ AppSecret
+
+
+
+
+ 公钥
+
+
+
+
+ 私钥
+
+
+
+
+ Get方法
+
+
+
+
+
+
+
+
+
+ Get方法
+
+
+
+
+
+
+
+
+
+ Post方法
+
+
+
+
+
+
+
+
+
+
+ Post方法
+
+
+
+
+
+
+
+
+
+ 公共http请求
+
+
+
+
+
+
+
+
+
+
+
+ 设置HttpRequestMessage
+
+
+
+
+
+
+
+
+
+ 设置请求内容
+
+
+
+
+
+
+
+ 设置请求头和超时时间:返回client
+
+
+
+
+
+
+
+ 创建token
+
+
+
+
+
+
+
+
+ 得到单点用户信息
+
+
+
+
+
+
+ 登录退出
+
+
+
+
+
+ 刷新token
+
+
+
+
+
+ 单点退出通知token失效
+
+
+
+
+
+
+
+
+ 单点退出通知token失效
+
+ 这个是单点传过来的SeesionId
+
+
+
+
+ 缓存退出的token
+
+
+
+
+
+
+ 获取登录后的信息
+
+
+
+
+
+
+ 移除登录后的用户信息
+
+
+
+
+
+ 单点-在线接口
+
+
+
+
+
+
+ 单点-下线接口
+
+
+
+
+
+
+ 保存单个key value
+
+
+
+
+
+
+
+
+ 获取单个key的值
+
+
+
+
+ 移除redis
+
+
+
+
+
+
+ 获取一个key的对象
+
+
+
+
+ 保存一个对象
+
+
+
+
+
+ 单点数据返回服务
+
+
+
+
+ 获取单点数据:根据接口方法名和公司ID
+ 后端列表查询统一使用
+
+
+
+
+
+
+
+ 获取单点数据:根据接口方法名和公司ID
+ 后端列表查询统一使用
+
+
+
+
+
+
+
+ 获取单点数据:根据接口方法名和公司ID
+ 后端列表查询统一使用
+
+
+
+
+
+
+
+ 根据名字模糊匹配
+
+
+
+
+
+
+
+
+ 获取单点数据:根据接口方法名和公司ID
+ 后端列表查询统一使用
+
+
+
+
+
+
+
+ 获取单点数据集合:泛型-同步
+
+
+
+
+
+
+
+
+ 获取单点数据集合:泛型-异步
+
+
+
+
+
+
+
+
+ 获取单点数据集合:泛型-异步-无缓存
+
+
+
+
+
+
+
+
+ 单点数据:可对接全部接口
+
+ 返回对象
+ 请求对象
+ 方法名称
+ 请求对象
+ 方法名称
+ 控制器名称
+
+
+
+
+ 单点数据:可对接全部接口
+
+ 返回对象
+ 请求对象
+ 方法名称
+ 请求对象
+ 方法名称
+ 控制器名称
+
+
+
+
+ 获取单点数据:配置项接口
+
+
+
+
+
+
+
+
+
+ 请求单点服务接口:同步
+
+
+
+
+
+
+
+
+ 请求单点服务接口:异步
+
+
+
+
+
+
+
+
+ 获取客户仓库
+
+
+
+
+
+
+
+ 错误提示信息
+
+
+
+
+ 对接单点的接口方法-枚举
+
+
+
+
+ 组织集合
+
+
+
+
+ 用户集合
+
+
+
+
+ 人员集合
+
+
+
+
+ 供应商集合
+
+
+
+
+ 客户集合
+
+
+
+
+ 收款条件集合
+
+
+
+
+ 付款条件集合
+
+
+
+
+ 结算方式集合
+
+
+
+
+ 结算币别集合
+
+
+
+
+ 税率集合
+
+
+
+
+ 汇率集合
+
+
+
+
+ 仓库集合
+
+
+
+
+ 单位集合
+
+
+
+
+ 客户仓库集合
+
+
+
+
+ 部门集合
+
+
+
+
+ 仓库211集合
+
+
+
+
+ 供应商默认联系人集合
+
+
+
+
+ 菜单集合
+
+
+
+
+ 单点-控制器枚举
+
+
+
+
+ 单点OPS列表数据-控制器
+
+
+
+
+ 单点配置项数据-控制器
+
+
+
+
+ 单点登录项数据-控制器
+
+
+
+
+ 单点公共接口数据-控制器
+
+
+
+
+ 单点数据接口-登录要使用的数据接口-方法枚举
+
+
+
+
+ 菜单
+
+
+
+
+ 人员
+
+
+
+
+ 公司
+
+
+
+
+ 供应商
+
+
+
+
+ 客户
+
+
+
+
+ 全部信息
+
+
+
+
+ 公司信息
+
+
+
+
+ 单点数据:配置项和公共接口的方法枚举值
+
+
+
+
+ 供应商-根据名称和公司
+
+
+
+
+ 组织-根据公司
+
+
+
+
+ 部门-根据组织和公司
+
+
+
+
+ 人员-根据公司
+
+
+
+
+ 人员-根据部门和公司
+
+
+
+
+ 人员-根据组织和公司
+
+
+
+
+ 客户-根据公司
+
+
+
+
+ 客户-根据客户和组织和公司
+
+
+
+
+ 客户信息-根据客户和组织和公司
+
+
+
+
+ 收款条件-根据公司
+
+
+
+
+ 付款条件-根据公司
+
+
+
+
+ 结算方式-根据公司
+
+
+
+
+ 结算币别-根据公司
+
+
+
+
+ 单位-根据公司
+
+
+
+
+ 单位(部分属性)-根据公司
+
+
+
+
+ 税率-根据公司
+
+
+
+
+ 仓库-根据名称和公司
+
+
+
+
+ 仓库-根据组织和公司
+
+
+
+
+ 仓库(不是调拨中转仓)-根据组织和公司
+
+
+
+
+ 仓库(211)-根据组织和公司
+
+
+
+
+ 仓库-根据客户和公司
+
+
+
+
+ 仓位-根据仓库和名称
+
+
+
+
+ 仓位-根据-
+
+
+
+
+ 汇率信息-根据原币、目标币和公司
+
+
+
+
+ 客户仓库-根据客户和组织和公司
+
+
+
+
+ 付款条件,结算币别,结算方式,采购员,采购部门-根据供应商和组织
+
+
+
+
+ 获取仓库:根据仓库id
+
+
+
+
+ 获取库存:根据组织和公司
+
+
+
+
+ 获取客户仓库:根据客户IDS和组织和公司
+
+
+
+
+ 汇率(所有)
+
+
+
+
+ 供应商选择后获取:付款条件,结算币别,结算方式,采购员,采购部门,根据组织IDS
+
+
+
+
+ 获取客户仓库:根据code集合
+
+
+
+
+ 供应商:根据ids
+
+
+
+
+ 根据公司搜索所有仓库(计算补货频次)
+
+
+
+
+ 获取仓库:根据codes
+
+
+
+
+ 获取客户仓库:根据codes
+
+
+
+
+ 获取调拨中转仓库:根据公司
+
+
+
+
+ 获取供应商数据根据ids
+
+
+
+
+ 获取仓库:根据默认补货客户
+
+
+
+
+ 获取用户(ID和Name):根据公司
+
+
+
+
+ 全部部门-根据组织和公司:不处理子级
+
+
+
+
+ 获取全部员工:根据公司和组织
+
+
diff --git a/src/WMS.Web.Domain/IService/Public/IHttpClientService.cs b/src/WMS.Web.Domain/IService/Public/IHttpClientService.cs
new file mode 100644
index 00000000..6b35e31a
--- /dev/null
+++ b/src/WMS.Web.Domain/IService/Public/IHttpClientService.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace WMS.Web.Domain.IService.Public
+{
+ public interface IHttpClientService
+ {
+ Task GetAsync(string url, int timeoutSecond = 180);
+ Task GetAsync(string url, Dictionary dicHeaders, int timeoutSecond = 180);
+ Task PostAsync(string url, string requestBody, int timeoutSecond = 180);
+ Task PostAsync(string url, string requestBody, Dictionary dicHeaders, int timeoutSecond = 180);
+ Task ExecuteAsync(string url, HttpMethod method, string requestBody, Dictionary dicHeaders, int timeoutSecond = 180);
+ }
+}
diff --git a/src/WMS.Web.Domain/IService/Public/ILoginService.cs b/src/WMS.Web.Domain/IService/Public/ILoginService.cs
new file mode 100644
index 00000000..3fe2c687
--- /dev/null
+++ b/src/WMS.Web.Domain/IService/Public/ILoginService.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using WMS.Web.Core.Dto.Login;
+using WMS.Web.Core.Internal.Results;
+
+namespace WMS.Web.Domain.IService.Public
+{
+ ///
+ /// 登录服务接口
+ ///
+ public interface ILoginService
+ {
+ ///
+ /// 得到单点用户信息
+ ///
+ ///
+ ///
+ Task> GetUserInfoAsync(string code);
+
+ ///
+ /// 登录退出
+ ///
+ ///
+ ///
+ Task LoginOutAsync(LoginOutDto dto);
+
+
+ ///
+ /// 刷新token
+ ///
+ ///
+ Task> RefreshToken(string OldToken, string RefreshToken);
+
+ ///
+ /// 单点退出通知token失效
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task LoginOutSingleAsync(int ucid, string token, int expires_in);
+
+ ///
+ /// 单点退出通知token失效
+ ///
+ ///
+ ///
+ Task LoginOutSingleAsync(string SeesionId);
+
+ ///
+ /// 获取登录后的信息
+ ///
+ ///
+ ///
+ LoginInDto GetLoginInfo(string authorization);
+
+ ///
+ /// 单点-在线接口
+ ///
+ ///
+ ///
+ Task Online(string sessionId);
+
+ ///
+ /// 单点-下线接口
+ ///
+ ///
+ ///
+ Task Offline(string sessionId);
+ }
+}
diff --git a/src/WMS.Web.Domain/IService/Public/ISingleDataService.cs b/src/WMS.Web.Domain/IService/Public/ISingleDataService.cs
new file mode 100644
index 00000000..5cbaeec4
--- /dev/null
+++ b/src/WMS.Web.Domain/IService/Public/ISingleDataService.cs
@@ -0,0 +1,127 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using WMS.Web.Domain.Values.Single;
+
+namespace WMS.Web.Domain.IService.Public
+{
+ ///
+ /// 单点数据返回服务接口
+ ///
+ public interface ISingleDataService
+ {
+ ///
+ /// 获取单点数据:根据方法名和公司ID
+ ///
+ ///
+ ///
+ ///
+ ///
+ string GetSingleData(SingleAction action, int companyId, int id);
+
+ ///
+ /// 获取单点数据:根据方法名和公司ID
+ ///
+ ///
+ ///
+ ///
+ ///
+ decimal GetSingleDataNumber(SingleAction action, int companyId, int id);
+ ///
+ /// 获取单点数据:根据方法名和公司ID
+ ///
+ ///
+ ///
+ ///
+ ///
+ string GetSingleDataCode(SingleAction action, int companyId, int id);
+
+ ///
+ /// 获取单点数据:根据方法名和公司ID
+ ///
+ ///
+ ///
+ ///
+ ///
+ string GetSingleData(SingleAction action, int companyId, string code);
+ ///
+ /// 根据名字模糊匹配
+ ///
+ ///
+ ///
+ ///
+ ///
+ List GetIdsBySingleName(SingleAction action, int companyId, string name);
+
+
+ ///
+ /// 获取单点数据集合:泛型-同步
+ ///
+ ///
+ ///
+ ///
+ ///
+ List GetSingleData(SingleAction action, int companyId) where T : class;
+
+ ///
+ /// 获取单点数据集合:泛型-异步
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task> GetSingleDataAsync(SingleAction action, int companyId) where T : class;
+
+ ///
+ /// 获取单点数据集合:泛型-异步-无缓存
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task> GetSingleDataNoCacheAsync(SingleAction action, int companyId) where T : class;
+
+ ///
+ /// 单点数据:可对接全部接口
+ ///
+ /// 返回对象
+ /// 请求对象
+ /// 方法名称
+ /// 请求对象
+ /// 方法名称
+ /// 控制器名称
+ ///
+ Task GetSingleData(X dto, Y action, SingleControllerType type = SingleControllerType.Single) where T : class;
+
+ ///
+ /// 单点数据:可对接全部接口-无缓存
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task GetSingleDataNoCache(X dto, Y action, SingleControllerType type = SingleControllerType.Single) where T : class;
+
+ ///
+ /// 获取单点数据:请求对象和接口方法名
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task GetSysConfigData(X dto, SysConfigAction action);
+
+ ///
+ /// 获取客户仓库
+ ///
+ ///
+ ///
+ ///
+ string GetCustomerStock(int companyId, string customerStockCode);
+ }
+}
diff --git a/src/WMS.Web.Domain/Mappers/AppMapper.cs b/src/WMS.Web.Domain/Mappers/AppMapper.cs
new file mode 100644
index 00000000..df5efc1c
--- /dev/null
+++ b/src/WMS.Web.Domain/Mappers/AppMapper.cs
@@ -0,0 +1,17 @@
+using AutoMapper;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WMS.Web.Domain.Mappers
+{
+ ///
+ /// mapper映射
+ ///
+ public class AppMapper : Profile
+ {
+ public AppMapper()
+ {
+ }
+ }
+}
diff --git a/src/WMS.Web.Domain/Mappers/MapperList.cs b/src/WMS.Web.Domain/Mappers/MapperList.cs
new file mode 100644
index 00000000..3d2b89d1
--- /dev/null
+++ b/src/WMS.Web.Domain/Mappers/MapperList.cs
@@ -0,0 +1,56 @@
+using AutoMapper;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using WMS.Web.Core;
+
+namespace WMS.Web.Domain.Mappers
+{
+ ///
+ /// 集合映射
+ ///
+ public static class MapperList
+ {
+ ///
+ /// 映射实体里 集合属性
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static List ToMapList(this IMapper mapper, List sourcList, List destinationList)
+ where ST : EntityBase
+ where DT : EntityBase
+ {
+ for (int i = 0; i < destinationList.Count; i++)
+ {
+ int id = destinationList[i].Id;
+ var detail = sourcList.FirstOrDefault(f => f.Id == id);
+ if (detail == null)
+ {
+ destinationList.Remove(destinationList[i]);
+ i--;//在列表移除掉一条数据后 必须把index回拨一位 因为数据在移除一条后会调整下标
+ }
+ }
+
+ foreach (var st in sourcList)
+ {
+ if (st.Id == 0)
+ destinationList.Add(mapper.Map(st));
+ else
+ {
+ var detail = destinationList.FirstOrDefault(f => f.Id == st.Id);
+
+ if (detail != null)
+ mapper.Map(st, detail);
+ //如果在目标数据里没找到这条id的数据 则不作处理
+ }
+ }
+
+ return destinationList;
+ }
+ }
+}
diff --git a/src/WMS.Web.Domain/Options/AppOptions.cs b/src/WMS.Web.Domain/Options/AppOptions.cs
new file mode 100644
index 00000000..e0553f91
--- /dev/null
+++ b/src/WMS.Web.Domain/Options/AppOptions.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WMS.Web.Domain.Options
+{
+ public class AppOptions
+ {
+ ///
+ /// 数据库
+ ///
+ public string DBConnectionString { get; set; }
+
+ ///
+ /// redis
+ ///
+ public string RedisConnectionString { get; set; }
+
+ ///
+ /// 单点数据请求地址-后端使用接口地址
+ ///
+ public string SingleBaseUrl { get; set; }
+
+ ///
+ /// redis数据目录
+ ///
+ public string RedisDirectory { get; set; }
+
+ ///
+ /// 数据库类型
+ ///
+ public string DBType { get; set; }
+
+ ///
+ /// 是否允许缓存
+ ///
+ public bool AllowCache { get; set; }
+ }
+}
diff --git a/src/WMS.Web.Domain/Options/SoaOptions.cs b/src/WMS.Web.Domain/Options/SoaOptions.cs
new file mode 100644
index 00000000..3458899b
--- /dev/null
+++ b/src/WMS.Web.Domain/Options/SoaOptions.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WMS.Web.Domain.Options
+{
+ public class SoaOptions
+ {
+ ///
+ /// 单点系统地址
+ ///
+ public string Url { get; set; }
+
+ ///
+ /// 应用id
+ ///
+ public int ModuleID { get; set; }
+
+ ///
+ /// AppId
+ ///
+ public string AppId { get; set; }
+
+ ///
+ /// AppSecret
+ ///
+ public string AppSecret { get; set; }
+
+ ///
+ /// 公钥
+ ///
+ public string PublicKey { get; set; }
+
+ ///
+ /// 私钥
+ ///
+ public string PrivateKey { get; set; }
+ }
+}
diff --git a/src/WMS.Web.Domain/Services/Public/HttpClientService.cs b/src/WMS.Web.Domain/Services/Public/HttpClientService.cs
new file mode 100644
index 00000000..db4f48e0
--- /dev/null
+++ b/src/WMS.Web.Domain/Services/Public/HttpClientService.cs
@@ -0,0 +1,230 @@
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+using WMS.Web.Core.Exceptions;
+using WMS.Web.Domain.IService.Public;
+
+namespace WMS.Web.Domain.Services.Public
+{
+ public class HttpClientService : IHttpClientService
+ {
+ private readonly IHttpClientFactory _clientFactory;
+ private readonly ILogger _logger;
+ private Dictionary headers;
+ private Dictionary contentHeaders;
+ public HttpClientService(IHttpClientFactory clientFactory, ILogger logger)
+ {
+ _clientFactory = clientFactory;
+ _logger = logger;
+ headers = new Dictionary();
+ headers.Add("Accept", "application/json");
+ headers.Add("User-Agent", "HttpClientFactory-Sample");
+
+ contentHeaders = new Dictionary();
+ contentHeaders.Add("Content-Type", "application/json; charset=utf-8");
+
+ }
+
+ ///
+ /// Get方法
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task GetAsync(string url, int timeoutSecond = 180)
+ {
+ try
+ {
+ var client = BuildHttpClient(headers, timeoutSecond);
+ var response = await client.GetAsync(url);
+ //var responseContent = await response.Content.ReadAsStreamAsync();//1.相比ReadAsString这个方法返回要快点,效率高
+ var responseContent = await response.Content.ReadAsStringAsync(); //2.当前使用这里是为了迎合错误信息观看
+ if (response.IsSuccessStatusCode)
+ {
+ var t = JsonSerializer.Deserialize(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
+ //var t = await JsonSerializer.DeserializeAsync(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });//3.配合1的ReadAsStream使用
+ return t;
+ }
+
+ throw new WebHttpException(response.StatusCode.ToString(), "请求出错");
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"HttpGet:{url} Error:{ex.Message}");
+ throw new Exception($"HttpGet:{url} Error", ex);
+ }
+ }
+
+ ///
+ /// Get方法
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task GetAsync(string url, Dictionary dicHeaders, int timeoutSecond = 180)
+ {
+ try
+ {
+ var client = BuildHttpClient(dicHeaders, timeoutSecond);
+ var response = await client.GetAsync(url);
+ //var responseContent = await response.Content.ReadAsStreamAsync();//1.相比ReadAsString这个方法返回要快点,效率高
+ var responseContent = await response.Content.ReadAsStringAsync(); //2.当前使用这里是为了迎合错误信息观看
+ if (response.IsSuccessStatusCode)
+ {
+ var t = JsonSerializer.Deserialize(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
+ //var t = await JsonSerializer.DeserializeAsync(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });//3.配合1的ReadAsStream使用
+ return t;
+ }
+
+ throw new WebHttpException(response.StatusCode.ToString(), "请求出错");
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"HttpGet:{url} Error:{ex.Message}");
+ throw new Exception($"HttpGet:{url} Error", ex);
+ }
+ }
+
+ ///
+ /// Post方法
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task PostAsync(string url, string requestBody, Dictionary dicHeaders, int timeoutSecond = 180)
+ {
+ var client = BuildHttpClient(null, timeoutSecond);
+ var requestContent = GenerateStringContent(requestBody, dicHeaders);
+ var response = await client.PostAsync(url, requestContent);
+ var responseContent = await response.Content.ReadAsStringAsync();
+ if (response.IsSuccessStatusCode)
+ {
+ var t = JsonSerializer.Deserialize(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
+ return t;
+ }
+
+ _logger.LogError($"HttpGet:{url} Error:{responseContent}");
+ throw new WebHttpException(response.StatusCode.ToString(), responseContent);
+ }
+
+ ///
+ /// Post方法
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task PostAsync(string url, string requestBody, int timeoutSecond = 180)
+ {
+ var client = BuildHttpClient(null, timeoutSecond);
+ var requestContent = GenerateStringContent(requestBody, contentHeaders);
+ var response = await client.PostAsync(url, requestContent);
+ var responseContent = await response.Content.ReadAsStringAsync();
+ if (response.IsSuccessStatusCode)
+ {
+ var t = JsonSerializer.Deserialize(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
+ if (t == null)
+ _logger.LogInformation($"获取单点数据为空---{responseContent}");
+ return t;
+ }
+
+ _logger.LogError($"HttpGet:{url} Error:{responseContent}");
+ throw new WebHttpException(response.StatusCode.ToString(), responseContent);
+ }
+
+ ///
+ /// 公共http请求
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task ExecuteAsync(string url, HttpMethod method, string requestBody, Dictionary dicHeaders, int timeoutSecond = 180)
+ {
+ var client = BuildHttpClient(null, timeoutSecond);
+ var request = GenerateHttpRequestMessage(url, requestBody, method, dicHeaders);
+ var response = await client.SendAsync(request);
+ var responseContent = await response.Content.ReadAsStringAsync();
+ if (response.IsSuccessStatusCode)
+ {
+ var t = JsonSerializer.Deserialize(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
+
+ return t;
+ }
+
+ throw new WebHttpException(response.StatusCode.ToString(), responseContent);
+ }
+
+
+ ///
+ /// 设置HttpRequestMessage
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private HttpRequestMessage GenerateHttpRequestMessage(string url, string requestBody, HttpMethod method, Dictionary dicHeaders)
+ {
+ var request = new HttpRequestMessage(method, url);
+ if (!string.IsNullOrEmpty(requestBody)) request.Content = new StringContent(requestBody);
+ if (dicHeaders != null)
+ foreach (var headerItme in dicHeaders)
+ request.Headers.Add(headerItme.Key, headerItme.Value);
+ return request;
+ }
+
+ ///
+ /// 设置请求内容
+ ///
+ ///
+ ///
+ ///
+ private StringContent GenerateStringContent(string requestBody, Dictionary dicHeaders)
+ {
+ var content = new StringContent(requestBody);
+ if (dicHeaders != null)
+ content.Headers.Remove("content-type");
+ foreach (var headerItme in dicHeaders)
+ content.Headers.Add(headerItme.Key, headerItme.Value);
+ return content;
+ }
+
+
+ ///
+ /// 设置请求头和超时时间:返回client
+ ///
+ ///
+ ///
+ ///
+ private HttpClient BuildHttpClient(Dictionary dicDefaultHeaders, int? timeoutSecond)
+ {
+ var httpClient = _clientFactory.CreateClient("ops_client");
+ httpClient.DefaultRequestHeaders.Clear(); //为了使客户端不受最后一个请求的影响,它需要清除DefaultRequestHeaders
+ httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
+ if (dicDefaultHeaders != null)
+ foreach (var headItem in dicDefaultHeaders)
+ if (!httpClient.DefaultRequestHeaders.Contains(headItem.Key))
+ httpClient.DefaultRequestHeaders.Add(headItem.Key, headItem.Value);
+
+ if (timeoutSecond != null) httpClient.Timeout = TimeSpan.FromSeconds(timeoutSecond.Value);
+ return httpClient;
+ }
+ }
+}
diff --git a/src/WMS.Web.Domain/Services/Public/LoginService.cs b/src/WMS.Web.Domain/Services/Public/LoginService.cs
new file mode 100644
index 00000000..d6c62a0b
--- /dev/null
+++ b/src/WMS.Web.Domain/Services/Public/LoginService.cs
@@ -0,0 +1,387 @@
+using AutoMapper;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Json;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WMS.Web.Core.Dto.Login;
+using WMS.Web.Core.Dto.Login.Temp;
+using WMS.Web.Core.Help;
+using WMS.Web.Core.Internal.Results;
+using WMS.Web.Core.Internal.Security;
+using WMS.Web.Domain.IService.Public;
+using WMS.Web.Domain.Options;
+using WMS.Web.Domain.Values.Single;
+
+namespace WMS.Web.Domain.Services.Public
+{
+ public class LoginService : ILoginService
+ {
+ private IMapper _mapper;
+ private SoaOptions _soaOptions;
+ private ILogger _logger;
+ private HttpClientHelp _httpClientHelp;
+ private readonly ISingleDataService _singleDataService;
+ private readonly RedisClientService _redisClientService;
+ public LoginService(
+ IMapper mapper,
+ IOptions soaOptions,
+ ILogger logger,
+ HttpClientHelp httpClientHelp,
+ ISingleDataService singleDataService,
+ RedisClientService redisClientService)
+ {
+ this._redisClientService = redisClientService;
+ this._singleDataService = singleDataService;
+ this._soaOptions = soaOptions?.Value;
+ this._mapper = mapper;
+ this._logger = logger;
+ this._httpClientHelp = httpClientHelp;
+ }
+
+ ///
+ /// 创建token
+ ///
+ ///
+ ///
+ ///
+ ///
+ private async Task CreateToken(UserInfoDto data, LoginTempDto tempDto, string NewToken)
+ {
+ return await Task.Run(() =>
+ {
+
+ DateTime expires_time = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)).AddSeconds(tempDto.expires_in);
+ AccessTokenDto accessToken = new AccessTokenDto()
+ {
+ Token = NewToken,
+ PhpToken = tempDto.access_token,
+ RefreshToken = tempDto.refresh_token,
+ Expired = expires_time
+ };
+ return accessToken;
+ });
+ }
+
+ ///
+ /// 得到单点用户信息
+ ///
+ ///
+ ///
+ public async Task> GetUserInfoAsync(string code)
+ {
+ JsonObject reqData = new JsonObject();
+ reqData.Add("app_id", _soaOptions.AppId);
+ reqData.Add("app_secret", _soaOptions.AppSecret);
+ reqData.Add("code", code);
+ //这个是登录的时候给前端验证的token,以及传给php单点那边的一个session值,用于单点退出时,通知ops退出
+ string NewToken = Guid.NewGuid().ToString("N");
+ try
+ {
+ string result = _httpClientHelp.PostHttp(_soaOptions.Url + "/uc/authorize/access_token", reqData, true, NewToken);
+ var jObject = JsonObject.Parse(result);
+
+ LoginInDto r = new LoginInDto();
+ r.UserInfo = new UserInfoDto();
+ r.TokenInfo = new AccessTokenDto();
+ var login_result = jObject["errno"] == 0 ? "成功" : "失败";
+ _logger.LogInformation($"登录信息:单点->{login_result}");
+
+ if (jObject["errno"] == 0)
+ {
+ string datajson = jObject["data"].ToString();
+ var _loginDto = JsonConvert.DeserializeObject(datajson);
+
+ #region 解码
+ string enptStr = _loginDto.encryptedData;
+ List enptlist = enptStr.Trim().Split(',').ToList();
+ string str = RSA.DecryptSection(_soaOptions.PrivateKey, enptlist);
+ var entity = JsonConvert.DeserializeObject(str);
+ #endregion
+
+ //映射登录信息
+ r.UserInfo = _mapper.Map(entity);
+ _logger.LogInformation($"登录信息:用户ID->{entity.uc_id}");
+
+ //HTTP请求获取登录信息:人员,客户,供应商,公司
+ var loginRequest = new LoginSingleRequest()
+ {
+ UserId = entity.uc_id,
+ SupplierId = entity.supplier_id ?? 0,
+ CustomerId = entity.customer_id ?? 0
+ };
+ var loginResponse_result = await _singleDataService.GetSingleDataNoCache, LoginSingleRequest, SingleLoginAction>
+ (loginRequest, SingleLoginAction.All, type: SingleControllerType.Login);
+
+ //绑定返回对象的登录信息
+ var staffName = "Null";
+ var token = await CreateToken(r.UserInfo, _loginDto, NewToken);
+ r.TokenInfo = token;
+ if (loginResponse_result.Success && loginResponse_result.Data != null)
+ {
+ var loginResponse = loginResponse_result.Data;
+ if (loginResponse.Supplier != null)
+ r.UserInfo.SupplierName = loginResponse.Supplier.Name;
+ if (loginResponse.Customer != null)
+ r.UserInfo.CustomerName = loginResponse.Customer.Name;
+ if (loginResponse.Staff != null)
+ {
+ r.UserInfo.StaffId = loginResponse.Staff.Id;
+ staffName = loginResponse.Staff.Name;
+ }
+ if (loginResponse.Company != null)
+ r.UserInfo.CompanyName = loginResponse.Company.Name;
+ }
+ r.UserInfo.UcId = entity.uc_id;
+ r.UserInfo.SeesionId = _loginDto?.uc_sessid;
+ r.UserInfo.CompanyId = entity.company_id.Value;
+ r.UserInfo.Identity = entity.identity;
+ r.UserInfo.OrgId = entity.org_id;
+ r.UserInfo.CustomerId = entity.customer_id;
+ r.UserInfo.SupplierId = entity.supplier_id;
+ r.SignedIn = true;
+ _logger.LogInformation($"登录信息:用户人员信息->{staffName}({r.UserInfo.StaffId}),公司名称->{r.UserInfo.CompanyName}");
+
+ //登录后缓存登录的用户信息和token信息
+ var loginInfo = new LoginInDto();
+ loginInfo.UserInfo = r.UserInfo;
+ loginInfo.TokenInfo = token;
+
+ var ops_login_time = token.Expired.AddDays(1) - DateTime.Now;//用于正式
+ _redisClientService.SetStringKey($"ops_login_{token.Token}", loginInfo, ops_login_time);
+
+ //登录成功移出对应的用户token黑名单:应为新的token产生,移除登录的信息
+ string blacktoken = _redisClientService.GetStringKey($"ops_black_token_{r.UserInfo.UcId}");
+ if (!string.IsNullOrEmpty(blacktoken))
+ {
+ this.RemoveLoginInfo(blacktoken);
+ _redisClientService.RemoveStringKey($"ops_black_token_{r.UserInfo.UcId}");
+ }
+ if (r == null || r.UserInfo == null || r.TokenInfo == null)
+ return Result.ReFailure("授权失败,请重新登录", 401);
+ return Result.ReSuccess(r);
+ }
+ else
+ {
+ var errno_text = "登陆失败:" + jObject["errmsg"];
+ r.SignedIn = false;
+ string datajson_sessid = jObject["data"]["uc_sessid"];
+ //调用单点的退出接口
+ result = _httpClientHelp.GetHttp(_soaOptions.Url + "/uc/authorize/signin_out", true, cookieValue: datajson_sessid);
+ jObject = JsonObject.Parse(result);
+ if (jObject["errno"] == 0)
+ {
+ _logger.LogInformation("用户信息登录:" + errno_text);
+ return Result.ReFailure("拒绝用户证书试图访问此web站点,请与站点管理员联系以建立用户证书权限", 403);
+ }
+ else
+ {
+ return Result.ReFailure(jObject["errmsg"], jObject["errno"]);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ return Result.ReFailure("授权失败,请重新登录", 401);
+ }
+ }
+
+ ///
+ /// 登录退出
+ ///
+ ///
+ public async Task LoginOutAsync(LoginOutDto dto)
+ {
+ _logger.LogInformation("dto_SessionId:" + dto.SessionId);
+ //2.请求PHP单点登出接口
+ JsonObject reqData = new JsonObject();
+ reqData.Add("app_id", _soaOptions.AppId);
+ reqData.Add("app_secret", _soaOptions.AppSecret);
+ reqData.Add("access_token", dto.AccessToken);
+ string result = _httpClientHelp.PostHttp(_soaOptions.Url + "/uc/authorize/signin_out", reqData, true, dto.SessionId);
+ _logger.LogInformation("退出登录返回:" + result);
+ var jObject = JsonObject.Parse(result);
+ if (jObject["errno"] == 0)
+ {
+ //设置本地token的缓存:为黑名单的token做存储
+ await CacheOutToken(dto);
+ return Result.ReSuccess();
+ }
+ else
+ {
+ return Result.ReFailure(jObject["errmsg"], jObject["errno"]);
+ }
+ }
+
+ ///
+ /// 刷新token
+ ///
+ ///
+ public async Task> RefreshToken(string Token, string RefreshToken)
+ {
+ _logger.LogInformation("RefreshToken:" + RefreshToken);
+ //1.根据旧token 找到登录对象
+ var loginInfo = _redisClientService.GetStringKey($"ops_login_{Token}");
+ //2.请求PHP单点登出接口
+ JsonObject reqData = new JsonObject();
+ reqData.Add("app_id", _soaOptions.AppId);
+ reqData.Add("app_secret", _soaOptions.AppSecret);
+ reqData.Add("refresh_token", RefreshToken);
+ string result = _httpClientHelp.PostHttp(_soaOptions.Url + "/uc/authorize/refresh_token", reqData, true, Token);
+ var jObject = JsonObject.Parse(result);
+
+ LoginInDto r = new LoginInDto();
+ r.UserInfo = new UserInfoDto();
+ r.TokenInfo = new AccessTokenDto();
+
+ if (jObject["errno"] == 0)
+ {
+ string datajson = jObject["data"].ToString();
+ var _loginDto = JsonConvert.DeserializeObject(datajson);
+ r.UserInfo = loginInfo.UserInfo;
+ r.SignedIn = true;
+ var token = await CreateToken(loginInfo.UserInfo, _loginDto, Token);
+ r.TokenInfo = token;
+ loginInfo.TokenInfo = token;
+
+ var ops_login_time = token.Expired.AddDays(1) - DateTime.Now;//用于正式
+ _redisClientService.SetStringKey($"ops_login_{token.Token}", loginInfo, ops_login_time);
+ return Result.ReSuccess(r);
+ }
+ else
+ {
+ //失败了1:就把登录的token清除 2: ucid添加到黑名单
+ var time = new TimeSpan(r.TokenInfo.Expired.Day, r.TokenInfo.Expired.Hour, r.TokenInfo.Expired.Minute, r.TokenInfo.Expired.Second, r.TokenInfo.Expired.Millisecond);
+ _redisClientService.SetStringKey($"ops_black_token_{r.UserInfo.UcId}", r.TokenInfo.Token, time);
+ this.RemoveLoginInfo(r.TokenInfo.Token);
+ r.SignedIn = false;
+ return Result.ReFailure(jObject["errmsg"], jObject["errno"]);
+ }
+ }
+
+ ///
+ /// 单点退出通知token失效
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task LoginOutSingleAsync(int ucid, string token, int expires_in)
+ {
+ await Task.Run(() =>
+ {
+ var cache_token = _redisClientService.GetStringKey($"ops_black_token_{ucid}");
+ if (string.IsNullOrEmpty(cache_token))
+ {
+ DateTime expires_time = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)).AddSeconds(expires_in);
+ var time = new TimeSpan(expires_time.Day, expires_time.Hour, expires_time.Minute, expires_time.Second, expires_time.Millisecond);
+ _redisClientService.SetStringKey($"ops_black_token_{ucid}", token, time);
+ this.RemoveLoginInfo(token);
+ }
+ });
+ }
+
+ ///
+ /// 单点退出通知token失效
+ ///
+ /// 这个是单点传过来的SeesionId
+ ///
+ public async Task LoginOutSingleAsync(string SeesionId)
+ {
+ var logininfo = _redisClientService.GetStringKey($"ops_login_{SeesionId}");
+ await Task.Run(() =>
+ {
+ if (logininfo != null)
+ {
+ var cache_token = _redisClientService.GetStringKey($"ops_black_token_{logininfo.UserInfo.UcId}");
+ if (string.IsNullOrEmpty(cache_token))
+ {
+ DateTime expires_time = logininfo.TokenInfo.Expired;
+ var time = new TimeSpan(expires_time.Day, expires_time.Hour, expires_time.Minute, expires_time.Second, expires_time.Millisecond);
+ _redisClientService.SetStringKey($"ops_black_token_{logininfo.UserInfo.UcId}", logininfo.TokenInfo.Token, time);
+ this.RemoveLoginInfo(logininfo.TokenInfo.Token);
+ }
+ }
+ });
+ }
+
+ ///
+ /// 缓存退出的token
+ ///
+ ///
+ ///
+ private async Task CacheOutToken(LoginOutDto dto)
+ {
+ await Task.Run(() =>
+ {
+ if (!string.IsNullOrEmpty(dto.AccessToken))
+ {
+ var time = new TimeSpan(dto.ExpiresIn.Day, dto.ExpiresIn.Hour, dto.ExpiresIn.Minute, dto.ExpiresIn.Second, dto.ExpiresIn.Millisecond);
+ _redisClientService.SetStringKey($"ops_black_token_{dto.UcId}", dto.AccessToken, time);
+ this.RemoveLoginInfo(dto.Token);
+
+ }
+ });
+ }
+
+ ///
+ /// 获取登录后的信息
+ ///
+ ///
+ ///
+ public LoginInDto GetLoginInfo(string authorization)
+ {
+ string token = string.Empty;
+ if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
+ {
+ token = authorization.Substring("Bearer ".Length).Trim();
+ }
+ var logininfo = _redisClientService.GetStringKey($"ops_login_{token}");
+ return logininfo;
+ }
+
+ ///
+ /// 移除登录后的用户信息
+ ///
+ ///
+ private void RemoveLoginInfo(string token)
+ {
+ if (!string.IsNullOrEmpty(token))
+ {
+ var info = _redisClientService.GetStringKey($"ops_login_{token}");
+ if (info != null)
+ {
+ _redisClientService.RemoveStringKey($"ops_login_{token}");
+ }
+ }
+ }
+
+ ///
+ /// 单点-在线接口
+ ///
+ ///
+ ///
+ public async Task Online(string sessionId)
+ {
+ var request = new { PHPSESSID = sessionId };
+ string result = _httpClientHelp.PostHttpNoData(_soaOptions.Url + "/uc/user/online.html?app_id=" + _soaOptions.AppId, sessionId);
+ return Result.ReSuccess();
+ }
+
+ ///
+ /// 单点-下线接口
+ ///
+ ///
+ ///
+ public async Task Offline(string sessionId)
+ {
+ var request = new { PHPSESSID = sessionId };
+ string result = _httpClientHelp.PostHttpNoData(_soaOptions.Url + "/uc/user/offline.html?app_id=" + _soaOptions.AppId, sessionId);
+ return Result.ReSuccess();
+ }
+ }
+}
diff --git a/src/WMS.Web.Domain/Services/Public/RedisClientService.cs b/src/WMS.Web.Domain/Services/Public/RedisClientService.cs
new file mode 100644
index 00000000..a631ed9d
--- /dev/null
+++ b/src/WMS.Web.Domain/Services/Public/RedisClientService.cs
@@ -0,0 +1,93 @@
+using Microsoft.Extensions.Options;
+using Newtonsoft.Json;
+using StackExchange.Redis;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using WMS.Web.Domain.Options;
+
+namespace WMS.Web.Domain.Services.Public
+{
+ public class RedisClientService
+ {
+ private static readonly object Locker = new object();
+
+ private ConnectionMultiplexer redisMultiplexer;
+ IDatabase db = null;
+ private readonly AppOptions _options;
+ public RedisClientService(IOptions options)
+ {
+ _options = options?.Value;
+ redisMultiplexer = ConnectionMultiplexer.Connect(_options.RedisConnectionString);
+ db = redisMultiplexer.GetDatabase();
+ }
+
+ #region String
+ ///
+ /// 保存单个key value
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool SetStringKey(string key, string value, TimeSpan? expiry = default(TimeSpan?))
+ {
+ var lastKey = _options.RedisDirectory + ":" + key;
+ return db.StringSet(lastKey, value, expiry);
+ }
+
+ ///
+ /// 获取单个key的值
+ ///
+ public RedisValue GetStringKey(string key)
+ {
+ var lastKey = _options.RedisDirectory + ":" + key;
+ return db.StringGet(lastKey);
+ }
+
+ ///
+ /// 移除redis
+ ///
+ ///
+ ///
+ public bool RemoveStringKey(string key)
+ {
+ var lastKey = _options.RedisDirectory + ":" + key;
+ return db.KeyDelete(lastKey);
+ }
+ ///
+ /// 获取一个key的对象
+ ///
+ public T GetStringKey(string key)
+ {
+ if (db == null)
+ {
+ return default;
+ }
+ var lastKey = _options.RedisDirectory + ":" + key;
+ var value = db.StringGet(lastKey);
+ if (value.IsNullOrEmpty)
+ {
+ return default;
+ }
+ return JsonConvert.DeserializeObject(value);
+ }
+
+ ///
+ /// 保存一个对象
+ ///
+ ///
+ public bool SetStringKey(string key, T obj, TimeSpan? expiry = default(TimeSpan?))
+ {
+ if (db == null)
+ {
+ return false;
+ }
+ var lastKey = _options.RedisDirectory + ":" + key;
+ string json = JsonConvert.SerializeObject(obj);
+ return db.StringSet(lastKey, json, expiry);
+ }
+
+ #endregion
+ }
+}
diff --git a/src/WMS.Web.Domain/Services/Public/SingleDataService.cs b/src/WMS.Web.Domain/Services/Public/SingleDataService.cs
new file mode 100644
index 00000000..6740cfd6
--- /dev/null
+++ b/src/WMS.Web.Domain/Services/Public/SingleDataService.cs
@@ -0,0 +1,473 @@
+using Microsoft.Extensions.Caching.Memory;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.IdentityModel.Tokens.Jwt;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+using WMS.Web.Core.Dto.SingleData;
+using WMS.Web.Core.Internal.Results;
+using WMS.Web.Domain.IService.Public;
+using WMS.Web.Domain.Options;
+using WMS.Web.Domain.Values.Single;
+
+namespace WMS.Web.Domain.Services.Public
+{
+ ///
+ /// 单点数据返回服务
+ ///
+ public class SingleDataService : ISingleDataService
+ {
+ private readonly AppOptions _options;
+ private readonly IHttpClientService _httpClientService;
+ private readonly ILogger _logger;
+ private readonly IMemoryCache _memoryCache;
+ private int hours = 10;//过期时间 默认10小时
+
+ public SingleDataService(IOptions options, IHttpClientService httpClientService, ILogger logger, IMemoryCache memoryCache)
+ {
+ this._memoryCache = memoryCache;
+ this._options = options?.Value;
+ this._httpClientService = httpClientService;
+ this._logger = logger;
+ }
+
+ ///
+ /// 获取单点数据:根据接口方法名和公司ID
+ /// 后端列表查询统一使用
+ ///
+ ///
+ ///
+ ///
+ public string GetSingleData(SingleAction action, int companyId, int id)
+ {
+ try
+ {
+ if (id == 0)
+ return "";
+
+ var cache_key = action + "_" + companyId + "_IdGetName";
+ var dic = _memoryCache.Get>(cache_key);
+ if (dic == null || dic.Count <= 0 || !dic.ContainsKey(id))
+ {
+ if (dic != null)
+ {
+
+ string no_data_key = cache_key + "_NoData";
+ var cache_id = _memoryCache.Get(no_data_key);
+ if (cache_id == true) return "";
+ //未找到数据请求
+ if (!dic.ContainsKey(id))
+ {
+ _memoryCache.Set(no_data_key, true, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(30)));
+ }
+ }
+ var list = SingleDataPost(action, companyId, cache_key);
+ if (list.Count() <= 0) return "";
+ dic = list.ToDictionary(s => s.Id, s => s.Name);
+ _memoryCache.Set(cache_key, dic, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromHours(hours)));
+ }
+ if (!dic.ContainsKey(id)) return "";
+ return dic[id];
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"请求单点数据错误:Action->{action.ToString()},CompanyeId->{companyId},Id->{id},(错误原因)=>{ex.Message}");
+ return "";
+ }
+ }
+
+ ///
+ /// 获取单点数据:根据接口方法名和公司ID
+ /// 后端列表查询统一使用
+ ///
+ ///
+ ///
+ ///
+ public decimal GetSingleDataNumber(SingleAction action, int companyId, int id)
+ {
+ try
+ {
+ if (id == 0)
+ return 0;
+
+ var cache_key = action + "_" + companyId + "_IdGetNumber";
+ var dic = _memoryCache.Get>(cache_key);
+ if (dic == null || dic.Count <= 0 || !dic.ContainsKey(id))
+ {
+ if (dic != null)
+ {
+ string no_data_key = cache_key + "_NoData";
+ var cache_id = _memoryCache.Get(no_data_key);
+ if (cache_id == true) return 0;
+ //未找到数据请求
+ if (!dic.ContainsKey(id))
+ {
+ _memoryCache.Set(no_data_key, true, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(30)));
+ }
+ }
+
+ var list = SingleDataPost(action, companyId, cache_key);
+ if (list.Count() <= 0) return 0;
+
+ dic = list.ToDictionary(s => s.Id, s => s.Number);
+ _memoryCache.Set(cache_key, dic, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromHours(hours)));
+ }
+
+ if (!dic.ContainsKey(id)) return 0;
+ return dic[id];
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
+ return 0;
+ }
+ }
+
+ ///
+ /// 获取单点数据:根据接口方法名和公司ID
+ /// 后端列表查询统一使用
+ ///
+ ///
+ ///
+ ///
+ public string GetSingleDataCode(SingleAction action, int companyId, int id)
+ {
+ try
+ {
+ if (id == 0)
+ return "";
+
+ var cache_key = action + "_" + companyId + "_IdGetCode";
+ var dic = _memoryCache.Get>(cache_key);
+ if (dic == null || dic.Count <= 0 || !dic.ContainsKey(id))
+ {
+ if (dic != null)
+ {
+ string no_data_key = cache_key + "_NoData";
+ var cache_id = _memoryCache.Get(no_data_key);
+ if (cache_id == true) return "";
+ //未找到数据请求
+ if (!dic.ContainsKey(id))
+ {
+ _memoryCache.Set(no_data_key, true, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(30)));
+ }
+ }
+
+ var list = SingleDataPost(action, companyId, cache_key);
+ if (list.Count() <= 0) return "";
+
+ dic = list.ToDictionary(s => s.Id, s => s.Code);
+ _memoryCache.Set(cache_key, dic, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromHours(hours)));
+ }
+
+ if (!dic.ContainsKey(id)) return "";
+ return dic[id];
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
+ return "";
+ }
+ }
+
+ ///
+ /// 根据名字模糊匹配
+ ///
+ ///
+ ///
+ ///
+ ///
+ public List GetIdsBySingleName(SingleAction action, int companyId, string name)
+ {
+ try
+ {
+ var cache_key = action + "_" + companyId + "_NameGetIds";
+ var dic = _memoryCache.Get>(cache_key);
+ if (dic == null || dic.Count <= 0)
+ {
+ var list = SingleDataPost(action, companyId, cache_key);
+ if (list.Count() <= 0) return new List();
+
+ dic = list.ToDictionary(s => s.Id, s => s.Name);
+ _memoryCache.Set(cache_key, dic, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromHours(hours)));
+ }
+ var res = from d in dic where d.Value.Contains(name) select d;
+ return res.Select(s => s.Key).ToList();
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
+ return new List();
+ }
+ }
+
+ ///
+ /// 获取单点数据:根据接口方法名和公司ID
+ /// 后端列表查询统一使用
+ ///
+ ///
+ ///
+ ///
+ public string GetSingleData(SingleAction action, int companyId, string code)
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(code))
+ return "";
+
+ var cache_key = action + "_" + companyId + "_CodeGetName";
+ var dic = _memoryCache.Get>(cache_key);
+ //仓库和客户仓库 不能为空了就重新请求 应为 这里是从仓库和客户仓库取值 有一个必然取不到
+ if (dic == null || dic.Count <= 0)
+ {
+ if (dic != null)
+ {
+ string no_data_key = cache_key + "_NoData";
+ var cache_id = _memoryCache.Get(no_data_key);
+ if (cache_id == true) return "";
+ //未找到数据请求
+ if (!dic.ContainsKey(code))
+ {
+ _memoryCache.Set(no_data_key, true, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(30)));
+ }
+ }
+
+ var list = SingleDataPost(action, companyId, cache_key);
+ if (list.Count() <= 0) return "";
+
+ dic = list.ToDictionary(s => s.Code, s => s.Name);
+ _memoryCache.Set(cache_key, dic, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromHours(hours)));
+ }
+
+ if (!dic.ContainsKey(code)) return "";
+ return dic[code];
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
+ return "";
+ }
+ }
+
+ ///
+ /// 获取单点数据集合:泛型-同步
+ ///
+ ///
+ ///
+ ///
+ ///
+ public List GetSingleData(SingleAction action, int companyId) where T : class
+ {
+ try
+ {
+ var cache_key = action + "_list_" + companyId;
+ var list = _memoryCache.Get>(cache_key);
+ if (list == null || list.Count <= 0)
+ list = SingleDataPost(action, companyId, cache_key);
+
+ return list;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
+ return null;
+ }
+ }
+
+ ///
+ /// 获取单点数据集合:泛型-异步
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task> GetSingleDataAsync(SingleAction action, int companyId) where T : class
+ {
+ try
+ {
+ var cache_key = action + "_list_" + companyId;
+ var list = _memoryCache.Get>(cache_key);
+ if (list == null || list.Count <= 0)
+ list = await SingleDataPostAsync(action, companyId, cache_key);
+
+ return list;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
+ return null;
+ }
+ }
+
+ ///
+ /// 获取单点数据集合:泛型-异步-无缓存
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task> GetSingleDataNoCacheAsync(SingleAction action, int companyId) where T : class
+ {
+ try
+ {
+ var list = await SingleDataPostAsync(action, companyId, "");
+ return list;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
+ return null;
+ }
+ }
+
+ ///
+ /// 单点数据:可对接全部接口
+ ///
+ /// 返回对象
+ /// 请求对象
+ /// 方法名称
+ /// 请求对象
+ /// 方法名称
+ /// 控制器名称
+ ///
+ public async Task GetSingleData(X dto, Y action, SingleControllerType type = SingleControllerType.Single) where T : class
+ {
+ try
+ {
+ var para = JsonExtensions.SerializeToJson(dto);
+ var cache_key = action + "_list_" + type + "_" + para;
+ var list = _memoryCache.Get(cache_key);
+ if (list == null)
+ {
+ var url = _options.SingleBaseUrl + "/" + type.ToString() + "/" + action.ToString();
+ var result = await _httpClientService.PostAsync(url, para);
+ _memoryCache.Set(cache_key, result, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromHours(hours)));
+ }
+ return _memoryCache.Get(cache_key);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
+ return default(T);
+ }
+ }
+
+ ///
+ /// 单点数据:可对接全部接口
+ ///
+ /// 返回对象
+ /// 请求对象
+ /// 方法名称
+ /// 请求对象
+ /// 方法名称
+ /// 控制器名称
+ ///
+ public async Task GetSingleDataNoCache(X dto, Y action, SingleControllerType type = SingleControllerType.Single) where T : class
+ {
+ try
+ {
+ var para = JsonExtensions.SerializeToJson(dto);
+ var url = _options.SingleBaseUrl + "/" + type.ToString() + "/" + action.ToString();
+ var result = await _httpClientService.PostAsync(url, para);
+ return result;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
+ return default(T);
+ }
+ }
+
+ ///
+ /// 获取单点数据:配置项接口
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task GetSysConfigData(X dto, SysConfigAction action)
+ {
+ try
+ {
+ var para = JsonExtensions.SerializeToJson(dto);
+ var url = _options.SingleBaseUrl + "/" + SingleControllerType.SysConfig.ToString() + "/" + action.ToString();
+ var result = await _httpClientService.PostAsync(url, para);
+ return result;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
+ return default(T);
+ }
+ }
+
+
+ #region 私有方法
+
+ ///
+ /// 请求单点服务接口:同步
+ ///
+ ///
+ ///
+ ///
+ ///
+ private List SingleDataPost(SingleAction action, int companyId, string cache_key)
+ {
+ var dto = new SingleDataRequest(companyId);
+ //var para = JsonExtensions.SerializeToJson(dto);
+ var para = JsonSerializer.Serialize(dto);
+ var url = _options.SingleBaseUrl + "/" + SingleControllerType.Single.ToString() + "/" + action.ToString();
+ var result = _httpClientService.PostAsync>(url, para).GetAwaiter().GetResult();
+ if (!result.Success)
+ return new List();
+ return result.Data.ToList();
+ }
+
+ ///
+ /// 请求单点服务接口:异步
+ ///
+ ///
+ ///
+ ///
+ ///
+ private async Task> SingleDataPostAsync(SingleAction action, int companyId, string cache_key)
+ {
+ var dto = new SingleDataRequest(companyId);
+ var para = JsonSerializer.Serialize(dto);
+ var url = _options.SingleBaseUrl + "/" + SingleControllerType.Single.ToString() + "/" + action.ToString();
+ var result = await _httpClientService.PostAsync>(url, para);
+ if (result.Success)
+ {
+ if (!string.IsNullOrEmpty(cache_key))
+ {
+ _memoryCache.Set(cache_key, result.Data.ToList(), new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromHours(hours)));
+ return _memoryCache.Get>(cache_key);
+ }
+ return result.Data.ToList();
+ }
+ return null;
+ }
+
+
+
+ #endregion
+ ///
+ /// 获取客户仓库
+ ///
+ ///
+ ///
+ ///
+ public string GetCustomerStock(int companyId, string customerStockCode)
+ {
+ return string.IsNullOrEmpty(this.GetSingleData(SingleAction.CustomerStocks, companyId, customerStockCode)) ?
+ this.GetSingleData(SingleAction.Stocks, companyId, customerStockCode) :
+ this.GetSingleData(SingleAction.CustomerStocks, companyId, customerStockCode);
+ }
+
+ }
+}
diff --git a/src/WMS.Web.Domain/Values/ResultCodes.cs b/src/WMS.Web.Domain/Values/ResultCodes.cs
new file mode 100644
index 00000000..95de178c
--- /dev/null
+++ b/src/WMS.Web.Domain/Values/ResultCodes.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WMS.Web.Domain.Values
+{
+ ///
+ /// 错误提示信息
+ ///
+ public partial class ResultCodes
+ {
+ }
+}
diff --git a/src/WMS.Web.Domain/Values/Single/SingleAction.cs b/src/WMS.Web.Domain/Values/Single/SingleAction.cs
new file mode 100644
index 00000000..9b7e3c14
--- /dev/null
+++ b/src/WMS.Web.Domain/Values/Single/SingleAction.cs
@@ -0,0 +1,105 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using WMS.Web.Core;
+
+namespace WMS.Web.Domain.Values.Single
+{
+ ///
+ /// 对接单点的接口方法-枚举
+ ///
+ public enum SingleAction
+ {
+ ///
+ /// 组织集合
+ ///
+ [EnumRemark("组织")]
+ Orgs = 1,
+ ///
+ /// 用户集合
+ ///
+ [EnumRemark("用户")]
+ Users = 2,
+ ///
+ /// 人员集合
+ ///
+ [EnumRemark("人员")]
+ Staffs = 3,
+ ///
+ /// 供应商集合
+ ///
+ [EnumRemark("供应商")]
+ Suppliers = 4,
+ ///
+ /// 客户集合
+ ///
+ [EnumRemark("客户")]
+ Customers = 5,
+ ///
+ /// 收款条件集合
+ ///
+ [EnumRemark("收款条件")]
+ CollectionTerms = 6,
+ ///
+ /// 付款条件集合
+ ///
+ [EnumRemark("付款条件")]
+ PaymentTerms = 7,
+ ///
+ /// 结算方式集合
+ ///
+ [EnumRemark("结算方式")]
+ SettlementMethods = 8,
+ ///
+ /// 结算币别集合
+ ///
+ [EnumRemark("结算币别")]
+ SettlementCurrencys = 9,
+ ///
+ /// 税率集合
+ ///
+ [EnumRemark("税率")]
+ TaxRates = 10,
+ ///
+ /// 汇率集合
+ ///
+ [EnumRemark("汇率")]
+ ExchangeRates = 11,
+ ///
+ /// 仓库集合
+ ///
+ [EnumRemark("仓库")]
+ Stocks = 12,
+ ///
+ /// 单位集合
+ ///
+ [EnumRemark("单位")]
+ Units = 13,
+ ///
+ /// 客户仓库集合
+ ///
+ [EnumRemark("客户仓库")]
+ CustomerStocks = 14,
+ ///
+ /// 部门集合
+ ///
+ [EnumRemark("部门")]
+ Depts = 15,
+ ///
+ /// 仓库211集合
+ ///
+ [EnumRemark("仓库211")]
+ StocksWith211 = 16,
+ ///
+ /// 供应商默认联系人集合
+ ///
+ [EnumRemark("供应商默认联系人")]
+ SuppliersContacts = 17,
+ ///
+ /// 菜单集合
+ ///
+ [EnumRemark("菜单")]
+ Menus = 18,
+
+ }
+}
diff --git a/src/WMS.Web.Domain/Values/Single/SingleControllerType.cs b/src/WMS.Web.Domain/Values/Single/SingleControllerType.cs
new file mode 100644
index 00000000..7561f8aa
--- /dev/null
+++ b/src/WMS.Web.Domain/Values/Single/SingleControllerType.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WMS.Web.Domain.Values.Single
+{
+ ///
+ /// 单点-控制器枚举
+ ///
+ public enum SingleControllerType
+ {
+ ///
+ /// 单点OPS列表数据-控制器
+ ///
+ Single = 1,
+ ///
+ /// 单点配置项数据-控制器
+ ///
+ SysConfig = 2,
+ ///
+ /// 单点登录项数据-控制器
+ ///
+ Login = 3,
+ ///
+ /// 单点公共接口数据-控制器
+ ///
+ Public = 4
+ }
+}
diff --git a/src/WMS.Web.Domain/Values/Single/SingleLoginAction.cs b/src/WMS.Web.Domain/Values/Single/SingleLoginAction.cs
new file mode 100644
index 00000000..2f496ccb
--- /dev/null
+++ b/src/WMS.Web.Domain/Values/Single/SingleLoginAction.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WMS.Web.Domain.Values.Single
+{
+ ///
+ /// 单点数据接口-登录要使用的数据接口-方法枚举
+ ///
+ public enum SingleLoginAction
+ {
+ ///
+ /// 菜单
+ ///
+ Menus = 1,
+ ///
+ /// 人员
+ ///
+ Staff = 2,
+ ///
+ /// 公司
+ ///
+ Company = 3,
+ ///
+ /// 供应商
+ ///
+ Supplier = 4,
+ ///
+ /// 客户
+ ///
+ Customer = 5,
+ ///
+ /// 全部信息
+ ///
+ All = 6,
+ ///
+ /// 公司信息
+ ///
+ CompanyInfo = 7,
+
+ }
+}
diff --git a/src/WMS.Web.Domain/Values/Single/SysConfigAction.cs b/src/WMS.Web.Domain/Values/Single/SysConfigAction.cs
new file mode 100644
index 00000000..569ba8de
--- /dev/null
+++ b/src/WMS.Web.Domain/Values/Single/SysConfigAction.cs
@@ -0,0 +1,186 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WMS.Web.Domain.Values.Single
+{
+ ///
+ /// 单点数据:配置项和公共接口的方法枚举值
+ ///
+ public enum SysConfigAction
+ {
+ ///
+ /// 供应商-根据名称和公司
+ ///
+ GetSupplierByNameAndCompany = 1,
+ ///
+ /// 组织-根据公司
+ ///
+ GetOrgByCompany = 2,
+ ///
+ /// 部门-根据组织和公司
+ ///
+ GetDeptByOrgAndCompany = 3,
+ ///
+ /// 人员-根据公司
+ ///
+ GetStaffByCompany = 4,
+ ///
+ /// 人员-根据部门和公司
+ ///
+ GetStaffByDeptAndCompany = 5,
+ ///
+ /// 人员-根据组织和公司
+ ///
+ GetStaffByOrgAndCompany = 6,
+ ///
+ /// 客户-根据公司
+ ///
+ GetCustomerByCompany = 7,
+ ///
+ /// 客户-根据客户和组织和公司
+ ///
+ GetCustomerByCustomerAndOrgAndCompany = 8,
+ ///
+ /// 客户信息-根据客户和组织和公司
+ ///
+ GetCustomerInfoByCustomerAndOrgAndCompany = 9,
+ ///
+ /// 收款条件-根据公司
+ ///
+ GetCollectionTermsByCompany = 10,
+ ///
+ /// 付款条件-根据公司
+ ///
+ GetPaymentTermByCompany = 11,
+ ///
+ /// 结算方式-根据公司
+ ///
+ GetSettlementMethodByCompany = 12,
+ ///
+ /// 结算币别-根据公司
+ ///
+ GetSettlementCurrencyByCompany = 13,
+ ///
+ /// 单位-根据公司
+ ///
+ GetUnitByCompany = 14,
+ ///
+ /// 单位(部分属性)-根据公司
+ ///
+ GetUnitPropertyByCompany = 15,
+ ///
+ /// 税率-根据公司
+ ///
+ GetTaxRateByCompany = 16,
+ ///
+ /// 仓库-根据名称和公司
+ ///
+ GetWarehouseByNameAndCompany = 17,
+ ///
+ /// 仓库-根据组织和公司
+ ///
+ GetWarehouseByOrgAndCompany = 18,
+ ///
+ /// 仓库(不是调拨中转仓)-根据组织和公司
+ ///
+ GetWarehouseByOrgAndCompanyForNotTransfer = 19,
+ ///
+ /// 仓库(211)-根据组织和公司
+ ///
+ GetWarehouseByOrgAndCompanyFor211 = 20,
+ ///
+ /// 仓库-根据客户和公司
+ ///
+ GetWareouseByCustomerAndCompany = 21,
+
+ ///
+ /// 仓位-根据仓库和名称
+ ///
+ GetChildWarehouseByPid = 22,
+ ///
+ /// 仓位-根据-
+ ///
+ GetChildWarehouse = 23,
+ ///
+ /// 汇率信息-根据原币、目标币和公司
+ ///
+ GetRateInfoByFromToAndCompany = 24,
+ ///
+ /// 客户仓库-根据客户和组织和公司
+ ///
+ GetCustomerStockByCustomerAndOrgAndCompany = 25,
+ ///
+ /// 付款条件,结算币别,结算方式,采购员,采购部门-根据供应商和组织
+ ///
+ GetPtAndScAndSmAndBuyerAndDeptBySupplierAndOrg = 26,
+ ///
+ /// 获取仓库:根据仓库id
+ ///
+ GetWarehouseByIds = 27,
+ ///
+ /// 获取库存:根据组织和公司
+ ///
+ GetCustomerByOrgAndCompany = 28,
+
+ ///
+ /// 获取客户仓库:根据客户IDS和组织和公司
+ ///
+ GetCustomerStockByCustomerListAndOrgAndCompany = 29,
+ ///
+ /// 汇率(所有)
+ ///
+ GetRateListByFromToAndCompany = 30,
+
+ ///
+ /// 供应商选择后获取:付款条件,结算币别,结算方式,采购员,采购部门,根据组织IDS
+ ///
+ GetPtAndScAndSmAndBuyerAndDeptByOrgs = 31,
+ ///
+ /// 获取客户仓库:根据code集合
+ ///
+ GetCustomerStockListByCodes = 32,
+ ///
+ /// 供应商:根据ids
+ ///
+ GetSupperByIds = 33,
+ ///
+ /// 根据公司搜索所有仓库(计算补货频次)
+ ///
+ GetWarehouseReplenDatebyCompany = 34,
+ ///
+ /// 获取仓库:根据codes
+ ///
+ GetWarehouseByCodes = 35,
+ ///
+ /// 获取客户仓库:根据codes
+ ///
+ GetCustomerStockByCodes = 36,
+
+ ///
+ /// 获取调拨中转仓库:根据公司
+ ///
+ GetWarehouseTransferByCompany = 37,
+ ///
+ /// 获取供应商数据根据ids
+ ///
+ GetSupperAbout1ByIds = 38,
+ ///
+ /// 获取仓库:根据默认补货客户
+ ///
+ GetWarehouseByDefaultReplenishCustomer = 39,
+ ///
+ /// 获取用户(ID和Name):根据公司
+ ///
+ GetUsersByCompany = 40,
+ ///
+ /// 全部部门-根据组织和公司:不处理子级
+ ///
+ GetDeptAllByOrgAndCompany = 41,
+
+ ///
+ /// 获取全部员工:根据公司和组织
+ ///
+ GetStaffAllByOrgAndCompany = 42,
+ }
+}
diff --git a/src/WMS.Web.Domain/WMS.Web.Domain.csproj b/src/WMS.Web.Domain/WMS.Web.Domain.csproj
index bcd91faa..f4b6e518 100644
--- a/src/WMS.Web.Domain/WMS.Web.Domain.csproj
+++ b/src/WMS.Web.Domain/WMS.Web.Domain.csproj
@@ -13,11 +13,6 @@
-
-
-
-
-