Browse Source

新增登录页

ZaiZai 11 months ago
parent
commit
3386a91a8d

+ 13 - 1
index.html

@@ -7,6 +7,7 @@
         <meta http-equiv="Expires" content="-1">
         <meta http-equiv="X-UA-Compatible" content="requiresActiveX=true" />
         <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+        <link rel="stylesheet" href="/plugins/css/loading.css">
         <link rel="stylesheet" href="/plugins/element-plus/index.css" />
         <link rel="stylesheet" href="/plugins/element-plus/theme-chalk/dark/css-vars.css" />
         <link rel="stylesheet" href="/plugins/remixicon/remixicon.css" />
@@ -15,7 +16,18 @@
         <title></title>
     </head>
     <body>
-        <div id="app"></div>
+        <div id="app">
+            <div class="loading">
+                <div class="loading-wrap">
+                    <div class="loading-dots">
+                        <span class="dot dot-spin">
+                            <i></i><i></i><i></i><i></i>
+                        </span>
+                    </div>
+                    <div class="loading-title">系统加载中</div>
+                </div>
+            </div>
+        </div>
         <script type="module" src="/src/main.js"></script>
     </body>
 </html>

+ 116 - 0
public/plugins/css/loading.css

@@ -0,0 +1,116 @@
+.loading {
+  display: flex;
+  width: 100%;
+  height: 100%;
+  justify-content: center;
+  align-items: center;
+  flex-direction: column;
+  background-color: #f4f7f9
+}
+
+.loading .loading-wrap {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  display: flex;
+  -webkit-transform: translate3d(-50%, -50%, 0);
+  transform: translate3d(-50%, -50%, 0);
+  justify-content: center;
+  align-items: center;
+  flex-direction: column
+}
+
+.loading .dots {
+  display: flex;
+  padding: 98px;
+  justify-content: center;
+  align-items: center
+}
+
+.loading .loading-title {
+  display: flex;
+  font-weight: bold;
+  margin-top: 30px;
+  font-size: 34px;
+  color: rgba(0, 0, 0, .85);
+  justify-content: center;
+  align-items: center
+}
+
+
+.dot {
+  position: relative;
+  display: inline-block;
+  width: 48px;
+  height: 48px;
+  margin-top: 30px;
+  font-size: 32px;
+  transform: rotate(45deg);
+  box-sizing: border-box;
+  animation: antRotate 1.2s infinite linear
+}
+
+.dot i {
+  position: absolute;
+  display: block;
+  width: 20px;
+  height: 20px;
+  background-color: #0065cc;
+  border-radius: 100%;
+  opacity: .3;
+  transform: scale(.75);
+  animation: antSpinMove 1s infinite linear alternate;
+  transform-origin: 50% 50%
+}
+
+.dot i:nth-child(1) {
+  top: 0;
+  left: 0
+}
+
+.dot i:nth-child(2) {
+  top: 0;
+  right: 0;
+  -webkit-animation-delay: .4s;
+  animation-delay: .4s
+}
+
+.dot i:nth-child(3) {
+  right: 0;
+  bottom: 0;
+  -webkit-animation-delay: .8s;
+  animation-delay: .8s
+}
+
+.dot i:nth-child(4) {
+  bottom: 0;
+  left: 0;
+  -webkit-animation-delay: 1.2s;
+  animation-delay: 1.2s
+}
+
+@keyframes antRotate {
+  to {
+    -webkit-transform: rotate(405deg);
+    transform: rotate(405deg)
+  }
+}
+
+@-webkit-keyframes antRotate {
+  to {
+    -webkit-transform: rotate(405deg);
+    transform: rotate(405deg)
+  }
+}
+
+@keyframes antSpinMove {
+  to {
+    opacity: 1
+  }
+}
+
+@-webkit-keyframes antSpinMove {
+  to {
+    opacity: 1
+  }
+}

BIN
src/assets/login/new-bg-1.png


BIN
src/assets/login/new-bg.png


BIN
src/assets/login/new-img.png


BIN
src/assets/login/new-logo.png


+ 4 - 3
src/config/index.js

@@ -18,10 +18,11 @@ export default {
     role_id: '1610526744728031234', //档案总管理角色组ID
     isLog: 'auto', //是否打印日志
     ...config,
+    //进入新登录页的域名或端口
+    domains: ['localhost:5175'],
+    ports: ['5175'],
+    //其它地址
     ossUrl: 'https://bladex-chongqing-info.oss-cn-hangzhou.aliyuncs.com', //oss地址
-    // socket: 'wss://business.hcxxy.com/wss/websocket/',  //测试线上
-    //socket: 'ws://192.168.0.113:8686/websocket/archive/',  //王文龙
-    // socket: 'ws://archives.hczcxx.cn/websocket/archive/',
     socket: 'wss://archives.hczcxx.cn/wss/websocket/archive/',
 
     //这里不再支持配置请求地址,请在 src/config/index.json 文件中配置。

+ 4 - 4
src/router/index.js

@@ -16,11 +16,11 @@ const router = vueRouter.createRouter({
 //路由拦截
 router.beforeResolve(async (to) => {
     NProgress.start()
-    const token = getToken(), auth = ['/login', '/auth', '/auth-token']
+    const token = getToken(), auth = ['/login-main', '/new-login', '/login', '/auth', '/auth-token']
     if (auth.indexOf(to.path) !== -1) {
         return true
     } else if (!token) {
-        return '/login'
+        return '/login-main'
     } else if (getTokenRouter(to.path)) {
         return true
     } else {
@@ -37,7 +37,7 @@ router.beforeResolve(async (to) => {
                 if (res) {
                     return true
                 } else {
-                    return '/login'
+                    return '/login-main'
                 }
             }
         } else {
@@ -45,7 +45,7 @@ router.beforeResolve(async (to) => {
             if (res) {
                 return true
             } else {
-                return '/login'
+                return '/login-main'
             }
         }
     }

+ 12 - 0
src/router/modules/base.js

@@ -6,12 +6,24 @@ export default [
         path: '/',
         redirect: '/using/stats',
     },
+    {
+        path: '/login-main',
+        name: 'login-main',
+        meta: { title: '登录' },
+        component: () => import('~src/views/login/main.vue'),
+    },
     {
         path: '/login',
         name: 'login',
         meta: { title: '登录' },
         component: () => import('~src/views/login/index.vue'),
     },
+    {
+        path: '/new-login',
+        name: 'new-login',
+        meta: { title: '登录' },
+        component: () => import('~src/views/login/new.vue'),
+    },
     {
         path: '/auth',
         name: 'auth',

+ 111 - 0
src/styles/view/new-login.scss

@@ -0,0 +1,111 @@
+.hc-new-login {
+    position: relative;
+    background-color: #13161F;
+    overflow: hidden;
+    .hc-new-login-bg {
+        position: absolute;
+        object-fit: cover;
+        width: 100%;
+        height: 100%;
+    }
+    .hc-new-login-main .hc-new-login-content .hc-new-login-form-card {
+        position: relative;
+        border-radius: 13px;
+        height: 500px;
+    }
+    .hc-new-login-copyright {
+        position: absolute;
+        bottom: 0;
+        width: 100%;
+        text-align: center;
+        padding: 20px 0;
+        color: white;
+        font-size: 12px;
+        .text {
+            white-space: pre-wrap;
+        }
+        .text + .text {
+            margin-top: 6px;
+        }
+    }
+}
+.hc-new-login .hc-new-login-main .hc-new-login-content .hc-new-login-form-card {
+    .form-left {
+        .form-img {
+            position: absolute;
+            width: 370px;
+            bottom: 16px;
+            left: 60px;
+        }
+        &:before {
+            content: '';
+            position: absolute;
+            width: 2px;
+            height: 90%;
+            right: 0;
+            top: 5%;
+            background: rgba(138, 138, 138, 0.39);
+        }
+    }
+    .form-right {
+        padding: 26px 0;
+        .form-main {
+            position: relative;
+            width: 359px;
+            margin: auto;
+            height: 100%;
+            .title {
+                color: #041015;
+                margin-bottom: 40px;
+            }
+            .el-form .el-form-item {
+                .el-input {
+                    --el-input-bg-color: #E7E7E6;
+                    --el-input-placeholder-color: #787676;
+                    .el-input-group__prepend {
+                        padding: 0 10px;
+                        background-color: var(--el-input-bg-color);
+                        box-shadow: 0 0 0 1px #d3d3d3 inset;
+                        i {
+                            font-size: 20px;
+                            color: #626060;
+                        }
+                        &:before {
+                            content: '';
+                            background: #BBBBBB;
+                            position: absolute;
+                            right: 0;
+                            height: 26px;
+                            width: 1px;
+                        }
+                    }
+                    .el-input__wrapper {
+                        box-shadow: 0 0 0 1px #d3d3d3 inset;
+                    }
+                    .el-input__inner {
+                        color: #0a0a0a;
+                    }
+                }
+                &.checkbox-1, &.checkbox-2 {
+                    margin-bottom: 0;
+                    .el-form-item__content {
+                        line-height: 30px;
+                        .el-checkbox.el-checkbox--large {
+                            height: 30px;
+                        }
+                    }
+                }
+                .el-checkbox {
+                    color: #626060;
+                }
+                .el-checkbox__input.is-checked + .el-checkbox__label {
+                    color: #626060;
+                }
+                &.login-btn {
+                    margin-top: 50px;
+                    margin-bottom: 0;
+                }
+            }
+        }
+    }
+}

+ 47 - 0
src/views/login/main.vue

@@ -0,0 +1,47 @@
+<template>
+    <div class="loading">
+        <div class="loading-wrap">
+            <div class="loading-dots">
+                <span class="dot dot-spin">
+                    <i /><i /><i /><i />
+                </span>
+            </div>
+            <div class="loading-title">系统加载中</div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { onMounted } from 'vue'
+import { getTopUrl } from '~uti/tools'
+import router from '~src/router/index'
+import config from '~src/config/index'
+
+//使用新登录页的域名和端口
+let newDomain = []
+
+//渲染完成
+onMounted(() => {
+    const domains = config.domains, port = config.ports
+    const currentDomain = getTopUrl()
+    //把http和https加进去
+    newDomain = []
+    for (let i = 0; i < domains.length; i++) {
+        newDomain.push('http://' + domains[i])
+        newDomain.push('https://' + domains[i])
+    }
+    //判断端口和域名
+    try {
+        const urls = currentDomain.split(':')
+        if (urls.length >= 3 && port.indexOf(urls[2]) !== -1) {
+            router.push({ name: 'new-login' })
+        } else if (newDomain.indexOf(currentDomain) !== -1) {
+            router.push({ name: 'new-login' })
+        } else {
+            router.push({ name: 'login' })
+        }
+    } catch (e) {
+        router.push({ name: 'login' })
+    }
+})
+</script>

+ 168 - 0
src/views/login/new.vue

@@ -0,0 +1,168 @@
+<template>
+    <div class="hc-new-login hc-full">
+        <img class="hc-new-login-bg" :src="bgPng1" :data-src="bgPng" loading="lazy" alt="bg">
+        <div class="hc-new-login-main hc-full hc-flex-center">
+            <div class="hc-new-login-content relative mt-30 w-[985px]">
+                <div class="app-title mb-8 text-center text-[34px] text-white">重庆市交通规划和技术发展中心 (重庆市交通工程档案馆)</div>
+                <div class="hc-new-login-form-card bg-white p-6 flex">
+                    <div class="form-left relative flex-1">
+                        <img class="form-logo w-[117px]" :src="logoPng" alt="bg">
+                        <img class="form-img" :src="imgPng" alt="bg">
+                    </div>
+                    <div class="form-right relative flex-1">
+                        <div class="form-main">
+                            <div class="title font-bold text-center text-[24px]">登&nbsp;&nbsp;录</div>
+                            <el-form ref="formRef" :model="formValue" :rules="formRules" label-position="left" label-width="0px" size="large">
+                                <el-form-item prop="tenantId">
+                                    <el-input v-model="formValue.tenantId" clearable placeholder="请输入区域号">
+                                        <template #prepend>
+                                            <hc-icon name="megaphone" />
+                                        </template>
+                                    </el-input>
+                                </el-form-item>
+                                <el-form-item prop="username">
+                                    <el-input v-model="formValue.username" clearable placeholder="请输入账号">
+                                        <template #prepend>
+                                            <hc-icon name="user" />
+                                        </template>
+                                    </el-input>
+                                </el-form-item>
+                                <el-form-item prop="password">
+                                    <el-input v-model="formValue.password" clearable placeholder="请输入密码" show-password type="password" @keyup="passwordKeyUp">
+                                        <template #prepend>
+                                            <hc-icon name="lock" />
+                                        </template>
+                                        <template #suffix>
+                                            <span class="clickable-text" @click="clickableClick">忘记密码</span>
+                                        </template>
+                                    </el-input>
+                                </el-form-item>
+                                <el-form-item class="checkbox-1">
+                                    <el-checkbox v-model="protocolCheckbox">我已经同意</el-checkbox>
+                                    <el-link type="primary" @click="protocolClick">软件产品用户使用服务协议</el-link>
+                                </el-form-item>
+                                <el-form-item class="checkbox-2">
+                                    <el-checkbox v-model="checkbox" label="记住密码" />
+                                </el-form-item>
+                                <el-form-item class="login-btn">
+                                    <el-button class="text-[18px]" :loading="loading" block color="#186DA5" @click="formValidateClick">登 录</el-button>
+                                </el-form-item>
+                            </el-form>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="hc-new-login-copyright">
+            <div class="text">版&nbsp;&nbsp;权&nbsp;&nbsp;所&nbsp;&nbsp;有:重庆市交通规划和技术发展中心</div>
+            <div class="text">技术支持单位:重庆泓创智诚信息技术有限公司</div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { onMounted, ref } from 'vue'
+import router from '~src/router/index'
+import { useAppStore } from '~src/store'
+import { setUserTenantInfo, useAppLogin } from '~sto/user'
+import { getTenantID } from '~api/user'
+import { getTopUrl } from '~uti/tools'
+import { formValidate, getObjVal } from 'js-fast-way'
+
+//图片文件
+import bgPng from '~src/assets/login/new-bg.png'
+import bgPng1 from '~src/assets/login/new-bg-1.png'
+import imgPng from '~src/assets/login/new-img.png'
+import logoPng from '~src/assets/login/new-logo.png'
+
+const userStore = useAppStore()
+userStore.clearStoreData() //先清理下缓存
+
+onMounted(() => {
+    //store.clearStoreData() //先清理下缓存
+    // 兼容性脚本,如果loading属性不被支持
+    document.querySelectorAll('img[loading="lazy"]').forEach((img) => {
+        img.src = img.dataset.src
+    })
+    getTenantIdApi()
+})
+
+//表单
+const formRef = ref(null)
+const formValue = ref({ tenantId: '000000', username: '', password: '', type: 'account' })
+const formRules = {
+    tenantId: {
+        required: true,
+        message: '请输入区域号',
+        trigger: 'blur',
+    },
+    username: {
+        required: true,
+        message: '请输入账号',
+        trigger: 'blur',
+    },
+    password: {
+        required: true,
+        message: '请输入密码',
+        trigger: 'blur',
+    },
+}
+const passwordKeyUp = (e) => {
+    if (e.key === 'Enter') {
+        formValidateClick()
+    }
+}
+
+//获取租户id
+const getTenantIdApi = async () => {
+    const { data } = await getTenantID(getTopUrl())
+    const { id } = await setUserTenantInfo(getObjVal(data))
+    formValue.value.tenantId = id //设置租户ID
+}
+
+//登录
+const loading = ref(false)
+const formValidateClick = async () => {
+    const formRes = await formValidate(formRef.value)
+    if (!formRes) return false
+    if (protocolCheckbox.value) {
+        window?.$message?.warning('请先同意软件产品用户使用服务协议')
+        return false
+    }
+    //登录请求
+    loading.value = true
+    const { error, msg } = await useAppLogin(formValue.value)
+    if (error) {
+        loading.value = false
+        window?.$message?.error(msg)
+        return false
+    }
+    //登录成功
+    window?.$message?.success('登录成功')
+    setTimeout(() => {
+        loading.value = false
+        router.push({ name: 'datav' })
+    }, 1500)
+}
+
+const checkbox = ref(false)
+const protocolCheckbox = ref(false)
+
+//忘记密码
+const clickableClick = () => {
+    const val = '<div style="font-size: 16px;">忘记密码请不要紧张,联系您项目上的专属客服人员电话 <span style="color:#1ECC95;">18423665354</span> ,提供身份证明信息即可初始化密码,建议初始化之后由您单独去更改密码</div>'
+    window?.$messageBox?.alert(val, '联系项目客服', {
+        confirmButtonText: '确定',
+        dangerouslyUseHTMLString: true,
+    })
+}
+
+//协议
+const protocolClick = () => {
+    window.open('https://bladex-chongqing-info.oss-cn-hangzhou.aliyuncs.com//upload/20231213/73025c8aba72e1165e0731942f6e66c9.pdf', '_blank')
+}
+</script>
+
+<style lang="scss">
+@import "../../styles/view/new-login";
+</style>