You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

activate.vue 29KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045
  1. <template>
  2. <view class="containers">
  3. <view class="sec_info">
  4. <view class="info_txt">信息确认</view>
  5. <view class="info_plate">
  6. <text>车牌号码</text>
  7. <text>{{ fileDataStrings.vehiclePlate }}</text>
  8. </view>
  9. <view class="info_plate">
  10. <text>车牌颜色</text>
  11. <text>{{ fileDataStrings.vehiclePlateColorStr }}</text>
  12. </view>
  13. <view class="info_plate">
  14. <text>手机号码</text>
  15. <text>{{ fileDataStrings.customerTel }}</text>
  16. </view>
  17. <view class="info_plate" style="border: none" v-if="fileDataStrings.cardId">
  18. <text>卡号</text>
  19. <text>{{ fileDataStrings.cardId }}</text>
  20. </view>
  21. <view class="info_plate" v-if="fileDataStrings.obuId">
  22. <text>OBU号</text>
  23. <text>{{ fileDataStrings.obuId }}</text>
  24. </view>
  25. <view class="info_plate">
  26. <text>收费车型</text>
  27. <text>{{ fileDataStrings.vehicleClassStr }}</text>
  28. </view>
  29. </view>
  30. <view class="up_btn" v-if="state.showBtn">
  31. <button aria-disabled="true" @click="btn" v-if="!state.isSuccess" :class="state.disabled?'button':'hui'">
  32. 点击开始激活
  33. </button>
  34. <button aria-disabled="true" @click="back" v-else>
  35. 点击返回首页
  36. </button>
  37. </view>
  38. </view>
  39. <!-- 激活成功popup -->
  40. <view v-if="state.showPopup" class="mask">
  41. <piaoyi-progress-bar canvasId="progressCanvas4" :progress="state.progressNum" progressBackgroundColor="#07C160"
  42. :showText="true" textColor="#fff" :textSize="28" :height="22" :isCircular="true"
  43. :diameter="300"></piaoyi-progress-bar>
  44. </view>
  45. </template>
  46. <script setup>
  47. import {
  48. reactive,
  49. ref
  50. } from "vue";
  51. import {
  52. formatTime,
  53. formatTime2,
  54. expireDate,
  55. expireDate2,
  56. getFormatDate,
  57. msg,
  58. navTo
  59. } from "@/utils/utils";
  60. import {
  61. onLoad,
  62. onUnload
  63. } from '@dcloudio/uni-app'
  64. import {
  65. getItem
  66. } from "@/utils/storage";
  67. import {
  68. requestNew,
  69. corefn
  70. } from "@/utils/network/request.js";
  71. import {
  72. IntegerToHexString,
  73. } from "@/utils/util/fileData.js";
  74. import {
  75. issueApply,
  76. issueCallback,
  77. orderDetailQuery,
  78. errorLogAdd,
  79. cardObuQuery,
  80. cardObuQueryinLog,
  81. obuFileDataDecrypt
  82. } from "@/utils/network/api";
  83. import {
  84. agentId
  85. } from "@/utils/network/difference";
  86. import {
  87. startHeartbeat,
  88. stopHeartbeat
  89. } from "@/pages/bluetooth/heartbeatService"
  90. const cmd = require("../../../static/etcUtil/cmdConfig.js");
  91. const tools = require("../../../static/etcUtil/tools.js");
  92. const bluetoothUtil = require("../../../static/etcUtil/index.js");
  93. import activeSuccess from "./components/popup-device-active-success";
  94. const datas = require("../../../static/etcUtil/datas.js");
  95. import {
  96. getVehicleType
  97. } from "@/subpackage/after-sale/js/vehicleType.js"
  98. import {
  99. getVehiclePlateColor
  100. } from "@/datas/vehiclePlateColor";
  101. import {
  102. searchVehicleInfoQuery
  103. } from "@/subpackage/after-sale/js/publicRequest";
  104. import {
  105. decryptCardVehicleInformation
  106. } from "@/datas/publicRequest";
  107. import {
  108. channelId
  109. } from "@/utils/network/difference";
  110. const state = reactive({
  111. orderId: "",
  112. id: "",
  113. cardStatus: "",
  114. obuStatus: "",
  115. isSuccess: false, //是否激活成功
  116. showPopup: false,
  117. transfer: 0, //0 是原来的激活 1 是过户激活
  118. showBtn: true,
  119. disabled: true,
  120. progressNum: 0,
  121. CardVersion: "",
  122. ObuVersion: "",
  123. ChipSn: ""
  124. })
  125. onLoad((option) => {
  126. //读取传入 存储的数据orderInfo
  127. let orderData = getItem("orderInfo");
  128. state.id = orderData.id;
  129. console.log(state);
  130. state.transfer = Number(option.transfer)
  131. //获取订单详情
  132. getOrderDetails(orderData.orderId);
  133. console.log("state.transfer", state.transfer, state.transfer == 0, state.transfer == 1, getItem(
  134. "orderInfo"))
  135. })
  136. // ====================== 页面卸载时清理资源 ======================
  137. onUnload(() => {
  138. stopHeartbeat();
  139. // 实际项目中需调用 uni.closeBLEConnection 断开连接
  140. console.log('页面卸载,清理资源');
  141. });
  142. const card = reactive({
  143. cardId: "",
  144. cardNo: "",
  145. startTime: "",
  146. endTime: "",
  147. userName: "",
  148. userNameStr: "",
  149. idNum: "",
  150. idNumStr: "",
  151. vehiclePlate: "",
  152. vehiclePlateColor: "",
  153. color: "",
  154. colorStr: "",
  155. version: "",
  156. type: "",
  157. typeStr: "",
  158. favourable: "",
  159. favourableStr: "",
  160. money: "",
  161. v_userType: ""
  162. });
  163. const obu = reactive({
  164. obuId: "",
  165. num: "",
  166. startTime: "",
  167. endTime: "",
  168. version: "",
  169. approvedCount: "",
  170. axleCount: "",
  171. axleDistance: "",
  172. engineNum: "",
  173. type: "",
  174. typeStr: "",
  175. userType: "",
  176. userTypeStr: "",
  177. vehiclePlate: "",
  178. vehiclePlateColor: "",
  179. vehiclePlateColorStr: "",
  180. vin: "",
  181. wheelCount: "",
  182. isJH: "",
  183. isJHStr: "",
  184. outsideDimensions: "",
  185. loadStatus: ""
  186. });
  187. let cmdRandNum = '';
  188. let orderInfo = {};
  189. const fileDataStrings = reactive({
  190. approvedCount: 0, //核载人数
  191. cardId: "", //卡号
  192. obuId: "", //obu号
  193. packageNum: "", //套餐编号
  194. axleCount: 0, //轴数
  195. axleDistance: "", //轴距
  196. engineNum: "", //发动机
  197. vehicleVin: "",
  198. vehicleEngineNum: "",
  199. cardStatus: "",
  200. obuStatus: "",
  201. type: 0, //类型
  202. userType: 0, //用户类型
  203. vehiclePlate: "", //车牌
  204. vehiclePlateColor: 0, //车牌颜色
  205. vehicleDimensions: "",
  206. wheelCount: 0, //车轮数
  207. vehicleIdNo: "", //车牌号
  208. vehiclePlateColorStr: "",
  209. customerTel: "",
  210. customerId: "",
  211. orderId: "",
  212. vehicleClassStr: ""
  213. });
  214. function cmdResult1() {
  215. // tools.showLoadingAlert('正在激活,请等待')
  216. state.progressNum = 10
  217. const options = {
  218. type: 2, //type: 2,JSON格式提交数据(默认表单形式提交)
  219. showLoading: false,
  220. data: {
  221. orderNo: orderInfo.orderNo,
  222. issueType: state.transfer ? 2 : 1, //1正常激活 2 过户激活
  223. cardId: card.cardId,
  224. cardVersion: state.CardVersion,
  225. obuVersion: obu.version,
  226. obuId: obu.obuId
  227. }, //请求参数
  228. method: "POST", //提交方式(默认POST)
  229. };
  230. console.log("options==", options)
  231. console.log("二发指令申请==前,/iaw/issue/order/issueApply", new Date(), options)
  232. //BDS-二发指令申请
  233. requestNew(issueApply, options)
  234. .then((res) => {
  235. console.log("在线激活 请求");
  236. console.log(res);
  237. const datas = res;
  238. console.log("二发指令申请==后,/iaw/issue/order/issueApply", new Date(), res)
  239. bluetoothUtil.transCmd(datas.cmd.split(','), datas.cmdType == 'CARD' ? '10' : '20', function(res) {
  240. implementCmd(datas.transOrderId, datas.cmd, res.toString(), datas.stepNo)
  241. }, (err) => {
  242. showModals(err.msg)
  243. console.log("err", err)
  244. errorLog(datas.cmd, JSON.stringify(err), datas.stepNo)
  245. tools.hideLoadingAlert();
  246. state.showPopup = false
  247. state.disabled = true
  248. });
  249. })
  250. .catch((err) => {
  251. console.log(err);
  252. tools.hideLoadingAlert();
  253. state.showPopup = false
  254. state.disabled = true
  255. });
  256. }
  257. function implementCmd(transOrderId, cmd, cmdResult, stepNo) {
  258. console.log("datas.stepNo1", stepNo)
  259. if (state.progressNum > 100) {
  260. state.progressNum = Number(stepNo) * 10 + 10
  261. } else {
  262. state.progressNum = 100
  263. }
  264. const options = {
  265. type: 2, //type: 2,JSON格式提交数据(默认表单形式提交)
  266. showLoading: false,
  267. data: {
  268. transOrderId, //步骤号
  269. cmd,
  270. cmdResult,
  271. stepNo,
  272. mpOpenId: getItem('mpOpenId') //公众号openid
  273. }, //请求参数
  274. method: "POST", //提交方式(默认POST)
  275. };
  276. console.log("options2222", options)
  277. console.log("二发指令回传==前,/iaw/issue/order/issueCallback", new Date(), options)
  278. //BDS-二发指令回传
  279. requestNew(issueCallback, options)
  280. .then((res) => {
  281. console.log("BDS-二发指令回传 ", res);
  282. const datas = res;
  283. console.log("二发指令回传==后,/iaw/issue/order/issueCallback", new Date(), res)
  284. console.log("在线激活 请求", datas);
  285. if (datas.stepNo == 100) {
  286. state.disabled = true
  287. tools.hideLoadingAlert();
  288. state.progressNum = 100
  289. setTimeout(() => {
  290. state.showPopup = false
  291. }, 1000)
  292. setTimeout(() => {
  293. msg("激活成功", {
  294. 'icon': 'success',
  295. 'duration': 3000
  296. })
  297. }, 2000)
  298. setTimeout(() => {
  299. getCardIdCommit()
  300. }, 5000)
  301. } else {
  302. console.log("datas.stepNo", datas.stepNo)
  303. bluetoothUtil.transCmd(datas.cmd.split(','), datas.cmdType == 'CARD' ? '10' : '20', function(res) {
  304. implementCmd(transOrderId, datas.cmd, res.toString(), datas.stepNo)
  305. }, (err) => {
  306. console.log("err", err)
  307. state.showPopup = false
  308. state.disabled = true
  309. errorLog(datas.cmd, JSON.stringify(err), datas.stepNo)
  310. showModals(err.msg)
  311. });
  312. }
  313. })
  314. .catch((err) => {
  315. console.log(err);
  316. tools.hideLoadingAlert();
  317. state.showPopup = false
  318. state.disabled = true
  319. });
  320. }
  321. //开始激活 按钮事件
  322. const btn = () => {
  323. if (!state.disabled) {
  324. return;
  325. }
  326. if (state.CardVersion == '48' || state.CardVersion == '49' || state.ObuVersion == '48' || state.ObuVersion ==
  327. '49') {
  328. // 是48,49 先密钥升级再激活
  329. obuUpdate();
  330. } else {
  331. // 不是48,49直接激活
  332. activateQuqet()
  333. }
  334. };
  335. const activateQuqet = () => {
  336. state.disabled = false
  337. state.showPopup = true
  338. console.log('orderInfo参数', orderInfo, state.disabled)
  339. stopHeartbeat();
  340. cmdResult1()
  341. }
  342. //获取订单详情
  343. const getOrderDetails = (orderId) => {
  344. console.log('======获取订单信息======')
  345. const options = {
  346. type: 2,
  347. data: {
  348. orderNo: orderId
  349. },
  350. method: "POST",
  351. showLoading: false,
  352. };
  353. state.disabled = false
  354. requestNew(orderDetailQuery, options).then((res) => {
  355. console.log("orderInfo", res);
  356. orderInfo = res;
  357. console.log("orderInfores", res);
  358. if (orderInfo) {
  359. fileDataStrings.userType = orderInfo.userType; //用户类型
  360. fileDataStrings.cardId = orderInfo.cardId;
  361. fileDataStrings.packageNum = orderInfo.packageNum;
  362. fileDataStrings.obuId = orderInfo.obuId;
  363. fileDataStrings.customerTel = orderInfo.customerTel;
  364. fileDataStrings.customerId = orderInfo.customerId;
  365. fileDataStrings.orderId = orderInfo.orderNo;
  366. fileDataStrings.vehiclePlateColorStr = getVehiclePlateColor(orderInfo
  367. .vehiclePlateColor);
  368. fileDataStrings.vehiclePlate = orderInfo.vehiclePlate; //车牌
  369. fileDataStrings.vehicleClassStr = orderInfo.vehicleClassStr;
  370. }
  371. });
  372. getObuId();
  373. };
  374. /**
  375. * 获取OBU号 读OBU
  376. */
  377. const getObuId = () => {
  378. console.log('======获取OBU号======')
  379. let cmdArray = [cmd.HOME_DIRECTORY, cmd.OBU_SYSTEM_FILE, cmd.RANDOM_NUMBER];
  380. bluetoothUtil.transCmd(cmdArray, "20", function(res) {
  381. var status = res[1].substring(res[1].length - 4, res[1].length);
  382. console.log('获取OBU号执行结果' + status, res)
  383. //第一次获取随机数
  384. if (status == "9000") {
  385. state.disabled = true
  386. obu.obuId = res[1].substring(20, 36);
  387. obu.vin = res[1].substring(18, 20);
  388. obu.version = res[1].substring(18, 20);
  389. state.ObuVersion = res[1].substring(18, 20)
  390. state.ChipSn = res[1].substring(0, 8)
  391. cmdRandNum = res[2].substring(0, res[2].length - 4);
  392. getCardId()
  393. } else {
  394. showModals('获取设备信息错误!')
  395. }
  396. }, () => {
  397. showModals('获取设备信息错误')
  398. });
  399. };
  400. function showModals(msg) {
  401. uni.showModal({
  402. title: '提示',
  403. content: msg,
  404. showCancel: false,
  405. success: function(res) {
  406. if (res.confirm) {
  407. uni.navigateBack()
  408. console.log('用户点击确定1');
  409. } else if (res.cancel) {
  410. console.log('用户点击取消1');
  411. }
  412. }
  413. });
  414. }
  415. const back = () => {
  416. uni.switchTab({
  417. url: "/pages/index/index"
  418. });
  419. }
  420. const getCardId = () => {
  421. //执行0015文件
  422. tools.showLoadingAlert("执行指令");
  423. let cmdArr = [cmd.HOME_DIRECTORY, cmd.APPLICATION_DIRECTORY, cmd.CMD_READBINARY, cmd.CMD_GETBALANCE];
  424. console.log(cmdArr);
  425. console.log(bluetoothUtil);
  426. bluetoothUtil.transCmd(cmdArr, '10', function(res) { //10:写卡 20:写OBU
  427. console.log("5201", res)
  428. let str = res[2].substring(res[2].length - 4, res[2].length); //判断是否为9000
  429. let str3 = res[3].substring(res[3].length - 4, res[3].length); //判断是否为9000
  430. if (str == "9000" || str3 == "9000") {
  431. if (res[2].length > 86 || res[3] >= 12) {
  432. card.cardId = res[2].substring(20, 40);
  433. state.CardVersion = res[2].substring(18, 20),
  434. tools.hideLoadingAlert();
  435. state.showBtn = true
  436. startHeartbeat()
  437. } else {
  438. alertF("CMD_READBINARY指令长度不符" + res[2]);
  439. }
  440. return;
  441. }
  442. alertF("CMD_READBINARY指令长度不符" + res[2]);
  443. })
  444. };
  445. const errorLog = (cmd, error, step) => {
  446. console.log('激活异常提交')
  447. const options = {
  448. type: 2,
  449. data: {
  450. cardId: card.cardId,
  451. obuId: obu.obuId,
  452. orderType: "1",
  453. factory: datas.getData("deviceName") + "_" + datas.getData("deviceNameZW"),
  454. orderNo: orderInfo.orderNo,
  455. cmd,
  456. error,
  457. step
  458. },
  459. method: "POST",
  460. showLoading: false,
  461. };
  462. requestNew(errorLogAdd, options).then((res) => {
  463. console.log("错误提交成功", res);
  464. });
  465. };
  466. /**
  467. * 获取卡号
  468. */
  469. const getCardIdCommit = () => {
  470. //执行0015文件
  471. tools.showLoadingAlert("执行指令");
  472. let cmdArr = [cmd.HOME_DIRECTORY, cmd.APPLICATION_DIRECTORY, cmd.CMD_READBINARY, cmd.CMD_GETBALANCE];
  473. console.log(cmdArr);
  474. console.log(bluetoothUtil);
  475. bluetoothUtil.transCmd(cmdArr, '10', function(res) { //10:写卡 20:写OBU
  476. console.log("5201", res)
  477. let str = res[2].substring(res[2].length - 4, res[2].length); //判断是否为9000
  478. let str3 = res[3].substring(res[3].length - 4, res[3].length); //判断是否为9000
  479. if (str == "9000" || str3 == "9000") {
  480. if (res[2].length > 86 || res[3] >= 12) {
  481. console.log("res[2]", res[2].substring(84, 86), getVehiclePlateColor(parseInt(res[2]
  482. .substring(82, 84), 16)), res[2].substring(18, 19))
  483. card.cardNo = res[2].substring(20, 40);
  484. card.startTime = res[2].substring(40, 48);
  485. card.endTime = res[2].substring(48, 56);
  486. card.version = res[2].substring(18, 20);
  487. card.money = res[3].substring(0, 8);
  488. card.v_userType = parseInt(res[2].substring(80, 82), 16);
  489. console.log("card.v_userType", card.v_userType)
  490. decryptCardVehicleInformation(res[2].substring(56, 80), function(res) {
  491. card.vehiclePlate = res;
  492. });
  493. console.log("res[2].substring(18, 19)", res[2].substring(18, 20))
  494. if (res[2].substring(18, 19) >= 4) {
  495. //4x卡
  496. card.type = parseInt(res[2].substring(84, 86), 16);
  497. card.typeStr = getVehicleType(parseInt(res[2].substring(84, 86), 16));
  498. card.color = parseInt(res[2].substring(82, 84), 16)
  499. card.colorStr = getVehiclePlateColor(parseInt(res[2].substring(82, 84), 16))
  500. } else {
  501. //2x卡--获取车牌颜色
  502. card.type = "--";
  503. card.color = parseInt(res[2].substring(82, 84), 16)
  504. card.colorStr = getVehiclePlateColor(parseInt(res[2].substring(82, 84), 16))
  505. card.typeStr = getVehicleType(parseInt(res[2].substring(84, 86), 16));
  506. }
  507. state.vehicleId = card.vehiclePlate + "_" + parseInt(res[2].substring(82, 84), 16)
  508. // 读卡信息
  509. //执行0016文件
  510. let arr = [cmd.HOME_DIRECTORY, cmd.PERSONAL_INFORMATION]
  511. bluetoothUtil.transCmd(arr, '10', function(res) {
  512. let str2 = res[1].substring(res[1].length - 4, res[1].length);
  513. if (str2 == "9000") {
  514. if (res[1].length > 108) {
  515. console.log("res====", res)
  516. decryptCardVehicleInformation(res[1].substring(4, 44), function(res) {
  517. card.userName = res; //姓名
  518. card.userNameStr = card.userName[0] + '*'.repeat(card
  519. .userName.length - 1)
  520. });
  521. decryptCardVehicleInformation(res[1].substring(44, 108), function(
  522. res) {
  523. card.idNum = res; //身份证号码
  524. card.idNumStr = res.replace(/^\d{14}/, '**************')
  525. });
  526. //获取是否有优惠
  527. let cmdArr3 = [cmd.HOME_DIRECTORY, cmd.APPLICATION_DIRECTORY, cmd
  528. .CMD_00B08E0000
  529. ];
  530. bluetoothUtil.transCmd(cmdArr3, '10', function(res) {
  531. let str3 = res[2].substring(res[2].length - 4, res[2]
  532. .length);
  533. if (str3 == "9000") {
  534. if (res[2].length > 131) {
  535. let _str = parseInt(res[2].substring(129, 130),
  536. 16);
  537. card.favourable = _str
  538. switch (_str) {
  539. case 0:
  540. card.favourableStr = "否";
  541. break;
  542. case 1:
  543. card.favourableStr = "是";
  544. break;
  545. default:
  546. card.favourableStr = '未知' + "_" + _str;
  547. break;
  548. }
  549. //回调读取OBU指令
  550. getObuIdCommit()
  551. tools.hideLoadingAlert();
  552. } else {
  553. alertF("CMD_00B08E0000指令长度不符" + res[2]);
  554. }
  555. return;
  556. }
  557. alertF(cmd.PERSONAL_INFORMATION + "_" + str);
  558. })
  559. } else {
  560. alertF("PERSONAL_INFORMATION指令长度不符" + res[1]);
  561. }
  562. return;
  563. }
  564. alertF("PERSONAL_INFORMATION指令长度不符" + res[1]);
  565. })
  566. } else {
  567. alertF("CMD_READBINARY指令长度不符" + res[2]);
  568. }
  569. return;
  570. }
  571. alertF("CMD_READBINARY指令长度不符" + res[2]);
  572. })
  573. };
  574. /**
  575. * 获取OBU号
  576. */
  577. const getObuIdCommit = () => {
  578. tools.showLoadingAlert("执行指令");
  579. let cmdArr = [cmd.HOME_DIRECTORY, cmd.OBU_SYSTEM_FILE];
  580. bluetoothUtil.transCmd(cmdArr, '20', function(res) {
  581. let str = res[1].substring(res[1].length - 4, res[1].length);
  582. if (str == "9000") {
  583. if (res[1].length > 52) {
  584. obu.num = res[1].substring(20, 36);
  585. obu.startTime = res[1].substring(36, 44);
  586. obu.endTime = res[1].substring(44, 52);
  587. obu.version = res[1].substring(18, 20);
  588. obu.isJH = res[1].substring(53, 54)
  589. obu.isJHStr = res[1].substring(53, 54) == "1" ? "是" : res[1].substring(53, 54) == "0" ?
  590. "否" : "其他:" + res[1].substring(53, 54);
  591. obu.loadStatus = res[1].substring(52, 54) == '01' ? '正常' : '已拆卸',
  592. console.log("开始执行车辆信息识读");
  593. let rand = res[1].substring(18, 20) >= 50 ? '40' : '00';
  594. var arr = [cmd.OBU_DF01, '00B400000A000000000000000045' + rand];
  595. bluetoothUtil.transCmd(arr, '20', function(res) {
  596. console.log(res);
  597. console.log("开始执行车辆信息识读成功");
  598. let str2 = res[1].substring(res[1].length - 4, res[1].length);
  599. let obuVersion = res[1].substring(18, 20);
  600. let keyIndex = obuVersion > 50 ? '40' : '00';
  601. let reqType = '00';
  602. let proviceCode = '5201';
  603. if (str2 == "9000") {
  604. console.log("===========", obu.num, res[1].substring(0, res[1].length - 4))
  605. decryptObuVehicleInfo(obu.num, res[1].substring(0, res[1].length - 4),
  606. obuVersion, rand, reqType, proviceCode,
  607. function(res) {
  608. obu.approvedCount = res.approvedCount;
  609. obu.axleCount = res.axleCount;
  610. obu.axleDistance = res.axleDistance;
  611. obu.engineNum = res.engineNumber.replace(/\u0000/g, '');
  612. obu.type = res.collectionType;
  613. obu.typeStr = getVehicleType(res.collectionType);
  614. obu.userType = res.userType;
  615. if (res.userType == 0) {
  616. obu.userTypeStr = "普通车";
  617. } else if (res.userType == 6) {
  618. obu.userTypeStr = "公务车";
  619. }
  620. obu.vehiclePlate = res.vehiclePlate.replace(/\u0000/g, '');
  621. //获取车牌颜色
  622. obu.vehiclePlateColor = res.vehiclePlateColor;
  623. obu.vehiclePlateColorStr = getVehiclePlateColor(res
  624. .vehiclePlateColor);
  625. obu.vin = res.vin.replace(/\u0000/g, '');
  626. obu.wheelCount = res.wheelsCount;
  627. obu.outsideDimensions = res.carLong + "x" + res.carWidth +
  628. "x" + res.carHeight
  629. getObuList();
  630. tools.hideLoadingAlert();
  631. });
  632. //断开蓝牙
  633. bluetoothUtil.disconnectDevice();
  634. tools.showToastAlert("蓝牙已断开");
  635. console.log('蓝牙已断开=========')
  636. return;
  637. }
  638. alertF("OBU_00B400000A+rand+OBU_4F00指令长度不符" + res[1]);
  639. })
  640. } else {
  641. alertF("OBU_SYSTEM_FILE指令长度不符" + res[1]);
  642. }
  643. return;
  644. }
  645. alertF("OBU_SYSTEM_FILE指令长度不符" + res[1]);
  646. })
  647. };
  648. const getObuList = () => {
  649. var data = {
  650. obuId: obu.num,
  651. cardId: card.cardNo,
  652. };
  653. const options = {
  654. type: 2,
  655. data: data,
  656. method: "POST",
  657. showLoading: true,
  658. };
  659. requestNew(cardObuQuery, options).then((res) => {
  660. tools.hideLoadingAlert();
  661. let result = res;
  662. state.obuStatus = result.obuStatus ? result.obuStatus : ""
  663. state.cardStatus = result.cardStatus
  664. if (result.cardType == 1 && result.debitType == 1) {
  665. state.cardTypeName = "预存卡"
  666. card['cardTypeName'] = 3
  667. } else if (result.cardType == 2) {
  668. state.cardTypeName = "储值卡"
  669. card['cardTypeName'] = 2
  670. } else {
  671. state.cardTypeName = "记账卡"
  672. card['cardTypeName'] = 1
  673. }
  674. // 卡签提交得信息
  675. card['cardStatus'] = result.cardStatus
  676. obu['obuStatus'] = result.obuStatus ? result.obuStatus : ""
  677. cardObuMsgUp()
  678. })
  679. }
  680. // 签信息提交日志记录
  681. const cardObuMsgUp = () => {
  682. var data = {
  683. cardLogInfo: card,
  684. obuLogInfo: obu,
  685. type: "active"
  686. };
  687. const options = {
  688. type: 2,
  689. data: data,
  690. method: "POST",
  691. showLoading: true,
  692. };
  693. requestNew(cardObuQueryinLog, options).then((res) => {
  694. tools.hideLoadingAlert();
  695. navTo(`/subpackage/after-sale/activation/result`)
  696. console.log("提交成功")
  697. })
  698. }
  699. /**
  700. * 解密OBU车辆信息
  701. */
  702. const decryptObuVehicleInfo = (num, data, obuVersion, keyIndex, reqType, proviceCode, func) => {
  703. const options = {
  704. type: 2,
  705. data: {
  706. contractSN: num,
  707. cipherData: data,
  708. reqType: reqType,
  709. keyIndex: keyIndex,
  710. proviceCode: proviceCode
  711. },
  712. method: "POST",
  713. showLoading: true,
  714. };
  715. requestNew(obuFileDataDecrypt, options).then((res) => {
  716. console.log("obuFileDataDecrypt", res)
  717. const data = res
  718. func(data)
  719. });
  720. };
  721. //提示对话框
  722. const alertF = (msg) => {
  723. //隐藏加载框
  724. tools.hideLoadingAlert();
  725. //提示对话框
  726. tools.showModalAlert(msg);
  727. stopHeartbeat();
  728. }
  729. async function obuUpdate() {
  730. tools.showLoadingAlert('升级中');
  731. //升级类OBU
  732. const applyData = await apply4Upgrade({
  733. contractSn: obu.obuId, //OBU合同序列号 16位
  734. chipSn: state.ChipSn, //OBU晶片序列号 8位
  735. issueMode: 'UPG', //发行模式
  736. issueType: 'SCOBU', //发行发行类型
  737. cardVersion: state.CardVersion, //卡版本号
  738. obuVersion: state.ObuVersion //OBU版本号
  739. });
  740. if (!applyData) return false;
  741. console.log("applyData", applyData)
  742. if (state.CardVersion == '48' || state.CardVersion == '49') {
  743. const updateEsDat = await updateEs('GEN_OBEIC_UPG', applyData);
  744. if (!updateEsDat) return false;
  745. }
  746. if (state.ObuVersion == '48' || state.ObuVersion == '49') {
  747. const updateEsDatTwo = await updateEs('GEN_OBESAM_UPG', applyData);
  748. if (!updateEsDatTwo) return false;
  749. }
  750. const upgradeDoneData = await upgradeDone({
  751. issueSerialNo: applyData.issueSerialNo, //发行订单号
  752. });
  753. if (!upgradeDoneData) return false;
  754. connectPrefixName = datas.getData("connectPrefixName");
  755. console.log(connectPrefixName);
  756. activateQuqet();
  757. }
  758. function apply4Upgrade(params) {
  759. return new Promise((resolve) => {
  760. corefn('IF01001202504281152', params, function(res) {
  761. console.log("成功1", res)
  762. if (res.rc != "00") {
  763. tools.alertF(res.rm);
  764. return;
  765. }
  766. console.log("成功", res)
  767. resolve(res.rd)
  768. })
  769. })
  770. }
  771. //获取发行脚本指令
  772. async function updateEs(type, applyData) {
  773. tools.showLoadingAlert('升级中');
  774. //获取发行脚本指令
  775. const getCommanData = await getCommands({
  776. cardNo: applyData.cardNo, //卡片序列号
  777. wareId: type, //OBU的物料代码 OBE-SAM通道 GEN_OBESAM_UPG OBE-IC通道 GEN_OBEIC_UPG
  778. issueSerialNo: applyData.issueSerialNo, //发行订单号
  779. });
  780. if (!getCommanData) return false;
  781. //指令解析
  782. const result = getCommanData.commands;
  783. const array = result.split('~');
  784. const cmdType = type == 'GEN_OBESAM_UPG' ? '20' : '10';
  785. for (const element of array) {
  786. tools.showLoadingAlert('升级中');
  787. // 让出主线程,确保UI更新
  788. await new Promise(resolve => setTimeout(resolve, 0));
  789. console.log("进来了", element.charAt(0), )
  790. if (element.charAt(0) === 'D' || element.charAt(0) === 'R') {
  791. await processDirectCommand(element, cmdType);
  792. } else if (element.charAt(0) === 'K') {
  793. await processKeyExchange(element, cmdType, applyData);
  794. } else if (element.charAt(0) === 'E') {
  795. await processExtAuth(element, cmdType, applyData);
  796. }
  797. }
  798. return true;
  799. }
  800. function getCommands(params) {
  801. return new Promise((resolve, reject) => {
  802. corefn('IF01001202504281153', params, function(res) {
  803. console.log("成功1", res)
  804. if (res.rc != "00") {
  805. tools.alertF(res.rm);
  806. return;
  807. }
  808. console.log("成功", res)
  809. resolve(res.rd)
  810. })
  811. })
  812. }
  813. // 提取出来的子函数
  814. async function processDirectCommand(element, cmdType) {
  815. // 添加随机延迟,避免连续请求
  816. return bluetoothUtil.transCmdArrAfter(element.substring(1), cmdType);
  817. }
  818. async function processKeyExchange(element, cmdType, applyData) {
  819. const ranData = await bluetoothUtil.transCmdArrAfter('0084000004', cmdType);
  820. console.log("ranData", ranData)
  821. const exchangeKeyData = await exchangeKey({
  822. key: element.substring(1),
  823. random: ranData['0084000004'][0].substring(0, 8),
  824. issueSerialNo: applyData.issueSerialNo
  825. });
  826. if (!exchangeKeyData) throw new Error('密钥置换失败');
  827. console.log("exchangeKeyData", exchangeKeyData)
  828. return bluetoothUtil.transCmdArrAfter(exchangeKeyData.apdu, cmdType);
  829. }
  830. async function processExtAuth(element, cmdType, applyData) {
  831. const ranData = await bluetoothUtil.transCmdArrAfter('0084000004', cmdType);
  832. const extAuth4IssData = await extAuth4Iss({
  833. keyType: element.substring(1),
  834. random: ranData['0084000004'][0].substring(0, 8),
  835. issueSerialNo: applyData.issueSerialNo,
  836. });
  837. console.log("extAuth4IssData", extAuth4IssData)
  838. if (!extAuth4IssData) throw new Error('外部认证失败');
  839. return bluetoothUtil.transCmdArrAfter(extAuth4IssData.apdu, cmdType);
  840. }
  841. function extAuth4Iss(params) {
  842. console.log("params", params)
  843. return new Promise((resolve) => {
  844. corefn('IF01001202504281156', params, function(res) {
  845. console.log("成功1", res)
  846. if (res.rc != "00") {
  847. tools.alertF(res.rm);
  848. return;
  849. }
  850. console.log("成功", res)
  851. resolve(res.rd)
  852. })
  853. })
  854. }
  855. function exchangeKey(params) {
  856. return new Promise((resolve) => {
  857. corefn('IF01001202504281154', params, function(res) {
  858. console.log("成功1", res)
  859. if (res.rc != "00") {
  860. tools.alertF(res.rm);
  861. return;
  862. }
  863. console.log("成功", res)
  864. resolve(res.rd)
  865. })
  866. })
  867. }
  868. function upgradeDone(params) {
  869. return new Promise((resolve) => {
  870. corefn('IF01001202504281155', params, function(res) {
  871. console.log("成功1", res)
  872. if (res.rc != "00") {
  873. tools.alertF(res.rm);
  874. return;
  875. }
  876. console.log("成功", res)
  877. resolve(res.rd)
  878. })
  879. })
  880. }
  881. </script>
  882. <style>
  883. .containers {
  884. height: 100%;
  885. display: flex;
  886. flex-direction: column;
  887. align-items: center;
  888. justify-content: space-between;
  889. box-sizing: border-box;
  890. }
  891. .sec_info {
  892. width: 90%;
  893. height: auto;
  894. margin: 0 auto;
  895. box-shadow: 0rpx 6rpx 25rpx 0rpx rgba(0, 0, 0, 0.2);
  896. margin-top: 50rpx;
  897. border-radius: 20rpx;
  898. }
  899. .info_txt {
  900. width: 100%;
  901. height: 120rpx;
  902. line-height: 120rpx;
  903. text-align: center;
  904. color: #000;
  905. font-size: 36rpx;
  906. margin-bottom: 20rpx;
  907. }
  908. .info_plate {
  909. display: flex;
  910. flex-direction: row;
  911. width: 94%;
  912. height: 100rpx;
  913. margin: 0 auto;
  914. border-bottom: 2rpx solid #f2f2f2;
  915. }
  916. .info_plate text:nth-child(1) {
  917. height: 100rpx;
  918. text-align: left;
  919. line-height: 100rpx;
  920. font-size: 32rpx;
  921. color: #999;
  922. }
  923. .info_plate text:nth-child(2) {
  924. flex: 1;
  925. height: 100rpx;
  926. line-height: 100rpx;
  927. font-size: 32rpx;
  928. color: #333;
  929. margin-left: 50rpx;
  930. text-align: right;
  931. }
  932. /*提交按钮样式*/
  933. .up_btn {
  934. width: 85%;
  935. height: 100rpx;
  936. margin: 0 auto;
  937. margin-top: 50rpx;
  938. margin-bottom: 100rpx;
  939. }
  940. .up_btn button {
  941. width: 100%;
  942. height: 80rpx;
  943. line-height: 80rpx;
  944. color: white;
  945. font-size: 32rpx;
  946. text-align: center;
  947. background: linear-gradient(to right, #01243A, #004576);
  948. border-radius: 40rpx;
  949. outline: none;
  950. border: #4cd95f;
  951. }
  952. .button {
  953. width: 100%;
  954. height: 80rpx;
  955. line-height: 80rpx;
  956. color: white;
  957. font-size: 32rpx;
  958. text-align: center;
  959. background: linear-gradient(to left, #43a1e0 0%, #13e7c1 100%);
  960. border-radius: 40rpx;
  961. outline: none;
  962. border: #4cd95f;
  963. }
  964. .hui {
  965. width: 100%;
  966. height: 80rpx;
  967. line-height: 80rpx;
  968. color: white;
  969. font-size: 32rpx;
  970. text-align: center;
  971. background: linear-gradient(to left, #b9b9b9 0%, #e7e7e7 100%) !important;
  972. border-radius: 40rpx;
  973. outline: none;
  974. border: #4cd95f;
  975. }
  976. .up_btn button[disabled] {
  977. background-color: rgba(0, 191, 112, 0.5);
  978. color: white;
  979. font-size: 34rpx;
  980. border-radius: 20rpx;
  981. }
  982. .mask {
  983. width: 100%;
  984. height: 100vh;
  985. background: rgba(0, 0, 0, 0.63);
  986. position: fixed;
  987. left: 0;
  988. top: 0;
  989. right: 0;
  990. bottom: 0;
  991. z-index: 999;
  992. display: flex;
  993. align-items: center;
  994. justify-content: center;
  995. }
  996. </style>