From ddaefab76f05cc7908fd9a7e83c7730af95ff6e0 Mon Sep 17 00:00:00 2001 From: surenjun Date: Wed, 31 Jul 2024 13:47:40 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E7=A7=91=E7=9B=AE=E4=B8=89?= =?UTF-8?q?=E8=AF=84=E5=88=A4=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- entry/src/main/cpp/BUILD.gn | 77 +-- .../src/main/cpp/bin/extract_h_cpp_files.txt | 53 +- .../cpp/bin/test_data/test-real-exam.json | 1 + entry/src/main/cpp/sdk/api/include/JudgeSdk.h | 6 +- .../src/main/cpp/sdk/api/jni/JNIApiBridge.cpp | 4 +- entry/src/main/cpp/sdk/api/jni/JNIApiBridge.h | 2 +- .../main/cpp/sdk/api/jni/JNIMethodTable.cpp | 2 +- entry/src/main/cpp/sdk/api/js/JSApiBridge.cpp | 7 +- .../main/cpp/sdk/api/platform/JudgeSdk.cpp | 6 +- entry/src/main/cpp/sdk/common/TThread.h | 2 +- entry/src/main/cpp/sdk/exam/ExamCarSub2.cpp | 32 +- entry/src/main/cpp/sdk/exam/ExamCarSub2.h | 6 +- entry/src/main/cpp/sdk/exam/ExamCarSub3.cpp | 205 ++++--- entry/src/main/cpp/sdk/exam/ExamCarSub3.h | 63 +- entry/src/main/cpp/sdk/exam/ExamDatagram.cpp | 7 + entry/src/main/cpp/sdk/exam/ExamDatagram.h | 3 +- entry/src/main/cpp/sdk/exam/ExamSensor.cpp | 74 ++- entry/src/main/cpp/sdk/exam/ExamSensor.h | 1 + entry/src/main/cpp/sdk/exam/ExamService.cpp | 6 +- entry/src/main/cpp/sdk/exam/ExamService.h | 2 +- entry/src/main/cpp/sdk/exam/IExamCar.cpp | 56 +- entry/src/main/cpp/sdk/exam/IExamCar.h | 14 +- .../src/main/cpp/sdk/exam/IExamCarAbstract.h | 2 +- entry/src/main/cpp/sdk/exam/IExamInterface.h | 2 +- entry/src/main/cpp/sdk/judge/HJudgeItem.h | 19 +- .../cpp/sdk/judge/sub2/ISub2JudgeWrap.cpp | 3 +- .../main/cpp/sdk/judge/sub3/ISub3JudgeWrap.h | 2 +- .../cpp/sdk/judge/sub3/Sub3Judge01Sczb.cpp | 2 +- .../cpp/sdk/judge/sub3/Sub3Judge02Qbxx.cpp | 195 +++++- .../main/cpp/sdk/judge/sub3/Sub3Judge02Qbxx.h | 8 +- .../cpp/sdk/judge/sub3/Sub3Judge10Ccxx.cpp | 4 +- .../cpp/sdk/judge/sub3/Sub3Judge20Comm.cpp | 76 +-- .../main/cpp/sdk/judge/sub3/Sub3Judge20Comm.h | 20 +- .../cpp/sdk/judge/sub3/Sub3Judge41Mndg.cpp | 173 +++--- .../main/cpp/sdk/judge/sub3/Sub3Judge41Mndg.h | 6 + entry/src/main/cpp/sdk/parser/XParser.cpp | 33 + entry/src/main/cpp/sdk/track/TrackReader.cpp | 2 +- entry/src/main/cpp/sdk/utility/HBean.h | 34 +- entry/src/main/cpp/sdk/utility/HTypes.h | 45 +- .../main/cpp/toolkit/replay/ReplayWrapper.cpp | 2 - entry/src/main/cpp/toolkit/ui/MainWindow.cpp | 27 +- entry/src/main/ets/api/judge.ts | 120 ++-- entry/src/main/ets/api/judgeNew.ts | 194 ++++++ entry/src/main/ets/api/userInfo.ts | 1 + entry/src/main/ets/common/constants/USER.ts | 4 +- .../ets/common/service/terminalService.ts | 3 + entry/src/main/ets/common/utils/request.ts | 37 +- .../src/main/ets/entryability/EntryAbility.ts | 4 +- entry/src/main/ets/mock/SignDisplay.ets | 22 +- entry/src/main/ets/model/SignDisplay.ets | 2 +- entry/src/main/ets/pages/Judge.ets | 214 ++++--- entry/src/main/ets/pages/TerminalInfos.ets | 2 +- entry/src/main/ets/pages/UserInfo.ets | 350 +++++++---- .../ets/pages/compontents/SignDisplayCom.ets | 50 +- .../judge/BoardPrePareSetPopup.ets | 320 ++++++++-- .../compontents/judge/DeductionPopup.ets | 7 +- .../ets/pages/compontents/judge/RealTime.ets | 78 ++- .../src/main/ets/pages/judgeSDK/api/index.ts | 9 +- .../main/ets/pages/judgeSDK/api/judgeSDK.d.ts | 236 ++++--- entry/src/main/ets/pages/judgeSDK/judge.ts | 576 ++++++++++++------ .../ets/pages/judgeSDK/utils/fileModel.ts | 15 +- .../ets/pages/judgeSDK/utils/filePhoto.ts | 66 +- .../ets/pages/judgeSDK/utils/judgeCommon.ts | 45 +- .../ets/pages/judgeSDK/utils/judgeConfig.ts | 14 +- .../ets/pages/judgeSDK/utils/judgeTask.ts | 55 +- .../ets/pages/judgeSDK/utils/judgeTask_BAK.ts | 58 ++ .../judgeSDK/utils/voiceAnnouncements.ts | 63 +- .../rawfile/judge/km3/会车_green.png | Bin 0 -> 8609 bytes .../resources/rawfile/judge/km3/会车_red.png | Bin 0 -> 8440 bytes .../rawfile/judge/km3/停车_green.png | Bin 0 -> 7462 bytes .../resources/rawfile/judge/km3/停车_red.png | Bin 0 -> 7248 bytes .../rawfile/judge/km3/变道_green.png | Bin 0 -> 8239 bytes .../resources/rawfile/judge/km3/变道_red.png | Bin 0 -> 8113 bytes .../rawfile/judge/km3/掉头_green.png | Bin 0 -> 8737 bytes .../resources/rawfile/judge/km3/掉头_red.png | Bin 0 -> 8531 bytes .../rawfile/judge/km3/直线_green.png | Bin 0 -> 8774 bytes .../resources/rawfile/judge/km3/直线_red.png | Bin 0 -> 8525 bytes .../rawfile/judge/km3/超车_green.png | Bin 0 -> 8533 bytes .../resources/rawfile/judge/km3/超车_red.png | Bin 0 -> 8387 bytes .../rawfile/judge/km3/路口_green.png | Bin 0 -> 7456 bytes .../resources/rawfile/judge/km3/路口_red.png | Bin 0 -> 7170 bytes .../main/resources/rawfile/voice/405002.mp3 | Bin 13392 -> 46520 bytes .../main/resources/rawfile/voice/empty.mp3 | Bin 0 -> 4595 bytes .../src/main/resources/rawfile/voice/关门.mp3 | Bin 0 -> 66676 bytes .../src/main/resources/rawfile/voice/熄火.mp3 | Bin 0 -> 29358 bytes 85 files changed, 2627 insertions(+), 1202 deletions(-) create mode 100644 entry/src/main/ets/api/judgeNew.ts create mode 100644 entry/src/main/ets/pages/judgeSDK/utils/judgeTask_BAK.ts create mode 100644 entry/src/main/resources/rawfile/judge/km3/会车_green.png create mode 100644 entry/src/main/resources/rawfile/judge/km3/会车_red.png create mode 100644 entry/src/main/resources/rawfile/judge/km3/停车_green.png create mode 100644 entry/src/main/resources/rawfile/judge/km3/停车_red.png create mode 100644 entry/src/main/resources/rawfile/judge/km3/变道_green.png create mode 100644 entry/src/main/resources/rawfile/judge/km3/变道_red.png create mode 100644 entry/src/main/resources/rawfile/judge/km3/掉头_green.png create mode 100644 entry/src/main/resources/rawfile/judge/km3/掉头_red.png create mode 100644 entry/src/main/resources/rawfile/judge/km3/直线_green.png create mode 100644 entry/src/main/resources/rawfile/judge/km3/直线_red.png create mode 100644 entry/src/main/resources/rawfile/judge/km3/超车_green.png create mode 100644 entry/src/main/resources/rawfile/judge/km3/超车_red.png create mode 100644 entry/src/main/resources/rawfile/judge/km3/路口_green.png create mode 100644 entry/src/main/resources/rawfile/judge/km3/路口_red.png create mode 100644 entry/src/main/resources/rawfile/voice/empty.mp3 create mode 100644 entry/src/main/resources/rawfile/voice/关门.mp3 create mode 100644 entry/src/main/resources/rawfile/voice/熄火.mp3 diff --git a/entry/src/main/cpp/BUILD.gn b/entry/src/main/cpp/BUILD.gn index 5e30cdf1..0c6ada09 100644 --- a/entry/src/main/cpp/BUILD.gn +++ b/entry/src/main/cpp/BUILD.gn @@ -1,4 +1,4 @@ -# FFmpeg build +# judge library build import("//build/ohos.gni") @@ -14,24 +14,21 @@ ohos_source_set("judge_dynamic") { "sdk/api/js/JSTypedef.cpp", "sdk/api/platform/JudgeApiFactory.cpp", "sdk/api/platform/JudgeSdk.cpp", - "sdk/common/CleverHelper.cpp", + "sdk/common/CostTimeHelper.cpp", "sdk/common/CryptoAlgorithm.cpp", - "sdk/common/HSystem.cpp", - "sdk/common/HVersion.cpp", "sdk/common/Loggerxx.cpp", + "sdk/common/ProfilerHelper.cpp", + "sdk/common/TAssert.cpp", "sdk/common/TQueue.cpp", "sdk/common/TimerPool.cpp", "sdk/common/Tools.cpp", - "sdk/database/IDBTables.cpp", "sdk/database/carinfo/CarInfoTable.cpp", - "sdk/database/iteminfo/ItemInfoTable.cpp", - "sdk/database/mappoint/MapPointItemTable.cpp", - "sdk/database/mappoint/MapPointTable.cpp", + "sdk/database/mark/MarkItemRule.cpp", "sdk/database/mark/MarkTable.cpp", "sdk/database/sysparm/SysParmTable.cpp", "sdk/database/sysset/SysSetTable.cpp", - "sdk/exam/ExamCarSub2.cpp", - "sdk/exam/ExamCarSub3.cpp", + "sdk/database/sysset/XSysSet.cpp", + "sdk/exam/ExamCar.cpp", "sdk/exam/ExamDatagram.cpp", "sdk/exam/ExamHistory.cpp", "sdk/exam/ExamSensor.cpp", @@ -42,55 +39,29 @@ ohos_source_set("judge_dynamic") { "sdk/graphic/IGraphicAbstract.cpp", "sdk/judge/IJudgeBrokerInterface.cpp", "sdk/judge/IJudgeItem.cpp", - "sdk/judge/sub2/ISub2JudgeItem.cpp", - "sdk/judge/sub2/ISub2JudgeWrap.cpp", - "sdk/judge/sub2/Sub2Judge00Dcrk.cpp", - "sdk/judge/sub2/Sub2Judge02Pdqb.cpp", - "sdk/judge/sub2/Sub2Judge03Cftc.cpp", - "sdk/judge/sub2/Sub2Judge05Qxxs.cpp", - "sdk/judge/sub2/Sub2Judge06Zjzw.cpp", - "sdk/judge/sub2/Sub2Judge20Comm.cpp", - "sdk/judge/sub3/ISub3JudgeItem.cpp", - "sdk/judge/sub3/ISub3JudgeWrap.cpp", - "sdk/judge/sub3/Sub3Judge01Sczb.cpp", - "sdk/judge/sub3/Sub3Judge02Qbxx.cpp", - "sdk/judge/sub3/Sub3Judge03Zxxs.cpp", - "sdk/judge/sub3/Sub3Judge04Bgcd.cpp", - "sdk/judge/sub3/Sub3Judge05Lkzx.cpp", - "sdk/judge/sub3/Sub3Judge06Rxhd.cpp", - "sdk/judge/sub3/Sub3Judge07Xxqy.cpp", - "sdk/judge/sub3/Sub3Judge08Gjzt.cpp", - "sdk/judge/sub3/Sub3Judge09Hcxx.cpp", - "sdk/judge/sub3/Sub3Judge10Ccxx.cpp", - "sdk/judge/sub3/Sub3Judge11Kbtc.cpp", - "sdk/judge/sub3/Sub3Judge12Dtxx.cpp", - "sdk/judge/sub3/Sub3Judge12Lkdt.cpp", - "sdk/judge/sub3/Sub3Judge12Ptdt.cpp", - "sdk/judge/sub3/Sub3Judge13Yjxs.cpp", - "sdk/judge/sub3/Sub3Judge14Jjdw.cpp", - "sdk/judge/sub3/Sub3Judge15Lkzz.cpp", - "sdk/judge/sub3/Sub3Judge16Lkyz.cpp", - "sdk/judge/sub3/Sub3Judge20Comm.cpp", - "sdk/judge/sub3/Sub3Judge41Mndg.cpp", + "sdk/judge/JudgeItemFactory.cpp", + "sdk/judge/sub2/ISub2Judge.cpp", + "sdk/judge/sub2/Sub2JudgeCftc.cpp", + "sdk/judge/sub2/Sub2JudgeComm.cpp", + "sdk/judge/sub2/Sub2JudgeDcrk.cpp", + "sdk/judge/sub2/Sub2JudgePdqb.cpp", + "sdk/judge/sub2/Sub2JudgeQxxs.cpp", + "sdk/judge/sub2/Sub2JudgeZjzw.cpp", + "sdk/judge/sub3/ISub3Judge.cpp", "sdk/parser/XIParser.cpp", "sdk/parser/XParser.cpp", "sdk/parser/XParser2.cpp", "sdk/survey/ISurveyCar.cpp", "sdk/survey/ISurveyItem.cpp", - "sdk/survey/ISurveySubject.cpp", + "sdk/survey/SurveyFactory.cpp", "sdk/survey/car/SurveyCar.cpp", - "sdk/survey/sub2/ISub2SurveyFactory.cpp", "sdk/survey/sub2/ISub2SurveyItem.cpp", "sdk/survey/sub2/Sub2SurveyCftc.cpp", "sdk/survey/sub2/Sub2SurveyDcrk.cpp", "sdk/survey/sub2/Sub2SurveyPdqb.cpp", "sdk/survey/sub2/Sub2SurveyQxxs.cpp", "sdk/survey/sub2/Sub2SurveyZjzw.cpp", - "sdk/survey/sub3/ISub3SurveyFactory.cpp", "sdk/survey/sub3/ISub3SurveyItem.cpp", - "sdk/survey/sub3/Sub3MeshDefines.cpp", - "sdk/survey/sub3/Sub3SurveyRoads.cpp", - "sdk/survey/sub3/Sub3SurveySharps.cpp", "sdk/track/TrackReader.cpp", "sdk/track/TrackWriter.cpp", "sdk/utility/Geometry.cpp", @@ -108,7 +79,7 @@ ohos_source_set("judge_dynamic") { "third/libb64/base64.cpp", "third/libb64/cdecode.c", "third/libb64/cencode.c", - "third/tinyxml2-9.0.0/tinyxml2.cpp", + "third/tinyxml2-9.0.0/tinyxml2.cpp" ] include_dirs = [ "sdk", @@ -121,8 +92,6 @@ ohos_source_set("judge_dynamic") { "sdk/common", "sdk/database", "sdk/database/carinfo", - "sdk/database/iteminfo", - "sdk/database/mappoint", "sdk/database/mark", "sdk/database/sysparm", "sdk/database/sysset", @@ -164,30 +133,24 @@ ohos_source_set("judge_dynamic") { "__OHOS_FAMILY__", ] cflags = [ - "-Wno-implicit-fallthrough", - "-Wno-unused-private-field", - "-Wunknown-warning-option", - "-Wno-unused-const-variable", "-Wno-unused-variable", "-Wno-deprecated-declarations", "-Wno-unused-command-line-argument", "-Wno-tautological-constant-out-of-range-compare", "-Wno-unused-function", "-Wno-unused-parameter", + "-Wno-unused-but-set-variable", "-fexceptions", ] cflags_cc = [ - "-Wno-implicit-fallthrough", - "-Wno-unused-private-field", - "-Wunknown-warning-option", - "-Wno-unused-const-variable", "-Wno-unused-variable", "-Wno-deprecated-declarations", "-Wno-unused-command-line-argument", "-Wno-tautological-constant-out-of-range-compare", "-Wno-unused-function", "-Wno-unused-parameter", + "-Wno-unused-but-set-variable", "-fexceptions", "-std=c++17", "-stdlib=libc++", diff --git a/entry/src/main/cpp/bin/extract_h_cpp_files.txt b/entry/src/main/cpp/bin/extract_h_cpp_files.txt index 9c3c0abc..a1a4940c 100644 --- a/entry/src/main/cpp/bin/extract_h_cpp_files.txt +++ b/entry/src/main/cpp/bin/extract_h_cpp_files.txt @@ -8,24 +8,23 @@ "sdk/api/js/JSTypedef.cpp", "sdk/api/platform/JudgeApiFactory.cpp", "sdk/api/platform/JudgeSdk.cpp", - "sdk/common/CleverHelper.cpp", + "sdk/common/CostTimeHelper.cpp", "sdk/common/CryptoAlgorithm.cpp", - "sdk/common/HSystem.cpp", - "sdk/common/HVersion.cpp", "sdk/common/Loggerxx.cpp", + "sdk/common/ProfilerHelper.cpp", + "sdk/common/TAssert.cpp", "sdk/common/TQueue.cpp", "sdk/common/TimerPool.cpp", "sdk/common/Tools.cpp", - "sdk/database/IDBTables.cpp", + "sdk/database/IDatabaseTable.cpp", "sdk/database/carinfo/CarInfoTable.cpp", - "sdk/database/iteminfo/ItemInfoTable.cpp", "sdk/database/mappoint/MapPointItemTable.cpp", "sdk/database/mappoint/MapPointTable.cpp", + "sdk/database/mark/MarkItemRule.cpp", "sdk/database/mark/MarkTable.cpp", "sdk/database/sysparm/SysParmTable.cpp", "sdk/database/sysset/SysSetTable.cpp", - "sdk/exam/ExamCarSub2.cpp", - "sdk/exam/ExamCarSub3.cpp", + "sdk/exam/ExamCar.cpp", "sdk/exam/ExamDatagram.cpp", "sdk/exam/ExamHistory.cpp", "sdk/exam/ExamSensor.cpp", @@ -36,36 +35,15 @@ "sdk/graphic/IGraphicAbstract.cpp", "sdk/judge/IJudgeBrokerInterface.cpp", "sdk/judge/IJudgeItem.cpp", - "sdk/judge/sub2/ISub2JudgeItem.cpp", - "sdk/judge/sub2/ISub2JudgeWrap.cpp", - "sdk/judge/sub2/Sub2Judge00Dcrk.cpp", - "sdk/judge/sub2/Sub2Judge02Pdqb.cpp", - "sdk/judge/sub2/Sub2Judge03Cftc.cpp", - "sdk/judge/sub2/Sub2Judge05Qxxs.cpp", - "sdk/judge/sub2/Sub2Judge06Zjzw.cpp", - "sdk/judge/sub2/Sub2Judge20Comm.cpp", - "sdk/judge/sub3/ISub3JudgeItem.cpp", - "sdk/judge/sub3/ISub3JudgeWrap.cpp", - "sdk/judge/sub3/Sub3Judge01Sczb.cpp", - "sdk/judge/sub3/Sub3Judge02Qbxx.cpp", - "sdk/judge/sub3/Sub3Judge03Zxxs.cpp", - "sdk/judge/sub3/Sub3Judge04Bgcd.cpp", - "sdk/judge/sub3/Sub3Judge05Lkzx.cpp", - "sdk/judge/sub3/Sub3Judge06Rxhd.cpp", - "sdk/judge/sub3/Sub3Judge07Xxqy.cpp", - "sdk/judge/sub3/Sub3Judge08Gjzt.cpp", - "sdk/judge/sub3/Sub3Judge09Hcxx.cpp", - "sdk/judge/sub3/Sub3Judge10Ccxx.cpp", - "sdk/judge/sub3/Sub3Judge11Kbtc.cpp", - "sdk/judge/sub3/Sub3Judge12Dtxx.cpp", - "sdk/judge/sub3/Sub3Judge12Lkdt.cpp", - "sdk/judge/sub3/Sub3Judge12Ptdt.cpp", - "sdk/judge/sub3/Sub3Judge13Yjxs.cpp", - "sdk/judge/sub3/Sub3Judge14Jjdw.cpp", - "sdk/judge/sub3/Sub3Judge15Lkzz.cpp", - "sdk/judge/sub3/Sub3Judge16Lkyz.cpp", - "sdk/judge/sub3/Sub3Judge20Comm.cpp", - "sdk/judge/sub3/Sub3Judge41Mndg.cpp", + "sdk/judge/JudgeItemFactory.cpp", + "sdk/judge/sub2/ISub2Judge.cpp", + "sdk/judge/sub2/Sub2JudgeCftc.cpp", + "sdk/judge/sub2/Sub2JudgeComm.cpp", + "sdk/judge/sub2/Sub2JudgeDcrk.cpp", + "sdk/judge/sub2/Sub2JudgePdqb.cpp", + "sdk/judge/sub2/Sub2JudgeQxxs.cpp", + "sdk/judge/sub2/Sub2JudgeZjzw.cpp", + "sdk/judge/sub3/ISub3Judge.cpp", "sdk/parser/XIParser.cpp", "sdk/parser/XParser.cpp", "sdk/parser/XParser2.cpp", @@ -115,7 +93,6 @@ "sdk/common", "sdk/database", "sdk/database/carinfo", - "sdk/database/iteminfo", "sdk/database/mappoint", "sdk/database/mark", "sdk/database/sysparm", diff --git a/entry/src/main/cpp/bin/test_data/test-real-exam.json b/entry/src/main/cpp/bin/test_data/test-real-exam.json index f3e162da..bf7d8fe8 100644 --- a/entry/src/main/cpp/bin/test_data/test-real-exam.json +++ b/entry/src/main/cpp/bin/test_data/test-real-exam.json @@ -35,6 +35,7 @@ "yl": 0, "yy": 0, "rmndg": 0, + "wavend": 1, "mndg": "2,1,3;4,1,2;3,4,2;2,2,1;3,1,1;", "sde": 0, "xhd":"" diff --git a/entry/src/main/cpp/sdk/api/include/JudgeSdk.h b/entry/src/main/cpp/sdk/api/include/JudgeSdk.h index 99ee118e..aec1fd2d 100644 --- a/entry/src/main/cpp/sdk/api/include/JudgeSdk.h +++ b/entry/src/main/cpp/sdk/api/include/JudgeSdk.h @@ -65,7 +65,7 @@ typedef int (JUDGE_SDK_METHOD *examJudgeEndExamHandle) (); typedef int (JUDGE_SDK_METHOD *examJudgeRealExamHandle) (const char* data, int len); typedef int (JUDGE_SDK_METHOD *examJudgeSetRealExamCallbackHandle) (examJudgeCallbackRealExam callback); typedef int (JUDGE_SDK_METHOD *examJudgeSetPerformCallbackHandle) (examJudgeCallbackPerform callback); -typedef int (JUDGE_SDK_METHOD *examJudgeArtificialMarkHandle) (int itemno, const char* serial); +typedef int (JUDGE_SDK_METHOD *examJudgeArtificialMarkHandle) (int itemno, const char* serial, int type); typedef int (JUDGE_SDK_METHOD *examJudgeArtificialItemHandle) (int itemno, int type); typedef int (JUDGE_SDK_METHOD *examJudgeSoundEndHandle) (int itemno, const char* code, int type); typedef const char* (JUDGE_SDK_METHOD *examJudgeTrackFileHandle) (); @@ -156,10 +156,10 @@ JUDGE_SDK_API int JUDGE_SDK_METHOD examJudgeSetPerformCallback(examJudgeCallback /* * 说明: 人工扣分 - * 参数: itemno:项目代码,serial:扣分代码 + * 参数: itemno:项目代码,serial:扣分代码 serial:人工扣分类型,1是本地人工扣分,2是远程人工扣分 * 返回值:调用执行结果错误码 0:成功,其他:失败 */ -JUDGE_SDK_API int JUDGE_SDK_METHOD examJudgeArtificialMark(int itemno, const char* serial); +JUDGE_SDK_API int JUDGE_SDK_METHOD examJudgeArtificialMark(int itemno, const char* serial, int type); /* * 说明: 人工项目 diff --git a/entry/src/main/cpp/sdk/api/jni/JNIApiBridge.cpp b/entry/src/main/cpp/sdk/api/jni/JNIApiBridge.cpp index bd51c6f9..6553dd18 100644 --- a/entry/src/main/cpp/sdk/api/jni/JNIApiBridge.cpp +++ b/entry/src/main/cpp/sdk/api/jni/JNIApiBridge.cpp @@ -130,13 +130,13 @@ jint JNI_JUDGE_FUN_IMPL(examJudgeSetPerformCallback)(JNIEnv* env, jobject thiz) return (jint)QE(code); } -jint JNI_JUDGE_FUN_IMPL(examJudgeArtificialMark)(JNIEnv* env, jobject thiz, jint itemno, jstring serial) +jint JNI_JUDGE_FUN_IMPL(examJudgeArtificialMark)(JNIEnv* env, jobject thiz, jint itemno, jstring serial, jint type) { logdebug("call JNI_examJudgeArtificialMark"); const char* markSerial = env->GetStringUTFChars(serial, NULL); //jsize size = env->GetStringUTFLength(data); //TASSERT(buf != nullptr && size == len, ""); - int code = ExamService::examJudgeArtificialMark(itemno, markSerial); + int code = ExamService::examJudgeArtificialMark(itemno, markSerial, type); env->ReleaseStringUTFChars(serial, markSerial); return (jint)QE((ErrorCode)code); } diff --git a/entry/src/main/cpp/sdk/api/jni/JNIApiBridge.h b/entry/src/main/cpp/sdk/api/jni/JNIApiBridge.h index 3cba66b3..8c9e9d3c 100644 --- a/entry/src/main/cpp/sdk/api/jni/JNIApiBridge.h +++ b/entry/src/main/cpp/sdk/api/jni/JNIApiBridge.h @@ -32,7 +32,7 @@ public: jint JNI_JUDGE_FUN_DECL(examJudgeRealExam) (JNIEnv* env, jobject thiz, jstring data, jint len); jint JNI_JUDGE_FUN_DECL(examJudgeSetRealExamCallback) (JNIEnv* env, jobject thiz); jint JNI_JUDGE_FUN_DECL(examJudgeSetPerformCallback) (JNIEnv* env, jobject thiz); - jint JNI_JUDGE_FUN_DECL(examJudgeArtificialMark) (JNIEnv* env, jobject thiz, jint itemno, jstring serial); + jint JNI_JUDGE_FUN_DECL(examJudgeArtificialMark) (JNIEnv* env, jobject thiz, jint itemno, jstring seria, jint type); jstring JNI_JUDGE_FUN_DECL(examJudgeTrackFile) (JNIEnv* env, jobject thiz); jint JNI_JUDGE_FUN_DECL(examJudgeMapSetParam) (JNIEnv* env, jobject thiz, jint width, jint height); jint JNI_JUDGE_FUN_DECL(examJudgeMapSetScaling) (JNIEnv* env, jobject thiz, jint scaling); diff --git a/entry/src/main/cpp/sdk/api/jni/JNIMethodTable.cpp b/entry/src/main/cpp/sdk/api/jni/JNIMethodTable.cpp index 2f865290..2f263ebc 100644 --- a/entry/src/main/cpp/sdk/api/jni/JNIMethodTable.cpp +++ b/entry/src/main/cpp/sdk/api/jni/JNIMethodTable.cpp @@ -16,7 +16,7 @@ JNIMethodTable::JNIMethodTable() jniSign(JNI_RET(jint), JNI_FUN(examJudgeRealExam), JNI_ARG(jstring), JNI_ARG(jint)); // "(Ljava/lang/String;I)I" jniSign(JNI_RET(jint), JNI_FUN(examJudgeSetRealExamCallback)); // "()I" jniSign(JNI_RET(jint), JNI_FUN(examJudgeSetPerformCallback)); // "()I" - jniSign(JNI_RET(jint), JNI_FUN(examJudgeArtificialMark), JNI_ARG(jint), JNI_ARG(jstring)); // "(ILjava/lang/String;)I" + jniSign(JNI_RET(jint), JNI_FUN(examJudgeArtificialMark), JNI_ARG(jint), JNI_ARG(jstring), JNI_ARG(jint)); // "(ILjava/lang/String;I)I" jniSign(JNI_RET(jint), JNI_FUN(examJudgeArtificialItem), JNI_ARG(jint), JNI_ARG(jint)); // "(II)I" jniSign(JNI_RET(jint), JNI_FUN(examJudgeSoundEnd), JNI_ARG(jint), JNI_ARG(jstring), JNI_ARG(jint)); // "(ILjava/lang/String;I)I" jniSign(JNI_RET(jstring), JNI_FUN(examJudgeTrackFile)); // "()Ljava/lang/String;" diff --git a/entry/src/main/cpp/sdk/api/js/JSApiBridge.cpp b/entry/src/main/cpp/sdk/api/js/JSApiBridge.cpp index ac49cbfe..29a34977 100644 --- a/entry/src/main/cpp/sdk/api/js/JSApiBridge.cpp +++ b/entry/src/main/cpp/sdk/api/js/JSApiBridge.cpp @@ -256,7 +256,7 @@ JS_JUDGE_FUN_IMPL(examJudgeSetPerformCallback) JS_JUDGE_FUN_IMPL(examJudgeArtificialMark) { logdebug("call js_examJudgeArtificialMark"); - size_t argc = 2; napi_value args[2] = {nullptr}; + size_t argc = 3; napi_value args[3] = {nullptr}; if(!getArg(env, cbinfo, argc, args)) { @@ -265,12 +265,13 @@ JS_JUDGE_FUN_IMPL(examJudgeArtificialMark) int itemno = 0; std::string serial = ""; - if(!getInt(env, args[0], itemno) || !getString(env, args[1], serial/*, 2*KB*/)) + int type = 0; + if(!getInt(env, args[0], itemno) || !getString(env, args[1], serial/*, 2*KB*/) || !getInt(env, args[2], type)) { return createErrorCode(env, errorNapiArgType); } - int code = ExamService::examJudgeArtificialMark(itemno, serial.c_str()); + int code = ExamService::examJudgeArtificialMark(itemno, serial.c_str(), type); return createErrorCode(env, code); } diff --git a/entry/src/main/cpp/sdk/api/platform/JudgeSdk.cpp b/entry/src/main/cpp/sdk/api/platform/JudgeSdk.cpp index 8f230601..7790de3c 100644 --- a/entry/src/main/cpp/sdk/api/platform/JudgeSdk.cpp +++ b/entry/src/main/cpp/sdk/api/platform/JudgeSdk.cpp @@ -107,7 +107,7 @@ JNI_JUDGE_API_JOIN(jint, examJudgeEndExam, (JNIEnv* env, jobje JNI_JUDGE_API_JOIN(jint, examJudgeRealExam, (JNIEnv* env, jobject thiz, jstring data, jint len), (env,thiz,data,len)); JNI_JUDGE_API_JOIN(jint, examJudgeSetRealExamCallback, (JNIEnv* env, jobject thiz), (env,thiz)); JNI_JUDGE_API_JOIN(jint, examJudgeSetPerformCallback, (JNIEnv* env, jobject thiz), (env,thiz)); -JNI_JUDGE_API_JOIN(jint, examJudgeArtificialMark, (JNIEnv* env, jobject thiz, jint itemno, jstring serial), (env,thiz,itemno,serial)); +JNI_JUDGE_API_JOIN(jint, examJudgeArtificialMark, (JNIEnv* env, jobject thiz, jint itemno, jstring serial, jint type), (env,thiz,itemno,serial,type)); JNI_JUDGE_API_JOIN(jint, examJudgeArtificialItem, (JNIEnv* env, jobject thiz, jint itemno, jint type), (env,thiz,itemno,type)); JNI_JUDGE_API_JOIN(jint, examJudgeSoundEnd, (JNIEnv* env, jobject thiz, jint itemno, jstring code, jint type), (env,thiz,itemno,code,type)); JNI_JUDGE_API_JOIN(jstring, examJudgeTrackFile, (JNIEnv* env, jobject thiz), (env, thiz)); @@ -282,9 +282,9 @@ JUDGE_SDK_API int JUDGE_SDK_METHOD examJudgeSetPerformCallback(examJudgeCallback return FactoryExamApi->examJudgeSetPerformCallback(callback); } -JUDGE_SDK_API int JUDGE_SDK_METHOD examJudgeArtificialMark(int itemno, const char* serial) +JUDGE_SDK_API int JUDGE_SDK_METHOD examJudgeArtificialMark(int itemno, const char* serial, int type) { - return FactoryExamApi->examJudgeArtificialMark(itemno, serial); + return FactoryExamApi->examJudgeArtificialMark(itemno, serial, type); } JUDGE_SDK_API int JUDGE_SDK_METHOD examJudgeArtificialItem(int itemno, int type) diff --git a/entry/src/main/cpp/sdk/common/TThread.h b/entry/src/main/cpp/sdk/common/TThread.h index 9a5c756a..f67ea205 100644 --- a/entry/src/main/cpp/sdk/common/TThread.h +++ b/entry/src/main/cpp/sdk/common/TThread.h @@ -63,7 +63,7 @@ public: while (m_run) { T value; - while(m_que->blockPull(value, 1000)) + while(m_que->blockPull(value, 20)) { m_func(value); } diff --git a/entry/src/main/cpp/sdk/exam/ExamCarSub2.cpp b/entry/src/main/cpp/sdk/exam/ExamCarSub2.cpp index 3a917283..7edc1b28 100644 --- a/entry/src/main/cpp/sdk/exam/ExamCarSub2.cpp +++ b/entry/src/main/cpp/sdk/exam/ExamCarSub2.cpp @@ -106,7 +106,7 @@ ErrorCode ExamCarSub2::examGoonExam() //已经不合格了 如果是考试模式,只要分数不合格就立即结束考试 if( (isExamMode() && !isQualified()) || allItemFinish() ) { - createEventExamFinish(); + //createEventExamFinish(ExamFinishAuto); //杨 20240724 都由苏那边控制 return QE(errorBeginNotQual); //已经不合格了 } @@ -135,9 +135,9 @@ ErrorCode ExamCarSub2::examJudgeExam() return QE(codeSuccess); } -ErrorCode ExamCarSub2::examArtifMark(ExamItemCode itemno, const std::string& serial) +ErrorCode ExamCarSub2::examArtifMark(ExamItemCode itemno, const std::string& serial, MarkType type) { - sub2MarkItem(itemno, serial, false, true, true); + examMarkItem(itemno, serial, false, true, true, type); return QE(codeSuccess); } @@ -160,16 +160,16 @@ bool ExamCarSub2::examDrawMap() return drawImageMap(); } -bool ExamCarSub2::sub2MarkItem(ExamItemCode itemNo, const std::string& serial, bool once, bool force, bool event) +bool ExamCarSub2::examMarkItem(ExamItemCode itemNo, const std::string& serial, bool once, bool force, bool event, MarkType type) { if(m_examState != examStateIng) { - logwarning("mark-warning itemNo=%d, serial=%s", itemNo, serial.c_str()); + logwarning("mark-warning itemNo=%d, serial=%s,type=%d", itemNo, serial.c_str(), type); return false; } if(!TableMark->has(itemNo, serial)) { - logerror("mark-error itemNo=%d, serial=%s", itemNo, serial.c_str()); + logerror("mark-error itemNo=%d, serial=%s,type=%d", itemNo, serial.c_str(), type); return false; } @@ -202,16 +202,16 @@ bool ExamCarSub2::sub2MarkItem(ExamItemCode itemNo, const std::string& serial, b const TMarkRule* rule = TableMark->find(itemNo, serial); //找到扣分的对象 if(nullptr == rule) { - logerror("not find mark-rule item=%d, serial=%s", itemNo, serial.c_str()); + logerror("not find mark-rule item=%d, serial=%s, type=%d", itemNo, serial.c_str(), type); return false; } if(rule->markreal == 0) { - loginfo("why mark-rule item=%d, serial=%s markreal=%d, real is 0 ? %s ", - itemNo, serial.c_str(), rule->markreal, rule->markshow.c_str()); + loginfo("why mark-rule type=%d, item=%d, serial=%s, markreal=%d, real is 0 ? %s ", + type, itemNo, serial.c_str(), rule->markreal, rule->markshow.c_str()); } - + const TGpsInfo& gps = historyGps(); int grade = rule->markreal; @@ -232,7 +232,7 @@ bool ExamCarSub2::sub2MarkItem(ExamItemCode itemNo, const std::string& serial, b if(itemNo != Sub2ItemType20Comm) { IExamItem* item = findExamItem(itemNo); - TASSERT(item != nullptr, "itemNo=%d, serial=%s", itemNo, serial.c_str()); + TASSERT(item != nullptr, "itemNo=%d, serial=%s, type=%d", itemNo, serial.c_str(), type); if(item != nullptr) { //扣分扣到不合格当前项目要结束掉 @@ -244,9 +244,9 @@ bool ExamCarSub2::sub2MarkItem(ExamItemCode itemNo, const std::string& serial, b if(event) { //插入监管扣分事件(C++评判不负责这块了,这里忽略,只是做个提醒) - createEventMarkItem({itemNo, serial, rule->markcatalog}); - logtrace("mark-item %s itemno=%d,markserial=%s,markreal=%d", - target().c_str(), rule->itemno, rule->markserial.c_str(), rule->markreal); + createEventMarkItem({itemNo, serial, rule->markcatalog, type}); + logtrace("mark-item %s type=%d itemno=%d,markserial=%s,markreal=%d", + target().c_str(), type, rule->itemno, rule->markserial.c_str(), rule->markreal); } return true; @@ -355,7 +355,7 @@ void ExamCarSub2::dealJudgeExam() #ifndef JUDGE_USE_INSPECT if( (isExamMode() && !isQualified()) || allItemFinish() ) { - createEventExamFinish(); + //createEventExamFinish(ExamFinishAuto); //杨 20240724 都由苏那边控制 } #endif } @@ -400,7 +400,7 @@ ISub2JudgeItem* ExamCarSub2::readEnterItem() if(!subIdx.empty() && subIdx != itemEnter->subIdx()) { //createEventFinishItem(itemEnter); //发送项目结束指令 - sub2MarkItem(Sub2ItemType20Comm, MARK_SUB2_COMM_41, true, false, true); //扣分:不按规定考试 + examMarkItem(Sub2ItemType20Comm, MARK_SUB2_COMM_41, true, false, true, MarkTypeAuto); //扣分:不按规定考试 return nullptr; } return itemEnter; diff --git a/entry/src/main/cpp/sdk/exam/ExamCarSub2.h b/entry/src/main/cpp/sdk/exam/ExamCarSub2.h index 36bc81b8..e184d490 100644 --- a/entry/src/main/cpp/sdk/exam/ExamCarSub2.h +++ b/entry/src/main/cpp/sdk/exam/ExamCarSub2.h @@ -26,10 +26,12 @@ public: //for IExamCar override virtual ErrorCode examGoonExam() override; virtual ErrorCode examEndExam() override; virtual ErrorCode examJudgeExam() override; - virtual ErrorCode examArtifMark(ExamItemCode itemno, const std::string& serial) override; + virtual ErrorCode examArtifMark(ExamItemCode itemno, const std::string& serial, MarkType type) override; virtual ErrorCode examArtifItem(ExamItemCode itemno, ArtifItemType type) override; virtual ErrorCode examSoundEnd(ExamItemCode itemno, const std::string& code, PlaySoundType type) override; virtual bool examDrawMap() override; + virtual bool examMarkItem(ExamItemCode itemNo, const std::string& serial, bool once=false, bool force=false, bool event=true, MarkType type=MarkTypeAuto) override; + public: //for IExamCarSub2 override virtual IExamItem* findExamItem(ExamItemCode itemNo) override; @@ -37,7 +39,7 @@ public: //for IExamCarSub2 override virtual bool allItemFinish() override; virtual ISub2JudgeItem* currentItem() const noexcept override { return m_curItem; } virtual ISub2JudgeItem* commItem() const noexcept override { return m_commItem; } - virtual bool sub2MarkItem(ExamItemCode itemNo, const std::string& serial, bool once, bool force=false, bool event=true) override; + protected: //执行考试评判 virtual void dealJudgeExam(); diff --git a/entry/src/main/cpp/sdk/exam/ExamCarSub3.cpp b/entry/src/main/cpp/sdk/exam/ExamCarSub3.cpp index 418b2846..3a959e59 100644 --- a/entry/src/main/cpp/sdk/exam/ExamCarSub3.cpp +++ b/entry/src/main/cpp/sdk/exam/ExamCarSub3.cpp @@ -38,6 +38,7 @@ ErrorCode ExamCarSub3::examBeginExam() // loginfo("exam-item xmdm=%d", item.xmdm); //} + m_pub = TPubKM3(); std::string sError; if(!Init_KM3_Global(sError)) { @@ -163,9 +164,9 @@ ErrorCode ExamCarSub3::examJudgeExam() return QE(codeSuccess); } -ErrorCode ExamCarSub3::examArtifMark(ExamItemCode itemno, const std::string& serial) +ErrorCode ExamCarSub3::examArtifMark(ExamItemCode itemno, const std::string& serial, MarkType type) { - judgeMark(itemno, serial, false, true, true, 1); + examMarkItem(itemno, serial, false, true, true, type); return QE(codeSuccess); } @@ -418,7 +419,7 @@ bool ExamCarSub3::Init_KM3_Global(std::string& sError) //注释改成:将之前的行驶里程减掉 if(m_stuInfo.yklc != 0) { - m_car.XSJL -= m_stuInfo.yklc; + m_car.XSJL -= m_stuInfo.yklc/100; if(m_car.XSJL <= 0) { m_car.XSJL = 0; @@ -1123,8 +1124,8 @@ bool ExamCarSub3::Init_KM3_Special() } //触发起步项目 - TKM3Item* item = findExamItem(Sub3ItemType02Qbxx); //加载起步项目 - triggerItem(item); + //TKM3Item* item = findExamItem(Sub3ItemType02Qbxx); //加载起步项目 + //triggerItem(item); //在通用评判里调用CallQiBu触发,通过判断502参数和307参数 20240726 return true; } @@ -1145,10 +1146,10 @@ void ExamCarSub3::Deal_KM3_Judge() // return; //} - TChuanGan* his1 = historyChuanGan(1); + //TChuanGan* his1 = historyChuanGan(1); + //const TGpsInfo& gps1 = his1->real.gps; const TGpsInfo& gps = m_cg->real.gps; - const TGpsInfo& gps1 = his1->real.gps; - if(gps.jd > 1 && gps.wd > 1 && gps1.jd > 1 && gps1.wd > 1) //rtkEnabled() + if(gps.jd > 1 && gps.wd > 1 && rtkEnabled()) { //1、计算考车位置 //Calc_CarPos //在ExamSensor里面计算了 @@ -1168,9 +1169,9 @@ void ExamCarSub3::Deal_KM3_Judge() Km3NewEnterItem(); - { //车道或路段变化事件 + TChuanGan* his1 = historyChuanGan(1); const TRTKResult& rtk = m_cg->RTKKM3; const TRTKResult& rtk1 = his1->RTKKM3; if(rtk.MapRoad_Code_No != rtk1.MapRoad_Code_No || @@ -1182,7 +1183,7 @@ void ExamCarSub3::Deal_KM3_Judge() } } - m_KsLjLc = m_stuInfo.yklc + m_cg->ai_ljjl; + m_pub.m_KsLjLc = m_stuInfo.yklc/100 + m_cg->ai_ljjl; m_cg->tkCnt = GetCurrentTick2(); m_cg->RTKKM3.CrossPointNo = lastCrossPtNo(); @@ -1196,20 +1197,21 @@ void ExamCarSub3::Deal_KM3_Judge() // CallRenGongEnterItem(mitemno); //} - if(m_cg->real.sensor.rmndg == SYES) - { - TKM3Item* item = findExamItem(Sub3ItemType41Mndg); - if(item && item->TestPro == ItemProFlagIdle) - { - item->Item_Color = itemStateZk; - item->TestPro = ItemProFlagInit; - item->FinishFlag = false; - //item->StartTime = GetCurrentTime2(); - //item->EndTime = 0; - //item->MsgData = ""; - //createEventEnterItem({item->ItemNo, ""}); - } - } + //240710 + //if(m_cg->real.sensor.rmndg == SYES) + //{ + // TKM3Item* item = findExamItem(Sub3ItemType41Mndg); + // if(item && item->TestPro == ItemProFlagIdle) + // { + // item->Item_Color = itemStateZk; + // item->TestPro = ItemProFlagInit; + // item->FinishFlag = false; + // //item->StartTime = GetCurrentTime2(); + // //item->EndTime = 0; + // //item->MsgData = ""; + // //createEventEnterItem({item->ItemNo, ""}); + // } + //} m_curItem = nullptr; //执行具体的专项评判 @@ -1260,31 +1262,29 @@ void ExamCarSub3::Deal_KM3_Judge() //如果考试结束(训练不存在结束的概念,都是界面上点击结束考试,一般科目三都是可以重复进项目的) if(isExamMode()) //考试模式的 { - if(allItemFinish() == true) - { - //ToDo1:告知上层当前考试结束,生成科目结束事件2 - createEventExamFinish(); - } - } + bool finish = allItemFinish(); + bool qualified = isQualified(); - if(isExamMode() && !isQualified()) //正式考试模式 - { //ToDo1:检查当前正在进行的项目状态 - for(auto it = m_sub3Items.begin(); it != m_sub3Items.end(); it++) + if(!qualified) { - const TKM3Item* examItem = it->second->getExamItem(); - if(examItem->TestPro == ItemProFlagInit || examItem->TestPro == ItemProFlagJudge) + for(auto it = m_sub3Items.begin(); it != m_sub3Items.end(); it++) { - KM3EndItem(examItem->ItemNo); + const TKM3Item* examItem = it->second->getExamItem(); + if(examItem->TestPro == ItemProFlagInit || examItem->TestPro == ItemProFlagJudge) + { + KM3EndItem(examItem->ItemNo); + } } } - //ToDo2:告知上层当前考试结束,生成科目结束事件2 - createEventExamFinish(); - - //ToDo3:考试状态:结束状态 - //*Test_Status = 1; ////考试中状态 0-考试中 1-考试结束,评判不继续 2-考试结束,继续评判(一般用于训练) + if(finish || !qualified) + { + //ToDo1:告知上层当前考试结束,生成科目结束事件2 + //createEventExamFinish(ExamFinishAuto); //杨 20240724 都由苏那边控制 + } } + } void ExamCarSub3::ClearRecord() @@ -2289,7 +2289,7 @@ void ExamCarSub3::RTKJudge_SubItem() RTKKM3.CrossLineAttr = TRTKResult::CrossLineAttr1; RTKKM3.ShapeNo = SNO; //RTKKM3.LS_ShapeNo = 0; - m_SNO = 0; + m_pub.m_SNO = 0; break; } } @@ -2301,7 +2301,7 @@ void ExamCarSub3::RTKJudge_SubItem() RTKKM3.CrossLineAttr = TRTKResult::CrossLineAttr1; RTKKM3.ShapeNo = SNO; //RTKKM3.LS_ShapeNo = SNO; - m_SNO = SNO; + m_pub.m_SNO = SNO; RTKKM3.CrossPoint = subItem->Point2; const Pointi& p1 = subItem->Line3.PtBegin; @@ -2311,19 +2311,19 @@ void ExamCarSub3::RTKJudge_SubItem() RTKKM3.CrossShapeLength = std::round(std::sqrt(x*x + y*y)); break; } - if(m_SNO == SNO) //RTKKM3.LS_ShapeNo == SNO + if(m_pub.m_SNO == SNO) //RTKKM3.LS_ShapeNo == SNO { if(GpsMath::IsCross(line, subItem->Line3)) { RTKKM3.CrossLineAttr = TRTKResult::CrossLineAttr2; //中心点右侧 RTKKM3.ShapeNo = SNO; //RTKKM3.LS_ShapeNo = 0; - m_SNO = 0; + m_pub.m_SNO = 0; } else if(GpsMath::IsCross(line, subItem->Line2)) { //RTKKM3.LS_ShapeNo = 0; - m_SNO = 0; + m_pub.m_SNO = 0; } const Pointi& p1 = RTKKM3.CrossPoint; const Pointi& p2 = m_cg->body.b1_b; //CarStatus.BasePoint1_RealTime; @@ -2332,7 +2332,7 @@ void ExamCarSub3::RTKJudge_SubItem() if(dis > RTKKM3.CrossShapeLength * 3) //3--6 20170924 { //RTKKM3.LS_ShapeNo = 0; - m_SNO = 0; + m_pub.m_SNO = 0; } } } @@ -3116,10 +3116,25 @@ void ExamCarSub3::Km3NewEnterItem() TChuanGan* his1 = historyChuanGan(1); if(cg->move != moveForward || his1->move != moveForward) return; //2、速度是0也退出 - if(cg->real.gps.sd < 0.1 || his1->real.gps.sd < 0.1) return; //ai_CS_GPS + //if(cg->real.gps.sd < 0.1 || his1->real.gps.sd < 0.1) return; //ai_CS_GPS //3、非差分状态忽略 if(!rtkEnabled()) return; //非差分状态不不允许进项目 + if(!rtkEnabled(1)) + { + if(historyCount() > 10) + { + for(int i = 2; i < 10; i++) + { + TChuanGan* his = historyChuanGan(i); + if(his->real.gps.rtkEnabled) + { + his1 = his; + } + } + } + } + static constexpr double KK0 = 1000000.0; if(E_1Deg2Cm == 0) { @@ -3271,8 +3286,8 @@ void ExamCarSub3::Km3NewEnterItem() cg->MapPoint_Road_Code = Road_Code; //得到穿越的点号,在路口项目中,会被转换成路段的点。(如果右路段信息的话,当然了,路口项目肯定是在特定的路段上的) - PubLastChuanYuePtNo = crossPointNo; - PubLastChuanYuePt_JLCM = disCM; + m_pub.PubLastChuanYuePtNo = crossPointNo; + m_pub.PubLastChuanYuePt_JLCM = disCM; //如果不是项目点,忽略 //读卡进项目的 //(*2024-03-05*) @@ -3336,10 +3351,10 @@ void ExamCarSub3::ReadItemByPoint(int crossPointNo) const std::string& s319 = TableSysSet->get319(); //SysSet[319]: 1:必须达到里程,才能进入靠边停车 //SysSet[319]: 2:必须达到里程,并且完成必考项目。才能进入靠边停车 - if(s319 == "1" && m_KsLjLc < m_car.XSJL) return; + if(s319 == "1" && m_pub.m_KsLjLc < m_car.XSJL) return; if(s319 == "2") { - if(m_KsLjLc < m_car.XSJL) return; + if(m_pub.m_KsLjLc < m_car.XSJL) return; bool unfinished = false; for(auto it = m_sub3Items.begin(); it != m_sub3Items.end(); it++) { @@ -3732,7 +3747,7 @@ bool ExamCarSub3::KM3AllPass() if(isQualified()) //当前是合格的 { int s336 = TableSysSet->asInt336(); - if(m_KsLjLc + s336 < m_car.XSJL) + if(m_pub.m_KsLjLc + s336 < m_car.XSJL) { return false; } @@ -3848,7 +3863,7 @@ void ExamCarSub3::KM3EndItem(int ItemNo) examItem->GPS_n = 0; if(examItem->ItemNo == Sub3ItemType04Bgcd || examItem->ItemNo == Sub3ItemType10Ccxx) { - PUB_JDCC_ZT = 0; //借道超车 + m_pub.PUB_JDCC_ZT = 0; //借道超车 } //已考项目变量更新 if(!isExamAlready(ItemNo)) @@ -3859,7 +3874,7 @@ void ExamCarSub3::KM3EndItem(int ItemNo) createEventFinishItem({examItem->ItemNo, "", markFlag ? 0 : 1}); } -bool ExamCarSub3::judgeMark(int ItemNo, const std::string& serial, bool OnlyOneID, bool ForceID, bool event, int8 Kind) +bool ExamCarSub3::examMarkItem(int itemNo, const std::string& serial, bool once, bool force, bool event, MarkType type) { //Kind:0 自动评判 1:考车人工扣分 2:远程下发的考试扣分 bool result = false; @@ -3867,31 +3882,31 @@ bool ExamCarSub3::judgeMark(int ItemNo, const std::string& serial, bool OnlyOneI //满分学习如果不扣分,除了考车人工点击扣分或者远程下发的扣分,一律忽略 if(m_stuInfo.mfxx && m_stuInfo.mfxxn) { - if(Kind == 0) return result; + if(type == MarkTypeAuto) return result; } const std::string& ksdd = TableSysSet->get211(); if(Tools::tolower(ksdd) == siteof::chongqingkm3) { - if(ItemNo == Sub3ItemType11Kbtc && serial == "10") + if(itemNo == Sub3ItemType11Kbtc && serial == "10") { - OnlyOneID = true; + once = true; } - if(ForceID == false) + if(force == false) { if(std::atoi(serial.c_str()) >= 100) { } - else if(ItemNo == Sub3ItemType01Sczb || ItemNo == Sub3ItemType41Mndg) //上车准备、模拟灯光 + else if(itemNo == Sub3ItemType01Sczb || itemNo == Sub3ItemType41Mndg) //上车准备、模拟灯光 { } - else if(ItemNo == Sub3ItemType20Comm && serial == "15") + else if(itemNo == Sub3ItemType20Comm && serial == "15") { } - else if(ItemNo == Sub3ItemType20Comm && serial == "36") + else if(itemNo == Sub3ItemType20Comm && serial == "36") { } @@ -3909,22 +3924,22 @@ bool ExamCarSub3::judgeMark(int ItemNo, const std::string& serial, bool OnlyOneI if(IS_A1(cartype) || IS_A2(cartype) || IS_A3(cartype) || IS_C6(cartype) || IS_B1(cartype) || IS_B2(cartype)) { //路口右转弯 - if(ItemNo == Sub3ItemType16Lkyz) + if(itemNo == Sub3ItemType16Lkyz) { if(isExamAlready(Sub3ItemType16Lkyz)) return result; } //直行通过路口 - if(ItemNo == Sub3ItemType05Lkzx) + if(itemNo == Sub3ItemType05Lkzx) { if(isExamAlready(Sub3ItemType05Lkzx)) return result; } //路口左转弯 - if(ItemNo == Sub3ItemType15Lkzz) + if(itemNo == Sub3ItemType15Lkzz) { if(isExamAlready(Sub3ItemType15Lkzz)) return result; } //夜间驾驶 - if(ItemNo == Sub3ItemType13Yjxs) + if(itemNo == Sub3ItemType13Yjxs) { for(auto it = m_sub3Items.begin(); it != m_sub3Items.end(); it++) { @@ -3943,29 +3958,29 @@ bool ExamCarSub3::judgeMark(int ItemNo, const std::string& serial, bool OnlyOneI if(IS_A2(cartype)) { - if( (ItemNo == Sub3ItemType02Qbxx && serial == "04") || - (ItemNo == Sub3ItemType02Qbxx && serial == "44") || - (ItemNo == Sub3ItemType20Comm && serial == "86") || - (ItemNo == Sub3ItemType20Comm && serial == "79") || - (ItemNo == Sub3ItemType20Comm && serial == "80") || - (ItemNo == Sub3ItemType20Comm && serial == "84") || - (ItemNo == Sub3ItemType20Comm && serial == "85") || - (ItemNo == Sub3ItemType20Comm && serial == "98") ) + if( (itemNo == Sub3ItemType02Qbxx && serial == "04") || + (itemNo == Sub3ItemType02Qbxx && serial == "44") || + (itemNo == Sub3ItemType20Comm && serial == "86") || + (itemNo == Sub3ItemType20Comm && serial == "79") || + (itemNo == Sub3ItemType20Comm && serial == "80") || + (itemNo == Sub3ItemType20Comm && serial == "84") || + (itemNo == Sub3ItemType20Comm && serial == "85") || + (itemNo == Sub3ItemType20Comm && serial == "98") ) { if(std::atoi(serial.c_str()) < 100) return result; } - if(ItemNo == Sub3ItemType14Jjdw) return result; + if(itemNo == Sub3ItemType14Jjdw) return result; } } if(ksdd == siteof::njdckm3) { - if( (ItemNo == Sub3ItemType20Comm && serial == "89") || - (ItemNo == Sub3ItemType04Bgcd && serial == "42") || - (ItemNo == Sub3ItemType04Bgcd && serial == "43") ) + if( (itemNo == Sub3ItemType20Comm && serial == "89") || + (itemNo == Sub3ItemType04Bgcd && serial == "42") || + (itemNo == Sub3ItemType04Bgcd && serial == "43") ) { if(m_cg->ai_ljjl < 500) return result; - if(m_KsLjLc + TableSysSet->asInt336() >= m_car.XSJL) return result; + if(m_pub.m_KsLjLc + TableSysSet->asInt336() >= m_car.XSJL) return result; } } @@ -3974,7 +3989,7 @@ bool ExamCarSub3::judgeMark(int ItemNo, const std::string& serial, bool OnlyOneI TKM3Item* item = findExamItem(Sub3ItemType12Dtxx); if(nullptr != item && item->TestPro > ItemProFlagIdle) { - if(ItemNo == Sub3ItemType02Qbxx) + if(itemNo == Sub3ItemType02Qbxx) { if(serial == "46" || serial == "47") return result; } @@ -3982,7 +3997,7 @@ bool ExamCarSub3::judgeMark(int ItemNo, const std::string& serial, bool OnlyOneI } //变更车道 - if(ItemNo == Sub3ItemType04Bgcd) + if(itemNo == Sub3ItemType04Bgcd) { TKM3Item* item = findExamItem(Sub3ItemType04Bgcd); if(item->TestPro == ItemProFlagIdle && (serial == "42" || serial == "43")) @@ -4000,8 +4015,8 @@ bool ExamCarSub3::judgeMark(int ItemNo, const std::string& serial, bool OnlyOneI { if( !m_car.Night_ID || serial.length() == 3 || (m_car.Night_ID && - (ItemNo == Sub3ItemType13Yjxs || - ((ItemNo == Sub3ItemType05Lkzx || ItemNo == Sub3ItemType15Lkzz || ItemNo == Sub3ItemType16Lkyz) && serial == "01"))) ) + (itemNo == Sub3ItemType13Yjxs || + ((itemNo == Sub3ItemType05Lkzx || itemNo == Sub3ItemType15Lkzz || itemNo == Sub3ItemType16Lkyz) && serial == "01"))) ) { } else @@ -4010,11 +4025,11 @@ bool ExamCarSub3::judgeMark(int ItemNo, const std::string& serial, bool OnlyOneI } } - if(!ForceID) + if(!force) { if(IS_C2(cartype) || IS_C5(cartype)) //自动挡不判 熄火, 起步闯动, 挂错挡,空挡滑行,溜车,抵挡高速 { - if(ItemNo == Sub3ItemType02Qbxx) + if(itemNo == Sub3ItemType02Qbxx) { //起步项目 if( (serial == "08" && ksdd != siteof::yingtan) || (serial == "44") ) @@ -4031,13 +4046,13 @@ bool ExamCarSub3::judgeMark(int ItemNo, const std::string& serial, bool OnlyOneI } } - if(ItemNo == Sub3ItemType14Jjdw && serial.length() < 3) //不判加减档操作 + if(itemNo == Sub3ItemType14Jjdw && serial.length() < 3) //不判加减档操作 { return result; } //通用评判扣分 - if(ItemNo == Sub3ItemType20Comm) + if(itemNo == Sub3ItemType20Comm) { const std::vector& s507 = TableSysSet->asArray507(); @@ -4062,22 +4077,22 @@ bool ExamCarSub3::judgeMark(int ItemNo, const std::string& serial, bool OnlyOneI bool RepeatKfID = false; for(size_t i = 0; i < m_marks.size(); i++) { - if(m_marks[i].serial == serial && m_marks[i].itemNo == ItemNo) + if(m_marks[i].serial == serial && m_marks[i].itemNo == itemNo) { RepeatKfID = true; } } - if(OnlyOneID) + if(once) { if(RepeatKfID) return result; } //执行扣分 - const TMarkRule* rule = TableMark->find(ItemNo, serial); + const TMarkRule* rule = TableMark->find(itemNo, serial); if(nullptr == rule) { - logerror("not find mark-rule item=%d, serial=%s", ItemNo, serial.c_str()); + logerror("not find mark-rule item=%d, serial=%s", itemNo, serial.c_str()); return result; } @@ -4143,15 +4158,15 @@ bool ExamCarSub3::judgeMark(int ItemNo, const std::string& serial, bool OnlyOneI if(event) { - createEventMarkItem({mark.itemNo, mark.serial, mark.catalog}); + createEventMarkItem({mark.itemNo, mark.serial, mark.catalog, type}); } result = true; } else { - loginfo("why mark-rule item=%d, serial=%s markreal=%d, real is 0 ? %s ", - ItemNo, serial.c_str(), rule->markreal, rule->markshow.c_str()); + loginfo("why mark-rule type=%d, item=%d, serial=%s, markreal=%d, real is 0 ? %s ", + type, itemNo, serial.c_str(), rule->markreal, rule->markshow.c_str()); } return result; @@ -4416,7 +4431,7 @@ bool ExamCarSub3::ManualStartItem(int ItemNo) if(ItemNo == Sub3ItemType04Bgcd || ItemNo == Sub3ItemType10Ccxx) { //ToDo:语音播报:取消变更车道 - PUB_JDCC_ZT = 0; //借道超车 + m_pub.PUB_JDCC_ZT = 0; //借道超车 } //ToDo:语音播报:取消变更车道 createEventCancelItem({ItemNo, ""}); diff --git a/entry/src/main/cpp/sdk/exam/ExamCarSub3.h b/entry/src/main/cpp/sdk/exam/ExamCarSub3.h index 7409ebfa..b96a6e99 100644 --- a/entry/src/main/cpp/sdk/exam/ExamCarSub3.h +++ b/entry/src/main/cpp/sdk/exam/ExamCarSub3.h @@ -26,10 +26,12 @@ public: //for IExamCar override virtual ErrorCode examGoonExam() override; virtual ErrorCode examEndExam() override; virtual ErrorCode examJudgeExam() override; - virtual ErrorCode examArtifMark(ExamItemCode itemno, const std::string& serial) override; + virtual ErrorCode examArtifMark(ExamItemCode itemno, const std::string& serial, MarkType type) override; virtual ErrorCode examArtifItem(ExamItemCode itemno, ArtifItemType type) override; virtual ErrorCode examSoundEnd(ExamItemCode itemno, const std::string& code, PlaySoundType type) override; virtual bool examDrawMap() override; + virtual bool examMarkItem(int ItemNo, const std::string& serial, bool once=false, bool force=false, bool event=true, MarkType type=MarkTypeAuto) override; + public: //for IExamCarSub3 override virtual ISub3JudgeItem* findJudgeItem(ExamItemCode itemNo) const override; @@ -38,7 +40,6 @@ public: //for IExamCarSub3 override virtual bool allItemFinish() override; virtual ISub3JudgeItem* currentItem() const noexcept override { return m_curItem; } virtual ISub3JudgeItem* commItem() const noexcept override { return m_commItem; } - bool judgeMark(int ItemNo, const std::string& serial, bool OnlyOneID=false, bool ForceID=false, bool event=true, int8 Kind=0) override; virtual const std::map& allExamItem() const noexcept override { return m_sub3Items; } virtual bool isCrossroadExaming() const override; @@ -51,25 +52,25 @@ public: //for IExamCarSub3 override virtual TCar* getTCar() override { return &m_car; } virtual TTestCtl* getTTestCtl() override { return &m_ctl; } - virtual int lastCrossPtNo() override { return PubLastChuanYuePtNo; } - virtual void setPUB_JDCC_ZT(int v) override { PUB_JDCC_ZT = v;} - virtual int getPUB_JDCC_ZT() const override { return PUB_JDCC_ZT;} - virtual void setChaoChe_Start_TM(int64 v) override { ChaoChe_Start_TM = v;} - virtual int64 getChaoChe_Start_TM() const override { return ChaoChe_Start_TM;} - virtual void setChaoChe_End_TM(int64 v) override { ChaoChe_End_TM = v;} - virtual int64 getChaoChe_End_TM() const override { return ChaoChe_End_TM;} - virtual void setPub_JSC_JL(int v) override { Pub_JSC_JL = v;} - virtual int getPub_JSC_JL() const override { return Pub_JSC_JL; } - virtual void setNJ_DiaoTou_JL(int v) override { NJ_DiaoTou_JL = v; } - virtual int getNJ_DiaoTou_JL() const override { return NJ_DiaoTou_JL; } - virtual void setPubCanJudge_XiHuoFlag(bool v) override { PubCanJudge_XiHuoFlag = v; } - virtual bool getPubCanJudge_XiHuoFlag() const override { return PubCanJudge_XiHuoFlag; } - virtual void setPubKaoBianTCFinish_LJJL(int v) override { PubKaoBianTCFinish_LJJL = v; } - virtual int getPubKaoBianTCFinish_LJJL() const override { return PubKaoBianTCFinish_LJJL; } - virtual void setKsLjLc(int v) override { m_KsLjLc = v; } - virtual int getKsLjLc() const override { return m_KsLjLc; } - virtual void setyjdg_road_code_kf(bool v) override { yjdg_road_code_kf = v; } - virtual bool getyjdg_road_code_kf() const override { return yjdg_road_code_kf; } + virtual int lastCrossPtNo() override { return m_pub.PubLastChuanYuePtNo; } + virtual void setPUB_JDCC_ZT(int v) override { m_pub.PUB_JDCC_ZT = v;} + virtual int getPUB_JDCC_ZT() const override { return m_pub.PUB_JDCC_ZT;} + virtual void setChaoChe_Start_TM(int64 v) override { m_pub.ChaoChe_Start_TM = v;} + virtual int64 getChaoChe_Start_TM() const override { return m_pub.ChaoChe_Start_TM;} + virtual void setChaoChe_End_TM(int64 v) override { m_pub.ChaoChe_End_TM = v;} + virtual int64 getChaoChe_End_TM() const override { return m_pub.ChaoChe_End_TM;} + virtual void setPub_JSC_JL(int v) override { m_pub.Pub_JSC_JL = v;} + virtual int getPub_JSC_JL() const override { return m_pub.Pub_JSC_JL; } + virtual void setNJ_DiaoTou_JL(int v) override { m_pub.NJ_DiaoTou_JL = v; } + virtual int getNJ_DiaoTou_JL() const override { return m_pub.NJ_DiaoTou_JL; } + virtual void setPubCanJudge_XiHuoFlag(bool v) override { m_pub.PubCanJudge_XiHuoFlag = v; } + virtual bool getPubCanJudge_XiHuoFlag() const override { return m_pub.PubCanJudge_XiHuoFlag; } + virtual void setPubKaoBianTCFinish_LJJL(int v) override { m_pub.PubKaoBianTCFinish_LJJL = v; } + virtual int getPubKaoBianTCFinish_LJJL() const override { return m_pub.PubKaoBianTCFinish_LJJL; } + virtual void setKsLjLc(int v) override { m_pub.m_KsLjLc = v; } + virtual int getKsLjLc() const override { return m_pub.m_KsLjLc; } + virtual void setyjdg_road_code_kf(bool v) override { m_pub.yjdg_road_code_kf = v; } + virtual bool getyjdg_road_code_kf() const override { return m_pub.yjdg_road_code_kf; } protected: bool Init_KM3_Global(std::string& sError); @@ -151,6 +152,7 @@ private: TCar m_car; TTestCtl m_ctl; + TPubKM3 m_pub; std::vector m_carPosMeshList; const int m_DrawArc_Step = 40; @@ -158,25 +160,6 @@ private: int E_1Deg2Cm = 0; //经度1度=多少厘米 const int N_1Deg2Cm = 11110792; //北纬1度=X cm - int m_KsZgDw = 0; //记录考试中的最高档位 - int m_KsZgSs = 0; //记录考试中的最高时速 - int m_KsLjLc = 0; //记录考试累计里程(米) - - int PubLastChuanYuePtNo = 0; //最后一次经过的点 - int PubLastChuanYuePt_JLCM = 0; //最后一次经过的点偏移量 - - int NJ_DiaoTou_JL = 0; //个性需求 - int64 ChaoChe_Start_TM = 0; //2018011 超车开始时间 - int64 ChaoChe_End_TM = 0; //2018011 超车结束时间 - int PUB_JDCC_ZT = 0; //借道超车状态 0:非借道 1:表示超车 2:表示正在返回原车道 3:回原车道道完成 20180227 - bool yjdg_road_code_kf = false; - - int Pub_JSC_JL = 0; - bool PubCanJudge_XiHuoFlag = true; //注意初始必须是true - int PubKaoBianTCFinish_LJJL = 0; - - int m_SNO = 0; - //TCarStatus m_carStatus; //int64 m_ContinuedStartTime = 0; //续考的上次开始考试时间 20150205 diff --git a/entry/src/main/cpp/sdk/exam/ExamDatagram.cpp b/entry/src/main/cpp/sdk/exam/ExamDatagram.cpp index ac67dd80..fa0a24cb 100644 --- a/entry/src/main/cpp/sdk/exam/ExamDatagram.cpp +++ b/entry/src/main/cpp/sdk/exam/ExamDatagram.cpp @@ -38,6 +38,13 @@ void ExamDatagram::addRealtime(int8 proto, const char* data, int len) addRealtime(pkg); } +void ExamDatagram::addRealtime(int8 proto, const std::string& data) +{ + Package* pkg = nullptr; + do { IAutoLock(m_mtxPool); pkg = POOL_CREATE_FROM_V1(m_pool, proto, data); } while(0); + addRealtime(pkg); +} + void ExamDatagram::addRealtime(Package* pkg) { push(pkg); diff --git a/entry/src/main/cpp/sdk/exam/ExamDatagram.h b/entry/src/main/cpp/sdk/exam/ExamDatagram.h index 366da9eb..fccf8752 100644 --- a/entry/src/main/cpp/sdk/exam/ExamDatagram.h +++ b/entry/src/main/cpp/sdk/exam/ExamDatagram.h @@ -23,7 +23,7 @@ struct Package data = std::string(_data,_len); } virtual ~Package() { data.clear(); } - enum {v1_json, v2_hardware}; + enum {v1_json, v2_hardware, v3_end}; int8 proto; std::string data; @@ -43,6 +43,7 @@ public: virtual void exitRealtime(); virtual void clearRealtime(); virtual void addRealtime(int8 proto, const char* data, int len); + virtual void addRealtime(int8 proto, const std::string& data); virtual void addRealtime(Package* pkg); private: HandleDatagram m_handle = nullptr; diff --git a/entry/src/main/cpp/sdk/exam/ExamSensor.cpp b/entry/src/main/cpp/sdk/exam/ExamSensor.cpp index 122ac487..a1f50659 100644 --- a/entry/src/main/cpp/sdk/exam/ExamSensor.cpp +++ b/entry/src/main/cpp/sdk/exam/ExamSensor.cpp @@ -110,32 +110,32 @@ bool ExamSensor::convertDatas(TChuanGan* cg) { TSensorInfo& sor = cg->real.sensor; sor.dw_plc = sor.dw; - if(m_car->examSubject() == ExamSubject2) - { - } - else if(m_car->examSubject() == ExamSubject3) - { - IExamCarSub3* car = dynamic_cast(m_car); - TCar* tcar = car->getTCar(); - //给雾灯信号赋值的时候,一定要遵守下面的规则 - switch(tcar->WD_Signal) - { - case 0: sor.wd = sor.ygq; break; - case 1: sor.wd = 1 - sor.yy; break; //这是取反的的意思如果有信号1, 1-1就是0; - //20140411 - case 2: sor.wd = 1 - sor.ygq; break; //这是取反的的意思如果有信号1, 1-1就是0; - case 3: sor.wd = sor.yy; break; - default:break; - } - - if(tcar->CarTypeName == XCharacter("吉利豪情")) - { - if(sor.ygq == SNOT) - { - sor.wd = SNOT; - } - } - } + // if(m_car->examSubject() == ExamSubject2) + // { + // } + // else if(m_car->examSubject() == ExamSubject3) + // { + // IExamCarSub3* car = dynamic_cast(m_car); + // TCar* tcar = car->getTCar(); + // //给雾灯信号赋值的时候,一定要遵守下面的规则 + // switch(tcar->WD_Signal) + // { + // case 0: sor.wd = sor.ygq; break; + // case 1: sor.wd = 1 - sor.yy; break; //这是取反的的意思如果有信号1, 1-1就是0; + // //20140411 + // case 2: sor.wd = 1 - sor.ygq; break; //这是取反的的意思如果有信号1, 1-1就是0; + // case 3: sor.wd = sor.yy; break; + // default:break; + // } + // + // if(tcar->CarTypeName == XCharacter("吉利豪情")) + // { + // if(sor.ygq == SNOT) + // { + // sor.wd = SNOT; + // } + // } + // } //油门计算,松油门信号 sor.sym = 0; @@ -296,11 +296,11 @@ bool ExamSensor::calcCarBody(TChuanGan* cg) } else { - if(m_car->historyCount() == 0) + if(m_car->historyCount() > 0) { - return false; //第一帧数据就是非差分状态? + cg->real.gps.ai_gps = m_car->historyAiGps(); //20240702 yhy + //return false; //这里不能返回false 第一帧数据就是非差分状态?如果做模拟灯光的时候一直没差分进不了项目了 } - cg->real.gps.ai_gps = m_car->historyAiGps(); //20240702 yhy } if(ExamSubject2 == subject) @@ -405,13 +405,13 @@ bool ExamSensor::GetCarDirStauts(TChuanGan* cg) else { //数据异常 - return false; + return true; //如果从一开始考试一直在非差分状态 如果返回false就进不了评判了 比如模拟灯光 20240726 } } if(cg->real.gps.rtkEnabled == false) //20240702 yhy { - cg->move = m_car->historyChuanGan()->move; + cloneWith(m_car->historyChuanGan(), cg); return true; } @@ -814,6 +814,18 @@ bool ExamSensor::GetCarDirStatus_KM2(TChuanGan* cg) return true; } +void ExamSensor::cloneWith(TChuanGan* src, TChuanGan* dest) +{ + dest->move = src->move; + dest->real.gps.ai_gps = src->real.gps.ai_gps; + dest->ai_ljjl = src->ai_ljjl; + dest->ai_dcjl = src->ai_dcjl; + dest->ai_ljjl_cm = src->ai_ljjl_cm; + dest->ai_dcjl_cm = src->ai_dcjl_cm; + //dest->tkCnt = src->tkCnt; + +} + #ifdef JUDGE_USE_INSPECT void ExamSensor::inspectSensor(TChuanGan* cg) diff --git a/entry/src/main/cpp/sdk/exam/ExamSensor.h b/entry/src/main/cpp/sdk/exam/ExamSensor.h index b4933c8c..983bbbc9 100644 --- a/entry/src/main/cpp/sdk/exam/ExamSensor.h +++ b/entry/src/main/cpp/sdk/exam/ExamSensor.h @@ -35,6 +35,7 @@ public: virtual int GetDBStop_Interval(int ItemNo); //计算考车前进状态 1:表示前进状态 -1:表示后退 0:无变化(停车) virtual CarMoveState calcMoveState(); + virtual void cloneWith(TChuanGan* src, TChuanGan* dest); private: IExamCarAbstract* m_car = nullptr; TGPSPoint m_basePoint; //地图对应的基准点(地图就是测绘项目, 跟考车模型没有关系) diff --git a/entry/src/main/cpp/sdk/exam/ExamService.cpp b/entry/src/main/cpp/sdk/exam/ExamService.cpp index 8cd72f2f..4e58164b 100644 --- a/entry/src/main/cpp/sdk/exam/ExamService.cpp +++ b/entry/src/main/cpp/sdk/exam/ExamService.cpp @@ -105,7 +105,7 @@ int ExamService::examJudgeInit(const char* data, int len) return QE(code); } m_init = true; - loginfo("exam-init success."); + loginfo("exam-init success version=%s.", JUDGE_VERSION_INFO); return QE(codeSuccess); } @@ -182,11 +182,11 @@ int ExamService::examJudgeSetPerformCallback(examJudgeCallbackPerform callback) return QE(codeSuccess); } -int ExamService::examJudgeArtificialMark(int itemno, const char* serial) +int ExamService::examJudgeArtificialMark(int itemno, const char* serial, int type) { logdebug("call examJudgeArtificialMark."); if(!m_init) return QE(errorInitNot); - return m_car->examJudgeArtificialMark(itemno, serial); + return m_car->examJudgeArtificialMark(itemno, serial, type); } int ExamService::examJudgeArtificialItem(int itemno, int type) diff --git a/entry/src/main/cpp/sdk/exam/ExamService.h b/entry/src/main/cpp/sdk/exam/ExamService.h index 91685dbc..efabd8c0 100644 --- a/entry/src/main/cpp/sdk/exam/ExamService.h +++ b/entry/src/main/cpp/sdk/exam/ExamService.h @@ -28,7 +28,7 @@ public: virtual int examJudgeRealExam2(const char* data, int len) override; virtual int examJudgeSetRealExamCallback(examJudgeCallbackRealExam callback) override; virtual int examJudgeSetPerformCallback(examJudgeCallbackPerform callback) override; - virtual int examJudgeArtificialMark(int itemno, const char* serial) override; + virtual int examJudgeArtificialMark(int itemno, const char* serial, int type) override; virtual int examJudgeArtificialItem(int itemno, int type) override; virtual int examJudgeSoundEnd(int itemno, const char* code, int type) override; virtual const char* examJudgeTrackFile() override; diff --git a/entry/src/main/cpp/sdk/exam/IExamCar.cpp b/entry/src/main/cpp/sdk/exam/IExamCar.cpp index 5a9f480e..99718481 100644 --- a/entry/src/main/cpp/sdk/exam/IExamCar.cpp +++ b/entry/src/main/cpp/sdk/exam/IExamCar.cpp @@ -89,6 +89,7 @@ int IExamCar::examJudgeBeginExam(const char* data, int len) m_timeEnd = 0; m_disForward = 0; m_disBackward = 0; + memset(m_disGears, 0, sizeof(m_disGears)); m_message = ""; m_codes.clear(); m_marks.clear(); @@ -117,7 +118,19 @@ int IExamCar::examJudgeBeginExam(const char* data, int len) int IExamCar::examJudgeEndExam() { - IAutoLock(m_mtx); + logtrace("end-exam-judge begin %s", target().c_str()); + //IAutoLock(m_mtx); + m_handle->addRealtime(Package::v3_end, ""); + return QE(codeSuccess); +} + +int IExamCar::examJudgeEndExamFinish() +{ + logtrace("end-exam begin %s", target().c_str()); + //IAutoLock(m_mtx); + + createEventExamFinish(ExamFinishArti); + m_handle->clearRealtime(); if(m_examState == examStateEnd) { @@ -166,11 +179,11 @@ int IExamCar::examJudgeRealExam2(const char* data, int len) return QE(codeSuccess); } -int IExamCar::examJudgeArtificialMark(int itemno, const char* serial) +int IExamCar::examJudgeArtificialMark(int itemno, const char* serial, int type) { IAutoLock(m_mtx); logtrace("artificial-mark itemNo=%d, serial=%s", itemno, serial); - ErrorCode code = examArtifMark(ExamItemCode(itemno), serial); + ErrorCode code = examArtifMark(ExamItemCode(itemno), serial, MarkType(type)); examPerformSummary(); return code; } @@ -180,7 +193,6 @@ int IExamCar::examJudgeArtificialItem(int itemno, int type) IAutoLock(m_mtx); logtrace("artificial-item itemNo=%d, type=%d", itemno, type); ErrorCode code = examArtifItem(ExamItemCode(itemno), ArtifItemType(type)); - //examPerformSummary(); return code; } @@ -303,15 +315,24 @@ void IExamCar::createEventMoveState(const TEventCarMove& event) FactoryExamService->examJudgeCallbackRealExamToCaller(data.c_str(), data.size()); } -void IExamCar::createEventExamFinish(void) +void IExamCar::createEventExamFinish(ExamFinishType type) { - //__DELETE__(m_track); //这里需不需要???这里停止录轨迹 + examPerformSummary(); + m_examState = examStateFinish; TJudgeData exam; exam.event = ExamEventTypeExamFinish; exam.sj = GetCurrentTime2(); - exam.ksjs = {m_disForward, m_disBackward}; + exam.ksjs.type = type; + exam.ksjs.qjjl = m_disForward; + exam.ksjs.dcjl = m_disBackward; + exam.ksjs.d1 = m_disGears[1]; + exam.ksjs.d2 = m_disGears[2]; + exam.ksjs.d3 = m_disGears[3]; + exam.ksjs.d4 = m_disGears[4]; + exam.ksjs.d5 = m_disGears[5]; + exam.ksjs.d6 = m_disGears[6]; std::string data = m_parser->toDataString(exam); FactoryExamService->examJudgeCallbackRealExamToCaller(data.c_str(), data.size()); logtrace("exam-finish-event %s", target().c_str()); @@ -363,6 +384,10 @@ void IExamCar::createEventLane(const TEventLane& event) void IExamCar::examPerformSummary() { + if(historyCount() == 0) + { + return; + } const Pointi& dis = historyAiGps(); TPerformData exam; exam.time = elapsedLastTime(); @@ -457,6 +482,11 @@ void IExamCar::doExamDatagram(Package* pkg) //m_history->push(cg); } + else if(pkg->proto == Package::v3_end) + { + examJudgeEndExamFinish(); + } + } void IExamCar::calcDistance() @@ -474,20 +504,24 @@ void IExamCar::calcDistance() double x = h.x - c.x; double y = h.y - c.y; int a = std::round(std::sqrt(x*x + y*y)); - CarMoveState state = historyMoveState(); - switch(state) + switch(m_cg->move) { case moveForward: m_disForward += a; break; case moveBackward: m_disBackward += a; break; default: break; } - //logdebug("move=%d,dis=%dCM", state, a); m_cg->ai_ljjl_cm = m_disForward; m_cg->ai_dcjl_cm = m_disBackward; m_cg->ai_ljjl = m_disForward/100.0; m_cg->ai_dcjl = m_disBackward/100.0; - //logdebug("calcDistance state=%d a=%d", state, a); + if(m_cg->move == moveForward) + { + int gear = m_cg->real.sensor.dw; + m_disGears[gear] += a; + } + + //logdebug("move=%d,dis=%dCM", state, a); } int64 IExamCar::GetCurrentTime2() const diff --git a/entry/src/main/cpp/sdk/exam/IExamCar.h b/entry/src/main/cpp/sdk/exam/IExamCar.h index e2085acd..5cf63449 100644 --- a/entry/src/main/cpp/sdk/exam/IExamCar.h +++ b/entry/src/main/cpp/sdk/exam/IExamCar.h @@ -30,7 +30,7 @@ public: virtual int examJudgeEndExam() override; virtual int examJudgeRealExam(const char* data, int len) override; virtual int examJudgeRealExam2(const char* data, int len) override; - virtual int examJudgeArtificialMark(int itemno, const char* serial) override; + virtual int examJudgeArtificialMark(int itemno, const char* serial, int type) override; virtual int examJudgeArtificialItem(int itemno, int type) override; virtual int examJudgeSoundEnd(int itemno, const char* code, int type) override; virtual const char* examJudgeTrackFile() override; @@ -49,7 +49,7 @@ public: virtual void createEventFinishItem(const TEventFinishItem& event) override; virtual void createEventMarkItem(const TEventItemMark& event) override; virtual void createEventMoveState(const TEventCarMove& event) override; - virtual void createEventExamFinish(void) override; + virtual void createEventExamFinish(ExamFinishType type) override; virtual void createEventCancelItem(const TEventCancelItem& event) override; virtual void createEventSound(const TEventSound& event) override; virtual void createEventLight(const TEventLight& event) override; @@ -116,12 +116,14 @@ public: virtual ErrorCode examGoonExam() = 0; virtual ErrorCode examEndExam() = 0; virtual ErrorCode examJudgeExam() = 0; - virtual ErrorCode examArtifMark(ExamItemCode itemno, const std::string& serial) = 0; + virtual ErrorCode examArtifMark(ExamItemCode itemno, const std::string& serial, MarkType type) = 0; virtual ErrorCode examArtifItem(ExamItemCode itemno, ArtifItemType type) = 0; virtual ErrorCode examSoundEnd(ExamItemCode itemno, const std::string& code, PlaySoundType type) = 0; virtual bool examDrawMap() = 0; + virtual bool examMarkItem(ExamItemCode itemNo, const std::string& serial, bool once=false, bool force=false, bool event=true, MarkType type=MarkTypeAuto) = 0; public: + virtual int examJudgeEndExamFinish(); //执行处理每一帧的GPS传感数据 virtual void doExamDatagram(Package* pkg); //前进 后退 距离计算 @@ -145,6 +147,7 @@ protected: int m_disForward = 0; //累计前进距离(单位厘米) 老的代码里也叫累计距离, 行驶距离=累计距离-倒车距离 int m_disBackward= 0; //累计倒车距离(单位厘米) 老的代码里也叫倒车距离 + int m_disGears[20]; //档位距离 int m_grade = 0; //当前得分 int m_gradePass = 0; //考试及格分数 @@ -173,9 +176,6 @@ public: explicit IExamCarSub2() = default; virtual ~IExamCarSub2() = default; - //扣分 - virtual bool sub2MarkItem(ExamItemCode itemNo, const std::string& serial, bool once, bool force=false, bool event=true) = 0; - //查找考试项目对象 virtual IExamItem* findExamItem(ExamItemCode itemNo) = 0; //是否是需要考试项目 @@ -207,8 +207,6 @@ public: virtual ISub3JudgeItem* currentItem() const = 0; //通用评判项目对象,只要是考试状态不会是NULL virtual ISub3JudgeItem* commItem() const = 0; - //Kind:0 自动评判 1:考车人工扣分 2:远程下发的考试扣分 - virtual bool judgeMark(int ItemNo, const std::string& MarkSerial, bool OnlyOneID=false, bool ForceID=false, bool event=true, int8 Kind=0) = 0; virtual const std::map& allExamItem() const = 0; //路口项目是否正考,如果路口项目没有结束 diff --git a/entry/src/main/cpp/sdk/exam/IExamCarAbstract.h b/entry/src/main/cpp/sdk/exam/IExamCarAbstract.h index 4d7a0612..e3f102c1 100644 --- a/entry/src/main/cpp/sdk/exam/IExamCarAbstract.h +++ b/entry/src/main/cpp/sdk/exam/IExamCarAbstract.h @@ -33,7 +33,7 @@ public: //考车移动状态改变事件 virtual void createEventMoveState(const TEventCarMove& event) = 0; //考试结束事件 - virtual void createEventExamFinish(void) = 0; + virtual void createEventExamFinish(ExamFinishType type) = 0; //项目取消事件 virtual void createEventCancelItem(const TEventCancelItem& event) = 0; //语音播报和提示事件 diff --git a/entry/src/main/cpp/sdk/exam/IExamInterface.h b/entry/src/main/cpp/sdk/exam/IExamInterface.h index e8d762ef..1814c469 100644 --- a/entry/src/main/cpp/sdk/exam/IExamInterface.h +++ b/entry/src/main/cpp/sdk/exam/IExamInterface.h @@ -20,7 +20,7 @@ public: virtual int examJudgeEndExam() = 0; virtual int examJudgeRealExam(const char* data, int len) = 0; virtual int examJudgeRealExam2(const char* data, int len) = 0; - virtual int examJudgeArtificialMark(int itemno, const char* serial) = 0; + virtual int examJudgeArtificialMark(int itemno, const char* serial, int type) = 0; virtual int examJudgeArtificialItem(int itemno, int type) = 0; virtual int examJudgeSoundEnd(int itemno, const char* code, int type) = 0; virtual const char* examJudgeTrackFile() = 0; diff --git a/entry/src/main/cpp/sdk/judge/HJudgeItem.h b/entry/src/main/cpp/sdk/judge/HJudgeItem.h index 2c601b78..92be9c96 100644 --- a/entry/src/main/cpp/sdk/judge/HJudgeItem.h +++ b/entry/src/main/cpp/sdk/judge/HJudgeItem.h @@ -256,7 +256,7 @@ struct TSub3Item10Ccxx //超车 //1:初始超车道阶段 2:初始普通车道阶段 3:左侧超车阶段 4:完成左侧超车阶段 //5:回原车道阶段 6:完成回原车道阶段 int8 Status = 0; - bool CS_CCD_Flag = false; + bool CS_CCD_Flag = false; //初始是否在超车到标记 int Temp_LJJL_CCD_PTCD = 0; //进入项目时的累计距离(超车道->普通车道) int Temp_LJJL_2 = 0; //变道发生时的累计距离 int64 Temp_TM = 0; //变道、超车以前后轮都过线的时间 @@ -273,8 +273,8 @@ struct TSub3Item10Ccxx //超车 int CS_CCD_Max_XSJL = 0; //超车道上最多可以行驶的距离 //初始超车道,二次超车最小行驶距离(如果初始在超车道上,需要驶离超车道, //然后行驶规定的距离后,再次进入超车道超车) - int CS_CCD_ErCiChaoChe_Min_XSJL = 0; - bool CS_CCD_ErCiChaoChe_Min_XSJL_OK = false; + int CS_CCD_ErCiChaoChe_Min_XSJL = 0; //初始在超车道行驶到普通车道,要行使一段距离才能再次进入超车道 + bool CS_CCD_ErCiChaoChe_Min_XSJL_OK = false; //初始在超车道行驶到普通车道,要行使一段距离才能再次进入超车道状态 int64 St4_HuiYuanCheDao_TM = 0; //超车回原车道时刻 int St4_HuiYuanCheDao_Miao = 0; //超车回原车道时间 int Temp_CC_CSSJ = 0; //超车达到车速的持续时间 20150507 @@ -428,7 +428,10 @@ struct TSub3Item41Mndg //模拟灯光 41 int64 Lt_LastChange_TM = 0; //灯光最后变化时间 int Lt_YJ_cs = 0; //远近光灯变化次数 20150327 - std::array Lt_Change; //: array[0..6] of string; //0:未定义 1:示宽,2:双跳,3:雾灯,4:远光,5:近光,6:交替, 注意:记录灯光的变化,示宽是从有到无,其他是从无到有 + //std::array Lt_Change; //: array[0..6] of string; //0:未定义 1:示宽,2:双跳,3:雾灯,4:远光,5:近光,6:交替, 注意:记录灯光的变化,示宽是从有到无,其他是从无到有 + std::string Lt_Change; + + std::string Lt_Change_Last; int8 ItemNo = 0, ItemStatus = 0; //St 控制具体项目 St1控制指定项目的状态 int64 Snd_Wav_Start_TM = 0; //语音开始时间 @@ -469,6 +472,14 @@ struct TSub3Item02Qbxx //起步 2 int QiBu_LJJL_CM = 0; bool Error_SSC_Flag = false; + + + //以下是溜车评判需要用到的变量 + int PubMaxLCValue = 0; + Pointi PubLCTCPtt; + double PubLCTC_GPS_JD = 0.0; + double PubLCTC_GPS_WD = 0.0; + bool PubCanMarkLC50Flag = true; //注意初始必须是true }; diff --git a/entry/src/main/cpp/sdk/judge/sub2/ISub2JudgeWrap.cpp b/entry/src/main/cpp/sdk/judge/sub2/ISub2JudgeWrap.cpp index 67702d7f..48b1174a 100644 --- a/entry/src/main/cpp/sdk/judge/sub2/ISub2JudgeWrap.cpp +++ b/entry/src/main/cpp/sdk/judge/sub2/ISub2JudgeWrap.cpp @@ -690,8 +690,7 @@ void ISub2JudgeWrap::setFinishItem() noexcept bool ISub2JudgeWrap::markItemGrade(ExamItemCode itemNo, const std::string& serial, bool once, bool force) noexcept { - static constexpr bool event = true; - bool ok = m_car->sub2MarkItem(itemNo, serial, once, force, event); + bool ok = m_car->examMarkItem(itemNo, serial, once, force, true, MarkTypeAuto); if(m_car->isExamMode() && !m_car->isQualified()) { m_exam->setState(itemStateEnd); diff --git a/entry/src/main/cpp/sdk/judge/sub3/ISub3JudgeWrap.h b/entry/src/main/cpp/sdk/judge/sub3/ISub3JudgeWrap.h index fdab2ff0..2fa23d5b 100644 --- a/entry/src/main/cpp/sdk/judge/sub3/ISub3JudgeWrap.h +++ b/entry/src/main/cpp/sdk/judge/sub3/ISub3JudgeWrap.h @@ -33,7 +33,7 @@ class JUDGE_API ISub3JudgeWrap : public ISub3JudgeItem //itemno, serial, once, force #define JUDGE_MARK_SUB3(itemno, serial, ...) \ { \ - if(m_car->judgeMark(JUDGE_VA_ARGS(itemno, serial, ##__VA_ARGS__))) \ + if(m_car->examMarkItem(JUDGE_VA_ARGS(itemno, serial, ##__VA_ARGS__))) \ { \ logtrace("sub3-mark itemno=%d,serial=%s", itemno, serial); \ } \ diff --git a/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge01Sczb.cpp b/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge01Sczb.cpp index b6ab1be6..9bcda5fe 100644 --- a/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge01Sczb.cpp +++ b/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge01Sczb.cpp @@ -116,7 +116,7 @@ void Sub3Judge01Sczb::dealJudgeItem() const TKfXm& m = sczb_mark[i]; //强制扣分 //JudgeKM3Obj.Mark(StrToInt(Temp1), Temp2, False, True); - JUDGE_MARK_SUB3(m.xmdm, m.kfdm.c_str(), false, true, false); + JUDGE_MARK_SUB3(m.xmdm, m.kfdm.c_str(), false, true, false, MarkTypeArti); } } m_exam->TestPro = ItemProFlagEnd; diff --git a/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge02Qbxx.cpp b/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge02Qbxx.cpp index c49972ca..470556b6 100644 --- a/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge02Qbxx.cpp +++ b/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge02Qbxx.cpp @@ -38,6 +38,16 @@ bool Sub3Judge02Qbxx::dealJudgeEnter() const TChuanGan* cg = m_car->historyChuanGan(); m_itemv.Temp_JL_CM = cg->ai_ljjl_cm; + if(m_car->disForward() > 10*100) //10米 + { + //20240730 在济南修改 yhy + //根据程军华口述修改过滤,在下面这种情况下: + //如果在做模拟灯光的时候,还没起步之前差分丢了,车子开起来一段距离后差分又恢复了,当进入路口直行项目时,如果这个时候正好在路口等红灯停车了,会触发第一次起步 + //路口直行是不需要打灯的,而程序又第一次触发了起步项目,又要打左灯,考生怎么操作都会扣分, + //所以这里过滤下,如果起步的时候前进的距离超过10米了就不算第一次起步了,就不判首次起步打左灯了 + m_Pub_First_QiBu_Flag = true; + } + m_itemv.State = 1; //车辆停车状态到前进距离小于1米的阶段 m_exam->TestPro = ItemProFlagJudge; @@ -131,10 +141,15 @@ void Sub3Judge02Qbxx::dealJudgeItem() //10秒未起步 nogo_timeout(); + //溜车评判 20240730 + Judge_LiuChe(); + if(cg->ai_ljjl_cm - m_itemv.Temp_JL_CM >= 100) { if(cg->move == moveForward && his1->move == moveForward) { + Judge_QiBu_FXD_LaBa(); //20240730 + Judge_QiBu_GuaCuoDang(); //20240730 m_itemv.State = 2; return; } @@ -194,11 +209,9 @@ void Sub3Judge02Qbxx::dealJudgeItem() void Sub3Judge02Qbxx::nogo_timeout() { const TChuanGan* cg = m_car->historyChuanGan(); - const TGpsInfo& gps = cg->real.gps; const TSensorInfo& sor = cg->real.sensor; const TChuanGan* his1 = m_car->historyChuanGan(1); - const TGpsInfo& gps1 = his1->real.gps; const TSensorInfo& sor1 = his1->real.sensor; //档位或者手刹信号发生变化,且变化的结果是前进挡和松手刹状态,开始计时,10秒后扣分 @@ -260,3 +273,181 @@ void Sub3Judge02Qbxx::nogo_timeout() } */ } + + +//6、起步方向灯、喇叭 +void Sub3Judge02Qbxx::Judge_QiBu_FXD_LaBa() +{ + const TChuanGan* cg = m_car->historyChuanGan(); + const TSensorInfo& sor = cg->real.sensor; + const TChuanGan* his1 = m_car->historyChuanGan(1); + //const TChuanGan* his2 = m_car->historyChuanGan(2); + + //1、检查起步前有没有打转向灯 + //if(cg->move == moveForward && his1->move == moveForward && his2->move == moveStop) + if(cg->move == moveForward && his1->move == moveForward) + { + //可以多次触发起步,但是起步方向灯,全程只评判一次 + if(m_Pub_First_QiBu_Flag == true) return; + m_Pub_First_QiBu_Flag = true; + bool FindFlag = (sor.zfxd == SYES && sor.yfxd == SNOT); + if(!FindFlag) + { + for(int i = 1; i < 50; i++) + { + const TChuanGan* hisi = m_car->historyChuanGan(i); + if(hisi == nullptr) break; + const TSensorInfo& sori = hisi->real.sensor; + if(hisi->move == moveStop) + { + if(sori.zfxd == SYES && sori.yfxd == SNOT) + { + FindFlag = true; + break; + } + } + } + } + if(!FindFlag) + { + JUDGE_MARK_SUB3(2, "42", false, true); //JUDGE_MARK_SUB3(20, "73", false, true); + } + else + { + //看方向灯是否小于3秒 + int OKNum = 0; + for(int i = 1; i < 50; i++) + { + const TChuanGan* hisi = m_car->historyChuanGan(i); + if(hisi == nullptr) break; + const TSensorInfo& sori = hisi->real.sensor; + if(hisi->move == moveStop) + { + if(sori.zfxd == SYES && sori.yfxd == SNOT) + { + OKNum++; + } + } + } + if(OKNum < 3*FRAMES_PER_SECOND) + { + //JUDGE_MARK_SUB3(20, "224", false, true); + JUDGE_MARK_SUB3(2, "43", false, true); + } + } + + //起步喇叭评判 + FindFlag = (sor.lb == SYES); + if(!FindFlag) + { + int count = m_car->historyCount(); + for(int i = 1; i < 100; i++) + { + if(i >= count) break; + const TChuanGan* hisi = m_car->historyChuanGan(i); + const TSensorInfo& sori = hisi->real.sensor; + if(hisi->move == moveStop) + { + if(sori.lb == SYES) + { + FindFlag = true; + break; + } + } + } + } + if(!FindFlag) + { + JUDGE_MARK_SUB3(2, "07", false, true); + } + } +} + +//22、起步挂错挡 +void Sub3Judge02Qbxx::Judge_QiBu_GuaCuoDang() +{ + if(m_car->historyCount() < 2) return; + const TChuanGan* cg = m_car->historyChuanGan(); + const TChuanGan* his1 = m_car->historyChuanGan(1); + //const TChuanGan* his5 = m_car->historyChuanGan(5); + //const TChuanGan* his10 = m_car->historyChuanGan(10); + //if(cg->move == moveForward && his1->move == moveStop && his5->move == moveStop && his10->move == moveStop) + if(cg->move == moveForward && his1->move == moveForward) + { + const TSensorInfo& sor = cg->real.sensor; + +#ifdef JUDGE_USE_INSPECT + if(sor.dw_plc >= 2) //无锡所用原始档位 + { + JUDGE_MARK_SUB3(2, "44", false); + } +#else + if(sor.dw >= 2) + { + JUDGE_MARK_SUB3(2, "44", false); + } +#endif + } +} + +//1、溜车评判 +void Sub3Judge02Qbxx::Judge_LiuChe() +{ + if(!m_car->rtkEnabled() || !m_car->rtkEnabled(1) || !m_car->rtkEnabled(2)) return; + + const TChuanGan* cg = m_car->historyChuanGan(); + const TGpsInfo& gps = cg->real.gps; + const TSensorInfo& sor = cg->real.sensor; + const TChuanGan* his1 = m_car->historyChuanGan(1); + + static constexpr int LCValue = 32; //后溜车距离 + static constexpr int LC30FaZhi = 12; + if(cg->move == moveForward && his1->move == moveForward) //前进的时候要评判溜车小于30厘米的 + { + if(m_itemv.PubMaxLCValue >= LC30FaZhi && m_itemv.PubMaxLCValue <= LCValue) + { + //通用或起步项目 + JUDGE_MARK_SUB3(2, "47", false); + } + + m_itemv.PubLCTCPtt.x = 0; + m_itemv.PubLCTCPtt.y = 0; + m_itemv.PubMaxLCValue = 0; + m_itemv.PubCanMarkLC50Flag = true; + } + if(sor.dw != 9 && sor.dw != 6 && sor.ssc == SNOT) + { + //if(m_itemv.PubLCTCPtt.x == 0 && m_itemv.PubLCTCPtt.y == 0 && m_car->rtkEnabled()) + { + const TChuanGan* his2 = m_car->historyChuanGan(2); + if(cg->move == moveStop && his1->move == moveStop && his2->move == moveStop) + { + m_itemv.PubLCTCPtt.x = gps.ai_gps.x; + m_itemv.PubLCTCPtt.y = gps.ai_gps.y; + m_itemv.PubLCTC_GPS_JD = gps.jd; + m_itemv.PubLCTC_GPS_WD = gps.wd; + m_itemv.PubMaxLCValue = 0; + } + } + + //ExamSensor* sensor = m_car->sensor(); //sensor->calcMoveState(); + if(m_itemv.PubLCTCPtt.x != 0 && m_itemv.PubLCTCPtt.y != 0 && cg->move != moveForward) // JudgeKM3Obj.GetMovingState <> 1 + { + Point Ptt = gps.ai_gps; + int b = m_itemv.PubLCTCPtt.x - Ptt.x; + int c = m_itemv.PubLCTCPtt.y - Ptt.y; + int a = std::round(std::sqrt(b*b + c*c)); //cm + int LC = a; + if(m_itemv.PubMaxLCValue < LC) + { + m_itemv.PubMaxLCValue = LC; + } + //溜车大于30了,直接扣分 + if(m_itemv.PubCanMarkLC50Flag == true && m_itemv.PubMaxLCValue > LCValue) + { + JUDGE_MARK_SUB3(2, "46", false); + m_itemv.PubCanMarkLC50Flag = false; + } + } + } +} diff --git a/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge02Qbxx.h b/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge02Qbxx.h index 04285dec..3cdce741 100644 --- a/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge02Qbxx.h +++ b/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge02Qbxx.h @@ -59,10 +59,16 @@ public: protected: //具备起步条件,10秒没有起步 void nogo_timeout(); + //1、溜车评判 + void Judge_LiuChe(); + //6、起步方向灯、喇叭 + void Judge_QiBu_FXD_LaBa(); + //22、起步挂错挡 + void Judge_QiBu_GuaCuoDang(); private: TSub3Item02Qbxx m_itemv; - + bool m_Pub_First_QiBu_Flag = false; //起步方向灯和喇叭 只判一次 第一次进起步项目才判 }; #endif // SUB3JUDGE02QBXX_H diff --git a/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge10Ccxx.cpp b/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge10Ccxx.cpp index 74ba97c6..1d6a988e 100644 --- a/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge10Ccxx.cpp +++ b/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge10Ccxx.cpp @@ -510,13 +510,15 @@ void Sub3Judge10Ccxx::dealJudgeItem() //在普通车道上,开始超车距离 if(m_itemv.Status == 2) //普通车道上,准备超车 { - if(m_itemv.CS_CCD_Flag == true) + //如果初始在超车道,行驶到普通车道,要行驶一段距离504参数才能在进超车道 + if(m_itemv.CS_CCD_Flag == true && m_itemv.CS_CCD_ErCiChaoChe_Min_XSJL_OK == false) { //初始超车道,二次超车最小行驶距离(如果初始在超车道上,需要驶离超车道, //然后行驶规定的距离后,再次进入超车道超车) if(cg->ai_ljjl - m_itemv.Temp_LJJL_CCD_PTCD >= m_itemv.CS_CCD_ErCiChaoChe_Min_XSJL) { m_itemv.CS_CCD_ErCiChaoChe_Min_XSJL_OK = true; + m_car->createEventSound({itemNo(), sound::sub3_414001}); return; } } diff --git a/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge20Comm.cpp b/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge20Comm.cpp index 0e662674..b4de8cc7 100644 --- a/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge20Comm.cpp +++ b/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge20Comm.cpp @@ -63,27 +63,29 @@ void Sub3Judge20Comm::dealJudgeItem() //自动靠边停车计算 Call_Auto_KBTC(); //Step0-2触发模拟灯光 - if(!m_car->isReplay()) //(Data_Replay.Kind = 2) then //杨海洋实际考试模式(就是说非回放模式的) - { - CallMoNiDengGuang(); //yhyflag - } - else - { - //回放相关的 - if(sor.rmndg == SYES) - { - TKM3Item* item = m_car->findExamItem(Sub3ItemType41Mndg); - if(item && item->TestPro == ItemProFlagIdle) - { - item->Item_Color = itemStateZk; - item->TestPro = ItemProFlagInit; - item->FinishFlag = false; - } - } - } + + CallMoNiDengGuang(); //240710 + //if(!m_car->isReplay()) //(Data_Replay.Kind = 2) then //杨海洋实际考试模式(就是说非回放模式的) + //{ + // CallMoNiDengGuang(); //yhyflag + //} + //else + //{ + // //回放相关的 + // if(sor.rmndg == SYES) + // { + // TKM3Item* item = m_car->findExamItem(Sub3ItemType41Mndg); + // if(item && item->TestPro == ItemProFlagIdle) + // { + // item->Item_Color = itemStateZk; + // item->TestPro = ItemProFlagInit; + // item->FinishFlag = false; + // } + // } + //} //1、溜车评判 - Judge_LiuChe(); + //Judge_LiuChe(); //移到起步专项里评判 20240730 //2、连续2次挂挡不进 Judge_GuaDangBuJin(); //3、空挡滑行 @@ -95,7 +97,7 @@ void Sub3Judge20Comm::dealJudgeItem() Judge_YaXian_10S_XuXian(); //6、起步方向灯、喇叭 - Judge_QiBu_FXD_LaBa(); + //Judge_QiBu_FXD_LaBa(); //移到起步项目里了 20240730 //7、连续变道 Judge_LianXuBianDao(); @@ -129,7 +131,7 @@ void Sub3Judge20Comm::dealJudgeItem() //21、考试过程中打开车门 Judge_DaKaiCheMen(); //22、起步挂错挡 - Judge_QiBu_GuaCuoDang(); + //Judge_QiBu_GuaCuoDang(); //移到起步专项里评判 20240730 //23、使用挡位与车速长时间不匹配,造成车辆发动机转速过高或过低(发动机转速〉2500转或〈900转,且时间大于30秒)扣100分 Judge_DangWei_CS_ZS(); @@ -172,10 +174,6 @@ void Sub3Judge20Comm::Init_ZongHe() m_itemvCJH.ZdKbTcJl = 1; } //溜车变量初始化 - m_PubLCTCPtt.x = 0; - m_PubLCTCPtt.y = 0; - m_PubMaxLCValue = 0; - m_PubCanMarkLC50Flag = true; //SysSet[529]:模拟灯光是否需要人脸验证 //说明:这个参数目前我没有实际的用到 @@ -928,7 +926,6 @@ void Sub3Judge20Comm::CallQiBu(int qbsj) } //SysSet[502]:起步触发顺序:0-无限制,1-上车准备完成,2-模拟灯光完成 - const std::vector& s502 = TableSysSet->asArray502(); int s502_9 = s502.size() > 9 && s502[9] != "" ? std::atoi(s502[9].c_str()) : 0; //StrToIntdef(GetDotStr(10, sysset[502], ','), 0); if(s502_9 == 1) @@ -949,8 +946,7 @@ void Sub3Judge20Comm::CallQiBu(int qbsj) if(item41) { if(item41->Item_Color == itemStateWk || item41->Item_Color == itemStateZk) return; - - if(MilliSecondsBetween(m_car->GetCurrentTime2(), item41->EndTime) < 2000) return; + if(MilliSecondsBetween(m_car->GetCurrentTime2(), item41->EndTime) < 2*SECOND) return; } } @@ -999,9 +995,12 @@ void Sub3Judge20Comm::CallQiBu(int qbsj) } } -//1、溜车评判 +/* +//1、溜车评判 //移到起步专项里评判 20240730 void Sub3Judge20Comm::Judge_LiuChe() { + if(!m_car->rtkEnabled() || !m_car->rtkEnabled(1) || !m_car->rtkEnabled(2)) return; + const TChuanGan* cg = m_car->historyChuanGan(); const TGpsInfo& gps = cg->real.gps; const TSensorInfo& sor = cg->real.sensor; @@ -1009,7 +1008,6 @@ void Sub3Judge20Comm::Judge_LiuChe() static constexpr int LCValue = 32; //后溜车距离 static constexpr int LC30FaZhi = 12; - if(!m_car->rtkEnabled() || !m_car->rtkEnabled(1)) return; if(cg->move == moveForward && his1->move == moveForward) //前进的时候要评判溜车小于30厘米的 { if(m_PubMaxLCValue >= LC30FaZhi && m_PubMaxLCValue <= LCValue) @@ -1063,7 +1061,7 @@ void Sub3Judge20Comm::Judge_LiuChe() } } } - +*/ //2、连续两次挂挡不进 void Sub3Judge20Comm::Judge_GuaDangBuJin() @@ -1376,7 +1374,7 @@ void Sub3Judge20Comm::Judge_KongDangHuaXing() { if(Tools::pos("C", m_car->carType2())) { - if(sor.lhq == SYES && cg->move == moveForward) + if(sor.lhq == SYES && cg->move == moveForward) { m_itemvCJH.kdhx_tk_lhq = cg->tkCnt; } @@ -1960,6 +1958,7 @@ void Sub3Judge20Comm::Judge_YaXian_10S_XuXian() } } +/* //6、起步方向灯、喇叭 void Sub3Judge20Comm::Judge_QiBu_FXD_LaBa() { @@ -1994,7 +1993,7 @@ void Sub3Judge20Comm::Judge_QiBu_FXD_LaBa() } if(!FindFlag) { - JUDGE_MARK_SUB3(20, "73", false, true); + JUDGE_MARK_SUB3(2, "42", false, true); //JUDGE_MARK_SUB3(20, "73", false, true); } else { @@ -2046,6 +2045,7 @@ void Sub3Judge20Comm::Judge_QiBu_FXD_LaBa() } } } +*/ //是否是连续变道 bool Sub3Judge20Comm::Is_Lxbd_New() @@ -4224,16 +4224,16 @@ void Sub3Judge20Comm::Judge_QiBuDang_50() const TChuanGan* his1 = m_car->historyChuanGan(1); const TChuanGan* his2 = m_car->historyChuanGan(2); - if((cg->move == moveStop && his1->move == moveStop && his2->move == moveStop) || (sor.dw >= 2 && sor.dw <= 9)) + if((cg->move == moveStop && his1->move == moveStop && his2->move == moveStop) || (sor.dw != 1)) { m_itemvXLG.CSH_QBDW_Flag = false; } if(cg->move == moveForward && his1->move == moveForward) { - if(sor.dw == 1) + if(sor.dw == 1 && cg->ai_ljjl_cm > 0) { - if(!m_itemvXLG.CSH_QBDW_Flag && cg->ai_ljjl_cm > 0) + if(!m_itemvXLG.CSH_QBDW_Flag) // && cg->ai_ljjl_cm > 0 { m_itemvXLG.CSH_QBDW_Flag = true; m_itemvXLG.Mark_20_77_Flag = false; @@ -4439,6 +4439,7 @@ void Sub3Judge20Comm::Judge_DaKaiCheMen() } } +/* //22、起步挂错挡 void Sub3Judge20Comm::Judge_QiBu_GuaCuoDang() { @@ -4464,6 +4465,7 @@ void Sub3Judge20Comm::Judge_QiBu_GuaCuoDang() #endif } } +*/ //23、挡位与车速、转速不匹配 void Sub3Judge20Comm::Judge_DangWei_CS_ZS() @@ -4797,7 +4799,7 @@ void Sub3Judge20Comm::Judge_DangWei_CS_ZS() //24、全程次高挡评判 void Sub3Judge20Comm::Judge_CiGaoDang() { - if(m_car->allItemFinish() == true) //全程次高挡评判 KM3AllPass() + if(m_car->allItemFinish() && m_car->isQualified()) //全程次高挡评判 KM3AllPass() { if(m_itemvXLG.CGD_Nums == 0) { diff --git a/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge20Comm.h b/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge20Comm.h index 7764fbb4..b3fd942a 100644 --- a/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge20Comm.h +++ b/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge20Comm.h @@ -109,8 +109,8 @@ protected: void CallQiBu(int qbsj = 5); //======================================= - //1、溜车评判 - void Judge_LiuChe(); + //1、溜车评判 //移到起步专项里评判 20240730 + //void Judge_LiuChe(); //2、连续两次挂挡不进 void Judge_GuaDangBuJin(); @@ -127,8 +127,8 @@ protected: //长时间骑轧车道分界线行驶 void Judge_YaXian_10S_XuXian(); - //6、起步方向灯、喇叭 - void Judge_QiBu_FXD_LaBa(); + //6、起步方向灯、喇叭 //移到起步专项里评判 20240730 + //void Judge_QiBu_FXD_LaBa(); //7、连续变更两条以上车道 //重点 void Judge_LianXuBianDao(); @@ -182,8 +182,8 @@ protected: //21、打开车门 void Judge_DaKaiCheMen(); - //22、起步挂错挡 - void Judge_QiBu_GuaCuoDang(); + //22、起步挂错挡 //移到起步专项里评判 20240730 + //void Judge_QiBu_GuaCuoDang(); //23、挡位与车速、转速不匹配 void Judge_DangWei_CS_ZS(); @@ -206,14 +206,8 @@ private: //std::string m_PubTongYong_Msg; int m_sfyz_state = 0; //模拟灯光是否需要人脸验证 bool m_qbjc_zuoyi = false; //20151207 贵州起步检查 - //以下是溜车评判需要用到的变量 - int m_PubMaxLCValue = 0; - Pointi m_PubLCTCPtt; - double m_PubLCTC_GPS_JD = 0.0; - double m_PubLCTC_GPS_WD = 0.0; - bool m_PubCanMarkLC50Flag = true; //注意初始必须是true - bool m_Pub_First_QiBu_Flag = false; + //bool m_Pub_First_QiBu_Flag = false; //int Pub_JSC_JL = 0; //in car //bool PubCanJudge_XiHuoFlag = true; //in car diff --git a/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge41Mndg.cpp b/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge41Mndg.cpp index fa4a68b5..91f56e46 100644 --- a/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge41Mndg.cpp +++ b/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge41Mndg.cpp @@ -26,7 +26,7 @@ bool Sub3Judge41Mndg::dealJudgeEnter() } const TGpsInfo& gps = m_car->historyGps(); - setSeed(gps.sj); //240709 gps.sj + setSeed(gps.sj); //加载合法的灯光 //参考头文件注释说明[灯光类型] // m_lights = @@ -96,6 +96,7 @@ bool Sub3Judge41Mndg::dealJudgeEnter() //Pub_Log('开始模拟夜间New'); //灯光初始化 m_itemv = TSub3Item41Mndg(); + m_itemv.Lt_Change.resize(7, N0); //m_exam->TestPro = ItemProFlagJudge; //ToDo2:生成进项目事件 @@ -160,6 +161,15 @@ void Sub3Judge41Mndg::dealJudgeItem() const TGpsInfo& gps1 = his1->real.gps; const std::string& ksdd = TableSysSet->get211(); + //调试代码 + if(gps.sj - m_lastDealTick > 5*SECOND) + { + m_lastDealTick = gps.sj; + + logtrace("mndg-tick-Op_Step=%d,ItemStatus=%d,Item=%d%d%d", m_itemv.Op_Step,m_itemv.ItemStatus, + m_itemv.ItemNo,m_itemv.SubWav1,m_itemv.SubWav2); + } + if(ksdd == siteof::zjnb) { if(cg->move == moveStop && sor.ssc == SNOT) @@ -260,7 +270,7 @@ void Sub3Judge41Mndg::dealJudgeItem() } else if(m_itemv.ItemNo == 100) //灯光结束 { - logtrace("sound-mndg-end"); + logtrace("mndg-item-end"); m_exam->TestPro = ItemProFlagEnd; if(m_car->isExamDrill()) //训练模式 { @@ -292,7 +302,7 @@ void Sub3Judge41Mndg::dealJudgeItem() } else { - logerror("mndg-error Op_Step=%d,ItemNo=%d,Status=%d",m_itemv.Op_Step, m_itemv.ItemNo, m_itemv.ItemStatus); + logerror("mndg-error-Op_Step=%d,ItemNo=%d,Status=%d",m_itemv.Op_Step, m_itemv.ItemNo, m_itemv.ItemStatus); } char buf[128] = {0}; @@ -363,18 +373,18 @@ void Sub3Judge41Mndg::UpdateDengGuangChange() { if(MilliSecondsBetween(gps.sj, m_itemv.Lt_YJ_TM) < m_itemv.P_YJGD_JT_YS) { - m_itemv.Lt_Change[6] = "1"; + m_itemv.Lt_Change[6] = Y1; m_itemv.Lt_YJ_TM = 0; m_itemv.Lt_YJ_cs++; //Inc(m_itemv.Lt_YJ_cs); //20150327 if(ksdd == siteof::shijiazhuang1001) { if(m_itemv.Lt_YJ_cs >= 2) { - m_itemv.Lt_Change[6] = "1"; + m_itemv.Lt_Change[6] = Y1; } else { - m_itemv.Lt_Change[6] = "0"; + m_itemv.Lt_Change[6] = N0; } } @@ -382,9 +392,9 @@ void Sub3Judge41Mndg::UpdateDengGuangChange() if(ksdd == siteof::gdjykm3 || ksdd == siteof::jiuquan) { if(m_itemv.Lt_YJ_cs == 2) - m_itemv.Lt_Change[6] = "1"; + m_itemv.Lt_Change[6] = Y1; else - m_itemv.Lt_Change[6] = "0"; + m_itemv.Lt_Change[6] = N0; } } } @@ -422,26 +432,26 @@ void Sub3Judge41Mndg::UpdateDengGuangChange() if(tm <= m_itemv.P_YJGD_JT_YS) { //(m_itemv.Snd_No = 2) and (m_itemv.Snd_No1 = 1) and (m_itemv.St=1) 超车 - m_itemv.Lt_Change[6] = "1"; + m_itemv.Lt_Change[6] = Y1; m_itemv.Lt_YJ_TM = 0; //成功闪灯一次,远近关灯时间清空 m_itemv.Lt_YJ_cs++; //Inc(m_itemv.Lt_YJ_cs); if(ksdd == siteof::shijiazhuang1001) { if(m_itemv.Lt_YJ_cs >= 2) - m_itemv.Lt_Change[6] = "1"; + m_itemv.Lt_Change[6] = Y1; else - m_itemv.Lt_Change[6] = "0"; + m_itemv.Lt_Change[6] = N0; } if(ksdd == siteof::gdjykm3 || ksdd == siteof::jiuquan) { if(m_itemv.Lt_YJ_cs == 2) { - m_itemv.Lt_Change[6] = "1"; + m_itemv.Lt_Change[6] = Y1; } else { - m_itemv.Lt_Change[6] = "0"; + m_itemv.Lt_Change[6] = N0; } } } @@ -451,7 +461,7 @@ void Sub3Judge41Mndg::UpdateDengGuangChange() //如果有闪灯信号,直接赋值就可以了(前提是要有硬件支持) if(sor.sde == SYES && sor1.sde == SNOT) { - m_itemv.Lt_Change[6] = "1"; + m_itemv.Lt_Change[6] = Y1; } //远光,近光, @@ -461,14 +471,14 @@ void Sub3Judge41Mndg::UpdateDengGuangChange() { if(sor.ygd == SYES) { - m_itemv.Lt_Change[4] = "1"; + m_itemv.Lt_Change[4] = Y1; m_itemv.Lt_YJ_TM = 0; } else { if(sor.jgd == SYES) { - m_itemv.Lt_Change[5] = "1"; + m_itemv.Lt_Change[5] = Y1; m_itemv.Lt_YJ_TM = 0; } } @@ -500,12 +510,12 @@ void Sub3Judge41Mndg::UpdateDengGuangChange() } if(Flag1 == true || Flag2 == true || Flag3 == true || Flag4 == true) { - m_itemv.Lt_Change[1] = "1"; + m_itemv.Lt_Change[1] = Y1; } //双跳, if(sor.shtd == SYES && sor1.shtd == SNOT) { - m_itemv.Lt_Change[2] = "1"; + m_itemv.Lt_Change[2] = Y1; } //雾灯, 20181015 @@ -513,12 +523,12 @@ void Sub3Judge41Mndg::UpdateDengGuangChange() { if(sor.wd == SYES && sor1.wd == SNOT) { - m_itemv.Lt_Change[3] = "1"; + m_itemv.Lt_Change[3] = Y1; } } else { - m_itemv.Lt_Change[3] = "0"; + m_itemv.Lt_Change[3] = N0; } } } @@ -527,6 +537,8 @@ void Sub3Judge41Mndg::UpdateDengGuangChange() //0、统一调度 void Sub3Judge41Mndg::CallItemProc() { + logtrace("mndg-Op_Step CallItemProc"); + const TChuanGan* cg = m_car->historyChuanGan(); const TGpsInfo& gps = cg->real.gps; const TSensorInfo& sor = cg->real.sensor; @@ -539,7 +551,7 @@ void Sub3Judge41Mndg::CallItemProc() { if(sor.wd == SYES || sor.zfxd == SYES || sor.yfxd == SYES || sor.shtd == SYES /* || sor.shtd == SYES*/) { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); if(m_car->isQualified() || m_car->isExamDrill()) { m_itemv.ItemNo = 0; @@ -582,7 +594,7 @@ void Sub3Judge41Mndg::CallItemProc() m_itemv.ItemNo = 100; } - logtrace("Op_Step=%d,ItemStatus=%d,Item=%d%d%d", m_itemv.Op_Step,m_itemv.ItemStatus, + logtrace("mndg-item-Op_Step=%d,ItemStatus=%d,Item=%d%d%d", m_itemv.Op_Step,m_itemv.ItemStatus, m_itemv.ItemNo,m_itemv.SubWav1,m_itemv.SubWav2); } } @@ -657,7 +669,7 @@ void Sub3Judge41Mndg::Open_DengGuang() } else { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); if(m_car->isQualified() || m_car->isExamDrill()) { m_itemv.ItemNo = 0; @@ -676,7 +688,7 @@ void Sub3Judge41Mndg::Open_DengGuang() } else { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); if(m_car->isQualified() || m_car->isExamDrill()) //20140722 { m_itemv.ItemNo = 0; @@ -1284,7 +1296,7 @@ void Sub3Judge41Mndg::JiaoTi_DengGuang() { for(size_t i = 0; i < m_itemv.Lt_Change.size(); i++) { - m_itemv.Lt_Change[i] = "0"; + m_itemv.Lt_Change[i] = N0; } m_itemv.Lt_YJ_TM = 0; @@ -1311,7 +1323,7 @@ void Sub3Judge41Mndg::JiaoTi_DengGuang() else if(m_itemv.ItemStatus == 3) //操作结果 { //检查灯光错误 - if(m_itemv.P_IF_Err_Kf) + if(m_itemv.P_IF_Err_Kf && m_itemv.Lt_Change != m_itemv.Lt_Change_Last) { //检查上一个灯光题目:是不是 “车辆发生故障” bool b5 = (m_itemv.LastSubItemNo == 5); @@ -1327,7 +1339,7 @@ void Sub3Judge41Mndg::JiaoTi_DengGuang() if(i == 2 || i == 3) { // //0:未定义 1:示宽, 2:双跳, 3:雾灯,4:远光,5:近光,6:交替, 注意:记录灯光的变化,示宽是从有到无,其他是从无到有 - if(m_itemv.Lt_Change[i] == "1") + if(m_itemv.Lt_Change[i] == Y1) { //打错灯了 if(m_itemv.SubWav1 == 2 || m_itemv.SubWav1 == 3) //按规则翻译,夜间超车相关的 @@ -1399,7 +1411,7 @@ void Sub3Judge41Mndg::JiaoTi_DengGuang() if(sor.zfxd == SYES && sor1.zfxd == SYES) { m_itemv.Cc_Jd = 1; - m_itemv.Lt_Change[6] = "0"; + m_itemv.Lt_Change[6] = N0; } //20171123 if(ksdd == siteof::guizhoubj && MilliSecondsBetween(gps.sj, m_itemv.Snd_Wav_End_TM) > m_itemv.P_zys) @@ -1442,7 +1454,7 @@ void Sub3Judge41Mndg::JiaoTi_DengGuang() } else if(m_itemv.Cc_Jd == 1) { - if(m_itemv.Lt_Change[6] == "1") + if(m_itemv.Lt_Change[6] == Y1) { m_itemv.Cc_Jd = 2; } @@ -1543,7 +1555,7 @@ void Sub3Judge41Mndg::JiaoTi_DengGuang() //雾天行驶 要判断双跳灯+雾灯 //检查灯光正确 //非特殊地点版本 - if(m_itemv.Lt_Change[6] == "1") + if(m_itemv.Lt_Change[6] == Y1) { if(m_itemv.Lt_LastChange_TM == 0) //灯光正确了 { @@ -1597,7 +1609,7 @@ void Sub3Judge41Mndg::JiaoTi_DengGuang() } //20171009 检查双跳灯 - if(m_itemv.P_IF_Err_Kf) + if(m_itemv.P_IF_Err_Kf && m_itemv.Lt_Change != m_itemv.Lt_Change_Last) { if(m_itemv.Lt_YesID) { @@ -1607,7 +1619,7 @@ void Sub3Judge41Mndg::JiaoTi_DengGuang() if(sor.shtd == SYES && sor1.shtd == SYES && sor2.shtd == SYES) { //Pub_Log('jt std:' + m_itemv.Lt_Change); - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); if(m_car->isQualified() || m_car->isExamDrill() || ksdd == siteof::hebtest) { m_itemv.ItemNo = 0; @@ -1654,7 +1666,7 @@ void Sub3Judge41Mndg::JiaoTi_DengGuang() } else { - if(m_itemv.Lt_Change[6] == "1") + if(m_itemv.Lt_Change[6] == Y1) { m_itemv.ItemNo = 0; } @@ -1710,8 +1722,9 @@ void Sub3Judge41Mndg::Open_JinGuangDeng() } else if(m_itemv.ItemStatus == 3) { + std::string s(7, N0); //检查灯光错误 - if(m_itemv.P_IF_Err_Kf) + if(m_itemv.P_IF_Err_Kf && m_itemv.Lt_Change != m_itemv.Lt_Change_Last) { //检查上一个灯光题目:是不是 “车辆发生故障” bool b5 = (m_itemv.LastSubItemNo == 5); @@ -1730,7 +1743,7 @@ void Sub3Judge41Mndg::Open_JinGuangDeng() //0:未定义 1:示宽,2:双跳,3:雾灯,4:远光,5:近光,6:交替, 注意:记录灯光的变化,示宽是从有到无,其他是从无到有 if(i == 4 || (b5 == false && i == 6)) //20170527 20171009 { - if(m_itemv.Lt_Change[i] == "1") + if(m_itemv.Lt_Change[i] == Y1) { if(ksdd == siteof::shanghaikm3 || ksdd == siteof::jiuquan) { @@ -1752,7 +1765,7 @@ void Sub3Judge41Mndg::Open_JinGuangDeng() } else if(m_itemv.SubWav1 == 5) { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); } } else @@ -1778,7 +1791,7 @@ void Sub3Judge41Mndg::Open_JinGuangDeng() } else if(m_itemv.SubWav1 == 5) { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); } } //20180129 @@ -1790,7 +1803,7 @@ void Sub3Judge41Mndg::Open_JinGuangDeng() } else { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); } } } @@ -1846,7 +1859,7 @@ void Sub3Judge41Mndg::Open_JinGuangDeng() } else { - if(m_itemv.Lt_Change[5] == "1") //相当于近光灯持续了一段时间 + if(m_itemv.Lt_Change[5] == Y1) //相当于近光灯持续了一段时间 m_itemv.Lt_YesID = true; } } @@ -1866,13 +1879,13 @@ void Sub3Judge41Mndg::Open_JinGuangDeng() } else { - if(m_itemv.Lt_Change[5] == "1") //相当于近光灯持续了一段时间 + if(m_itemv.Lt_Change[5] == Y1) //相当于近光灯持续了一段时间 m_itemv.Lt_YesID = true; } } } //20171009 检查双跳灯 - if(m_itemv.P_IF_Err_Kf) + if(m_itemv.P_IF_Err_Kf && m_itemv.Lt_Change != m_itemv.Lt_Change_Last) { if(m_itemv.Lt_YesID) { @@ -1881,7 +1894,7 @@ void Sub3Judge41Mndg::Open_JinGuangDeng() const TSensorInfo& sor2 = m_car->historySensor(2); if(sor.shtd == SYES && sor1.shtd == SYES && sor2.shtd == SYES) { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); if(m_car->isQualified() || m_car->isExamDrill() || ksdd == siteof::hebtest) { m_itemv.ItemNo = 0; @@ -1916,7 +1929,7 @@ void Sub3Judge41Mndg::Open_JinGuangDeng() { if(m_itemv.SubWav1 == 3 && m_itemv.SubWav2 > 1) { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); if(m_car->isQualified() || m_car->isExamDrill()) { m_itemv.ItemNo = 0; @@ -1951,7 +1964,7 @@ void Sub3Judge41Mndg::Open_JinGuangDeng() } else if(m_itemv.SubWav1 == 5) { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); } } else @@ -1964,7 +1977,7 @@ void Sub3Judge41Mndg::Open_JinGuangDeng() } else { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); } } else if(m_itemv.SubWav1 == 2) @@ -1979,7 +1992,7 @@ void Sub3Judge41Mndg::Open_JinGuangDeng() } else { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); } } else if(m_itemv.SubWav1 == 4) @@ -1990,12 +2003,12 @@ void Sub3Judge41Mndg::Open_JinGuangDeng() } else { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); } } else if(m_itemv.SubWav1 == 5) { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); } } if(m_car->isQualified() || m_car->isExamDrill()) @@ -2027,7 +2040,7 @@ void Sub3Judge41Mndg::Open_JinGuangDeng() } else { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); } } else if(m_itemv.SubWav1 == 2) @@ -2042,7 +2055,7 @@ void Sub3Judge41Mndg::Open_JinGuangDeng() } else { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); } } else if(m_itemv.SubWav1 == 4) @@ -2053,12 +2066,12 @@ void Sub3Judge41Mndg::Open_JinGuangDeng() } else { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); } } else if(m_itemv.SubWav1 == 5) { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); } if(m_car->isQualified() || m_car->isExamDrill()) { @@ -2103,7 +2116,7 @@ void Sub3Judge41Mndg::Open_YuanGuangDeng() else if(m_itemv.ItemStatus == 3) { //检查灯光错误 - if(m_itemv.P_IF_Err_Kf) + if(m_itemv.P_IF_Err_Kf && m_itemv.Lt_Change != m_itemv.Lt_Change_Last) { //检查上一个灯光题目:是不是 “车辆发生故障” bool b5 = (m_itemv.LastSubItemNo == 5); @@ -2115,11 +2128,11 @@ void Sub3Judge41Mndg::Open_YuanGuangDeng() { //20171010 if(i != 4 && i != 1 && i != 6 && i != 5) //20140812 { - if(m_itemv.Lt_Change[i] == "1") + if(m_itemv.Lt_Change[i] == Y1) { if(m_itemv.SubWav1 == 2) //远光灯 20150126 { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); } else { @@ -2142,11 +2155,11 @@ void Sub3Judge41Mndg::Open_YuanGuangDeng() { if(i != 4 && i != 1) //20140812 { - if(m_itemv.Lt_Change[i] == "1") + if(m_itemv.Lt_Change[i] == Y1) { if(m_itemv.SubWav1 == 2) //远光灯 20150126 { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); } else { @@ -2180,7 +2193,7 @@ void Sub3Judge41Mndg::Open_YuanGuangDeng() } else { - if(m_itemv.Lt_Change[4] == "1") //相当于远光灯持续了一段时间 + if(m_itemv.Lt_Change[4] == Y1) //相当于远光灯持续了一段时间 { m_itemv.Lt_YesID = true; } @@ -2196,7 +2209,7 @@ void Sub3Judge41Mndg::Open_YuanGuangDeng() } } //20171009 检查双跳灯 - if(m_itemv.P_IF_Err_Kf) + if(m_itemv.P_IF_Err_Kf && m_itemv.Lt_Change != m_itemv.Lt_Change_Last) { if(m_itemv.Lt_YesID) { @@ -2205,7 +2218,7 @@ void Sub3Judge41Mndg::Open_YuanGuangDeng() const TSensorInfo& sor2 = m_car->historySensor(2); if(sor.shtd == SYES && sor1.shtd == SYES && sor2.shtd == SYES) { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); if(m_car->isQualified() || m_car->isExamDrill() || ksdd == siteof::hebtest) { m_itemv.ItemNo = 0; @@ -2236,7 +2249,7 @@ void Sub3Judge41Mndg::Open_YuanGuangDeng() { if(m_itemv.SubWav1 == 2) //远光灯 20150126 { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); } else { @@ -2285,7 +2298,7 @@ void Sub3Judge41Mndg::CheLiangGuZhang() { const std::string& s421 = TableSysSet->get421(); //检查灯光错误 - if(m_itemv.P_IF_Err_Kf) + if(m_itemv.P_IF_Err_Kf && m_itemv.Lt_Change != m_itemv.Lt_Change_Last) { for(int i = 1; i <= 6; i++) { @@ -2295,7 +2308,7 @@ void Sub3Judge41Mndg::CheLiangGuZhang() ////0:未定义 1:示宽,2:双跳,3:雾灯,4:远光,5:近光,6:交替, 注意:记录灯光的变化,示宽是从有到无,其他是从无到有 if(i == 3) { - if(m_itemv.Lt_Change[i] == "1") + if(m_itemv.Lt_Change[i] == Y1) { //打错灯了 if(m_itemv.SubWav1 == 1) @@ -2323,7 +2336,7 @@ void Sub3Judge41Mndg::CheLiangGuZhang() { if(i != 1 && i != 2 && i != 6) { - if(m_itemv.Lt_Change[i] == "1") + if(m_itemv.Lt_Change[i] == Y1) { //打错灯了 if(ksdd == siteof::guizhouzy) @@ -2355,7 +2368,7 @@ void Sub3Judge41Mndg::CheLiangGuZhang() if((ksdd == siteof::jiuquan && i != 1 && i != 5) || (ksdd != siteof::jiuquan && i != 1 && i != 2 && i != 5)) //之前判断方法 //20170809 { ////0:未定义 1:示宽,2:双跳,3:雾灯,4:远光,5:近光,6:交替, 注意:记录灯光的变化,示宽是从有到无,其他是从无到有 - if(m_itemv.Lt_Change[i] == "1") + if(m_itemv.Lt_Change[i] == Y1) { //打错灯了 if(m_itemv.SubWav1 == 1) @@ -2381,7 +2394,7 @@ void Sub3Judge41Mndg::CheLiangGuZhang() if(i != 1 && i!= 2 && i != 5) //20140923 新增不判远光灯 { ////0:未定义 1:示宽,2:双跳,3:雾灯,4:远光,5:近光,6:交替, 注意:记录灯光的变化,示宽是从有到无,其他是从无到有 - if(m_itemv.Lt_Change[i] == "1") + if(m_itemv.Lt_Change[i] == Y1) { //打错灯了 if(m_itemv.SubWav1 == 1) @@ -2558,17 +2571,17 @@ void Sub3Judge41Mndg::GuZhangJieChu() else if(m_itemv.ItemStatus == 3) { //检查灯光错误 - if(m_itemv.P_IF_Err_Kf) + if(m_itemv.P_IF_Err_Kf && m_itemv.Lt_Change != m_itemv.Lt_Change_Last) { //示宽,双跳,雾灯,远光,近光,交替, 注意:记录灯光的变化,示宽是从有到无,其他是从无到有 for(int i = 1; i <= 6; i++) { if(i == 3) { - if(m_itemv.Lt_Change[i] == "1") + if(m_itemv.Lt_Change[i] == Y1) { //打错灯了 - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); if(m_car->isQualified() || m_car->isExamDrill() || ksdd == siteof::hebtest) { m_itemv.ItemNo = 0; @@ -2612,7 +2625,7 @@ void Sub3Judge41Mndg::GuZhangJieChu() } else { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); if(m_car->isQualified() || m_car->isExamDrill() || ksdd == siteof::hebtest) { m_itemv.ItemNo = 0; @@ -2653,17 +2666,17 @@ void Sub3Judge41Mndg::CloseAllDengGuang() else if(m_itemv.ItemStatus == 3) { //检查灯光错误 - if(m_itemv.P_IF_Err_Kf) + if(m_itemv.P_IF_Err_Kf && m_itemv.Lt_Change != m_itemv.Lt_Change_Last) { for(int i = 1; i <= 6; i++) { //示宽,双跳,雾灯,远光,近光,交替, 注意:记录灯光的变化,示宽是从有到无,其他是从无到有 if(i == 3) { - if(m_itemv.Lt_Change[i] == "1") + if(m_itemv.Lt_Change[i] == Y1) { //打错灯了 - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); if(m_car->isQualified() || m_car->isExamDrill() || ksdd == siteof::hebtest) { m_itemv.ItemNo = 0; @@ -2707,7 +2720,7 @@ void Sub3Judge41Mndg::CloseAllDengGuang() } else { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); if(m_car->isQualified() || m_car->isExamDrill() || ksdd == siteof::hebtest) { m_itemv.ItemNo = 0; @@ -2786,7 +2799,7 @@ void Sub3Judge41Mndg::WuTianXingShi() } else { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); if(m_car->isQualified() || m_car->isExamDrill() || ksdd == siteof::hebtest) { m_itemv.ItemNo = 0; @@ -2806,7 +2819,7 @@ void Sub3Judge41Mndg::WuTianXingShi() } else { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); if(m_car->isQualified() || m_car->isExamDrill() || ksdd == siteof::hebtest) { m_itemv.ItemNo = 0; @@ -2826,7 +2839,7 @@ void Sub3Judge41Mndg::WuTianXingShi() } else { - JUDGE_MARK_SUB3(41, "01", true); + JUDGE_MARK_SUB3(41, "01", false); if(m_car->isQualified() || m_car->isExamDrill() || ksdd == siteof::hebtest) { m_itemv.ItemNo = 0; @@ -2959,9 +2972,11 @@ void Sub3Judge41Mndg::CSH_DengGuangSubItem() { for(size_t i = 0; i < m_itemv.Lt_Change.size(); i++) { - m_itemv.Lt_Change[i] = "0"; + m_itemv.Lt_Change[i] = N0; } + m_itemv.Lt_Change_Last = m_itemv.Lt_Change; + m_itemv.Lt_YJ_TM = 0; m_itemv.Lt_YJ_cs = 0; //20150327 } @@ -3014,7 +3029,7 @@ void Sub3Judge41Mndg::playSoundEnd(const std::string& code) m_itemv.Snd_Wav_End_TM = gps.sj; CSH_DengGuangSubItem(); m_itemv.ItemStatus = m_itemv.ItemStatus + 1; - logtrace("sound-end code=%s", code.c_str()); + logtrace("mndg-sound-end code=%s", code.c_str()); } } diff --git a/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge41Mndg.h b/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge41Mndg.h index 0850a31d..1937c503 100644 --- a/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge41Mndg.h +++ b/entry/src/main/cpp/sdk/judge/sub3/Sub3Judge41Mndg.h @@ -212,6 +212,10 @@ protected: void playSound(const std::string& kind, int SubWav1, int SubWav2); private: + + #define Y1 ('1') + #define N0 ('0') + TSub3Item41Mndg m_itemv; std::map m_lights; //HeFaDengGuangDataList //加载合法的灯光 //参考头文件注释说明[灯光类型] @@ -220,6 +224,8 @@ private: // 四套灯光语音,随机播放任意一套作为考试题目 const std::string m_s383arg = "0^1^4^"; //383参数 新模拟夜间(次数^错扣^固定^) + int64 m_lastDealTick = 0; + //bool PlaySnd_ID = false; //正在播报语音标志 //int PlaySnd_Cnt = 0, PlaySnd_Cnt1 = 0; //std::set g_lstsound; diff --git a/entry/src/main/cpp/sdk/parser/XParser.cpp b/entry/src/main/cpp/sdk/parser/XParser.cpp index fa530788..2e261a2c 100644 --- a/entry/src/main/cpp/sdk/parser/XParser.cpp +++ b/entry/src/main/cpp/sdk/parser/XParser.cpp @@ -302,6 +302,15 @@ bool XParser::parsePerform(const std::string& data, TPerformData& info) //CHECK_GET_PARAM(lane, "xxxxx", info.lane.Body_RB_ToRightEdge); //车轮相交的形状线号 CHECK_GET_PARAM(lane, "CrossPointNo", info.lane.CrossPointNo); + //20240730 增加 yhy + CHECK_GET_PARAM(lane, "TouchLineDirCS", info.lane.TouchLineDirCS); + CHECK_GET_PARAM(lane, "BackPointLaneNo", info.lane.BackPointLaneNo); + CHECK_GET_PARAM(lane, "BackPointLaneCount", info.lane.BackPointLaneCount); + CHECK_GET_PARAM(lane, "Body_RF_ToBaseLine", info.lane.Body_RF_ToBaseLine); + CHECK_GET_PARAM(lane, "Body_RB_ToBaseLine", info.lane.Body_RB_ToBaseLine); + CHECK_GET_PARAM(lane, "DirInverse", info.lane.DirInverse); + CHECK_GET_PARAM(lane, "ShapeNoWheel", info.lane.ShapeNoWheel); + } return true; @@ -381,6 +390,15 @@ std::string XParser::toDataString(const TPerformData& data) //set(lane, "xxxxx", data.lane.Body_RB_ToRightEdge); //车轮相交的形状线号 set(lane, "CrossPointNo", data.lane.CrossPointNo); + //20240730 增加 yhy + set(lane, "TouchLineDirCS", data.lane.TouchLineDirCS); + set(lane, "BackPointLaneNo", data.lane.BackPointLaneNo); + set(lane, "BackPointLaneCount", data.lane.BackPointLaneCount); + set(lane, "Body_RF_ToBaseLine", data.lane.Body_RF_ToBaseLine); + set(lane, "Body_RB_ToBaseLine", data.lane.Body_RB_ToBaseLine); + set(lane, "DirInverse", data.lane.DirInverse); + set(lane, "ShapeNoWheel", data.lane.ShapeNoWheel); + root["lane"] = lane; } @@ -629,8 +647,15 @@ bool XParser::get(Json::Value& object, const char* key, TEventItemMark& store, c bool XParser::get(Json::Value& object, const char* key, TEventExamFinish& store, const TEventExamFinish& defaults) noexcept { CHECK_GET_OBJECT({ + CHECK_GET_PARAM(value, "type", store.type); CHECK_GET_PARAM(value, "qjjl", store.qjjl); CHECK_GET_PARAM(value, "dcjl", store.dcjl); + CHECK_GET_PARAM(value, "d1", store.d1); + CHECK_GET_PARAM(value, "d2", store.d2); + CHECK_GET_PARAM(value, "d3", store.d3); + CHECK_GET_PARAM(value, "d4", store.d4); + CHECK_GET_PARAM(value, "d5", store.d5); + CHECK_GET_PARAM(value, "d6", store.d6); }); return true; } @@ -1414,6 +1439,7 @@ inline bool XParser::set(Json::Value& object, const char* key, const TEventItemM set(value, "xmdm", store.xmdm); set(value, "kfdm", store.kfdm); set(value, "markcatalog", store.markcatalog); + set(value, "type", store.type); object[key] = value; return true; } @@ -1421,8 +1447,15 @@ inline bool XParser::set(Json::Value& object, const char* key, const TEventItemM inline bool XParser::set(Json::Value& object, const char* key, const TEventExamFinish& store) noexcept { Json::Value value; + set(value, "type", store.type); set(value, "qjjl", store.qjjl); set(value, "dcjl", store.dcjl); + set(value, "d1", store.d1); + set(value, "d2", store.d2); + set(value, "d3", store.d3); + set(value, "d4", store.d4); + set(value, "d5", store.d5); + set(value, "d6", store.d6); object[key] = value; return true; } diff --git a/entry/src/main/cpp/sdk/track/TrackReader.cpp b/entry/src/main/cpp/sdk/track/TrackReader.cpp index 862298a8..a54a2bd6 100644 --- a/entry/src/main/cpp/sdk/track/TrackReader.cpp +++ b/entry/src/main/cpp/sdk/track/TrackReader.cpp @@ -76,7 +76,7 @@ bool TrackReader::read(TTrackData::Ptr& data) data->type = TTrackTypeRealExam; } else if(root.isMember("method") && root["method"].asString() == "examJudgeArtificialMark" && - root.isMember("itemno") && root.isMember("serial")) + root.isMember("itemno") && root.isMember("serial") && root.isMember("type") ) { data->type = TTrackTypeArtificialMark; } diff --git a/entry/src/main/cpp/sdk/utility/HBean.h b/entry/src/main/cpp/sdk/utility/HBean.h index d92c9dce..88d5683b 100644 --- a/entry/src/main/cpp/sdk/utility/HBean.h +++ b/entry/src/main/cpp/sdk/utility/HBean.h @@ -80,7 +80,7 @@ JUDGE_C_API const char* ExamEventType2Desc(ExamEventType code); JUDGE_C_API ExamEventType Name2ExamEventType(const char* name); //******注意顺序不能变,这个类型要传给上层APP调用方的***杨海洋2023-07-04*** -//考车移动状态 +//考车移动状态,***注意:枚举不能变,和外壳有对应关系 enum CarMoveState { moveInvalid = -2, //无效未知的状态 @@ -89,35 +89,35 @@ enum CarMoveState moveForward = 1, //前进状态 }; -//考试模式(0:训练 1:考试) +//考试模式(0:训练 1:考试)***注意:枚举不能变,和外壳有对应关系 enum ExamMode { examModeDrill = 0, //0:训练 examModeExam = 1, //1:考试 }; -//是否轨迹(回放)(0:否 1:是) +//是否轨迹(回放)(0:否 1:是)***注意:枚举不能变,和外壳有对应关系 enum TrackReplayType { - TrackReplayTypeNot = 0, //0:否 - TrackReplayTypeYes = 1, //1:是 + TrackReplayNot = 0, //0:否 + TrackReplayYes = 1, //1:是 }; -//传感信号 +//传感信号,***注意:枚举不能变,和外壳有对应关系 enum SensorSignal { SNOT = 0, //传感无信号 SYES = 1, //传感有信号 }; -//考试科目类型定义 +//考试科目类型定义,注意:枚举不能变,和外壳有对应关系 enum ExamSubject { ExamSubject2 = 2, //科目二 ExamSubject3 = 3, //科目三 }; -//人工项目操作类型 +//人工项目操作类型,***注意:枚举不能变,和外壳有对应关系 enum ArtifItemType { ArtifItemTypeAuto = 0, @@ -126,13 +126,29 @@ enum ArtifItemType ArtifItemTypeEnd = 3, }; -//语音播报类型 +//扣分类型,***注意:枚举不能变,和外壳有对应关系 +enum MarkType +{ + MarkTypeAuto = 0, //0:评判自动扣分 + MarkTypeArti = 1, //1:人工扣分 + MarkTypeRemote = 2, //2:远程扣分 +}; + +//考试结束类型,***注意:枚举不能变,和外壳有对应关系 +enum ExamFinishType +{ + ExamFinishAuto = 0, //0:评判自动结束 + ExamFinishArti = 1, //1:人工结束 +}; + +//语音播报类型,***注意:枚举不能变,和外壳有对应关系 enum PlaySoundType { PlaySoundDefault = 0, //0:默认 PlaySoundEndNotify = 1, //1:表示是模拟灯光项目的语音,语音播报结束需要调用examJudgeSoundEnd通知评判。 }; + //Tag1=0-无标线 //Tag1=1-中心线(黄色实线) //Tag1=2-道路分界线(虚线) diff --git a/entry/src/main/cpp/sdk/utility/HTypes.h b/entry/src/main/cpp/sdk/utility/HTypes.h index eaf03492..79606121 100644 --- a/entry/src/main/cpp/sdk/utility/HTypes.h +++ b/entry/src/main/cpp/sdk/utility/HTypes.h @@ -703,12 +703,20 @@ struct TEventItemMark int32 xmdm = Sub2ItemTypeInvalid; //项目代码 对应枚举 ExamItemCode std::string kfdm; //扣分代码 对应markserial std::string markcatalog; //无锡所标准扣分代码 + int32 type = MarkTypeAuto; //扣分类型,评判自动、人工、远程 }; struct TEventExamFinish { - int32 qjjl = 0; //累计前进距离 单位厘米 - int32 dcjl = 0; //累计倒车距离 单位厘米 + int32 type = ExamFinishAuto; //考试结束类型 + int32 qjjl = 0; //累计前进距离 单位厘米 + int32 dcjl = 0; //累计倒车距离 单位厘米 + int32 d1 = 0; //1档档位行驶距离,单位厘米 + int32 d2 = 0; + int32 d3 = 0; + int32 d4 = 0; + int32 d5 = 0; + int32 d6 = 0; }; struct TEventSound @@ -842,6 +850,17 @@ struct TRTKResult int CrossPointNo = 0; //穿越点 + + //20240730 新增 还没计算 + int TouchLineDirCS = 0; //车身碰线 车身碰线方向 + int BackPointLaneNo = 0; //后点车道 后点所在车道号 + int BackPointLaneCount = 0; //后点车道 后点天线共有几股车道 + int Body_RF_ToBaseLine = 0; //右前车身边线 指车身离右侧路边缘线距离 + int Body_RB_ToBaseLine = 0; //右后车身边线 指车身离右侧路边缘线距离 + + int DirInverse = 0; //车道属性 是否逆向行驶 + int ShapeNoWheel = 0; //形状 车轮相交的形状线号 + #ifdef JUDGE_USE_INSPECT std::string BodySharpData; //解决无锡所路口左转227a用例误判问题 #endif @@ -1293,6 +1312,28 @@ struct TTestCtl bool Dw_Cgd_OK = false; }; +struct TPubKM3 +{ + int m_KsZgDw = 0; //记录考试中的最高档位 + int m_KsZgSs = 0; //记录考试中的最高时速 + int m_KsLjLc = 0; //记录考试累计里程(米) + + int PubLastChuanYuePtNo = 0; //最后一次经过的点 + int PubLastChuanYuePt_JLCM = 0; //最后一次经过的点偏移量 + + int NJ_DiaoTou_JL = 0; //个性需求 + int64 ChaoChe_Start_TM = 0; //2018011 超车开始时间 + int64 ChaoChe_End_TM = 0; //2018011 超车结束时间 + int PUB_JDCC_ZT = 0; //借道超车状态 0:非借道 1:表示超车 2:表示正在返回原车道 3:回原车道道完成 20180227 + bool yjdg_road_code_kf = false; + + int Pub_JSC_JL = 0; + bool PubCanJudge_XiHuoFlag = true; //注意初始必须是true + int PubKaoBianTCFinish_LJJL = 0; + + int m_SNO = 0; +}; + /* //后面去掉可能没用了 struct TCarStatus diff --git a/entry/src/main/cpp/toolkit/replay/ReplayWrapper.cpp b/entry/src/main/cpp/toolkit/replay/ReplayWrapper.cpp index 00ecf201..7a1b0302 100644 --- a/entry/src/main/cpp/toolkit/replay/ReplayWrapper.cpp +++ b/entry/src/main/cpp/toolkit/replay/ReplayWrapper.cpp @@ -371,8 +371,6 @@ void ReplayWrapper::replayTrackTypeArtificialItem(const TTrackData::Ptr& data) void ReplayWrapper::replayTrackTypeSoundEnd(const TTrackData::Ptr &data) { - //return; //240709 - Json::Value root; bool ok = Tools::fromJson(data->data, root); TASSERT(ok, ""); diff --git a/entry/src/main/cpp/toolkit/ui/MainWindow.cpp b/entry/src/main/cpp/toolkit/ui/MainWindow.cpp index b374e027..ac426473 100644 --- a/entry/src/main/cpp/toolkit/ui/MainWindow.cpp +++ b/entry/src/main/cpp/toolkit/ui/MainWindow.cpp @@ -52,15 +52,6 @@ void MainWindow::init() KIT_CONNECT(updateDataFrameNum(int, int)); KIT_CONNECT(updateNextDoing()); - connect(&m_audio, &QMediaPlayer::stateChanged, [=](QMediaPlayer::State state) - { - if(state == QMediaPlayer::StoppedState) - { - //examJudgeSoundEnd(); - //logtrace("examJudge-SoundEnd"); - } - }); - static const QString gpsStyle1("color:#9933FA;"); static const QString gpsStyle2("color:#802A2A;"); #define KIT_SET_GPS_STYLE(name) name->setStyleSheet(gpsStyle1); name##_2->setStyleSheet(gpsStyle2); @@ -1122,7 +1113,7 @@ void MainWindow::updateDataCallbackRealExam(const QString& info) m_parser->parseJudgeData(org, value); ExamEventType eventType = (ExamEventType)value.event; - std::string time = toEasyTime(Tools::nowTime()); //value.sj 240709 + std::string time = toEasyTime(value.sj); std::string desc = ExamEventType2Desc(eventType); //loginfo("recv time=%s, event=%s", time.c_str(), desc.c_str()); @@ -1200,16 +1191,11 @@ void MainWindow::updateDataCallbackRealExam(const QString& info) } else if(eventType == ExamEventTypeSound) { - const TEventSound& sound = value.sound; - int itemNo = sound.xmdm; - QString s = QString::fromUtf8(sound.code.c_str()); - QString text = event + getItemText(itemNo) + CL8(",语音代码:") + s + CL8(",语音类型:")+kit::toString(sound.type); + int itemNo = value.sound.xmdm; + QString s = QString::fromUtf8(value.sound.code.c_str()); + QString text = event + getItemText(itemNo) + CL8(",语音代码:") + s; updateExamEvent(text); playSoundVoice(value.sound.code); - if(sound.xmdm == Sub3ItemType41Mndg && sound.type == PlaySoundEndNotify) - { - examJudgeSoundEnd(sound.xmdm, sound.code.c_str(),sound.type); //240709 - } } else if(eventType == ExamEventTypeLight) { @@ -1218,10 +1204,6 @@ void MainWindow::updateDataCallbackRealExam(const QString& info) QString text = event + ",[" + s +"]"; updateExamEvent(text); } - else if(eventType == ExamEventTypeLane) - { - const TEventLane& lane = value.lane; - } else { QString text = event + ""; @@ -1333,6 +1315,7 @@ void MainWindow::updateDataCallbackPerform(const QString& info) m_ui->PubLastChuanYuePtNo->setText(CL8("穿越点=") + kit::toString(PubLastChuanYuePtNo)); m_ui->PubLastChuanYuePtNo->setStyleSheet("color:#FF0000;"); + std::string aaasss = cg->MapPoint_Road_Code; m_ui->MapRoad->setText(CL8("MapRoad:") + kit::toString(RTKKM3.MapRoad_Name) + CL8(" Point路段:") + kit::toString(cg->MapPoint_Road_Code)); m_ui->MapRoad->setStyleSheet("color:#FF0000;"); diff --git a/entry/src/main/ets/api/judge.ts b/entry/src/main/ets/api/judge.ts index 861f4901..9a9a27f8 100644 --- a/entry/src/main/ets/api/judge.ts +++ b/entry/src/main/ets/api/judge.ts @@ -1,33 +1,58 @@ import request from "../common/utils/request" -import {getCurrentTime} from '../common/utils/tools' +import { getCurrentTime } from '../common/utils/tools' +import { getSyncData } from '../common/service/initable'; +import writeObjectOutNew from './judgeNew' +import FileLog from '../pages/judgeSDK/utils/fileLog'; +let baseHost = globalThis.host; -// const baseHost = 'http://192.168.36.2:8081'; -const baseHost = 'http://112.80.35.83:11051'; // 下载模型 -export async function download(){ +export async function download() { return await request({ - host:baseHost, - url:'/para/initEsModel.ws', - method:'post', - xml:false + host: baseHost, + url: '/para/initEsModel.ws', + method: 'post', + xml: false }) } // 通用监管接口 -export async function writeObjectOut(params):Promise{ +export async function writeObjectOut(params): Promise { const singlePlay = globalThis.singlePlay - if(singlePlay){ - return + if (singlePlay) { + return 1 } - const {xtlb,jkxlh,jkid,drvexam} = params; - const {lsh,kskm,sfzmhm,ksxm,sbxh,kchp,kssj} = drvexam; + + //获取监管接口地址路径 + if (!globalThis.JGPATH) { + const syssetParams = await getSyncData('MA_SYSSET') || []; + //@ts-ignore + syssetParams.forEach(sys => { + if (sys.v_no == '839') { + //是否是新监管 + globalThis.isJGNew = sys.v_value == '3' + } + if (sys.v_no == '900') { + globalThis.JGHOST = validateIP(decodeURIComponent(sys.v_value)) + } + }) + } + const {xtlb,jkxlh,jkid,drvexam} = params; + //新监管调用 + if (globalThis.isJGNew) { + return await writeObjectOutNew(params) + } + + const fileLog = new FileLog(globalThis.context) + const drvexamArrs = Reflect.ownKeys(drvexam).map((key: string) => (`<${key}>${drvexam[key]}`)); + fileLog.setExamJudgeWuxiData(JSON.stringify({ + xtlb,jkxlh,jkid,drvexam + })) //对象转换成xml - const drvexamArrs = Reflect.ownKeys(drvexam).map((key:string) => (`<${key}>${drvexam[key]}`)) - return await request({ - host:baseHost, - url:'/dems_ws/services/TmriOutAccess?wsdl', - data:` + const temp = await request({ + host: globalThis.JGHOST, + url: '/dems_ws/services/TmriOutAccess?wsdl', + data: ` { `, - method:'post', - xml:true + method: 'post', + xml: true }) + return temp } // 过程文件上传 -export async function uploadExamProgressData(params){ +export async function uploadExamProgressData(params) { const singlePlay = globalThis.singlePlay const {carId,examinationRoomId,type,time,cardNo,examData,examStartTime,examEndTime} = params - if(singlePlay){ + if (singlePlay) { return } return await request({ - url:'/der2/services/exam/uploadExamDataFile.ws', - data:` + url: '/der2/services/exam/uploadExamDataFile.ws', + data: ` @@ -78,50 +104,62 @@ export async function uploadExamProgressData(params){ ${examEndTime} `, - method:'post', - xml:true + method: 'post', + xml: true }) } // 上传考试里程 -export async function uploadExamMileage(params){ +export async function uploadExamMileage(params) { const singlePlay = globalThis.singlePlay - if(singlePlay){ + if (singlePlay) { return } - const paramsArrs = Reflect.ownKeys(params).map((key:string) => (`<${key}>${params[key]}`)) const time = await getCurrentTime() + return await request({ - url:'/der2/services/exam/uploadExamMileage.ws', - data:` + url: '/der2/services/exam/uploadExamMileage.ws', + data: ` - ${paramsArrs} + ${params.carId} + ${params.examinationRoomId} + ${params.lsh} + ${params.examinationRoomId} + ${params.kslc} `, - method:'post', - xml:true + method: 'post', + xml: true }) } + // 上传考试成绩 -export async function uploadExamGrade(params){ +export async function uploadExamGrade(params) { const singlePlay = globalThis.singlePlay - if(singlePlay){ + if (singlePlay) { return } - const paramsArrs = Reflect.ownKeys(params).map((key:string) => (`<${key}>${params[key]}`)) + const paramsArrs = Reflect.ownKeys(params).map((key: string) => (`<${key}>${params[key]}`)) const time = await getCurrentTime() return await request({ - url:'/der2/services/exam/uploadExamGrade.ws', - data:` + url: '/der2/services/exam/uploadExamGrade.ws', + data: ` ${paramsArrs} `, - method:'post', - xml:true + method: 'post', + xml: true }) } + +function validateIP(path: string) { + const reg = new RegExp(/(\w+):\/\/([^/:]+)(:\d*)?/) + const result = path.match(reg); + return result[0] +} + diff --git a/entry/src/main/ets/api/judgeNew.ts b/entry/src/main/ets/api/judgeNew.ts new file mode 100644 index 00000000..ecc2a8b5 --- /dev/null +++ b/entry/src/main/ets/api/judgeNew.ts @@ -0,0 +1,194 @@ +import { getSyncData } from '../common/service/initable'; +import request from "../common/utils/request" +let baseHost = globalThis.host; +import FileLog from '../pages/judgeSDK/utils/fileLog'; + +//新监管接口 + + +//监管接口序列号映射 +const gjxlhObj = { + '17C51': '02-21-000009', + '17C52': '02-21-000010', + '17C53': '02-21-000011', + '17C54': '02-21-000012', + '17C55': '02-21-000013', + '17C56': '02-21-000014', +} + +export default async function writeObjectOutNew(data): Promise { + const {jkid , drvexam} = data; + const basic = await getBasicConfig(jkid); + const params = await getParams(jkid, drvexam); + const {wglb,jkxlh,glbm,jgbh,sjbs} = basic; + + return await request({ + host: globalThis.JGHOST, + method: 'post', + //是否是新中心 + isNewCenter: true, + xml: true, + url: '/dems_ws/services/TmriOutAccess?wsdl', + data: ` + + + + ${wglb} + ${jkxlh} + ${glbm} + ${jgbh} + ${sjbs} + ${JSON.stringify(params.data)} + ${JSON.stringify(params.file)} + + + `, + }) +} + +export async function getParams(jkid, drvexam) { + const examSubject = globalThis.carInfo.examSubject; + switch (jkid) { + //开始考试 + case '17C51': + return { + data: { + sjbs: gjxlhObj[jkid], + param: { + sfzmhm: drvexam.sfzmhm, + kchp: decodeURI(drvexam.kchp), + kskm: examSubject, + ksxl: examSubject == 3 ? drvexam.ksxl : undefined, + kssj: drvexam.kssj + } + }, + file: { + sjbs: gjxlhObj[jkid], + param: [{ field: '', data: examSubject == 2 ? encodeURIComponent(drvexam.zp) : drvexam.zp }] + } + } + //项目开始 + case '17C52': + return { + data: { + sjbs: gjxlhObj[jkid], + param: { + sfzmhm: drvexam.sfzmhm, + kskm: drvexam.kskm, + ksxm: drvexam.ksxm, + ksxl: examSubject == 3 ? drvexam.ksxl : undefined, + kchp: decodeURI(drvexam.kchp), + //TODO 待验证 科目三无 + sbbh: examSubject == 3 ? undefined : drvexam.sbxh, + kssj: drvexam.kssj + } + }, + file: { + sjbs: gjxlhObj[jkid], + param: [{ field: '', data: '' }] + } + } + //扣分 + case '17C53': + return { + data: { + sjbs: gjxlhObj[jkid], + param: { + kffs: drvexam.kffs, + kfsj: drvexam.kfsj, + kfxm: drvexam.kfxm, + kfxmmx: drvexam.kfxmmx, + kskm: examSubject, + ksxm: drvexam.ksxm, + sfzmhm: drvexam.sfzmhm + } + }, + file: { + sjbs: gjxlhObj[jkid], + param: [{ field: '', data: '' }] + } + } + //过程照片 + case '17C54': + return { + data: { + sjbs: gjxlhObj[jkid], + param: { + cs: drvexam.cs, + kskm: drvexam.kskm, + ksxm: drvexam.ksxm, + sfzmhm: drvexam.sfzmhm, + zpsj: drvexam.zpsj + } + }, + file: { + sjbs: gjxlhObj[jkid], + param: [{ field: '', data: examSubject == 2 ? encodeURIComponent(drvexam.zp) : drvexam.zp }] + } + } + //项目结束 + case '17C55': + return { + data: { + param: { + czlx: drvexam.czlx, + jssj: drvexam.jssj, + kskm: examSubject, + ksxl: drvexam.ksxl, + ksxm: drvexam.ksxm, + sfzmhm: drvexam.sfzmhm + }, + sjbs: gjxlhObj[jkid], + }, + file: { sjbs: gjxlhObj[jkid], param: [{ field: '', data: '' }] } + } + //考试结束 + case '17C56': + return { + data: { + sjbs: gjxlhObj[jkid], + param: { + dwlc: drvexam.dwlc, + ghks: "0", + jssj: drvexam.jssj, + kscj: drvexam.kscj, + kskm: examSubject, + kslc: drvexam.kslc, + sfzmhm: drvexam.sfzmhm + }, + }, + file: { sjbs: gjxlhObj[jkid], param: [{ field: '', data: drvexam.zp }] } + } + + default: + return {} + } +} + +//获取基础信息 +async function getBasicConfig(jkid) { + const examSubject = globalThis.carInfo.examSubject; + const syssetParam = await getSyncData('MA_SYSSET'); + let syssetObj = {}; + //@ts-ignore + syssetParam.forEach(sys => { + syssetObj[sys.v_no] = decodeURIComponent(sys.v_value) + }); + + return { + //外挂类别 + wglb: examSubject == 2 ? "700203" : "700204", + //监管接口序列号 + jkxlh: syssetObj['901'], + //管理部门 + glbm: syssetObj['903'], + //考场序号 + jgbh: syssetObj['905'], + //接口id + sjbs: gjxlhObj[jkid], + } +} \ No newline at end of file diff --git a/entry/src/main/ets/api/userInfo.ts b/entry/src/main/ets/api/userInfo.ts index e8e372fc..8db7e169 100644 --- a/entry/src/main/ets/api/userInfo.ts +++ b/entry/src/main/ets/api/userInfo.ts @@ -47,6 +47,7 @@ export async function examinationStuAbsent(params) { }) } +//获取断点续考 export async function getExaminationItem(params) { return await request({ url: '/der2/services/exam/getExaminationItem.ws', diff --git a/entry/src/main/ets/common/constants/USER.ts b/entry/src/main/ets/common/constants/USER.ts index 2b847459..e9000a73 100644 --- a/entry/src/main/ets/common/constants/USER.ts +++ b/entry/src/main/ets/common/constants/USER.ts @@ -25,8 +25,8 @@ CommonConstants { */ static readonly ACCOUNT_TABLE = { tableName: 'USER', - sqlCreate: 'CREATE TABLE IF NOT EXISTS USER(id INTEGER PRIMARY KEY AUTOINCREMENT,sfzmhm TEXT,xm CHAR(20), lsh TEXT, kszp TEXT,ksdd TEXT,kssycs TEXT,kslx TEXT,kscx TEXT)', - columns: ['id','sfzmhm','xm','lsh','kszp','ksdd','kssycs','kslx','kscx'] + sqlCreate: 'CREATE TABLE IF NOT EXISTS USER(id INTEGER PRIMARY KEY AUTOINCREMENT,sfzmhm TEXT,xm CHAR(20), lsh TEXT, kszp TEXT,ksdd TEXT,kssycs TEXT,kslx TEXT,kscx TEXT,ksxl TEXT)', + columns: ['id','sfzmhm','xm','lsh','kszp','ksdd','kssycs','kslx','kscx','ksxl'] }; /** diff --git a/entry/src/main/ets/common/service/terminalService.ts b/entry/src/main/ets/common/service/terminalService.ts index 2511aa70..e05ddfe3 100644 --- a/entry/src/main/ets/common/service/terminalService.ts +++ b/entry/src/main/ets/common/service/terminalService.ts @@ -10,6 +10,9 @@ import FileUtil from '../../common/utils/File' export async function getDeviceInfo(context) { // globalThis.deviceNo = '153216400880'; //科目三设备 globalThis.deviceNo = '150667400235'; //科目三设备 + // globalThis.deviceNo = 'MAC-36E6575F'; //杭州科目二设备 489 + // globalThis.deviceNo = 'MAC-C57C8966'; //杭州科目二设备 + return return new Promise(async (resolve, reject) => { const fileUtil = new FileUtil(context) diff --git a/entry/src/main/ets/common/utils/request.ts b/entry/src/main/ets/common/utils/request.ts index 917ecfcb..cef78b68 100644 --- a/entry/src/main/ets/common/utils/request.ts +++ b/entry/src/main/ets/common/utils/request.ts @@ -21,13 +21,13 @@ let httpRequest = http.createHttp(); */ export default async function request(req: any) { - const {url,params = {},data = {},xml,method = 'get',host} = req; + const {url,params = {},data = {},xml,method = 'get',host,isNewCenter = false} = req; const options = { method: http.RequestMethod[method.toUpperCase()], header: { 'Content-Type': xml ? 'text/xml' : 'application/json' }, - extraData: xml?data:JSON.stringify(data) + extraData: xml ? data : JSON.stringify(data) } //params转url拼接参数 let paramsStr = Reflect.ownKeys(params).reduce((p: string, n: string) => (`${p}${n}=${params[n]}&`), '?') || ''; @@ -36,14 +36,9 @@ export default async function request(req: any) { paramsStr = paramsStr.substring(0, paramsStr.length-1) try { let baseUrl=host?host:globalThis.host - // let baseUrl=host?config.csptHost:config.host' - console.info('surenjun',baseUrl) const {result,responseCode} = await httpRequest.request(`${baseUrl}${url}${paramsStr}`, options); - console.log('daihai5') let res:any = xml ? xmlToJson(result,url) : result; - console.log('daihai55') - console.log('响应头地址' + JSON.stringify(res)) let resObj = null; if(typeof res === "string"){ @@ -53,11 +48,7 @@ export default async function request(req: any) { //处理中心服务code if(res.Envelope){ const msgXml = res.Envelope.Body.writeObjectOutResponse.return; - console.log('daihai6') - - const dd = handleCenterCode(msgXml); - console.log('daihai7') - + const dd = handleCenterCode(msgXml,isNewCenter); return dd } @@ -86,6 +77,7 @@ export default async function request(req: any) { }); } } catch (e) { + console.info('surenjun',JSON.stringify(e)) if(!e||!(e?.message)){ return false } @@ -130,7 +122,24 @@ function xmlToJson(result,url) { } //处理中心服务code -function handleCenterCode(msgXml){ +function handleCenterCode(msgXml,isNewCenter){ + //新监管 + if(isNewCenter){ + const msg = JSON.parse(msgXml); + const result = msg?.data[0]?.result; + if(result){ + const {code,message} = result + if(code != '1'){ + prompt.showToast({ + message, duration: 3000 + }); + return + }else{ + return code + } + } + } + //正则匹配code message字段 const [code,message] = [/(.*)<\/code>/i,/(.*)<\/message>/i].map(pattern=>{ const patternArr = pattern.exec(msgXml); @@ -139,7 +148,7 @@ function handleCenterCode(msgXml){ if(code === ''){ prompt.showToast({ - message: decodeURIComponent(message), + message: decodeURIComponent(message as string), duration: 3000 }); return diff --git a/entry/src/main/ets/entryability/EntryAbility.ts b/entry/src/main/ets/entryability/EntryAbility.ts index 07c6b125..a85e910d 100644 --- a/entry/src/main/ets/entryability/EntryAbility.ts +++ b/entry/src/main/ets/entryability/EntryAbility.ts @@ -56,8 +56,8 @@ export default class EntryAbility extends UIAbility { const windowClass = await windowStage.getMainWindow(); globalThis.windowClass = windowClass // await windowClass.setWindowLayoutFullScreen(true) - // await windowClass.setWindowSystemBarEnable([]) //全屏 - await windowClass.setWindowSystemBarEnable(['navigation']) + await windowClass.setWindowSystemBarEnable([]) //全屏 + // await windowClass.setWindowSystemBarEnable(['navigation']) windowStage.loadContent('pages/Index', (err, data) => { if (err.code) { diff --git a/entry/src/main/ets/mock/SignDisplay.ets b/entry/src/main/ets/mock/SignDisplay.ets index b8344fdb..3e27eecc 100644 --- a/entry/src/main/ets/mock/SignDisplay.ets +++ b/entry/src/main/ets/mock/SignDisplay.ets @@ -64,4 +64,24 @@ export const GPSData = [ { key: '经度', value: '0' }, { key: '纬度', value: '0' }, { key: '速度', value: '0' }, -] \ No newline at end of file +] + +export const RoadData = [ + {name:'路段组号',key:'MapRoad_Code_No'}, + {name:'路段编码',key:'MapRoad_Name'}, + {name:'车轮压线',key:['TouchLineType','TouchDir']}, + {name:'车身碰线',key:['TouchLineTypeCS','TouchLineDirCS']}, + {name:'基准车道',key:['BasePointInLaneNo','BaseLaneCount']}, + {name:'前点车道',key:['FrontPointLaneNo','FrontPointLaneCount']}, + {name:'后车点道',key:[]}, + {name:'左前/后车身距离',key:['Body_LF_ToLeftEdge','Body_LB_ToLeftEdge']}, + {name:'右前/后车身距离',key:['Body_RF_ToRightEdge','Body_RB_ToRightEdge']}, + {name:'右前/后车身边线',key:[]}, + {name:'右前/后轮距离',key:['Wheel_RF_ToRightEdge','Wheel_RB_ToRightEdge']}, + {name:'右前/后轮边线',key:['Wheel_RF_ToBaseLine','Wheel_RF_ToBaseLine']}, + {name:'左前/后轮距离',key:['Wheel_LF_ToRightEdge','Wheel_LB_ToRightEdge']}, + {name:'左前/后轮边线',key:['Wheel_LF_ToBaseLine','Wheel_LB_ToBaseLine']}, + {name:'车道属性',key:['BasePointInLaneDir','CrossLineAttr']}, + {name:'形状',key:['InShapeAttr','ShapeNo','']}, + {name:'路段点',key:['CrossPointNo']}, +] diff --git a/entry/src/main/ets/model/SignDisplay.ets b/entry/src/main/ets/model/SignDisplay.ets index 7ded50b4..c3df4d32 100644 --- a/entry/src/main/ets/model/SignDisplay.ets +++ b/entry/src/main/ets/model/SignDisplay.ets @@ -1,4 +1,4 @@ export type SignalDataType = { key: string; value: string; -}; \ No newline at end of file +}; diff --git a/entry/src/main/ets/pages/Judge.ets b/entry/src/main/ets/pages/Judge.ets index 819ed4e0..f033a710 100644 --- a/entry/src/main/ets/pages/Judge.ets +++ b/entry/src/main/ets/pages/Judge.ets @@ -7,6 +7,7 @@ import DeductedPopup from './compontents/judge/DeductionPopup'; import AmplifyPopup from './compontents/judge/AmplifyPopup'; import Judge from './judgeSDK/judge'; import { defaultJudgeConfigObj } from './judgeSDK/utils//judgeCommon'; +import {uploadExamMileage} from '../api/judge' import { CARINFO, @@ -31,6 +32,10 @@ import SignDisplayCom from './compontents/signDisplayCom'; @Entry @Component struct Index { + async aboutToDisappear(){ + clearInterval(this.mileageTimer) + } + async aboutToAppear() { globalThis.windowClass.setWindowSystemBarEnable([]) const time = await getCurrentTime() @@ -38,6 +43,7 @@ struct Index { this.startTime = time.split(' ')[1] this.startFullTime = await getCurrentTime(1); this.startHourTime = await getCurrentHourTime() + this.startExamTime = time setInterval(async () => { this.time = await getCurrentTime(); @@ -53,6 +59,7 @@ struct Index { //初始化评判 const judge = await this.initJudge(); this.judge = judge + } //初始化相关数据库表 @@ -70,6 +77,7 @@ struct Index { await this.initSystemParam() await this.initMarkRules(); await this.initSysset(); + this.singlePlay = globalThis.singlePlay } await this.initCDSBInfo() @@ -77,6 +85,11 @@ struct Index { if (examSubject == 3) { await this.initMapPoint() await this.initMapPointItem() + //定时上传考试里程 + // let mileageTimer = setInterval(()=>{ + // this.uploadMileage() + // },5000) + // this.mileageTimer = mileageTimer } } @@ -102,13 +115,16 @@ struct Index { async initStudent() { const students = await getSyncData('USER') const stuInfo = students[0] || {}; - const {xm,sfzmhm,lsh,kszp,ksdd,kssycs,kslx} = stuInfo; + console.info('surenjun stuInfo=>', JSON.stringify(stuInfo)) + const {xm,sfzmhm,lsh,kszp,ksdd,kssycs,kslx,ksxl} = stuInfo; this.name = xm || '测试考生'; this.idCard = sfzmhm || '01234567891010'; this.lsh = lsh; this.kszp = kszp; this.ksdd = ksdd; this.kssycs = kssycs; + this.ksxl = ksxl; + this.wayno = ksxl; this.kslx = kslx; } @@ -210,14 +226,17 @@ struct Index { const {carName,carType,examSubject} = this; //小车车型列表 const sCarTypes = ['C1', 'C2', 'C5'] - this.wayno = currentParams.wayno || 1; + if (globalThis.singlePlay) { + this.wayno = currentParams.wayno || 1; + } + const {isTrajectoryOpen} = judgeConfig let carNo = '', allItems = []; systemParms.forEach((systemParm) => { if (isTrajectoryOpen) { - systemParm.no1 = systemParm.NO1; - systemParm.no2 = systemParm.NO2; - systemParm.no3 = systemParm.NO3; + systemParm.no1 = systemParm.NO1 + ''; + systemParm.no2 = systemParm.NO2 + ''; + systemParm.no3 = systemParm.NO3 + ''; systemParm.txt1 = systemParm.TXT1; systemParm.txt2 = systemParm.TXT2; systemParm.txt3 = systemParm.TXT3; @@ -233,6 +252,7 @@ struct Index { //获取当前考车的考试项目 if (carNo !== '' && no1 == 3 && no2 == carNo && no3 == 10) { allItems = decodeURIComponent(systemParm.txt1).split(',').filter(txt => txt !== '') + console.info('surenjun', JSON.stringify(allItems)) } const txt2 = decodeURIComponent(systemParm.txt2); if ( @@ -255,6 +275,8 @@ struct Index { projectCodeCenter: txt2, //是否是必考 isRequired: allItems.includes(no2 + ''), + //是否考过了 + isEnd: false, } this.projectsObj[no2*1] = currentProject this.projectsCenterObj[txt2] = currentProject @@ -314,31 +336,38 @@ struct Index { // 断点续考判断 async goDdxkItems() { const judgeConfigObj = this.judgeConfigObj - if (judgeConfigObj['369'] != 1 || judgeConfigObj['432'] != 1) { - return - } - //断点续考判断 - let currentParams: any = router.getParams(); - const examItems: string = currentParams?.examItems; - // 2024-01-03 16:29:26;0;20300,;2,4^2,4;null; - if (examItems !== '' && examItems !== undefined) { - const examItemsArrs = examItems.split(';'); - const startTime = examItemsArrs[0] - const ddxkKsxmArr = examItemsArrs[2]?.split(',').filter(item => item) || [] - const ddxkKfArr = examItemsArrs[3]?.split('^').filter(item => item) || [] - - if (ddxkKsxmArr?.length) { - this.isDdxk = true - ddxkKsxmArr.forEach(xmdm => { - const projectCode = this.projectsCenterObj[xmdm].projectCode - this.projectsObj[projectCode].type = '3' - }) + if (judgeConfigObj['432'] != 0) { + //断点续考判断 + let currentParams: any = router.getParams(); + const examItems: string = currentParams?.examItems; + // 2024-01-03 16:29:26;0;20300,;2,4^2,4;null; + if (examItems !== '' && examItems !== undefined) { + console.info('surenjun examItems=>', JSON.stringify(examItems)) + const examItemsArrs = examItems.split(';'); + const startTime = examItemsArrs[0] + const ddxkKsxmArr = examItemsArrs[2]?.split(',').filter(item => item) || [] + const ddxkKfArr = examItemsArrs[3]?.split('^').filter(item => item) || [] + if (judgeConfigObj['432'] == 2) { + //TODO 带项目带里程 + if (ddxkKsxmArr?.length) { + //断点续考 + ddxkKsxmArr.forEach(xmdm => { + const projectCode = this.projectsCenterObj[xmdm].projectCode + if(this.projectsObj[projectCode]){ + this.projectsObj[projectCode].type = '3' + } + }) + } + } + //扣分续考 ddxkKfArr.forEach((kf) => { const [xmdm, kfdm] = kf.split(',') const currentKf = this.markRuleListObj[`${xmdm}_${kfdm}`] - const currentProject = this.projectsObj[xmdm] - this.projectsObj[xmdm].type = '4' + const currentProject = this.projectsObj[xmdm] || { name: '通用评判' } + if (this.projectsObj[xmdm]) { + this.projectsObj[xmdm].type = '4' + } this.kfArr.push({ //扣分项目名称 xmmcStr: currentProject.name, @@ -355,8 +384,10 @@ struct Index { this.ddxkKsxmArr = ddxkKsxmArr this.ddxkKfArr = ddxkKfArr this.ddxkTime = Date.parse(startTime); + this.isDdxk = true } } + } // 初始化mapPoint表 @@ -418,24 +449,40 @@ struct Index { const strArr = str.split('\n'); const [initData, beginData] = [strArr[0], strArr[1]]; const initDataObj = JSON.parse(initData) + const beginDataObj = JSON.parse(beginData) // initDataObj.systemparm = - const systemparm = initDataObj.systemparm; const examSubject = globalThis.carInfo.examSubject; this.examSubject = isTrajectoryOpen ? (initDataObj.kskm * 1) : examSubject; globalThis.carInfo.examSubject = this.examSubject - await this.initSystemParam(systemparm) + this.singlePlay = beginDataObj.exam == 0; + globalThis.singlePlay = beginDataObj.exam == 0; + await this.initSystemParam(initDataObj.systemparm) await this.initMarkRules(initDataObj.mark); await this.initSysset(initDataObj.sysset); } + // 上传考试里程 + async uploadMileage(){ + if(!globalThis.singlePlay){ + const {lsh,startExamTime:kskssj,jl:kslc} = this + const { carId ,examinationRoomId} = globalThis.carInfo; + await uploadExamMileage({ + carId,examinationRoomId, + lsh,kskssj,kslc + }) + console.info('surenjun 考试里程上传成功') + } + } + build() { Column() { Row() { Row() { Image($rawfile('judge/signal_logoS.png')).width(120) Text(this.time).fontColor('#CCB48F').fontSize(32).padding({ left: 10, right: 5 }) - Image($rawfile(this.isDwztRight?'judge/xh_red.png':'judge/xh_green.png')).width(50) + Image($rawfile(this.isDwztRight ? 'judge/xh_green.png' : 'judge/xh_red.png')).width(50) }.padding({ left: 20 }) + Row() { Text(`当前项目:${this.xmmcStr || '无'} `).fontColor('#E5CCA1').fontSize(32) } @@ -501,12 +548,16 @@ struct Index { Column() { Row() { Text(this.carztStr).fontColor('#FFA500').fontSize(this.FONTSIZE) + if (this.judgeConfigObj['342'] == 0) { + Text(`${this.dw}挡`).fontColor('#FFA500').fontSize(this.FONTSIZE).padding({ left: 15, right: 15 }) + Text(`${this.sd}km/h`).fontColor('#FFA500').fontSize(this.FONTSIZE) + } }.height(40) Row() { Flex({ direction: FlexDirection.Column }) { if (this.kfArr.length) { - List({}) { + List({ scroller: this.kfArrScroller }) { ForEach(this.kfArr, (item) => { ListItem() { Column() { @@ -539,7 +590,6 @@ struct Index { .padding({ top: 12, bottom: 12, left: 8, right: 3 }) }.margin({ top: 35 }).padding({ left: 20, right: 20 }).alignItems(HorizontalAlign.Start) } - } .backgroundImage($rawfile('judge/score_bg.png'), ImageRepeat.NoRepeat) .backgroundImageSize({ width: '100%', height: '100%' }) @@ -594,7 +644,6 @@ struct Index { .padding(30) .margin({ right: 10 }) } - //科目三 if (this.examSubject == 3) { Column() { @@ -606,16 +655,17 @@ struct Index { List({}) { ForEach(this.projects, (project) => { ListItem() { - Text(project.name) {} + Text(project.name) { + } .fontColor(this.getProjectColor(this.projectsObj[project.projectCode].type)) - .margin({ bottom: 5 }) - .fontSize(26) - }.margin({ bottom: 8 }) + .margin({ bottom: 3 }) + .fontSize(22) + }.margin({ bottom: 3 }) }) }.lanes(2).margin({ left: 25 }) } .width('100%') - .height('50%') + .height('57%') .backgroundImage($rawfile('judge/project_km3_bg.png'), ImageRepeat.NoRepeat) .backgroundImageSize({ width: '100%', height: '100%' }) .padding(30) @@ -637,13 +687,13 @@ struct Index { ), ImageRepeat.NoRepeat) .backgroundImageSize({ width: '100%', height: '100%' }) .width(174) - .height(118) - .margin({ bottom: 15 }) + .height(118 * 0.95) + .margin({ bottom: 8 }) .onClick(() => { this.setManualProjectFn(index) }) }) - }.lanes(3).margin({ left: 5, top: 18 }) + }.lanes(3).margin({ left: 5, top: 12 }) } } @@ -663,7 +713,7 @@ struct Index { Column() { Column() { Row() { - Text(this.totalScore + '').fontColor('#FFEECC').fontSize(55) + Text(this.totalScore <= 0 ? '0' : this.totalScore + '').fontColor('#FFEECC').fontSize(55) Text('分').fontColor('#FFEECC').fontSize(30).padding({ top: 5 }) } .width(334) @@ -770,14 +820,19 @@ struct Index { this.endPopupVisible = false; }, confirmFn: async () => { + if (this.judgeConfigObj['344'] == 1) { + Prompt.showToast({ + message: '考试未结束,不允许手动退出!', + duration: 4000 + }); + return + } this.endPopupVisible = false; this.loadingPopupVisible = true - globalThis.isJudge = false clearInterval(this.timer); clearInterval(globalThis.judgeTimer) globalThis.windowClass.setWindowSystemBarEnable(['navigation']) - const judge = this.judge - await judge.handEndExam(true); + this.judge.checkExamIsEnd(true); } }) } @@ -793,8 +848,8 @@ struct Index { Column() { SignDisplayCom({ showBack: false, - scaleNum: 1.5, - msgStr: this.judge.plcStr || '' + scaleNum: 1.8, + msgStr: this.judge.plcStr || '', }).margin({ top: 100 }) Row() { @@ -813,6 +868,7 @@ struct Index { //科目三人工扣分弹窗 if (this.isDeductedPopShow && this.examSubject == 3) { DeductedPopup({ + defaultTabIndex: this.defaultTabIndex, currentItems: Reflect.ownKeys(this.projectsObj).map(projectKey => { //@ts-ignore const project = this.projectsObj[projectKey] @@ -820,7 +876,8 @@ struct Index { }).filter(project => project !== undefined), markRules: this.manualMarkRules, closePopup: () => { - this.isDeductedPopShow = false + this.isDeductedPopShow = false; + this.defaultTabIndex = 0; }, confirmMark: async (itemno, serial) => { const judge = this.judge @@ -955,11 +1012,11 @@ struct Index { } //项目进行中不能人工触发 - if(isProjectIn) { - if(param340 == 1){ - if(isManualProjectIn && (currentXmdm == projectCode)){ + if (isProjectIn) { + if (param340 == 1) { + if (isManualProjectIn && (currentXmdm == projectCode)) { return true - }else{ + } else { return false } } @@ -967,7 +1024,7 @@ struct Index { } //项目路段信息判断 - if(!getProjectIsInRoad(projectCode+'')){ + if (!getProjectIsInRoad(projectCode + '')) { return false } @@ -981,7 +1038,6 @@ struct Index { return false } - //319不为0,或者387不为1,里程不够时,靠边停车项目不能触发 if ((param387 != '1' || param319 != '0') && index === 5) { const {examMileage,isRequiredProjectsEnd,jl} = this; @@ -992,56 +1048,56 @@ struct Index { return true } // 判断项目是否在当前路段号 - getProjectIsInRoad = (projectCode:string,) => { + getProjectIsInRoad = (projectCode: string,) => { const { judgeConfigObj, - lane:{road,num,count} + lane:{ road, num, count } } = this; const projectRoads = { //直线行驶 '3': (judgeConfigObj['514']?.split(',') || []), //变更车道 - '4':judgeConfigObj['515']?.split(',') || [], + '4': judgeConfigObj['515']?.split(',') || [], //超车 - '10':judgeConfigObj['516']?.split(',') || [], + '10': judgeConfigObj['516']?.split(',') || [], //靠边停车 - '11':judgeConfigObj['517']?.split(',') || [], + '11': judgeConfigObj['517']?.split(',') || [], //会车 - '9':judgeConfigObj['518']?.split(',') || [], + '9': judgeConfigObj['518']?.split(',') || [], //掉头 - '12':judgeConfigObj['519']?.split(',') || [], + '12': judgeConfigObj['519']?.split(',') || [], }; - console.info('surenjun',JSON.stringify(projectRoads)) - //未测绘得道路上或者不在差分状态 - if(road === ''){ + if (road === '') { return false } //设置了514-519参数,只能在设置的路段触发对应项目 - if(projectRoads[projectCode].includes(road)){ + if (projectRoads[projectCode].includes(road)) { //如果525为1,则514-519设置的路段不能触发对应项目 - if(judgeConfigObj['525'] == '1'){ + if (judgeConfigObj['525'] == '1') { return false } - }else{ + } else { return false } //405参数为2是,如果在最左侧车道,超车项目不能触发; - if(projectCode == '10' && + if (projectCode == '10' && judgeConfigObj['402'] == '2' && (num === count) && num > 0 - ){ + ) { return false } // 车道总数少于2条,超车和变道不能触发 - if(projectCode == '10' || projectCode == '4'){ - if(count < 2){return false} + if (projectCode == '10' || projectCode == '4') { + if (count < 2) { + return false + } } return true @@ -1075,6 +1131,7 @@ struct Index { @State startTime: string = '00:00:00' @State startFullTime: string = '' @State startHourTime: string = '' + @State startExamTime: string = '' //科目类型 @State examSubject: 2 | 3 = 3; @State ddxkTime: number = 0; @@ -1090,6 +1147,7 @@ struct Index { }[] = [] @State name: string = '' @State idCard: string = '' + @State singlePlay: boolean = false; @State totalScore: number = 100 //模拟考试项目 @State projects: Project[] = [] @@ -1105,6 +1163,7 @@ struct Index { @State kszp: string = '' @State ksdd: string = '' @State kssycs: string = '' + @State ksxl: string = '' @State kslx: string = '' //监管接口序列号 @State serialNumber: number = 0 @@ -1132,11 +1191,20 @@ struct Index { @State isProjectIn: boolean = false; //正在进行的项目代码 @State currentXmdm: string = '' - //必考项目除靠边停车是否全部完成 + // 必考项目除靠边停车是否全部完成 @State isRequiredProjectsEnd: boolean = false; + // 考试项目是否全部完成 + // @State isAllProjectsEnd: boolean = false; @State lane: LANE = { road: '', num: 0, count: 0 } + @State roadData: Object = {}; //定位差分状态时候正常 - @State isDwztRight:boolean = false; + @State isDwztRight: boolean = false; + @State defaultTabIndex: number = 0; private context = getContext(this) as common.UIAbilityContext; - //已考考试项目 + public kfArrScroller: Scroller = new Scroller() + //档位 + @State dw: string = '' + //速度 + @State sd: string = '' + @State mileageTimer: number = 0; } diff --git a/entry/src/main/ets/pages/TerminalInfos.ets b/entry/src/main/ets/pages/TerminalInfos.ets index 2564d567..99c143da 100644 --- a/entry/src/main/ets/pages/TerminalInfos.ets +++ b/entry/src/main/ets/pages/TerminalInfos.ets @@ -18,7 +18,7 @@ struct Index { // '',] // @State inputTextList2: string[] = ['192.168.7.124','20022'] - + // @State inputTextList1: string[] = ['172.37.55.191','18782','172.37.55.191','8082','255.255.255.0','172.37.55.1','114.114.114.114','192.168.7.124','20022','172.37.55.59','20122'] @State inputTextList1: string[] = ['172.37.55.191','18782','172.37.55.191','8082','255.255.255.0','192.168.7.1','114.114.114.114','192.168.7.124','20022','192.168.7.170','20122'] // @State inputTextList2: string[] = [] // 112.80.35.83 11052 diff --git a/entry/src/main/ets/pages/UserInfo.ets b/entry/src/main/ets/pages/UserInfo.ets index 59e0bc0d..5e5d5346 100644 --- a/entry/src/main/ets/pages/UserInfo.ets +++ b/entry/src/main/ets/pages/UserInfo.ets @@ -14,12 +14,20 @@ import common from '@ohos.app.ability.common'; import { User } from './interfaces'; import WebRTCVoice from './webRTC/'; import promptAction from '@ohos.promptAction'; -import { getSyncData } from '../common/service/initable'; +import FilePhoto from './judgeSDK/utils/filePhoto'; +import { getSyncData, upDateTableByArray } from '../common/service/initable'; import { CandidateData, EmptyCandidateObject } from '../mock/CandidateData'; import BoardPrePareSetPopup from './compontents/judge/BoardPrePareSetPopup' +import LoadingPopup from './compontents/judge/LoadingPopup'; +import VoiceAnnounce from './judgeSDK/utils/voiceAnnouncements'; +import { JudgeConfig } from '../config/judge'; +import { judgeConfig } from './judgeSDK/utils/judgeConfig'; + @Entry @Component struct UserInfo { + private filePhoto: FilePhoto + private avPlayer @State pageIndex: number = 0 @State ratio: number = 1700 / 960 @State index: number = 0 @@ -38,6 +46,8 @@ struct UserInfo { @State isBoardPrePareSetPopupOpen: boolean = false @State isFirstBoardPrePareSetPopupBtnShow: boolean = false @State isBoardPrePareSetPopupShow: boolean = false + @State isLoadingPopupVisible:boolean = false; + @State loadingText:string = '正在生成考试记录,请稍后...' @State sczbkf:{xmdm:number,kfdm:string}[] = [] @State currentUser: User = EmptyCandidateObject @State dataList: Array = [] @@ -50,6 +60,8 @@ struct UserInfo { @State nation: string = ''; @State idCard: string = ''; @State grantDept: string = ''; + //是否已经开始考试 + @State isExamStart:boolean = false; @State effectDate: string = ''; @State interval: any = null; @State studentRefreshStatue: string = '0'; @@ -68,12 +80,14 @@ struct UserInfo { { label: '考生姓名', key: 'xm' }, { label: '身份证号', key: 'sfzmhm' }, { label: ' 流 水 号 ', key: 'lsh' }, - { label: '考试路线', key: 'kslx' }, + { label: '考试路线', key: 'ksxl' }, { label: '待考次数', key: 'kssycs' }, { label: '考官姓名', key: 'ksy1' }, ] async onPageShow() { + const mediaTest = new FilePhoto(this.context); + this.filePhoto = new FilePhoto(this.context); //语音功能 new WebRTCVoice(this.context); //初始化数据 @@ -85,7 +99,9 @@ struct UserInfo { this.initSysset() //心跳处理 this.heartMsg() - + this.isExamStart = false + this.sczbkf = []; + this.avPlayer = new VoiceAnnounce(); } //身份证读卡器初始化 @@ -117,14 +133,14 @@ struct UserInfo { this.lsh = this.currentUser.lsh globalThis.lsh = this.currentUser.lsh globalThis.ksyh = this.currentUser.ksy1sfzmhm || this.currentUser.ksy2sfzmhm - + const {examSubject} = globalThis.carInfo; // this.currentUser.kszp=this.photo+res.kszp // this.currentUser.ksmjzp=this.photo+this.currentUser.ksmjzp if (globalThis.singlePlay) { this.stopDeviceById() // globalThis.statue=4 router.pushUrl({ - url: 'pages/Judge', + url: examSubject == 3 ? 'pages/Roads':'pages/Judge', params:{ sczb:Number(this.isBoardPrePareSetPopupOpen), kfdm:this.sczbkf @@ -204,7 +220,6 @@ struct UserInfo { } async initData() { - this.sczbkf = [] this.isFirstBoardPrePareSetPopupBtnShow = false; this.stepFlag = false this.faceCompareSucess = 0 @@ -225,7 +240,7 @@ struct UserInfo { globalThis.ksyh = this.currentUser.ksy1sfzmhm || this.currentUser.ksy2sfzmhm globalThis.lsh = this.lsh } else { - // this.getExaminationStudentInfoFn() + this.getExaminationStudentInfoFn() } const syssetParams = await getSyncData('MA_SYSSET'); //@ts-ignore @@ -432,7 +447,6 @@ struct UserInfo { } async getExaminationItemFn() { - console.info('surenjun', this.currentUser.lsh) if (!this.currentUser.lsh || globalThis.singlePlay) { return } @@ -444,6 +458,7 @@ struct UserInfo { lsh: this.currentUser.lsh || '', examinationRoomId }); + if (examItems?.getExaminationItemRsp?.body?.kssycs != 0) { this.getExaminationStudentInfoFn() } else { @@ -456,34 +471,136 @@ struct UserInfo { //身份比对 async sfbdinterfaceFn() { this.stepFlag = true - console.info('surenjun', this.currentUser.lsh) const carInfo = globalThis.carInfo; const {carId,examinationRoomId} = carInfo; - const examItems = await getExaminationItem({ - time: getCurrentTime(), - carId, - lsh: this.currentUser.lsh || '', - examinationRoomId - }); - - //获取已考项目 - console.log('goroute') - const date = new Date() this.showFaceCompare = false + let examItems = {getExaminationItemRsp:{body:{ykxx:''}}}; + if(!globalThis.singlePlay){ + //获取已考项目 + examItems = await getExaminationItem({ + time: getCurrentTime(), + carId, + lsh: this.currentUser.lsh || '', + examinationRoomId + }); + } + this.currentUser.id = '1' + //是否已经开始考试 + // if(!this.isExamStart){ + const code = await this.beginExam(); + if (code != 1) { + return + } + // } + this.AccountTable.query('0', (result) => { + if (result.length == 0) { + this.isExamStart = true + this.AccountTable.insertData(this.currentUser, (id) => { + this.AccountTable.query('0', (result) => { + globalThis.statue = 4 + this.stepFlag = false + router.pushUrl({ + url: 'pages/Judge', + params: { + examItems: examItems?.getExaminationItemRsp?.body?.ykxx , + sczb:Number(this.isBoardPrePareSetPopupOpen), + kfdm:this.sczbkf + } + }, router.RouterMode.Single); + this.stopDeviceById() + }) + }) + } else { + this.AccountTable.updateData(this.currentUser, (id) => { + this.AccountTable.query('0', (result) => { + this.stepFlag = false + router.pushUrl({ + url:'pages/Judge', + params: { + examItems: examItems?.getExaminationItemRsp?.body?.ykxx , + sczb:Number(this.isBoardPrePareSetPopupOpen), + kfdm:this.sczbkf + } + }, router.RouterMode.Single); + globalThis.statue = 4 + this.stopDeviceById() + }) + }) + } + }) + this.stepFlag = false + } + // 过程照片拍照 + getPhoto = async (empty?: boolean) => { + const singlePlay = globalThis.singlePlay + //单机模式返回空照片 + if (singlePlay) { + return '' + } else { + const {filePhoto} = this; + const photoBase64 = await filePhoto.getPhoto(); + return photoBase64 + } + } + + // 检测车门、熄火信号 + async checkSignal():Promise{ + const {isCheckFireOpen} = judgeConfig + return new Promise((resolve,reject)=>{ + if(isCheckFireOpen){ + resolve(true) + } + globalThis.udpClient.onMessage_1(async (msg) => { + const msgArr = msg.split(',') + const mkg = msgArr[14]; + const fdjzs = msgArr[25]; + globalThis.udpClient.onMessage_1(()=>{}); + //TODO + console.info('surenjun mkg=>', mkg) + console.info('surenjun fdjzs=>', fdjzs) + if(mkg == 1){ + this.avPlayer.playAudio(['voice/关门.mp3']) + promptAction.showToast({ + message:'请关闭车门', + duration:4000 + }) + reject(false) + } + if(fdjzs*1 > 0){ + this.avPlayer.playAudio(['voice/熄火.mp3']) + promptAction.showToast({ + message:'请熄火', + duration:4000 + }) + reject(false) + } + resolve(true) + }) + }) + } + // 开始考试 + async beginExam(){ + const carInfo = globalThis.carInfo; + const {carId,examinationRoomId} = carInfo; const { examSubject,plateNo } = carInfo; + const date = new Date() + console.info('surenjun','photoBase64') + const photoBase64 = await this.getPhoto(); + console.info('surenjun','photoBase64End') const drvexam = { lsh: this.currentUser.lsh || '', - kskm: 2, + kskm: examSubject, ksxtbh: this.ksxtbh || '222', sfzmhm: this.currentUser.sfzmhm || '', ksysfzmhm: this.currentUser.ksy1sfzmhm || '', - zp: encodeURIComponent((this.faceCatchImg || this.currentUser.kszp.substr(22)) || ''), + ksxl:this.currentUser.ksxl, + zp: photoBase64, kssj: dateFormat(date) || '', kchp: decodeURI(plateNo), Ksy2sfzmhm: this.currentUser.ksy2sfzmhm || '' } const param = { - drvexam: drvexam, + drvexam, xtlb: '17', //接口序列号 jkxlh: this.jkxlh || '1234567', @@ -492,48 +609,8 @@ struct UserInfo { } const code = await writeObjectOut(param); globalThis.lsh = this.currentUser.lsh - globalThis.ksyh = this.currentUser.ksy1sfzmhm || this.currentUser.ksy2sfzmhm - this.currentUser.id = '1' - if (code) { - this.AccountTable.query('0', (result) => { - if (result.length == 0) { - this.AccountTable.insertData(this.currentUser, (id) => { - this.AccountTable.query('0', (result) => { - globalThis.statue = 4 - this.stepFlag = false - router.pushUrl({ - url: 'pages/Judge', - params: { - examItems: examItems?.getExaminationItemRsp?.body?.ykxx , - sczb:Number(this.isBoardPrePareSetPopupOpen), - kfdm:this.sczbkf - } - }, router.RouterMode.Single); - this.stopDeviceById() - - }) - }) - } else { - this.AccountTable.updateData(this.currentUser, (id) => { - this.AccountTable.query('0', (result) => { - this.stepFlag = false - router.pushUrl({ - url: 'pages/Judge', - params: { - examItems: examItems?.getExaminationItemRsp?.body?.ykxx , - sczb:Number(this.isBoardPrePareSetPopupOpen), - kfdm:this.sczbkf - } - }, router.RouterMode.Single); - globalThis.statue = 4 - this.stopDeviceById() - }) - }) - } - }) - } else { - this.stepFlag = false - } + globalThis.ksyh = this.currentUser.ksy1sfzmhm || this.currentUser.ksy2sfzmhm; + return code } aboutToDisappear() { @@ -659,67 +736,84 @@ struct UserInfo { if( this.isBoardPrePareSetPopupOpen && !this.isFirstBoardPrePareSetPopupBtnShow){ //上车准备 - Image($r('app.media.sczb_btn')).commStyle().onClick(()=>{ - this.isBoardPrePareSetPopupShow = true; - this.isFirstBoardPrePareSetPopupBtnShow = true; + Image($r('app.media.sczb_btn')).commStyle().onClick(async ()=>{ + try { + await this.checkSignal() + this.isExamStart = true + await upDateTableByArray('USER',[this.currentUser]) + globalThis.statue = 4 + this.isBoardPrePareSetPopupShow = true; + this.isFirstBoardPrePareSetPopupBtnShow = true; + this.stepFlag = false + this.stopDeviceById() + }catch (e){ + + } }) }else{ Image($r('app.media.ksks_btn')) .commStyle() - .onClick(() => { - this.faceCompareSucess = 0 - globalThis.statue = 2 - if (!this.currentUser.xm) { - return - } - // if(globalThis.spzdFlag){ - // promptAction.showToast({ - // message: '摄像头被遮挡', - // duration: 2000 - // }); - // return - // } - if (globalThis.singlePlay) { - const {examSubject} = globalThis.carInfo; - this.AccountTable.query('0', (result) => { - if (result.length == 0) { - this.AccountTable.insertData(this.currentUser, (id) => { - this.AccountTable.query('0', (result) => { - router.pushUrl({ - url: examSubject == 3 ? 'pages/Roads':'pages/Judge', - params:{ - sczb:Number(this.isBoardPrePareSetPopupOpen), - kfdm:this.sczbkf - } - }, router.RouterMode.Single); - this.stopDeviceById() + .onClick(async () => { + try { + // await this.checkSignal() + this.faceCompareSucess = 0 + globalThis.statue = 2 + if (!this.currentUser.xm) { + return + } + // if(globalThis.spzdFlag){ + // promptAction.showToast({ + // message: '摄像头被遮挡', + // duration: 2000 + // }); + // return + // } + console.info('surenjun currentUser',JSON.stringify(this.currentUser)) + if (globalThis.singlePlay) { + const {examSubject} = globalThis.carInfo; + console.info('surenjun => sczbkf',JSON.stringify(this.sczbkf)) + this.AccountTable.query('0', (result) => { + if (result.length == 0) { + this.AccountTable.insertData(this.currentUser, (id) => { + this.AccountTable.query('0', (result) => { + router.pushUrl({ + url: examSubject == 3 ? 'pages/Roads':'pages/Judge', + params:{ + sczb:Number(this.isBoardPrePareSetPopupOpen), + kfdm:this.sczbkf + } + }, router.RouterMode.Single); + this.stopDeviceById() + }) }) - }) - } else { - this.AccountTable.updateData(this.currentUser, (id) => { - this.AccountTable.query('0', (result) => { - router.pushUrl({ - url: examSubject == 3?'pages/Roads':'pages/Judge', - params:{ - sczb:Number(this.isBoardPrePareSetPopupOpen), - kfdm:this.sczbkf - } - }, router.RouterMode.Single); - this.stopDeviceById() + } else { + this.AccountTable.updateData(this.currentUser, (id) => { + this.AccountTable.query('0', (result) => { + router.pushUrl({ + url: examSubject == 3?'pages/Roads':'pages/Judge', + params:{ + sczb:Number(this.isBoardPrePareSetPopupOpen), + kfdm:this.sczbkf + } + }, router.RouterMode.Single); + this.stopDeviceById() + }) }) - }) - } - }) - return - } - if (this.FaceOpenStatue != '0') { - this.showFaceCompare = true - } else { - this.sfbdinterfaceFn() + } + }) + return + } + if (this.FaceOpenStatue != '0') { + this.showFaceCompare = true + } else { + this.sfbdinterfaceFn() + } + }catch (e){ + } + }) } - } } @@ -765,18 +859,34 @@ struct UserInfo { .borderRadius(19 * this.ratio) } - // 上车准备 + // 上车准备弹窗 if(this.isBoardPrePareSetPopupShow){ BoardPrePareSetPopup({ - closePopup:()=>{ - this.isBoardPrePareSetPopupShow = false + closePopup:(bool)=>{ + this.isBoardPrePareSetPopupShow = false; + // if(!globalThis.singlePlay){ + // this.isFirstBoardPrePareSetPopupBtnShow = !bool; + // } }, + // endLoading:()=>{ + // this.isLoadingPopupVisible = false; + // this.faceCompareSucess = 0 + // this.numCount = 0 + // this.getExaminationStudentInfoFn() + // }, confirmMark:(kfdm)=>{ - this.sczbkf= kfdm + this.sczbkf = kfdm } }) } + // loading + // if(this.isLoadingPopupVisible){ + // LoadingPopup({ + // title: this.loadingText, + // }) + // } + } .height('100%') .width('100%') diff --git a/entry/src/main/ets/pages/compontents/SignDisplayCom.ets b/entry/src/main/ets/pages/compontents/SignDisplayCom.ets index 614af9ad..f8351370 100644 --- a/entry/src/main/ets/pages/compontents/SignDisplayCom.ets +++ b/entry/src/main/ets/pages/compontents/SignDisplayCom.ets @@ -2,7 +2,7 @@ import router from '@ohos.router'; import UdpClient from '../../common/utils/UdpClient'; import FileLog from '../judgeSDK/utils/fileLog'; import RealTime from '../compontents/judge/RealTime'; -import { GPSData, SignalData } from '../../mock'; +import { GPSData, SignalData, RoadData } from '../../mock'; import { SignalDataType } from '../../model'; @Component @@ -48,21 +48,23 @@ export default struct SignDisplayCom { }) - Row() { - Text('实时轨迹').fontColor(this.active == 1 ? '#FFAD33' : '#e7cba3').fontSize(20 * this.ratio) + if (!this.showBack) { + Row() { + Text('实时轨迹').fontColor(this.active == 1 ? '#FFAD33' : '#e7cba3').fontSize(20 * this.ratio) + } + .backgroundImage(this.active == 1 ? $r('app.media.signal_tabS') : $r('app.media.signal_tab')) + .width(144 * this.ratio) + .height(50 * this.ratio) + .backgroundImageSize({ width: '100%', height: '100%' }) + .justifyContent(FlexAlign.Center) + .onClick(() => { + this.active = 1 + // this.vocObj.playAudio({ + // type: 1, + // name: 'media_button.wav' + // }) + }) } - .backgroundImage(this.active == 1 ? $r('app.media.signal_tabS') : $r('app.media.signal_tab')) - .width(144 * this.ratio) - .height(50 * this.ratio) - .backgroundImageSize({ width: '100%', height: '100%' }) - .justifyContent(FlexAlign.Center) - .onClick(() => { - this.active = 1 - // this.vocObj.playAudio({ - // type: 1, - // name: 'media_button.wav' - // }) - }) Row() { Text('原始数据').fontColor(this.active == 2 ? '#FFAD33' : '#e7cba3').fontSize(20 * this.ratio) @@ -240,7 +242,7 @@ export default struct SignDisplayCom { Row() { Text('GPS').fontColor(this.gpsActive == 0 ? '#2D3C5A' : '#fff') } - .width(316 * this.ratio) + .width(316 / 2 * this.ratio) .height(24 * this.ratio) .backgroundColor(this.gpsActive == 0 ? '#fff' : '#1A1A1A') .margin({ left: 10 * this.ratio, right: 10 * this.ratio }) @@ -255,22 +257,18 @@ export default struct SignDisplayCom { ForEach(this.GPSColum, (item) => { Column() { Text(`${item.key}:${item.value}`) - .fontSize(14 * this.ratio) - .lineHeight(25 * this.ratio) + .fontSize(12 * this.ratio) + .lineHeight(20 * this.ratio) .fontColor('#fff') - }.height(25 * this.ratio).justifyContent(FlexAlign.Start).width('100%') + }.height(20 * this.ratio).justifyContent(FlexAlign.Start).width('100%') }) } } - .width(168 * 2 * this.ratio) + .width(168 * this.ratio) .height(380 * this.ratio) .backgroundColor('#282828') .margin({ top: 6 * this.ratio, left: 10 * this.ratio }) - // Row() { - // - // }.width(168 * this.ratio).height(380 * this.ratio).backgroundColor('#1A1A1A').margin({ top: 6 * this.ratio }) - Row() { RealTime({ widthNumber: Math.floor(550 * this.ratio), @@ -280,7 +278,7 @@ export default struct SignDisplayCom { .width(550 * this.ratio) .height(380 * this.ratio) .backgroundColor('#1A1A1A') - .margin({ top: 6 * this.ratio, left: 6 * this.ratio }) + .margin({ top: 6 * this.ratio,}) } .width(936 * this.ratio) @@ -308,7 +306,7 @@ export default struct SignDisplayCom { if (showBack) { - this.ratio=1.4 + this.ratio = 1.4 globalThis.udpClient.onMessage_1((msg) => { console.log('msgmsg', msg) if (msg) { diff --git a/entry/src/main/ets/pages/compontents/judge/BoardPrePareSetPopup.ets b/entry/src/main/ets/pages/compontents/judge/BoardPrePareSetPopup.ets index b277baca..5f33ea1e 100644 --- a/entry/src/main/ets/pages/compontents/judge/BoardPrePareSetPopup.ets +++ b/entry/src/main/ets/pages/compontents/judge/BoardPrePareSetPopup.ets @@ -3,20 +3,23 @@ import { judgeConfig } from '../../judgeSDK/utils/judgeConfig'; import FileUtil from '../../../common/utils/File'; import common from '@ohos.app.ability.common'; import VoiceAnnounce from '../../judgeSDK/utils/voiceAnnouncements'; - -import { - MarkRule, - SYSSET, -} from '../../judgeSDK/api/judgeSDK.d'; +import { getCurrentTime } from '../../../common/utils/tools'; +import { MarkRule, SYSSET } from '../../judgeSDK/api/judgeSDK.d'; +import { uploadExamProgressData, writeObjectOut } from '../../../api/judge'; +import JudgeTask from '../../judgeSDK/utils/judgeTask'; +import FilePhoto from '../../judgeSDK/utils/filePhoto'; interface SEL { fontColor: string bgColor: string } +//考前模拟人工扣分 @Component export default struct DeductedPopup { private context = getContext(this) as common.UIAbilityContext; + private judgeTask: JudgeTask + private filePhoto: FilePhoto private avPlayer @State name: string = '' @State idCard: string = '' @@ -25,10 +28,14 @@ export default struct DeductedPopup { @State ksdd: string = '' @State kssycs: string = '' @State kslx: string = '' + @State ksxl: string = '' + @State score: number = 100; + @State judgeConfigObj: { [k: string]: any } = {} @State kfdmArr: { xmdm: number, kfdm: string, - markreal: number + markreal: number, + markcatalog: string }[] = [] //开始考试前判绕车一周评判是否开启 @State isOpen: boolean = false @@ -51,22 +58,36 @@ export default struct DeductedPopup { } private confirmMark: Function = (itemno: number, serial: string) => { } + private endLoading: Function = () => { + } @State selectedLineStyle: SEL = { fontColor: '#FFF', bgColor: '#B36E00' } - aboutToAppear() { + async aboutToAppear() { + this.avPlayer = new VoiceAnnounce(); + this.judgeTask = new JudgeTask(); + const mediaTest = new FilePhoto(this.context); + this.filePhoto = mediaTest //上车准备 // this.universalMarkRules = this.markRules.filter(item => this.currentItems.includes(item.itemno+'')) const {isTrajectoryOpen} = judgeConfig; if (isTrajectoryOpen) { - this.initDb() + await this.initDb() } else { - this.initSysset() - this.initMarkRules() + await this.initSysset() + await this.initMarkRules() + await this.initStudent() } - this.avPlayer = new VoiceAnnounce(); + + // const {judgeTask} = this; + // judgeTask.addTask(async () => { + // await this.beginProject(); + // }, { isDelay: true }) + // judgeTask.addTask(async () => { + // await this.uploadProgressPhoto(); + // }, { isDelay: true }) } //本地数据初始化 @@ -86,9 +107,239 @@ export default struct DeductedPopup { await this.initStudent() } + // 过程照片拍照 + getPhoto = async (empty?: boolean) => { + const singlePlay = globalThis.singlePlay + //单机模式返回空照片 + if (singlePlay) { + return '' + } else { + const {filePhoto} = this; + const photoBase64 = await filePhoto.getPhoto(); + return photoBase64 + } + } + + // 扣分操作 + async pointsDedute() { + const singlePlay = globalThis.singlePlay + const index = this.currentIndex ? this.currentUniversalPageIndex : this.currentPageIndex; + const mark = this.universalMarkRules[index * 7 + this.selectedLine]; + const {judgeConfigObj,kssycs,avPlayer,judgeTask} = this; + this.kfdmArr.push({ xmdm: 1, kfdm: mark.markserial, markreal: mark.markreal, markcatalog: mark.markcatalog }) + const kfdmArr = this.kfdmArr + + //计算总扣分 + let score = kfdmArr.reduce((p, n) => { + p += n.markreal * 1 + return p + }, 0); + this.score = score + + this.confirmMark(this.kfdmArr.map((kf) => ({ + xmdm: kf.xmdm, + kfdm: kf.kfdm, + }))) + + if (judgeConfigObj['418'] == '1' || judgeConfig.kfVoiceOpen) { + avPlayer.playAudio([`voice/${mark.markcatalog}.mp3`], false, () => { + this.closePopup(true) + }); + return + } + + if (singlePlay) { + return + } else { + this.closePopup() + } + return; + + if (score < 90) { + this.closePopup(true) + avPlayer.playAudio(['voice/exam_waiting.mp3', `voice/kfdesc.mp3`]) + judgeTask.addTask(async () => { + //扣分 + await this.kfFn(); + }, { isDelay: true }) + + judgeTask.addTask(async () => { + //项目结束 + await this.endProject(); + }, { isDelay: true }) + + judgeTask.addTask(async () => { + //结束考试 + await this.endFn() + }, { isDelay: true }) + } + ; + + let voiceURL = score < 90 ? `voice/${kssycs == '1' ? 'exam_no_pass_finish' : 'exam_no_pass'}.mp3` : 'voice/exam_pass.mp3' + + let kfScore = 0; + if (kfdmArr.length) { + kfdmArr.forEach((kf, index) => { + kfScore += Math.abs(Number(kf.markreal)); + if (kfScore <= 100) { + judgeTask.addTask(() => { + if (index === kfdmArr.length - 1) { + avPlayer.playAudio([`voice/${kf.markcatalog}.mp3`, voiceURL], false, () => { + this.endLoading(true) + }) + } else { + avPlayer.playAudio([`voice/${kf.markcatalog}.mp3`]) + } + }) + } + }) + } + + this.confirmMark(this.kfdmArr.map((kf) => ({ + xmdm: kf.xmdm, + kfdm: kf.kfdm, + }))) + + } + + //项目开始 + async beginProject() { + //项目开始 //过程照片 //扣分 //结束考试 + const carInfo = globalThis.carInfo; + const { examSubject,plateNo } = carInfo; + const {serialNumber,lsh,idCard,ksxl,kslx,ksdd} = this + const time = await getCurrentTime(); + const beginData = { + xtlb: '17', jkxlh: serialNumber, jkid: '17C52', + drvexam: { + // 考试科目 身份证号码 + lsh, + kskm: examSubject, + sfzmhm: idCard, + ksxm: '40100', + ksxl, + kchp: decodeURI(plateNo), + ksdd: decodeURI(ksdd), + kslx: decodeURI(kslx) || '', + kssj: time + }, + } + const code = await writeObjectOut(beginData) + //TODO code待处理 + if (code == 1) { + + } + } + + //过程照片 + async uploadProgressPhoto() { + const {serialNumber,lsh,idCard,ksdd,kfdmArr,getPhoto} = this; + const carInfo = globalThis.carInfo; + const { examSubject,plateNo,carNo } = carInfo; + const time = await getCurrentTime(); + console.info('surenjun uploadProgressPhoto',) + const photoBase64 = await getPhoto() + const photoData = { + xtlb: '17', jkxlh: serialNumber, jkid: '17C54', + drvexam: { + lsh, + kskm: examSubject, + ksxm: '40100', + sfzmhm: idCard, + kchp: decodeURI(plateNo), + zpsj: time, + //@ts-ignore + // zp: encodeURIComponent(photoBase64), + zp: photoBase64, + cs: 0, + ksdd: decodeURI(ksdd) + } + }; + const code = await writeObjectOut(photoData); + console.info('surenjun uploadProgressPhoto end',) + } + + // 扣分 + async kfFn() { + const {serialNumber,lsh,idCard,ksdd,kfdmArr} = this; + const kfLen = kfdmArr.length; + const kf = kfdmArr[kfLen -1]; + const carInfo = globalThis.carInfo; + const { examSubject} = carInfo; + const time = await getCurrentTime(); + const kfData = { + xtlb: '17', jkxlh: serialNumber, jkid: '17C53', + drvexam: { + lsh, + kskm: examSubject, + // 通用评判科二10000,科三30000 + ksxm: 40100, + kfxm: kf.markcatalog, + kfxmmx: `${'1'},${kf.kfdm}`, + sfzmhm: idCard, + kchp: decodeURI(carInfo.plateNo), + kffs: 2, + ksdd: decodeURI(ksdd), + kfsj: time + } + } + const code = await writeObjectOut(kfData); + } + + // 项目结束 + async endProject() { + const carInfo = globalThis.carInfo; + const { examSubject,plateNo,carNo } = carInfo; + const {lsh,idCard,serialNumber,ksdd,kslx,ksxl,} = this; + const time = await getCurrentTime(); + const endProjectData = { + xtlb: '17', jkxlh: serialNumber, jkid: '17C55', + drvexam: { + lsh, + kskm: examSubject, + sfzmhm: idCard, + ksxm: '40100', + czlx: '1', + ksxl, + kchp: decodeURI(plateNo), + ksdd: decodeURI(ksdd), + kslx: encodeURI(kslx) || '', + jssj: time + } + } + const code = await writeObjectOut(endProjectData); + } + + //考试结束 + async endFn() { + const {serialNumber,lsh,idCard,score,getPhoto} = this; + const carInfo = globalThis.carInfo; + const { examSubject,plateNo } = carInfo; + const time = await getCurrentTime(); + const photoBase64 = await getPhoto(); + const endData = { + xtlb: '17', jkxlh: serialNumber, jkid: '17C56', + drvexam: { + lsh, + kchp: decodeURI(plateNo), + kskm: examSubject, + sfzmhm: idCard, + //@ts-ignore + // zp: encodeURIComponent(photoBase64), + zp: photoBase64, + jssj: time, + kscj: (score * 1) > 0 ? score : 0, + kslc: 0, + dwlc: '', + } + } + const code = await writeObjectOut(endData); + } + //获取sysset表数据 async initSysset(sysset?: SYSSET[]) { const syssetParams = sysset || await getSyncData('MA_SYSSET'); + console.info('surenjun syssetParams', JSON.stringify(syssetParams)); //@ts-ignore syssetParams.forEach(sys => { //监管序列号 @@ -101,15 +352,14 @@ export default struct DeductedPopup { if (isOpen) { this.avPlayer.playAudio(['voice/上车准备.mp3']) } - } + this.judgeConfigObj[sys.v_no] = decodeURIComponent(sys.v_value) }) } //获取markrule表数据 async initMarkRules(markRules ?: MarkRule[]) { const markRuleParams = markRules || (await getSyncData('MA_MARKRULE') as MarkRule[]) - markRuleParams.forEach(mark => { const tempObj = { itemno: mark.itemno * 1, @@ -140,7 +390,8 @@ export default struct DeductedPopup { async initStudent() { const students = await getSyncData('USER') const stuInfo = students[0] || {}; - const {xm,sfzmhm,lsh,kszp,ksdd,kssycs,kslx} = stuInfo; + + const {xm,sfzmhm,lsh,kszp,ksdd,kssycs,kslx,ksxl} = stuInfo; this.name = xm || '测试考生'; this.idCard = sfzmhm || '01234567891010'; this.lsh = lsh; @@ -148,6 +399,7 @@ export default struct DeductedPopup { this.ksdd = ksdd; this.kssycs = kssycs; this.kslx = kslx; + this.ksxl = ksxl; } //上一页 下一页 @@ -273,34 +525,8 @@ export default struct DeductedPopup { .alignItems(VerticalAlign.Center) .backgroundImage($rawfile(`judge/km3/button_nor.png`)) .backgroundImageSize({ width: '100%', height: '100%' }) - .onClick(() => { - const index = this.currentIndex ? this.currentUniversalPageIndex : this.currentPageIndex; - const mark = this.universalMarkRules[index * 7 + this.selectedLine]; - const {avPlayer,kssycs} = this; - this.kfdmArr.push({ xmdm: 1, kfdm: mark.markserial, markreal: mark.markreal }) - - //计算总扣分 - let score = this.kfdmArr.reduce((p, n) => { - p += n.markreal - return p - }, 0); - avPlayer.playAudio([`voice/${mark.markcatalog}.mp3`]); - console.info('surenjun',score) - if(!globalThis.singlePlay){ - if (score < -90) { - avPlayer.playAudio([ - 'voice/exam_waiting.mp3', - kssycs == '1' ? 'voice/unqualified_one.wav' : 'voice/unqualified_two.wav' - ]); - - }; - } - - this.confirmMark(this.kfdmArr.map((kf) => ({ - xmdm:kf.xmdm, - kfdm:kf.kfdm, - }))) - + .onClick(async () => { + this.pointsDedute() }) } }.width('100%').justifyContent(FlexAlign.SpaceBetween) @@ -340,8 +566,14 @@ export default struct DeductedPopup { .position({ y: '85%', x: '50%' }) .backgroundImage($rawfile('judge/km3/close_nor.png')) .backgroundImageSize({ width: '100%', height: '100%' }) - .onClick(() => { - this.closePopup() + .onClick(async () => { + //没有扣分项目通过 + this.closePopup(this.kfdmArr.length ? true : false) + + // judgeTask.addTask(async () => { + // await this.endProject() + // }, { isDelay: true }) + }) }.width('100%').height('100%').position({ y: 0 }).backgroundColor('rgba(0,0,0,0.7)') } diff --git a/entry/src/main/ets/pages/compontents/judge/DeductionPopup.ets b/entry/src/main/ets/pages/compontents/judge/DeductionPopup.ets index 576e8b14..43893b14 100644 --- a/entry/src/main/ets/pages/compontents/judge/DeductionPopup.ets +++ b/entry/src/main/ets/pages/compontents/judge/DeductionPopup.ets @@ -21,8 +21,8 @@ export default struct DeductedPopup { private markRules:MarkRule[] = [] @State universalMarkRules:MarkRule[] = [] @State manualMarkRules:MarkRule[] = [] - @State currentItems:number[] = [] - + @State currentItems:string[] = [] + @Prop defaultTabIndex:number = 0 @State lineBg:Array = ['#4D4136','#26231E'] @State selectedLine:number = undefined private closePopup:Function = ()=> {} @@ -34,8 +34,9 @@ export default struct DeductedPopup { aboutToAppear(){ //@ts-ignore + this.universalMarkRules = this.markRules.filter(item => (this.currentItems.includes(item.itemno) || this.currentItems.includes(item.itemno + ''))); + this.currentIndex = this.defaultTabIndex - this.universalMarkRules = this.markRules.filter(item => (this.currentItems.includes(item.itemno) || this.currentItems.includes(item.itemno + ''))) } //上一页 下一页 goPage(typeIndex){ diff --git a/entry/src/main/ets/pages/compontents/judge/RealTime.ets b/entry/src/main/ets/pages/compontents/judge/RealTime.ets index 7f17973a..28b87539 100644 --- a/entry/src/main/ets/pages/compontents/judge/RealTime.ets +++ b/entry/src/main/ets/pages/compontents/judge/RealTime.ets @@ -3,6 +3,11 @@ import Judge from '../../judgeSDK/utils/judgeReal'; import { MarkRule, Project, ProjectObj } from '../../judgeSDK/api/judgeSDK.d'; import common from '@ohos.app.ability.common'; +interface RoadDataType { + name: string, + key: string | string[] +} + @Component export default struct RealTime { @State message: string = '开始绘制' @@ -14,9 +19,13 @@ export default struct RealTime { @State projects: Project[] = [] @State projectsObj: ProjectObj = {} @State markRuleListObj: MarkRule = {} + @State gpsActive: number = 1 private widthNumber: string | number | Resource = 0 private heightNumber: string | number | Resource = 0 private context = getContext(this) as common.UIAbilityContext; + @State ratio: number = 1 + @State lane: Object = {} + @State timer:number = 0 constructor() { super() @@ -26,6 +35,32 @@ export default struct RealTime { build() { Row() { + Column() { + Row() { + Text('车道信息').fontColor(this.gpsActive == 0 ? '#2D3C5A' : '#fff').fontSize(20) + } + .width('100%') + .height(37) + .backgroundColor(this.gpsActive == 0 ? '#fff' : '#1A1A1A') + .margin({ top: 10 * this.ratio, right: 10 }) + .justifyContent(FlexAlign.Center) + + Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start }) { + ForEach(this.RoadData, (item) => { + Column() { + Text(`${item.name}:${this.getValues(item)}`) + .fontSize(20) + .lineHeight(30) + .fontColor('#fff') + }.height(30).justifyContent(FlexAlign.Start).width('100%') + }) + }.margin({top:5}) + + }.width(168 * 1.5) + .height(this.heightNumber) + .backgroundColor('#282828') + .margin({ top: 6 * this.ratio, }) + Column() { if (this.draw) { XComponent({ @@ -57,14 +92,49 @@ export default struct RealTime { .height('100%') } + async aboutToDisappear() { + clearInterval(this.timer) + } async aboutToAppear() { - const judge = new Judge(this) + let timer = setInterval(()=>{ + this.lane = globalThis.laneData; + },1000) + this.timer = timer } - aboutToDisappear() { - //apiJudgeSdk.stopRender(); - + getValues(roadColumn) { + const lane = this.lane || {}; + let key = roadColumn.key; + let str = '' + if (Array.isArray(key)) { + key.forEach((k, index) => { + str += (lane[k] === undefined ? '' : lane[k]) + (index == key.length - 1 ? '' : '/') + }) + } else { + str = lane[key] === undefined ? '' : lane[key] + } + return str } + + private RoadData: Array = [ + { name: '路段组号', key: 'MapRoad_Code_No' }, + { name: '路段编码', key: 'MapRoad_Name' }, + { name: '车轮压线', key: ['TouchLineType', 'TouchDir'] }, + { name: '车身碰线', key: ['TouchLineTypeCS', 'TouchLineDirCS'] }, + { name: '基准车道', key: ['BasePointInLaneNo', 'BaseLaneCount'] }, + { name: '前点车道', key: ['FrontPointLaneNo', 'FrontPointLaneCount'] }, + { name: '后车点道', key: ['BackPointLaneNo','BackPointLaneCount'] }, + { name: '左前/后车身距离', key: ['Body_LF_ToLeftEdge', 'Body_LB_ToLeftEdge'] }, + { name: '右前/后车身距离', key: ['Body_RF_ToRightEdge', 'Body_RB_ToRightEdge'] }, + { name: '右前/后车身边线', key: ['Body_RF_ToBaseLine','Body_RB_ToBaseLine'] }, + { name: '右前/后轮距离', key: ['Wheel_RF_ToRightEdge', 'Wheel_RB_ToRightEdge'] }, + { name: '右前/后轮边线', key: ['Wheel_RF_ToBaseLine', 'Wheel_RB_ToBaseLine'] }, + { name: '左前/后轮距离', key: ['Wheel_LF_ToRightEdge', 'Wheel_LB_ToRightEdge'] }, + { name: '左前/后轮边线', key: ['Wheel_LF_ToBaseLine', 'Wheel_LB_ToBaseLine'] }, + { name: '车道属性', key: ['BasePointInLaneDir', 'CrossLineAttr','DirInverse'] }, + { name: '形状', key: ['InShapeAttr', 'ShapeNo','ShapeNoWheel'] }, + { name: '路段点', key: ['CrossPointNo'] }, + ] } diff --git a/entry/src/main/ets/pages/judgeSDK/api/index.ts b/entry/src/main/ets/pages/judgeSDK/api/index.ts index c5124d35..1130ab6d 100644 --- a/entry/src/main/ets/pages/judgeSDK/api/index.ts +++ b/entry/src/main/ets/pages/judgeSDK/api/index.ts @@ -77,9 +77,11 @@ export async function examJudgeArtificialMark( //项目代码 itemno:number, //扣分代码 - serial:string + serial:string, + //扣分类型:number + type:number ){ - const temp = libJudgeSdk.examJudgeArtificialMark(itemno,serial); + const temp = libJudgeSdk.examJudgeArtificialMark(itemno,serial,type); return await handle(temp,'examJudgeArtificialMark') } @@ -93,8 +95,6 @@ export async function examJudgeArtificialItem( //操作类型 type:number = 0 ){ - console.info('surenjun itemno=>',itemno) - console.info('surenjun type=>',type) const temp = libJudgeSdk.examJudgeArtificialItem(itemno,type); return await handle(temp,'examJudgeArtificialMark') } @@ -133,7 +133,6 @@ export function handleLog(level,infoStr, len){ * */ export async function examJudgeEndExam(){ - console.info('surenjun','考试结束调用') const temp = libJudgeSdk.examJudgeEndExam(); return await handle(temp,'examJudgeEndExam') } diff --git a/entry/src/main/ets/pages/judgeSDK/api/judgeSDK.d.ts b/entry/src/main/ets/pages/judgeSDK/api/judgeSDK.d.ts index f75ad652..9ba7fded 100644 --- a/entry/src/main/ets/pages/judgeSDK/api/judgeSDK.d.ts +++ b/entry/src/main/ets/pages/judgeSDK/api/judgeSDK.d.ts @@ -1,170 +1,206 @@ - -export interface Project{ +export interface Project { //项目名称 - name:string + name: string //项目代码 - projectCode:string + projectCode: string //无锡所项目代码 - projectCodeCenter:string + projectCodeCenter: string //项目简写 - abbreviation?:string + abbreviation?: string //项目状态:未做 正在做 及格 不及格 type?: '1' | '2' | '3' | '4' + // } -export interface MarkRule{ - itemno?:number - markcatalog?:string - markshow?:string - markserial?:string - markstandard?:number, - markreal?:number - kfxh?:string - onlyoneid?:number - nocancelid?:number - gps_sid?:number - +export interface MarkRule { + itemno?: number + markcatalog?: string + markshow?: string + markserial?: string + markstandard?: number, + markreal?: number + kfxh?: string + onlyoneid?: number + nocancelid?: number + gps_sid?: number } -export interface SYSTEMPARMARR{ - 'NO1':number, - 'NO2':number, - 'NO3':number, - 'TXT1':string, - 'TXT2':string, - 'TXT3':string, +export interface KF{ + //项目名称 + xmmcStr: string, + xmdm: string | number, + //扣分描述 + desc: string, + //扣分 + score: string + //无锡所扣分代码 + markcatalog: string + markserial: string + kfxh: string + type: 0| 1 | 2 } -export interface SYSTEMPARMARROBJ{ - 'no1':number, - 'no2':number, - 'no3':number, - 'txt1':string, - 'txt2':string, - 'txt3':string, - [k:string]:string|number +export interface SYSTEMPARMARR { + 'NO1': number, + 'NO2': number, + 'NO3': number, + 'TXT1': string, + 'TXT2': string, + 'TXT3': string, +} + +export interface SYSTEMPARMARROBJ { + 'no1': number, + 'no2': number, + 'no3': number, + 'txt1': string, + 'txt2': string, + 'txt3': string, + + [k: string]: string | number } -export interface CARINFO{ - CARID:string, - IPADDR:string, - CARCLASS:string, - KSCX:string, - CARNAME:string, - FLAG:string, - BK1:string, - BK2:string +export interface CARINFO { + CARID: string, + IPADDR: string, + CARCLASS: string, + KSCX: string, + CARNAME: string, + FLAG: string, + BK1: string, + BK2: string } -export interface MAPPOINT{ - point_no:number, - gps_e:number, - gps_n:number, - point_no_f:number, - point_type:number, - road_code:string, - gps_e_Location:number - gps_n_Location:number - f_gps_e:number, - f_gps_n:number, - passed:number +export interface MAPPOINT { + point_no: number, + gps_e: number, + gps_n: number, + point_no_f: number, + point_type: number, + road_code: string, + gps_e_Location: number + gps_n_Location: number + f_gps_e: number, + f_gps_n: number, + passed: number } -export interface MAPITEMPOINTITEM{ - point_no:number, - itemno:number, - itemno1:number, - subname:string +export interface MAPITEMPOINTITEM { + point_no: number, + itemno: number, + itemno1: number, + subname: string } -export interface EXAMDATA{ +export interface EXAMDATA { //1:项目开始 2:项目结束 3:扣分 4:考车状态 5:考试结束 6:项目取消 7:语音播放和提示 8:模拟灯光事件 9:车道信息事件 - event:1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 + event: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 //时间 - sj:number + sj: number //考车状态 -1:后退 0:停车 1:前进 - carzt:-1 | 0 | 1 + carzt: -1 | 0 | 1 //项目开始 - xmks:{ + xmks: { //项目代码 项目子序号 - xmdm:number, xmxh:string + xmdm: number, + xmxh: string } //项目结束 - xmjs:{ + xmjs: { //项目代码 项目子序号 项目是否合格 - xmdm:number, xmxh:string, xmhg: 1 | 0 + xmdm: number, + xmxh: string, + xmhg: 1 | 0 }, + //扣分 - kf:{ + kf: { //项目代码 - xmdm:number, + xmdm: number, //扣分代码 - kfdm:string, + kfdm: string, //无锡所扣分代码 - markcatalog:string + markcatalog: string + // 0:评判自动扣分 1:本地人工扣分 2:远程人工扣分 + type: 0 | 1 | 2 }, + //考试结束 - ksjs:{ + ksjs: { //前进距离 - qjjl:number, + qjjl: number, //倒车距离 - dcjl:number + dcjl: number }, + //项目取消 - xmqx:{ + xmqx: { //项目代码 项目子序号 - xmdm:number, xmxh:string + xmdm: number, + xmxh: string }, - sound:{ - xmdm:number, + sound: { + xmdm: number, //语音播放文件代码 - code:string, - type:number + code: string, + type: number }, + //模拟灯光 - mndg:string, - lane:LANE + mndg: string, + lane: LANE, + type: number } - -export interface MAPPOINTITEM{ - +export interface KSJS { + //0:自动结束,1:手动结束 + type: 0 | 1 + qjjl: number, + dcjl: number, + d1: number, + d2: number, + d3: number, + d4: number, + d5: number, + d6: number, } -export interface CDSBInfo{ +export interface MAPPOINTITEM {} -} +export interface CDSBInfo {} export interface SOUND { //项目代码 - xmdm:number + xmdm: number //语音播放提示代码 - code:string, + code: string, + //0:普通,1:模拟灯光 - type:number -} -export interface SYSSET { - v_no:string, - v_name:string, - v_value:string + type: number } -export interface LANE{ +export interface SYSSET { + v_no: string, + v_name: string, + v_value: string +} + +export interface LANE { //当前路段号 如果road为空字符串””,说明当前在未测绘得道路上或者不在差分状态 - road:string + road: string /*当前基准天线所在车道号 num等于0或者count等于0说明当前未在测绘路段,或者不在差分状态。 num等于1的时候表示在最右侧车道 num等于count的时候的表示在最左侧车道 */ - num:number + num: number //当前基准天线共有几股车道 - count:number + count: number } export interface ProjectObj { - [k:string]:Project + [k: string]: Project } diff --git a/entry/src/main/ets/pages/judgeSDK/judge.ts b/entry/src/main/ets/pages/judgeSDK/judge.ts index 85d98f0a..71a7ecf0 100644 --- a/entry/src/main/ets/pages/judgeSDK/judge.ts +++ b/entry/src/main/ets/pages/judgeSDK/judge.ts @@ -3,18 +3,18 @@ import router from '@ohos.router'; import util from '@ohos.util'; import buffer from '@ohos.buffer'; import { testKmItems, testMarkRules } from './dataTest/index'; -import { EXAMDATA, SOUND } from './api/judgeSDK'; +import { EXAMDATA, SOUND, KSJS } from './api/judgeSDK'; import VoiceAnnounce from './utils/voiceAnnouncements'; import FileModel from './utils/fileModel'; import FilePhoto from './utils/filePhoto'; import FileUtil from '../../common/utils/File'; import FileLog from './utils/fileLog'; - import JudgeTask from './utils/judgeTask'; import { judgeConfig } from './utils/judgeConfig'; - - import { uploadExamProgressData, writeObjectOut } from '../../api/judge'; +import UsbService from '../../common/service/usbService'; +import { LANE,KF } from '../judgeSDK/api/judgeSDK.d'; + import { Array2Byte, convertGpsCoord2, @@ -24,6 +24,7 @@ import { string2Bytes, stringToASC } from '../../common/utils/tools'; + import { getCarStatus, getCarStatusType, @@ -35,6 +36,7 @@ import { promptWxCode, senorToWXDataStr } from './utils/judgeCommon'; + import { examJudgeArtificialItem, examJudgeArtificialMark, @@ -47,9 +49,6 @@ import { examJudgeSetPerformCallback, examJudgeSetRealExamCallback } from './api/index'; -import UsbService from '../../common/service/usbService'; - -import Prompt from '@system.prompt'; const judgeTag = 'SURENJUN_JUDGE' @@ -57,7 +56,6 @@ export default class Judge { constructor(judgeUI) { this.serialIndex = 1; this.judgeUI = judgeUI - //语音播放工具 this.avPlayer = new VoiceAnnounce(); //模型工具 @@ -65,9 +63,8 @@ export default class Judge { //文件工具 this.fileUtil = new FileUtil(judgeUI.context) this.judgeTask = new JudgeTask() - const mediaTest = new FilePhoto(judgeUI.context); this.usbService = new UsbService(); - this.filePhoto = mediaTest + this.filePhoto = new FilePhoto(judgeUI.context); this.kfArr = judgeUI.kfArr this.xmmcStr = ''; this.xmmcCode = ''; @@ -80,7 +77,7 @@ export default class Judge { this.modelPath = modelPath; this.trajectoryPath = trajectoryPath; - this.isExam = !globalThis.singlePlay; + this.isExam = !this.judgeUI.singlePlay; const {projectsCenterObj} = judgeUI //科目三待修改 @@ -93,12 +90,13 @@ export default class Judge { } } }) - this.isEnd = false; + this.isExamEnd = false; } public async onJudgeFn(fn: Function) { await this.judging(fn) } + //开始评判 private async judging(callBack: Function) { const {judgeUI} = this; @@ -119,7 +117,7 @@ export default class Judge { } //日志回调 console.info(judgeTag, '1.进入评判入口') - await examJudgeSetLogCallback(3, async (level, info, len) => { + await examJudgeSetLogCallback(6, async (level, info, len) => { console.log('评判日志:' + info) await fileLog.setExamJudgeLogData(info); }) @@ -151,6 +149,8 @@ export default class Judge { const performInfo = JSON.parse(info) this.performInfo = performInfo this.judgeUI.jl = Math.floor((performInfo.qjjl + performInfo.dcjl) / 100) + //TODO 待优化 跨组件传值不生效 + globalThis.laneData = performInfo.lane; }) // 3.开始考试 @@ -162,11 +162,8 @@ export default class Judge { await fileLog.setExamJudgeData(beginExamInfo) await examJudgeBeginExam(beginExamInfo); console.info(judgeTag, '6.开始考试注册完成') - avPlayer.playAudio(['voice/ksks.WAV']) - this.judgeUI.draw = true - // 处理轨迹plc信息 if (isTrajectoryOpen) { handleTrajectoryUdp(strArr); @@ -177,6 +174,7 @@ export default class Judge { handleUdp(msg) }) } + // 获取评判初始化数据 getJudgeInitData = async () => { const {getModelData,getKm3JudgeInitConfig} = this @@ -206,14 +204,14 @@ export default class Judge { name: carName, carmodel: getModelData(`${examType}/${carType}.txt`), allitems, - iteminfo:[], + iteminfo: [], systemparm: systemparmArr, mark: Reflect.ownKeys(markRuleListObj).map(ruleKey => (markRuleListObj[ruleKey])) || testMarkRules, sysset: judgeUI.judgeConfig, }; let km3Config = {} - if (examSubject == 3) { + if (examSubject == 3) { km3Config = await getKm3JudgeInitConfig(); } // 获取科目三的评判配置 @@ -223,6 +221,7 @@ export default class Judge { ...km3Config, } } + // 获取开始考试数据 getJudgeBeginData = async () => { const {code,name:examinerName} = globalThis.examinerInfo; @@ -259,7 +258,7 @@ export default class Judge { }), //断点续考 ddxk: isDdxk ? 1 : 0, - ddkssj: ddxkTime, + ddkssj: ddxkTime || 0, ykxm: isDdxk ? (ddxkKsxmArr?.map(projectCenterCode => (projectsCenterObj[projectCenterCode]?.projectCode) * 1)) : [], kfxm: isDdxk ? (ddxkKfArr?.map(kf => { const [xmdm, kfdm] = kf.split(',') @@ -268,11 +267,12 @@ export default class Judge { kfdm } })) : [], + //TODO 已考里程待修改 yklc: 0, special: [], //TODO 科目三参数临时写死 - sczb: (sczb === undefined || sczb == 0)?0:1, - sczbkf:kfdm, + sczb: (sczb === undefined || sczb == 0) ? 0 : 1, + sczbkf: kfdm, dmndg: false, nitem1: false, nitem41: false, @@ -297,11 +297,11 @@ export default class Judge { //项目开始 case 1: judgeUI.projectsObj[xmdm].type = '2'; - if(isManualProjectIn){ + if (isManualProjectIn) { //手动项目是否在进行中 this.judgeUI.isManualProjectIn = true } - if(xmdm == 41 && examSubject == 3){ + if (xmdm == 41 && examSubject == 3) { this.rmndg = 1 } this.judgeUI.currentXmdm = xmdm; @@ -321,14 +321,15 @@ export default class Judge { //项目结束 case 2: judgeUI.projectsObj[xmdm].type = (xmjs.xmhg === 0 ? '4' : '3'); - //计算项目是否全部结束 + + //计算项目是否全部结束 this.judgeUI.isProjectIn = (Reflect.ownKeys(judgeUI.projectsObj).filter( projectKey => judgeUI.projectsObj[projectKey].type == '2').length ) > 0; - if(isManualProjectIn){ + if (isManualProjectIn) { this.judgeUI.isManualProjectIn = false } - //统计必考项目数量 + //统计必考项目数量 this.xmmcStr = '无'; this.xmmcCode = ''; this.xmmcSingleCode = 0; @@ -352,7 +353,9 @@ export default class Judge { // 扣分无锡所代码 markcatalog: thisKf.markcatalog, markserial: thisKf.markserial, - kfxh: thisKf.kfxh + kfxh: thisKf.kfxh, + //扣分类型 + type: kf.type }) this.judgeUI.totalScore += thisKf.score * 1; break; @@ -383,7 +386,8 @@ export default class Judge { //车道和路段变化 case 9: this.judgeUI.lane = lane - console.info('surenjun',JSON.stringify(lane)) + this.lane = lane; + console.info(judgeTag + 'lane', JSON.stringify(lane)) break; default: @@ -399,68 +403,102 @@ export default class Judge { }); //语音播报 - this.goVoiceAnnounce(event, xmdm, this.kfArr, xmjs) + this.goVoiceAnnounce(event, xmdm, this.kfArr, xmjs, ksjs) //更新UI if (event == 1 || event == 2 || event == 3) { const copyProjectsObj = this.judgeUI.projectsObj; judgeUI.projectsObj = deepClone(copyProjectsObj); - //科目三统计必考数量 - this.setCountItems() } } - // 更改考试状态 - goVoiceAnnounce = async (event, xmdm, kf, xmjs) => { - const {beginProject,pointsDedute,endProject,avPlayer,uploadProgressPhoto,judgeTask,handEndExam,judgeUI} = this; - const {projectsObj,judgeConfigObj,examSubject} = judgeUI; - const kfLen = kf.length + // 更改考试状态 + goVoiceAnnounce = async (event, xmdm, kf, xmjs, ksjs) => { + const { + beginProject, + pointsDedute, + endProject, + avPlayer, + uploadProgressPhoto, + judgeTask, + handEndExam, + judgeUI, + checkExamIsEnd, + checkProjectIsStart, + lane + } = this; + + const {projectsObj,judgeConfigObj,examSubject,examMileage,jl,isAllProjectsEnd} = judgeUI; + const kfLen = kf.length; //不报语音的项目列表 const ignoreVoiceCodeArr = (judgeConfigObj['312'] || '').split(',') switch (event) { - // 项目开始 case 1: const code = projectsObj[xmdm].projectCodeCenter; - const kmCode = getKmProjectVoice(code, 1) + const isEnd = projectsObj[xmdm].isEnd; + const kmCode = getKmProjectVoice(code, 1, judgeConfigObj, lane) if (!ignoreVoiceCodeArr.includes(code)) { kmCode && avPlayer.playAudio([`voice/${kmCode}.mp3`]) } - await judgeTask.addTask(async () => { - console.info(judgeTag, `项目开始-${xmdm}-${projectsObj[xmdm].name}`) - await beginProject(xmdm) - // console.info(judgeTag,'上传照片 start') - await uploadProgressPhoto(xmdm) - }) + //项目已考不上传监管信息 + if (!isEnd) { + await judgeTask.addTask(async () => { + console.info(judgeTag, `项目开始-${xmdm}-${projectsObj[xmdm].name}`) + await beginProject(xmdm) + }, { + isDelay: true + }) + + await judgeTask.addTask(async () => { + console.info(judgeTag, '上传照片 start') + await uploadProgressPhoto(xmdm) + }, { + isDelay: true + }) + } break; // 项目结束 - case 2: + case 2:{ const endCode = projectsObj[xmdm].projectCodeCenter; - const endKmCode = getKmProjectVoice(endCode, 2) + const projectIsEnd = projectsObj[xmdm].isEnd; + const endKmCode = getKmProjectVoice(endCode, 2, judgeConfigObj, lane) if (!ignoreVoiceCodeArr.includes(endCode) && examSubject == 3) { endKmCode && avPlayer.playAudio([`voice/${endKmCode}.mp3`]) } - await judgeTask.addTask(async () => { - console.info(judgeTag, `项目结束-${xmdm}-${projectsObj[xmdm].name}`) - await endProject(xmdm); - //TODO 靠边停车结束 - if(xmdm === 11){ + const isStart = await checkProjectIsStart(xmdm,1); + if(isStart){ + //项目结束了就不再生成数据 + if (!projectIsEnd) { + await judgeTask.addTask(async () => { + console.info(judgeTag, `项目结束-${xmdm}-${projectsObj[xmdm].name}`) + await endProject(xmdm); + }, { + isDelay: true + }) } - }) + } + judgeUI.projectsObj[xmdm].isEnd = true; break; + } // 扣分 case 3: - //扣分时实时播报语音(0-否+1-是) - if(judgeConfigObj['418'] == '1' || judgeConfig.kfVoiceOpen){ + //扣分时实时播报语音(0-否+1-是) + if (judgeConfigObj['418'] == '1' || judgeConfig.kfVoiceOpen) { avPlayer.playAudio([`voice/${kf[kfLen -1].markcatalog}.mp3`]) } - await judgeTask.addTask(async () => { - console.info(judgeTag, `项目扣分-${kf[kfLen -1].markcatalog}-${kf[kfLen -1].desc}`) - await pointsDedute(kf[kfLen -1].xmdm, kf[kfLen -1]) - }) + const isStart = await checkProjectIsStart(xmdm,2,kf[kfLen -1]); + if(isStart){ + await judgeTask.addTask(async () => { + console.info(judgeTag, `项目扣分-${kf[kfLen -1].markcatalog}-${kf[kfLen -1].desc}`) + await pointsDedute(kf[kfLen -1].xmdm, kf[kfLen -1]) + }, { + isDelay: true + }) + } break; // 考车状态 @@ -469,23 +507,67 @@ export default class Judge { // 考试结束 case 5: - console.info(judgeTag,'考试结束') - clearInterval(globalThis.judgeTimer) + console.info(judgeTag, '考试结束') await judgeTask.addTask(async () => { console.info(judgeTag, '考试结束 start') - await handEndExam() + globalThis.isJudge = false; + await handEndExam(ksjs) }) + clearInterval(globalThis.judgeTimer) break default: break } + if (event == 2 || event == 3) { + //科目三统计必考数量 + await this.setCountItems(); + await checkExamIsEnd() + setTimeout(() => { + this.judgeUI.kfArrScroller.scrollTo({ + yOffset: 999999, xOffset: 0 + }) + console.info(judgeTag, '发生滚动') + }) + } } + + // 检测扣分、结束项目时该项目是否开始 + checkProjectIsStart = async(xmdm,currentType:1|2,kf?:KF) => { + if(xmdm == 20){ + return + } + const {judgeTask,beginProject,pointsDedute,uploadProgressPhoto,endProject,checkExamIsEnd} = this; + const {projectsObj} = this.judgeUI + const type = projectsObj[xmdm].type; + + //如果项目没有开始 + if(type == 1){ + console.info(judgeTag,'项目补传开始') + //项目开始补传 + judgeTask.addTask(async ()=>{await beginProject(xmdm)},{isDelay:true}) + judgeTask.addTask(async ()=>{await uploadProgressPhoto(xmdm)},{isDelay:true}) + //扣分补传 + if(currentType == 2){ + judgeTask.addTask(async ()=>{await pointsDedute(xmdm,kf)},{isDelay:true}) + } + judgeTask.addTask(async ()=>{await endProject(xmdm)},{isDelay:true}) + judgeTask.addTask(async ()=>{ + this.judgeUI.projectsObj[xmdm].isEnd = true; + checkExamIsEnd() + }) + + return false; + }else{ + return true + } + } + // 项目开始接口同步 beginProject = async (ksxm) => { const carInfo = globalThis.carInfo; const { examSubject,plateNo } = carInfo; const {judgeUI,fileLog,getSbbm,xmxh} = this; - const {lsh,idCard,serialNumber,projectsObj,ksdd,kslx} = judgeUI + const {lsh,idCard,serialNumber,projectsObj,ksdd,kslx,ksxl} = judgeUI const time = await getCurrentTime(); const project = projectsObj[ksxm] const sbxh = getSbbm(ksxm, xmxh) @@ -499,20 +581,19 @@ export default class Judge { sfzmhm: idCard, ksxm: project.projectCodeCenter, sbxh, + ksxl, kchp: encodeURI(plateNo), // 开始时间 ksdd: encodeURI(ksdd), - ksxl: encodeURI(kslx) || '', + kslx: encodeURI(kslx) || '', kssj: time } } const code = await writeObjectOut(data) - // console.info(judgeTag,'项目开始 end') + console.info(judgeTag, '项目开始 end') if (code === 2300007) { this.isJudgeDisConnect = true; } - const isJudgeDisConnect = this.isJudgeDisConnect - isJudgeDisConnect ? fileLog.setExamJudgeDisWuxiProgressData(data) : fileLog.setExamJudgeWuxiData(data) promptWxCode('17C52', code) } // 项目结束接口同步 @@ -521,10 +602,10 @@ export default class Judge { const deviceNo = globalThis.deviceNo; const { examSubject,plateNo,carNo } = carInfo; const {judgeUI,fileLog,getSbxh,xmxh,getSbbm} = this; - const {lsh,idCard,serialNumber,projectsObj,cdsbInfoObj,ksdd,kslx} = judgeUI + const {lsh,idCard,serialNumber,projectsObj,cdsbInfoObj,ksdd,kslx,ksxl,} = judgeUI const time = await getCurrentTime(); const project = projectsObj[ksxm] - const sbxh = getSbbm(ksxm, xmxh) + const sbxh = examSubject == 3 ? undefined : getSbbm(ksxm, xmxh) const data = { xtlb: '17', jkxlh: serialNumber, jkid: '17C55', @@ -534,11 +615,12 @@ export default class Judge { sfzmhm: idCard, ksxm: project.projectCodeCenter, sbxh, - //操作类型 1:正常 0:撤销该考试记录 + //TODO 操作类型 1:正常 0:撤销该考试记录 czlx: '1', + ksxl, kchp: encodeURI(plateNo), ksdd: encodeURI(ksdd), - ksxl: encodeURI(kslx) || '', + kslx: encodeURI(kslx) || '', jssj: time } } @@ -546,9 +628,7 @@ export default class Judge { if (code === 2300007) { this.isJudgeDisConnect = true; } - const isJudgeDisConnect = this.isJudgeDisConnect - isJudgeDisConnect ? fileLog.setExamJudgeDisWuxiProgressData(data) : fileLog.setExamJudgeWuxiData(data) - // console.info(judgeTag,'项目结束 end') + console.info(judgeTag, '项目结束 end') promptWxCode('17C55', code) } // 考试扣分 @@ -556,23 +636,26 @@ export default class Judge { const carInfo = globalThis.carInfo; const deviceNo = globalThis.deviceNo; const { examSubject,plateNo,carNo } = carInfo; - const {judgeUI,getProjectInfo,fileLog} = this; + const {judgeUI,getProjectInfo,fileLog,xmmcSingleCode} = this; const {lsh,idCard,serialNumber,ksdd} = judgeUI const time = await getCurrentTime(); const project = getProjectInfo(ksxm); + //科目三上车准备、模拟灯光、夜间行驶出现通用评判,ksxm为当前进行的项目 + const checkProjects = ['41600', '41700', '40100'] + const data = { xtlb: '17', jkxlh: serialNumber, jkid: '17C53', drvexam: { lsh, kskm: examSubject, - // 通用评判科二10000,科三30000 - ksxm: project ? project.projectCodeCenter : 10000, + ksxm: project + ? (checkProjects.includes(xmmcSingleCode + '') ? xmmcSingleCode : project.projectCodeCenter) + : (examSubject == 3 ? 30000 : 10000), kfxm: kf.markcatalog, kfxmmx: `${ksxm},${kf.markserial}`, sfzmhm: idCard, kchp: encodeURI(carInfo.plateNo), - //1:自动 2:人工 - kffs: 1, + kffs: kf.type == 0 ? 1 : 2, ksdd: encodeURI(ksdd), kfsj: time } @@ -581,8 +664,6 @@ export default class Judge { if (code === 2300007) { this.isJudgeDisConnect = true } - const isJudgeDisConnect = this.isJudgeDisConnect - isJudgeDisConnect ? fileLog.setExamJudgeDisWuxiProgressData(data) : fileLog.setExamJudgeWuxiData(data) console.info(judgeTag, '项目扣分 end') promptWxCode('17C53', code) } @@ -607,7 +688,7 @@ export default class Judge { kchp: encodeURI(plateNo), zpsj: time, //@ts-ignore - zp: encodeURIComponent(photoBase64), + zp: photoBase64, cs: Math.ceil(gps.sd * 1.852), ksdd: encodeURI(ksdd) } @@ -617,21 +698,24 @@ export default class Judge { this.isJudgeDisConnect = true } promptWxCode('17C54', code) - fileLog.setExamJudgeWuxiData(data) console.info(judgeTag, '上传照片 end') } + // 评判语音提示 goJudgeVoice = async (sound: SOUND) => { const {avPlayer,fileLog} = this; const {xmdm,code,type} = sound; //判断是不是模拟灯光语音 - if(type == 1){ + if (type == 1) { console.info(judgeTag, '模拟灯光开始播放:' + code) } + console.info(judgeTag, '语音播放代码:' + code) avPlayer.playAudio([`voice/${code}.mp3`], false, () => { if (type == 1) { console.info(judgeTag, '播放结束:' + code) - examJudgeSoundEnd({itemno:xmdm,code,type}) + examJudgeSoundEnd({ + itemno: xmdm, code, type + }) fileLog.setExamJudgeData({ method: 'examJudgeSoundEnd', itemno: xmdm, @@ -641,71 +725,130 @@ export default class Judge { } }) } - // 处理考试结束 - public handEndExam = async (isManual?: Boolean) => { - const {isExam,judgeUI,endExam,handleSEP,kfArr,avPlayer,judgeTask} = this; - const singlePlay = globalThis.singlePlay - const {judgeConfigObj,totalScore,} = judgeUI - this.judgeUI.loadingPopupVisible = true; - if (judgeConfigObj['344'] == 1) { - Prompt.showToast({ - message: '考试未结束,不允许手动退出!', - duration: 4000 - }); + // 校验考试是否结束 + checkExamIsEnd = async (isManual?: boolean) => { + const {judgeUI,avPlayer,isExamEnd} = this; + const {isAllProjectsEnd,examSubject,singlePlay,totalScore,judgeConfigObj,jl,examMileage} = judgeUI; + + if (isExamEnd) { return } - //结束评判函数 - await examJudgeEndExam(); - //TODO 科目三考试合格 考官综合评判 - - //TODO 语音播放扣分项 - let score = 0; - if(kfArr.length){ - avPlayer.playAudio([`voice/kfdesc.mp3`]) - kfArr.forEach(kf => { - score += Math.abs(Number(kf.score)); - if(score <= 100){ - judgeTask.addTask(()=>{ - avPlayer.playAudio([`voice/${kf.markcatalog}.mp3`]) - }) + //及格分 + let passingGrade = examSubject == 2 ? 80 : 90 + if (isManual) { + if (isAllProjectsEnd) { + // 考试合格 + if (totalScore >= passingGrade) { + // 考试合格 + await examJudgeEndExam(); + this.isExamEnd = true } + } else { + // 考试不合格 + await examJudgeEndExam() + this.isExamEnd = true + } + this.isManual = true + + } else { + //单机模式 + if (singlePlay) { + console.info(judgeTag + ' isAllProjectsEnd',isAllProjectsEnd) + if (isAllProjectsEnd) { + await examJudgeEndExam() + this.isExamEnd = true + } + } else { + //成绩不合格 + if (totalScore < passingGrade) { + await examJudgeEndExam() + this.isExamEnd = true + return + } + //成绩合格 + if (isAllProjectsEnd && totalScore >= passingGrade) { + const param302 = judgeConfigObj['302']; + if (examSubject == 3 && (param302 != 6 || param302 != 7 || param302 != 8)) { + avPlayer.playAudio(['voice/综合评判.mp3']) + this.judgeUI.isDeductedPopShow = true + this.judgeUI.defaultTabIndex = 1 + } else { + await examJudgeEndExam() + this.isExamEnd = true + } + } + } + } + } + + // 处理考试结束 + public handEndExam = async (ksjs: KSJS) => { + this.judgeUI.loadingPopupVisible = true; + this.judgeUI.endPopupVisible = false; + const {qjjl,dcjl} = ksjs + const {judgeUI,endExam,handleSEP,kfArr,avPlayer,judgeTask,isManual} = this; + const {judgeConfigObj,examSubject,isAllProjectsEnd,totalScore,projectsObj} = judgeUI; + //计算考试分数 + this.judgeUI.totalScore = isAllProjectsEnd ? totalScore : 0; + const singlePlay = globalThis.singlePlay + const param302 = judgeConfigObj['302']; + globalThis.windowClass.setWindowSystemBarEnable(['navigation']) + + //自动退出待验证并且不合格 + if (!isManual && examSubject == 3 && (param302 == 1 || (singlePlay && param302 == 2)) && totalScore < 90) { + avPlayer.playAudio([`voice/考试结束.mp3`]) + } + + //联网模式下手动结束的直接退出 + if (!singlePlay && isManual && !isAllProjectsEnd) { + avPlayer.playAudio(['voice/empty.mp3'], true, () => { + router.back(); }) + return + } + + if (examSubject == 3) { + const param302 = judgeConfigObj['302']; + //TODO 分数待修改从sysset表里获取 + if (totalScore < 90) { + //考试不合格;考试模式,自动退出; + if (param302 == 4 || param302 == 5 || param302 == 7 || param302 == 8) { + } + } else { + //考试合格 + } } await handleSEP(306); - judgeTask.addTask(()=>{ - avPlayer.playAudio(['voice/exam_waiting.mp3'],false,async ()=>{ - this.isEnd = true - try { - if(!singlePlay){ - const bytes = await this.getMessageHeartbeat(true); - globalThis.judgeUdp.send(bytes) - } - globalThis.isJudge = false - //TODO endExam函数逻辑待验证 - !singlePlay && await endExam(isManual) - router.back(); - } catch (e) { - // setTimeout(() => { - // // avPlayer.avPlayerStop(); - // router.back(); - // }, 3000) + avPlayer.playAudio(['voice/exam_waiting.mp3'], true, async () => { + try { + if (!singlePlay) { + // TODO 待验证 + // const bytes = await this.getMessageHeartbeat(true); + // globalThis.judgeUdp.send(bytes) } - }) - }) + //TODO endExam函数逻辑待验证 + await endExam() + } catch (e) { + // setTimeout(() => { + // // avPlayer.avPlayerStop(); + // router.back(); + // }, 3000) + } + }); + } // 考试结束 public endExam = async (isManual?: Boolean) => { const carInfo = globalThis.carInfo; - const deviceNo = globalThis.deviceNo; + const singlePlay = globalThis.singlePlay const { examSubject ,plateNo} = carInfo; - const {judgeUI,fileLog,ksjs,getPhoto,uploadProgressData,uploadDisConnectData,avPlayer} = this; - const {lsh,idCard,serialNumber,kssycs,totalScore} = judgeUI + const {judgeUI,ksjs,getPhoto,uploadProgressData,uploadDisConnectData,avPlayer,kfArr,judgeTask} = this; + const {lsh,idCard,serialNumber,kssycs,totalScore,judgeConfigObj,isAllProjectsEnd} = judgeUI await uploadDisConnectData(); const time = await getCurrentTime(); const photoBase64 = await getPhoto(); - const data = { xtlb: '17', jkxlh: serialNumber, jkid: '17C56', drvexam: { @@ -714,42 +857,80 @@ export default class Judge { kskm: examSubject, sfzmhm: idCard, //@ts-ignore - zp: encodeURIComponent(photoBase64), + zp: photoBase64, jssj: time, kscj: (totalScore * 1) > 0 ? totalScore : 0, - kslc: (ksjs?.qjjl + ksjs?.dcjl) || 0, + kslc: Math.ceil(((ksjs?.qjjl + ksjs?.dcjl) || 0) / 100), + //TODO dwlc: '', } } const code = await writeObjectOut(data); promptWxCode('17C56', code) console.info(judgeTag, '考试结束 end') - if (!isManual) { - judgeUI.loadingPopupVisible = true; - if (examSubject == 2 && totalScore < 80) { - avPlayer.playAudio([ - `voice/unqualified_${kssycs == 1?'one':'two'}.wav`, - ], true) - } else { - avPlayer.playAudio(['voice/qualified.mp3'], true) - } + let noPassExitVoice = '' + const param302 = judgeConfigObj['302']; - if (examSubject == 3 && totalScore < 90) { - avPlayer.playAudio([ - `voice/${kssycs == 1?'exam_no_pass':'exam_no_pass_finish'}.mp3`, - ], true) + judgeUI.loadingPopupVisible = true; + + let voiceURL = '' + if (examSubject == 2) { + voiceURL = (totalScore < 80 ? `voice/unqualified_${kssycs == 1 ? 'one' : 'two'}.wav` : 'voice/qualified.mp3') + } + + if (examSubject == 3) { + if (isAllProjectsEnd) { + if (totalScore < 90) { + voiceURL = `voice/${kssycs == 1 ? 'exam_no_pass_finish' : 'exam_no_pass'}.mp3` + } else { + voiceURL = 'voice/exam_pass.mp3' + } } else { - avPlayer.playAudio(['voice/exam_pass.mp3'], true) + voiceURL = `voice/${kssycs == 1 ? 'exam_no_pass_finish' : 'exam_no_pass'}.mp3` } } - console.info(judgeTag, `考试成绩:${totalScore}`) - // fileLog.setExamJudgeWuxiData(data) - await uploadProgressData(); - setTimeout(() => { - router.back(); - }, 3000) + console.info(judgeTag, `考试成绩:${totalScore}`) + await uploadProgressData(); + + //语音播放扣分项 + let score = 0; + if (kfArr.length) { + avPlayer.playAudio([`voice/kfdesc.mp3`], false, () => { + try { + kfArr.forEach((kf, index) => { + score += Math.abs(Number(kf.score)); + console.info(judgeTag + 'score=>', score) + //TODO 考试分数待替换 + if (score <= (examSubject == 3 ? 10 : 20)) { + if (kfArr.length - 1 === index) { + avPlayer.playAudio([`voice/${kf.markcatalog}.mp3`, voiceURL], false, () => { + router.back(); + }) + throw new Error('End Loop') + } + avPlayer.playAudio([`voice/${kf.markcatalog}.mp3`]) + } else { + avPlayer.playAudio([`voice/${kf.markcatalog}.mp3`, voiceURL], false, () => { + router.back(); + }) + throw new Error('End Loop') + } + }) + } catch (e) { + + } + }) + + } else { + avPlayer.playAudio([voiceURL], true, () => { + setTimeout(() => { + router.back(); + }, param302 == 8 ? 3000 : 0) + }) + } } + // 当前项目转换 getDqxmStr = (type) => { const projectsObj = this.judgeUI.projectsObj @@ -936,25 +1117,26 @@ export default class Judge { } } //人工操作项目 - public setJudgeItem = async (itemno,type:1|2) => { + public setJudgeItem = async (itemno, type: 1 | 2) => { const {fileLog} = this; - await examJudgeArtificialItem(itemno * 1,type); + await examJudgeArtificialItem(itemno * 1, type); await fileLog.setExamJudgeData({ method: 'examJudgeArtificialItem', itemno: itemno * 1, type }) - console.info(judgeTag, `人工评判${type == 1?'进入':'取消'}项目-${itemno}`) + console.info(judgeTag, `人工评判${type == 1 ? '进入' : '取消'}项目-${itemno}`) } //人工扣分 - public setJudgeMark = async (itemno, serial) => { + public setJudgeMark = async (itemno, serial, type = 1) => { const {fileLog} = this - await examJudgeArtificialMark(itemno * 1, serial); + await examJudgeArtificialMark(itemno * 1, serial, type); await fileLog.setExamJudgeData({ method: 'examJudgeArtificialMark', itemno: itemno * 1, - serial + serial, + type }) console.info(judgeTag, `人工扣分-${itemno}-${serial}`) @@ -1026,8 +1208,8 @@ export default class Judge { console.info('plc信号', msg) const {fileLog,getPlcData,usbService} = this const stachArr = msg.split(',') - const {isEnd} = this; - if (stachArr[0] != '#DN_GD' || isEnd) { + const {isExamEnd} = this; + if (stachArr[0] != '#DN_GD' || isExamEnd) { return } const plcData = await getPlcData(msg); @@ -1039,6 +1221,8 @@ export default class Judge { usbService.sendUSB(str) } this.judgeUI.isDwztRight = plcData.gps.dwzt == 4; + this.judgeUI.sd = (Math.floor(plcData.gps.sd as number) || 0) + ''; + this.judgeUI.dw = (Math.floor(plcData.sensor.dw as number) || 0) + '' await examJudgeRealExam(plcData) const udpIndex = globalThis.udpIndex; if (udpIndex % 5 === 0) { @@ -1103,48 +1287,59 @@ export default class Judge { } // 4.过程数据 this.tempData = msg + this.judgeUI.isDwztRight = msg?.gps?.dwzt == 4; + this.judgeUI.sd = Math.floor(msg?.gps?.sd) + ''; + this.judgeUI.dw = Math.floor(msg?.sensor?.dw) + '' this.plcData = msg + // this.judgeUI.isDwztRight = msg.gps.dwzt == 4; globalThis.msgStr = '' - if(msg.method === 'examJudgeArtificialItem'){ - setJudgeItem(msg.itemno,msg.type) + if (msg.method === 'examJudgeArtificialItem') { + setJudgeItem(msg.itemno, msg.type) } - if(msg.method === 'examJudgeArtificialMark'){ - setJudgeItem(msg.itemno,msg.serial) + if (msg.method === 'examJudgeArtificialMark') { + setJudgeItem(msg.itemno, msg.serial) } await examJudgeRealExam(msg) num++ - }, 200) + }, 50) globalThis.judgeTimer = judgeTimer; } - // 统计必考项目数量 + // 统计必考项目、所有项目、已考数量 setCountItems = async () => { const carInfo = globalThis.carInfo; const { examSubject} = carInfo; const {projectsObj} = this.judgeUI; - if(examSubject == 3){ - //必考项目数量 必考项目已考数量 - let projectNum = 0,endProjectsNum =0; - Reflect.ownKeys(projectsObj).forEach(projectKey=>{ - const {type,isRequired} = projectsObj[projectKey]; - if(isRequired){ - projectNum += 1; - if(type == 3 || type == 4){ - endProjectsNum += 1; - } - } - }) - //必考项目除靠边停车是否全部完成 - this.judgeUI.isRequiredProjectsEnd = (projectNum - endProjectsNum === 0) - } - } + //必考项目数量 必考项目已考数量 + let projectNum = 0, endProjectsNum = 0; + // 所有考试项目数量 项目已考项目数量 + let allProjectNum = 0, allEndProjectsNum = 0; + Reflect.ownKeys(projectsObj).forEach(projectKey => { + const {type,isRequired} = projectsObj[projectKey]; + allProjectNum += 1; + if (type == 3 || type == 4) { + allEndProjectsNum += 1; + } + + if (isRequired) { + projectNum += 1; + if (type == 3 || type == 4) { + endProjectsNum += 1; + } + } + + }) + //必考项目除靠边停车是否全部完成 + this.judgeUI.isRequiredProjectsEnd = (projectNum - endProjectsNum === 0) + this.judgeUI.isAllProjectsEnd = (allProjectNum - allEndProjectsNum === 0) + } // 模拟灯光 setMndg = async (mndgStr: string) => { this.mndgStr = mndgStr } // 路段信息处理 - setRoadAndLane = async (lane)=>{ + setRoadAndLane = async (lane) => { const {road,num,count} = lane; } @@ -1170,7 +1365,9 @@ export default class Judge { //是否是考试模式 private isExam: boolean //考试是否结束了 - private isEnd: boolean + private isExamEnd: boolean + //是否手动结束考试 + private isManual: boolean //UDP服务序列号 private serialIndex: number private fileUtil: FileUtil @@ -1195,6 +1392,7 @@ export default class Judge { markcatalog: string markserial: string kfxh: string + type: 0| 1 | 2 }[] private km2ItemsStatus: any[] //所有的科目考试项目(大车&小车) @@ -1209,6 +1407,8 @@ export default class Judge { private isTrajectoryOpen: boolean; // 调代理接口是否断网了 private isJudgeDisConnect: boolean; - private artSubject3ProjectsCodesArr:number[] = [3, 9, 4, 10, 12, 11] - + private artSubject3ProjectsCodesArr: number[] = [3, 9, 4, 10, 12, 11] + private lane: LANE = { + road: '', num: 0, count: 0 + } } \ No newline at end of file diff --git a/entry/src/main/ets/pages/judgeSDK/utils/fileModel.ts b/entry/src/main/ets/pages/judgeSDK/utils/fileModel.ts index a935a7fd..f5abffbc 100644 --- a/entry/src/main/ets/pages/judgeSDK/utils/fileModel.ts +++ b/entry/src/main/ets/pages/judgeSDK/utils/fileModel.ts @@ -1,5 +1,8 @@ import FileUtil from '../../../common/utils/File' import zlib from '@ohos.zlib'; +import promptAction from '@ohos.promptAction'; +import router from '@ohos.router'; + export default class FileModel{ //后续文件路径待替换 @@ -47,8 +50,16 @@ export default class FileModel{ //获取文件内容 public getModelContent = (folderPath,fileName) => { const {fileUtil} = this; - const content = fileUtil.getFileContent(`${folderPath}/${fileName}`) - return content; + try { + const content = fileUtil.getFileContent(`${folderPath}/${fileName}`) + return content; + }catch (e){ + promptAction.showToast({ + message:"请检查模型路径是否正确!", + duration:4000 + }) + router.back() + } } } \ No newline at end of file diff --git a/entry/src/main/ets/pages/judgeSDK/utils/filePhoto.ts b/entry/src/main/ets/pages/judgeSDK/utils/filePhoto.ts index 58aac620..660ac918 100644 --- a/entry/src/main/ets/pages/judgeSDK/utils/filePhoto.ts +++ b/entry/src/main/ets/pages/judgeSDK/utils/filePhoto.ts @@ -1,8 +1,7 @@ -import mediaLibrary from '@ohos.multimedia.mediaLibrary' -import onvifclient from '@ohos.onvifclient'; -import fs from '@ohos.file.fs' -import util from '@ohos.util'; import FileUtil from '../../../common/utils/File' +import { takePhoto } from '../../../common/service/videoService'; +import promptAction from '@ohos.promptAction'; +import {judgeConfig} from './judgeConfig' interface Params{ userName:string @@ -10,6 +9,7 @@ interface Params{ ip:string port:string rlls:string + pztd:string } export default class FilePhoto{ @@ -21,51 +21,33 @@ export default class FilePhoto{ constructor(context) { (async ()=>{ + //TODO 309参数 获取拍照摄像头拍照通道 const fileUtil = new FileUtil(context) - const strConfig = await fileUtil.readFile('/mnt/hmdfs/100/account/device_view/local/files/logs/config/config3.txt'); + const strConfig = await fileUtil.readFile('/mnt/hmdfs/100/account/device_view/local/files/config/config3.txt'); const config = JSON.parse(strConfig) - const {userName,ip,pwd,port,rlls} = config - this.params = {userName,pwd,ip,port,rlls} + const {userName,ip,pwd,port,rlls,pztd} = config + this.params = {userName,pwd,ip,port,rlls,pztd} this.context = context this.fileUtil = fileUtil })() } - public async getPhoto(){ - const {params,context,fileUtil} = this; - const {userName,pwd,ip,port,rlls} = params; - const mediaTest = mediaLibrary.getMediaLibrary(context); - let mediaType = mediaLibrary.MediaType.IMAGE; - let DIR_DOCUMENTS = mediaLibrary.DirectoryType.DIR_IMAGE; - const path = await mediaTest.getPublicDirectory(DIR_DOCUMENTS); - - return new Promise(async (resolve)=>{ - mediaTest.createAsset(mediaType, 'judge_face.jpg', path,(error,asset)=>{ - asset.open('rw', (error, fd) => { - if (fd > 0) { - const file_path = "/mnt/hmdfs/100/account/device_view/local/files/Pictures/judge_face.jpg" - const result3 = onvifclient.getVideoSnapshot(`rtsp://${userName}:${pwd}@${ip}:${port}/h264/ch${rlls}/main/av_stream`,file_path,fd); - fs.closeSync(fd); - asset.close(fd); - fs.lstat(file_path).then((stat) => { - console.info("get link status succeed, the size of file is" + stat.size); - let file = fs.openSync(file_path, fs.OpenMode.READ_WRITE); - const size=Number(stat.size)+100 - let buf = new ArrayBuffer(size); - let num = fs.readSync(file.fd, buf); - const that = new util.Base64(); - const array = new Uint8Array(buf); - const result = that.encodeToStringSync(array);//base64圖片 - fileUtil.deleteF(file_path,3) - resolve(result) - }).catch((err) => { - console.info("get link status failed with error message: " + err.message + ", error code: " + err.code); - }); - } else { - console.error('baoyihu getVideoSnapshot File Open failed with error: ' + error); - } + public getPhoto = async () => { + const {params} = this; + if(!judgeConfig.isPhotoOpen){ + return '' + }else{ + try { + const res = await takePhoto(params, this.context, 'pz/',2); + return res.base64 + } catch (e) { + promptAction.showToast({ + message: JSON.stringify(e), + duration: 2000 }); - }); - }) + return '' + } + } } + } \ No newline at end of file diff --git a/entry/src/main/ets/pages/judgeSDK/utils/judgeCommon.ts b/entry/src/main/ets/pages/judgeSDK/utils/judgeCommon.ts index 144a65ac..cbe28464 100644 --- a/entry/src/main/ets/pages/judgeSDK/utils/judgeCommon.ts +++ b/entry/src/main/ets/pages/judgeSDK/utils/judgeCommon.ts @@ -66,36 +66,44 @@ export function getCenterProjectStatus(status){ export function getKmProjectVoice( projectCode, // 1:项目开始 2:项目结束 - type: 1 | 2 + type: 1 | 2, + judgeConfig, + lane ) { const carInfo = globalThis.carInfo; const { examSubject } = carInfo; + const param506Str = judgeConfig['506']?.split(',') || []; + const param512Str = judgeConfig['512']?.split(',') || []; + const param544Str = judgeConfig['544'] || 0; + const param405Str = judgeConfig['405'] || 0; + const {num,count} = lane if(examSubject == 2){ return projectCode } - switch (projectCode*1){ //直线行驶 case 40300: return type === 1 ? 403001 : 403002 //变更车道 case 40500: return type === 1 ? 405001 : 405002 - //超车 - case 41400 : return type === 1 ? 414001 : undefined - //直线行驶 - case 40700 : return type === 1 ? 407001 : undefined //左转 case 40800 : return type === 1 ? 408001 : undefined //右转 case 40900 : return type === 1 ? 409001 : undefined - //通过人行横道 - case 41000 : return type === 1? 410001:undefined - //通过学校 - case 41100 : return type === 1 ? 411001:undefined + //会车 506-6为1都报 + case 41300 : return type === 1 ? 413001: (param506Str[5]===1?413002:undefined) + //超车 + case 41400 : return type === 1 + ? (param405Str == 1 && (num == count)?undefined:414001) + : undefined + //直线行驶 + case 40700 : return type === 1 ? 407001 : undefined + //TODO 通过学校 结束param544Str + case 41100 : return type === 1 ? (param512Str[2] ==3 ? 411001 : undefined):undefined //通过车站 - case 41200 : return type === 1 ? 412001 : undefined - //会车 - case 41300 : return type === 1 ? 413001: 413002 + case 41200 : return type === 1 ? (param512Str[2] ==3 ? 412001 : undefined):undefined + //通过人行横道 + case 41000 : return type === 1? (param512Str[2] == 3 ? 410001 : undefined):undefined //靠边停车 case 40600 : return type === 1 ? 406001 : undefined //掉头 @@ -114,6 +122,7 @@ export function promptWxCode( code:number ){ let toast = ''; + const singlePlay = globalThis.singlePlay if(singlePlay){ return @@ -204,10 +213,12 @@ export function promptWxCode( break; default :break; } - promptAction.showToast({ - message: decodeURIComponent(toast), - duration: 4000 - }); + //TODO 兼容新监管code + // console.info('surenjun showToast') + // promptAction.showToast({ + // message: decodeURIComponent(toast), + // duration: 4000 + // }); } // 获取plc数据 diff --git a/entry/src/main/ets/pages/judgeSDK/utils/judgeConfig.ts b/entry/src/main/ets/pages/judgeSDK/utils/judgeConfig.ts index 58e31e14..bf2790ef 100644 --- a/entry/src/main/ets/pages/judgeSDK/utils/judgeConfig.ts +++ b/entry/src/main/ets/pages/judgeSDK/utils/judgeConfig.ts @@ -3,14 +3,20 @@ export const judgeConfig = { //本地目录开关 isTrajectoryOpen: false, + //是否开启拍照 + isPhotoOpen: false, + //扣分语音是否强制开启 + kfVoiceOpen: true, + // 是否忽略考试前熄火、车门检查 + isCheckFireOpen: true, //是否开启Udp udpOpen:false, // 本地模型地址 modelPath: 'models/model_enc', - // 轨迹回放地址 - trajectoryPath: 'logs/2024_07_11/0000000000001_342323199501470011_测试学员1_2024_07_11_13_33_10/judge_exam_data.txt', - //扣分语音是否强制开启 - kfVoiceOpen:true, + // 济南科目三 + trajectoryPath: 'logs/2024_07_31/0000000000001_342323199501470011_测试学员1_2024_07_31_10_21_38/judge_exam_data.txt', + // 杭州科目二 + // trajectoryPath: 'logs/2024_07_19/0000000000001_342323199501470011_测试学员1_2024_07_19_06_49_12/judge_exam_data.txt', //TODO 济南临时特殊配置 systemParamConfig:{} } \ No newline at end of file diff --git a/entry/src/main/ets/pages/judgeSDK/utils/judgeTask.ts b/entry/src/main/ets/pages/judgeSDK/utils/judgeTask.ts index 7925f759..a2b0ef5f 100644 --- a/entry/src/main/ets/pages/judgeSDK/utils/judgeTask.ts +++ b/entry/src/main/ets/pages/judgeSDK/utils/judgeTask.ts @@ -2,41 +2,66 @@ import Prompt from '@system.prompt' const TAG = 'SURENJUN_JUDGE' -export default class JudgeTask{ +interface QUEUE { + fn: Function, + config?: { + isDelay: boolean + delayTime: number + } +} + +export default class JudgeTask { private queue = [] - private status:string + private status: string + constructor() { this.queue = [] this.status = 'end' } - executeQueue = async ()=>{ - const {queue,executeQueue} = this - if(queue.length){ - for (const currentTask of queue) { - const {status} = this + // + goTask = async (currentTask) => { + const {fn,delayConfig={}} = currentTask; + const { isDelay = false,delayTime = 1000} = delayConfig + return new Promise(async (res, rej) => { + setTimeout(async () => { try { - await currentTask(); - }catch (e){ - // console.info(TAG,'过程数据接口解析错误') + await fn() + res(true) + } catch (e) { + console.info(TAG, JSON.stringify(e)) Prompt.showToast({ message: '过程数据接口解析错误', duration: 3000 }); + rej(false) } + }, isDelay ? delayTime : 0); + }) + } + + executeQueue = async () => { + const {queue,executeQueue} = this + if (queue.length) { + for (const currentTask of queue) { + await this.goTask(currentTask) this.queue.shift() await executeQueue() } - }else{ + } else { this.status = 'end' } } - addTask = async (fn) =>{ - this.queue.push(fn); - if(this.status == 'end' && this.queue.length === 1){ + addTask = async (fn, delayConfig?: { + isDelay: Boolean, + delayTime?: Number + }) => { + this.queue.push({ + fn, delayConfig + }); + if (this.status == 'end' && this.queue.length === 1) { await this.executeQueue(); } } - } diff --git a/entry/src/main/ets/pages/judgeSDK/utils/judgeTask_BAK.ts b/entry/src/main/ets/pages/judgeSDK/utils/judgeTask_BAK.ts new file mode 100644 index 00000000..ffc86328 --- /dev/null +++ b/entry/src/main/ets/pages/judgeSDK/utils/judgeTask_BAK.ts @@ -0,0 +1,58 @@ +import Prompt from '@system.prompt' + +const TAG = 'SURENJUN_JUDGE' +interface QUEUE{ + fn:Function, + config?:{ + isDelay:boolean + delayTime:number + } +} + +export default class JudgeTask{ + private queue = [] + private status:string + constructor() { + this.queue = [] + this.status = 'end' + } + + executeQueue = async ()=>{ + const {queue,executeQueue} = this + if(queue.length){ + for (const currentTask of queue) { + const {fn,delayConfig:{ + isDelay = false, + delayTime = 1000 + }} = currentTask; + const {status} = this + try { + isDelay + ?setTimeout(async ()=>{await fn()}) + :await fn(); + }catch (e){ + // console.info(TAG,'过程数据接口解析错误') + Prompt.showToast({ + message: '过程数据接口解析错误', + duration: 3000 + }); + } + this.queue.shift() + await executeQueue() + } + }else{ + this.status = 'end' + } + } + + addTask = async (fn,delayConfig?:{ + isDelay:Boolean, + delayTime:Number + }) =>{ + this.queue.push({fn,delayConfig}); + if(this.status == 'end' && this.queue.length === 1){ + await this.executeQueue(); + } + } + +} diff --git a/entry/src/main/ets/pages/judgeSDK/utils/voiceAnnouncements.ts b/entry/src/main/ets/pages/judgeSDK/utils/voiceAnnouncements.ts index e1f4c1b2..a8c0ee70 100644 --- a/entry/src/main/ets/pages/judgeSDK/utils/voiceAnnouncements.ts +++ b/entry/src/main/ets/pages/judgeSDK/utils/voiceAnnouncements.ts @@ -1,6 +1,8 @@ import media from '@ohos.multimedia.media'; import Prompt from '@system.prompt'; import url from '@ohos.url'; +import fileuri from "@ohos.file.fileuri"; +import mediaLibrary from '@ohos.multimedia.mediaLibrary'; const TAG = 'VoiceAnnounce' @@ -84,10 +86,49 @@ class AVPlayer { // 以下为使用资源管理接口获取打包在HAP内的媒体资源文件并通过fdSrc属性进行播放示例 async play(name,callback) { + let isInSD = true + try { + //检查SD中的语音 + console.info('surenjun name',name) + console.info('surenjun name',name.split('/')[1]) + let playSrc = await this.queryFile(name.split('/')[1]); + let fdPath = await playSrc.open('r') + let audioPlayer = media.createAudioPlayer() + console.info('surenjun fdPath=>',fdPath) + audioPlayer.on('dataLoad', () => { + this.voiceStatus = 'playing' + audioPlayer.play() + }) + return new Promise(async (resolve)=>{ + audioPlayer.on('finish', () => { + //@ts-ignore + this.voiceStatus = 'completed' + if(callback){ + callback() + } + audioPlayer.stop(); + audioPlayer.reset() + audioPlayer.release() + resolve(true) + }) + audioPlayer.reset() + audioPlayer.src = `fd://${fdPath}` + }) + + + return + }catch (e){ + console.info('surenjun fdPath=>',JSON.stringify(e)) + isInSD = false; + } + if(!isInSD){ + return + } + //检查SD中的语音 this.endCallback = callback const avPlayer = await media.createAVPlayer(); this.avPlayer = avPlayer; - console.info('surenjun',callback) + return new Promise(async (resolve,reject) => { let url = '' await this.setAVPlayerCallback(()=>{ @@ -106,6 +147,26 @@ class AVPlayer { } }) } + + async queryFile(displayName): Promise { + const mediaLib = mediaLibrary.getMediaLibrary(globalThis.context); + let ret + let fetchOp = { + selections: `media_type=? AND display_name = ?`, + selectionArgs: [`${mediaLibrary.MediaType.AUDIO}`,displayName], + }; + let fileResult = await mediaLib.getFileAssets(fetchOp); + let retCount = fileResult.getCount(); + console.info('surenjun retCount=>',retCount) + if (retCount > 0) { + ret = fileResult.getFirstObject(); + return Promise.resolve(ret); + }else{ + return Promise.reject(0); + } + + } + //音频播放队列 public releasePlayer() { this.avPlayer.release(); diff --git a/entry/src/main/resources/rawfile/judge/km3/会车_green.png b/entry/src/main/resources/rawfile/judge/km3/会车_green.png new file mode 100644 index 0000000000000000000000000000000000000000..e1b58a829d4659355d4e824414b4408738d04d5e GIT binary patch literal 8609 zcmY*S=MjGjmPU-IMP5}W)B_%HJ zd)K=6`~EoR{B!nMXYcjwSkKTm^IEGjGj0C1HQf%ddVWU>f99Ux~- zg_l727|lKaFaSz>QFOM;Vx(Xl8%xJvMl1s8rkiT#d8$Q0R-ZTOGH4#j26p$I{Z0QbWVyCIj2SbxDPO-7BNV2H)G``(sTU5=D?EqKgDUtSdnJ8Y>1I zCW<5_C520gSfC_VQ6fZx;+@dsxBOCVpo7%7N5X?*1uAs0FxHn!9L zYF~a(eejTZ5H zIdWUKEQbb`)$gCljCqfVcWs2@n~ciCzY_{(=bOahOOd^U`Us>;MF%|qah~toZ^5Rr za$~1hP~O$djQ0L=vE`Sr#n4d481T8YbDskN={C+U#Sb|zdcz->Sv$T?5h&dddFI-& zukf(2Wew|sOqpjCv^=0Y8|GL}(Lr?5nqv1~*Y?r1m;}bw6KJP+8!8r0Eo*b+dpp`n zO0?;zuSwC{xHyQM_-gZ-COm?vV<>1i>@-M;?6KJ;*%2C`&a`XHF!VROiZ;|8-*xF} zKv8lMCrPX8i|O&xwpAF1@UPVe-EMrRp&+gVmTZqCLy(#oPF&}Zei=nR6J$#XL%i_9Gd{e?osXlcrLC~0}h-^i{$yR{gx zIZ#ke-eulVBemRHmz=YW#O#PjO|=m?@xp_}e%&+rnua{4bbv@$_=?C8%sCw+gKqAL zEO8Z4m)>}VZS@C(!6Rf1k$tF?NB+whM;y-UCMudW@NZFYocbL&<~kUO($dLY*t zQ_nqM@Erhn_ zPzkCKz``0Y7>s--8TSki?W9|_8u@p zG?63|qy#)M&l@6}j^WJc^Oz(jC5`gvR~-_@mi} z6Q_U1MQTq$38wWVNWB886={&g!l+Spu z6{=+Vq!nK=vNE91ThgiiDx9PltL9Hclu|dKEs^D`Q1iwW`oo(l{XkSI76vsHHu@;T zC9ci@Q3N?-h0XpDa|0w*?T6qF$2cRxo^svR92KJ8^iV(TKi*9^hJ(7U;+5Y+$(BY3 z;Z=(MG2k+u=-YC*Vyn~#=zVjrKDF;RA8NGhU2oB>V}I$vd`A&t>e7nlpE<1=@qdeN zKNvCTvOeFqOev19g~T^6nRQ><%;B#+BirlF;1@%Z7IH{@)KjhyxO>abJ#tf>v;57j zvViY~#J#c&)c#`v2i@G=Y~Sp6I=|1kkXhXP8|S`HCEe;a23BUBQ(z0tB9z9$f{*b% zRTZq0{vq;86Cqh<;-hma4vqVYlX+e^zMAVu6O%@Y?;A~)|wt&nMDLKV-OeNC( zr9BX3cree(x{1%J%b<}%7@grGp>5nn=)ATgs}}!J@xjj2)%X=Naw{!?m{XQ+f<+Q< zCz~7ck3=2#t$XsD|4rUhB#Q>9sKct(Tg;u%1)olHIy84aKW}5vV%WZ_?Xp<#;vtSr%Ya7{n#C4>O`mTS7 zFNv=DUHLs{i=*@IMrZI=z7C05e#ci(OL;E@|LDH9PCCL?8gC3#M~+*>kYLG0{Q}wE zG=Y39>tIDj(Ae7YLc_kd?IvnS&lg7EJftn33qgkd!ZX$>u_w5*b&Do%gUiJb>6@{UERE*7 zcGDNxVY{RhFOc&lpVG!N%u+QOFc5{usFOsAmRusZ8x?6(r^KKvA{^$!zR?X3Y4=-; zqT(`0#Cl!cQs~f*%upy^825Y5O6OOf==8PB-de_DbU=TdG9U@B>OS(Lzct0`SU0xo zc`Olsk5CI%%o^W!Jm!bdwV_c+z0(2de8eG2A7E~&G!r_HFYNU<(<;P5MbP}U&^Y2p zL6)#@y@fda{I-6=BfO=sHy*^5iWU_Yg_YS^1W9|p0M0Fg9AH0`ymB)@*o* z>igwHn?^GoHF$!DC3m2(=u(#EfT)65ge!*A8Dkj%~nab?B z0v@5T0Ld&C7-}^@B{jVgMxQQDcxHs^KE$SdKf-q~qmUSwx1b3*(uCp`X37xz+wim!-VS1gm6{(TTl<-Kk8@?o# zql-py;G7usk0eJM2}Ekb#N#*tS9He#ftTt{%+9F5;aQ+_-M8ylUDeXB^^*n_MfE#e zIlELXV%})ewlpOrX9x54Rk{1gK6L+487yC?5CEs31>5uf(qTezHwKEhi$X7BY_~N- zdp0(3P-2G(sovdUh9T&9lmfmC9~gX_Z7({{YQv@vJr(?cA{lMVn4$wC{q2bR`r}G{B z(iz@h-7j^zN)H}*JoTBmNf@pVkXfdtvLp>88}pj2I}O}cVU6DUWTN)YrOUN(cF*B6 z%Fc5?(*NMTJ7=kz5y0&$7Bt6=&e#Pg8525G*z`;MM zSw%ua*+9UTY~KMt^&W*y)Psax&f&|8nKEA^QyMmrn^G9iCqqv*t4o#6_su6gpK_52 zWg**B#wGN5f2*^=Y3^Sg&(iZRM+!!MS(}xP1H&b}Iz^v6=j}8Bl5d818=3Js?hU2A zh?|!-ht3WC{{u>8dXR}qFZmVB7tfG|r!ja4f=J#`EcfR+ZEdXZ_PK_UKpWGf%8PDCzhBmHB(~) zw`L%+bEj3kGdYij_pH~d z(>Aj8UDzCJZxk2}AQ&Ciq_vFqdT^S)HTXrnZTH)B$fobn13V@KIxc5E;oUZ#H> zaU$Cxh7oy%wvs458}ORC51iQ}dy&N;ElSG!eL%1LD?P_g`ce!77&k=*FCk_C@Eosn zAj|OZ!}_A_^*hRoAA!cdsnC_-ZT|(R6$>i_sd|v(X)WurAGcx(y7Son(6TreBwgNu zHci`Yl2-~qvsYT|22AdSx`+>2OAvB^e94tq+K2JM_U&r}s(_`lUj#_kA_@yS7FIk6 zXyyw5QOiRIy`~qqA~zf}{TJ!+b%*BWt+B7_53FqEw9O8=r^J3FrOuDaO+yOPNGZv5 z{mDEURy~{WmhA~OozCj#`-};7?@#O}>J#`Act+*VM!tar4Ug_pt2f{jgnwNmy5|H| znT9q;mmIKQH5OVelcWrQ!aUn9zq0LPNcH9O3nJztv=`Z*7ClME-%{w@+~{}(kU2H} z$TIz~n${W!L@FOuu|5a-%TtcnNdQCY?h0a(Jy7z_H+S6xfX-)_4^_w^G+ZKTc+<#B z5@hXl5}nQnf{q2?>%1Lg^^@24GPlMn8XHwk#s+emQ#@B=MJ5E7bOq})*WQ8{j2Z^x`X}b>T{Offw4^l?OV1aBeKntjQDa1560s!--rB>?`!el*fJYGQgoR{D1vlIr>OJ|GiJo z>|fY^$$NDPR%PI^9-G$J6cp89szA3!s=9T$>z4`Cwz}EiLC4~vTN~q2eb}1w+SGe1 z)oKL)P?3!5tSwrLzH57A{e+5!hlYL?)W`>oleh1!u3;O4aFX4HqhZ(2+($-6a5 zsGGs}mEJfQ&vrLX0FM1AX+c??oiBQc>Q<2hhH)!l8S3`Ey#Y%%*c z`ixL0NB@>zl)soY3u#TwUrf_zVQ{YtnvKyv1B-d11co%2-q`Gc8t%x!6D1R5(}YN} z;F{Fmu_S^!oCB-5jNE7=rUL*h z=|QGCg;T{NboY_d8|#Y!?|)anPXBd@CBR76`^M1w|P-FplH65=e% z^on?sd_}hA|5wfvR7h!b6d?;N<>w80lO6ejK_C7JQq+$bg|VJDY_AP{OfXVkcPdR0 z2QA&&H(Jhld*5#?7dbf2kx%#T^W%A+3)NxR;`h9cj@{+#N0Z(Z2E|G@=wQ4F_qW0cL`ss)J zSVylXQzptWXm-o$4_0FML&z(dA!)lQ;zemUtRU}44Bqn@_=dB)Bae)yW<;^8I
BeEGE3&A9XCc>UW>Ntv<(7nY_Y=-#tPdHt-Wr<=^q4`@fZN
z#`EoK-(#z@aZzgStLww3p)XOAQxhM)_i$Wn?kemLbULT%LFVz6tlPK=r2F-P%@#Dab>{esb0BIcm0kJ{ui70m@VKp$Jpf
zj{{piC6!SQ`7=d-ivQ##nD$T{318{c)4J>t3Rpcb5SR}wM>8o8sSm+`)hKI7XfmK-
z5g_>q604aZBOEXwRVQLA7R;~yRFL`?C9tp~bV1;W@0uiENW%P|Dr+3Md@dzW&69{_
zVvc(r4Ce_-<_sJbN?2cYkbqz*NiP$`EE@n(plFo6TU?nAZqJkseoxNR`x~=`Zq3jS
zEy{?N*chLa3f?D(ib(&v)G+iIq?bmWuym(zOt#X(;q}tib@_07`+iI}|95DO@D}`Y
zvW%+Y4y)<6ry}>$l4CSYM_|9Sx@|QVBVn`aniQk%>1#vma-TzpQEaunNr#RzS&#oq
ztp+UA4b-bLLMhyi#}!Xbf%30H$3idWb`EV+&L(!#`daal4gH_4Twed7*WL0GLPwv4
zz3KEbY`}!5=tdbHd3vKP+$67Wzw@im-1T!<;V<9$Vko=)odN6=AjUj(9*%At#7n=D
zJ8vzq7ts7gZ+ngDgx$jLISVQ8`lmfqc4rS#6(HK#4_oC=e0$=i%~_L;5Jg$k=}X@$
z^&bx5$A;BZ>-z1ON<0lasRgZXY(?#BF>Tnys{>FGwQ36#Q}oRX$Vbl&T-x%@5YH~k
z^Bp(i$!*Nfe-Xa^7NHm*Xb7BYuLyMmis?YJ75+>iZ4XoBhWDhkfLAq4&`dwuT4(HQ
z*=GB(mrsu_RoNML4LPD<**uLy|Ha;vW*>$v5wc#=R@RF7`x<^L>FrW#7z^DwyJktRmh!X
zy&d_TViMi@cjLpi^r3pfesniBl>C}O)wIe_*xB8CDKRrX=YA3F!tG`HgRZq{;v9wN
zeAT7JcA{Edkbx?+cMHG!aiP&(QK*MNm%3nX{med%w7I2*39vu#Gd(kY`1yFiuGe9$b($ypYgb
zp2zHcY%unNiLjjpvT~TXSf7F4jZ;#WQn=x6v&7|E_t;9cZUAG}`Y;MLn_Y=p{u#hM
zC=8ALun$9CC626ATA=W+)G*08Op!6Px#ysb-ut+__S+XoyxBTo2b#L|lr-Z@uCe&=vjDpu(+y2XMgd+eN
zBcn5e^H&X#_0M;J+6q2#wZ+rY)&Ytq_9f$S0VH(PGi2iwz;5!^Z}PTaW3p86hdD;*
zK&EpRT#;$S;ig(ZEngI2*Q9L;Yvn|a6$op<-kZ9vjVJ=+z#H$6`T{g~;Q&oO{j)2t
zzJleDvDrwGX$q9xSbi5;D|16o2>nNu+Nhv(FPXzX$f0t#$IWOcrmK@y+A}>(|
z0~q-k{#-`1?Q~sTYKSHwa*_l3=@yT*f6?CoDt0R$g#N^}(&3>vsj2Qf4>vba%R#~Y
z9JjI6;lj=1-t#*)fCcg}-r0JKiCKjwG6i{Uwt8GhPorL+7G;r^k{=Nj^OQ9VClS8f
zJd{ziv@y3RF_gk514GO7Xo%iotS>8xQ^S-_ALS>Ao2o{Gwdq0D`6|!GFQZ)VSU(oo
zLb}4!lWnP@>gQ)7lHw(!oH_&>b@18H^K3H0Au8CnT>we@@3Ql@PRiy@?!DMNU&LKb~7=WBm#RjGc^FI2q#j>9D1{fv=j
z{Qb5Kp7lxYjuk9J97$INjDwy?>9zmx`Y}KR{;(~F8-KK6+HT{dvpm>UxOtO7?N?E&
z8AJ+X(BKFgG`!<9PRI$ik}AU!f3$L?5Vw_A2!{c$N)hh2JgoifCiv+`LkW(0PXuKZ
ze;)(>@LFp3yz|&P4wM4UtI~H1C!eyWgPK*yiM{QSf1PDmtEn`-f2c5;|6H>5Ot-qq
z^}?j$(QHJGmH=sfl(@P5ek?iq^ASP--TZfmy*~9C6(Q^_e>aj)cOw3G=d6ACL=xq{
z0}+;w0&V+jWVl4{Lzk!{Ul}UY=6ZuC@JJIUp9futZ=d+*mN~}!u~=X%y3T1C@?xU!
zGD@Nt<5KOK6UL7NUuxTx>Rk*>#Z
zq)YH};B2vT0>+<0RfTHLUhmq%-QMDmBd^E2pPV5LU+ivLiiyv3ZzF)(90PZ%Dz|(c
zt`;{JnS--%-v9PZ%!|@PA(dP4LyP_(ZGMEz_8sa^v^f55a)|;t#`9BhO;ZrE_A2Gb+Ql*XBT7kRm5+!W
z4@XU5NH4)BtQ$@RgWG(=b0_x|)Ktjdz|gkcEe+vo^9n;Bv;q08bK8?rpn35mj?c#u
zYxjl*^;?~9j<%LM2)7NJhjNvh7U4??tQ&pJ@Ef)s6@qMJ4h>Oif*$~cLI(?@s0-CD
zdb%JDt*X(j?+|A;t~fQV@85b?{~J{A1*RL?2J)Y~99L>`_8@sQM_Ng-`F#p^x^&Wy
z=z;I&1V@sM6tVc0*k7a${k>1nhH=$iL7`N=>1vd&9K)!jG!MM?<88YEDX-G1kp{0w
zg@mTxtzFR|pKanLRw(vJB%@E?6TPk8^u>O`qD7;Lh~r@3BR=$|g;SDy`@}4H1|F*+
zl6xdfxCe#~1eR<0K}8k@#z#Ix2)FR{9XawiO(K3n*Ek`;QnB8&S}beb3jOok!Wt3x
zE*Z?b;-|h}bN>>b3J~$~sq?qq+0k2d8;rntpu|*EJ>7^v=8fR)b9}CHh4g;0g7g%l
zRrO5l#!N1)qg#2kSC5>2@k$tT?xSDGOneMTyfs8qC#kO};c$Ubx#Q5darmJyhrpD<
zmhKXYu`JAJ0C}NkPNIrxBjjl=Ke9rH
z(-uQlKPzW=^vC7$L;_OeZA|Txr=UDELsctuajN?v?1ND@aPl~4po-;?wjOS6pE2xx;+e7h*}aq!*I+!
zs8UKg&p(V9BfWKq`A+OyQA1Ftk`z|X6Ng~Y8j*8ji)`Y
z>5KpEI?MhXpyJfi(AfOxtR?J3nFeYj>-dNacZO~`+%Y#(y}XG5laZc&&h^>?P|zJw
zodRS^%mgksH5DvmWc;tCEE#u!zVEvU{Oo*?rz*J+#;QsDyaN14{~GEZ{Lgmi=4s{v
NP?CqsmA^y;{2#|P4c7nw

literal 0
HcmV?d00001

diff --git a/entry/src/main/resources/rawfile/judge/km3/会车_red.png b/entry/src/main/resources/rawfile/judge/km3/会车_red.png
new file mode 100644
index 0000000000000000000000000000000000000000..047e23864fcaeb531e9e00a945d9a914b41b3957
GIT binary patch
literal 8440
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
B;@bcK

literal 0
HcmV?d00001

diff --git a/entry/src/main/resources/rawfile/judge/km3/停车_green.png b/entry/src/main/resources/rawfile/judge/km3/停车_green.png
new file mode 100644
index 0000000000000000000000000000000000000000..0536a1f91f72f0d7c05ac1c28ca8ae3275da1ed4
GIT binary patch
literal 7462
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
I+BERL0DrdQJpcdz

literal 0
HcmV?d00001

diff --git a/entry/src/main/resources/rawfile/judge/km3/停车_red.png b/entry/src/main/resources/rawfile/judge/km3/停车_red.png
new file mode 100644
index 0000000000000000000000000000000000000000..3322b7dcc80668b63100332101a9d8d18980d559
GIT binary patch
literal 7248
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
azWz3w^H0-2cI*}*j;5*(yjIyJ{J#L00cddm

literal 0
HcmV?d00001

diff --git a/entry/src/main/resources/rawfile/judge/km3/变道_green.png b/entry/src/main/resources/rawfile/judge/km3/变道_green.png
new file mode 100644
index 0000000000000000000000000000000000000000..72926b020401fd359cedc19cce0bd8f5bee68a7e
GIT binary patch
literal 8239
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

literal 0
HcmV?d00001

diff --git a/entry/src/main/resources/rawfile/judge/km3/变道_red.png b/entry/src/main/resources/rawfile/judge/km3/变道_red.png
new file mode 100644
index 0000000000000000000000000000000000000000..4be6efe12ef23e6e666de7ae394e1ebf06a1213b
GIT binary patch
literal 8113
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

literal 0
HcmV?d00001

diff --git a/entry/src/main/resources/rawfile/judge/km3/掉头_green.png b/entry/src/main/resources/rawfile/judge/km3/掉头_green.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb6d9ff94a9194c40e43151f7eb2fe897d9b0a21
GIT binary patch
literal 8737
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
cJN_aME;7Y3~eE
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

literal 0
HcmV?d00001

diff --git a/entry/src/main/resources/rawfile/judge/km3/直线_green.png b/entry/src/main/resources/rawfile/judge/km3/直线_green.png
new file mode 100644
index 0000000000000000000000000000000000000000..ca4438ec3d513395f8c35e3bd9ab94ee39894c22
GIT binary patch
literal 8774
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
KSSxQG`F{X^nqMdY

literal 0
HcmV?d00001

diff --git a/entry/src/main/resources/rawfile/judge/km3/直线_red.png b/entry/src/main/resources/rawfile/judge/km3/直线_red.png
new file mode 100644
index 0000000000000000000000000000000000000000..0309d51f72ef10849ac0f1f3569197f3e5f3961a
GIT binary patch
literal 8525
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
F{|BUiDq#Qs

literal 0
HcmV?d00001

diff --git a/entry/src/main/resources/rawfile/judge/km3/超车_red.png b/entry/src/main/resources/rawfile/judge/km3/超车_red.png
new file mode 100644
index 0000000000000000000000000000000000000000..1d45bc571254bec1912eebb93126122cd49ecb50
GIT binary patch
literal 8387
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
Hwh{jWUzn*%

literal 0
HcmV?d00001

diff --git a/entry/src/main/resources/rawfile/judge/km3/路口_green.png b/entry/src/main/resources/rawfile/judge/km3/路口_green.png
new file mode 100644
index 0000000000000000000000000000000000000000..c8a25cbac7d80e9f3c702ddf86da67d7cc057635
GIT binary patch
literal 7456
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

literal 0
HcmV?d00001

diff --git a/entry/src/main/resources/rawfile/judge/km3/路口_red.png b/entry/src/main/resources/rawfile/judge/km3/路口_red.png
new file mode 100644
index 0000000000000000000000000000000000000000..f18d7087cebb8b83205aa001648ff82339d80938
GIT binary patch
literal 7170
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

literal 13392
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ɳ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
vVU~=KTg*7%bVK>y3A1tge