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