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.

activeDesIn.js 15KB

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