login.vue 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. <template>
  2. <!-- 登录 -->
  3. <div class="login">
  4. <s-header
  5. :name="sys ? sys.title : $t('public.sysName')"
  6. ></s-header>
  7. <div class="loginLogoBox l-re">
  8. <div class="loginLogo"></div>
  9. <div class="l-ab pointer languageCon" @click="languageClk">
  10. <div class="c-text-b">
  11. {{ compLang }}
  12. </div>
  13. </div>
  14. </div>
  15. <div class="loginTitleBox l-flex-center">
  16. <span class="loginTitle">{{ $t("login.title") }}</span>
  17. </div>
  18. <div class="loginFormBox">
  19. <van-form @submit="onSubmit">
  20. <van-field
  21. v-model="userName"
  22. name="userName"
  23. label=""
  24. :placeholder="$t('login.userNameInput')"
  25. :rules="[{ required: true, message: $t('login.userNameInput') }]"
  26. />
  27. <van-field
  28. v-model="userPwd"
  29. type="password"
  30. name="userPwd"
  31. label=""
  32. :placeholder="$t('login.passWordInput')"
  33. :rules="[{ required: true, message: $t('login.passWordInput') }]"
  34. />
  35. <div class="checkedPasswordBox">
  36. <van-checkbox icon-size="18px" class="checkedPassWord" v-model="checked">
  37. {{ $t("login.checkedPassWord") }}
  38. </van-checkbox>
  39. <span class="forgetPassWord" @click="forgetPassword">{{
  40. $t("login.forgetPassWord")
  41. }}</span>
  42. </div>
  43. <br>
  44. <br>
  45. <!-- 微信登录 -->
  46. <!-- <div v-if="isInWeChat" class="loginWithWechatClass">
  47. <van-button class="wechat-btn" type="primary" size="large" @click="wxLoginHandler">
  48. <van-icon name="wechat" color="#1bd66c" size="40" class="wechat-icon"/>
  49. </van-button>
  50. </div> -->
  51. <div class="buttonBox">
  52. <van-button
  53. round
  54. type="primary"
  55. class="register"
  56. @click="registerClick"
  57. >{{ $t("login.regusterButton") }}
  58. </van-button>
  59. <van-button round type="primary" native-type="submit">{{
  60. $t("login.loginButton")
  61. }}
  62. </van-button>
  63. </div>
  64. </van-form>
  65. </div>
  66. </div>
  67. </template>
  68. <script>
  69. import md5 from "js-md5";
  70. import {onMounted, ref, computed, reactive} from "vue";
  71. import {Toast, Dialog, Button} from "vant";
  72. import {login, getSys, getOpenid} from "../service/login";
  73. import {setLocal, getLocal, navigatorLanguage, styleUrl} from "../common/js/utils";
  74. import sHeader from "../components/SimpleHeader";
  75. import {useRoute, useRouter} from "vue-router";
  76. import {useI18n} from "vue-i18n";
  77. // vant 组件的中英文切换
  78. import {Locale} from "vant";
  79. // 引入英文语言包
  80. import enUS from "vant/es/locale/lang/en-US";
  81. // 引入简体中文语言包
  82. import zhCN from "vant/es/locale/lang/zh-CN";
  83. export default {
  84. setup() {
  85. let languageName = ref(getLocal("curLang"));
  86. const {locale, t} = useI18n();
  87. // 语言点击
  88. const languageClk = () => {
  89. if (languageName.value === "zh") {
  90. locale.value = "en";
  91. languageName.value = "en";
  92. setLocal("curLang", "en");
  93. // 切换vant语言包
  94. Locale.use("en-US", enUS);
  95. } else {
  96. locale.value = "zh";
  97. languageName.value = "zh";
  98. setLocal("curLang", "zh");
  99. // 切换vant语言包
  100. Locale.use("zh-CN", zhCN);
  101. }
  102. };
  103. const compLang = computed(() => {
  104. if (languageName.value === "en") {
  105. return "中文";
  106. } else {
  107. return "English";
  108. }
  109. });
  110. const checked = ref(false); // 是否记住密码状态
  111. const userName = ref("");
  112. const userPwd = ref("");
  113. const router = useRouter();
  114. const route = useRoute();
  115. const sys = ref(null);
  116. // 页面初始化
  117. onMounted(() => {
  118. // 加载样式
  119. styleUrl('login');
  120. // localStorage.clear();
  121. // 如果没有语言缓存
  122. if (!getLocal("curLang")) {
  123. // 根据浏览器语言重新缓存到localstorage
  124. setLocal("curLang", navigatorLanguage());
  125. languageName.value = getLocal("curLang");
  126. }
  127. if (route.query.relation_admin_id) {
  128. getSysFun();
  129. }
  130. const savedCredentials = localStorage.getItem('savedCredentials');
  131. if (savedCredentials) {
  132. checked.value = true;
  133. const { savedUsername, savedPassword } = JSON.parse(savedCredentials);
  134. userName.value = savedUsername;
  135. userPwd.value = savedPassword;
  136. }
  137. });
  138. const getSysFun = async () => {
  139. const {data} = await getSys({
  140. relationAdminId: route.query.relation_admin_id,
  141. });
  142. if (data.code === "00000") {
  143. data.data.relationAdminId = route.query.relation_admin_id;
  144. setLocal("loginSys", JSON.stringify(data.data));
  145. sys.value = data.data;
  146. }
  147. };
  148. // 登录
  149. const onSubmit = async (values) => {
  150. const {data} = await login({
  151. username: values.userName,
  152. password: md5(values.userPwd),
  153. hostName: 'Sevencloud',
  154. });
  155. if (data.code === "00000") {
  156. setLocal("loginUser", JSON.stringify(data.data));
  157. if (checked.value) {
  158. const savedCredentials = JSON.stringify({ savedUsername: values.userName, savedPassword: values.userPwd });
  159. localStorage.setItem('savedCredentials', savedCredentials);
  160. } else {
  161. const savedCredentials = localStorage.getItem('savedCredentials');
  162. if (savedCredentials) {
  163. localStorage.removeItem('savedCredentials', savedCredentials);
  164. }
  165. }
  166. // console.log('loginUser JSON:', JSON.stringify(data.data));
  167. Toast.success(t('login.loginSucess'));
  168. // 需要刷新页面,否则 axios.js 文件里的 token 不会被重置
  169. // window.location.href = '/';
  170. window.location.href = '/sc/';
  171. setTimeout(() => {
  172. router.push("/home");
  173. }, 200);
  174. } else {
  175. Toast.fail(data.message);
  176. }
  177. };
  178. // 跳转注册页面
  179. const registerClick = async () => {
  180. await router.push("/register");
  181. };
  182. // 跳转忘记密码页面
  183. const forgetPassword = async () => {
  184. await router.push("/forgetpassword");
  185. };
  186. const state = reactive({
  187. isLoading: false
  188. })
  189. // 微信登录
  190. const wxLoginHandler = async () => {
  191. state.isLoading = true;
  192. try {
  193. // 用户静默授权,获取 用户信息
  194. const {data} = await getOpenid();
  195. console.log("微信登录:", data)
  196. if (data.code === "00000") {
  197. window.location.href = data.data;
  198. } else {
  199. Toast.fail('微信登录失败:' + data.message);
  200. }
  201. } catch (error) {
  202. handleError(error.message || '微信登录失败,请重试');
  203. } finally {
  204. state.isLoading = false;
  205. }
  206. }
  207. const isInWeChat = computed(() => {
  208. const ua = window.navigator.userAgent.toLowerCase();
  209. return new RegExp('micromessenger').test(ua);
  210. });
  211. const handleError = (errMsg) => {
  212. Dialog.alert({
  213. title: '错误提示',
  214. message: errMsg
  215. })
  216. }
  217. return {
  218. checked,
  219. userName,
  220. userPwd,
  221. onSubmit,
  222. registerClick,
  223. forgetPassword,
  224. sys,
  225. compLang,
  226. languageClk,
  227. isInWeChat,
  228. state,
  229. wxLoginHandler,
  230. getOpenid,
  231. };
  232. },
  233. components: {
  234. sHeader,
  235. [Button.name]: Button,
  236. [Dialog.name]: Dialog
  237. },
  238. };
  239. </script>
  240. <style lang="less" scoped>
  241. @import "../common/style/mixin";
  242. </style>