商米-android-使用NFC讀IC卡,身份證云解和IC卡同時兼容

商米介紹地址:https://www.sunmi.com/
商米是一個提供手持PDA的一個很好的解決方案廠商,
也有其他的一些桌面設備。
其中商米提供的軟件服務中,比較特別的是 身份證云解功能。

此處重點說明一下,身份證云解功能。

以往市面上的身份證讀卡功能,都是找公安申請身份證讀卡器硬件模塊。比較貴。
商米的身份證讀卡,是利用商米的NFC功能,配合身份證云解功能來實現

單獨實現身份證讀卡,和單獨實現NFC刷IC卡,在商米提供的SDK很容易能實現
但是同時實現兼容 讀IC卡和身份證,現在的商米SDK 就兼容性做的很差。
這里主要說明一下同時兼容 讀IC卡和身份證,

1、引用jar包:implementation ‘com.sunmi:SunmiEID-SDK:1.3.16’

2、主界面上,初始化NFC,NfcUtils

package com.smk.travelpda.common.nfc;import android.app.Activity;
import android.content.Context;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.util.Log;
import android.widget.Toast;import com.smk.travelpda.common.util.RString;/*** luoyang*/public class NfcUtils {private static final String TAG = "NfcUtils";private static NfcAdapter mNfcAdapter;private NfcUtils(){}private static NfcUtils nfcUtils = null;private static boolean isOpen = false;/*** 獲取NFC的單例* @return NfcUtils*/public static NfcUtils getInstance(){if (nfcUtils == null){synchronized (NfcUtils.class){if (nfcUtils == null){nfcUtils = new NfcUtils();}}}return nfcUtils;}private  NfcListener nfcListener;public void setNfcListener(NfcListener listener){nfcListener = listener;}/*** 在onStart中檢測是否支持nfc功能* @param context 當前頁面上下文*/public void onStartNfcAdapter(Context context){//設備的NfcAdapter對象mNfcAdapter = NfcAdapter.getDefaultAdapter(context);}/*** 在onResume中開啟nfc功能* @param activity*/public void onResumeNfcAdapter(final Activity activity){if(mNfcAdapter==null){//判斷設備是否支持NFC功能RString.showDia(activity,"提醒","設備不支持NFC功能");return;}if (!mNfcAdapter.isEnabled()){//判斷設備NFC功能是否打開RString.showDia(activity,"提醒","請到系統設置中打開NFC功能!");return;}if (!isOpen) {mNfcAdapter.enableReaderMode(activity, new NfcAdapter.ReaderCallback() {@Overridepublic void onTagDiscovered(final Tag tag) {if (nfcListener != null){(activity).runOnUiThread(new Runnable() {@Overridepublic void run() {nfcListener.nfcReadHander(tag);}});}}},(NfcAdapter.FLAG_READER_NFC_A |NfcAdapter.FLAG_READER_NFC_B |NfcAdapter.FLAG_READER_NFC_F |NfcAdapter.FLAG_READER_NFC_V |NfcAdapter.FLAG_READER_NFC_BARCODE ),null);isOpen = true;}}/*** 在onPause中關閉nfc功能* @param activity*/public void onPauseNfcAdapter(Activity activity){if(mNfcAdapter!=null && mNfcAdapter.isEnabled()){if (isOpen){mNfcAdapter.disableReaderMode(activity);}isOpen = false;}}}

NFC監聽組件

package com.smk.travelpda.common.nfc;import android.nfc.Tag;/*** 自定義的NFC接口*/public interface NfcListener{/*** 用于掃到nfc后的后續操作*/void nfcReadHander(Tag tag);}

設置商米SDK的回調方法

package com.smk.travelpda.common.yidcard;import android.util.Log;import com.smk.travelpda.MainActivity;
import com.smk.travelpda.common.util.RJson;
import com.sunmi.eidlibrary.EidCall;
import com.sunmi.eidlibrary.EidConstants;
import com.sunmi.eidlibrary.EidSDK;import java.util.Map;//云解身份證讀卡回調方法
public class EidCardReadCall implements EidCall {private String TAG = "IdCardHander";private EidcardListener eidcardListener;private String eventType;public  EidCardReadCall(EidcardListener eidcardListener,String eventType){this.eidcardListener = eidcardListener;this.eventType = eventType;}@Overridepublic void onCallData(int code, String msg) {if(this.eventType.endsWith(EidHanderEo.EID_INIT)){initEidHanderCall(code, msg);}else if(this.eventType.endsWith(EidHanderEo.Eid_READY_NFC)){readerForNfc(code, msg);} else if (this.eventType.endsWith(EidHanderEo.GETIDCARDINFO)) {getIDCardInfo(code, msg);}}public void initEidHanderCall(int i, String s){EidHanderEo inttEo = new EidHanderEo(this.eventType);inttEo.setEventCode(i);switch (i) {case EidConstants.EID_INIT_SUCCESS:inttEo.setSucces(true);break;default:inttEo.setSucces(false);inttEo.setMsg(s);break;}eidcardListener.handEidEvent(inttEo);}public void getIDCardInfo(int i, String s) {EidHanderEo eo = new EidHanderEo(this.eventType);eo.setEventCode(i);if (i == EidConstants.DECODE_SUCCESS) {eo.setSucces(true);eo.setCardType("sfz");try{Map<String,Object> sfzMap = RJson.parseJson2Map(s);String idnum = (String)((Map<String,Object>)sfzMap.get("base_info")).get("idnum");eo.setCardId(idnum);}catch (Exception e){eo.setSucces(false);eo.setMsg("身份證解析失敗,請重試");}} else {//解碼失敗,code 為錯誤嗎,data為錯誤原因// typetext.setText("解析失敗:code:"+i);//typetext.setText("解析失敗:data:"+s);eo.setSucces(false);eo.setMsg(s);}eidcardListener.handEidEvent(eo);}public void readerForNfc(int code, String msg) {System.out.println("code:" + code + ":msg:" + msg);EidHanderEo eidHanderEo = new EidHanderEo(this.eventType);eidHanderEo.setEventCode(code);switch (code) {case  EidConstants.EID_INIT_SUCCESS:eidHanderEo.setSucces(true);break;case EidConstants.ERR_NFC_NOT_SUPPORT:// 該機器不支持NFC功能,無法使用SDKeidHanderEo.setSucces(false);eidHanderEo.setMsg("機器不支持NFC");break;case EidConstants.ERR_NETWORK_NOT_CONNECTED:eidHanderEo.setSucces(false);eidHanderEo.setMsg("網絡未連接,請聯網后重試");// *** 異常處理: 連接網絡后,需要重新調用 startCheckCard 方法 (手動觸發,非自動)***break;case EidConstants.ERR_NFC_CLOSED:eidHanderEo.setSucces(false);eidHanderEo.setMsg("NFC 未打開,打開后重試 ");//  *** 異常處理: 打開NFC后,需要重新調用 startCheckCard 方法 (手動觸發,非自動)***break;case EidConstants.READ_CARD_READY://Step 3 讀卡準備完成 -> 業務方可以引導用戶開始進行刷卡操作eidHanderEo.setSucces(true);eidHanderEo.setMsg("SDK準備完成,請刷卡");break;case EidConstants.READ_CARD_START://Step 4 讀卡中 -> 業務方可以提醒用戶"讀卡中,請勿移動卡片"eidHanderEo.setSucces(true);eidHanderEo.setMsg("開始讀卡,請勿移動");break;case EidConstants.READ_CARD_SUCCESS://Step 5 讀卡成功 -> 返回的msg為reqId,通過 reqId 業務方走云對云方案獲取身份證信息//注:如不需要循環讀卡,可在此處調用stopCheckCard方法eidHanderEo.setSucces(true);eidHanderEo.setMsg("讀卡成功");eidHanderEo.setCardId(msg);//設置讀取的身份證IDbreak;case EidConstants.READ_CARD_FAILED://*** 異常處理: 讀卡失敗,請重新讀卡 ***eidHanderEo.setSucces(false);eidHanderEo.setMsg("讀卡失敗,請重試"+ msg);break;case EidConstants.ERR_ACCOUNT_EXCEPTION://*** 異常處理: 讀卡失敗,請重新讀卡 ***eidHanderEo.setSucces(false);eidHanderEo.setMsg("該設備未開通身份證讀卡權限!");break;default://*** 異常處理: 其他失敗 - code為錯誤碼,msg為詳細錯誤原因 需要重新調用 startCheckCard 方法 (手動觸發,非自動)***eidHanderEo.setSucces(false);eidHanderEo.setMsg("讀卡異常,請重試code:"+code+ msg);break;}eidcardListener.handEidEvent(eidHanderEo);}}

商米SDK的監聽方法

package com.smk.travelpda.common.yidcard;/*** 處理EID的事件*/
public interface EidcardListener {public void handEidEvent(EidHanderEo eidHanderEo);
}

主界面

package com.smk.travelpda;import android.content.IntentFilter;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.nfc.tech.MifareClassic;
import android.nfc.tech.NfcA;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;import com.smk.travelpda.common.macinfo.MacInfoHander;
import com.smk.travelpda.common.nfc.NfcListener;
import com.smk.travelpda.common.nfc.NfcReadHander;
import com.smk.travelpda.common.nfc.NfcUtils;
import com.smk.travelpda.common.scan.ScanEventEo;
import com.smk.travelpda.common.scan.ScanListener;
import com.smk.travelpda.common.util.BusinessException;
import com.smk.travelpda.common.util.RString;
import com.smk.travelpda.common.util.VersionCheckUtil;
import com.smk.travelpda.common.yidcard.EidCardReadCall;
import com.smk.travelpda.common.yidcard.EidHanderEo;
import com.smk.travelpda.common.scan.ScanMachinReceive;
import com.smk.travelpda.common.yidcard.EidcardListener;
import com.sunmi.eidlibrary.EidCall;
import com.sunmi.eidlibrary.EidConstants;
import com.sunmi.eidlibrary.EidReader;
import com.sunmi.eidlibrary.EidSDK;/*** luoyang 2024-04-17*/
public class MainActivity extends AppCompatActivity  implements NfcListener, ScanListener, EidcardListener {public final static String APP_ID = "商米的APPID";public final static String APP_KEY = "商米的APPKEY";private   TextView datatext;//綁定的歸屬方,景區名稱private   TextView tourname;private   TextView sntext;private TextView visionnum;private NfcUtils nfcUtils = NfcUtils.getInstance();private EidReader eid;private ScanMachinReceive myReceiver ;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});datatext = findViewById(R.id.data);tourname = findViewById(R.id.tourname);sntext = findViewById(R.id.sntext);visionnum = findViewById(R.id.visionnum);sntext.setText("序列號:"+MacInfoHander.getSN());visionnum.setText("V1.0.0");tourname.setText("景區");//初始化NFC讀卡器nfcUtils.setNfcListener(this);//商米的掃碼監聽initScanReceiveLislen();//初始話監聽//初始化身份證讀卡initCardEidSdk();}@Overrideprotected void onDestroy() {super.onDestroy();// 注銷掃碼接收廣播unregisterReceiver(myReceiver);//注銷讀卡服務EidSDK.destroy();}@Overrideprotected void onStart() {super.onStart();System.out.println("onStart................................");nfcUtils.onStartNfcAdapter(this);       //初始化Nfc對象}@Overrideprotected void onResume() {super.onResume();System.out.println("onResume................................");nfcUtils.onResumeNfcAdapter(this);      //activity激活的時候開始掃描datatext.append("NFC初始化成功\n");}@Overrideprotected void onPause() {super.onPause();System.out.println("onPause................................");nfcUtils.onPauseNfcAdapter(this);       //activity切換到后臺的時候停止掃描}//讀NFC卡后的返回事件@Overridepublic void nfcReadHander(Tag tag) {datatext.setText("start new card");String tl[] = tag.getTechList();//POS機器,只支持2代和3代卡,身份證,其他證件不支持try {boolean isHandCard = false;for (String s:tl) {if(s.equals("android.nfc.tech.MifareClassic")){//String data = NfcReadHander.readMifareTag(tag,MifareClassic.get(tag));datatext.setText(RString.byteToString(tag.getId()));isHandCard = true;break;//旅游卡PDA 無需支持M1卡類型}else if(s.equals("android.nfc.tech.IsoDep")){String cardType = "smk";//讀取IC卡String cardId = NfcReadHander.readIsoDepTag(tag, IsoDep.get(tag));System.out.println("cardId"+cardId);datatext.setText(cardId);isHandCard = true;break;}else  if(s.equals("android.nfc.tech.NfcB")){//跳轉到身份證云解讀取,NFCB為身份證模塊,此處調用身份證云解,其他的為IC卡讀取eid.nfcReadCard(tag);isHandCard = true;break;}}if(!isHandCard){throw new BusinessException("請刷IC卡或身份證");}}catch (BusinessException e){//捕獲自定義異常datatext.setText(e.getMessage());}}/*** 實現掃碼事件* @return*/@Overridepublic void scanEventHander(ScanEventEo eventEo) {String  eventType = eventEo.getEventType();if(eventType.equals(ScanEventEo.SCAN_START)){//typetext.setText("開始掃碼");datatext.setText("開始掃碼");} else if (eventType.equals(ScanEventEo.SCAN_RECEVIE)) {//typetext.setText("掃碼成功");datatext.setText("");datatext.append(eventEo.isAllow()+":"+ eventEo.getQrData());} else if (eventType.equals(ScanEventEo.SCAN_END)) {datatext.setText("掃碼結束");}}//實現云解身份證的事件@Overridepublic void handEidEvent(EidHanderEo eidHanderEo) {String eventType = eidHanderEo.getEventType();if(eventType.equals(EidHanderEo.EID_INIT)){//typetext.setText("init success");//init初始化監聽時間if(eidHanderEo.isSucces() &&  eidHanderEo.getEventCode() == EidConstants.EID_INIT_SUCCESS){eid = EidSDK.getEidReaderForNfc(3, new EidCardReadCall(this,EidHanderEo.Eid_READY_NFC));}else {//其他都是失敗的,RString.showDia(this,"身份證模塊初始化失敗",eidHanderEo.getMsg());}} else if (eventType.equals(EidHanderEo.Eid_READY_NFC)) {// typetext.setText("Eid_READY_NFC");//讀卡的回調if(eidHanderEo.isSucces() &&  eidHanderEo.getEventCode() == EidConstants.READ_CARD_SUCCESS){datatext.setText(eidHanderEo.getCardId());//讀卡成功的回調EidSDK.getIDCardInfo(eidHanderEo.getCardId(), MainActivity.APP_KEY, new EidCardReadCall(this,EidHanderEo.GETIDCARDINFO));}else if(!eidHanderEo.isSucces()){RString.showDia(this,"提醒",eidHanderEo.getMsg());}else{//有些成功,是否需要干預流程處理,不需要就不做任何事情//datatext.setText(eidHanderEo.getMsg());datatext.append("身份證模塊初始化成功");}} else if (eventType.equals(EidHanderEo.GETIDCARDINFO)) {//typetext.setText("GETIDCARDINFO");//調用if(eidHanderEo.isSucces() && eidHanderEo.getEventCode() == EidConstants.DECODE_SUCCESS){//解析成功datatext.setText("");datatext.append(eidHanderEo.getCardId());}else {RString.showDia(this,"提醒",eidHanderEo.getMsg());}}}private  void initScanReceiveLislen(){myReceiver = new ScanMachinReceive(this);IntentFilter intentFilter = new IntentFilter();intentFilter.addAction(ScanEventEo.SCAN_RECEVIE); // 監聽網絡變化廣播intentFilter.addAction(ScanEventEo.SCAN_START); // 監聽網絡變化廣播intentFilter.addAction(ScanEventEo.SCAN_END); // 監聽網絡變化廣播// 注冊廣播  只從原生獲取,不從外部APP獲取registerReceiver(myReceiver, intentFilter);datatext.append("掃碼初始化成功\n");}private  void initCardEidSdk(){EidSDK.init(this, APP_ID, new EidCardReadCall(this,EidHanderEo.EID_INIT));// EidSDK.startCheckCard不要使用這個API}public  void visionClick(View view){//startActivity(VersionCheckUtil.check(false));}
}

這個兼容身份證和IC讀卡的關鍵點在于,不要使用SDK里面 EidSDK.startCheckCard();

1、EidSDK.init方法,
2、在EidSDK.init的成功回調函數中,獲取NFC讀卡的
EidReader eid = EidSDK.getEidReaderForNfc(3, new EidCardReadCall(this,EidHanderEo.Eid_READY_NFC));
3、初始化成EidReader , 此時刷卡,在NFC讀卡器檢測到NFCB 的tag類型之后,再使用EidReader 去處理身份證讀卡的功能 eid.nfcReadCard(tag); 此處會在第二部的回調函數中 得到讀取身份證的結果。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/10285.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/10285.shtml
英文地址,請注明出處:http://en.pswp.cn/web/10285.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Vue學習JSON.stringify()將Object類型轉換成String類型

Vue學習JSON.stringify&#xff08;&#xff09;將Object類型轉換成String類型 一、前言1、基本用法2、復雜對象轉換3、過濾器函數4、序列化函數 一、前言 JSON.stringify() 是一個 JavaScript 函數&#xff0c;用于將 JavaScript 值轉換為 JSON 字符串。它接受一個 JavaScrip…

深入探索MySQL視圖

前言 在數據庫的世界里&#xff0c;MySQL視圖作為數據抽象的一把利劍&#xff0c;為我們提供了一種靈活而高效的方式來管理和查詢數據。它不僅能夠簡化復雜的查詢邏輯&#xff0c;還能在不改動底層數據結構的前提下&#xff0c;實現數據的定制化展示與訪問控制。本文旨在深入解…

【小紅書采集工具】根據搜索關鍵詞批量采集小紅書筆記,含筆記正文、筆記鏈接、發布時間、轉評贊藏等

一、背景介紹 1.1 爬取目標 熟悉我的小伙伴都了解&#xff0c;我之前開發過2款軟件&#xff1a; 【GUI軟件】小紅書搜索結果批量采集&#xff0c;支持多個關鍵詞同時抓取&#xff01; 【GUI軟件】小紅書詳情數據批量采集&#xff0c;含筆記內容、轉評贊藏等&#xff0c;支持…

【C++】string類的使用①(默認成員函數 || 迭代器接口begin,end,rbegin和rend)

&#x1f525;個人主頁&#xff1a; Forcible Bug Maker &#x1f525;專欄&#xff1a; STL || C 目錄 前言&#x1f308;關于string類&#x1f308;string類的成員函數&#x1f525;默認成員函數string類對象的構造(constructor)string類對象的析構string類對象的賦值運算符…

NPOI生成word浮動圖標

1、NPOI版本2.7.0, net框架4.8 2、安裝OpenXMLSDKToolV25.msi 3、先創建一個word文檔&#xff0c;并設置圖片為浮于文字之上 4、OpenXML顯示的結果 5、實際代碼如下&#xff1a; public class GenerateWordDemo {public GenerateWordDemo(){}//https://blog.fileformat.co…

js由那三部分組成

JavaScript 主要由三部分組成&#xff1a;ECMAScript、DOM&#xff08;文檔對象模型&#xff09;和 BOM&#xff08;瀏覽器對象模型&#xff09;。 1、ECMAScript ECMAScript 是 JavaScript 的核心&#xff0c;描述了語言的基本語法&#xff08;變量、函數、條件語句、循環、…

前端筆記-day03

文章目錄 01-初始CSS02-CSS引入方式03-標簽選擇器04-類選擇器05-id選擇器06-通配符選擇器07-畫盒子08-字體大小09-文字粗細10-字體傾斜11-行高12-行高垂直居中13-字體族14-font復合屬性15-文本縮進16-文本對齊方式17-圖片對齊方式18-文本修飾線19-文字顏色20-調試工具21-綜合案…

Dual Aggregation Transformer for Image Super-Resolution論文總結

題目&#xff1a;Dual Aggregation Transformer&#xff08;雙聚合Transformer&#xff09; for Image Super-Resolution&#xff08;圖像超分辨&#xff09; 論文&#xff08;ICCV&#xff09;&#xff1a;Chen_Dual_Aggregation_Transformer_for_Image_Super-Resolution_ICCV…

IM 是什么?

在當今數字化的時代&#xff0c;即時通訊&#xff08;IM&#xff09;已經滲透到人們的日常生活和企業的工作環境中。IM技術的快速i發展為人們提供了一種高效、便捷的溝通方式&#xff0c;不僅推動了社會的信息化進程&#xff0c;也提升了企業的協同效率和競爭力。 作為企業級I…

【GD32】01-GPIO通用輸入輸出

GD32 閑話說在前頭 這里又開一個系列啦。 原因就是之前買了立創開發板的9.9的GD32E230C8T6的板子&#xff0c;買都買了就跟著立創開發板學習一下&#xff08;屬于是一次性支持了兩個國產品牌了&#xff0c;立創和兆易創新&#xff09;。并且我還買了GD32F407VET6的板子&…

資金流分析下的企業供貨關系強度模型

圖技術 利用neo4j、networkx、dgl、python做圖分析挖掘 【1】最短路徑算法dijkstra 【2】基于networkx的隱性集團關系識別模型 【3】基于Neo4j的擔保社群型態分析挖掘 【4】基于python求有向無環圖中target到其他節點全路徑 【5】有向圖中任意兩點的路徑 【6】圖基礎入門 【7】…

項目管理中控制質量的工具與技術

項目管理中控制質量的工具與技術 控制質量的工具與技術包括多種方法&#xff0c;旨在確保產品或服務達到既定的質量標準。關于具體的工具格式和樣式&#xff0c;以下是一些示例&#xff1a; 統計技術&#xff1a; 這是一種將質量控制要素的數據轉化為實際控制手段的技術。通…

Visual Studio和Visual Studio Code適用于哪些編程語言

Visual Studio和Visual Studio Code都適用于多種編程語言&#xff0c;它們的適用編程語言如下&#xff1a; Visual Studio適用于&#xff1a; C#Visual Basic .NETF#CJavaScriptTypeScriptPythonHTML/CSSJava&#xff08;通過插件支持&#xff09; Visual Studio Code適用于…

Jtti:哪些方法可以降低美國CN2服務器的延遲?

降低美國CN2服務器的延遲可以采取多種方法&#xff0c;以下是一些常用的方法&#xff1a; 1.選擇優質的網絡提供商和服務商&#xff1a;選擇具有高質量網絡和優質服務的網絡提供商和服務商是降低延遲的關鍵。確保您選擇的網絡提供商具有可靠的基礎設施和優質的網絡連接&#xf…

C++:關于圓形魚眼半全景圖轉為等距圓柱投影圖

C&#xff1a;空間坐標映射到球面坐標/全景圖_如何將球體坐標映射到球面uv-CSDN博客 C&#xff1a;關于360全景圖像和立方體6面全景圖像的相互轉換_彩色全景拆解正方體6個面-CSDN博客 之前記錄了立方體和360全景之間的轉換&#xff0c;這次記錄下魚眼圖與360全景圖之間的轉換…

C++ STL的鎖介紹

在 C Standard Template Library (STL) 中&#xff0c;有幾個鎖的實現&#xff0c;這些都位于 <mutex> 頭文件。以下是一些常見的鎖及其功能&#xff1a; std::mutex&#xff1a;最基本的互斥鎖&#xff0c;不可遞歸使用。該鎖提供了獨占的非公平鎖定能力。 std::mutex…

處理瀏覽器緩存問題

處理瀏覽器緩存問題 main.js router.onError((error) > {hasRefreshed false;console.log("異常" error.message);let ind0 error.message.indexOf(Loading chunk chunk-)let ind2 error.message.indexOf(failed.)if(ind0 ! -1 && ind2 !-1){console.…

spring-boot-starter-validation校驗框架

介紹 Spring Boot Starter Validation是一個Spring Boot模塊&#xff0c;用于簡化應用程序中的驗證功能。它包含以下依賴&#xff1a; Hibernate Validator&#xff1a;Hibernate Validator是JavaBean Validation&#xff08;JSR 380&#xff09;規范的參考實現&#xff0c;提…

信創應用軟件之辦公流版簽

信創應用軟件之辦公流版簽 文章目錄 信創應用軟件之辦公流版簽概述流式文件版式文件電子簽章廠商金山辦公永中-永中Office中標-中標普華Office福昕科技e簽寶法大大 概述 辦公流版簽軟件主要包括辦公中常用到的流式軟件、版式軟件以及電子簽章。 版式文件和流式文件都是文書類…

軟件體系結構總結

文章目錄 一、軟件體系結構概述1.1 基本概念1.1.1 背景1.1.2 定義1.1.3 系統1.1.3.1 定義1.1.3.2 特性1.1.3.3 系統的體系結構 1.1.4 軟件設計的層次性1.1.5 體系結構的類別&#xff08;類型&#xff09;1.1.6 重要性&#xff08;意義&#xff09; 1.2 模塊及其設計1.2.1 定義1…