carKeyboard.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. <template>
  2. <!--车牌号输入组件-->
  3. <view v-if="show" class="trailer-keyboard">
  4. <u-popup :show="show">
  5. <view class="trailer-keyboard">
  6. <view class="keyBoard_content">
  7. <!-- header -->
  8. <view class="top-part flex">
  9. <view class="font-30 close" @click="closeKeyboard">
  10. <u-icon name="close"></u-icon>
  11. </view>
  12. <view class="message color-333">{{$t('order.PleaseEnterTheLicensePlateNumber')}}</view>
  13. <view class="font-30 confirm" :class="{'confirm-active': confirmBtnFocus}"
  14. @click="confirmKeyboard">{{$t('settings.confirmText')}}
  15. </view>
  16. </view>
  17. <!-- input checkbox -->
  18. <view class="input-and-checkbox">
  19. <!-- input -->
  20. <view class="license flex">
  21. <view v-for="(item,index) in codeList" :key="index" class="edit-text"
  22. :class="{'border-active': currentFocus === index,'space-left': index === 2}">
  23. <view>{{item.value}}</view>
  24. </view>
  25. </view>
  26. <!-- checkbox -->
  27. <view v-if="vehicleType === 'car' && checkboxShow" class="checkbox-box">
  28. <!-- -->
  29. <u-checkbox-group class="uCheckbox" v-model="checkboxList" @change="checkboxChange">
  30. <u-checkbox :label="$t('settings.newEnergyAutomobile')" :name="$t('settings.newEnergyAutomobile')" shape="circle" activeColor="#27B57D"
  31. :checked="isNewEnergy">
  32. </u-checkbox>
  33. </u-checkbox-group>
  34. </view>
  35. </view>
  36. <!-- 键盘 -->
  37. <view class="keyboard-content">
  38. <!-- 省份键盘 -->
  39. <template v-if="isProvince && provinceBoardShow">
  40. <view class="province-keyboard flex">
  41. <view class="td td-nor color-333" v-for="(item,index) in provincesKeyList" :key="index"
  42. @click="provinceKeyClick(item,index)" hover-class="board-active"
  43. hover-start-time="0" hover-stay-time="80">
  44. {{item}}
  45. </view>
  46. </view>
  47. </template>
  48. <!--数字键盘-->
  49. <template v-if="!isProvince || !provinceBoardShow">
  50. <view class="number-keyboard flex between">
  51. <template>
  52. <view class="td td-num color-333" :class="numberIsDis ? 'board-active' : ''"
  53. v-for="(item,index) in numberKeyList" :key="index"
  54. @click="numberKeyClick(item,index)"
  55. :hover-class="numberIsDis ? '' : 'board-active'" hover-start-time="0"
  56. hover-stay-time="80">
  57. {{item}}
  58. </view>
  59. </template>
  60. </view>
  61. </template>
  62. <!--字母键盘-->
  63. <template v-if="!isProvince || !provinceBoardShow">
  64. <view class="english-keyboard flex between">
  65. <template>
  66. <view class="td td-num color-333" :class="englishIsDis ? 'board-active' : ''"
  67. v-for="(item,idx) in englishKeyOneList" :key="idx"
  68. @click="englishKeyClick(item,idx)"
  69. :hover-class="englishIsDis ? '' : 'board-active'" hover-start-time="0"
  70. hover-stay-time="80">
  71. {{item}}
  72. </view>
  73. </template>
  74. </view>
  75. <!-- 第二行 -->
  76. <view class="english-keyboard flex englishtTwo">
  77. <template>
  78. <view class="td td-num color-333" :class="englishIsDis ? 'board-active' : ''"
  79. v-for="(item,index) in englishKeyTwoList" :key="index"
  80. @click="englishKeyClick(item,index)"
  81. :hover-class="englishIsDis ? '' : 'board-active'" hover-start-time="0"
  82. hover-stay-time="80">
  83. {{item}}
  84. </view>
  85. </template>
  86. </view>
  87. <!-- 最后一行 -->
  88. <view class="english-keyboard flex englishtThree">
  89. <template>
  90. <view class="td td-num color-333" :class="englishIsDis ? 'board-active' : ''"
  91. v-for="(item,index) in englishKeyThreeList" :key="index"
  92. @click="englishKeyClick(item,index)"
  93. :hover-class="englishIsDis ? '' : 'board-active'" hover-start-time="0"
  94. hover-stay-time="80">
  95. {{item}}
  96. </view>
  97. <!--清除按钮-->
  98. <view @click="backspace" class="delete flex" hover-class="board-active"
  99. hover-start-time="0" hover-stay-time="80">
  100. <!-- <image class="deleteImg" src="../../static/my/clear.png" /> -->
  101. <u-icon name="backspace" size='32'></u-icon>
  102. </view>
  103. </template>
  104. <!-- 挂字键 -->
  105. <template v-if="vehicleType === 'trailer'">
  106. <view @click="trailerFiledClick('挂')" class="td td-num color-333"
  107. :class="trailerFiledIsDis ? 'board-active' : ''"
  108. :hover-class="trailerFiledIsDis ? '' : 'board-active'" hover-start-time="0"
  109. hover-stay-time="80">挂</view>
  110. </template>
  111. </view>
  112. </template>
  113. </view>
  114. </view>
  115. </view>
  116. </u-popup>
  117. </view>
  118. </template>
  119. <script>
  120. export default {
  121. name: 'carKeyboard',
  122. props: {
  123. // 组件显示
  124. show: {
  125. type: Boolean,
  126. default: false
  127. },
  128. // 初始传入车牌号
  129. vehicleNo: {
  130. type: String,
  131. default: ''
  132. },
  133. /**
  134. * 车辆牌照类型 默认挂车
  135. * trailer 挂车
  136. * car 汽车
  137. */
  138. vehicleType: {
  139. type: String,
  140. default: 'trailer'
  141. },
  142. // 是否展示新能源切换按钮
  143. checkboxShow: {
  144. type: Boolean,
  145. default: true,
  146. },
  147. //是否影藏省份
  148. isProvince: {
  149. type: Boolean,
  150. default: true,
  151. }
  152. },
  153. data() {
  154. return {
  155. /**
  156. * currIndex 初始化为零 控制确定按钮高亮
  157. * currentFocus 初始化为零 控制输入框高亮
  158. */
  159. numberIsDis: true, // 输入键盘不可点击 true为不可点击
  160. englishIsDis: false, // 字母键盘可点击
  161. provinceBoardShow: true, // 省键盘
  162. isNewEnergy: false, // 是否新能源
  163. checkboxList: [],
  164. trailerFiledIsDis: true, // 挂字禁用
  165. provincesKeyList: '京津冀晋蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新',
  166. numberKeyList: '0123456789',
  167. englishKeyOneList: 'QWERTYUIOP',
  168. englishKeyTwoList: 'ASDFGHJKL',
  169. englishKeyThreeList: 'ZXCVBNM',
  170. englishKeyForList: 'WXYZ',
  171. currentFocus: 0,
  172. currIndex: 0,
  173. plateLimit: 7, // 车牌号位数
  174. codeList: [],
  175. // codeReset: []
  176. };
  177. },
  178. watch: {
  179. show: {
  180. handler(val) {
  181. this.initData()
  182. },
  183. immediate: true,
  184. }
  185. },
  186. computed: {
  187. confirmBtnFocus() {
  188. return this.currIndex === this.codeList.length || this.currIndex == 0
  189. }
  190. },
  191. methods: {
  192. // 省份键盘
  193. provinceKeyClick(val, index) {
  194. this.currentFocus++;
  195. this.currIndex++;
  196. this.codeList[0].value = val;
  197. this.provinceBoardShow = false;
  198. this.numberIsDis = true;
  199. this.englishIsDis = false;
  200. },
  201. // 数字键盘
  202. numberKeyClick(val, idx) {
  203. if (this.numberIsDis) return
  204. if (this.currIndex >= this.codeList.length) return
  205. this.currIndex++;
  206. this.currentFocus = this.currIndex;
  207. this.codeList[this.currIndex - 1].value = val;
  208. if (this.vehicleType === 'trailer') {
  209. this.setTrailerKeyboardDis()
  210. }
  211. },
  212. // 字母键盘
  213. englishKeyClick(val, idx) {
  214. if (this.englishIsDis) return
  215. if (this.currIndex >= this.codeList.length) return
  216. this.currIndex++;
  217. this.currentFocus = this.currIndex;
  218. this.codeList[this.currIndex - 1].value = val;
  219. if (this.currIndex === 2) this.numberIsDis = false;
  220. if (this.vehicleType === 'trailer') {
  221. this.setTrailerKeyboardDis()
  222. }
  223. },
  224. // 挂字点击
  225. trailerFiledClick(val) {
  226. if (this.trailerFiledIsDis) return
  227. if (this.currIndex > this.codeList.length - 1) return
  228. this.currIndex++;
  229. this.currentFocus = this.currIndex + 1;
  230. this.codeList[this.currIndex - 1].value = val;
  231. },
  232. // 设置挂车键盘禁用(最后一个只能选择挂)
  233. setTrailerKeyboardDis() {
  234. if (this.currIndex + 1 === this.codeList.length) {
  235. this.numberIsDis = true;
  236. this.englishIsDis = true;
  237. this.trailerFiledIsDis = false;
  238. }
  239. },
  240. // 退格
  241. backspace() {
  242. if (!this.currIndex) return
  243. this.currIndex--;
  244. this.codeList[this.currIndex].value = '';
  245. this.currentFocus = this.currIndex;
  246. this.provinceBoardShow = this.currIndex === 0;
  247. if (this.currIndex === 1) this.numberIsDis = true;
  248. if (this.vehicleType === "trailer" && this.currIndex === this.codeList.length - 2) {
  249. this.numberIsDis = false;
  250. this.englishIsDis = false;
  251. this.trailerFiledIsDis = true;
  252. }
  253. },
  254. // 关闭
  255. closeKeyboard(e) {
  256. this.$emit('update:show', false)
  257. this.$emit('close')
  258. },
  259. // 确定
  260. confirmKeyboard(e) {
  261. if (this.currIndex < this.codeList.length && this.currIndex != 0) return
  262. let plate = ''
  263. this.codeList.map(item => (plate += item.value))
  264. this.$emit('confirm', plate)
  265. this.closeKeyboard()
  266. },
  267. // 是否新能源车牌checkbox change
  268. checkboxChange(val) {
  269. console.log(val, 'checkbox change');
  270. this.isNewEnergy = val.length ? true : false;
  271. if (val.length) {
  272. this.codeList.push({
  273. value: ''
  274. })
  275. // this.codeReset.push({value: ''})
  276. } else {
  277. this.codeList.splice(this.codeList.length - 1, 1)
  278. // this.codeReset.splice(this.codeList.codeReset - 1,1)
  279. let vehicleNo = "";
  280. this.codeList.map(item => (vehicleNo += item.value))
  281. if (vehicleNo.length === this.codeList.length && this.currIndex > this.codeList.length) {
  282. this.currIndex--;
  283. this.currentFocus--
  284. }
  285. }
  286. },
  287. initData() {
  288. console.log('initData', this.isNewEnergy);
  289. console.log(this.checkboxList);
  290. let temp = []
  291. // let reset = []
  292. const vehicleNoTrim = this.vehicleNo.trim()
  293. const Leng = vehicleNoTrim ? vehicleNoTrim.length : 0;
  294. // 新能源checkbox回显
  295. this.isNewEnergy = Leng > 7 ? true : false;
  296. this.checkboxList = Leng > 7 ? [{
  297. text: '新能源车',
  298. value: 1
  299. }] : []
  300. if (Leng) {
  301. let arr = vehicleNoTrim.split('')
  302. arr.forEach(item => {
  303. temp.push({
  304. value: item
  305. })
  306. // reset.push({value: ''})
  307. })
  308. } else {
  309. // 初始化设置数据
  310. for (let index = 0; index < this.plateLimit; index++) {
  311. temp.push({
  312. value: ''
  313. })
  314. // reset.push({value: ''})
  315. }
  316. }
  317. // 解决车牌号回显位数不够问题
  318. if (Leng > 0 && Leng < 7) {
  319. let num = 7 - Leng;
  320. for (let i = 0; i < num; i++) {
  321. temp.push({
  322. value: ''
  323. })
  324. }
  325. }
  326. // 禁用设置
  327. this.isNewEnergy = Leng > 7 ? true : false;
  328. this.provinceBoardShow = Leng > 0 ? false : true;
  329. this.numberIsDis = Leng < 2 ? true : false;
  330. this.englishIsDis = false;
  331. if (this.vehicleType === 'trailer') {
  332. if (Leng >= 6) {
  333. this.numberIsDis = true;
  334. this.englishIsDis = true;
  335. }
  336. this.trailerFiledIsDis = Leng < 6 ? true : false;
  337. }
  338. this.codeList = temp;
  339. // this.codeReset = reset;
  340. this.currentFocus = Leng;
  341. this.currIndex = vehicleNoTrim ? vehicleNoTrim.length : 0;
  342. }
  343. },
  344. }
  345. </script>
  346. <style lang="scss" scoped>
  347. .flex {
  348. display: flex;
  349. }
  350. .between {
  351. justify-content: space-between;
  352. }
  353. .font-30 {
  354. font-size: 30rpx;
  355. }
  356. .color-333 {
  357. color: #333333;
  358. }
  359. .trailer-keyboard {}
  360. .keyBoard_content {
  361. z-index: 9999;
  362. position: fixed;
  363. bottom: 0;
  364. left: 0;
  365. width: 100%;
  366. height: auto;
  367. background: #fff;
  368. .top-part {
  369. width: 100%;
  370. padding: 25rpx 40rpx;
  371. height: 92rpx;
  372. justify-content: center;
  373. align-items: center;
  374. box-sizing: border-box;
  375. border-bottom: 1rpx solid #EAEAEA;
  376. margin-bottom: 15rpx;
  377. text-align: center;
  378. .close {
  379. width: 10%;
  380. font-size: 47rpx;
  381. color: #A0A0A0;
  382. }
  383. .message {
  384. font-size: 15px;
  385. width: 80%;
  386. text-align: center;
  387. font-weight: Semibold;
  388. }
  389. .confirm {
  390. width: 10%;
  391. color: #A0A0A0;
  392. font-weight: Regular;
  393. &.confirm-active {
  394. color: #27B57D;
  395. }
  396. }
  397. }
  398. .input-and-checkbox {
  399. .license {
  400. box-sizing: border-box;
  401. justify-content: space-around;
  402. margin: 72rpx 86rpx 30rpx;
  403. .edit-text {
  404. height: 80rpx;
  405. line-height: 80rpx;
  406. width: 60rpx;
  407. border: 1rpx solid #A0A0A0;
  408. border-radius: 8rpx;
  409. text-align: center;
  410. font-size: 36rpx;
  411. &.space-left {
  412. // margin-left: 30rpx;
  413. }
  414. &.border-active {
  415. border: 1rpx solid #5BCA92;
  416. }
  417. }
  418. }
  419. .checkbox-box {
  420. margin: 25rpx 86rpx 28rpx;
  421. display: flex;
  422. justify-content: flex-end;
  423. .uCheckbox {}
  424. }
  425. }
  426. .keyboard-content {
  427. width: 100%;
  428. height: 510rpx;
  429. box-sizing: border-box;
  430. position: relative;
  431. .td {
  432. font-family: "PingFangSC";
  433. font-size: 32rpx;
  434. color: #333333;
  435. font-weight: 500;
  436. margin: 12rpx 2rpx;
  437. border: 1rpx solid #E0E0E0;
  438. border-radius: 8rpx;
  439. height: 84rpx;
  440. line-height: 84rpx;
  441. text-align: center;
  442. }
  443. .province-keyboard {
  444. margin: 0 50rpx;
  445. flex-wrap: wrap;
  446. .td-nor {
  447. flex: 0 1 9%;
  448. margin-right: 3px;
  449. }
  450. }
  451. .number-keyboard {
  452. margin: 0 5rpx;
  453. .td-num {
  454. flex: 0 1 8%;
  455. }
  456. }
  457. .english-keyboard {
  458. margin: 0 5rpx;
  459. flex-wrap: wrap;
  460. &.englishtTwo {
  461. display: flex;
  462. justify-content: center;
  463. .td-num {
  464. margin-right: 5px;
  465. flex: 0 1 8%;
  466. }
  467. }
  468. &.englishtThree {
  469. display: flex;
  470. justify-content: center;
  471. align-items: center;
  472. .td-num {
  473. margin-right: 5px;
  474. flex: 0 1 8%;
  475. }
  476. }
  477. .td-num {
  478. flex: 0 1 8%;
  479. }
  480. }
  481. .board-active {
  482. box-shadow: 0 0 0 #e5e5e5;
  483. background: #e5e5e5;
  484. }
  485. .delete {
  486. width: 95rpx;
  487. height: 84rpx;
  488. margin-left: 10px;
  489. text-align: center;
  490. background-color: #D8D8D8;
  491. border-radius: 8rpx;
  492. // position: absolute;
  493. // right: 73rpx;
  494. // bottom: 32rpx;
  495. justify-content: center;
  496. align-items: center;
  497. .deleteImg {
  498. width: 48rpx;
  499. height: 48rpx;
  500. }
  501. }
  502. }
  503. }
  504. </style>