checkApp.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. <template>
  2. <view class="page" :style="{'min-height':(h)+'px','padding-top':mt+'px'}">
  3. <c-nav-bar title="核销" @goBack="back()"></c-nav-bar>
  4. <view class="types">
  5. <view class="item bg2" @tap="scanCode(0)">
  6. <view class="n">扫码核销</view>
  7. <u-icon name="arrow-right" color="#fff" size="26" label="点击扫描" label-color="#fff" label-size="32" cu
  8. label-pos="left"></u-icon>
  9. </view>
  10. <view class="item bg1" @tap="scanCode(1)">
  11. <view class="n">扫身份证核销</view>
  12. <u-icon name="arrow-right" color="#fff" size="26" label="点击扫描" label-color="#fff" label-size="32"
  13. label-pos="left"></u-icon>
  14. </view>
  15. </view>
  16. <view class="orderInfo">
  17. <view class="tit">
  18. 订单详情
  19. </view>
  20. <view class="time">{{orderInfo.playDate}} {{orderInfo.playTime}}出发</view>
  21. <view class="bottom">
  22. <text>{{orderInfo.num}}人</text>
  23. <text>出游·{{orderInfo.playLength||0}}小时</text>
  24. <text>¥{{orderInfo.realPrice}}</text>
  25. </view>
  26. </view>
  27. <view class="list">
  28. <view class="tit">{{boatNo}} 共({{data.length}})人</view>
  29. <view class="item" v-for="(i,index) in data" :key="index">
  30. <text class="type" :class="i.remark=='book'?'t1':'t2'">{{i.remark=='book'?'预订单':'现场单'}}</text>
  31. <view class="personInfo">
  32. <view class="name">{{i.touristName|handle(1)}}</view>
  33. <view class="code">
  34. 身份证 {{i.touristCode|handle(3)}}
  35. </view>
  36. <view style="display: flex;justify-content: flex-start;padding: 8rpx 0;">
  37. <view v-if="i.touristJpg.length!=0" >已补充证件照片
  38. <span @click="view(i.touristJpg)" style="background-color: #007A69;color: #007A69;color: #fff;display: inline-block;border-radius: 12rpx;padding: 4rpx 12rpx;margin-right: 8rpx;">查看</span>
  39. </view>
  40. <view v-if="i.touristType==1" @click="idCardUpload(i,index)" style="background-color: #007A69;color: #007A69;color: #fff;display: inline-block;border-radius: 12rpx;padding: 4rpx 12rpx;">
  41. {{i.touristJpg.length!=0?'重新上传':'补充证件照片'}}
  42. </view>
  43. </view>
  44. </view>
  45. <u-icon name="minus-circle" size="36" color="#FEA400" @tap="jian(index)"
  46. ></u-icon>
  47. </view>
  48. </view>
  49. <view class="list">
  50. <view class="tit">选择渔船</view>
  51. <view class="typeItem">
  52. <view class="txt" v-for="(t,i) in types" :key="i" @click="typeIndex=i" :class="typeIndex==i?'on':''">
  53. {{t.boatNo}}
  54. <image v-if="typeIndex==i"
  55. src="https://fsy.shengsi.gov.cn/file/20240320/b458b03f8f654a51a921656b8aa955de.png"></image>
  56. </view>
  57. </view>
  58. </view>
  59. <view class="btn">
  60. <text @click="hexiao">开始发船</text>
  61. </view>
  62. </view>
  63. </template>
  64. <script>
  65. import {
  66. encrypt,
  67. decrypt,
  68. tuomin
  69. } from '../../utils/aes.js'
  70. var that;
  71. const lcReader = uni.requireNativePlugin('LcReader');
  72. const modal = uni.requireNativePlugin('modal');
  73. var globalEvent = uni.requireNativePlugin('globalEvent');
  74. // 依赖引入
  75. const Intent = plus.android.importClass('android.content.Intent')
  76. const IntentFilter = plus.android.importClass('android.content.IntentFilter')
  77. const main = plus.android.runtimeMainActivity()
  78. // // pda广播名称
  79. const SCANACTION = "scan.rcv.message"//扫描名称
  80. export default {
  81. data() {
  82. return {
  83. typeIndex: null,
  84. types: [],
  85. date: new Date().Format('yyyy-MM-dd'),
  86. show: false,
  87. data: [],
  88. merchantId: uni.getStorageSync('merchantId'),
  89. playTime: '',
  90. boatNo: '',
  91. type: '',
  92. orderInfo: {},
  93. keyName: '',
  94. playDate:''
  95. }
  96. },
  97. onLoad(opt) {
  98. that = this;
  99. this.playTime = opt.playTime || '';
  100. this.boatNo = opt.boatNo || '';
  101. this.playDate = opt.playDate || '';
  102. this.getOrderInfo();
  103. this.getTypes();
  104. this.initSDK();
  105. globalEvent.addEventListener('readInfo', function(e) {
  106. if(e.Id&&e.Name) that.handleScanResult(e.Id,1,e.Name);
  107. });
  108. },
  109. filters: {
  110. handle(val, type) {
  111. return tuomin(val, type);
  112. }
  113. },
  114. destroyed() {
  115. this.keyName = this.orderInfo.playDate + this.orderInfo.playTime + this.boatNo;
  116. uni.setStorageSync(this.keyName, JSON.stringify(this.data));
  117. },
  118. methods: {
  119. view(item){
  120. uni.previewImage({
  121. urls:[item]
  122. })
  123. },
  124. idCardUpload(item,index) {
  125. console.log(item)
  126. uni.chooseImage({
  127. sourceType: ['camera'], //从相册选择
  128. success: chooseImageRes => {
  129. const tempFilePaths = chooseImageRes.tempFilePaths;
  130. uni.uploadFile({
  131. url: 'https://fsy.shengsi.gov.cn/island-cloud-server/oss/file/aliyunUpload', // 仅为示例,非真实的接口地址
  132. filePath: tempFilePaths[0],
  133. name: 'file',
  134. header: {
  135. token: wx.getStorageSync('access_token')
  136. },
  137. success: res => {
  138. // uploadFile上传成功后,根据和后台的约定msgCode判断接口调用状态
  139. let data = JSON.parse(res.data);
  140. this.data[index].touristJpg = data.data.url
  141. }
  142. });
  143. },
  144. fail: err => {
  145. this.myToast('图片上传失败', 'none');
  146. }
  147. });
  148. },
  149. initSDK() {
  150. // 调用异步方法
  151. lcReader.initSDK({
  152. 'name': 'unimp',
  153. 'age': 1
  154. });
  155. },
  156. getTypes() {
  157. this.$api.get('/scenic/api/boat/page?sailFlag=0&merchantId='+this.merchantId, {
  158. page: -1
  159. }).then(res => {
  160. if (res.data.code == 0) {
  161. this.types = res.data.data.list;
  162. }
  163. })
  164. },
  165. getOrderInfo() {
  166. this.$api.post('/scenic/api/order/queryStartOrderInfo', {
  167. merchantId: this.merchantId,
  168. playDate:this.playDate,
  169. boatNo: this.boatNo
  170. }).then(res => {
  171. if (res.data.code == 0) {
  172. this.orderInfo = res.data.data;
  173. this.keyName = this.orderInfo.playDate + this.orderInfo.playTime + this.boatNo;
  174. if (uni.getStorageSync(this.keyName)) {
  175. this.data = JSON.parse(uni.getStorageSync(this.keyName)) || [];
  176. }
  177. }
  178. })
  179. },
  180. scanCode(type) {
  181. // let mg = '请按下按钮进行二维码扫描';
  182. if(type==1){
  183. this.$showToast('请放置身份证进行读取');
  184. lcReader.cycleReadCard();//循环读卡
  185. }
  186. if(type==0) this.scanCodeByEwm();
  187. },
  188. scanCodeByEwm(type) {
  189. uni.scanCode({
  190. onlyFromCamera: true,
  191. success: (res) => {
  192. console.log('扫码结果:' + res.result);
  193. // 扫码成功后的操作,例如:
  194. that.handleScanResult(res.result, 0, '');
  195. },
  196. fail: (err) => {
  197. console.error('扫码失败:' + err);
  198. }
  199. });
  200. },
  201. //扫二维码或条形码
  202. // scanCodeByEwm(){
  203. // var filter = new IntentFilter();
  204. // filter.addAction(SCANACTION);
  205. // // 接收
  206. // let that = this;
  207. // var receiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver', {
  208. // onReceive: (context, intent)=>{
  209. // if (intent.getAction() === SCANACTION) {
  210. // // 扫描信息处理
  211. // let scanCode = intent.getStringExtra("barcodeData");
  212. // // 接收信息处理
  213. // if(scanCode) that.handleScanResult(scanCode,0,'');
  214. // }
  215. // }
  216. // })
  217. // main.registerReceiver(receiver, filter);
  218. // },
  219. // 处理扫码结果的函数,可以根据实际需求进行扩展
  220. handleScanResult(result, type, name) {
  221. // 例如:导航到某个页面,或者处理其他业务逻辑
  222. let sendData = {};
  223. sendData.playDate = this.orderInfo.playDate;
  224. sendData.playTime = this.orderInfo.playTime;
  225. sendData.playLength = this.orderInfo.playLength || 1;
  226. sendData.merchantId = this.orderInfo.merchantId;
  227. sendData.orderType = this.orderInfo.orderType;
  228. sendData.type = type;
  229. sendData.boatNo = this.boatNo;
  230. if(type==0) sendData.writeOffCode = result;
  231. else if(type==1){
  232. sendData.touristCode = encrypt(result);
  233. sendData.touristName = encrypt(name);
  234. }
  235. this.$api.post('/scenic/api/order/scanCode', sendData).then(res => {
  236. if (res.data.code == 0) {
  237. if (this.data.findIndex((item) => {
  238. return item.touristCode == res.data.data.touristCode
  239. }) > -1) {
  240. let mg = '该核验码已扫';
  241. if(type==1) mg = '该身份证已扫';
  242. this.$showToast(mg);
  243. } else {
  244. if(type==1){
  245. res.data.data.touristType = 0
  246. res.data.data.touristJpg = ''
  247. this.data.push(res.data.data);
  248. }else{
  249. res.data.data.touristType = 1
  250. res.data.data.touristJpg = ''
  251. this.data.push(res.data.data);
  252. }
  253. // if(res.data.data.remark=='book'){
  254. // if(type==1){
  255. // res.data.data.touristType = 0
  256. // }else{
  257. // res.data.data.touristType = 1
  258. // }
  259. // this.data.push(res.data.data);
  260. // }else{
  261. // this.$showToast("非订单内游客身份证,无法核销");
  262. // }
  263. }
  264. if(type==1) lcReader.cancelCycle();//关闭循环读卡
  265. } else {
  266. this.$showToast(res.data.msg)
  267. if(type==1) lcReader.cancelCycle();//关闭循环读卡
  268. }
  269. })
  270. },
  271. check() {
  272. uni.navigateTo({
  273. url: '/pagesHouse/Verification/check'
  274. })
  275. },
  276. hexiao() {
  277. let that = this
  278. if (this.data.length == 0) {
  279. return this.$showToast('请选择核销人')
  280. }
  281. if (this.typeIndex == null) {
  282. return this.$showToast('请选择渔船')
  283. }
  284. let boatCode = this.types[this.typeIndex].boatNo;
  285. let newData = JSON.parse(JSON.stringify(this.data));
  286. newData.forEach(d=>{
  287. d.touristCode = encrypt(d.touristCode);
  288. d.touristName = encrypt(d.touristName);
  289. })
  290. uni.showModal({
  291. title: '提示',
  292. content: '确定该操作?',
  293. success: function(res) {
  294. if (res.confirm) {
  295. that.$api.post('/scenic/api/order/sailWriteOff', {
  296. playDate:that.orderInfo.playDate,
  297. playTime:that.orderInfo.playTime,
  298. playLength:that.orderInfo.playLength,
  299. orderType: that.orderInfo.orderType,
  300. orderCode:that.orderInfo.orderCode,
  301. merchantId:that.merchantId,
  302. touristList: newData,
  303. boatCode: boatCode
  304. }).then(res => {
  305. if (res.data.code == 0) {
  306. uni.navigateTo({
  307. url: "/pagesHouse/Verification/success?boatNo=" + that.boatNo + '&price=' +
  308. that.orderInfo.realPrice
  309. })
  310. }else that.$showToast(res.data.msg)
  311. })
  312. }
  313. }
  314. })
  315. uni.removeStorageSync(that.keyName);
  316. },
  317. jian(index){
  318. if(this.data.length>index) this.data.splice(index,1);
  319. }
  320. }
  321. }
  322. </script>
  323. <style lang="less" scoped>
  324. /deep/.u-icon {
  325. justify-content: flex-end;
  326. }
  327. .btn {
  328. position: fixed;
  329. bottom: 0;
  330. left: 0;
  331. z-index: 1;
  332. padding: 16rpx 30rpx 36rpx 30rpx;
  333. width: 100%;
  334. box-sizing: border-box;
  335. background: #fff;
  336. text {
  337. display: block;
  338. background-color: #007A69;
  339. color: #007A69;
  340. color: #fff;
  341. height: 88rpx;
  342. line-height: 88rpx;
  343. border-radius: 44rpx;
  344. text-align: center;
  345. font-size: 32rpx;
  346. font-weight: bold;
  347. box-sizing: border-box;
  348. }
  349. }
  350. .page {
  351. background: #F5F8FA;
  352. padding: 20rpx 24rpx 160rpx;
  353. box-sizing: border-box;
  354. .types {
  355. display: flex;
  356. gap: 36rpx;
  357. justify-content: space-between;
  358. .n {
  359. margin-bottom: 20rpx;
  360. color: #fff;
  361. }
  362. .item {
  363. width: 330rpx;
  364. height: 156rpx;
  365. padding: 34rpx 24rpx;
  366. font-size: 38rpx;
  367. font-weight: bold;
  368. box-sizing: border-box;
  369. }
  370. .bg2 {
  371. background: url('https://fsy.shengsi.gov.cn/file/20240316/3fc9f6a78557492e98caa50392411e3a.png') no-repeat center;
  372. background-size: 100%;
  373. }
  374. .bg1 {
  375. background: url('https://fsy.shengsi.gov.cn/file/20240316/8a927d5d4da84728b6bb0896541baccf.png') no-repeat center;
  376. background-size: 100%;
  377. }
  378. }
  379. .orderInfo {
  380. background-color: #fff;
  381. color: #333;
  382. padding: 0 24rpx 36rpx;
  383. margin: 20rpx 0 0;
  384. background: #fff;
  385. border-radius: 16rpx;
  386. .tit {
  387. padding: 32rpx 0 24rpx;
  388. font-size: 32rpx;
  389. }
  390. .time {
  391. font-size: 36rpx;
  392. font-weight: bold;
  393. margin-bottom: 32rpx;
  394. }
  395. .bottom {
  396. display: flex;
  397. align-items: center;
  398. text {
  399. &:first-child {
  400. width: 88rpx;
  401. height: 54rpx;
  402. background-color: #007A69;
  403. color: #fff;
  404. font-size: 34rpx;
  405. font-weight: bold;
  406. margin-right: 10rpx;
  407. text-align: center;
  408. border-radius: 12rpx;
  409. }
  410. &:nth-child(2) {
  411. width: 200rpx;
  412. flex: 1;
  413. }
  414. &:last-child {
  415. font-size: 30rpx;
  416. font-weight: bold;
  417. }
  418. }
  419. }
  420. }
  421. }
  422. .list {
  423. box-sizing: border-box;
  424. padding: 0 24rpx 0;
  425. border-radius: 16rpx;
  426. background-color: #fff;
  427. margin-top: 20rpx;
  428. .tit {
  429. font-size: 36rpx;
  430. font-weight: bold;
  431. color: #111;
  432. padding: 36rpx 0 17rpx;
  433. }
  434. .typeItem {
  435. display: flex;
  436. justify-content: space-between;
  437. flex-wrap: wrap;
  438. gap: 20rpx 0;
  439. padding-bottom: 50rpx;
  440. .txt {
  441. display: inline-block;
  442. width: 316rpx;
  443. height: 80rpx;
  444. background: #fff;
  445. border-radius: 16rpx;
  446. text-align: center;
  447. line-height: 80rpx;
  448. border: 2rpx solid #EFEFEF;
  449. color: #333;
  450. position: relative;
  451. margin-bottom: 20rpx;
  452. font-size: 32rpx;
  453. &.on {
  454. color: #007A69;
  455. background: rgba(0, 122, 105, 0.06);
  456. border: 2rpx solid #007A69;
  457. image {
  458. position: absolute;
  459. bottom: 0;
  460. right: 0;
  461. width: 34rpx;
  462. height: 26rpx;
  463. z-index: 11;
  464. }
  465. }
  466. }
  467. }
  468. .item {
  469. display: flex;
  470. justify-content: space-between;
  471. padding: 24rpx 0;
  472. align-items: center;
  473. .type {
  474. width: 110rpx;
  475. height: 48rpx;
  476. text-align: center;
  477. display: inline-block;
  478. line-height: 48rpx;
  479. border-radius: 11rpx;
  480. font-size: 26rpx;
  481. font-weight: bold;
  482. color: #111;
  483. margin-right: 16rpx;
  484. }
  485. .t1 {
  486. background-color: #F0F8F6;
  487. color: #007A69;
  488. }
  489. .t2 {
  490. background-color: #E8EFFD;
  491. color: #326EE0;
  492. }
  493. .personInfo {
  494. flex: 1;
  495. .name {
  496. font-size: 30rpx;
  497. color: #111;
  498. margin-bottom: 16rpx;
  499. }
  500. .code {
  501. color: #666;
  502. font-size: 28rpx;
  503. }
  504. }
  505. }
  506. }
  507. </style>