Sfoglia il codice sorgente

新增 忘记密码;修改密码;修改邮箱功能

wzg 1 anno fa
parent
commit
157d81dc79
6 ha cambiato i file con 546 aggiunte e 137 eliminazioni
  1. 20 0
      src/apis/fetch.js
  2. 233 35
      src/components/Header.vue
  3. 1 1
      src/main.js
  4. 8 0
      src/router/index.js
  5. 97 101
      src/views/index/Login.vue
  6. 187 0
      src/views/index/forgetPassword.vue

+ 20 - 0
src/apis/fetch.js

@@ -460,4 +460,24 @@ export default {
   getIndexSelect(data) {
     return $http("/pc/index/select", data);
   },
+
+  // 发送验证码
+  sendEmailVerifyCode(data) {
+    return $http("/mail/send/verification", data);
+  },
+
+  // 修改密码(已登录)
+  changePassword(data) {
+    return $http("/user/change/password", data);
+  },
+
+  // 忘记密码(未登录)
+  forgetPassword(data) {
+    return $http("/user/forget/password", data);
+  },
+
+  // 修改登录子账户邮箱
+  changeSubAccountEmail(data) {
+    return $http("/user/proxy/update/email", data);
+  },
 };

+ 233 - 35
src/components/Header.vue

@@ -13,7 +13,103 @@
     </div>
     <div class="right">
       <img class="user-icon" src="../assets/user.png" alt="" />
-      <div class="user">{{ contactName }}</div>
+      <el-dropdown>
+        <span class="user">
+          {{ contactName }}
+        </span>
+        <template #dropdown>
+          <el-dropdown-menu>
+            <el-dropdown-item
+              @click="(changeModelVisible = true), (modelType = 'password')"
+            >
+              修改密码
+            </el-dropdown-item>
+            <el-dropdown-item
+              @click="(changeModelVisible = true), (modelType = 'email')"
+            >
+              修改邮箱
+            </el-dropdown-item>
+          </el-dropdown-menu>
+        </template>
+      </el-dropdown>
+      <el-dialog
+        v-model="changeModelVisible"
+        :title="modelType == 'email' ? '修改邮箱' : '修改密码'"
+        width="500px"
+        @close="reset()"
+      >
+        <el-form
+          ref="ruleFormRef"
+          :model="ruleForm"
+          :rules="rules"
+          label-width="120px"
+        >
+          <el-form-item label="当前邮箱">
+            {{ email }}
+          </el-form-item>
+          <el-form-item v-if="modelType == 'email'" label="新邮箱" prop="email">
+            <el-input
+              style="width: 300px"
+              v-model="ruleForm.email"
+              placeholder="请输入新邮箱"
+            ></el-input>
+          </el-form-item>
+          <el-form-item
+            v-if="modelType == 'password'"
+            label="验证码"
+            prop="verificationCode"
+          >
+            <el-input
+              style="width: 160px"
+              v-model="ruleForm.verificationCode"
+              placeholder="请输入验证码"
+            ></el-input>
+            <el-button
+              style="width: 120px"
+              class="ml20"
+              size="small"
+              type="primary"
+              @click="getCode"
+              :disabled="send"
+              :loading="send"
+            >
+              {{ send ? seconds + "秒后重发" : "获取验证码" }}
+            </el-button>
+          </el-form-item>
+          <el-form-item
+            v-if="modelType == 'password'"
+            label="新密码"
+            prop="newPassword"
+          >
+            <el-input
+              style="width: 300px"
+              v-model="ruleForm.newPassword"
+              placeholder="请输入新密码"
+            ></el-input>
+          </el-form-item>
+          <el-form-item
+            v-if="modelType == 'password'"
+            label="确认新密码"
+            prop="password2"
+          >
+            <el-input
+              style="width: 300px"
+              v-model="ruleForm.password2"
+              placeholder="请确认新密码"
+            ></el-input>
+          </el-form-item>
+        </el-form>
+        <div class="df aic jcc">
+          <el-button
+            class="mr20"
+            type="primary"
+            @click="changeModelVisible = false"
+          >
+            取消
+          </el-button>
+          <el-button type="primary" @click="submitForm()">确定</el-button>
+        </div>
+      </el-dialog>
       <el-popover placement="bottom" trigger="hover" :width="280">
         <div
           style="
@@ -55,50 +151,152 @@
     </div>
   </div>
 </template>
-<script>
+<script setup>
 import store from "../store";
 import router from "../router";
 import { onMounted, ref } from "vue";
 import { AnonymousLogin, tcb } from "../apis/cloudLogin";
+import { ElMessage, ElNotification } from "element-plus";
+import api from "../apis/fetch";
+import md5 from "md5";
 const db = tcb.database();
 const v = db.collection("huihenduo_versions");
 const __ = db.command;
 
-export default {
-  setup() {
-    let contactName = localStorage.contactName;
-    function quit() {
-      localStorage.clear();
-      store.commit("changeLogin", false);
-      router.push({ path: "/login" });
-    }
-    let timelineData = ref([]);
-    onMounted(() => {
-      cloudLogin();
-    });
-    async function getAbledVersions() {
-      let res = await v
-        .aggregate()
-        .match({ deleted: __.neq(true) })
-        .sort({
-          createTime: -1,
-        })
-        .limit(10)
-        .end();
-      timelineData.value = res.data;
-    }
+let contactName = localStorage.contactName;
+function quit() {
+  localStorage.clear();
+  store.commit("changeLogin", false);
+  router.push({ path: "/login" });
+}
+let timelineData = ref([]);
 
-    async function cloudLogin() {
-      await AnonymousLogin();
-      getAbledVersions();
-    }
-    return {
-      quit,
-      contactName,
-      timelineData,
-    };
-  },
+async function getAbledVersions() {
+  let res = await v
+    .aggregate()
+    .match({ deleted: __.neq(true) })
+    .sort({
+      createTime: -1,
+    })
+    .limit(10)
+    .end();
+  timelineData.value = res.data;
+}
+
+async function cloudLogin() {
+  await AnonymousLogin();
+  getAbledVersions();
+}
+
+let changeModelVisible = ref(false);
+const email = localStorage.email;
+const ruleFormRef = ref(null);
+const ruleForm = ref({
+  email: "",
+  verificationCode: "",
+  newPassword: "",
+});
+const rules = {
+  email: [
+    { required: true, message: "请输入邮箱地址", trigger: "blur" },
+    {
+      type: "email",
+      message: "请输入正确的邮箱地址",
+      trigger: ["blur", "change"],
+    },
+  ],
+  newPassword: [{ required: true, message: "请输入密码", trigger: "blur" }],
+  password2: [{ required: true, message: "请输入密码", trigger: "blur" }],
+  verificationCode: [
+    { required: true, message: "请输入验证码", trigger: "blur" },
+  ],
 };
+function submitForm() {
+  ruleFormRef.value.validate(async (valid) => {
+    if (valid) {
+      if (modelType.value == "email") {
+        let { data } = await api.changeSubAccountEmail({
+          email: ruleForm.value.email,
+        });
+        if (data.status === 0) {
+          ElNotification({
+            title: "提示",
+            message: "重置成功!",
+            type: "success",
+          });
+          changeModelVisible.value = false;
+        } else {
+          ElMessage({
+            title: "提示",
+            message: data.msg,
+            type: "warning",
+          });
+        }
+      } else if (modelType.value == "password") {
+        if (ruleForm.value.newPassword !== ruleForm.value.password2) {
+          ElMessage({
+            title: "提示",
+            message: "两次密码不一致",
+            type: "warning",
+          });
+          return;
+        }
+        let { data } = await api.changePassword({
+          verificationCode: ruleForm.value.verificationCode,
+          newPassword: md5(md5(ruleForm.value.newPassword)),
+        });
+        if (data.status === 0) {
+          ElNotification({
+            title: "提示",
+            message: data.msg,
+            type: "success",
+          });
+          changeModelVisible.value = false;
+
+          quit();
+        } else {
+          ElMessage({
+            title: "提示",
+            message: data.msg,
+            type: "warning",
+          });
+        }
+      }
+    }
+  });
+}
+function reset() {
+  ruleForm.value = {};
+}
+const modelType = ref("");
+
+const send = ref(false);
+const seconds = ref(10);
+async function getCode() {
+  send.value = true;
+  let { data } = await api.sendEmailVerifyCode({
+    email: localStorage.email,
+    verificationType: 2,
+  });
+  if (data.status === 0) {
+    ElMessage({
+      title: "提示",
+      message: "验证码已发送,请注意查收",
+      type: "success",
+    });
+    let timer = setInterval(() => {
+      seconds.value--;
+      if (seconds.value <= 0) {
+        clearInterval(timer);
+        send.value = false;
+        seconds.value = 10;
+      }
+    }, 1000);
+  }
+}
+onMounted(() => {
+  cloudLogin();
+});
 </script>
 <style scoped>
 .header {

+ 1 - 1
src/main.js

@@ -56,7 +56,7 @@ router.beforeEach(async (to, from, next) => {
     }
   } else {
     store.commit("changeLogin", false);
-    if (to.path == "/login") {
+    if (to.path == "/login" || to.path == "/forgetPassword") {
       next();
     } else {
       next("/login");

+ 8 - 0
src/router/index.js

@@ -27,6 +27,14 @@ const router = createRouter({
       },
       component: Login,
     },
+    {
+      path: "/forgetPassword",
+      name: "forgetPassword",
+      meta: {
+        title: "忘记密码",
+      },
+      component: () => import("../views/index/forgetPassword.vue"),
+    },
     {
       path: "/voyage/voyageDetail",
       name: "voyageDetail",

+ 97 - 101
src/views/index/Login.vue

@@ -44,6 +44,19 @@
                 登录
               </el-button>
             </el-form-item>
+
+            <div
+              style="
+                text-align: center;
+                text-decoration: underline;
+                color: #999;
+                font-size: 14px;
+                cursor: pointer;
+              "
+              @click="router.push('/forgetPassword')"
+            >
+              忘记密码
+            </div>
           </el-form>
         </div>
         <div class="df aic jcc" style="margin-top: 55px">
@@ -72,7 +85,7 @@
     </div>
   </div>
 </template>
-<script>
+<script setup>
 import { ref, reactive, toRefs, computed } from "vue";
 import { ElNotification } from "element-plus";
 import store from "../../store";
@@ -81,112 +94,95 @@ import router from "../../router";
 import md5 from "md5";
 import api from "../../apis/fetch";
 
-export default {
-  setup() {
-    const form = ref(null);
-    const ruleForm = reactive({
-      ruleForm: {
-        phone: "",
-        password: "",
-      },
-    });
+const form = ref(null);
+const ruleForm = ref({
+  phone: "",
+  password: "",
+});
 
-    const rules = reactive({
-      rules: {
-        phone: [
-          { required: true, message: "请输入手机号", trigger: "blur" },
-          { min: 11, max: 11, message: "请正确输入手机号", trigger: "blur" },
-        ],
-        password: [
-          { required: true, message: "请输入密码", trigger: "blur" },
-          { min: 6, max: 20, message: "请正确输入手机号", trigger: "blur" },
-        ],
-      },
-    });
-    function check() {
-      // form.value.validate((valid) => {});
-    }
-    function login() {
-      form.value.validate(async (valid) => {
-        if (valid) {
-          let { phone, password } = ruleForm.ruleForm;
-          let res = await api.staffLogin({
-            phone,
-            // password: md5(password).toUpperCase(),
-            password,
-            // proxyId: 31,
+const rules = ref({
+  phone: [
+    { required: true, message: "请输入手机号", trigger: "blur" },
+    { min: 11, max: 11, message: "请正确输入手机号", trigger: "blur" },
+  ],
+  password: [
+    { required: true, message: "请输入密码", trigger: "blur" },
+    { min: 6, max: 20, message: "请正确输入手机号", trigger: "blur" },
+  ],
+});
+function check() {
+  // form.value.validate((valid) => {});
+}
+function login() {
+  form.value.validate(async (valid) => {
+    if (valid) {
+      let { phone, password } = ruleForm.value;
+      let res = await api.staffLogin({
+        phone,
+        // password: md5(password).toUpperCase(),
+        password: md5(md5(password)),
+        // proxyId: 31,
+      });
+      if (res.data.status == 0) {
+        let {
+          userId,
+          userName,
+          phone,
+          contactName,
+          loginAccountId,
+          rolePermission,
+          email,
+        } = res.data.result;
+        if (!rolePermission.length) {
+          ElNotification.error({
+            title: "失败",
+            duration: 2000,
+            message: "暂无权限,请联系管理员",
+            type: "error",
           });
-          if (res.data.status == 0) {
-            let {
-              userId,
-              userName,
-              phone,
-              contactName,
-              loginAccountId,
-              rolePermission,
-            } = res.data.result;
-            if (!rolePermission.length) {
-              ElNotification.error({
-                title: "失败",
-                duration: 2000,
-                message: "暂无权限,请联系管理员",
-                type: "error",
-              });
-              return;
-            }
-            ElNotification.success({
-              title: "成功",
-              duration: 2000,
-              message: res.data.msg,
-              type: "success",
-            });
-            localStorage.setItem("userId", userId);
-            localStorage.setItem("userName", userName);
-            localStorage.setItem("phone", phone);
-            localStorage.setItem("contactName", contactName);
-            localStorage.setItem("userType", 1);
-            localStorage.setItem("loginAccountId", loginAccountId);
-            rolePermission = rolePermission || [];
-            let arr = [...new Set([...rolePermission])];
-            localStorage.setItem("rolePermission", arr);
-            store.dispatch(
-              "GetBasePermissionData",
-              localStorage.loginAccountId
-            );
-            let res1 = await store.dispatch(
-              "GetUserPermission",
-              localStorage.loginAccountId
-            );
-
-            router.replace("/index");
-            store.commit("changeLogin", true);
-          } else {
-            ElNotification.error({
-              title: "错误",
-              duration: 3000,
-              message: res.data.msg,
-            });
-          }
-        } else {
-          console.log("error submit!!");
-          return false;
+          return;
         }
-      });
-    }
+        ElNotification.success({
+          title: "成功",
+          duration: 2000,
+          message: res.data.msg,
+          type: "success",
+        });
+        localStorage.setItem("userId", userId);
+        localStorage.setItem("userName", userName);
+        localStorage.setItem("phone", phone);
+        localStorage.setItem("contactName", contactName);
+        localStorage.setItem("userType", 1);
+        localStorage.setItem("email", email);
+        localStorage.setItem("loginAccountId", loginAccountId);
+        rolePermission = rolePermission || [];
+        let arr = [...new Set([...rolePermission])];
+        localStorage.setItem("rolePermission", arr);
+        store.dispatch("GetBasePermissionData", localStorage.loginAccountId);
+        let res1 = await store.dispatch(
+          "GetUserPermission",
+          localStorage.loginAccountId
+        );
 
-    function goBeian() {
-      window.open("https://beian.miit.gov.cn/");
+        router.replace("/index");
+        store.commit("changeLogin", true);
+      } else {
+        ElNotification.error({
+          title: "错误",
+          duration: 3000,
+          message: res.data.msg,
+        });
+      }
+    } else {
+      console.log("error submit!!");
+      return false;
     }
+  });
+}
 
-    return {
-      form,
-      ...toRefs(ruleForm),
-      ...toRefs(rules),
-      login,
-      goBeian,
-    };
-  },
-};
+function goBeian() {
+  window.open("https://beian.miit.gov.cn/");
+}
 </script>
 <style scoped>
 .container {

+ 187 - 0
src/views/index/forgetPassword.vue

@@ -0,0 +1,187 @@
+<template>
+  <div style="background: #f2f2f2; height: 100vh">
+    <div
+      style="
+        background: #fff;
+        height: 60px;
+        line-height: 60px;
+        font-size: 24px;
+        color: #0094fe;
+        padding-left: 60px;
+      "
+    >
+      汇很多科技 |
+      <span style="font-size: 20px">忘记密码</span>
+    </div>
+    <el-card style="width: 620px; margin: 100px auto">
+      <template #header>
+        <div class="card-header">
+          <span>忘记密码</span>
+        </div>
+        <el-form
+          ref="ruleFormRef"
+          :model="ruleForm"
+          :rules="rules"
+          label-width="120px"
+        >
+          <el-form-item label="邮箱" prop="email">
+            <el-input
+              style="width: 300px"
+              v-model="ruleForm.email"
+              placeholder="请输入邮箱"
+            ></el-input>
+          </el-form-item>
+          <el-form-item label="验证码" prop="verificationCode">
+            <el-input
+              style="width: 300px"
+              v-model="ruleForm.verificationCode"
+              placeholder="请输入验证码"
+            ></el-input>
+            <el-button
+              style="width: 120px"
+              class="ml20"
+              size="small"
+              type="primary"
+              @click="getCode"
+              :disabled="send"
+              :loading="send"
+            >
+              {{ send ? seconds + "秒后重发" : "获取验证码" }}
+            </el-button>
+          </el-form-item>
+          <el-form-item label="新密码" prop="newPassword">
+            <el-input
+              style="width: 300px"
+              v-model="ruleForm.newPassword"
+              placeholder="请输入新密码"
+            ></el-input>
+          </el-form-item>
+          <el-form-item label="确认密码" prop="password2">
+            <el-input
+              style="width: 300px"
+              v-model="ruleForm.password2"
+              placeholder="请输入确认密码"
+            ></el-input>
+          </el-form-item>
+        </el-form>
+        <div class="df aic jcc">
+          <el-button
+            style="width: 120px; margin-right: 50px"
+            size="small"
+            type="primary"
+            @click="goBack()"
+          >
+            返回
+          </el-button>
+          <el-button
+            style="width: 120px"
+            size="small"
+            type="primary"
+            @click="submitForm(ruleFormRef)"
+          >
+            确定
+          </el-button>
+        </div>
+      </template>
+    </el-card>
+  </div>
+</template>
+<script setup>
+import { ref, reactive, toRefs, computed, onMounted, inject } from "vue";
+import { ElMessage, ElNotification } from "element-plus";
+import store from "../../store";
+import router from "../../router";
+
+import md5 from "md5";
+import api from "../../apis/fetch";
+import downloadBlobFile from "../../utils/downloadBlobFile";
+import url from "../../apis/config";
+const ruleFormRef = ref(null);
+const ruleForm = ref({});
+const rules = ref({
+  email: [
+    { required: true, message: "请输入邮箱", trigger: "blur" },
+    {
+      type: "email",
+      message: "请输入正确的邮箱地址",
+      trigger: ["blur", "change"],
+    },
+  ],
+  verificationCode: [
+    { required: true, message: "请输入验证码", trigger: "blur" },
+  ],
+  newPassword: [{ required: true, message: "请输入密码", trigger: "blur" }],
+  password2: [{ required: true, message: "请输入确认密码", trigger: "blur" }],
+});
+const send = ref(false);
+const seconds = ref(10);
+async function getCode() {
+  if (!ruleForm.value.email) {
+    ElMessage({
+      title: "提示",
+      message: "请输入邮箱",
+      type: "warning",
+    });
+    return;
+  }
+  send.value = true;
+
+  let { data } = await api.sendEmailVerifyCode({
+    email: ruleForm.value.email,
+    verificationType: 1,
+  });
+  if (data.status === 0) {
+    ElMessage({
+      title: "提示",
+      message: "验证码已发送,请注意查收",
+      type: "success",
+    });
+    let timer = setInterval(() => {
+      seconds.value--;
+      if (seconds.value <= 0) {
+        clearInterval(timer);
+        send.value = false;
+        seconds.value = 10;
+      }
+    }, 1000);
+  }
+}
+function goBack() {
+  router.push("/login");
+}
+function submitForm() {
+  ruleFormRef.value.validate(async (valid) => {
+    if (valid) {
+      if (ruleForm.value.newPassword !== ruleForm.value.password2) {
+        ElMessage({
+          title: "提示",
+          message: "两次密码不一致",
+          type: "warning",
+        });
+        return;
+      }
+      let { data } = await api.forgetPassword({
+        email: ruleForm.value.email,
+        verificationCode: ruleForm.value.verificationCode,
+        newPassword: md5(md5(ruleForm.value.newPassword)),
+      });
+      if (data.status === 0) {
+        ElNotification({
+          title: "提示",
+          message: "重置成功,请重新登录!",
+          type: "success",
+        });
+        router.replace("/login");
+      } else {
+        ElMessage({
+          title: "提示",
+          message: data.msg,
+          type: "warning",
+        });
+      }
+    }
+  });
+}
+</script>
+
+<style scoped></style>