FindPassword.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. <template>
  2. <div
  3. class="find-password"
  4. >
  5. <div class="bg-deco" />
  6. <img
  7. class="logo-and-title"
  8. src="@/assets/images/logo-and-title.png"
  9. alt=""
  10. draggable="false"
  11. >
  12. <div class="form-item">
  13. <div class="title">
  14. <img
  15. src="@/assets/images/icon-account.png"
  16. alt=""
  17. draggable="false"
  18. >
  19. <span>帐号</span>
  20. </div>
  21. <input
  22. v-model.trim="account"
  23. type="text"
  24. placeholder="请输入邮箱"
  25. aotufocus
  26. :class="{
  27. invalid: isAccountInputOver && !isAccountValid
  28. }"
  29. @blur="isAccountInputOver=true"
  30. >
  31. </div>
  32. <div class="form-item">
  33. <div class="title">
  34. <img
  35. src="@/assets/images/icon-phone.png"
  36. alt=""
  37. draggable="false"
  38. >
  39. <span>手机号</span>
  40. </div>
  41. <input
  42. v-model="phone"
  43. type="number"
  44. placeholder="请输入11位手机号"
  45. :class="{
  46. invalid: isPhoneInputOver && !isPhoneValid
  47. }"
  48. @blur="isPhoneInputOver=true"
  49. >
  50. </div>
  51. <div class="form-item form-item-verifi">
  52. <div class="title">
  53. <!-- <img
  54. src="@/assets/images/icon-lock.png"
  55. alt=""
  56. draggable="false"
  57. > -->
  58. <span>验证码</span>
  59. </div>
  60. <div class="row">
  61. <input
  62. v-model="verifiCode"
  63. placeholder="请输入验证码"
  64. :class="{
  65. invalid: isVerifiCodeInputOver && !isVerifiCodeValid
  66. }"
  67. @blur="isVerifiCodeInputOver=true"
  68. >
  69. <button
  70. class="get-verifi-code"
  71. @click="onClickVerifiCode"
  72. >
  73. <img
  74. v-if="isShowVerifiCode"
  75. class=""
  76. src="https://sit-cnzhengquan.4dage.com/api/show/getRandCode"
  77. alt=""
  78. draggable="false"
  79. >
  80. </button>
  81. </div>
  82. </div>
  83. <button
  84. class="submit"
  85. @click="submit"
  86. >
  87. 发送验证邮件
  88. </button>
  89. <button
  90. class="return"
  91. @click="$router.push({
  92. name: 'HomeView',
  93. })"
  94. >
  95. 返回首页
  96. </button>
  97. </div>
  98. </template>
  99. <script setup>
  100. import { ref, computed, watch, onMounted, nextTick } from "vue"
  101. import { useRoute, useRouter } from "vue-router"
  102. import { useStore } from "vuex"
  103. import { showDialog } from 'vant'
  104. import { findPassowrd } from '@/api.js'
  105. const route = useRoute()
  106. const router = useRouter()
  107. const store = useStore()
  108. const {
  109. windowSizeInCssForRef,
  110. windowSizeWhenDesignForRef,
  111. } = useSizeAdapt(390, 752)
  112. const account = ref('')
  113. const phone = ref('')
  114. const password = ref('')
  115. const passwordRepeat = ref('')
  116. const verifiCode = ref('')
  117. const accountTrimed = computed(() => {
  118. return account.value.trim()
  119. })
  120. const phoneTrimed = computed(() => {
  121. return phone.value.toString().trim()
  122. })
  123. const verifiCodeTrimed = computed(() => {
  124. return verifiCode.value.trim()
  125. })
  126. const isAccountValid = computed(() => {
  127. return !!accountTrimed.value
  128. })
  129. const isPhoneValid = computed(() => {
  130. return phoneTrimed.value.length === 11
  131. })
  132. const isVerifiCodeValid = computed(() => {
  133. return verifiCodeTrimed.value.length > 0
  134. })
  135. const isAccountInputOver = ref(false)
  136. const isPhoneInputOver = ref(false)
  137. const isVerifiCodeInputOver = ref(false)
  138. const isShowVerifiCode = ref(true)
  139. const onClickVerifiCode = utils.throttle(() => {
  140. isShowVerifiCode.value = false
  141. nextTick(() => {
  142. isShowVerifiCode.value = true
  143. })
  144. }, 333)
  145. function submit() {
  146. if (!isAccountValid.value) {
  147. showDialog({
  148. message: '请正确输入邮箱',
  149. theme: 'round-button',
  150. })
  151. isAccountInputOver.value = true
  152. return
  153. }
  154. if (!isPhoneValid.value) {
  155. showDialog({
  156. message: '请正确输入手机号',
  157. theme: 'round-button',
  158. })
  159. isPhoneInputOver.value = true
  160. return
  161. }
  162. if (!isVerifiCodeValid.value) {
  163. showDialog({
  164. message: '请输入验证码',
  165. theme: 'round-button',
  166. })
  167. isVerifiCodeInputOver.value = true
  168. return
  169. }
  170. findPassowrd(accountTrimed.value, phoneTrimed.value, verifiCodeTrimed.value).then(() => {
  171. showDialog({
  172. message: '已发送邮件到您的邮箱',
  173. theme: 'round-button',
  174. }).then(() => {
  175. router.replace({
  176. name: 'HomeView'
  177. })
  178. })
  179. }).catch((err) => {
  180. showDialog({
  181. message: err,
  182. theme: 'round-button',
  183. })
  184. })
  185. }
  186. </script>
  187. <style lang="less" scoped>
  188. .find-password{
  189. display: flex;
  190. flex-direction: column;
  191. align-items: center;
  192. position: absolute;
  193. left: 0;
  194. top: 0;
  195. width: 100%;
  196. height: 100%;
  197. overflow: hidden;
  198. >.bg-deco{
  199. position: absolute;
  200. left: calc(-67 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  201. bottom: calc(-130 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  202. width: calc(250 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  203. height: calc(250 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  204. background: #D1B489;
  205. filter: blur(calc(100 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')));
  206. }
  207. >.logo-and-title{
  208. margin-top: calc(53 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  209. width: calc(120 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  210. margin-bottom: calc(38 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  211. }
  212. >.form-item{
  213. width: calc(321 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  214. margin-bottom: calc(22 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  215. >.title{
  216. width: 100%;
  217. display: flex;
  218. align-items: center;
  219. margin-bottom: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  220. >img{
  221. width: calc(22 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  222. height: calc(22 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  223. margin-right: calc(10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  224. }
  225. >span{
  226. font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  227. font-family: Source Han Sans SC, Source Han Sans SC;
  228. font-weight: 400;
  229. color: #D1B489;
  230. line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  231. }
  232. }
  233. >input{
  234. width: 100%;
  235. height: calc(29 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  236. border-bottom: 1px solid #D9D9D9;
  237. font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  238. font-family: Source Han Sans SC, Source Han Sans SC;
  239. font-weight: 400;
  240. color: black;
  241. line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  242. &::placeholder {
  243. font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  244. font-family: Source Han Sans SC, Source Han Sans SC;
  245. font-weight: 400;
  246. color: #B8B8B8;
  247. line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  248. }
  249. }
  250. >input.invalid{
  251. border-bottom: 1px solid red;
  252. }
  253. }
  254. >.form-item{
  255. >.title{
  256. width: 100%;
  257. display: flex;
  258. align-items: center;
  259. margin-bottom: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  260. >img{
  261. width: calc(22 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  262. height: calc(22 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  263. margin-right: calc(10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  264. }
  265. >span{
  266. font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  267. font-family: Source Han Sans SC, Source Han Sans SC;
  268. font-weight: 400;
  269. color: #D1B489;
  270. line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  271. }
  272. }
  273. >div.row{
  274. display: flex;
  275. justify-content: space-between;
  276. align-items: flex-end;
  277. margin-top: calc(-11 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  278. >input{
  279. width: 50%;
  280. height: calc(29 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  281. border-bottom: 1px solid #D9D9D9;
  282. font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  283. font-family: Source Han Sans SC, Source Han Sans SC;
  284. font-weight: 400;
  285. color: black;
  286. line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  287. &::placeholder {
  288. font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  289. font-family: Source Han Sans SC, Source Han Sans SC;
  290. font-weight: 400;
  291. color: #B8B8B8;
  292. line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  293. }
  294. }
  295. >input.invalid{
  296. border-bottom: 1px solid red;
  297. }
  298. >button.get-verifi-code{
  299. height: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  300. >img{
  301. height: 100%;
  302. }
  303. }
  304. }
  305. }
  306. >button.submit{
  307. width: calc(332 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  308. height: calc(56 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  309. background: rgba(197, 161, 108, 0.8);
  310. border-radius: calc(10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  311. font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  312. font-family: Source Han Sans SC, Source Han Sans SC;
  313. font-weight: 400;
  314. color: #FFFFFF;
  315. line-height: calc(23 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  316. }
  317. >button.return{
  318. font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  319. font-family: Source Han Sans SC, Source Han Sans SC;
  320. font-weight: 400;
  321. color: #A97C46;
  322. line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  323. padding: calc(15 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  324. opacity: 0.5;
  325. }
  326. }
  327. </style>