Browse Source

feat: #初始登录

loki 3 years ago
parent
commit
2098bdf4a8
10 changed files with 217 additions and 82 deletions
  1. 2 1
      .env.development
  2. 19 0
      src/api/banner.js
  3. 18 3
      src/api/user.js
  4. 7 0
      src/main.js
  5. 5 3
      src/store/modules/user.js
  6. 35 0
      src/utils/message.js
  7. 13 6
      src/utils/request.js
  8. 3 4
      src/utils/validate.js
  9. 114 64
      src/views/login/index.vue
  10. 1 1
      vue.config.js

+ 2 - 1
.env.development

@@ -2,5 +2,6 @@
 ENV = 'development'
 
 # base api
-VUE_APP_BASE_API = '/dev-api'
+VUE_APP_BASE_API = 'http://127.0.0.1:18080/'
+# VUE_APP_BASE_API = 'http://localhost:18080/'
 VUE_APP_API_TIMEOUT = 30000

+ 19 - 0
src/api/banner.js

@@ -0,0 +1,19 @@
+import api from '@/utils/request';
+
+export const iGetList = params =>
+	api.post(`/yxl-back-end/admin/banner/page`, params);
+
+export const iGetItem = ({ id, ...params }) =>
+	api.get(`/yxl-back-end/admin/banner/${id}`);
+
+export const iDelItem = ({ id, ...params }) =>
+	api.del(`/yxl-back-end/admin/banner/del/${id}`, params);
+
+export const iGetTotalNum = ({ id, ...params }) =>
+	api.del(`/yxl-back-end/admin/banner/del/${id}`, params);
+
+export const iUpdateItem = params =>
+	api.post(`/yxl-back-end/admin/banner/save`, params);
+
+export const iShowItem = ({ id, ...params }) =>
+	api.post(`/yxl-back-end/admin/banner/show/${id}`, params);

+ 18 - 3
src/api/user.js

@@ -1,8 +1,23 @@
 import api from '@/utils/request';
 
+// export const login = params =>
+//   api.post(`/vue-admin-template/user/login`, params);
+// export const getInfo = params =>
+//   api.get(`/vue-admin-template/user/info`, { token: params });
+// export const logout = params =>
+//   api.post(`/vue-admin-template/user/logout`, params);
+
 export const login = params =>
-  api.post(`/vue-admin-template/user/login`, params);
+  api.post(`/yxl-back-end/framework/uiac/admin/sign-in`, params);
 export const getInfo = params =>
-  api.get(`/vue-admin-template/user/info`, { token: params });
+  api.get(`/yxl-back-end/framework/uiac/admin/myself`, { token: params });
 export const logout = params =>
-  api.post(`/vue-admin-template/user/logout`, params);
+  api.post(`/yxl-back-end/framework/uiac/admin/logout`, params);
+
+export const getImgCode = params =>
+  api.get(
+    `/yxl-back-end/framework/uiac/admin/mobile-number-sms/img-code`,
+    params
+  );
+export const getSMSCode = params =>
+  api.post(`/yxl-back-end/framework/uiac/admin/mobile-number-sms/code`, params);

+ 7 - 0
src/main.js

@@ -18,6 +18,8 @@ import '@/permission'; // permission control
 import './components';
 import './containers';
 
+import message from '@/utils/message';
+
 /**
  * If you don't want to use mock-server
  * you want to use MockJs for mock api
@@ -38,6 +40,11 @@ Vue.use(ElementUI, { size: 'small', zIndex: 3000 });
 
 Vue.config.productionTip = false;
 
+// 提示
+Vue.prototype.$success = message.success;
+Vue.prototype.$error = message.error;
+Vue.prototype.$warning = message.warning;
+
 new Vue({
   el: '#app',
   router,

+ 5 - 3
src/store/modules/user.js

@@ -34,11 +34,13 @@ const mutations = {
 const actions = {
   // user login
   login({ commit }, userInfo) {
-    const { username, password } = userInfo;
+    console.log(userInfo);
+    const { phone, code } = userInfo;
     return new Promise((resolve, reject) => {
       login({
-        username: username.trim(),
-        password: password
+        account: phone,
+        signInType: 'MOBILE_NUMBER_SMS',
+        smsCode: code
       })
         .then(response => {
           const { data } = response;

+ 35 - 0
src/utils/message.js

@@ -0,0 +1,35 @@
+import { Message } from 'element-ui';
+
+const info = msg => {
+  Message({
+    message: msg,
+    type: 'info',
+    duration: 5 * 1000
+  });
+};
+
+const success = msg => {
+  Message({
+    message: msg,
+    type: 'success',
+    duration: 5 * 1000
+  });
+};
+
+const warning = msg => {
+  Message({
+    message: msg,
+    type: 'warning',
+    duration: 5 * 1000
+  });
+};
+
+const error = msg => {
+  Message({
+    message: msg,
+    type: 'error',
+    duration: 5 * 1000
+  });
+};
+
+export default { success, info, warning, error };

+ 13 - 6
src/utils/request.js

@@ -111,7 +111,7 @@ const formatResponse = fetchResult =>
  */
 const formatStatus = response => {
   // 如果http状态码正常,则直接返回数据
-  if (response && (response.code === 200 || response.code === 20000)) {
+  if (response && response.code === 200) {
     response.success = true;
     return response;
     // 如果不需要除了data之外的数据,可以直接 return response.data
@@ -166,12 +166,19 @@ const formatCode = ({ code, data, msg }) => {
   //     data: {}
   //   }
   // }
-  console.log();
+  if (code !== 200) {
+    return {
+      code: code,
+      success: false,
+      msg,
+      data: {}
+    };
+  }
   return {
-    success: true,
-    msg: msg || '',
-    code,
-    data
+    success: data.code === 200,
+    msg: data.msg,
+    code: data.code,
+    data: data.data
   };
 };
 

+ 3 - 4
src/utils/validate.js

@@ -7,14 +7,13 @@
  * @returns {Boolean}
  */
 export function isExternal(path) {
-  return /^(https?:|mailto:|tel:)/.test(path)
+  return /^(https?:|mailto:|tel:)/.test(path);
 }
 
 /**
  * @param {string} str
  * @returns {Boolean}
  */
-export function validUsername(str) {
-  const valid_map = ['admin', 'editor']
-  return valid_map.indexOf(str.trim()) >= 0
+export function validPhone(str) {
+  return /^1\d{10}$/.test(str);
 }

+ 114 - 64
src/views/login/index.vue

@@ -13,100 +13,106 @@
         <p class="title-tip">管理后台</p>
       </div>
 
-      <el-form-item prop="username">
-        <span class="svg-container">
-          <svg-icon icon-class="user" />
-        </span>
+      <el-form-item prop="phone">
         <el-input
-          ref="username"
-          v-model="loginForm.username"
-          placeholder="请输入用户名"
-          name="username"
+          ref="phone"
+          v-model="loginForm.phone"
+          placeholder="请输入手机号"
+          name="phone"
           type="text"
           tabindex="1"
           auto-complete="on"
-        />
+          prefix-icon="el-icon-phone"
+        >
+          <el-button
+            slot="suffix"
+            class="inline-btn"
+            type="primary"
+            :disabled="!validPhone(loginForm.phone)"
+            @click="dialogVisible = true"
+          >
+            获取验证码
+          </el-button>
+        </el-input>
       </el-form-item>
 
-      <el-form-item prop="password">
-        <span class="svg-container">
-          <svg-icon icon-class="password" />
-        </span>
+      <el-form-item prop="code">
         <el-input
-          :key="passwordType"
-          ref="password"
-          v-model="loginForm.password"
-          :type="passwordType"
-          placeholder="请输入密码"
-          name="password"
-          tabindex="2"
-          auto-complete="on"
-          @keyup.enter.native="handleLogin"
-        />
-        <span class="show-pwd" @click="showPwd">
-          <svg-icon
-            :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'"
-          />
-        </span>
+          ref="code"
+          v-model="loginForm.code"
+          placeholder="请输入手机验证码"
+          name="code"
+          type="text"
+          tabindex="1"
+          prefix-icon="el-icon-chat-dot-round"
+        >
+        </el-input>
       </el-form-item>
 
       <el-button
         :loading="loading"
         type="primary"
-        style="width:100%;margin-bottom:30px;"
+        style="width:100%;margin-bottom:30px;font-size: 20px;"
         @click.native.prevent="handleLogin"
       >
         登录
       </el-button>
-
-      <!--       <div class="tips">
-        <span style="margin-right:20px;">username: admin</span>
-        <span> password: any</span>
-      </div> -->
     </el-form>
     <div class="footer">
       copyright @ {{ new Date().getFullYear() }}
       广东帕斯融媒体科技有限公司
     </div>
+
+    <el-dialog title="真人验证" :visible.sync="dialogVisible" width="20%">
+      <div class="f-c-c f-col">
+        <img :src="info.base64Img" class="info-img" />
+        <el-input placeholder="请输入验证码" v-model="point" clearable />
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="handleGetSMS">获取验证码</el-button>
+      </span>
+    </el-dialog>
   </div>
 </template>
 
 <script>
-import { validUsername } from '@/utils/validate';
+import { validPhone } from '@/utils/validate';
+import { getImgCode, getSMSCode } from '@/api/user';
 
 export default {
   name: 'Login',
   data() {
-    const validateUsername = (rule, value, callback) => {
-      if (!validUsername(value)) {
-        callback(new Error('请输入正确的用户名'));
+    const validatePhone = (rule, value, callback) => {
+      if (!validPhone(value)) {
+        callback(new Error('请输入正确的电话号码'));
       } else {
         callback();
       }
     };
-    const validatePassword = (rule, value, callback) => {
-      if (value.length < 6) {
-        callback(new Error('请输入正确码'));
+    const validateCode = (rule, value, callback) => {
+      if (value.length !== 6) {
+        callback(new Error('请输入正确电话验证码'));
       } else {
         callback();
       }
     };
     return {
       loginForm: {
-        username: 'admin',
-        password: '111111'
+        phone: '13450765204',
+        code: ''
       },
       loginRules: {
-        username: [
-          { required: true, trigger: 'blur', validator: validateUsername }
-        ],
-        password: [
-          { required: true, trigger: 'blur', validator: validatePassword }
-        ]
+        phone: [{ required: true, trigger: 'blur', validator: validatePhone }],
+        code: [{ required: true, trigger: 'blur', validator: validateCode }]
       },
+      validPhone,
       loading: false,
-      passwordType: 'password',
-      redirect: undefined
+      redirect: undefined,
+
+      dialogVisible: false,
+      info: {},
+      point: ''
     };
   },
   watch: {
@@ -115,25 +121,34 @@ export default {
         this.redirect = route.query && route.query.redirect;
       },
       immediate: true
+    },
+    dialogVisible: {
+      handler(b) {
+        if (b) {
+          getImgCode().then(response => {
+            const { data, success } = response;
+            if (success) {
+              this.info = data;
+            } else {
+              this.$error('加载失败,请稍后重试~');
+            }
+          });
+        }
+      },
+      immediate: true
     }
   },
   methods: {
-    showPwd() {
-      if (this.passwordType === 'password') {
-        this.passwordType = '';
-      } else {
-        this.passwordType = 'password';
-      }
-      this.$nextTick(() => {
-        this.$refs.password.focus();
-      });
-    },
     handleLogin() {
+      console.log('------------');
       this.$refs.loginForm.validate(valid => {
         if (valid) {
           this.loading = true;
           this.$store
-            .dispatch('user/login', this.loginForm)
+            .dispatch(
+              'user/login',
+              Object.assign({ uuid: this.info.uuid }, this.loginForm)
+            )
             .then(() => {
               this.$router.push({ path: this.redirect || '/' });
               this.loading = false;
@@ -146,6 +161,20 @@ export default {
           return false;
         }
       });
+    },
+
+    async handleGetSMS() {
+      const { success, msg } = await getSMSCode({
+        code: this.point,
+        mobileNumber: this.loginForm.phone,
+        uuid: this.info.uuid
+      });
+      if (success) {
+        this.$success('短信已发出请稍等...');
+        this.dialogVisible = false;
+      } else {
+        this.$error(msg);
+      }
     }
   }
 };
@@ -170,14 +199,14 @@ $cursor: #666;
   .el-input {
     display: inline-block;
     height: 47px;
-    width: 85%;
+    width: 100%;
 
     input {
       background: transparent;
       border: 0px;
       -webkit-appearance: none;
       border-radius: 0px;
-      padding: 12px 5px 12px 15px;
+      padding: 12px 0 12px 40px;
       color: $light_gray;
       height: 47px;
       caret-color: $cursor;
@@ -195,6 +224,16 @@ $cursor: #666;
     border-radius: 5px;
     color: #454545;
   }
+
+  .el-input__prefix {
+    font-size: 20px;
+  }
+  .el-input__inner {
+    font-size: 16px;
+  }
+  .el-input__suffix {
+    right: 0;
+  }
 }
 </style>
 
@@ -280,4 +319,15 @@ $light_gray: #eee;
   font-size: 18px;
   color: rgba(0, 0, 0, 0.45);
 }
+
+.inline-btn {
+  width: 120px;
+  height: 100%;
+  border: none;
+}
+
+.info-img {
+  width: 130px;
+  height: 48px;
+}
 </style>

+ 1 - 1
vue.config.js

@@ -96,7 +96,7 @@ module.exports = {
       .set('utils', path.resolve('src/utils'))
       .set('views', path.resolve('src/views'));
 
-    config.when(process.env.NODE_ENV !== 'development', (config) => {
+    config.when(process.env.NODE_ENV !== 'development', config => {
       config
         .plugin('ScriptExtHtmlWebpackPlugin')
         .after('html')