From eede0d8477e7117e652b870cb29ef78a95b7f38a Mon Sep 17 00:00:00 2001
From: hwh <332078369@qq.com>
Date: 星期三, 19 六月 2024 14:08:41 +0800
Subject: [PATCH] 全局异常处理和规范返回
---
HTML/js/public.js | 51 +
Wms/Utility/Entity/ApiResponse.cs | 20
Wms/Utility/Extension/RequestAuditLogFilter.cs | 26
Wms/Utility/Enum/ErrorCodeEnum.cs | 592 ++++++++++++++++++
Wms/Wms/Wms.csproj | 16
Wms/Utility/Filter/CustomerExceptionMiddleware.cs | 64 ++
Wms/Utility/Extension/LogExtends.cs | 75 ++
Wms/Utility/Exception/ErrorCodeTypeAttribute.cs | 14
Wms/Utility/Exception/AppFriendlyException.cs | 80 ++
Wms/Utility/Exception/Oops.cs | 209 ++++++
Wms/Utility/UnitOfWork/UnitOfWorkAttribute.cs | 290 +++++++++
Wms/Wms/Controllers/BllTaskController.cs | 3
Wms/Wms/Startup.cs | 19
Wms/Wms/Program.cs | 17
Wms/Utility/Extension/ApplicationBuilderExtensions.cs | 85 ++
Wms/Utility/Extension/ApiResponseActionFilter.cs | 37 +
Wms/Utility/Extension/ApiResponseMiddleware.cs | 97 +++
Wms/Utility/Utility.csproj | 14
Wms/Utility/Enum/ResponseEnum.cs | 15
Wms/Utility/Extension/ServiceCollectionExtensions.cs | 79 ++
Wms/Utility/UnitOfWork/IUnitOfWork.cs | 38 +
Wms/Utility/Exception/ErrorCodeItemMetadataAttribute.cs | 40 +
22 files changed, 1,874 insertions(+), 7 deletions(-)
diff --git a/HTML/js/public.js b/HTML/js/public.js
index a15a788..27b625e 100644
--- a/HTML/js/public.js
+++ b/HTML/js/public.js
@@ -282,4 +282,55 @@
});
});
}
+}
+//娣辨嫹璐�
+function deepClone(source) {
+ if (typeof source !== 'object' || source == null) {
+ return source;
+ }
+ const target = Array.isArray(source) ? [] : {};
+ for (const key in source) {
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
+ if (typeof source[key] === 'object' && source[key] !== null) {
+ target[key] = deepClone(source[key]);
+ } else {
+ target[key] = source[key];
+ }
+ }
+ }
+ return target;
+}
+/**
+ * 灏嗚〃鍗曡祴鍊间负鎸囧畾鐨勫璞�
+ * @param {Object} data - 鍖呭惈琛ㄥ崟鏁版嵁鐨勫璞�
+ * @param {String} formSelector - 琛ㄥ崟鐨勯�夋嫨鍣紝渚嬪 '#myForm' 鎴� '.myForm'
+ */
+function setFormData(data, formSelector) {
+ var $form = $(formSelector);
+
+ $.each(data, function(key, value) {
+ var $field = $form.find('[name=' + key + ']');
+
+ if ($field.length > 0) {
+ var fieldType = $field.attr('type');
+
+ switch (fieldType) {
+ case 'checkbox':
+ if (Array.isArray(value)) {
+ $field.each(function() {
+ $(this).prop('checked', value.includes($(this).val()));
+ });
+ } else {
+ $field.prop('checked', value);
+ }
+ break;
+ case 'radio':
+ $field.filter('[value=' + value + ']').prop('checked', true);
+ break;
+ default:
+ $field.val(value);
+ break;
+ }
+ }
+ });
}
\ No newline at end of file
diff --git a/Wms/Utility/Entity/ApiResponse.cs b/Wms/Utility/Entity/ApiResponse.cs
new file mode 100644
index 0000000..c88a3a1
--- /dev/null
+++ b/Wms/Utility/Entity/ApiResponse.cs
@@ -0,0 +1,20 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Utility.Entity
+{
+ public class ApiResponse<T>
+ {
+ public int code { get; set; }
+ public string msg { get; set; }
+ public T data { get; set; }
+
+ public ApiResponse(int code, string message, T data)
+ {
+ this.code = code;
+ this.msg = message;
+ this.data = data;
+ }
+ }
+}
diff --git a/Wms/Utility/Enum/ErrorCodeEnum.cs b/Wms/Utility/Enum/ErrorCodeEnum.cs
new file mode 100644
index 0000000..eda5615
--- /dev/null
+++ b/Wms/Utility/Enum/ErrorCodeEnum.cs
@@ -0,0 +1,592 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Text;
+
+
+namespace Utility
+{
+ /// <summary>
+ /// 绯荤粺閿欒鐮�
+ /// </summary>
+ [ErrorCodeType]
+ [Description("绯荤粺閿欒鐮�")]
+ public enum ErrorCodeEnum
+ {
+ /// <summary>
+ /// 楠岃瘉鐮侀敊璇�
+ /// </summary>
+ [ErrorCodeItemMetadata("楠岃瘉鐮侀敊璇�")]
+ D0008,
+
+ /// <summary>
+ /// 璐﹀彿涓嶅瓨鍦�
+ /// </summary>
+ [ErrorCodeItemMetadata("璐﹀彿涓嶅瓨鍦�")]
+ D0009,
+
+ /// <summary>
+ /// 瀵嗙爜涓嶆纭�
+ /// </summary>
+ [ErrorCodeItemMetadata("瀵嗙爜涓嶆纭�")]
+ D1000,
+
+ /// <summary>
+ /// 闈炴硶鎿嶄綔锛佺姝㈠垹闄よ嚜宸�
+ /// </summary>
+ [ErrorCodeItemMetadata("闈炴硶鎿嶄綔锛岀姝㈠垹闄よ嚜宸�")]
+ D1001,
+
+ /// <summary>
+ /// 璁板綍涓嶅瓨鍦�
+ /// </summary>
+ [ErrorCodeItemMetadata("璁板綍涓嶅瓨鍦�")]
+ D1002,
+
+ /// <summary>
+ /// 璐﹀彿宸插瓨鍦�
+ /// </summary>
+ [ErrorCodeItemMetadata("璐﹀彿宸插瓨鍦�")]
+ D1003,
+
+ /// <summary>
+ /// 鏃у瘑鐮佷笉鍖归厤
+ /// </summary>
+ [ErrorCodeItemMetadata("鏃у瘑鐮佽緭鍏ラ敊璇�")]
+ D1004,
+
+ /// <summary>
+ /// 娴嬭瘯鏁版嵁绂佹鏇存敼admin瀵嗙爜
+ /// </summary>
+ [ErrorCodeItemMetadata("娴嬭瘯鏁版嵁绂佹鏇存敼鐢ㄦ埛銆恆dmin銆戝瘑鐮�")]
+ D1005,
+
+ /// <summary>
+ /// 鏁版嵁宸插瓨鍦�
+ /// </summary>
+ [ErrorCodeItemMetadata("鏁版嵁宸插瓨鍦�")]
+ D1006,
+
+ /// <summary>
+ /// 鏁版嵁涓嶅瓨鍦ㄦ垨鍚湁鍏宠仈寮曠敤锛岀姝㈠垹闄�
+ /// </summary>
+ [ErrorCodeItemMetadata("鏁版嵁涓嶅瓨鍦ㄦ垨鍚湁鍏宠仈寮曠敤锛岀姝㈠垹闄�")]
+ D1007,
+
+ /// <summary>
+ /// 绂佹涓虹鐞嗗憳鍒嗛厤瑙掕壊
+ /// </summary>
+ [ErrorCodeItemMetadata("绂佹涓虹鐞嗗憳鍒嗛厤瑙掕壊")]
+ D1008,
+
+ /// <summary>
+ /// 閲嶅鏁版嵁鎴栬褰曞惈鏈変笉瀛樺湪鏁版嵁
+ /// </summary>
+ [ErrorCodeItemMetadata("閲嶅鏁版嵁鎴栬褰曞惈鏈変笉瀛樺湪鏁版嵁")]
+ D1009,
+
+ /// <summary>
+ /// 绂佹涓鸿秴绾х鐞嗗憳瑙掕壊鍒嗛厤鏉冮檺
+ /// </summary>
+ [ErrorCodeItemMetadata("绂佹涓鸿秴绾х鐞嗗憳瑙掕壊鍒嗛厤鏉冮檺")]
+ D1010,
+
+ /// <summary>
+ /// 闈炴硶鎿嶄綔锛屾湭鐧诲綍
+ /// </summary>
+ [ErrorCodeItemMetadata("闈炴硶鎿嶄綔锛屾湭鐧诲綍")]
+ D1011,
+
+ /// <summary>
+ /// Id涓嶈兘涓虹┖
+ /// </summary>
+ [ErrorCodeItemMetadata("Id涓嶈兘涓虹┖")]
+ D1012,
+
+ /// <summary>
+ /// 鎵�灞炴満鏋勪笉鍦ㄨ嚜宸辩殑鏁版嵁鑼冨洿鍐�
+ /// </summary>
+ [ErrorCodeItemMetadata("娌℃湁鏉冮檺鎿嶄綔璇ユ暟鎹�")]
+ D1013,
+
+ /// <summary>
+ /// 绂佹鍒犻櫎瓒呯骇绠$悊鍛�
+ /// </summary>
+ [ErrorCodeItemMetadata("绂佹鍒犻櫎瓒呯骇绠$悊鍛�")]
+ D1014,
+
+ /// <summary>
+ /// 绂佹淇敼瓒呯骇绠$悊鍛樼姸鎬�
+ /// </summary>
+ [ErrorCodeItemMetadata("绂佹淇敼瓒呯骇绠$悊鍛樼姸鎬�")]
+ D1015,
+
+ /// <summary>
+ /// 娌℃湁鏉冮檺
+ /// </summary>
+ [ErrorCodeItemMetadata("娌℃湁鏉冮檺")]
+ D1016,
+
+ /// <summary>
+ /// 璐﹀彿宸插喕缁�
+ /// </summary>
+ [ErrorCodeItemMetadata("璐﹀彿宸插喕缁�")]
+ D1017,
+
+ /// <summary>
+ /// 绂佹鍒犻櫎绠$悊鍛�
+ /// </summary>
+ [ErrorCodeItemMetadata("绂佹鍒犻櫎绠$悊鍛�")]
+ D1018,
+
+ /// <summary>
+ /// 绂佹鍒犻櫎绯荤粺绠$悊鍛樿鑹�
+ /// </summary>
+ [ErrorCodeItemMetadata("绂佹鍒犻櫎绯荤粺绠$悊鍛樿鑹�")]
+ D1019,
+
+ /// <summary>
+ /// 绂佹淇敼绯荤粺绠$悊鍛樿鑹�
+ /// </summary>
+ [ErrorCodeItemMetadata("绂佹淇敼绯荤粺绠$悊鍛樿鑹�")]
+ D1020,
+
+ /// <summary>
+ /// 绂佹涓虹郴缁熺鐞嗗憳瑙掕壊鍒嗛厤鏉冮檺
+ /// </summary>
+ [ErrorCodeItemMetadata("绂佹涓虹郴缁熺鐞嗗憳瑙掕壊鍒嗛厤鏉冮檺")]
+ D1021,
+
+ /// <summary>
+ /// 绂佹涓鸿秴绾х鐞嗗憳鍒嗛厤瑙掕壊
+ /// </summary>
+ [ErrorCodeItemMetadata("绂佹涓鸿秴绾х鐞嗗憳鍒嗛厤瑙掕壊")]
+ D1022,
+
+ /// <summary>
+ /// 绂佹鍒犻櫎榛樿绉熸埛
+ /// </summary>
+ [ErrorCodeItemMetadata("绂佹鍒犻櫎榛樿绉熸埛")]
+ D1023,
+
+ /// <summary>
+ /// 宸插皢鍏朵粬鍦版柟鐧诲綍璐﹀彿涓嬬嚎
+ /// </summary>
+ [ErrorCodeItemMetadata("宸插皢鍏朵粬鍦版柟鐧诲綍璐﹀彿涓嬬嚎")]
+ D1024,
+
+ /// <summary>
+ /// 鐖舵満鏋勪笉瀛樺湪
+ /// </summary>
+ [ErrorCodeItemMetadata("鐖舵満鏋勪笉瀛樺湪")]
+ D2000,
+
+ /// <summary>
+ /// 褰撳墠鏈烘瀯Id涓嶈兘涓庣埗鏈烘瀯Id鐩稿悓
+ /// </summary>
+ [ErrorCodeItemMetadata("褰撳墠鏈烘瀯Id涓嶈兘涓庣埗鏈烘瀯Id鐩稿悓")]
+ D2001,
+
+ /// <summary>
+ /// 宸叉湁鐩稿悓缁勭粐鏈烘瀯,缂栫爜鎴栧悕绉扮浉鍚�
+ /// </summary>
+ [ErrorCodeItemMetadata("宸叉湁鐩稿悓缁勭粐鏈烘瀯,缂栫爜鎴栧悕绉扮浉鍚�")]
+ D2002,
+
+ /// <summary>
+ /// 娌℃湁鏉冮檺鎿嶄綔鏈烘瀯
+ /// </summary>
+ [ErrorCodeItemMetadata("娌℃湁鏉冮檺鎿嶄綔鏈烘瀯")]
+ D2003,
+
+ /// <summary>
+ /// 璇ユ満鏋勪笅鏈夌敤鎴风姝㈠垹闄�
+ /// </summary>
+ [ErrorCodeItemMetadata("璇ユ満鏋勪笅鏈夌敤鎴风姝㈠垹闄�")]
+ D2004,
+
+ /// <summary>
+ /// 闄勫睘鏈烘瀯涓嬫湁鐢ㄦ埛绂佹鍒犻櫎
+ /// </summary>
+ [ErrorCodeItemMetadata("闄勫睘鏈烘瀯涓嬫湁鐢ㄦ埛绂佹鍒犻櫎")]
+ D2005,
+
+ /// <summary>
+ /// 鍙兘澧炲姞涓嬬骇鏈烘瀯
+ /// </summary>
+ [ErrorCodeItemMetadata("鍙兘澧炲姞涓嬬骇鏈烘瀯")]
+ D2006,
+
+ /// <summary>
+ /// 涓嬬骇鏈烘瀯涓嬫湁鐢ㄦ埛绂佹鍒犻櫎
+ /// </summary>
+ [ErrorCodeItemMetadata("涓嬬骇鏈烘瀯涓嬫湁鐢ㄦ埛绂佹鍒犻櫎")]
+ D2007,
+
+ /// <summary>
+ /// 绉熸埛榛樿鏈烘瀯绂佹鍒犻櫎
+ /// </summary>
+ [ErrorCodeItemMetadata("绉熸埛榛樿鏈烘瀯绂佹鍒犻櫎")]
+ D2008,
+
+ /// <summary>
+ /// 瀛楀吀绫诲瀷涓嶅瓨鍦�
+ /// </summary>
+ [ErrorCodeItemMetadata("瀛楀吀绫诲瀷涓嶅瓨鍦�")]
+ D3000,
+
+ /// <summary>
+ /// 瀛楀吀绫诲瀷宸插瓨鍦�
+ /// </summary>
+ [ErrorCodeItemMetadata("瀛楀吀绫诲瀷宸插瓨鍦�,鍚嶇О鎴栫紪鐮侀噸澶�")]
+ D3001,
+
+ /// <summary>
+ /// 瀛楀吀绫诲瀷涓嬮潰鏈夊瓧鍏稿�肩姝㈠垹闄�
+ /// </summary>
+ [ErrorCodeItemMetadata("瀛楀吀绫诲瀷涓嬮潰鏈夊瓧鍏稿�肩姝㈠垹闄�")]
+ D3002,
+
+ /// <summary>
+ /// 瀛楀吀鍊煎凡瀛樺湪
+ /// </summary>
+ [ErrorCodeItemMetadata("瀛楀吀鍊煎凡瀛樺湪,鍚嶇О鎴栫紪鐮侀噸澶�")]
+ D3003,
+
+ /// <summary>
+ /// 瀛楀吀鍊间笉瀛樺湪
+ /// </summary>
+ [ErrorCodeItemMetadata("瀛楀吀鍊间笉瀛樺湪")]
+ D3004,
+
+ /// <summary>
+ /// 瀛楀吀鐘舵�侀敊璇�
+ /// </summary>
+ [ErrorCodeItemMetadata("瀛楀吀鐘舵�侀敊璇�")]
+ D3005,
+
+ /// <summary>
+ /// 鑿滃崟宸插瓨鍦�
+ /// </summary>
+ [ErrorCodeItemMetadata("鑿滃崟宸插瓨鍦�")]
+ D4000,
+
+ /// <summary>
+ /// 璺敱鍦板潃涓虹┖
+ /// </summary>
+ [ErrorCodeItemMetadata("璺敱鍦板潃涓虹┖")]
+ D4001,
+
+ /// <summary>
+ /// 鎵撳紑鏂瑰紡涓虹┖
+ /// </summary>
+ [ErrorCodeItemMetadata("鎵撳紑鏂瑰紡涓虹┖")]
+ D4002,
+
+ /// <summary>
+ /// 鏉冮檺鏍囪瘑鏍煎紡涓虹┖
+ /// </summary>
+ [ErrorCodeItemMetadata("鏉冮檺鏍囪瘑鏍煎紡涓虹┖")]
+ D4003,
+
+ /// <summary>
+ /// 鏉冮檺鏍囪瘑鏍煎紡閿欒
+ /// </summary>
+ [ErrorCodeItemMetadata("鏉冮檺鏍囪瘑鏍煎紡閿欒 濡倄xx:xxx")]
+ D4004,
+
+ /// <summary>
+ /// 鏉冮檺涓嶅瓨鍦�
+ /// </summary>
+ [ErrorCodeItemMetadata("鏉冮檺涓嶅瓨鍦�")]
+ D4005,
+
+ /// <summary>
+ /// 鐖剁骇鑿滃崟涓嶈兘涓哄綋鍓嶈妭鐐癸紝璇烽噸鏂伴�夋嫨鐖剁骇鑿滃崟
+ /// </summary>
+ [ErrorCodeItemMetadata("鐖剁骇鑿滃崟涓嶈兘涓哄綋鍓嶈妭鐐癸紝璇烽噸鏂伴�夋嫨鐖剁骇鑿滃崟")]
+ D4006,
+
+ /// <summary>
+ /// 涓嶈兘绉诲姩鏍硅妭鐐�
+ /// </summary>
+ [ErrorCodeItemMetadata("涓嶈兘绉诲姩鏍硅妭鐐�")]
+ D4007,
+
+ /// <summary>
+ /// 宸插瓨鍦ㄥ悓鍚嶆垨鍚岀紪鐮佸簲鐢�
+ /// </summary>
+ [ErrorCodeItemMetadata("宸插瓨鍦ㄥ悓鍚嶆垨鍚岀紪鐮佸簲鐢�")]
+ D5000,
+
+ /// <summary>
+ /// 榛樿婵�娲荤郴缁熷彧鑳芥湁涓�涓�
+ /// </summary>
+ [ErrorCodeItemMetadata("榛樿婵�娲荤郴缁熷彧鑳芥湁涓�涓�")]
+ D5001,
+
+ /// <summary>
+ /// 璇ュ簲鐢ㄤ笅鏈夎彍鍗曠姝㈠垹闄�
+ /// </summary>
+ [ErrorCodeItemMetadata("璇ュ簲鐢ㄤ笅鏈夎彍鍗曠姝㈠垹闄�")]
+ D5002,
+
+ /// <summary>
+ /// 宸插瓨鍦ㄥ悓鍚嶆垨鍚岀紪鐮佸簲鐢�
+ /// </summary>
+ [ErrorCodeItemMetadata("宸插瓨鍦ㄥ悓鍚嶆垨鍚岀紪鐮佸簲鐢�")]
+ D5003,
+
+ /// <summary>
+ /// 宸插瓨鍦ㄥ悓鍚嶆垨鍚岀紪鐮佽亴浣�
+ /// </summary>
+ [ErrorCodeItemMetadata("宸插瓨鍦ㄥ悓鍚嶆垨鍚岀紪鐮佽亴浣�")]
+ D6000,
+
+ /// <summary>
+ /// 璇ヨ亴浣嶄笅鏈夌敤鎴风姝㈠垹闄�
+ /// </summary>
+ [ErrorCodeItemMetadata("璇ヨ亴浣嶄笅鏈夌敤鎴风姝㈠垹闄�")]
+ D6001,
+
+ /// <summary>
+ /// 閫氱煡鍏憡鐘舵�侀敊璇�
+ /// </summary>
+ [ErrorCodeItemMetadata("閫氱煡鍏憡鐘舵�侀敊璇�")]
+ D7000,
+
+ /// <summary>
+ /// 閫氱煡鍏憡鍒犻櫎澶辫触
+ /// </summary>
+ [ErrorCodeItemMetadata("閫氱煡鍏憡鍒犻櫎澶辫触")]
+ D7001,
+
+ /// <summary>
+ /// 閫氱煡鍏憡缂栬緫澶辫触
+ /// </summary>
+ [ErrorCodeItemMetadata("閫氱煡鍏憡缂栬緫澶辫触锛岀被鍨嬪繀椤讳负鑽夌")]
+ D7002,
+
+ /// <summary>
+ /// 閫氱煡鍏憡鎿嶄綔澶辫触锛岄潪鍙戝竷鑰呬笉鑳借繘琛屾搷浣�
+ /// </summary>
+ [ErrorCodeItemMetadata("閫氱煡鍏憡鎿嶄綔澶辫触锛岄潪鍙戝竷鑰呬笉鑳借繘琛屾搷浣�")]
+ D7003,
+
+ /// <summary>
+ /// 鏂囦欢涓嶅瓨鍦�
+ /// </summary>
+ [ErrorCodeItemMetadata("鏂囦欢涓嶅瓨鍦�")]
+ D8000,
+
+ /// <summary>
+ /// 涓嶅厑璁哥殑鏂囦欢绫诲瀷
+ /// </summary>
+ [ErrorCodeItemMetadata("涓嶅厑璁哥殑鏂囦欢绫诲瀷")]
+ D8001,
+
+ /// <summary>
+ /// 鏂囦欢瓒呰繃鍏佽澶у皬
+ /// </summary>
+ [ErrorCodeItemMetadata("鏂囦欢瓒呰繃鍏佽澶у皬")]
+ D8002,
+
+ /// <summary>
+ /// 鏂囦欢鍚庣紑閿欒
+ /// </summary>
+ [ErrorCodeItemMetadata("鏂囦欢鍚庣紑閿欒")]
+ D8003,
+
+ /// <summary>
+ /// 宸插瓨鍦ㄥ悓鍚嶆垨鍚岀紪鐮佸弬鏁伴厤缃�
+ /// </summary>
+ [ErrorCodeItemMetadata("宸插瓨鍦ㄥ悓鍚嶆垨鍚岀紪鐮佸弬鏁伴厤缃�")]
+ D9000,
+
+ /// <summary>
+ /// 绂佹鍒犻櫎绯荤粺鍙傛暟
+ /// </summary>
+ [ErrorCodeItemMetadata("绂佹鍒犻櫎绯荤粺鍙傛暟")]
+ D9001,
+
+ /// <summary>
+ /// 宸插瓨鍦ㄥ悓鍚嶄换鍔¤皟搴�
+ /// </summary>
+ [ErrorCodeItemMetadata("宸插瓨鍦ㄥ悓鍚嶄换鍔¤皟搴�")]
+ D1100,
+
+ /// <summary>
+ /// 浠诲姟璋冨害涓嶅瓨鍦�
+ /// </summary>
+ [ErrorCodeItemMetadata("浠诲姟璋冨害涓嶅瓨鍦�")]
+ D1101,
+
+ /// <summary>
+ /// 婕旂ず鐜绂佹淇敼鏁版嵁
+ /// </summary>
+ [ErrorCodeItemMetadata("婕旂ず鐜绂佹淇敼鏁版嵁")]
+ D1200,
+
+ /// <summary>
+ /// 宸插瓨鍦ㄥ悓鍚嶇殑绉熸埛
+ /// </summary>
+ [ErrorCodeItemMetadata("宸插瓨鍦ㄥ悓鍚嶇殑绉熸埛")]
+ D1300,
+
+ /// <summary>
+ /// 宸插瓨鍦ㄥ悓鍚嶇殑绉熸埛绠$悊鍛�
+ /// </summary>
+ [ErrorCodeItemMetadata("宸插瓨鍦ㄥ悓鍚嶇殑绉熸埛绠$悊鍛�")]
+ D1301,
+
+ /// <summary>
+ /// 璇ヨ〃浠g爜妯℃澘宸茬粡鐢熸垚杩�
+ /// </summary>
+ [ErrorCodeItemMetadata("璇ヨ〃浠g爜妯℃澘宸茬粡鐢熸垚杩�")]
+ D1400,
+
+ /// <summary>
+ /// 璇ョ被鍨嬩笉瀛樺湪
+ /// </summary>
+ [ErrorCodeItemMetadata("璇ョ被鍨嬩笉瀛樺湪")]
+ D1501,
+
+ /// <summary>
+ /// 璇ュ瓧娈典笉瀛樺湪
+ /// </summary>
+ [ErrorCodeItemMetadata("璇ュ瓧娈典笉瀛樺湪")]
+ D1502,
+
+ /// <summary>
+ /// 璇ョ被鍨嬩笉鏄灇涓剧被鍨�
+ /// </summary>
+ [ErrorCodeItemMetadata("璇ョ被鍨嬩笉鏄灇涓剧被鍨�")]
+ D1503,
+
+ /// <summary>
+ /// 璇ュ疄浣撲笉瀛樺湪
+ /// </summary>
+ [ErrorCodeItemMetadata("璇ュ疄浣撲笉瀛樺湪")]
+ D1504,
+
+ /// <summary>
+ /// 鐖惰彍鍗曚笉瀛樺湪
+ /// </summary>
+ [ErrorCodeItemMetadata("鐖惰彍鍗曚笉瀛樺湪")]
+ D1505,
+
+ /// <summary>
+ /// 鐖惰祫婧愪笉瀛樺湪
+ /// </summary>
+ [ErrorCodeItemMetadata("鐖惰祫婧愪笉瀛樺湪")]
+ D1600,
+
+ /// <summary>
+ /// 褰撳墠璧勬簮Id涓嶈兘涓庣埗璧勬簮Id鐩稿悓
+ /// </summary>
+ [ErrorCodeItemMetadata("褰撳墠璧勬簮Id涓嶈兘涓庣埗璧勬簮Id鐩稿悓")]
+ D1601,
+
+ /// <summary>
+ /// 宸叉湁鐩稿悓缂栫爜鎴栧悕绉�
+ /// </summary>
+ [ErrorCodeItemMetadata("宸叉湁鐩稿悓缂栫爜鎴栧悕绉�")]
+ D1602,
+
+ /// <summary>
+ /// 鑴氭湰浠g爜涓嶈兘涓虹┖
+ /// </summary>
+ [ErrorCodeItemMetadata("鑴氭湰浠g爜涓嶈兘涓虹┖")]
+ D1701,
+
+ /// <summary>
+ /// 鑴氭湰浠g爜涓殑浣滀笟绫伙紝闇�瑕佸畾涔� [JobDetail] 鐗规��
+ /// </summary>
+ [ErrorCodeItemMetadata("鑴氭湰浠g爜涓殑浣滀笟绫伙紝闇�瑕佸畾涔� [JobDetail] 鐗规��")]
+ D1702,
+
+ /// <summary>
+ /// 浣滀笟缂栧彿闇�瑕佷笌鑴氭湰浠g爜涓殑浣滀笟绫� [JobDetail('jobId')] 涓�鑷�
+ /// </summary>
+ [ErrorCodeItemMetadata("浣滀笟缂栧彿闇�瑕佷笌鑴氭湰浠g爜涓殑浣滀笟绫� [JobDetail('jobId')] 涓�鑷�")]
+ D1703,
+
+ /// <summary>
+ /// 绂佹淇敼浣滀笟缂栧彿
+ /// </summary>
+ [ErrorCodeItemMetadata("绂佹淇敼浣滀笟缂栧彿")]
+ D1704,
+
+ /// <summary>
+ /// 宸插瓨鍦ㄥ悓鍚嶆垨鍚岀紪鐮侀」鐩�
+ /// </summary>
+ [ErrorCodeItemMetadata("宸插瓨鍦ㄥ悓鍚嶆垨鍚岀紪鐮侀」鐩�")]
+ xg1000,
+
+ /// <summary>
+ /// 宸插瓨鍦ㄧ浉鍚岃瘉浠跺彿鐮佷汉鍛�
+ /// </summary>
+ [ErrorCodeItemMetadata("宸插瓨鍦ㄧ浉鍚岃瘉浠跺彿鐮佷汉鍛�")]
+ xg1001,
+
+ /// <summary>
+ /// 妫�娴嬫暟鎹笉瀛樺湪
+ /// </summary>
+ [ErrorCodeItemMetadata("妫�娴嬫暟鎹笉瀛樺湪")]
+ xg1002,
+
+ /// <summary>
+ /// 璇锋坊鍔犳暟鎹垪
+ /// </summary>
+ [ErrorCodeItemMetadata("璇锋坊鍔犳暟鎹垪")]
+ db1000,
+
+ /// <summary>
+ /// 鏁版嵁琛ㄤ笉瀛樺湪
+ /// </summary>
+ [ErrorCodeItemMetadata("鏁版嵁琛ㄤ笉瀛樺湪")]
+ db1001,
+
+ /// <summary>
+ /// 鏁版嵁琛ㄤ笉瀛樺湪
+ /// </summary>
+ [ErrorCodeItemMetadata("涓嶅厑璁告坊鍔犵浉鍚屽瓧娈靛悕")]
+ db1002,
+
+ /// <summary>
+ /// 鐖惰妭鐐逛笉瀛樺湪
+ /// </summary>
+ [ErrorCodeItemMetadata("鐖惰妭鐐逛笉瀛樺湪")]
+ R2000,
+
+ /// <summary>
+ /// 褰撳墠鑺傜偣Id涓嶈兘涓庣埗鑺傜偣Id鐩稿悓
+ /// </summary>
+ [ErrorCodeItemMetadata("褰撳墠鑺傜偣Id涓嶈兘涓庣埗鑺傜偣Id鐩稿悓")]
+ R2001,
+
+ /// <summary>
+ /// 宸叉湁鐩稿悓缂栫爜鎴栧悕绉�
+ /// </summary>
+ [ErrorCodeItemMetadata("宸叉湁鐩稿悓缂栫爜鎴栧悕绉�")]
+ R2002,
+
+ /// <summary>
+ /// 榛樿绉熸埛鐘舵�佺姝慨鏀�
+ /// </summary>
+ [ErrorCodeItemMetadata("榛樿绉熸埛鐘舵�佺姝慨鏀�")]
+ Z1001,
+
+ /// <summary>
+ /// 绂佹鍒涘缓姝ょ被鍨嬬殑鏁版嵁搴�
+ /// </summary>
+ [ErrorCodeItemMetadata("绂佹鍒涘缓姝ょ被鍨嬬殑鏁版嵁搴�")]
+ Z1002,
+
+ /// <summary>
+ /// 绉熸埛宸茬鐢�
+ /// </summary>
+ [ErrorCodeItemMetadata("绉熸埛宸茬鐢�")]
+ Z1003,
+ }
+}
\ No newline at end of file
diff --git a/Wms/Utility/Enum/ResponseEnum.cs b/Wms/Utility/Enum/ResponseEnum.cs
new file mode 100644
index 0000000..43852d0
--- /dev/null
+++ b/Wms/Utility/Enum/ResponseEnum.cs
@@ -0,0 +1,15 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Utility
+{
+ public enum ResponseEnum
+ {
+ Sucess = 0,
+
+ Fail = 1,
+
+ Error = 2,
+ }
+}
diff --git a/Wms/Utility/Exception/AppFriendlyException.cs b/Wms/Utility/Exception/AppFriendlyException.cs
new file mode 100644
index 0000000..c45772d
--- /dev/null
+++ b/Wms/Utility/Exception/AppFriendlyException.cs
@@ -0,0 +1,80 @@
+锘縰sing Microsoft.AspNetCore.Http;
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace Utility
+{
+ public class AppFriendlyException : Exception
+ {
+ /// <summary>
+ /// 鏋勯�犲嚱鏁�
+ /// </summary>
+ public AppFriendlyException() : base()
+ {
+ }
+
+ /// <summary>
+ /// 鏋勯�犲嚱鏁�
+ /// </summary>
+ /// <param name="message"></param>
+ /// <param name="errorCode"></param>
+ public AppFriendlyException(string message, object errorCode) : base(message)
+ {
+ ErrorMessage = message;
+ ErrorCode = OriginErrorCode = errorCode;
+ }
+
+ /// <summary>
+ /// 鏋勯�犲嚱鏁�
+ /// </summary>
+ /// <param name="message"></param>
+ /// <param name="errorCode"></param>
+ /// <param name="innerException"></param>
+ public AppFriendlyException(string message, object errorCode, Exception innerException) : base(message, innerException)
+ {
+ ErrorMessage = message;
+ ErrorCode = OriginErrorCode = errorCode;
+ }
+
+ /// <summary>
+ /// 鏋勯�犲嚱鏁�
+ /// </summary>
+ /// <param name="info"></param>
+ /// <param name="context"></param>
+ public AppFriendlyException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
+ }
+
+ /// <summary>
+ /// 閿欒鐮�
+ /// </summary>
+ public object ErrorCode { get; set; }
+
+ /// <summary>
+ /// 閿欒鐮侊紙娌¤澶嶅啓杩囩殑 ErrorCode 锛�
+ /// </summary>
+ public object OriginErrorCode { get; set; }
+
+ /// <summary>
+ /// 閿欒娑堟伅锛堟敮鎸� Object 瀵硅薄锛�
+ /// </summary>
+ public object ErrorMessage { get; set; }
+
+ /// <summary>
+ /// 鐘舵�佺爜
+ /// </summary>
+ public int StatusCode { get; set; } = StatusCodes.Status500InternalServerError;
+
+ /// <summary>
+ /// 鏄惁鏄暟鎹獙璇佸紓甯�
+ /// </summary>
+ public bool ValidationException { get; set; } = false;
+
+ /// <summary>
+ /// 棰濆鏁版嵁
+ /// </summary>
+ public new object Data { get; set; }
+ }
+}
diff --git a/Wms/Utility/Exception/ErrorCodeItemMetadataAttribute.cs b/Wms/Utility/Exception/ErrorCodeItemMetadataAttribute.cs
new file mode 100644
index 0000000..0f2faed
--- /dev/null
+++ b/Wms/Utility/Exception/ErrorCodeItemMetadataAttribute.cs
@@ -0,0 +1,40 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Utility
+{
+
+ /// <summary>
+ /// 寮傚父鍏冩暟鎹壒鎬�
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Field)]
+ public sealed class ErrorCodeItemMetadataAttribute : Attribute
+ {
+ /// <summary>
+ /// 鏋勯�犲嚱鏁�
+ /// </summary>
+ /// <param name="errorMessage">閿欒娑堟伅</param>
+ /// <param name="args">鏍煎紡鍖栧弬鏁�</param>
+ public ErrorCodeItemMetadataAttribute(string errorMessage, params object[] args)
+ {
+ ErrorMessage = errorMessage;
+ Args = args;
+ }
+
+ /// <summary>
+ /// 閿欒娑堟伅
+ /// </summary>
+ public string ErrorMessage { get; set; }
+
+ /// <summary>
+ /// 閿欒鐮�
+ /// </summary>
+ public object ErrorCode { get; set; }
+
+ /// <summary>
+ /// 鏍煎紡鍖栧弬鏁�
+ /// </summary>
+ public object[] Args { get; set; }
+ }
+}
diff --git a/Wms/Utility/Exception/ErrorCodeTypeAttribute.cs b/Wms/Utility/Exception/ErrorCodeTypeAttribute.cs
new file mode 100644
index 0000000..aa37e27
--- /dev/null
+++ b/Wms/Utility/Exception/ErrorCodeTypeAttribute.cs
@@ -0,0 +1,14 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Utility
+{
+ /// <summary>
+ /// 閿欒浠g爜绫诲瀷鐗规��
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Enum)]
+ public sealed class ErrorCodeTypeAttribute : Attribute
+ {
+ }
+}
diff --git a/Wms/Utility/Exception/Oops.cs b/Wms/Utility/Exception/Oops.cs
new file mode 100644
index 0000000..09b43d7
--- /dev/null
+++ b/Wms/Utility/Exception/Oops.cs
@@ -0,0 +1,209 @@
+锘縰sing Microsoft.AspNetCore.DataProtection.KeyManagement;
+using Microsoft.AspNetCore.Http;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+
+namespace Utility
+{
+ /// <summary>
+ /// 鎶涘紓甯搁潤鎬佺被
+ /// </summary>
+ public static class Oops
+ {
+
+ /// <summary>
+ /// 閿欒浠g爜绫诲瀷
+ /// </summary>
+ private static readonly IEnumerable<Type> ErrorCodeTypes;
+
+ /// <summary>
+ /// 鏋勯�犲嚱鏁�
+ /// </summary>
+ static Oops()
+ {
+ ErrorCodeTypes = GetErrorCodeTypes();
+
+ }
+
+ /// <summary>
+ /// 鎶涘嚭涓氬姟寮傚父淇℃伅
+ /// </summary>
+ /// <param name="errorMessage">寮傚父娑堟伅</param>
+ /// <param name="args">String.Format 鍙傛暟</param>
+ /// <returns>寮傚父瀹炰緥</returns>
+ public static AppFriendlyException Bah(string errorMessage, params object[] args)
+ {
+ var friendlyException = Oh(errorMessage, typeof(ValidationException), args);
+ friendlyException.StatusCode = StatusCodes.Status400BadRequest;
+ friendlyException.ValidationException = true;
+ return friendlyException;
+ }
+
+ /// <summary>
+ /// 鎶涘嚭涓氬姟寮傚父淇℃伅
+ /// </summary>
+ /// <param name="errorCode">閿欒鐮�</param>
+ /// <param name="args">String.Format 鍙傛暟</param>
+ /// <returns>寮傚父瀹炰緥</returns>
+ public static AppFriendlyException Bah(object errorCode, params object[] args)
+ {
+ var friendlyException = Oh(errorCode, typeof(ValidationException), args);
+ friendlyException.StatusCode = StatusCodes.Status400BadRequest;
+ friendlyException.ValidationException = true;
+ return friendlyException;
+ }
+
+ /// <summary>
+ /// 鎶涘嚭瀛楃涓插紓甯�
+ /// </summary>
+ /// <param name="errorMessage">寮傚父娑堟伅</param>
+ /// <param name="args">String.Format 鍙傛暟</param>
+ /// <returns>寮傚父瀹炰緥</returns>
+ public static AppFriendlyException Oh(string errorMessage, params object[] args)
+ {
+ var friendlyException = new AppFriendlyException(errorMessage, default);
+
+ friendlyException.StatusCode = StatusCodes.Status400BadRequest;
+ friendlyException.ValidationException = true;
+ return friendlyException;
+ }
+
+ /// <summary>
+ /// 鎶涘嚭瀛楃涓插紓甯�
+ /// </summary>
+ /// <param name="errorMessage">寮傚父娑堟伅</param>
+ /// <param name="exceptionType">鍏蜂綋寮傚父绫诲瀷</param>
+ /// <param name="args">String.Format 鍙傛暟</param>
+ /// <returns>寮傚父瀹炰緥</returns>
+ public static AppFriendlyException Oh(string errorMessage, Type exceptionType, params object[] args)
+ {
+ var exceptionMessage = string.Format(errorMessage, args);
+ return new AppFriendlyException(exceptionMessage, default,
+ Activator.CreateInstance(exceptionType, new object[] { exceptionMessage }) as Exception);
+ }
+
+ /// <summary>
+ /// 鎶涘嚭瀛楃涓插紓甯�
+ /// </summary>
+ /// <typeparam name="TException">鍏蜂綋寮傚父绫诲瀷</typeparam>
+ /// <param name="errorMessage">寮傚父娑堟伅</param>
+ /// <param name="args">String.Format 鍙傛暟</param>
+ /// <returns>寮傚父瀹炰緥</returns>
+ public static AppFriendlyException Oh<TException>(string errorMessage, params object[] args)
+ where TException : class
+ {
+ return Oh(errorMessage, typeof(TException), args);
+ }
+
+ /// <summary>
+ /// 鎶涘嚭閿欒鐮佸紓甯�
+ /// </summary>
+ /// <param name="errorCode">閿欒鐮�</param>
+ /// <param name="args">String.Format 鍙傛暟</param>
+ /// <returns>寮傚父瀹炰緥</returns>
+ public static AppFriendlyException Oh(object errorCode, params object[] args)
+ {
+ var (ErrorCode, Message) = GetErrorCodeMessage(errorCode, args);
+ var friendlyException = new AppFriendlyException(Message, errorCode) { ErrorCode = ErrorCode };
+
+ friendlyException.StatusCode = StatusCodes.Status400BadRequest;
+ friendlyException.ValidationException = true;
+ return friendlyException;
+ }
+
+ /// <summary>
+ /// 鎶涘嚭閿欒鐮佸紓甯�
+ /// </summary>
+ /// <param name="errorCode">閿欒鐮�</param>
+ /// <param name="exceptionType">鍏蜂綋寮傚父绫诲瀷</param>
+ /// <param name="args">String.Format 鍙傛暟</param>
+ /// <returns>寮傚父瀹炰緥</returns>
+ public static AppFriendlyException Oh(object errorCode, Type exceptionType, params object[] args)
+ {
+ var (ErrorCode, Message) = GetErrorCodeMessage(errorCode, args);
+ return new AppFriendlyException(Message, errorCode,
+ Activator.CreateInstance(exceptionType, new object[] { Message }) as Exception)
+ { ErrorCode = ErrorCode };
+ }
+
+ /// <summary>
+ /// 鎶涘嚭閿欒鐮佸紓甯�
+ /// </summary>
+ /// <typeparam name="TException">鍏蜂綋寮傚父绫诲瀷</typeparam>
+ /// <param name="errorCode">閿欒鐮�</param>
+ /// <param name="args">String.Format 鍙傛暟</param>
+ /// <returns>寮傚父瀹炰緥</returns>
+ public static AppFriendlyException Oh<TException>(object errorCode, params object[] args)
+ where TException : class
+ {
+ return Oh(errorCode, typeof(TException), args);
+ }
+ /// <summary>
+ /// 鑾峰彇閿欒鐮佹秷鎭�
+ /// </summary>
+ /// <param name="errorCode"></param>
+ /// <param name="args"></param>
+ /// <returns></returns>
+ private static (object ErrorCode, string Message) GetErrorCodeMessage(object errorCode, params object[] args)
+ {
+ string errorMessage = "";
+ (errorCode, errorMessage) = HandleEnumErrorCode(errorCode);
+ return (errorCode, errorMessage);
+ }
+ /// <summary>
+ /// 澶勭悊鏋氫妇绫诲瀷閿欒鐮�
+ /// </summary>
+ /// <param name="errorCode">閿欒鐮�</param>
+ /// <returns></returns>
+ private static (object ErrorCode, string Message) HandleEnumErrorCode(object errorCode)
+ {
+ string errorMessage = "";
+ // 鑾峰彇绫诲瀷
+ var errorType = errorCode.GetType();
+
+ // 鍒ゆ柇鏄惁鏄唴缃灇涓剧被鍨嬶紝濡傛灉鏄В鏋愮壒鎬�
+ if (ErrorCodeTypes.Any(u => u == errorType))
+ {
+ var fieldinfo = errorType.GetField(Enum.GetName(errorType, errorCode));
+ if (fieldinfo.IsDefined(typeof(ErrorCodeItemMetadataAttribute), true))
+ {
+ var info = GetErrorCodeItemInformation(fieldinfo);
+ errorCode = info.Key;
+ errorMessage = info.Value;
+ }
+ }
+
+ return (errorCode, errorMessage);
+ }
+ /// <summary>
+ /// 鑾峰彇閿欒浠g爜淇℃伅
+ /// </summary>
+ /// <param name="fieldInfo">瀛楁瀵硅薄</param>
+ /// <returns>(object key, object value)</returns>
+ private static (object Key, string Value) GetErrorCodeItemInformation(FieldInfo fieldInfo)
+ {
+ var errorCodeItemMetadata = fieldInfo.GetCustomAttribute<ErrorCodeItemMetadataAttribute>();
+ return (errorCodeItemMetadata.ErrorCode ?? fieldInfo.Name, string.Format(errorCodeItemMetadata.ErrorMessage, errorCodeItemMetadata.Args));
+ }
+ /// <summary>
+ /// 鑾峰彇閿欒浠g爜绫诲瀷
+ /// </summary>
+ /// <returns></returns>
+ private static IEnumerable<Type> GetErrorCodeTypes()
+ {
+ var typesWithErrorCodeTypeAttribute = AppDomain.CurrentDomain
+ .GetAssemblies()
+ .SelectMany(assembly => assembly.GetTypes())
+ .Where(type => type.IsEnum && type.GetCustomAttribute<ErrorCodeTypeAttribute>() != null)
+ .ToList();
+ return typesWithErrorCodeTypeAttribute;
+
+ }
+
+ }
+}
diff --git a/Wms/Utility/Extension/ApiResponseActionFilter.cs b/Wms/Utility/Extension/ApiResponseActionFilter.cs
new file mode 100644
index 0000000..186f008
--- /dev/null
+++ b/Wms/Utility/Extension/ApiResponseActionFilter.cs
@@ -0,0 +1,37 @@
+锘縰sing Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Filters;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using Utility.Entity;
+
+namespace Utility
+{
+ public class ApiResponseActionFilter: IAsyncActionFilter
+ {
+ public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
+ {
+ // 鍦ㄦ墽琛屽姩浣滀箣鍓嶇殑閫昏緫
+ var resultContext = await next(); // 鎵ц鍔ㄤ綔鏂规硶骞惰幏鍙栨墽琛岀粨鏋�
+
+ // 鍦ㄦ墽琛屽姩浣滀箣鍚庣殑閫昏緫
+ if (resultContext.Result is ObjectResult objectResult)
+ {
+ var apiResponse = new ApiResponse<object>(
+ context.HttpContext.Response.StatusCode,
+ context.HttpContext.Response.StatusCode == 200 ? "璇锋眰鎴愬姛" : "閿欒",
+ objectResult.Value
+ );
+
+ var json = JsonConvert.SerializeObject(apiResponse);
+ context.HttpContext.Response.ContentType = "application/json";
+ context.HttpContext.Response.ContentLength = Encoding.UTF8.GetByteCount(json);
+
+ await context.HttpContext.Response.WriteAsync(json);
+ }
+ }
+ }
+}
diff --git a/Wms/Utility/Extension/ApiResponseMiddleware.cs b/Wms/Utility/Extension/ApiResponseMiddleware.cs
new file mode 100644
index 0000000..745862c
--- /dev/null
+++ b/Wms/Utility/Extension/ApiResponseMiddleware.cs
@@ -0,0 +1,97 @@
+锘縰sing Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc.Controllers;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Utility.Entity;
+
+namespace Utility.Extension
+{
+ public class ApiResponseMiddleware : IMiddleware
+ {
+ public ApiResponseMiddleware()
+ {
+
+ }
+
+ public async Task InvokeAsync(HttpContext context, RequestDelegate next)
+ {
+ if (ShouldApplyApiResponseMiddleware(context))
+ {
+ // 鎹曡幏鍝嶅簲
+ var originalBodyStream = context.Response.Body;
+
+ using (var responseBody = new MemoryStream())
+ {
+ context.Response.Body = responseBody;
+
+ await next(context);
+ // 璇诲彇鍝嶅簲鍐呭
+ context.Response.Body.Seek(0, SeekOrigin.Begin);
+ var body = await new StreamReader(context.Response.Body).ReadToEndAsync();
+ context.Response.Body.Seek(0, SeekOrigin.Begin);
+
+ // 鍙嶅簭鍒楀寲鍝嶅簲鍐呭
+ object data = null;
+ if (!string.IsNullOrEmpty(body))
+ {
+ try
+ {
+ data = JsonConvert.DeserializeObject<object>(body);
+ }
+ catch (JsonException)
+ {
+ // 濡傛灉鍝嶅簲涓嶆槸鏈夋晥鐨凧SON鏍煎紡锛岀洿鎺ュ皢鍏朵綔涓哄瓧绗︿覆鏁版嵁澶勭悊
+ data = body;
+ }
+ }
+
+ var apiResponse = new ApiResponse<object>(
+ code: context.Response.StatusCode == StatusCodes.Status200OK ? (int)ResponseEnum.Sucess : (int)ResponseEnum.Fail,
+ message: context.Response.StatusCode == StatusCodes.Status200OK ? "璇锋眰鎴愬姛" : "",
+ data: data
+ );
+
+ var json = JsonConvert.SerializeObject(apiResponse);
+ context.Response.ContentType = "application/json";
+ context.Response.ContentLength = Encoding.UTF8.GetByteCount(json);
+
+ context.Response.Body = originalBodyStream;
+ await context.Response.WriteAsync(json);
+ }
+ }
+ else
+ {
+ await next(context);
+ }
+ }
+ private bool ShouldApplyApiResponseMiddleware(HttpContext context)
+ {
+ // 鑾峰彇褰撳墠澶勭悊璇锋眰鐨勬帶鍒跺櫒淇℃伅
+ var controllerActionDescriptor = context.GetEndpoint()?.Metadata.GetMetadata<ControllerActionDescriptor>();
+ if (controllerActionDescriptor != null)
+ {
+ // 鍒ゆ柇鎺у埗鍣ㄦ槸鍚﹀甫鏈� ResponseAttribute 鐗规��
+ return controllerActionDescriptor.ControllerTypeInfo.IsDefined(typeof(UnifyResponseAttribute), inherit: true);
+ }
+ return false;
+ }
+ }
+ public static class ApiResponse
+ {
+ public static void UseApiResponse(this IApplicationBuilder app)
+ {
+ app.UseMiddleware<ApiResponseMiddleware>();
+ }
+ }
+
+ public class UnifyResponseAttribute : Attribute
+ {
+
+ }
+}
diff --git a/Wms/Utility/Extension/ApplicationBuilderExtensions.cs b/Wms/Utility/Extension/ApplicationBuilderExtensions.cs
new file mode 100644
index 0000000..5c72390
--- /dev/null
+++ b/Wms/Utility/Extension/ApplicationBuilderExtensions.cs
@@ -0,0 +1,85 @@
+锘縰sing Microsoft.AspNetCore.Builder;
+using System;
+using Serilog;
+using Serilog.Events;
+using System.IO;
+using System.Net;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Http.Headers;
+using System.Runtime.CompilerServices;
+using Utility.Tools;
+using System.Security.Claims;
+using System.IdentityModel.Tokens.Jwt;
+using System.Linq;
+
+namespace Utility
+{
+ public static class ApplicationBuilderExtensions
+ {
+ /// <summary>
+ /// 娣诲姞浣跨敤Serilog璇锋眰鏃ュ織
+ /// </summary>
+ /// <param name="app"></param>
+ /// <returns></returns>
+ public static IApplicationBuilder UseSerilogRequestLogging(this IApplicationBuilder app)
+ {
+ //鍏佽body閲嶇敤
+ app.Use(next => context =>
+ {
+ context.Request.EnableBuffering();
+ return next(context);
+ });
+
+ // 娣诲姞浣跨敤Serilog璁板綍璇锋眰鏃ュ織
+ app.UseSerilogRequestLogging(options =>
+ {
+ // 璇锋眰鏃ュ織杈撳嚭妯℃澘
+ options.MessageTemplate = "\n {RequestMethod}={_RequestPath} | 鐘舵��={StatusCode} | 鏃堕棿={Elapsed}ms | 鎿嶄綔浜�={_UserName} \n 璇锋眰鍐呭={_RequestBody} \n 杩斿洖缁撴灉={_ResponseBody}";
+
+ // 鍙戝嚭璋冭瘯绾у埆浜嬩欢鑰屼笉鏄粯璁や簨浠讹紝灏嗚姹傛棩蹇楄褰曞埌:Debug鏃ュ織
+ options.GetLevel = (httpContext, elapsed, ex) =>
+ {
+ var method = httpContext.Request.Method.ToLower();
+ if (method == "options")
+ return LogEventLevel.Debug;
+ return LogEventLevel.Information;
+ };
+
+ // 灏嗗叾浠栧睘鎬ч檮鍔犲埌璇锋眰瀹屾垚浜嬩欢锛屽皢璇锋眰灞炴�ч檮鍔犲彲浠ュ湪妯℃澘涓娇鐢�
+ options.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
+ {
+ diagnosticContext.Set("_RequestPath", WebUtility.UrlDecode(httpContext.Request.Path + httpContext.Request.QueryString));
+ var token = httpContext.Request.Headers["Token"].ToString();
+ if (!string.IsNullOrEmpty(token))
+ {
+ var handler = new JwtSecurityTokenHandler();
+ var jwtToken = handler.ReadJwtToken(token);
+ var claim = jwtToken.Payload.Claims.FirstOrDefault(s => s.Type == "LoginName");
+ //foreach (var claim in jwtToken.Payload.Claims)
+ //{
+ // Console.WriteLine($"{claim.Type}: {claim.Value}");
+ //}
+ if (claim != null)
+ diagnosticContext.Set("_UserName", claim.Value);
+ else
+ diagnosticContext.Set("_UserName", "");
+ }
+ //璇锋眰body
+ var requestContent = "{}";
+ var method = httpContext.Request.Method.ToLower();
+ if (method == "post" || method == "put")
+ {
+ httpContext.Request.Body.Position = 0;
+ var requestReader = new StreamReader(httpContext.Request.Body);
+ if (requestReader.BaseStream.Length != 0)
+ requestContent = requestReader.ReadToEnd();
+ }
+ diagnosticContext.Set("_RequestBody", requestContent);
+ diagnosticContext.Set("_Service", AppDomain.CurrentDomain.FriendlyName);
+ };
+ });
+
+ return app;
+ }
+ }
+}
diff --git a/Wms/Utility/Extension/LogExtends.cs b/Wms/Utility/Extension/LogExtends.cs
new file mode 100644
index 0000000..de01c02
--- /dev/null
+++ b/Wms/Utility/Extension/LogExtends.cs
@@ -0,0 +1,75 @@
+锘縰sing Serilog.Events;
+using Serilog;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+
+namespace Wms
+{
+ public static class LogExtends
+ {
+ //const string infoPath = "Logs/Information.log";
+ //const string warnPath = "Logs/Warning.log";
+ //const string errorPath = "Logs/Error.log";
+ //const string fatalPath = "Logs/Fatal.log";
+ //const string template = "鏃堕棿: {Timestamp:yyyy-MM-dd HH:mm:ss}{NewLine}鏉ユ簮: {SourceContext}{NewLine}鍐呭: [{Level:u3}] {Message}{NewLine}{Exception}{NewLine}";
+
+ //// 鍙互灏嗘棩蹇楄緭鍑哄埌鎺у埗鍙般�佹枃浠躲�佹暟鎹簱銆丒S绛�
+ //public static void AddSerilog(this IServiceCollection c)
+ //{
+ // Log.Logger = new LoggerConfiguration()
+ // .MinimumLevel.Information()
+ // .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) // 鎺掗櫎Dotnet鑷甫鐨勬棩蹇�
+ // .Enrich.FromLogContext()
+ // .WriteTo.Console(outputTemplate: template)
+ // .WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(lev => lev.Level == LogEventLevel.Information).WriteTo.Async(congfig => congfig.File(
+ // infoPath,
+ // rollingInterval: RollingInterval.Day,
+ // fileSizeLimitBytes: 1024 * 1024 * 10, //榛樿1GB
+ // retainedFileCountLimit: 100, //淇濈暀鏈�杩戝灏戜釜鏂囦欢,榛樿31涓�
+ // rollOnFileSizeLimit: true, //瓒呰繃鏂囦欢澶у皬鏃�,鑷姩鍒涘缓鏂版枃浠�
+ // shared: true,
+ // outputTemplate: template)
+ // ))
+
+ // .WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(lev => lev.Level == LogEventLevel.Warning).WriteTo.Async(congfig => congfig.File(
+ // warnPath,
+ // rollingInterval: RollingInterval.Day,
+ // fileSizeLimitBytes: 1024 * 1024 * 10,
+ // retainedFileCountLimit: 100,
+ // rollOnFileSizeLimit: true,
+ // shared: true,
+ // outputTemplate: template)
+ // ))
+
+ // .WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(lev => lev.Level == LogEventLevel.Error).WriteTo.Async(congfig => congfig.File(
+ // errorPath,
+ // rollingInterval: RollingInterval.Day,
+ // fileSizeLimitBytes: 1024 * 1024 * 10,
+ // retainedFileCountLimit: 100,
+ // rollOnFileSizeLimit: true,
+ // shared: true,
+ // outputTemplate: template)
+ // ))
+
+ // .WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(lev => lev.Level == LogEventLevel.Fatal).WriteTo.Async(congfig => congfig.File(
+ // fatalPath,
+ // rollingInterval: RollingInterval.Day,
+ // fileSizeLimitBytes: 1024 * 1024 * 10,
+ // retainedFileCountLimit: 100,
+ // rollOnFileSizeLimit: true,
+ // shared: true,
+ // outputTemplate: template)
+ // )).CreateLogger();
+
+ // // 娉ㄥ叆鍒板鍣�
+ // c.AddLogging(opt =>
+ // {
+ // opt.ClearProviders();
+ // opt.AddSerilog(dispose: true);
+ // });
+ //}
+ }
+}
diff --git a/Wms/Utility/Extension/RequestAuditLogFilter.cs b/Wms/Utility/Extension/RequestAuditLogFilter.cs
new file mode 100644
index 0000000..26ddd49
--- /dev/null
+++ b/Wms/Utility/Extension/RequestAuditLogFilter.cs
@@ -0,0 +1,26 @@
+锘縰sing Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Filters;
+using Newtonsoft.Json;
+using Serilog;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Utility
+{
+ public class RequestAuditLogFilter : IResultFilter
+ {
+ private readonly IDiagnosticContext _diagnosticContext;
+
+ public RequestAuditLogFilter(IDiagnosticContext diagnosticContext) { _diagnosticContext = diagnosticContext; }
+
+ public void OnResultExecuted(ResultExecutedContext context)
+ {
+ var result = context.Result as ObjectResult;
+ var resultJson = JsonConvert.SerializeObject(result?.Value);
+ _diagnosticContext.Set("_ResponseBody", resultJson);
+ }
+
+ public void OnResultExecuting(ResultExecutingContext context) { }
+ }
+}
diff --git a/Wms/Utility/Extension/ServiceCollectionExtensions.cs b/Wms/Utility/Extension/ServiceCollectionExtensions.cs
new file mode 100644
index 0000000..c15adad
--- /dev/null
+++ b/Wms/Utility/Extension/ServiceCollectionExtensions.cs
@@ -0,0 +1,79 @@
+锘縰sing Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Serilog.Events;
+using Serilog;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Serilog.Sinks.SystemConsole.Themes;
+using Serilog.Filters;
+
+namespace Utility
+{
+ public static class ServiceCollectionExtensions
+ {
+ const string template = "鏃堕棿: {Timestamp:yyyy-MM-dd HH:mm:ss}{NewLine}鏉ユ簮: {SourceContext}{NewLine}鍐呭: [{Level:u3}] {Message}{NewLine}{Exception}{NewLine}";
+ /// <summary>
+ /// 娣诲姞閰嶇疆Serilog
+ /// </summary>
+ /// <param name="services"></param>
+ /// <param name="configuration"></param>
+ /// <returns></returns>
+ public static IServiceCollection AddConfigSerilog(this IServiceCollection services)
+ {
+ // 鍒涘缓Serilog璁板綍鏃ュ織
+ Log.Logger = new LoggerConfiguration()
+ .MinimumLevel.Information()
+ .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) // 鎺掗櫎Dotnet鑷甫鐨勬棩蹇�
+ //.MinimumLevel.Verbose()
+ //.MinimumLevel.Override("System", LogEventLevel.Debug)
+ //.MinimumLevel.Override("Microsoft", LogEventLevel.Debug)
+ //.MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Error)
+ //.MinimumLevel.Override("Microsoft.AspNetCore.Cors.Infrastructure.CorsService", LogEventLevel.Error)
+ //.MinimumLevel.Override("Microsoft.AspNetCore.Mvc", LogEventLevel.Error)
+ //.MinimumLevel.Override("Microsoft.AspNetCore.Hosting", LogEventLevel.Error)
+ // 鍏ㄩ儴鏃ュ織鍐欏叆鍒癈onsole
+ .WriteTo.Console()
+ .WriteTo.Async(c => c.Console(
+ theme: AnsiConsoleTheme.Literate,
+ outputTemplate: template))
+ // Information鏃ュ織鍐欏叆鍒版枃浠�
+ .WriteTo.Async(c => c.File(
+ path: "Logs/Information_.txt",
+ rollingInterval: RollingInterval.Day,
+ fileSizeLimitBytes: 1024 * 1024 * 10,
+ retainedFileCountLimit: 100,
+ outputTemplate: template,
+ restrictedToMinimumLevel: LogEventLevel.Information))
+ // Debug鏃ュ織鍐欏叆鍒版枃浠�
+ //.WriteTo.Async(c => c.File(
+ // path: "Logs/Debug.txt",
+ // rollingInterval: RollingInterval.Day,
+ // fileSizeLimitBytes: 1024 * 1024 * 10,
+ // retainedFileCountLimit: 100,
+ // outputTemplate: template,
+ // restrictedToMinimumLevel: LogEventLevel.Debug))
+ // Warning鏃ュ織鍐欏叆鍒版枃浠�
+ .WriteTo.Async(c => c.File(
+ path: "Logs/Warning_.txt",
+ rollingInterval: RollingInterval.Day,
+ fileSizeLimitBytes: 1024 * 1024 * 10,
+ retainedFileCountLimit: 100,
+ outputTemplate: template,
+ restrictedToMinimumLevel: LogEventLevel.Warning))
+ // Error鏃ュ織鍐欏叆鍒版枃浠�
+ .WriteTo.Async(c => c.File(
+ path: "Logs/Error_.txt",
+ rollingInterval: RollingInterval.Day,
+ fileSizeLimitBytes: 1024 * 1024 * 10,
+ retainedFileCountLimit: 1000,
+ outputTemplate: template,
+ restrictedToMinimumLevel: LogEventLevel.Error))
+ .CreateLogger();
+
+ services.AddSerilog();
+
+ return services;
+ }
+ }
+}
diff --git a/Wms/Utility/Filter/CustomerExceptionMiddleware.cs b/Wms/Utility/Filter/CustomerExceptionMiddleware.cs
new file mode 100644
index 0000000..f07c390
--- /dev/null
+++ b/Wms/Utility/Filter/CustomerExceptionMiddleware.cs
@@ -0,0 +1,64 @@
+锘縰sing Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using System.Threading.Tasks;
+using System;
+using System.Text.Json;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.Logging;
+using Utility.Entity;
+using Newtonsoft.Json;
+
+namespace Utility
+{
+ public class CustomerExceptionMiddleware
+ {
+ private readonly RequestDelegate _next;
+ private readonly ILogger<CustomerExceptionMiddleware> _logger;
+
+ public CustomerExceptionMiddleware(RequestDelegate next, ILogger<CustomerExceptionMiddleware> logger)
+ {
+ _next = next;
+ _logger = logger;
+ }
+
+ public async Task Invoke(HttpContext context)
+ {
+ try
+ {
+ await _next(context);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, ex.Message);
+ context.Response.ContentType = "application/json";
+ context.Response.StatusCode = StatusCodes.Status500InternalServerError;
+ var result = "绯荤粺寮傚父锛岃鑱旂郴绠$悊鍛�";
+ if (ex is AppFriendlyException)
+ result = ex.Message;
+ var apiResponse = new ApiResponse<object>(
+ code: (int)ResponseEnum.Error,
+ message: result,
+ data: result
+ );
+
+ await context.Response.WriteAsync(JsonConvert.SerializeObject(apiResponse));
+ }
+ }
+ }
+
+ /// <summary>
+ /// 闈欐�佺被
+ /// </summary>
+ public static class ExceptionMiddlewareExtension
+ {
+ /// <summary>
+ /// 闈欐�佹柟娉�
+ /// </summary>
+ /// <param name="app">瑕佽繘琛屾墿灞曠殑绫诲瀷</param>
+ public static void UseExceptionMiddleware(this IApplicationBuilder app)
+ {
+ app.UseMiddleware(typeof(CustomerExceptionMiddleware));
+ }
+ }
+}
+
diff --git a/Wms/Utility/UnitOfWork/IUnitOfWork.cs b/Wms/Utility/UnitOfWork/IUnitOfWork.cs
new file mode 100644
index 0000000..5a7abbd
--- /dev/null
+++ b/Wms/Utility/UnitOfWork/IUnitOfWork.cs
@@ -0,0 +1,38 @@
+锘縰sing Microsoft.AspNetCore.Mvc.Filters;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Utility
+{
+ public interface IUnitOfWork
+ {
+ /// <summary>
+ /// 寮�鍚伐浣滃崟鍏冨鐞�
+ /// </summary>
+ /// <param name="context"></param>
+ /// <param name="unitOfWork"></param>
+ void BeginTransaction(FilterContext context, UnitOfWorkAttribute unitOfWork);
+
+ /// <summary>
+ /// 鎻愪氦宸ヤ綔鍗曞厓澶勭悊
+ /// </summary>
+ /// <param name="resultContext"></param>
+ /// <param name="unitOfWork"></param>
+ void CommitTransaction(FilterContext resultContext, UnitOfWorkAttribute unitOfWork);
+
+ /// <summary>
+ /// 鍥炴粴宸ヤ綔鍗曞厓澶勭悊
+ /// </summary>
+ /// <param name="resultContext"></param>
+ /// <param name="unitOfWork"></param>
+ void RollbackTransaction(FilterContext resultContext, UnitOfWorkAttribute unitOfWork);
+
+ /// <summary>
+ /// 鎵ц瀹屾瘯锛堟棤璁烘垚鍔熷け璐ワ級
+ /// </summary>
+ /// <param name="context"></param>
+ /// <param name="resultContext"></param>
+ void OnCompleted(FilterContext context, FilterContext resultContext);
+ }
+}
diff --git a/Wms/Utility/UnitOfWork/UnitOfWorkAttribute.cs b/Wms/Utility/UnitOfWork/UnitOfWorkAttribute.cs
new file mode 100644
index 0000000..aefa7fb
--- /dev/null
+++ b/Wms/Utility/UnitOfWork/UnitOfWorkAttribute.cs
@@ -0,0 +1,290 @@
+锘縰sing Microsoft.AspNetCore.Mvc.Controllers;
+using Microsoft.AspNetCore.Mvc.Filters;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Reflection;
+using System.Threading.Tasks;
+using System.Transactions;
+
+namespace Utility
+{
+ /// <summary>
+ /// 宸ヤ綔鍗曞厓閰嶇疆鐗规��
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Method)]
+ public sealed class UnitOfWorkAttribute : Attribute, IAsyncActionFilter, IAsyncPageFilter, IOrderedFilter
+ {
+ /// <summary>
+ /// 纭繚浜嬪姟鍙敤
+ /// <para>姝ゆ柟娉曚负浜嗚В鍐抽潤鎬佺被鏂瑰紡鎿嶄綔鏁版嵁搴撶殑闂</para>
+ /// </summary>
+ public bool EnsureTransaction { get; set; } = false;
+
+ /// <summary>
+ /// 鏄惁浣跨敤鍒嗗竷寮忕幆澧冧簨鍔�
+ /// </summary>
+ public bool UseAmbientTransaction { get; set; } = false;
+
+ /// <summary>
+ /// 鍒嗗竷寮忕幆澧冧簨鍔¤寖鍥�
+ /// </summary>
+ /// <remarks><see cref="UseAmbientTransaction"/> 涓� true 鏈夋晥</remarks>
+ public TransactionScopeOption TransactionScope { get; set; } = TransactionScopeOption.Required;
+
+ /// <summary>
+ /// 鍒嗗竷寮忕幆澧冧簨鍔¢殧绂荤骇鍒�
+ /// </summary>
+ /// <remarks><see cref="UseAmbientTransaction"/> 涓� true 鏈夋晥</remarks>
+ public IsolationLevel TransactionIsolationLevel { get; set; } = IsolationLevel.ReadCommitted;
+
+ /// <summary>
+ /// 鍒嗗竷寮忕幆澧冧簨鍔¤秴鏃舵椂闂�
+ /// </summary>
+ /// <remarks>鍗曚綅绉�</remarks>
+ public int TransactionTimeout { get; set; } = 0;
+
+ /// <summary>
+ /// 鏀寔鍒嗗竷寮忕幆澧冧簨鍔″紓姝ユ祦
+ /// </summary>
+ /// <remarks><see cref="UseAmbientTransaction"/> 涓� true 鏈夋晥</remarks>
+ public TransactionScopeAsyncFlowOption TransactionScopeAsyncFlow { get; set; } = TransactionScopeAsyncFlowOption.Enabled;
+
+ /// <summary>
+ /// MiniProfiler 鍒嗙被鍚�
+ /// </summary>
+ private const string MiniProfilerCategory = "unitOfWork";
+
+ /// <summary>
+ /// 杩囨护鍣ㄦ帓搴�
+ /// </summary>
+ private const int FilterOrder = 9999;
+
+ /// <summary>
+ /// 鎺掑簭灞炴��
+ /// </summary>
+ public int Order => FilterOrder;
+
+ /// <summary>
+ /// 鏋勯�犲嚱鏁�
+ /// </summary>
+ public UnitOfWorkAttribute()
+ {
+ }
+
+ /// <summary>
+ /// 鏋勯�犲嚱鏁�
+ /// </summary>
+ /// <param name="ensureTransaction"></param>
+ public UnitOfWorkAttribute(bool ensureTransaction)
+ {
+ EnsureTransaction = ensureTransaction;
+ }
+
+ /// <summary>
+ /// 鎷︽埅璇锋眰
+ /// </summary>
+ /// <param name="context">鍔ㄤ綔鏂规硶涓婁笅鏂�</param>
+ /// <param name="next">涓棿浠跺鎵�</param>
+ /// <returns></returns>
+ public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
+ {
+ // 鑾峰彇鍔ㄤ綔鏂规硶鎻忚堪鍣�
+ var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
+ var method = actionDescriptor.MethodInfo;
+
+ // 鍒涘缓鍒嗗竷寮忕幆澧冧簨鍔�
+ (var transactionScope, var logger) = CreateTransactionScope(context);
+
+ try
+ {
+ // 鎵撳嵃宸ヤ綔鍗曞厓寮�濮嬫秷鎭�
+ Console.WriteLine("Beginning (Ambient)");
+ // 寮�濮嬩簨鍔�
+ BeginTransaction(context, method, out var _unitOfWork, out var unitOfWorkAttribute);
+
+ // 鑾峰彇鎵ц Action 缁撴灉
+ var resultContext = await next();
+
+ // 鎻愪氦浜嬪姟
+ CommitTransaction(context, _unitOfWork, unitOfWorkAttribute, resultContext);
+
+ // 鎻愪氦鍒嗗竷寮忕幆澧冧簨鍔�
+ if (resultContext.Exception == null)
+ {
+ transactionScope?.Complete();
+
+ // 鎵撳嵃浜嬪姟鎻愪氦娑堟伅
+ if (UseAmbientTransaction) Console.WriteLine("Completed (Ambient)");
+ }
+ else
+ {
+ // 鎵撳嵃浜嬪姟鍥炴粴娑堟伅
+ if (UseAmbientTransaction) Console.WriteLine("Rollback (Ambient)");
+
+ logger.LogError(resultContext.Exception, "Transaction Failed.");
+ }
+ }
+ catch (Exception ex)
+ {
+ logger.LogError(ex, "Transaction Failed.");
+
+ // 鎵撳嵃浜嬪姟鍥炴粴娑堟伅
+ if (UseAmbientTransaction) Console.WriteLine("Rollback (Ambient)");
+
+ throw;
+ }
+ finally
+ {
+ transactionScope?.Dispose();
+ }
+ }
+
+ /// <summary>
+ /// 妯″瀷缁戝畾鎷︽埅
+ /// </summary>
+ /// <param name="context"></param>
+ /// <returns></returns>
+ public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
+ {
+ return Task.CompletedTask;
+ }
+
+ /// <summary>
+ /// 鎷︽埅璇锋眰
+ /// </summary>
+ /// <param name="context"></param>
+ /// <param name="next"></param>
+ /// <returns></returns>
+ public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
+ {
+ // 鑾峰彇鍔ㄤ綔鏂规硶鎻忚堪鍣�
+ var method = context.HandlerMethod?.MethodInfo;
+ // 澶勭悊 Blazor Server
+ if (method == null)
+ {
+ _ = await next.Invoke();
+ return;
+ }
+
+ // 鍒涘缓鍒嗗竷寮忕幆澧冧簨鍔�
+ (var transactionScope, var logger) = CreateTransactionScope(context);
+
+ try
+ {
+ // 鎵撳嵃宸ヤ綔鍗曞厓寮�濮嬫秷鎭�
+ if (UseAmbientTransaction) Console.WriteLine("Beginning (Ambient)");
+
+ // 寮�濮嬩簨鍔�
+ BeginTransaction(context, method, out var _unitOfWork, out var unitOfWorkAttribute);
+
+ // 鑾峰彇鎵ц Action 缁撴灉
+ var resultContext = await next.Invoke();
+
+ // 鎻愪氦浜嬪姟
+ CommitTransaction(context, _unitOfWork, unitOfWorkAttribute, resultContext);
+
+ // 鎻愪氦鍒嗗竷寮忕幆澧冧簨鍔�
+ if (resultContext.Exception == null)
+ {
+ transactionScope?.Complete();
+
+ // 鎵撳嵃浜嬪姟鎻愪氦娑堟伅
+ if (UseAmbientTransaction) Console.WriteLine("Completed (Ambient)");
+ }
+ else
+ {
+ // 鎵撳嵃浜嬪姟鍥炴粴娑堟伅
+ if (UseAmbientTransaction) Console.WriteLine("Rollback (Ambient)");
+
+ logger.LogError(resultContext.Exception, "Transaction Failed.");
+ }
+ }
+ catch (Exception ex)
+ {
+ logger.LogError(ex, "Transaction Failed.");
+
+ // 鎵撳嵃浜嬪姟鍥炴粴娑堟伅
+ if (UseAmbientTransaction) Console.WriteLine("Rollback (Ambient)");
+
+ throw;
+ }
+ finally
+ {
+ transactionScope?.Dispose();
+ }
+ }
+
+ /// <summary>
+ /// 鍒涘缓鍒嗗竷寮忕幆澧冧簨鍔�
+ /// </summary>
+ /// <param name="context"></param>
+ /// <returns></returns>
+ private (TransactionScope, ILogger) CreateTransactionScope(FilterContext context)
+ {
+ // 鏄惁鍚敤鍒嗗竷寮忕幆澧冧簨鍔�
+ var transactionScope = UseAmbientTransaction
+ ? new TransactionScope(TransactionScope,
+ new TransactionOptions { IsolationLevel = TransactionIsolationLevel, Timeout = TransactionTimeout > 0 ? TimeSpan.FromSeconds(TransactionTimeout) : default }
+ , TransactionScopeAsyncFlow)
+ : default;
+
+ // 鍒涘缓鏃ュ織璁板綍鍣�
+ var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<UnitOfWorkAttribute>>();
+
+ return (transactionScope, logger);
+ }
+
+ /// <summary>
+ /// 寮�濮嬩簨鍔�
+ /// </summary>
+ /// <param name="context"></param>
+ /// <param name="method"></param>
+ /// <param name="_unitOfWork"></param>
+ /// <param name="unitOfWorkAttribute"></param>
+ private static void BeginTransaction(FilterContext context, MethodInfo method, out IUnitOfWork _unitOfWork, out UnitOfWorkAttribute unitOfWorkAttribute)
+ {
+ // 瑙f瀽宸ヤ綔鍗曞厓鏈嶅姟
+ _unitOfWork = context.HttpContext.RequestServices.GetRequiredService<IUnitOfWork>();
+
+ // 鑾峰彇宸ヤ綔鍗曞厓鐗规��
+ unitOfWorkAttribute = method.GetCustomAttribute<UnitOfWorkAttribute>();
+
+ // 璋冪敤寮�鍚簨鍔℃柟娉�
+ _unitOfWork.BeginTransaction(context, unitOfWorkAttribute);
+
+ // 鎵撳嵃宸ヤ綔鍗曞厓寮�濮嬫秷鎭�
+ if (!unitOfWorkAttribute.UseAmbientTransaction) Console.WriteLine("Beginning");
+ }
+
+ /// <summary>
+ /// 鎻愪氦浜嬪姟
+ /// </summary>
+ /// <param name="context"></param>
+ /// <param name="_unitOfWork"></param>
+ /// <param name="unitOfWorkAttribute"></param>
+ /// <param name="resultContext"></param>
+ private static void CommitTransaction(FilterContext context, IUnitOfWork _unitOfWork, UnitOfWorkAttribute unitOfWorkAttribute, FilterContext resultContext)
+ {
+ // 鑾峰彇鍔ㄦ�佺粨鏋滀笂涓嬫枃
+ dynamic dynamicResultContext = resultContext;
+
+ if (dynamicResultContext.Exception == null)
+ {
+ // 璋冪敤鎻愪氦浜嬪姟鏂规硶
+ _unitOfWork.CommitTransaction(resultContext, unitOfWorkAttribute);
+ }
+ else
+ {
+ // 璋冪敤鍥炴粴浜嬪姟鏂规硶
+ _unitOfWork.RollbackTransaction(resultContext, unitOfWorkAttribute);
+ }
+
+ // 璋冪敤鎵ц瀹屾瘯鏂规硶
+ _unitOfWork.OnCompleted(context, resultContext);
+
+ // 鎵撳嵃宸ヤ綔鍗曞厓缁撴潫娑堟伅
+ if (!unitOfWorkAttribute.UseAmbientTransaction) Console.WriteLine("Ending");
+ }
+ }
+}
diff --git a/Wms/Utility/Utility.csproj b/Wms/Utility/Utility.csproj
index d2026ba..49a3a6a 100644
--- a/Wms/Utility/Utility.csproj
+++ b/Wms/Utility/Utility.csproj
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+锘�<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
@@ -13,8 +13,18 @@
</ItemGroup>
<ItemGroup>
+ <PackageReference Include="Autofac" Version="8.0.0" />
+ <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.32" />
+ <PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
+ <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />
+ <PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
- <PackageReference Include="System.Drawing.Common" Version="5.0.3" />
+ <PackageReference Include="Serilog" Version="4.0.0" />
+ <PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
+ <PackageReference Include="Serilog.Sinks.Async" Version="2.0.0" />
+ <PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
+ <PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
+ <PackageReference Include="System.Drawing.Common" Version="6.0.0" />
<PackageReference Include="ZXing.Net" Version="0.16.7" />
</ItemGroup>
diff --git a/Wms/Wms/Controllers/BllTaskController.cs b/Wms/Wms/Controllers/BllTaskController.cs
index 3fd9e3b..9688f2d 100644
--- a/Wms/Wms/Controllers/BllTaskController.cs
+++ b/Wms/Wms/Controllers/BllTaskController.cs
@@ -7,6 +7,8 @@
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
+using Utility;
+using Utility.Extension;
using Wms.Tools;
using WMS.IBLL.IBllTaskServer;
@@ -36,6 +38,7 @@
/// <param name="model"></param>
/// <returns></returns>
[HttpPost]
+ [AllowAnonymous]
public IActionResult GetTaskSyncList(TaskSyncVm model)
{
try
diff --git a/Wms/Wms/Program.cs b/Wms/Wms/Program.cs
index ebbbefe..0c08ea0 100644
--- a/Wms/Wms/Program.cs
+++ b/Wms/Wms/Program.cs
@@ -3,6 +3,7 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
+using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -14,7 +15,18 @@
{
public static void Main(string[] args)
{
- CreateHostBuilder(args).Build().Run();
+ try
+ {
+ CreateHostBuilder(args).Build().Run();
+ }
+ catch (Exception ex)
+ {
+ Log.Fatal(ex, "*** Program Stop ***");
+ }
+ finally
+ {
+ Log.CloseAndFlush();
+ }
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
@@ -22,6 +34,7 @@
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
- }).UseServiceProviderFactory(new AutofacServiceProviderFactory());
+ }).UseServiceProviderFactory(new AutofacServiceProviderFactory())
+ .UseSerilog();
}
}
diff --git a/Wms/Wms/Startup.cs b/Wms/Wms/Startup.cs
index 93f1405..9414fe7 100644
--- a/Wms/Wms/Startup.cs
+++ b/Wms/Wms/Startup.cs
@@ -14,6 +14,12 @@
using Wms.Tools;
using WMS.Entity.Context;
using WMS.IBLL.IDataServer;
+using Serilog;
+using Autofac.Core;
+using Utility;
+using Utility.Extension;
+using Microsoft.Extensions.Options;
+using Microsoft.AspNetCore.Http;
namespace Wms
{
@@ -37,7 +43,9 @@
services.AddHostedService<DailyTaskService>(provider =>
new DailyTaskService(url,url2));
- services.AddControllers()
+ services.AddControllers(options => {
+ options.Filters.Add<RequestAuditLogFilter>();
+ })
.AddJsonOptions(options =>
{
//不使用驼峰样式的key
@@ -110,6 +118,9 @@
services.AddAutoMapper(typeof(AutoMapperProfile)); // automapper依赖
#endregion
+ //注册serilog
+ services.AddConfigSerilog();
+ services.AddScoped<ApiResponseActionFilter>();
}
public void ConfigureContainer(ContainerBuilder builder)
{
@@ -133,7 +144,12 @@
c.RoutePrefix = string.Empty;
});
}
+ //全局返回规范
+ //app.UseApiResponse();//弃用 改用Filter [ServiceFilter(typeof(ApiResponseActionFilter))]
+ app.UseExceptionMiddleware();
+ //使用Serilog记录请求日志
+ app.UseSerilogRequestLogging();
//app.UseHttpsRedirection();
app.UseRouting();
@@ -141,7 +157,6 @@
app.UseAuthentication();
app.UseAuthorization();
app.UseCors("MyCors");//跨域
-
app.UseEndpoints(endpoints =>
{
diff --git a/Wms/Wms/Wms.csproj b/Wms/Wms/Wms.csproj
index 6ea9517..63bb75b 100644
--- a/Wms/Wms/Wms.csproj
+++ b/Wms/Wms/Wms.csproj
@@ -11,18 +11,28 @@
</PropertyGroup>
<ItemGroup>
+ <Compile Remove="Logs\**" />
<Compile Remove="ModelVm\**" />
+ <Content Remove="Logs\**" />
<Content Remove="ModelVm\**" />
+ <EmbeddedResource Remove="Logs\**" />
<EmbeddedResource Remove="ModelVm\**" />
+ <None Remove="Logs\**" />
<None Remove="ModelVm\**" />
</ItemGroup>
<ItemGroup>
- <PackageReference Include="Autofac" Version="6.5.0" />
+ <PackageReference Include="Autofac" Version="8.0.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="AutoMapper" Version="12.0.1" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.32" />
+ <PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
+ <PackageReference Include="Serilog" Version="4.0.0" />
+ <PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
+ <PackageReference Include="Serilog.Sinks.Async" Version="2.0.0" />
+ <PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
+ <PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.6" />
</ItemGroup>
@@ -31,6 +41,10 @@
<ProjectReference Include="..\WMS.BLL\WMS.BLL.csproj" />
</ItemGroup>
+ <ItemGroup>
+ <Folder Include="Configuration\" />
+ </ItemGroup>
+
<ProjectExtensions><VisualStudio><UserProperties appsettings_1json__JsonSchema="" /></VisualStudio></ProjectExtensions>
--
Gitblit v1.8.0