verification.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. <template>
  2. <view>
  3. <view v-if="!hid" class="flex-row-center" :style="{ top: scHight }" style="width: 750rpx; position: fixed; z-index: 100; left: 0">
  4. <view class="flex-column-center" style="background-color: #fcfcfc; padding: 30rpx; border-radius: 10rpx">
  5. <movable-area class="flex" style="width: 100%" animation="false" :style="{ height: originalHeight }">
  6. <movable-view scale-value="1" animation="false" damping="5000" :x="moveX" :style="{
  7. height: sliderHeight,
  8. width: sliderWidth,
  9. 'z-index': 101,
  10. }" direction="horizontal">
  11. <image :src="imgbk" class="image" mode="aspectFit" :style="{
  12. height: sliderHeight,
  13. width: sliderWidth,
  14. 'margin-top': imgbKH,
  15. }"></image>
  16. </movable-view>
  17. <image :src="img" mode="aspectFit" :style="{ height: originalHeight, width: originalWidth }" style="border-radius: 10rpx"></image>
  18. </movable-area>
  19. <movable-area class="flex-row-start" style="
  20. width: 100%;
  21. background-color: #efefef;
  22. height: 80rpx;
  23. border-radius: 40rpx;
  24. margin-top: 30rpx;
  25. ">
  26. <movable-view scale-value="1" animation="false" damping="50" :x="movePv" class="flex-row-center" style="
  27. border-radius: 50%;
  28. height: 100rpx;
  29. width: 100rpx;
  30. background-color: #ffffff;
  31. border: 2rpx solid #e3e3e3;
  32. margin-top: -13rpx;
  33. " direction="horizontal" @change="moveChange" @touchend="end">
  34. <view :class="endLoad ? 'cuIcon-right' : 'cuIcon-loading turn-load'" class="loadIcon" style="">
  35. </view>
  36. </movable-view>
  37. <text style="padding-left: 140rpx" :style="{ color: col }">{{
  38. hasImg
  39. }}</text>
  40. </movable-area>
  41. <view class="flex-row-around padding-top" style="width: 100%">
  42. <view @click="hide" class="cuIcon-close" style="font-size: 50rpx; color: #e25915">
  43. </view>
  44. <text class="cu-tag bg-cyan round" @click="getCode">刷新拼图</text>
  45. <text class="my-neirong-sm cuIcon-safe" style="color: #c1c1c1">Lili-FRAMEWORK</text>
  46. </view>
  47. </view>
  48. </view>
  49. </view>
  50. </template>
  51. <script>
  52. import api from "@/config/api.js";
  53. import storage from "@/utils/storage.js";
  54. const phone = uni.getSystemInfoSync();
  55. const l = phone.screenWidth / 750;
  56. export default {
  57. name: "verification",
  58. created() {
  59. // 可自行调整
  60. this.scHight = phone.screenHeight / 2 - 200 + "px";
  61. this.getCode();
  62. // 监听是否要重新验证
  63. uni.$on("vert", (data) => {
  64. this.vsr = data;
  65. this.vsrtx = "点击进行验证";
  66. this.getCode();
  67. });
  68. },
  69. props: {
  70. height: {
  71. type: String,
  72. default: "80rpx",
  73. },
  74. width: {
  75. type: String,
  76. default: "350rpx",
  77. },
  78. left: {
  79. type: String,
  80. default: "180rpx",
  81. },
  82. top: {
  83. type: String,
  84. default: "30rpx",
  85. },
  86. business: {
  87. type: String,
  88. default: "LOGIN",
  89. },
  90. },
  91. data() {
  92. return {
  93. flage: false,
  94. key: "", //key
  95. vsrtx: "点击进行验证", //按钮提示语
  96. vsr: false, //
  97. hid: true,
  98. col: "#838383",
  99. movePv: 0,
  100. hasImg: "拖动滑块已完成拼图",
  101. spcode: "",
  102. tl: 0,
  103. moveCode: 0,
  104. //X轴移动距离
  105. moveX: 0,
  106. //模版高度
  107. originalHeight: "",
  108. //模版宽度
  109. originalWidth: "",
  110. //拼图高度
  111. sliderHeight: "",
  112. //平涂宽度
  113. sliderWidth: "",
  114. scHight: 0,
  115. //原图
  116. img: "",
  117. //拼图
  118. imgbk: "",
  119. endLoad: true,
  120. imgbKH: "",
  121. };
  122. },
  123. methods: {
  124. show() {
  125. this.hid = false;
  126. },
  127. hide() {
  128. if (!this.vsr) {
  129. // vsr判断是否验证成功,成功隐藏验证框
  130. this.hid = !this.hid;
  131. }
  132. },
  133. // 获取验证图片
  134. getCode() {
  135. this.col = "#b3afae";
  136. this.hasImg = "图片加载中...";
  137. uni.request({
  138. url: api.common + "/slider/" + this.business,
  139. header: {
  140. uuid: storage.getUuid(),
  141. },
  142. success: (res) => {
  143. this.col = "#838383";
  144. this.hasImg = "拖动滑块以完成拼图";
  145. var data = res.data.result;
  146. // base64的图片
  147. this.img = data.backImage;
  148. this.imgbk = data.slidingImage;
  149. // 根据参数动态适应验证图片的高宽
  150. this.imgbKH = data.randomY * 1.8 + "rpx";
  151. this.originalHeight = data.originalHeight * 1.8 + "rpx";
  152. this.originalWidth = data.originalWidth * 1.8 + "rpx";
  153. this.sliderHeight = data.sliderHeight * 1.8 + "rpx";
  154. this.sliderWidth = data.sliderWidth * 1.8 + "rpx";
  155. // 适应比率,用来适应滑动距离
  156. this.tl = 1 / (1.8 * l);
  157. // 无用信息
  158. this.spcode = data.capcode;
  159. // 验证令牌
  160. this.key = data.key;
  161. this.$store.state.verificationKey = data.key;
  162. },
  163. });
  164. },
  165. end(e) {
  166. this.endLoad = false;
  167. // 验证拼图位置是否正确
  168. uni.request({
  169. method: "POST",
  170. url:
  171. api.common +
  172. "/slider/" +
  173. this.business +
  174. "?xPos=" +
  175. parseInt(this.moveCode * this.tl),
  176. header: {
  177. uuid: storage.getUuid(),
  178. },
  179. success: (res) => {
  180. this.endLoad = true;
  181. res.data.result == false
  182. ? (res.data.result = false)
  183. : (res.data.result = true);
  184. if (res.data && res.data.result) {
  185. //验证成功后把key发送出去,后端会把验证信息存在缓存里
  186. this.$emit("send", this.key);
  187. this.hide();
  188. this.vsr = true;
  189. this.vsrtx = "已通过验证";
  190. } else {
  191. this.getCode(); // 让滑块回到起始位置
  192. if (this.movePv == 1) {
  193. this.movePv = 0;
  194. } else {
  195. this.movePv = 1;
  196. }
  197. }
  198. },
  199. fail: (res) => {
  200. this.$msg("连接服务器失败");
  201. },
  202. });
  203. },
  204. // 绑定拼图位置
  205. moveChange(e) {
  206. this.moveX = e.detail.x;
  207. this.moveCode = e.detail.x;
  208. },
  209. },
  210. };
  211. </script>
  212. <style lang="scss" scoped>
  213. @import "./animation.css";
  214. @import "./icon.css";
  215. // @import './main.css';
  216. .dh-wt {
  217. animation: at 1.1s ease;
  218. animation-iteration-count: infinite;
  219. animation-direction: alternate;
  220. background-color: $main-color;
  221. border-radius: 50%;
  222. }
  223. @keyframes at {
  224. from {
  225. width: 27rpx;
  226. height: 27rpx;
  227. }
  228. to {
  229. width: 45rpx;
  230. height: 45rpx;
  231. }
  232. }
  233. .ttcl {
  234. color: $main-color;
  235. }
  236. .border-index {
  237. border: 1rpx solid $main-color;
  238. }
  239. .loadIcon {
  240. color: $main-color;
  241. font-size: 40rpx;
  242. }
  243. .status_bar {
  244. height: var(--status-bar-height);
  245. background-color: #f1f1f1;
  246. width: 100%;
  247. }
  248. .status_bar-nobg {
  249. height: var(--status-bar-height);
  250. width: 100%;
  251. }
  252. /* 转圈动画 */
  253. .turn-load {
  254. animation: turnmy 1s linear infinite;
  255. }
  256. @keyframes turnmy {
  257. 0% {
  258. -webkit-transform: rotate(0deg);
  259. }
  260. 25% {
  261. -webkit-transform: rotate(90deg);
  262. }
  263. 50% {
  264. -webkit-transform: rotate(180deg);
  265. }
  266. 75% {
  267. -webkit-transform: rotate(270deg);
  268. }
  269. 100% {
  270. -webkit-transform: rotate(360deg);
  271. }
  272. }
  273. .status_bar-fixed {
  274. height: var(--status-bar-height);
  275. width: 100%;
  276. position: fixed;
  277. background-color: #f1f1f1;
  278. z-index: 20;
  279. }
  280. .head-dh-my {
  281. display: flex;
  282. position: fixed;
  283. justify-content: space-around;
  284. align-items: flex-end;
  285. padding-bottom: 10rpx;
  286. z-index: 15;
  287. background-color: #e3e3e3;
  288. width: 750rpx;
  289. }
  290. .border-bom {
  291. border-bottom: 0.5rpx solid #dddddd;
  292. }
  293. .border-red {
  294. border-bottom: 1rpx solid #d33e18;
  295. }
  296. .border-bom-big {
  297. border-bottom: 8rpx solid #dddddd;
  298. }
  299. .border-bom-white {
  300. border-bottom: 2rpx solid #ffffff;
  301. }
  302. .border-bom-green {
  303. border-bottom: 4rpx solid #f8f9bd;
  304. }
  305. .border-bom-index {
  306. border-bottom: 4rpx solid #27d9b3;
  307. }
  308. .padding-left {
  309. padding-left: 20rpx;
  310. }
  311. .padding-left-top {
  312. padding-left: 20rpx;
  313. padding-top: 20rpx;
  314. }
  315. .padding-right {
  316. padding-right: 20rpx;
  317. }
  318. .input-my {
  319. padding-left: 20rpx;
  320. border-radius: 40rpx;
  321. height: 50rpx;
  322. margin: 10rpx;
  323. }
  324. .tb-tag-absolute {
  325. position: absolute;
  326. z-index: 5;
  327. border-radius: 25rpx;
  328. font-size: 16rpx;
  329. margin-left: 25rpx;
  330. margin-top: -35rpx;
  331. }
  332. .flex-column-center {
  333. display: flex;
  334. flex-direction: column;
  335. justify-content: center;
  336. align-items: center;
  337. }
  338. .flex-column-between {
  339. display: flex;
  340. flex-direction: column;
  341. justify-content: space-between;
  342. align-items: center;
  343. }
  344. .flex-column-start {
  345. display: flex;
  346. flex-direction: column;
  347. justify-content: center;
  348. }
  349. .flex-column-around {
  350. display: flex;
  351. flex-direction: column;
  352. justify-content: space-around;
  353. align-items: center;
  354. }
  355. .flex-row-start {
  356. display: flex;
  357. flex-direction: row;
  358. align-items: center;
  359. }
  360. .flex-row-around {
  361. display: flex;
  362. flex-direction: row;
  363. justify-content: space-around;
  364. align-items: center;
  365. }
  366. .flex-row-center {
  367. display: flex;
  368. flex-direction: row;
  369. justify-content: center;
  370. align-items: center;
  371. }
  372. .flex-row-between {
  373. display: flex;
  374. flex-direction: row;
  375. justify-content: space-between;
  376. align-items: center;
  377. }
  378. .my-title {
  379. font-size: 35rpx;
  380. font-weight: bold;
  381. }
  382. .my-neirong {
  383. font-size: 26rpx;
  384. color: #6d6d6d;
  385. }
  386. .my-neirong-sm {
  387. font-size: 23rpx;
  388. color: #616161;
  389. }
  390. .my-tag-text {
  391. font-size: 22rpx;
  392. padding-top: 20rpx;
  393. color: #bababa;
  394. }
  395. .padding-top {
  396. padding-top: 35rpx;
  397. }
  398. .padding-top-sm {
  399. padding-top: 20rpx;
  400. }
  401. .bottom-dh {
  402. background-color: #f1f1f1;
  403. position: fixed;
  404. z-index: 10;
  405. bottom: 0;
  406. width: 750rpx;
  407. height: 110rpx;
  408. }
  409. .tb-text {
  410. display: flex;
  411. flex-direction: column;
  412. justify-content: center;
  413. align-items: center;
  414. }
  415. .bottom-text {
  416. width: 750rpx;
  417. position: fixed;
  418. text-align: center;
  419. font-size: 26rpx;
  420. color: #9d9d9d;
  421. bottom: 70rpx;
  422. }
  423. .moneycolor {
  424. color: #ea5002;
  425. }
  426. .margin-top {
  427. margin-top: 20rpx;
  428. }
  429. .margin-top-sm {
  430. margin-top: 12rpx;
  431. }
  432. .margin {
  433. margin: 20rpx;
  434. }
  435. .margin-left {
  436. margin-left: 20rpx;
  437. }
  438. .margin-right {
  439. margin-right: 20rpx;
  440. }
  441. .main-color {
  442. color: #07d188;
  443. }
  444. </style>