mobile.vue 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <template>
  2. <el-form ref="loginForm" :model="form" :rules="rules" label-width="0" label-position="top" size="large" @keyup.enter="login">
  3. <el-form-item prop="phone" :label="$t('login.mobilePlaceholder')">
  4. <el-input v-model="form.phone" prefix-icon="el-icon-iphone" clearable :placeholder="$t('login.mobilePlaceholder')">
  5. <template #prepend>+86</template>
  6. </el-input>
  7. </el-form-item>
  8. <el-form-item prop="yzm" :label="$t('login.smsPlaceholder')">
  9. <div class="login-msg-yzm">
  10. <el-input v-model="form.yzm" prefix-icon="el-icon-unlock" clearable :placeholder="$t('login.smsPlaceholder')"></el-input>
  11. <el-button @click="getYzm" :disabled="disabled">{{this.$t('login.smsGet')}}<span v-if="disabled"> ({{time}})</span></el-button>
  12. </div>
  13. </el-form-item>
  14. <el-form-item prop="code" :label="$t('login.code')">
  15. <el-input v-model="form.code" :placeholder="$t('login.codeErr')">
  16. <template #suffix>
  17. <el-tooltip placement="top-start" :content="$t('login.codeTips')">
  18. <div class="captcha" @click="updateCaptcha"><img :src="captcha.base64" /></div>
  19. </el-tooltip>
  20. </template>
  21. </el-input>
  22. </el-form-item>
  23. <el-form-item prop="privacy">
  24. <el-checkbox :label="$t('login.rememberMe')" v-model="form.privacy">
  25. <template #default>
  26. <div class="privacy">我已阅读并同意<span @click="showPrivacy">《隐私协议》</span></div>
  27. </template>
  28. </el-checkbox>
  29. </el-form-item>
  30. <el-form-item>
  31. <el-button type="primary" size="large" style="width: 100%;" :loading="islogin" @click="login">{{ $t('login.signIn') }}</el-button>
  32. </el-form-item>
  33. </el-form>
  34. <el-dialog title="隐私协议" v-model="visible" :width="680" destroy-on-close :close-on-click-modal="false" :show-close="false">
  35. <div class="showPrivacy">
  36. <div v-html="baseData.privacy"></div>
  37. </div>
  38. <template #footer>
  39. <el-button type="primary" @click="showPrivacyState">我已阅读并同意</el-button>
  40. </template>
  41. </el-dialog>
  42. </template>
  43. <script>
  44. export default {
  45. emits: ['success', 'upCaptcha'],
  46. props: ['baseData',"captcha"],
  47. data() {
  48. return {
  49. form: {
  50. phone: "",
  51. yzm: "",
  52. },
  53. rules: {
  54. phone: [
  55. { required: true, message: this.$t('login.mobileError'), trigger: 'blur' },
  56. {
  57. validator: (rule, value, callback) => {
  58. const phoneReg = /^1[3-9]\d{9}$/ // 手机号正则
  59. const landlineReg = /^(?:(?:\d{3}-)?\d{8}|^(?:\d{4}-)?\d{7,8})(?:-\d+)?$/
  60. if (!value) {
  61. callback(new Error('请输入联系方式'))
  62. } else if (!phoneReg.test(value) && !landlineReg.test(value)) {
  63. callback(new Error('请输入有效的手机号码号码'))
  64. } else {
  65. callback()
  66. }
  67. },
  68. trigger: 'blur'
  69. }
  70. ],
  71. yzm: [
  72. {required: true, message: this.$t('login.smsError')}
  73. ],
  74. code: [
  75. { required: true, message: this.$t('login.codeErr'), trigger: 'blur' }
  76. ],
  77. privacy: [
  78. { required: true, message: this.$t('login.privacy'), trigger: 'change' }
  79. ]
  80. },
  81. disabled: false,
  82. time: 0,
  83. islogin: false,
  84. visible:false,
  85. isShow:false
  86. }
  87. },
  88. mounted() {
  89. },
  90. methods: {
  91. updateCaptcha(){
  92. this.$emit("upCaptcha");
  93. },
  94. showPrivacy(){
  95. this.visible = true;
  96. },
  97. showPrivacyState(){
  98. if (this.form.privacy == false) {
  99. this.form.privacy = true;
  100. }
  101. this.visible = false;
  102. },
  103. onClose() {
  104. this.isShow = false;
  105. },
  106. async onSuccess(){
  107. this.isShow = false;
  108. },
  109. getYzm(){
  110. var field = ["phone","code"];
  111. this.$refs.loginForm.validateField(field, async (valid) => {
  112. if(!valid){
  113. return false
  114. }
  115. var resp = await this.$API.auth.sms.post({"mobile":this.form.phone,"code":this.form.code,"key":this.captcha.key,"scene":"login"});
  116. if (resp.code == 0) {
  117. return this.$message.error(resp.msg);
  118. }
  119. this.$message.success(resp.msg)
  120. this.disabled = true
  121. this.time = 60
  122. var t = setInterval(() => {
  123. this.time -= 1
  124. if(this.time < 1){
  125. clearInterval(t)
  126. this.disabled = false
  127. this.time = 0
  128. }
  129. },1000)
  130. })
  131. },
  132. async login(){
  133. var validate = await this.$refs.loginForm.validate().catch(()=>{})
  134. if(!validate){ return false }
  135. this.isShow = false;
  136. this.islogin = true
  137. var data = {
  138. mobile: this.form.phone,
  139. code: this.form.yzm,
  140. scene: "login",
  141. }
  142. //获取token
  143. var user = await this.$API.auth.mobile.post(data)
  144. if (user.code == 1) {
  145. this.$TOOL.cookie.set("TOKEN", user.data.access_token, {
  146. expires: user.data.expires_in
  147. })
  148. } else {
  149. this.islogin = false
  150. this.$message.error(user.msg)
  151. return false
  152. }
  153. //获取菜单
  154. var menu = await this.$API.menu.list.get()
  155. if (menu.code == 1) {
  156. if (menu.data.menu.length == 0) {
  157. this.islogin = false
  158. this.$alert("当前用户无任何菜单权限,请联系系统管理员", "无权限访问", {
  159. type: 'error',
  160. center: true
  161. })
  162. return false
  163. }
  164. var userData = await this.$API.auth.user.get()
  165. if (userData.code == 0) {
  166. this.islogin = false
  167. this.$alert("当前用户无任何菜单权限,请联系系统管理员", "无权限访问", {
  168. type: 'error',
  169. center: true
  170. })
  171. return false
  172. }
  173. if (userData.data.is_mch == 2) {
  174. this.$store.commit("SET_layout", "header")
  175. } else {
  176. this.$store.commit("TOGGLE_layoutTags")
  177. }
  178. this.$TOOL.data.set("USER_TYPE", userData.data.type)
  179. this.$TOOL.data.set("USER_INFO", userData.data)
  180. this.$TOOL.data.set("MENU", menu.data.menu)
  181. this.$TOOL.data.set("PERMISSIONS", menu.data.permissions)
  182. this.$TOOL.data.set("DASHBOARDGRID", menu.data.dashboardGrid)
  183. } else {
  184. this.islogin = false
  185. this.$message.warning(menu.message)
  186. return false
  187. }
  188. var userType = userData.data.type;
  189. var dashboard = "/dashboard";
  190. if (userType == 1) {
  191. dashboard = "/manage/dashboard";
  192. } else if (userType == 2) {
  193. dashboard = "/merchant/dashboard";
  194. } else if (userType == 3) {
  195. dashboard = "/store/dashboard";
  196. } else if (userType == 4) {
  197. dashboard = "/factory/dashboard";
  198. }
  199. this.$emit("success");
  200. this.$message.success(user.msg)
  201. this.islogin = false;
  202. this.$router.replace({
  203. path: dashboard
  204. })
  205. }
  206. }
  207. }
  208. </script>
  209. <style>
  210. .privacy {
  211. color: #333;
  212. }
  213. .privacy span {
  214. color: #f00;
  215. }
  216. .showPrivacy {
  217. max-height: 500px;
  218. overflow: hidden;
  219. overflow-y: scroll;
  220. line-height: 1.5;
  221. }
  222. .el-input--large .el-input__wrapper{
  223. position: relative;
  224. }
  225. .captcha{
  226. display: flex;
  227. align-items: center;
  228. cursor: pointer;
  229. position: absolute;
  230. right: 1px;
  231. top: 1px;
  232. bottom: 1px;
  233. z-index: 99;
  234. }
  235. .captcha img{
  236. height: 38px;
  237. border-radius: 5px;
  238. }
  239. </style>