Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

activate.vue 29KB

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