Browse Source

✨ feat(Login): 增加企业微信登录功能

Pchen. 8 months ago
parent
commit
60e35b464f
4 changed files with 233 additions and 45 deletions
  1. 16 2
      src/app/lib/ServerAPI.js
  2. 0 43
      src/components/HelloWorld.vue
  3. 140 0
      src/pages/Login/Login.vue
  4. 77 0
      src/pages/Login/WXLoginStage2.vue

+ 16 - 2
src/app/lib/ServerAPI.js

@@ -99,7 +99,7 @@ class ServerAPI {
         )
     }
 
-    static Attendance(data, callback = function () { }) {
+    static EditAttendanceItems(data, callback = function () { }) {
         core.request(
             "/Attendance",
             data,
@@ -147,9 +147,10 @@ class ServerAPI {
         )
     }
 
+    //网站管理
     static UserList(uuid, session, callback = function () { }) {
         core.request(
-            "/UserList",
+            "/Admin/User",
             {
                 uuid,
                 session
@@ -159,6 +160,19 @@ class ServerAPI {
         )
     }
 
+    static SetPermission(uuid, session, userid, manage, callback = function () { }) {
+        core.request(
+            "/Admin/SetPermission",
+            {
+                uuid,
+                session, 
+                userid, 
+                manage
+            },
+            { method: 'POST' },
+            callback
+        )
+    }
 }
 
 export {

+ 0 - 43
src/components/HelloWorld.vue

@@ -1,43 +0,0 @@
-<script setup>
-import { ref } from 'vue'
-
-defineProps({
-  msg: String,
-})
-
-const count = ref(0)
-</script>
-
-<template>
-  <h1>{{ msg }}</h1>
-
-  <div class="card">
-    <button type="button" @click="count++">count is {{ count }}</button>
-    <p>
-      Edit
-      <code>components/HelloWorld.vue</code> to test HMR
-    </p>
-  </div>
-
-  <p>
-    Check out
-    <a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
-      >create-vue</a
-    >, the official Vue + Vite starter
-  </p>
-  <p>
-    Learn more about IDE Support for Vue in the
-    <a
-      href="https://vuejs.org/guide/scaling-up/tooling.html#ide-support"
-      target="_blank"
-      >Vue Docs Scaling up Guide</a
-    >.
-  </p>
-  <p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
-</template>
-
-<style scoped>
-.read-the-docs {
-  color: #888;
-}
-</style>

+ 140 - 0
src/pages/Login/Login.vue

@@ -0,0 +1,140 @@
+<template>
+    <div class="background-image">
+        <Header :color="'aliceblue'"/>
+
+        <div class="content">
+            <h1>用户登录</h1>
+            <button>企业微信一键登录</button>
+            <button @click="WXLogin('login')">企业微信扫码登录</button>
+            <div class="agreementBox">
+                <div class="checkBox">
+                    <input type="checkbox" v-model="agreement">
+                </div>
+                <div class="text">
+                    阅读并同意 <span class="bold">《使用协议》《隐私协议》</span>
+                </div>
+                <router-view></router-view>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import Header from "../../components/Header.vue";
+import { ServerAPI } from '../../app/lib/ServerAPI';
+
+let agreement = ref(false);
+
+let WXLogin = function () {
+    if (!agreement.value) {
+        ElMessage({
+            message: "请仔细阅读并同意下方使用协议和隐私协议",
+            type: 'warning'
+        });
+        return;
+    }
+
+    const num = 0; //解决一个奇怪的bug,需要登录两次
+    ServerAPI.WXWorkUrl(num, 'login', (res) => {
+        if (!res || res.code !== 0 || !res.data.url) 
+            return ElMessage.error(`请求登录失败!${res.msg}`)
+        window.location.href = res.data.url
+    });
+
+}
+
+</script>
+
+<style scoped>
+.background-image {
+    position: relative;
+    background-image: url("../../assets/img/background.jpg");
+    background-size: cover;
+    background-position: center;
+    background-repeat: no-repeat;
+    height: 100vh;
+    width: 100%;
+}
+
+.content {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    flex-direction: column;
+    background-color: rgba(255, 255, 255, 0.7);
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    height: 400px;
+    width: 650px;
+    padding: 30px;
+    box-sizing: border-box;
+    border-radius: 10px;
+}
+
+.background-image h1 {
+    color: #337ecc;
+    font-size: 2em;
+    margin: 0;
+    margin-bottom: 20px;
+}
+
+.background-image button {
+    display: block;
+    width: 100%;
+    height: 60px;
+    padding: 15px;
+    margin: 10px 0;
+    font-size: 1em;
+    border: none;
+    border-radius: 10px;
+    cursor: pointer;
+    background-color: #337ecc;
+    color: #fff;
+}
+
+.agreementBox {
+    margin-top: 10px;
+    display: flex;
+}
+
+.agreementBox .checkBox {
+    display: inline-block;
+    height: 20px;
+}
+
+.agreementBox .text {
+    margin-left: 5px;
+    display: inline;
+    font-size: 12px;
+    line-height: 20px;
+}
+
+.agreementBox .text .bold {
+    font-weight: bold;
+    color: #000;
+}
+
+@media only screen and (max-width: 768px) {
+    .content {
+        height: auto;
+        width: 80%;
+        height: 35%;
+        padding: 25px;
+    }
+
+    .background-image button {
+        height: 50px;
+    }
+
+    .background-image h1 {
+        font-size: 1.5em;
+    }
+
+    .background-image button {
+        font-size: 0.9em;
+        padding: 10px;
+    }
+}
+</style>

+ 77 - 0
src/pages/Login/WXLoginStage2.vue

@@ -0,0 +1,77 @@
+<script setup>
+import { useRoute, useRouter } from 'vue-router';
+import { App } from '../../app/app';
+import { ServerAPI } from '../../app/lib/ServerAPI';
+
+let route = useRoute();
+let router = useRouter();
+
+onMounted(async () => {
+    console.log('1')
+    const loading = ElLoading.service({
+        lock: true,
+        text: '正在登录中,请稍候'
+    })
+    // 获取当前 URL 中的 code 参数
+    const queryString = window.location.search;
+    const urlParams = new URLSearchParams(queryString);
+    const code = urlParams.get('code');
+    let num = urlParams.get('num');
+
+    //修复一个奇怪的bug 新用户企微第一次登录没有返回code
+    if (num === 0 && code === '' || code === null) {
+        num = 1
+        ServerAPI.WXWorkUrl(num, 'login', (res) => {
+            if (res == undefined || res.code != 0) {
+                ElMessage.error('请求登录失败!');
+                loading.close();
+                return;
+            }
+            loading.close();
+            window.location.href = res.data.url
+        })
+    }
+
+    try {
+        ServerAPI.WXWorkLogin(code, (res) => {
+            if (res.code !== 0) {
+                loading.close();
+                ElMessage.error('登录失败!请检查是否授予小红帽必要的权限');
+                router.replace({
+                    name: "Login",
+                })
+                return;
+            }
+
+            loading.close();
+            ElMessage.success('登录成功');
+            App.refershUser(res.data);
+
+            if (route.query.backPage !== undefined) {
+                ElMessage.success("即将跳转...");
+                setTimeout(() => {
+                    router.replace({
+                        name: route.query.backPage
+                    });
+                }, 1000);
+                return;
+            }
+
+            // 如果有历史记录,返回上一页,否则跳转到首页
+            if (window.history.state && window.history.state.key) {
+                router.back();
+            } else {
+                router.replace({
+                    name: "Main",
+                })
+            }
+
+        })
+    } catch (error) {
+        ElMessage.error("登录失败!请稍后再试" + error);
+        router.replace({
+            name: "Login",
+        })
+    }
+});
+</script>