login.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. <template>
  2. <view class="login-container">
  3. <!-- Logo和标题区域 -->
  4. <view class="logo-section">
  5. <image class="logo" src="/static/img/logo.png" mode="aspectFit" />
  6. </view>
  7. <!-- 表单区域 -->
  8. <view class="form-section">
  9. <u--form :model="formData" ref="uForm">
  10. <u-form-item>
  11. <u-input
  12. :prefixIconStyle="prefixIconStyle"
  13. :placeholder-style="placeholderStyle"
  14. :custom-style="customStyle"
  15. v-model="formData.username"
  16. placeholder="请输入用户名"
  17. prefixIcon="account"
  18. />
  19. </u-form-item>
  20. <u-form-item>
  21. <u-input
  22. :prefixIconStyle="prefixIconStyle"
  23. :placeholder-style="placeholderStyle"
  24. :custom-style="customStyle"
  25. v-model="formData.password"
  26. type="password"
  27. placeholder="请输入密码"
  28. prefixIcon="lock"
  29. />
  30. </u-form-item>
  31. <u-form-item>
  32. <u-input
  33. :prefixIconStyle="prefixIconStyle"
  34. :placeholder-style="placeholderStyle"
  35. :custom-style="customStyle"
  36. v-model="formData.code"
  37. placeholder="请输入验证码"
  38. prefixIcon="chat"
  39. >
  40. <template #suffix>
  41. <u-button
  42. custom-style="width:200rpx"
  43. color="#22ac38"
  44. size="small"
  45. @click="getVerifyCode"
  46. :disabled="isCountingDown"
  47. >
  48. {{ countDownText }}
  49. </u-button>
  50. </template>
  51. </u-input>
  52. </u-form-item>
  53. </u--form>
  54. <u-button
  55. custom-style="margin-top:5%"
  56. type="primary"
  57. block
  58. @click="handleLogin"
  59. color="#22ac38"
  60. shape="circle"
  61. >登录</u-button
  62. >
  63. </view>
  64. </view>
  65. </template>
  66. <script setup>
  67. import { ref, reactive, getCurrentInstance } from "vue";
  68. import { onLoad } from "@dcloudio/uni-app";
  69. const prefixIconStyle = "font-size:50rpx";
  70. const placeholderStyle = "font-size:32rpx";
  71. const customStyle = reactive({
  72. "font-size": "40rpx",
  73. height: "90rpx",
  74. });
  75. let { proxy } = getCurrentInstance();
  76. const formData = reactive({
  77. username: "",
  78. password: "",
  79. code: "",
  80. });
  81. const uForm = ref(null);
  82. const isCountingDown = ref(false);
  83. const countdown = ref(60);
  84. const countDownText = ref("获取验证码");
  85. const startCountDown = () => {
  86. isCountingDown.value = true;
  87. countdown.value = 60;
  88. countDownText.value = `${countdown.value}秒重发`;
  89. const timer = setInterval(() => {
  90. countdown.value--;
  91. countDownText.value = `${countdown.value}秒重发`;
  92. if (countdown.value <= 0) {
  93. clearInterval(timer);
  94. isCountingDown.value = false;
  95. countDownText.value = "重新发送";
  96. }
  97. }, 1000);
  98. };
  99. const getVerifyCode = () => {
  100. if (isCountingDown.value) return;
  101. if (!formData.username) return uni.$u.toast("请输入用户名");
  102. if (!formData.password) return uni.$u.toast("请输入密码");
  103. let data = {
  104. username: formData.username,
  105. password: formData.password,
  106. };
  107. // TODO: 调用发送验证码的API
  108. uni.showLoading({
  109. mask: true,
  110. title: "发送中...",
  111. });
  112. uni.$u.http
  113. .post("/app/appUser/sendMobileCode", data)
  114. .then((res) => {
  115. if (res.code == 200) {
  116. uni.showToast({
  117. title: "验证码发送成功,请注意查收",
  118. icon: "none",
  119. });
  120. startCountDown();
  121. } else {
  122. uni.$u.toast(res.msg);
  123. }
  124. })
  125. .finally(() => uni.hideLoading());
  126. };
  127. const handleLogin = () => {
  128. // 实现登录逻辑
  129. if (!formData.username) return uni.$u.toast("请输入用户名");
  130. if (!formData.password) return uni.$u.toast("请输入密码");
  131. // if (!formData.code) return uni.$u.toast('请输入验证码')
  132. // TODO: 调用登录API /app/appUser/login
  133. uni.showLoading({
  134. mask: true,
  135. title: "登录中...",
  136. });
  137. // /actuator/debug/loginNotCode ///app/appUser/login
  138. uni.$u.http
  139. .post("/app/appUser/login", formData)
  140. .then((res) => {
  141. if (res.code == 200) {
  142. uni.setStorageSync("token", res.data);
  143. setTimeout(() => {
  144. getUserInfo();
  145. //获取菜单权限
  146. uni.$u.http.get("/app/appUser/getRouters").then((resp) => {
  147. if (resp.code == 200) {
  148. uni.setStorageSync("menuList", resp.data);
  149. uni.$u.toast("登录成功");
  150. uni.switchTab({
  151. url: "/pages/index/index",
  152. });
  153. uni.$u.ttsModule.speak("书嗨,不辜负每一个爱书的人");
  154. } else {
  155. uni.$u.toast(resp.msg);
  156. }
  157. });
  158. }, 50);
  159. } else {
  160. uni.$u.toast(res.msg);
  161. }
  162. })
  163. .catch((error) => {
  164. uni.showModal({
  165. title: "登录失败",
  166. content: JSON.stringify(error),
  167. showCancel: false,
  168. });
  169. })
  170. .finally(() => uni.hideLoading());
  171. };
  172. //获取登陆人信息并存储本地 /app/appUser/getUserInfoById
  173. function getUserInfo() {
  174. uni.$u.http.get("/app/appUser/getUserInfoById").then((res) => {
  175. if (res.code == 200) {
  176. uni.setStorageSync("userInfo", res.data);
  177. }
  178. });
  179. }
  180. //检测token是否可用
  181. function checkToken() {
  182. // /app/appUser/checkToken
  183. uni.showLoading({
  184. title: "检测登录状态...",
  185. });
  186. uni.$u.http
  187. .get("/app/appUser/checkToken")
  188. .then((res) => {
  189. if (res.code == 200) {
  190. uni.$u.toast("登录成功");
  191. uni.switchTab({
  192. url: "/pages/index/index",
  193. });
  194. } else {
  195. uni.$u.toast("请先登录");
  196. }
  197. })
  198. .finally(() => uni.hideLoading());
  199. }
  200. onLoad(() => {
  201. let token = uni.getStorageSync("token");
  202. if (token) {
  203. checkToken();
  204. }
  205. });
  206. </script>
  207. <style>
  208. page {
  209. background-color: #ffffff;
  210. }
  211. </style>
  212. <style lang="scss" scoped>
  213. .login-container {
  214. padding: 5% 60rpx;
  215. .logo-section {
  216. display: flex;
  217. flex-direction: column;
  218. align-items: center;
  219. }
  220. .logo {
  221. width: 300rpx;
  222. height: 300rpx;
  223. }
  224. .form-section {
  225. margin-top: 40rpx;
  226. }
  227. }
  228. </style>