Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

activeAgainStep.js 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. // plugin/etc/pages/activeDes/activeDes.js
  2. import {
  3. configPluginData,
  4. failPluginData
  5. } from "../../../config.js"
  6. import {
  7. ActiveDevice,
  8. DisConnectDevice,
  9. EquipmentDetection,
  10. ObuSystemInfo
  11. } from "../../../utils/active-tools/active-device-tools.js"
  12. import {
  13. starSearch,
  14. stopSearch
  15. } from "../../../utils/blue-related-tools/blue_tool.js"
  16. import {
  17. formatCardNumber
  18. } from "../../../utils/obj-tools.js"
  19. import {
  20. HOME_DIRECTORY,
  21. OBU_SYSTEM_FILE,
  22. RANDOM_NUMBER,
  23. APPLICATION_DIRECTORY,
  24. CMD_READBINARY,
  25. CMD_GETBALANCE
  26. } from '../../../utils/cmdConfig'
  27. import {
  28. transCmd,
  29. transCmdArrAfter,
  30. transCmdAfter
  31. } from '../../../utils/etc-sdk-tool/etc-sdk-tool'
  32. import {
  33. API
  34. } from '../../../network/etcApi'
  35. Page({
  36. /**
  37. * 页面的初始数据
  38. */
  39. data: {
  40. orderNo: "",
  41. type: 1,
  42. devList: [],
  43. showPopDevice: false,
  44. obuIdStr: "xxxx xxxx xxxx xxxx",
  45. cardIdStr: "xxxx xxxx xxxx xxxx",
  46. searchFailMsg: "请检查手机蓝牙、ETC蓝牙是否均已打开,连接过程中将手机和ETC设备尽量靠近",
  47. searchFailTitle: "未检测到ETC设备",
  48. activeFail: false,
  49. activeFailMsg: "不可发行/设备未入库",
  50. showType: 1,
  51. obuInfo: {
  52. version: '',
  53. obuId: '',
  54. chipSn: ''
  55. },
  56. cardInfo: {
  57. version: '',
  58. cardId: ''
  59. },
  60. plateNum: '', // 车牌号
  61. cardId: '',
  62. obuId: '',
  63. vehPosImgUrl: '',
  64. vehNegImgUrl: '',
  65. vehBodyUrl: '',
  66. installImgUrl: ''
  67. },
  68. /**
  69. * 生命周期函数--监听页面加载
  70. */
  71. onLoad(options) {
  72. this.configData(options)
  73. },
  74. onUnload() {
  75. this.configStop()
  76. },
  77. /// -------------- 工具类型 ---------------- ///
  78. // 配置默认参数
  79. configData(options) {
  80. configPluginData()
  81. const plateNum = options.plateNum ? options.plateNum : ''
  82. const cardId = options.cardId ? options.cardId : ''
  83. const obuId = options.obuId ? options.obuId : ''
  84. const vehPosImgUrl = options.vehPosImgUrl ? options.vehPosImgUrl : ''
  85. const vehNegImgUrl = options.vehNegImgUrl ? options.vehNegImgUrl : ''
  86. const vehBodyUrl = options.vehBodyUrl ? options.vehBodyUrl : ''
  87. const installImgUrl = options.installImgUrl ? options.installImgUrl : ''
  88. this.setData({
  89. plateNum,
  90. cardId,
  91. obuId,
  92. vehPosImgUrl,
  93. vehNegImgUrl,
  94. vehBodyUrl,
  95. installImgUrl
  96. })
  97. },
  98. /// 新版激活 -------- 触发方法
  99. /// 停止一切与设备相关的操作
  100. async configStop(isStop = true) {
  101. console.log('configStop')
  102. console.log("这个方法里执行断开设备")
  103. await DisConnectDevice()
  104. stopSearch(isStop)
  105. },
  106. // 点击开始搜索
  107. tapStar() {
  108. this.configNavTitle()
  109. this.setData({
  110. showPopDevice: false,
  111. devList: [],
  112. showType: 1,
  113. })
  114. wx.showLoading({
  115. title: '正在搜索设备...',
  116. })
  117. let self = this;
  118. starSearch((DevResult) => {
  119. console.log(DevResult);
  120. wx.hideLoading()
  121. if (DevResult.code == 0) {
  122. self.configNavTitle("验证设备")
  123. self.setData({
  124. devList: DevResult.data,
  125. showPopDevice: true,
  126. });
  127. } else {
  128. self.configSearchFail(DevResult.code)
  129. }
  130. }, false, "", false);
  131. },
  132. /// 配置导航栏标题
  133. configNavTitle(title = "设备搜索") {
  134. wx.setNavigationBarTitle({
  135. title: title,
  136. })
  137. },
  138. async tapOwner(e) {
  139. console.log(e)
  140. stopSearch(false);
  141. let device = e.detail;
  142. const res = await this.configActive(device);
  143. await DisConnectDevice()
  144. wx.hideLoading()
  145. if (res.code == 0) {
  146. this.configActiveSuccess();
  147. } else if (res.code == 250) {
  148. this.configSearchFail(res.code)
  149. } else {
  150. this.setData({
  151. activeFail: true,
  152. devName: device.name || "",
  153. activeFailMsg: res.msg || '请检查ETC硬件是否处于通电并开启蓝牙的状态'
  154. })
  155. }
  156. },
  157. // 连接设备
  158. async configActive(device) {
  159. const that = this;
  160. const rt = await EquipmentDetection({
  161. device,
  162. disconnectCallback: () => {
  163. that.configSearchFail(250)
  164. },
  165. })
  166. if (rt.code !== 0) {
  167. return rt
  168. } else {
  169. this.configEtcNumber(rt.data);
  170. // 激活前先查看是否需要升级设备
  171. await this.getObjDetail()
  172. await this.getCardId()
  173. if (this.data.obuInfo.version == '48' || this.data.obuInfo.version == '49' || this.data.cardInfo.version == '48' || this.data.cardInfo.version == '49') {
  174. await this.devideUpgrade()
  175. // 升级以后需要重新更新一下设备信息
  176. await ObuSystemInfo()
  177. }
  178. let cmdRandNum = await this.getVFJObuActive()
  179. let vFJObuInfo = await this.getObuActivation(cmdRandNum);
  180. return vFJObuInfo
  181. // 激活逻辑
  182. // const res = await ActiveDevice({
  183. // device,
  184. // params: {
  185. // orderNo: this.data.orderNo,
  186. // },
  187. // disconnectCallback: () => {
  188. // that.configSearchFail(250)
  189. // },
  190. // isNeedContect: false,
  191. // isNeedReadDevice: false
  192. // })
  193. // return res
  194. }
  195. },
  196. // 获取激活指令
  197. async getVFJObuActive() {
  198. let cmdArr = [HOME_DIRECTORY, RANDOM_NUMBER];
  199. let res = await transCmd(cmdArr, '20')
  200. let cmdResult = res.cmdResult ? res.cmdResult.split(',') : []
  201. var status = cmdResult[1].substring(cmdResult[1].length - 4, cmdResult[1].length);
  202. if (status == "9000") {
  203. let cmdRandNum = cmdResult[1].substring(0, cmdResult[1].length - 4);
  204. return cmdRandNum
  205. } else {
  206. wx.showToast("RANDOM_NUMBER指令长度不符" + cmdResult[1]);
  207. }
  208. },
  209. async getObuActivation(cmdRandNum) {
  210. let vehicleArr = this.data.plateNum.split('_')
  211. let params = {
  212. // Flag: '0001',
  213. // ContractSN: this.data.obuId,
  214. // Random: cmdRandNum,
  215. cardId: this.data.cardId,
  216. obuId: this.data.obuId,
  217. vehiclePlate: vehicleArr[0],
  218. vehiclePlateColor: vehicleArr[1],
  219. vehicleType: this.data.vehicleType,
  220. random: cmdRandNum
  221. }
  222. let resData = await API.ETC.getVFJObuActive(params)
  223. let APDUInfo = resData.data
  224. let cmdArr = APDUInfo.APDU.split(',')
  225. let res = await transCmd(cmdArr, '20')
  226. let cmdResult = res.cmdResult ? res.cmdResult.split(',') : []
  227. if (cmdResult && cmdResult.length) {
  228. if (cmdResult[0] === '9000') {
  229. await this.activeSaveRecords()
  230. wx.showLoading({
  231. title: '激活成功'
  232. })
  233. return {
  234. code: 0,
  235. msg: "激活成功"
  236. }
  237. } else {
  238. wx.showToast('获取设备信息错误!')
  239. }
  240. } else {
  241. wx.showToast('获取设备信息错误!')
  242. }
  243. },
  244. // 二次设备激活保存记录
  245. async activeSaveRecords() {
  246. let data = this.data
  247. let vehicleArr = data.plateNum.split('_')
  248. let params = {
  249. vehicleId: data.plateNum,
  250. vehiclePlate: vehicleArr[0],
  251. vehiclePlateColor: vehicleArr[1],
  252. cardId: data.cardId,
  253. obuId: data.obuId,
  254. vehPosImgUrl: data.vehPosImgUrl,
  255. vehNegImgUrl: data.vehNegImgUrl,
  256. vehBodyUrl: data.vehBodyUrl,
  257. installImgUrl: data.installImgUrl,
  258. type: 2,
  259. activeType: 2,
  260. sourceType: "CHANNEL"
  261. }
  262. await API.ETC.activeSaveRecords(params).then(res => {
  263. // wx.navigateBack()
  264. })
  265. },
  266. configActiveSuccess() {
  267. wx.redirectTo({
  268. url: 'plugin://issuer-plugin/activeStatus' + "?obu=" + this.data.obuIdStr + "&card=" + this.data.cardIdStr + "&type=1",
  269. })
  270. },
  271. // 格式化obu号
  272. configEtcNumber(data) {
  273. this.setData({
  274. obuIdStr: formatCardNumber(data.serialNumber),
  275. cardIdStr: formatCardNumber(data.faceCardNum),
  276. })
  277. },
  278. // 配置搜索失败
  279. configSearchFail(code) {
  280. let failMsg = "请检查手机蓝牙、ETC蓝牙是否均已打开,连接过程中将手机和ETC设备尽量靠近"
  281. let failTitle = "未检测到ETC设备"
  282. if (code == -111 || code == -112) {
  283. failMsg = code == -111 ? "手机蓝牙权限未授权,无法读取蓝牙是否开启状态,请打开蓝牙" : "手机定位权限获取失败,请前往手机系统设置开启手机定位服务"
  284. failTitle = "蓝牙状态异常"
  285. }
  286. this.setData({
  287. showType: 2,
  288. searchFailMsg: failMsg,
  289. searchFailTitle: failTitle,
  290. })
  291. },
  292. tapActiveFailSure() {
  293. failPluginData(this.data.activeFailMsg);
  294. this.setData({
  295. activeFail: false,
  296. });
  297. wx.navigateBack()
  298. },
  299. // 获取Obu设备详情
  300. async getObjDetail() {
  301. let cmdArr = [HOME_DIRECTORY, OBU_SYSTEM_FILE, RANDOM_NUMBER]
  302. let res = await transCmd(cmdArr, '20')
  303. console.log('设备卡签信息:1111')
  304. console.log(res)
  305. let cmdResult = res.cmdResult ? res.cmdResult.split(',') : []
  306. if (cmdResult && cmdResult.length) {
  307. var status = cmdResult[1].substring(cmdResult[1].length - 4, cmdResult[1].length);
  308. //第一次获取随机数
  309. if (status == "9000") {
  310. this.data.obuInfo.obuId = cmdResult[1].substring(20, 36);
  311. this.data.obuInfo.version = cmdResult[1].substring(18, 20);
  312. this.data.obuInfo.chipSn = cmdResult[1].substring(0, 8)
  313. console.log(this.data.obuInfo)
  314. } else {
  315. wx.showToast('获取设备信息错误!')
  316. }
  317. } else {
  318. wx.showToast('获取设备信息错误!')
  319. }
  320. return true
  321. },
  322. // 获取卡信息
  323. async getCardId() {
  324. let cmdArr = [HOME_DIRECTORY, APPLICATION_DIRECTORY, CMD_READBINARY, CMD_GETBALANCE];
  325. let res = await transCmd(cmdArr, '10')
  326. let cmdResult = res.cmdResult ? res.cmdResult.split(',') : []
  327. let str = cmdResult[2].substring(cmdResult[2].length - 4, cmdResult[2].length); //判断是否为9000
  328. let str3 = cmdResult[3].substring(cmdResult[3].length - 4, cmdResult[3].length); //判断是否为9000
  329. if (str == "9000" || str3 == "9000") {
  330. if (cmdResult[2].length > 86 || cmdResult[3] >= 12) {
  331. this.data.cardInfo.cardId = cmdResult[2].substring(20, 40);
  332. this.data.cardInfo.version = cmdResult[2].substring(18, 20)
  333. console.log(this.data.cardInfo)
  334. } else {
  335. wx.showModal({
  336. title: '提示',
  337. content: "CMD_READBINARY指令长度不符" + cmdResult
  338. })
  339. }
  340. return;
  341. } else {
  342. return true
  343. }
  344. return true
  345. },
  346. // 设备升级
  347. async devideUpgrade() {
  348. return new Promise(async resolve => {
  349. let params = {
  350. contractSN: this.data.obuInfo.obuId, //OBU合同序列号 16位
  351. chipSn: this.data.obuInfo.chipSn, //OBU晶片序列号 8位
  352. issueMode: 'UPG', //发行模式
  353. issueType: 'SCOBU', //发行发行类型
  354. cardVersion: this.data.cardInfo.version, //卡版本号
  355. obuVersion: this.data.obuInfo.version //OBU版本号
  356. }
  357. let applyData = await API.ETC.getVfjApply4Upgrade(params)
  358. console.log('9999 获取设备升级指令')
  359. console.log(applyData)
  360. if (!applyData || (applyData && applyData.code !== 0)) {
  361. // this.showModals('获取升级指令失败')
  362. return false
  363. }
  364. let applyDataRes = applyData.data
  365. if (this.data.obuInfo.version == '48' || this.data.obuInfo.version == '49') {
  366. const updateEsDat = await this.updateEs('GEN_OBEIC_UPG', applyDataRes);
  367. if (!updateEsDat) return false;
  368. }
  369. if (this.data.cardInfo.version == '48' || this.data.cardInfo.version == '49') {
  370. const updateEsDatTwo = await this.updateEs('GEN_OBESAM_UPG', applyDataRes);
  371. if (!updateEsDatTwo) return false;
  372. }
  373. const upgradeDoneData = await API.ETC.vfjUpgradeDone({
  374. issueSerialNo: applyDataRes.issueSerialNo, //发行订单号
  375. });
  376. if (!upgradeDoneData || (upgradeDoneData && upgradeDoneData.code !== 0)) return false;
  377. // 升级完成后完成后重新写入
  378. const cardres = await this.getCardIdAfter();
  379. if (!cardres) return false;
  380. const obures = await this.getObuIdAfter();
  381. if (!obures) return false;
  382. resolve(true)
  383. })
  384. // wx.showModal({
  385. // title: '提示',
  386. // content: '设备升级完成',
  387. // showCancel: false,
  388. // complete: (res) => {
  389. // if (res.confirm) {
  390. // wx.navigateBack()
  391. // }
  392. // }
  393. // })
  394. },
  395. // 获取发行指令脚本
  396. async updateEs(type, applyData) {
  397. wx.showLoading({
  398. title: '设备升级中'
  399. })
  400. let getCommanData = await API.ETC.getVfjGetCommands({
  401. cardNo: applyData.cardNo, //卡片序列号
  402. wareId: type, //OBU的物料代码 OBE-SAM通道 GEN_OBESAM_UPG OBE-IC通道 GEN_OBEIC_UPG
  403. issueSerialNo: applyData.issueSerialNo, //发行订单号
  404. })
  405. if (!getCommanData || (getCommanData && getCommanData.code !== 0)) {
  406. // this.showModals('获取发行脚本指令失败')
  407. return false
  408. };
  409. let getCommanDataRes = getCommanData.data
  410. //指令解析
  411. const result = getCommanDataRes.commands;
  412. const array = result.split('~');
  413. let cmdType = type == 'GEN_OBESAM_UPG' ? '20' : '10';
  414. for (const element of array) {
  415. console.log('updateEs', element, cmdType);
  416. // 让出主线程,确保UI更新
  417. await new Promise(resolve => setTimeout(resolve, 0));
  418. console.log("进来了", element.charAt(0), )
  419. if (element.charAt(0) === 'D' || element.charAt(0) === 'R') {
  420. await this.processDirectCommand(element, cmdType);
  421. } else if (element.charAt(0) === 'K') {
  422. await this.processKeyExchange(element, cmdType, applyData);
  423. } else if (element.charAt(0) === 'E') {
  424. await this.processExtAuth(element, cmdType, applyData);
  425. } else if (element === 'SESAM') {
  426. cmdType = '20';
  427. } else {
  428. cmdType = '10';
  429. }
  430. }
  431. return true;
  432. },
  433. processDirectCommand(element, cmdType) {
  434. // 添加随机延迟,避免连续请求
  435. return transCmdArrAfter(element.substring(1), cmdType);
  436. },
  437. async processKeyExchange(element, cmdType, applyData) {
  438. const ranData = await transCmdArrAfter('0084000004', cmdType);
  439. console.log("ranData", ranData)
  440. const exchangeKeyData = await API.ETC.vfjExchangeKey({
  441. key: element.substring(1),
  442. random: ranData['0084000004'][0].substring(0, 8),
  443. issueSerialNo: applyData.issueSerialNo
  444. });
  445. if (!exchangeKeyData) throw new Error('密钥置换失败');
  446. console.log("exchangeKeyData", exchangeKeyData)
  447. let exchangeKeyDataRes = exchangeKeyData.data
  448. return transCmdArrAfter(exchangeKeyDataRes.apdu, cmdType);
  449. },
  450. async processExtAuth(element, cmdType, applyData) {
  451. const ranData = await transCmdArrAfter('0084000004', cmdType);
  452. const extAuth4IssData = await API.ETC.vfjExtAuth4Iss({
  453. keyType: element.substring(1),
  454. random: ranData['0084000004'][0].substring(0, 8),
  455. issueSerialNo: applyData.issueSerialNo,
  456. });
  457. console.log("extAuth4IssData", extAuth4IssData)
  458. if (!extAuth4IssData) throw new Error('外部认证失败');
  459. let extAuth4IssDataRes = extAuth4IssData.data
  460. return transCmdArrAfter(extAuth4IssDataRes.apdu, cmdType);
  461. },
  462. // 读卡
  463. async getCardIdAfter() {
  464. return new Promise(async (resolve, reject) => {
  465. try {
  466. let cmdArr = [HOME_DIRECTORY, APPLICATION_DIRECTORY, CMD_READBINARY, CMD_GETBALANCE];
  467. const res = await transCmdAfter(cmdArr, "10");
  468. let cmdResult = res.cmdResult ? res.cmdResult.split(',') : []
  469. let str = cmdResult[2].substring(cmdResult[2].length - 4, cmdResult[2].length); //判断是否为9000
  470. let str3 = cmdResult[3].substring(cmdResult[3].length - 4, cmdResult[3].length); //判断是否为9000
  471. if (str == "9000" || str3 == "9000") {
  472. if (cmdResult[2].length > 86 || cmdResult[3] >= 12) {
  473. // card.cardId = cmdResult[2].substring(20, 40);
  474. // card.cardId = '52012511110201724155';
  475. this.data.cardInfo.cardId = cmdResult[2].substring(20, 40);
  476. this.data.cardInfo.version = cmdResult[2].substring(18, 20);
  477. console.log(9999999)
  478. console.log(this.data.cardInfo)
  479. wx.hideLoading()
  480. resolve(true);
  481. return
  482. } else {
  483. console.log("CMD_READBINARY指令长度不符" + cmdResult[2]);
  484. this.showModals("CMD_READBINARY指令长度不符" + cmdResult[2])
  485. resolve(false);
  486. return
  487. }
  488. }
  489. console.log("CMD_READBINARY指令长度不符" + cmdResult[2]);
  490. this.showModals("CMD_READBINARY指令长度不符" + cmdResult[2])
  491. resolve(false);
  492. return
  493. } catch (e) {
  494. //TODO handle the exception
  495. console.log('错误错误', e);
  496. reject(e);
  497. }
  498. })
  499. },
  500. // 读取签
  501. getObuIdAfter() {
  502. return new Promise(async (resolve, reject) => {
  503. try {
  504. let cmdArray = [HOME_DIRECTORY, OBU_SYSTEM_FILE, RANDOM_NUMBER];
  505. const res = await transCmdAfter(cmdArray, "20");
  506. let cmdResult = res.cmdResult ? res.cmdResult.split(',') : []
  507. var status = cmdResult[1].substring(cmdResult[1].length - 4, cmdResult[1].length);
  508. console.log('获取OBU号执行结果' + status, cmdResult)
  509. //第一次获取随机数
  510. if (status == "9000") {
  511. this.data.obuInfo.obuId = cmdResult[1].substring(20, 36);
  512. this.data.obuInfo.version = cmdResult[1].substring(18, 20);
  513. this.data.obuInfo.chipSn = cmdResult[1].substring(0, 8)
  514. resolve(true);
  515. console.log("success")
  516. return
  517. } else {
  518. this.showModals('获取设备信息错误!')
  519. resolve(false);
  520. return
  521. }
  522. } catch (e) {
  523. //TODO handle the exception
  524. console.log('错误错误', e);
  525. reject(e);
  526. }
  527. })
  528. },
  529. showModals(content) {
  530. wx.showModal({
  531. title: '提示',
  532. content: content,
  533. showCancel: false
  534. })
  535. },
  536. })