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.

flowingWater.vue 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. <template>
  2. <view class="wrapper" v-if="state.haveData">
  3. <!-- 背景颜色充满屏 -->
  4. <view class="bg-color"></view>
  5. <!-- 补卡额订单列表-->
  6. <view class="list-wrap">
  7. <view class="card-info" v-for="(item,index) in state.list" :key="item.id">
  8. <view class="info-wrap">
  9. <view class="info-left">
  10. <view class="info-left-text">
  11. <text class="label">车牌号:</text>
  12. <text class="val">{{item.vehiclePlate}}</text>
  13. </view>
  14. <!-- <view class="info-left-text">
  15. <text class="label">补卡额单号:</text>
  16. <text class="val">{{item.supplyId}}</text>
  17. </view> -->
  18. <view>
  19. <text class="label">ETC卡号:</text>
  20. <text class="val">{{item.cardId}}</text>
  21. </view>
  22. </view>
  23. <view class="info-right">
  24. <view class="price-label">
  25. 交易金额
  26. </view>
  27. <view class="price-val">
  28. <u-icon name="rmb"></u-icon>
  29. <text class="price-val-text">{{item.cardBalance/100}}</text>
  30. </view>
  31. </view>
  32. </view>
  33. <!-- <view class="card-text-wrap">
  34. <view class="text-box">
  35. <text class="name-text">贵阳西</text>
  36. <text class="time-text">12:09</text>
  37. <text class="date-text">2023-01-08</text>
  38. </view>
  39. <view class="arrow-wrap">
  40. <text class="arrow-text">粤A12345</text>
  41. <image class="d-img" :src="`${$imgUrl}order/arrowCard.png`"></image>
  42. </view>
  43. <view class="text-box">
  44. <text class="name-text">XXXXX</text>
  45. <text class="time-text">18:52</text>
  46. <text class="date-text">2023-01-08</text>
  47. </view>
  48. </view> -->
  49. <view class="btn-wrap">
  50. <view>
  51. <text v-if="item.status === 1" class="status-wrap">审核进度:<text>已进行</text></text>
  52. <text v-if="item.status === 2" class="status-wrap">审核进度:<text
  53. class="status-text">未进行</text></text>
  54. <text v-if="item.status === -1" class="status-wrap">审核进度:<text>驳回</text></text>
  55. <text v-if="item.status === 3" class="status-wrap">审核进度:<text>待审核</text></text>
  56. </view>
  57. <view class="btn-1 btn" v-if="item.status === 2" @click="refundTypeAction(item)">圈存</view>
  58. <!-- <view class="btn-1 btn" v-if="item.status === 1" @click="toApply(item)">补卡额申请</view>
  59. <view class="btn-1 btn" v-if="item.status === 2" @click="toView(item)">查看进度</view>
  60. <view class="btn-1 btn" v-if="item.status === 3" @click="toEvaluate(item)">去评价</view> -->
  61. </view>
  62. </view>
  63. </view>
  64. </view>
  65. <view class="no">暂无补卡额圈存数据</view>
  66. </template>
  67. <script lang="ts" setup>
  68. import { reactive, ref } from "vue";
  69. import { onLoad, onUnload } from "@dcloudio/uni-app";
  70. import { request } from "@/utils/network/request.js";
  71. import { queryCardLimit, quanCheck, quanApply, quanConfirm, quanXf } from "@/utils/network/api";
  72. import { stringToJson } from "@/utils/network/encryption";
  73. import { msg } from "@/utils/utils";
  74. const cmd = require("../../static/etcUtil/cmdConfig.js");
  75. const tools = require("../../static/etcUtil/tools.js");
  76. const bluetoothUtil = require("../../static/etcUtil/index.js");
  77. import { navTo } from "@/utils/utils"
  78. const card = reactive({
  79. /*卡相关信息*/
  80. cardId: "",
  81. netId: "",
  82. cardType: "",
  83. startTime: "",
  84. endTime: "",
  85. userName: "",
  86. idNum: "",
  87. vehiclePlate: "",
  88. vehiclePlateColor: "",
  89. color: "",
  90. version: "",
  91. type: "",
  92. favourable: "",
  93. money: undefined,
  94. v_userType: "",
  95. });
  96. const show = ref(false);
  97. const dataTime = reactive({
  98. startDate: "",
  99. endDate: ""
  100. })
  101. const state = reactive({
  102. vehicleId: "",//车牌号
  103. id: "",
  104. list: "",
  105. cardBalance: "",
  106. haveData: false, //是否有数据
  107. })
  108. const listData = reactive(null)
  109. onLoad((options) => {
  110. state.vehicleId = options.vehicleId
  111. //根据车牌查询信息.data
  112. queryRefundAction().then(val => {
  113. console.log("val", val)
  114. if (val.data) {
  115. state.list = val.data
  116. state.haveData = true
  117. }
  118. })
  119. /*监听蓝牙回调*/
  120. uni.$on('bluetoothLink', function (status) {
  121. getCardId()
  122. })
  123. });
  124. onUnload(() => {
  125. /*移除监听*/
  126. uni.$off('bluetoothLink')
  127. });
  128. // 补卡额列表查询接口
  129. const queryRefundAction = () => {
  130. const options = {
  131. type: 2,
  132. data: {
  133. "vehicleId": state.vehicleId,
  134. "systemType": "WX"
  135. },
  136. method: "POST",
  137. showLoading: true,
  138. };
  139. return new Promise(async (resolve, reject) => {
  140. const res = await request(queryCardLimit, options);
  141. const data = stringToJson(res.bizContent);
  142. console.log("储值卡注销退费查询接口", data)
  143. resolve(data);
  144. }).catch((error) => {
  145. reject(error);
  146. });
  147. };
  148. // 日期修改
  149. function changeHandle(e) {
  150. dataTime.startDate = e.startDate;
  151. dataTime.endDate = e.endDate;
  152. }
  153. // 补卡申请
  154. function toApply(item) {
  155. uni.navigateTo({
  156. url: `/subpackage/orders/cardAmount?id=${item.id}`
  157. });
  158. }
  159. // 去评价
  160. function toEvaluate(item) {
  161. uni.navigateTo({
  162. url: `/subpackage/orders/order-evaluate?id=${item.id}`
  163. });
  164. }
  165. // 查看进度
  166. function toView(item) {
  167. uni.navigateTo({
  168. url: `/subpackage/orders/cardAmountDetail?id=${item.id}`
  169. });
  170. }
  171. // 去圈存
  172. //功能跳转入口
  173. const refundTypeAction = (val : any) => {
  174. /*圈存*/
  175. //链接蓝牙
  176. console.log("val.id", val.id)
  177. state.id = val.id;
  178. state.cardBalance = val.cardBalance
  179. uni.navigateTo({
  180. url: `/pages/bluetooth/bluetooth?routeType=5`,
  181. });
  182. }
  183. /*读卡*/
  184. const getCardId = () => {
  185. console.log("======获取卡信息======");
  186. let cmdArr = [
  187. cmd.HOME_DIRECTORY,
  188. //选择主目
  189. cmd.APPLICATION_DIRECTORY,
  190. //选择文件1001--DF01联网收费应用目录
  191. cmd.CMD_READBINARY,
  192. //15文件--卡片发行基本数据文件
  193. cmd.CMD_GETBALANCE,
  194. //钱包
  195. ];
  196. tools.showLoadingAlert("正在执行指令");
  197. //10:写卡 20:写OBU
  198. bluetoothUtil.transCmd(cmdArr, "10", function (res) {
  199. tools.hideLoadingAlert();
  200. let str = res[2].substring(res[2].length - 4, res[2].length);
  201. let str3 = res[3].substring(res[3].length - 4, res[3].length);
  202. if (str == "9000" || str3 == "9000") {
  203. if (res[2].length > 86 || res[3] >= 12) {
  204. card.cardId = res[2].substring(20, 40); //卡号
  205. card.startTime = res[2].substring(40, 48);
  206. card.endTime = res[2].substring(48, 56);
  207. card.version = res[2].substring(18, 19) >= 4 ? "4x" : "2x";
  208. card.netId = res[2].substring(20, 24);
  209. card.cardType = res[2].substring(28, 29) == 23 ? 1 : 2;
  210. card.vehiclePlateColor = parseInt(res[2].substring(82, 84), 16);
  211. (card.money = parseInt(parseInt(res[3].substring(0, 8), 16), 10)),
  212. console.log("======卡信息======", card);
  213. quanCheckActionTrue().then((val) => {
  214. checkQuanCengEvent(val);
  215. });
  216. } else {
  217. console.error("CMD_READBINARY指令长度不符" + res[2]);
  218. tools.hideLoadingAlert();
  219. }
  220. }
  221. console.error("CMD_READBINARY指令长度不符" + res[2]);
  222. tools.hideLoadingAlert();
  223. });
  224. };
  225. const quanCheckActionTrue = () => {
  226. console.log("进行真实圈存检测");
  227. var data = {
  228. cardId: card.cardId,
  229. orderId: state.id,
  230. preBalance: card.money,
  231. fee: state.cardBalance,
  232. tradeType: 5,
  233. };
  234. const options = {
  235. type: 2,
  236. data: data,
  237. method: "POST",
  238. showLoading: true,
  239. };
  240. return new Promise(async (resolve, reject) => {
  241. const res = await request(quanCheck, options);
  242. const data = stringToJson(res.bizContent);
  243. resolve(data);
  244. }).catch((error) => {
  245. reject(error);
  246. });
  247. };
  248. const checkQuanCengEvent = (val : any) => {
  249. if (val.chargeStatus === 1) {
  250. let cmdArr = val.command.split(",");
  251. uni.showLoading({
  252. title: "写入中",
  253. });
  254. bluetoothUtil.transCmd(cmdArr, "10", function (res) {
  255. let response = res.toString();
  256. var dic = {
  257. command: val.command,
  258. cosResponse: response,
  259. };
  260. uni.hideLoading();
  261. quanApplyAction(dic).then((value) => {
  262. console.log("圈存申请完后的结果");
  263. console.log(value);
  264. //圈存初始化验证通过 , 进行圈存
  265. if (value.commandType === 2) {
  266. uanConfirmAction(value).then((confirmResult) => {
  267. navTo(
  268. `/subpackage/after-sale/refund-order-balance/result`)
  269. });
  270. } else {
  271. msg("圈存初始化指令验证失败, 重新初始化");
  272. }
  273. });
  274. });
  275. } else {
  276. let cmdArr = val.command.split(",");
  277. uni.showLoading({
  278. title: "写入中",
  279. });
  280. bluetoothUtil.transCmd(cmdArr, "10", function (res) {
  281. var status = res[1].substring(res[1].length - 4, res[1].length);
  282. console.log("打印状态");
  283. console.log(status);
  284. if (status === "9000") {
  285. console.log("修复指令入参");
  286. let response = res.toString();
  287. var dic = {
  288. command: val.command,
  289. cosResponse: response,
  290. rechargeId: val.rechargeId,
  291. };
  292. quanFixAction(dic).then((value) => {
  293. console.log(value);
  294. console.log("修复结果返回");
  295. var fixStatus = value.fixStatus;
  296. //圈存修复COS指令Response信息不足,重新进行修复初始化
  297. if (fixStatus === 3) {
  298. let xfcmdArr = value.command.split(",");
  299. bluetoothUtil.transCmd(xfcmdArr, "10", function (resValueData) {
  300. var status = resValueData[1].substring(
  301. resValueData[1].length - 4,
  302. resValueData[1].length
  303. );
  304. console.log("打印状态");
  305. console.log(status);
  306. if (status === "9000") {
  307. console.log(resValueData);
  308. var valueResponse = resValueData.toString();
  309. console.log(response);
  310. var applyDic = {
  311. command: value.command,
  312. cosResponse: valueResponse,
  313. rechargeId: value.rechargeId,
  314. };
  315. console.log("消费成功");
  316. quanApplyAction(applyDic).then((applyValue) => {
  317. uanConfirmAction(applyValue).then((
  318. confirmResult) => {
  319. navTo(
  320. `/subpackage/orders/flowingWater-result`)
  321. });
  322. });
  323. }
  324. });
  325. } else if (fixStatus === 2) {
  326. uanConfirmSucessAction(value).then((confirmResult) => {
  327. navTo(
  328. `/subpackage/orders/flowingWater-result`)
  329. });
  330. } else if (fixStatus === 1) {
  331. quanCheckActionTrue().then((val) => {
  332. checkQuanCengEvent(val);
  333. });
  334. }
  335. });
  336. uni.hideLoading();
  337. }
  338. });
  339. }
  340. };
  341. /*圈存申请*/
  342. const quanApplyAction = (data) => {
  343. var form = {
  344. cardId: card.cardId,
  345. tradeType: 5,
  346. command: data.command,
  347. cosResponse: data.cosResponse,
  348. orderId: state.id,
  349. rechargeId: data.rechargeId,
  350. fee: state.cardBalance,
  351. preBalance: card.money,
  352. };
  353. const options = {
  354. type: 2,
  355. data: form,
  356. method: "POST",
  357. showLoading: true,
  358. };
  359. return new Promise(async (resolve, reject) => {
  360. console.log("70", options)
  361. const res = await request(quanApply, options);
  362. const data = stringToJson(res.bizContent);
  363. resolve(data);
  364. }).catch((error) => {
  365. reject(error);
  366. });
  367. };
  368. /*圈存确认*/
  369. const uanConfirmAction = (data) => {
  370. console.log("圈存确认进入");
  371. let cmdArr = data.command.split(",");
  372. console.log(cmdArr);
  373. bluetoothUtil.transCmd(cmdArr, "10", function (res) {
  374. console.log("圈存透传");
  375. console.log(res);
  376. var arraylenth = res.length;
  377. var status = res[arraylenth - 1].substring(
  378. res[arraylenth - 1].length - 4,
  379. res[arraylenth - 1].length
  380. );
  381. console.log("打印圈存确认指令状态");
  382. console.log(status);
  383. if (status === "9000") {
  384. var form = {
  385. command: data.command,
  386. cosResponse: res.toString(),
  387. rechargeId: data.rechargeId,
  388. paidAmount: data.fee,
  389. giftAmount: 0,
  390. };
  391. const options = {
  392. type: 2,
  393. data: form,
  394. method: "POST",
  395. showLoading: true,
  396. };
  397. return new Promise(async (resolve, reject) => {
  398. console.log("实收金额报错", options)
  399. const res = await request(quanConfirm, options);
  400. const data = stringToJson(res.bizContent);
  401. resolve(data);
  402. }).catch((error) => {
  403. reject(error);
  404. });
  405. }
  406. });
  407. };
  408. const uanConfirmSucessAction = (data) => {
  409. var form = {
  410. command: data.command,
  411. cosResponse: "9000",
  412. rechargeId: data.rechargeId,
  413. paidAmount: data.fee,
  414. giftAmount: 0,
  415. };
  416. const options = {
  417. type: 2,
  418. data: form,
  419. method: "POST",
  420. showLoading: true,
  421. };
  422. return new Promise(async (resolve, reject) => {
  423. const res = await request(quanConfirm, options);
  424. const data = stringToJson(res.bizContent);
  425. resolve(data);
  426. }).catch((error) => {
  427. reject(error);
  428. });
  429. };
  430. /*圈存修复*/
  431. const quanFixAction = (val) => {
  432. var data = {
  433. command: val.command, //修复初始化的指令
  434. cosResponse: val.cosResponse, //修复初始化结果
  435. rechargeId: val.rechargeId, //充值流水号
  436. };
  437. const options = {
  438. type: 2,
  439. data: data,
  440. method: "POST",
  441. showLoading: true,
  442. };
  443. return new Promise(async (resolve, reject) => {
  444. const res = await request(quanXf, options);
  445. const data = stringToJson(res.bizContent);
  446. resolve(data);
  447. }).catch((error) => {
  448. reject(error);
  449. });
  450. };
  451. </script>
  452. <style lang="scss" scoped>
  453. .no {
  454. text-align: center;
  455. font-size: 32rpx;
  456. margin: 20rpx auto;
  457. }
  458. .bg-color {
  459. position: fixed;
  460. top: 0;
  461. left: 0;
  462. right: 0;
  463. bottom: 0;
  464. background: #EEF7F7;
  465. z-index: -1;
  466. }
  467. .search-box {
  468. margin: 30rpx 30rpx 20rpx 30rpx;
  469. height: 72rpx;
  470. height: 81rpx;
  471. background: #FFFFFF;
  472. border: 1px solid #DCDCDC;
  473. border-radius: 40rpx;
  474. display: flex;
  475. justify-content: center;
  476. align-items: center;
  477. box-sizing: border-box;
  478. }
  479. .search-box .icon {
  480. width: 48rpx;
  481. height: 48rpx;
  482. margin: 0 20rpx;
  483. }
  484. .search-box .search {
  485. flex: 1;
  486. margin-right: 20rpx;
  487. height: 100%;
  488. padding: 0 10rpx;
  489. font-size: 28rpx;
  490. color: #00b38b;
  491. }
  492. .scroll-view {
  493. white-space: nowrap;
  494. position: sticky;
  495. top: 0;
  496. background: #ffffff;
  497. box-shadow: 0rpx 2rpx 6rpx 0rpx rgba(223, 223, 223, 0.8);
  498. }
  499. .search-time {
  500. // width: 100%;
  501. display: flex;
  502. padding: 10rpx 30rpx 30rpx;
  503. .search-time-box {
  504. flex: 1;
  505. }
  506. .time-btn {
  507. width: 130rpx;
  508. height: 80rpx;
  509. background: #00B38B;
  510. border-radius: 40rpx;
  511. color: #FFFFFF;
  512. font-size: 32rpx;
  513. line-height: 80rpx;
  514. text-align: center;
  515. margin-left: 20rpx;
  516. }
  517. .show-info {
  518. // width: 541rpx;
  519. width: 85%;
  520. height: 81rpx;
  521. padding: 0 31rpx;
  522. background: #FFFFFF;
  523. border: 1px solid #DCDCDC;
  524. border-radius: 40rpx;
  525. display: flex;
  526. justify-content: space-between;
  527. align-items: center;
  528. .show-text {
  529. display: flex;
  530. align-items: center;
  531. }
  532. .date-text {
  533. color: #999999;
  534. font-size: 28rpx;
  535. }
  536. .text-val {
  537. color: #333
  538. }
  539. .line {
  540. width: 25rpx;
  541. height: 1rpx;
  542. background: #999999;
  543. margin: 0 24rpx;
  544. }
  545. }
  546. }
  547. .total-num {
  548. font-size: 28rpx;
  549. color: #999999;
  550. margin-left: 30rpx;
  551. }
  552. .list-wrap {
  553. margin: 30rpx;
  554. padding-bottom: 20rpx;
  555. }
  556. .card-info {
  557. background: #FFFFFF;
  558. box-shadow: 0rpx 2rpx 6rpx 0rpx rgba(223, 223, 223, 0.8);
  559. border-radius: 20rpx;
  560. margin-bottom: 30rpx;
  561. padding: 30rpx 30px 13rpx 30rpx;
  562. .info-wrap {
  563. display: flex;
  564. justify-content: space-between;
  565. align-items: center;
  566. border-bottom: 1px solid #dcdcdc;
  567. padding-bottom: 30rpx;
  568. .info-left-text {
  569. margin-bottom: 20rpx;
  570. }
  571. .label {
  572. color: #999999;
  573. font-size: 26rpx;
  574. font-weight: 400;
  575. }
  576. .val {
  577. color: #333333;
  578. font-size: 26rpx;
  579. font-weight: 400;
  580. }
  581. .price-label {
  582. color: #999999;
  583. font-size: 24rpx;
  584. font-weight: 400;
  585. margin-bottom: 22rpx;
  586. text-align: center;
  587. }
  588. .price-val-text {
  589. font-size: 36rpx;
  590. font-weight: 700;
  591. color: #333333;
  592. margin-left: 9rpx;
  593. }
  594. .price-val {
  595. font-size: 26rpx;
  596. color: #333333;
  597. }
  598. }
  599. .card-text-wrap {
  600. display: flex;
  601. justify-content: space-between;
  602. align-items: center;
  603. margin: 38rpx 0 46rpx 0;
  604. .text-box {
  605. display: flex;
  606. flex-direction: column;
  607. align-items: center;
  608. .name-text {
  609. font-size: 30rpx;
  610. font-weight: 400;
  611. color: #333333;
  612. }
  613. .time-text {
  614. font-size: 30rpx;
  615. color: #333333;
  616. font-weight: 400;
  617. margin-top: 8rpx;
  618. }
  619. .date-text {
  620. font-size: 24rpx;
  621. color: #999999;
  622. font-weight: 400;
  623. margin-top: 8rpx;
  624. }
  625. }
  626. .arrow-wrap {
  627. display: flex;
  628. flex-direction: column;
  629. align-items: center;
  630. .d-img {
  631. width: 186rpx;
  632. height: 12rpx;
  633. }
  634. .arrow-text {
  635. color: #666666;
  636. font-size: 26rpx;
  637. }
  638. }
  639. }
  640. .btn-wrap {
  641. margin-top: 30rpx;
  642. display: flex;
  643. justify-content: space-between;
  644. align-items: center;
  645. .status-wrap {
  646. color: #999999;
  647. font-size: 26rpx;
  648. margin-right: 23rpx;
  649. }
  650. .status-text {
  651. color: #00B38B;
  652. }
  653. .btn {
  654. background: #FFFFFF;
  655. border: 1px solid #00B38B;
  656. border-radius: 30rpx;
  657. line-height: 50rpx;
  658. text-align: center;
  659. color: #00B38B;
  660. font-size: 26rpx;
  661. }
  662. .btn-1 {
  663. width: 140rpx;
  664. height: 50rpx;
  665. }
  666. .btn-2 {
  667. width: 141rpx;
  668. height: 50rpx;
  669. }
  670. .btn-3 {
  671. width: 121rpx;
  672. height: 50rpx;
  673. }
  674. }
  675. }
  676. </style>