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 30KB

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