From 7defcb73ac495fdabc3d67a3125c1c798df05a8b Mon Sep 17 00:00:00 2001
From: 马宇豪 <978517621@qq.com>
Date: 星期二, 28 十一月 2023 14:13:56 +0800
Subject: [PATCH] 新增

---
 src/assets/images/laws.png         |    0 
 src/permission.js                  |   54 
 src/api/login.js                   |    6 
 src/assets/styles/index.scss       |    8 
 src/views/homePage.vue             |  435 ++++++-------
 src/store/modules/user.js          |    4 
 src/assets/images/loginImg.png     |    0 
 src/assets/images/article.png      |    0 
 src/assets/images/notice.png       |    0 
 src/assets/images/file.png         |    0 
 src/views/components/home.vue      |  251 +++++++
 src/views/components/publish.vue   |  215 ++++++
 src/views/originLogin.vue          |  288 +++++++++
 src/utils/request.js               |    8 
 src/views/components/notice.vue    |  167 +++++
 .env.development                   |    6 
 src/api/home/homePage.js           |   28 
 src/assets/images/city-bg.png      |    0 
 src/views/components/loginForm.vue |  239 +++++++
 src/assets/images/section.png      |    0 
 src/views/components/laws.vue      |  203 ++++++
 21 files changed, 1,646 insertions(+), 266 deletions(-)

diff --git a/.env.development b/.env.development
index e991bb4..4f5599a 100644
--- a/.env.development
+++ b/.env.development
@@ -8,8 +8,8 @@
 #黄镇
 #VITE_APP_BASE_API = 'http://192.168.0.47:8085'
 
-#张凤
-#VITE_APP_BASE_API = 'http://192.168.0.70:8085'
+#孔哥
+VITE_APP_BASE_API = 'http://192.168.0.77:8088/api'
 
 #线上
-VITE_APP_BASE_API = 'http://121.239.169.30:8086/api'
\ No newline at end of file
+#VITE_APP_BASE_API = 'http://121.239.169.30:8086/api'
\ No newline at end of file
diff --git a/src/api/home/homePage.js b/src/api/home/homePage.js
new file mode 100644
index 0000000..eba3b5d
--- /dev/null
+++ b/src/api/home/homePage.js
@@ -0,0 +1,28 @@
+import request from '@/utils/request'
+
+// 获取分页
+export function getNotice(params) {
+    return request({
+        url: '/system/notice/noticeList',
+        method: 'get',
+        params: params
+    })
+}
+
+// 获取分页
+export function getLaws(params) {
+    return request({
+        url: '/system/law/lawList',
+        method: 'get',
+        params: params
+    })
+}
+
+// 获取分页
+export function getPublish(params) {
+    return request({
+        url: '/system/agency/agencyList',
+        method: 'get',
+        params: params
+    })
+}
\ No newline at end of file
diff --git a/src/api/login.js b/src/api/login.js
index 7b7388f..69a8d71 100644
--- a/src/api/login.js
+++ b/src/api/login.js
@@ -9,7 +9,7 @@
     uuid
   }
   return request({
-    url: '/login',
+    url: '/account/login',
     headers: {
       isToken: false,
       repeatSubmit: false
@@ -42,7 +42,7 @@
 // 退出方法
 export function logout() {
   return request({
-    url: '/logout',
+    url: '/account/logout',
     method: 'post'
   })
 }
@@ -50,7 +50,7 @@
 // 获取验证码
 export function getCodeImg() {
   return request({
-    url: '/captchaImage',
+    url: '/system/captcha/captchaImage',
     headers: {
       isToken: false
     },
diff --git a/src/assets/images/article.png b/src/assets/images/article.png
new file mode 100644
index 0000000..e9ed48e
--- /dev/null
+++ b/src/assets/images/article.png
Binary files differ
diff --git a/src/assets/images/city-bg.png b/src/assets/images/city-bg.png
new file mode 100644
index 0000000..21689e3
--- /dev/null
+++ b/src/assets/images/city-bg.png
Binary files differ
diff --git a/src/assets/images/file.png b/src/assets/images/file.png
new file mode 100644
index 0000000..6630e0c
--- /dev/null
+++ b/src/assets/images/file.png
Binary files differ
diff --git a/src/assets/images/laws.png b/src/assets/images/laws.png
new file mode 100644
index 0000000..7c14e0e
--- /dev/null
+++ b/src/assets/images/laws.png
Binary files differ
diff --git a/src/assets/images/loginImg.png b/src/assets/images/loginImg.png
index ae56de7..b309db7 100644
--- a/src/assets/images/loginImg.png
+++ b/src/assets/images/loginImg.png
Binary files differ
diff --git a/src/assets/images/notice.png b/src/assets/images/notice.png
new file mode 100644
index 0000000..043ff14
--- /dev/null
+++ b/src/assets/images/notice.png
Binary files differ
diff --git a/src/assets/images/section.png b/src/assets/images/section.png
new file mode 100644
index 0000000..4813d95
--- /dev/null
+++ b/src/assets/images/section.png
Binary files differ
diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss
index c2b2035..eaec52a 100644
--- a/src/assets/styles/index.scss
+++ b/src/assets/styles/index.scss
@@ -188,4 +188,12 @@
   --el-color-warning: #EAB308 !important;
   --el-color-success: #10B981 !important;
   --el-color-info: #1f2937 !important;
+}
+
+.blueFont{
+  color: #5175C0;
+}
+
+.blueBg{
+  background: #5175C0;
 }
\ No newline at end of file
diff --git a/src/permission.js b/src/permission.js
index 1658dd5..f13cc3c 100644
--- a/src/permission.js
+++ b/src/permission.js
@@ -18,34 +18,34 @@
   if (getToken()) {
     to.meta.title && useSettingsStore().setTitle(to.meta.title)
     /* has token*/
-    if (to.path === '/homePage') {
-      next({ path: '/' })
-      NProgress.done()
-    } else {
-      if (useUserStore().roles.length === 0) {
-        isRelogin.show = true
-        // 判断当前用户是否已拉取完user_info信息
-        useUserStore().getInfo().then(() => {
-          isRelogin.show = false
-          usePermissionStore().generateRoutes().then(accessRoutes => {
-            // 根据roles权限生成可访问的路由表
-            accessRoutes.forEach(route => {
-              if (!isHttp(route.path)) {
-                router.addRoute(route) // 动态添加可访问路由表
-              }
-            })
-            next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
-          })
-        }).catch(err => {
-          useUserStore().logOut().then(() => {
-            ElMessage.error(err)
-            next({ path: '/' })
-          })
-        })
-      } else {
+    // if (to.path === '/homePage') {
+    //   next({ path: '/' })
+    //   NProgress.done()
+    // } else {
+    //   if (useUserStore().roles.length === 0) {
+    //     isRelogin.show = true
+    //     // 判断当前用户是否已拉取完user_info信息
+    //     useUserStore().getInfo().then(() => {
+    //       isRelogin.show = false
+    //       usePermissionStore().generateRoutes().then(accessRoutes => {
+    //         // 根据roles权限生成可访问的路由表
+    //         accessRoutes.forEach(route => {
+    //           if (!isHttp(route.path)) {
+    //             router.addRoute(route) // 动态添加可访问路由表
+    //           }
+    //         })
+    //         next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
+    //       })
+    //     }).catch(err => {
+    //       useUserStore().logOut().then(() => {
+    //         ElMessage.error(err)
+    //         next({ path: '/' })
+    //       })
+    //     })
+    //   } else {
         next()
-      }
-    }
+    //   }
+    // }
   } else {
     // 没有token
     if (whiteList.indexOf(to.path) !== -1) {
diff --git a/src/store/modules/user.js b/src/store/modules/user.js
index d439c44..733c04a 100644
--- a/src/store/modules/user.js
+++ b/src/store/modules/user.js
@@ -22,8 +22,8 @@
         const uuid = userInfo.uuid
         return new Promise((resolve, reject) => {
           login(username, password, code, uuid).then(res => {
-            setToken(res.token)
-            this.token = res.token
+            setToken(res.data.token)
+            this.token = res.data.token
             resolve()
           }).catch(error => {
             reject(error)
diff --git a/src/utils/request.js b/src/utils/request.js
index 00b910f..e848155 100644
--- a/src/utils/request.js
+++ b/src/utils/request.js
@@ -82,7 +82,7 @@
       return res.data
     }
     if (code === 401) {
-      if (!isRelogin.show) {
+      // if (!isRelogin.show) {
         isRelogin.show = true;
         ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
           isRelogin.show = false;
@@ -90,10 +90,10 @@
             location.href = '/index';
           })
       }).catch(() => {
-        isRelogin.show = false;
+        isRelogin.show = false
       });
-    }
-      return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
+    // }
+      // return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
     } else if (code === 500) {
       ElMessage({ message: msg, type: 'error' })
       return Promise.reject(new Error(msg))
diff --git a/src/views/components/home.vue b/src/views/components/home.vue
new file mode 100644
index 0000000..bdf277a
--- /dev/null
+++ b/src/views/components/home.vue
@@ -0,0 +1,251 @@
+<template>
+  <div class="container">
+    <div class="main-content">
+      <div class="list-container">
+        <div class="tit">
+          <div>
+            <Platform style="width: 1em; height: 1em;margin-right: 4px" />
+            通知公告
+          </div>
+          <el-button plain @click="toMore(2)">查看更多</el-button>
+        </div>
+        <div class="list">
+          <div v-for="item in state.noticeList">
+            <div><img src="src/assets/images/notice.png"></div>
+            <div>
+              <div>{{item.title}}</div>
+              <span>{{item.updateTime}}</span>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="list-container">
+        <div class="tit">
+          <div>
+            <Platform style="width: 1em; height: 1em;margin-right: 4px" />
+            法律法规
+          </div>
+          <el-button plain @click="toMore(3)">查看更多</el-button>
+        </div>
+        <div class="list">
+          <div v-for="item in state.lawsList">
+            <div><img src="src/assets/images/laws.png"></div>
+            <div>
+              <div>{{item.title}}</div>
+              <span>{{item.updateTime}}</span>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="list-container">
+        <div class="tit">
+          <div>
+            <Platform style="width: 1em; height: 1em;margin-right: 4px" />
+            机构公示
+          </div>
+          <el-button plain @click="toMore(4)">查看更多</el-button>
+        </div>
+        <div class="list">
+          <div v-for="item in state.pubList">
+            <div><img src="src/assets/images/section.png"></div>
+            <div>
+              <div>{{item.title}}</div>
+              <span>{{item.updateTime}}</span>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="login-container">
+<!--        <div class="tit">-->
+<!--          <div>-->
+<!--            <Platform style="width: 1em; height: 1em;margin-right: 4px" />-->
+<!--            资料下载-->
+<!--          </div>-->
+<!--          <el-button plain>查看更多</el-button>-->
+<!--        </div>-->
+<!--        <div class="list">-->
+<!--          <div v-for="item in state.newList">-->
+<!--            <div><img src="src/assets/images/file.png"></div>-->
+<!--            <div>-->
+<!--              <div>{{item.title}}</div>-->
+<!--              <span>{{item.date}}</span>-->
+<!--            </div>-->
+<!--          </div>-->
+<!--        </div>-->
+        <login-form ref="loginRef"/>
+      </div>
+    </div>
+<!--    <login-form ref="loginRef"/>-->
+  </div>
+</template>
+
+<script setup>
+import {onMounted, ref, reactive, watch, onUnmounted, defineEmits, defineExpose} from "vue"
+import { getNotice, getLaws, getPublish } from '@/api/home/homePage'
+import useUserStore from '@/store/modules/user'
+import LoginForm from './loginForm'
+import {ElMessage} from "element-plus";
+
+const route = useRoute()
+const router = useRouter()
+
+const state = reactive({
+  noticeList: [],
+  lawsList: [],
+  pubList: []
+})
+const emit = defineEmits(["toMore"])
+const redirect = ref(undefined);
+
+onMounted(()=>{
+  getNoticeList()
+  getLawsList()
+  getPubList()
+})
+
+onUnmounted(()=>{
+
+})
+
+watch(route, (newRoute) => {
+    redirect.value = newRoute.query && newRoute.query.redirect;
+}, { immediate: true })
+
+const toMore=(num)=>{
+  emit('toMore',num)
+}
+
+const getNoticeList = async ()=>{
+  const res = await getNotice({title: '', content: '', pageNum: 1, pageSize: 5})
+  if(res.code == 200){
+    state.noticeList = res.data.list
+  }else{
+    ElMessage.warning(res.message)
+  }
+}
+
+const getLawsList = async ()=>{
+  const res = await getLaws({title: '', content: '', pageNum: 1, pageSize: 5})
+  if(res.code == 200){
+    state.lawsList = res.data.list
+  }else{
+    ElMessage.warning(res.message)
+  }
+}
+
+const getPubList = async ()=>{
+  const res = await getPublish({title: '', content: '', pageNum: 1, pageSize: 5})
+  if(res.code == 200){
+    state.pubList = res.data.list
+  }else{
+    ElMessage.warning(res.message)
+  }
+}
+
+defineExpose({
+  getNoticeList,
+  getLawsList,
+  getPubList
+})
+
+</script>
+
+<style lang='scss' scoped>
+.container {
+  width: 100%;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  margin-top: 170px;
+
+  .main-content{
+    width: 1200px;
+    margin: 20px 0 80px;
+    display: grid;
+    grid-gap: 15px;
+    grid-template-columns: repeat(2, 1fr);
+    grid-template-rows: repeat(2, 350px);
+    grid-auto-flow: row;
+    justify-content: center;
+    color: #333;
+
+    .login-container{
+      border-radius: 4px;
+      box-shadow: 1px 1px 3px rgba(0,0,0,.04);
+      padding: 0 15px;
+      overflow: hidden;
+      background: url("../../assets/images/login-bg.jpg");
+    }
+
+    .list-container{
+      border-radius: 4px;
+      box-shadow: 1px 1px 3px rgba(0,0,0,.04);
+      padding: 0 15px;
+      overflow: hidden;
+      background: #fff url("../../assets/images/city-bg.png") no-repeat right bottom;
+      background-size: 40% auto;
+
+      .tit{
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        padding: 10px 0;
+        border-bottom: 1px solid #ebeef5;
+        &>div{
+          display: flex;
+          align-items: center;
+          font-size: 18px;
+          color: #425f9f;
+          font-weight: bolder;
+        }
+      }
+      .list{
+        width: 100%;
+        margin-top: 10px;
+
+        &>div{
+          width: 100%;
+          display: flex;
+          align-items: center;
+          cursor: pointer;
+          padding: 5px;
+          border-radius: 4px;
+
+          &>div:first-of-type{
+            width: 40px;
+            height: 40px;
+            border-radius: 4px;
+            background: #eaf1ff;
+            margin-right: 10px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            img{
+              width: 28px;
+              height: 28px;
+            }
+          }
+          &>div:last-of-type{
+            width: calc(100% - 50px);
+            font-size: 16px;
+            div{
+              width: 100%;
+              white-space: nowrap;
+              overflow: hidden;
+              text-overflow: ellipsis;
+              font-family: "PingFang SC";
+              margin-bottom: 4px;
+            }
+            span{
+              color: #999;
+            }
+          }
+          &:hover{
+            background: #f5f5f5;
+          }
+        }
+      }
+    }
+  }
+}
+</style>
diff --git a/src/views/components/laws.vue b/src/views/components/laws.vue
new file mode 100644
index 0000000..ab6ef7d
--- /dev/null
+++ b/src/views/components/laws.vue
@@ -0,0 +1,203 @@
+<template>
+  <div class="container">
+    <div class="main-content">
+      <div class="filters">
+        <el-form :model="state.querys">
+          <el-form-item label="法律法规名称" style="width: 500px;margin-bottom: 0;margin-right: 20px">
+            <el-input v-model="state.querys.title" />
+          </el-form-item>
+        </el-form>
+        <el-button type="primary" :icon="Search" class="searchBtn">搜索</el-button>
+        <el-button type="primary" :icon="Refresh" class="resetBtn">重置</el-button>
+      </div>
+      <div class="list">
+        <div v-for="item in state.dataList">
+          <div>
+            <div><img src="src/assets/images/article.png"></div>
+            <div>{{item.title}}</div>
+          </div>
+          <span>
+            {{item.updateTime}}
+          </span>
+        </div>
+      </div>
+      <div class="pag-container">
+        <el-pagination
+            v-model:current-page="state.querys.pageNum"
+            v-model:page-size="state.querys.pageSize"
+            :page-sizes="[10,15,20,25]"
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="state.total"
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import {onMounted, ref, reactive, watch, onUnmounted, defineExpose} from "vue"
+import { getLaws } from '@/api/home/homePage'
+import useUserStore from '@/store/modules/user'
+import { Search, Refresh } from '@element-plus/icons-vue'
+import {ElMessage} from "element-plus";
+
+const route = useRoute()
+const router = useRouter()
+
+const state = reactive({
+  dataList: [],
+  querys:{
+    title: '',
+    content: '',
+    pageNum: 1,
+    pageSize: 10
+  },
+  total: null
+})
+
+const redirect = ref(undefined);
+
+onMounted(()=>{
+  getData()
+})
+
+onUnmounted(()=>{
+
+})
+
+watch(route, (newRoute) => {
+    redirect.value = newRoute.query && newRoute.query.redirect;
+}, { immediate: true });
+
+const getData = async ()=>{
+  const res = await getLaws(state.querys)
+  if(res.code == 200){
+    state.dataList = res.data.list
+    state.total = res.data.total
+  }else{
+    ElMessage.warning(res.message)
+  }
+}
+
+const handleSizeChange = (val) => {
+  state.querys.pageSize = val
+  getData()
+}
+const handleCurrentChange = (val) => {
+  state.querys.pageNum = val
+  getData()
+}
+
+defineExpose({
+  getData
+})
+
+</script>
+
+<style lang='scss' scoped>
+.container {
+  width: 100%;
+  display: flex;
+  justify-content: center;
+  margin-top: 170px;
+
+  .main-content{
+    width: 1200px;
+    margin: 20px 0;
+    background: #fff;
+    border-radius: 4px;
+    box-shadow: 1px 1px 3px rgba(0,0,0,.04);
+    padding: 0 10px;
+    color: #333;
+
+    .filters{
+      margin-top: 20px;
+      display: flex;
+      align-items: center;
+      padding-left: 10px;
+
+      .searchBtn{
+        border: none;
+        border-radius: 4px !important;
+        background-image: linear-gradient(90deg,#4064df,#548dfb);
+
+        &:active{
+          border-radius: 99px !important;
+          background-image: linear-gradient(-90deg,#4064df,#548dfb);
+        }
+      }
+      .resetBtn{
+        border: none;
+        border-radius: 4px !important;
+        background-image: linear-gradient(90deg,#fc8e2e,#ffaa59);
+
+        &:active{
+          border-radius: 99px !important;
+          background-image: linear-gradient(-90deg,#fc8e2e,#ffaa59);
+        }
+      }
+    }
+
+    .list{
+      padding: 15px 0;
+
+      &>div{
+        display: flex;
+        padding: 10px;
+        align-items: center;
+        justify-content: space-between;
+        border-bottom: 1px dashed #ebeef5;
+        cursor: pointer;
+        border-radius: 4px;
+        font-size: 16px;
+
+        &>div{
+          display: flex;
+          align-items: center;
+
+          div:first-of-type{
+            width: 40px;
+            height: 40px;
+            margin-right: 10px;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+
+            img{
+              width: 28px;
+              height: 28px;
+            }
+          }
+          div:last-of-type{
+            width: 1000px;
+            white-space: nowrap;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            font-family: "PingFang SC";
+          }
+        }
+        span{
+          color: #999;
+        }
+        &:hover{
+          background: #f5f5f5;
+        }
+        &:active{
+          background: #425f9f;
+          color: #fff;
+        }
+      }
+    }
+
+    .pag-container{
+      width: 100%;
+      height: 80px;
+      display: flex;
+      align-items: center;
+      justify-content: right;
+    }
+  }
+}
+</style>
diff --git a/src/views/components/loginForm.vue b/src/views/components/loginForm.vue
new file mode 100644
index 0000000..08b6651
--- /dev/null
+++ b/src/views/components/loginForm.vue
@@ -0,0 +1,239 @@
+<template>
+  <div class="login-panel">
+    <div class="login-img">
+      <img src="src/assets/images/loginImg.png">
+    </div>
+    <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
+      <h3 class="title">登录系统</h3>
+      <el-form-item prop="username">
+        <el-input
+          v-model="loginForm.username"
+          type="text"
+          size="large"
+          auto-complete="off"
+          placeholder="账号"
+        >
+          <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
+        </el-input>
+      </el-form-item>
+      <el-form-item prop="password">
+        <el-input
+          v-model="loginForm.password"
+          type="password"
+          size="large"
+          auto-complete="off"
+          placeholder="密码"
+          @keyup.enter="handleLogin"
+        >
+          <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
+        </el-input>
+      </el-form-item>
+      <el-form-item prop="code" v-if="captchaEnabled">
+        <el-input
+          v-model="loginForm.code"
+          size="large"
+          auto-complete="off"
+          placeholder="验证码"
+          style="width: 63%"
+          @keyup.enter="handleLogin"
+        >
+          <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
+        </el-input>
+        <div class="login-code">
+          <img :src="codeUrl" @click="getCode" class="login-code-img"/>
+        </div>
+      </el-form-item>
+      <div style="display: flex;justify-content: space-between;align-items: center;margin-bottom: 25px">
+<!--        <el-checkbox v-model="loginForm.rememberMe">记住密码</el-checkbox>-->
+        <el-button
+            :loading="loading"
+            size="large"
+            type="primary"
+            style="width:50%;"
+            @click.prevent="handleLogin"
+        >
+          <span v-if="!loading">登 录</span>
+          <span v-else>登 录 中...</span>
+        </el-button>
+        <div v-if="isRegister">
+          <el-button link type="primary" @click="openRegist">立即注册</el-button>
+        </div>
+      </div>
+    </el-form>
+  </div>
+  <register ref="regRef"/>
+</template>
+
+<script setup>
+import {onMounted, ref, watch, defineAsyncComponent, nextTick} from "vue"
+import { getCodeImg } from "@/api/login";
+import Cookies from "js-cookie";
+import { encrypt, decrypt } from "@/utils/jsencrypt";
+import useUserStore from '@/store/modules/user'
+import { Register } from "@/layout/components";
+
+const userStore = useUserStore()
+const route = useRoute();
+const router = useRouter();
+const { proxy } = getCurrentInstance();
+
+const loginForm = ref({
+  username: "admin",
+  password: "admin@123",
+  code: "",
+  uuid: ""
+});
+
+const loginRules = {
+  username: [{ required: true, trigger: "blur", message: "请输入您的账号" }],
+  password: [{ required: true, trigger: "blur", message: "请输入您的密码" }],
+  code: [{ required: true, trigger: "change", message: "请输入验证码" }]
+};
+
+const codeUrl = ref("");
+const loading = ref(false);
+const regRef = ref(null)
+// 验证码开关
+const captchaEnabled = ref(true);
+// 注册开关
+const isRegister = ref(true);
+const redirect = ref(undefined);
+
+onMounted(()=>{
+
+})
+
+const openRegist = ()=>{
+  regRef.value.dialogVisible = true
+}
+
+watch(route, (newRoute) => {
+    redirect.value = newRoute.query && newRoute.query.redirect;
+}, { immediate: true });
+
+function handleLogin() {
+  proxy.$refs.loginRef.validate(valid => {
+    if (valid) {
+      loading.value = true;
+      // 勾选了需要记住密码设置在 cookie 中设置记住用户名和密码
+      // if (loginForm.value.rememberMe) {
+        Cookies.set("username", loginForm.value.username, { expires: 30 });
+        Cookies.set("password", encrypt(loginForm.value.password), { expires: 30 });
+      //   Cookies.set("rememberMe", loginForm.value.rememberMe, { expires: 30 });
+      // } else {
+        // 否则移除
+      //   Cookies.remove("username");
+      //   Cookies.remove("password");
+      //   Cookies.remove("rememberMe");
+      // }
+      // 调用action的登录方法
+      userStore.login(loginForm.value).then(() => {
+        const query = route.query;
+        const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
+          if (cur !== "redirect") {
+            acc[cur] = query[cur];
+          }
+          return acc;
+        }, {});
+        router.push({ path: redirect.value || "/", query: otherQueryParams });
+      }).catch(() => {
+        loading.value = false;
+        // 重新获取验证码
+        if (captchaEnabled.value) {
+          getCode();
+        }
+      });
+    }
+  });
+}
+
+function getCode() {
+  getCodeImg().then(res => {
+    captchaEnabled.value = res.data.captchaEnabled === undefined ? true : res.captchaEnabled
+    if (captchaEnabled.value) {
+      codeUrl.value = "data:image/gif;base64," + res.data.image
+      loginForm.value.uuid = res.data.uuid
+    }
+  });
+}
+
+// function getCookie() {
+//   const username = Cookies.get("username")
+//   const password = Cookies.get("password")
+//   loginForm.value = {
+//     username: username === undefined ? loginForm.value.username : username,
+//     password: password === undefined ? loginForm.value.password : decrypt(password),
+//   };
+// }
+
+getCode();
+// getCookie();
+</script>
+
+<style lang='scss' scoped>
+.login-panel{
+  width: 100%;
+  height: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+.login-img{
+  flex: 1;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  img{
+    width: 100%;
+  }
+}
+.login-form {
+  flex: 2;
+  padding: 10px;
+
+  .title{
+    margin: 20px 0;
+  }
+
+  .el-input {
+    height: 40px;
+    input {
+      height: 40px;
+    }
+  }
+  .input-icon {
+    height: 39px;
+    width: 14px;
+    margin-left: 0px;
+  }
+}
+.login-tip {
+  font-size: 13px;
+  text-align: center;
+  color: #bfbfbf;
+}
+.login-code {
+  width: 33%;
+  height: 40px;
+  float: right;
+  img {
+    display: inline-block;
+    width: 100%;
+    cursor: pointer;
+    vertical-align: middle;
+  }
+}
+
+.el-form-item--default{
+  margin-bottom: 15px;
+}
+
+::v-deep(.el-form-item__content){
+  display: flex;
+  justify-content: space-between;
+}
+.login-code-img {
+  height: 40px;
+  padding-left: 12px;
+}
+</style>
diff --git a/src/views/components/notice.vue b/src/views/components/notice.vue
new file mode 100644
index 0000000..d70ef98
--- /dev/null
+++ b/src/views/components/notice.vue
@@ -0,0 +1,167 @@
+<template>
+  <div class="container">
+    <div class="main-content">
+      <div class="list">
+        <div v-for="item in state.dataList">
+          <div>
+            <div><img src="src/assets/images/article.png"></div>
+            <div>{{item.title}}</div>
+          </div>
+          <span>
+            {{item.updateTime}}
+          </span>
+        </div>
+      </div>
+      <div class="pag-container">
+        <el-pagination
+            v-model:current-page="state.querys.pageNum"
+            v-model:page-size="state.querys.pageSize"
+            :page-sizes="[10,15,20,25]"
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="state.total"
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import {onMounted, ref, reactive, watch, onUnmounted, defineExpose} from "vue"
+import { getNotice } from '@/api/home/homePage'
+import useUserStore from '@/store/modules/user'
+import {ElMessage} from "element-plus";
+
+const route = useRoute()
+const router = useRouter()
+
+const state = reactive({
+  dataList: [],
+  querys:{
+    title: '',
+    content: '',
+    pageNum: 1,
+    pageSize: 10
+  },
+  total: null
+})
+
+const redirect = ref(undefined);
+
+onMounted(()=>{
+  getData()
+})
+
+onUnmounted(()=>{
+
+})
+
+watch(route, (newRoute) => {
+    redirect.value = newRoute.query && newRoute.query.redirect;
+}, { immediate: true });
+
+const handleSizeChange = (val) => {
+  state.querys.pageSize = val
+  getData()
+}
+const handleCurrentChange = (val) => {
+  state.querys.pageNum = val
+  getData()
+}
+
+const getData = async ()=>{
+  const res = await getNotice(state.querys)
+  if(res.code == 200){
+    state.dataList = res.data.list
+    state.total = res.data.total
+  }else{
+    ElMessage.warning(res.message)
+  }
+}
+
+defineExpose({
+  getData
+})
+
+</script>
+
+<style lang='scss' scoped>
+.container {
+  width: 100%;
+  display: flex;
+  justify-content: center;
+  margin-top: 170px;
+
+  .main-content{
+    width: 1200px;
+    margin: 20px 0;
+    background: #fff;
+    border-radius: 4px;
+    box-shadow: 1px 1px 3px rgba(0,0,0,.04);
+    padding: 0 10px;
+    color: #333;
+
+    .list{
+      padding: 15px 0;
+      max-height: calc(100vh - 350px);
+      overflow-y: auto;
+
+      &>div{
+        display: flex;
+        padding: 10px;
+        align-items: center;
+        justify-content: space-between;
+        border-bottom: 1px dashed #ebeef5;
+        cursor: pointer;
+        border-radius: 4px;
+        font-size: 16px;
+
+        &>div{
+          display: flex;
+          align-items: center;
+
+          div:first-of-type{
+            width: 40px;
+            height: 40px;
+            margin-right: 10px;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+
+            img{
+              width: 28px;
+              height: 28px;
+            }
+          }
+          div:last-of-type{
+            width: 1000px;
+            white-space: nowrap;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            font-family: "PingFang SC";
+          }
+        }
+        span{
+          color: #999;
+        }
+        &:hover{
+          background: #f5f5f5;
+        }
+        &:active{
+          background: #425f9f;
+          color: #fff;
+        }
+      }
+    }
+
+    .pag-container{
+      width: 100%;
+      height: 80px;
+      display: flex;
+      align-items: center;
+      justify-content: right;
+    }
+  }
+}
+</style>
diff --git a/src/views/components/publish.vue b/src/views/components/publish.vue
new file mode 100644
index 0000000..3ed921c
--- /dev/null
+++ b/src/views/components/publish.vue
@@ -0,0 +1,215 @@
+<template>
+  <div class="container">
+    <div class="main-content">
+      <div class="filters">
+        <el-form :model="state.querys" style="display:flex;">
+          <el-form-item label="机构名称" style="width: 300px;margin-bottom: 0;margin-right: 20px">
+            <el-input v-model="state.querys.name" />
+          </el-form-item>
+          <el-form-item label="所在地市" style="margin-bottom: 0;margin-right: 20px">
+            <el-select v-model="state.querys.area">
+              <el-option label="Zone one" value="shanghai" />
+              <el-option label="Zone two" value="beijing" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="业务范围" style="margin-bottom: 0;margin-right: 20px">
+            <el-select v-model="state.querys.business">
+              <el-option label="Zone one" value="shanghai" />
+              <el-option label="Zone two" value="beijing" />
+            </el-select>
+          </el-form-item>
+        </el-form>
+        <el-button type="primary" :icon="Search" class="searchBtn">搜索</el-button>
+        <el-button type="primary" :icon="Refresh" class="resetBtn">重置</el-button>
+      </div>
+      <div class="list">
+        <div v-for="item in state.dataList">
+          <div>
+            <div><img src="src/assets/images/article.png"></div>
+            <div>{{item.title}}</div>
+          </div>
+          <span>
+            {{item.updateTime}}
+          </span>
+        </div>
+      </div>
+      <div class="pag-container">
+        <el-pagination
+            v-model:current-page="state.querys.pageNum"
+            v-model:page-size="state.querys.pageSize"
+            :page-sizes="[10,15,20,25]"
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="state.total"
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import {onMounted, ref, reactive, watch, onUnmounted, defineExpose} from "vue"
+import { getPublish } from '@/api/home/homePage'
+import { Search, Refresh } from '@element-plus/icons-vue'
+import {ElMessage} from "element-plus";
+
+const route = useRoute()
+const router = useRouter()
+
+const state = reactive({
+  dataList: [],
+  querys:{
+    name: '',
+    area: '',
+    bussiness: '',
+    pageNum: 1,
+    pageSize: 10
+  },
+  total: null
+})
+
+const redirect = ref(undefined);
+
+onMounted(()=>{
+  getData()
+})
+
+onUnmounted(()=>{
+
+})
+
+watch(route, (newRoute) => {
+    redirect.value = newRoute.query && newRoute.query.redirect;
+}, { immediate: true });
+
+const getData = async ()=>{
+  const res = await getPublish(state.querys)
+  if(res.code == 200){
+    state.dataList = res.data.list
+    state.total = res.data.total
+  }else{
+    ElMessage.warning(res.message)
+  }
+}
+
+const handleSizeChange = (val) => {
+  state.querys.pageSize = val
+  getData()
+}
+const handleCurrentChange = (val) => {
+  state.querys.pageNum = val
+  getData()
+}
+
+defineExpose({
+  getData
+})
+
+</script>
+
+<style lang='scss' scoped>
+.container {
+  width: 100%;
+  display: flex;
+  justify-content: center;
+  margin-top: 170px;
+
+  .main-content{
+    width: 1200px;
+    margin: 20px 0;
+    background: #fff;
+    border-radius: 4px;
+    box-shadow: 1px 1px 3px rgba(0,0,0,.04);
+    padding: 0 10px;
+    color: #333;
+
+    .filters{
+      margin-top: 20px;
+      display: flex;
+      align-items: center;
+      padding-left: 10px;
+
+      .searchBtn{
+        border: none;
+        border-radius: 4px !important;
+        background-image: linear-gradient(90deg,#4064df,#548dfb);
+
+        &:active{
+          border-radius: 99px !important;
+          background-image: linear-gradient(-90deg,#4064df,#548dfb);
+        }
+      }
+      .resetBtn{
+        border: none;
+        border-radius: 4px !important;
+        background-image: linear-gradient(90deg,#fc8e2e,#ffaa59);
+
+        &:active{
+          border-radius: 99px !important;
+          background-image: linear-gradient(-90deg,#fc8e2e,#ffaa59);
+        }
+      }
+    }
+
+    .list{
+      padding: 15px 0;
+
+      &>div{
+        display: flex;
+        padding: 10px;
+        align-items: center;
+        justify-content: space-between;
+        border-bottom: 1px dashed #ebeef5;
+        cursor: pointer;
+        border-radius: 4px;
+        font-size: 16px;
+
+        &>div{
+          display: flex;
+          align-items: center;
+
+          div:first-of-type{
+            width: 40px;
+            height: 40px;
+            margin-right: 10px;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+
+            img{
+              width: 28px;
+              height: 28px;
+            }
+          }
+          div:last-of-type{
+            width: 1000px;
+            white-space: nowrap;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            font-family: "PingFang SC";
+          }
+        }
+        span{
+          color: #999;
+        }
+        &:hover{
+          background: #f5f5f5;
+        }
+        &:active{
+          background: #425f9f;
+          color: #fff;
+        }
+      }
+    }
+
+    .pag-container{
+      width: 100%;
+      height: 80px;
+      display: flex;
+      align-items: center;
+      justify-content: right;
+    }
+  }
+}
+</style>
diff --git a/src/views/homePage.vue b/src/views/homePage.vue
index 115fc56..100a502 100644
--- a/src/views/homePage.vue
+++ b/src/views/homePage.vue
@@ -1,196 +1,242 @@
 <template>
   <div class="login">
-    <img class="pics1" src="src/assets/images/login-data.png">
-    <img class="pics2" src="src/assets/images/login-search.png">
-    <div class="login-panel">
-      <div class="login-img">
-        <img src="src/assets/images/loginImg.png">
-      </div>
-      <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
-        <h3 class="title">智慧安评</h3>
-        <el-form-item prop="username">
-          <el-input
-            v-model="loginForm.username"
-            type="text"
-            size="large"
-            auto-complete="off"
-            placeholder="账号"
-          >
-            <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
-          </el-input>
-        </el-form-item>
-        <el-form-item prop="password">
-          <el-input
-            v-model="loginForm.password"
-            type="password"
-            size="large"
-            auto-complete="off"
-            placeholder="密码"
-            @keyup.enter="handleLogin"
-          >
-            <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
-          </el-input>
-        </el-form-item>
-        <el-form-item prop="code" v-if="captchaEnabled">
-          <el-input
-            v-model="loginForm.code"
-            size="large"
-            auto-complete="off"
-            placeholder="验证码"
-            style="width: 63%"
-            @keyup.enter="handleLogin"
-          >
-            <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
-          </el-input>
-          <div class="login-code">
-            <img :src="codeUrl" @click="getCode" class="login-code-img"/>
-          </div>
-        </el-form-item>
-        <div style="display: flex;justify-content: space-between;align-items: center;margin-bottom: 25px">
-          <el-checkbox v-model="loginForm.rememberMe">记住密码</el-checkbox>
-          <div v-if="isRegister">
-            <el-button link type="primary" @click="openRegist">立即注册</el-button>
+<!--    <img class="pics1" src="src/assets/images/login-data.png">-->
+<!--    <img class="pics2" src="src/assets/images/login-search.png">-->
+    <div class="main-content">
+      <div class="top">
+        <div class="top-cont">
+          <div class="logo blueFont">智慧安评</div>
+          <div class="time">
+            <div>
+              <span>{{state.date}}</span>
+              <span>{{state.weekDay}}</span>
+            </div>
+            <div>
+              {{state.dayTime}}好!
+            </div>
           </div>
         </div>
-        <el-form-item style="width:100%;">
-          <el-button
-            :loading="loading"
-            size="large"
-            type="primary"
-            style="width:100%;"
-            @click.prevent="handleLogin"
-          >
-            <span v-if="!loading">登 录</span>
-            <span v-else>登 录 中...</span>
-          </el-button>
-        </el-form-item>
-      </el-form>
+      </div>
+
+      <div class="nav blueBg">
+        <div class="nav-cont">
+          <div :class="state.activeMenu == 1?'active': ''" @click="changeTab(1)">
+            <HomeFilled style="width: 1em; height: 1em; margin-right: 8px" />
+            <div>首页</div>
+          </div>
+          <div :class="state.activeMenu == 2?'active': ''" @click="changeTab(2)">
+            <Comment style="width: 1em; height: 1em; margin-right: 8px" />
+            <div>通知公告</div>
+          </div>
+          <div :class="state.activeMenu == 3?'active': ''" @click="changeTab(3)">
+            <BellFilled style="width: 1em; height: 1em; margin-right: 8px" />
+            <div>法律法规</div>
+          </div>
+          <div :class="state.activeMenu == 4?'active': ''" @click="changeTab(4)">
+            <List style="width: 1em; height: 1em; margin-right: 8px" />
+            <div>信息公示</div>
+          </div>
+        </div>
+      </div>
+      <div class="content">
+        <Home v-if="state.activeMenu==1" ref="homeRef" @toMore="changeTab"/>
+        <Notice v-if="state.activeMenu==2" ref="noticeRef"/>
+        <Laws v-if="state.activeMenu==3" ref="lawsRef"/>
+        <Publish v-if="state.activeMenu==4" ref="publishRef"/>
+      </div>
     </div>
     <!--  底部  -->
-<!--    <div class="el-login-footer">-->
-<!--      <span>Copyright © 2018-2023 ruoyi.vip All Rights Reserved.</span>-->
-<!--    </div>-->
+    <div class="el-login-footer">
+      <span>Copyright © All Rights Reserved.</span>
+    </div>
   </div>
-  <register ref="regRef"/>
 </template>
 
 <script setup>
-import {onMounted, ref, watch, defineAsyncComponent, nextTick} from "vue"
-import { getCodeImg } from "@/api/login";
-import Cookies from "js-cookie";
-import { encrypt, decrypt } from "@/utils/jsencrypt";
+import {onMounted, ref, reactive, watch, defineAsyncComponent, nextTick, onUnmounted} from "vue"
 import useUserStore from '@/store/modules/user'
-import { Register } from "@/layout/components";
+import Home from './components/home'
+import Notice from './components/notice'
+import Laws from './components/laws'
+import Publish from './components/publish'
 
-const userStore = useUserStore()
-const route = useRoute();
-const router = useRouter();
-const { proxy } = getCurrentInstance();
+const route = useRoute()
+const router = useRouter()
+// 时间格式化
+const timeForm = {
+  hour12: false,
+  year: 'numeric',
+  month: '2-digit',
+  day: '2-digit',
+  hour: '2-digit',
+  minute: '2-digit',
+  second: '2-digit'
+}
 
-const loginForm = ref({
-  username: "admin",
-  password: "Admin@123.com",
-  rememberMe: false,
-  code: "",
-  uuid: ""
-});
+const homeRef = ref(null)
+const noticeRef = ref(null)
+const lawsRef = ref(null)
+const publishRef = ref(null)
 
-const loginRules = {
-  username: [{ required: true, trigger: "blur", message: "请输入您的账号" }],
-  password: [{ required: true, trigger: "blur", message: "请输入您的密码" }],
-  code: [{ required: true, trigger: "change", message: "请输入验证码" }]
+const state = reactive({
+  activeMenu: 1,
+  date: '',
+  weekDay: '',
+  dayTime: ''
+})
+
+// 当前时间
+const getDateTime = () => {
+  const curTime = new Date().toLocaleString('zh', timeForm).replace(/\//g, '-');
+  console.log(curTime,'time')
+  state.date = curTime.slice(0, 10);
+  let week = ['日', '一', '二', '三', '四', '五', '六'];
+  let day = new Date().getDay();
+  state.weekDay = '星期' + week[day];
+  let curHour = Number(curTime.slice(10, 13));
+  if (curHour >= 5 && curHour <= 10) {
+    state.dayTime = '上午';
+  }
+  if (curHour > 10 && curHour <= 12) {
+    state.dayTime = '中午';
+  }
+  if (curHour > 12 && curHour <= 18) {
+    state.dayTime = '下午';
+  }
+  if (curHour > 18 && curHour <= 22) {
+    state.dayTime = '晚上';
+  }
+  if (curHour > 22) {
+    state.dayTime = '午夜';
+  }
 };
 
-const codeUrl = ref("");
-const loading = ref(false);
-const regRef = ref(null)
-// 验证码开关
-const captchaEnabled = ref(true);
-// 注册开关
-const isRegister = ref(true);
+
 const redirect = ref(undefined);
 
 onMounted(()=>{
-
+  getDateTime();
 })
 
-const openRegist = ()=>{
-  regRef.value.dialogVisible = true
-}
+onUnmounted(()=>{
+
+})
 
 watch(route, (newRoute) => {
     redirect.value = newRoute.query && newRoute.query.redirect;
 }, { immediate: true });
 
-function handleLogin() {
-  proxy.$refs.loginRef.validate(valid => {
-    if (valid) {
-      loading.value = true;
-      // 勾选了需要记住密码设置在 cookie 中设置记住用户名和密码
-      if (loginForm.value.rememberMe) {
-        Cookies.set("username", loginForm.value.username, { expires: 30 });
-        Cookies.set("password", encrypt(loginForm.value.password), { expires: 30 });
-        Cookies.set("rememberMe", loginForm.value.rememberMe, { expires: 30 });
-      } else {
-        // 否则移除
-        Cookies.remove("username");
-        Cookies.remove("password");
-        Cookies.remove("rememberMe");
-      }
-      // 调用action的登录方法
-      userStore.login(loginForm.value).then(() => {
-        const query = route.query;
-        const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
-          if (cur !== "redirect") {
-            acc[cur] = query[cur];
-          }
-          return acc;
-        }, {});
-        router.push({ path: redirect.value || "/", query: otherQueryParams });
-      }).catch(() => {
-        loading.value = false;
-        // 重新获取验证码
-        if (captchaEnabled.value) {
-          getCode();
-        }
-      });
-    }
-  });
+const changeTab=(num)=>{
+  state.activeMenu = num
+  console.log(state.activeMenu)
+  // if(num == 1){
+  //   homeRef.value.getNoticeList()
+  //   homeRef.value.getLawsList()
+  //   homeRef.value.getPubList()
+  // }
+  // if(num == 2){
+  //   noticeRef.value.getData()
+  // }
+  // if(num == 3){
+  //   lawsRef.value.getData()
+  // }
+  // if(num == 4){
+  //   publishRef.value.getData()
+  // }
 }
 
-function getCode() {
-  getCodeImg().then(res => {
-    captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled;
-    if (captchaEnabled.value) {
-      codeUrl.value = "data:image/gif;base64," + res.img;
-      loginForm.value.uuid = res.uuid;
-    }
-  });
-}
-
-function getCookie() {
-  const username = Cookies.get("username");
-  const password = Cookies.get("password");
-  const rememberMe = Cookies.get("rememberMe");
-  loginForm.value = {
-    username: username === undefined ? loginForm.value.username : username,
-    password: password === undefined ? loginForm.value.password : decrypt(password),
-    rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
-  };
-}
-
-getCode();
-getCookie();
 </script>
 
 <style lang='scss' scoped>
 .login {
+  width: 100%;
   display: flex;
-  position: relative;
   justify-content: center;
-  align-items: center;
   height: 100%;
-  background-image: url("../assets/images/login-bg.jpg");
+
+  .main-content{
+    width: 100%;
+    display: flex;
+    flex-direction: column;
+    color: #333;
+
+    .top{
+      width: 100%;
+      background: rgba(249,250,251,1);
+      position: fixed;
+      top: 0;
+      left: 0;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      .top-cont{
+        width: 1200px;
+        height: 90px;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        margin: 0 auto;
+
+        .logo{
+          font-size: 2rem;
+          font-weight: 800;
+          height: 90px;
+          line-height: 90px;
+          font-family: "PingFang SC";
+        }
+
+        .time{
+          font-size: 16px;
+          height: 90px;
+          display: flex;
+          flex-direction: column;
+          justify-content: center;
+          span{
+            &:first-of-type{
+              margin-right: 10px;
+            }
+          }
+        }
+      }
+    }
+
+
+    .nav{
+      width: 100%;
+      height: 80px;
+      position: fixed;
+      top: 90px;
+      left: 0;
+      .nav-cont{
+        width: 1200px;
+        height: 80px;
+        margin: 0 auto;
+        display: flex;
+        align-items: center;
+        justify-content: left;
+
+        &>div{
+          height: 100%;
+          padding: 0 50px;
+          color: #ffffff;
+          background-color: #5175C0;
+          font-size: 20px;
+          text-decoration: none;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          cursor: pointer;
+
+          &:hover{
+            background: #425f9f;
+          }
+        }
+        .active{
+          background: #425f9f;
+        }
+      }
+    }
+  }
 }
 .pics1{
   position: absolute;
@@ -206,83 +252,18 @@
   left: 20px;
   opacity: 0.5;
 }
-.title {
-  margin: 0px auto 30px auto;
-  text-align: center;
-  color: #333;
-  font-size: 1.4rem;
-}
-.login-panel{
-  border-radius: 1.2rem;
-  background: #ffffff;
-  width: 800px;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  transform: translateY(-20%);
-  box-shadow: 15px 15px 30px rgba(0,0,0,.1);
-}
-.login-img{
-  flex: 1;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  img{
-    width: 80%;
-  }
-}
-.login-form {
-  flex: 1;
-  padding: 25px;
-  .el-input {
-    height: 44px;
-    input {
-      height: 44px;
-    }
-  }
-  .input-icon {
-    height: 39px;
-    width: 14px;
-    margin-left: 0px;
-  }
-}
-.login-tip {
-  font-size: 13px;
-  text-align: center;
-  color: #bfbfbf;
-}
-.login-code {
-  width: 33%;
-  height: 40px;
-  float: right;
-  img {
-    cursor: pointer;
-    vertical-align: middle;
-  }
-}
 
-.el-form-item--default{
-  margin-bottom: 24px;
-}
-
-::v-deep(.el-form-item__content){
-  display: flex;
-  justify-content: space-between;
-}
 .el-login-footer {
-  height: 40px;
-  line-height: 40px;
+  height: 60px;
+  line-height: 60px;
   position: fixed;
   bottom: 0;
   width: 100%;
   text-align: center;
   color: #fff;
-  font-family: Arial;
+  background: #5175C0;
+  font-family: "PingFang SC";
   font-size: 12px;
   letter-spacing: 1px;
-}
-.login-code-img {
-  height: 40px;
-  padding-left: 12px;
 }
 </style>
diff --git a/src/views/originLogin.vue b/src/views/originLogin.vue
new file mode 100644
index 0000000..115fc56
--- /dev/null
+++ b/src/views/originLogin.vue
@@ -0,0 +1,288 @@
+<template>
+  <div class="login">
+    <img class="pics1" src="src/assets/images/login-data.png">
+    <img class="pics2" src="src/assets/images/login-search.png">
+    <div class="login-panel">
+      <div class="login-img">
+        <img src="src/assets/images/loginImg.png">
+      </div>
+      <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
+        <h3 class="title">智慧安评</h3>
+        <el-form-item prop="username">
+          <el-input
+            v-model="loginForm.username"
+            type="text"
+            size="large"
+            auto-complete="off"
+            placeholder="账号"
+          >
+            <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
+          </el-input>
+        </el-form-item>
+        <el-form-item prop="password">
+          <el-input
+            v-model="loginForm.password"
+            type="password"
+            size="large"
+            auto-complete="off"
+            placeholder="密码"
+            @keyup.enter="handleLogin"
+          >
+            <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
+          </el-input>
+        </el-form-item>
+        <el-form-item prop="code" v-if="captchaEnabled">
+          <el-input
+            v-model="loginForm.code"
+            size="large"
+            auto-complete="off"
+            placeholder="验证码"
+            style="width: 63%"
+            @keyup.enter="handleLogin"
+          >
+            <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
+          </el-input>
+          <div class="login-code">
+            <img :src="codeUrl" @click="getCode" class="login-code-img"/>
+          </div>
+        </el-form-item>
+        <div style="display: flex;justify-content: space-between;align-items: center;margin-bottom: 25px">
+          <el-checkbox v-model="loginForm.rememberMe">记住密码</el-checkbox>
+          <div v-if="isRegister">
+            <el-button link type="primary" @click="openRegist">立即注册</el-button>
+          </div>
+        </div>
+        <el-form-item style="width:100%;">
+          <el-button
+            :loading="loading"
+            size="large"
+            type="primary"
+            style="width:100%;"
+            @click.prevent="handleLogin"
+          >
+            <span v-if="!loading">登 录</span>
+            <span v-else>登 录 中...</span>
+          </el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <!--  底部  -->
+<!--    <div class="el-login-footer">-->
+<!--      <span>Copyright © 2018-2023 ruoyi.vip All Rights Reserved.</span>-->
+<!--    </div>-->
+  </div>
+  <register ref="regRef"/>
+</template>
+
+<script setup>
+import {onMounted, ref, watch, defineAsyncComponent, nextTick} from "vue"
+import { getCodeImg } from "@/api/login";
+import Cookies from "js-cookie";
+import { encrypt, decrypt } from "@/utils/jsencrypt";
+import useUserStore from '@/store/modules/user'
+import { Register } from "@/layout/components";
+
+const userStore = useUserStore()
+const route = useRoute();
+const router = useRouter();
+const { proxy } = getCurrentInstance();
+
+const loginForm = ref({
+  username: "admin",
+  password: "Admin@123.com",
+  rememberMe: false,
+  code: "",
+  uuid: ""
+});
+
+const loginRules = {
+  username: [{ required: true, trigger: "blur", message: "请输入您的账号" }],
+  password: [{ required: true, trigger: "blur", message: "请输入您的密码" }],
+  code: [{ required: true, trigger: "change", message: "请输入验证码" }]
+};
+
+const codeUrl = ref("");
+const loading = ref(false);
+const regRef = ref(null)
+// 验证码开关
+const captchaEnabled = ref(true);
+// 注册开关
+const isRegister = ref(true);
+const redirect = ref(undefined);
+
+onMounted(()=>{
+
+})
+
+const openRegist = ()=>{
+  regRef.value.dialogVisible = true
+}
+
+watch(route, (newRoute) => {
+    redirect.value = newRoute.query && newRoute.query.redirect;
+}, { immediate: true });
+
+function handleLogin() {
+  proxy.$refs.loginRef.validate(valid => {
+    if (valid) {
+      loading.value = true;
+      // 勾选了需要记住密码设置在 cookie 中设置记住用户名和密码
+      if (loginForm.value.rememberMe) {
+        Cookies.set("username", loginForm.value.username, { expires: 30 });
+        Cookies.set("password", encrypt(loginForm.value.password), { expires: 30 });
+        Cookies.set("rememberMe", loginForm.value.rememberMe, { expires: 30 });
+      } else {
+        // 否则移除
+        Cookies.remove("username");
+        Cookies.remove("password");
+        Cookies.remove("rememberMe");
+      }
+      // 调用action的登录方法
+      userStore.login(loginForm.value).then(() => {
+        const query = route.query;
+        const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
+          if (cur !== "redirect") {
+            acc[cur] = query[cur];
+          }
+          return acc;
+        }, {});
+        router.push({ path: redirect.value || "/", query: otherQueryParams });
+      }).catch(() => {
+        loading.value = false;
+        // 重新获取验证码
+        if (captchaEnabled.value) {
+          getCode();
+        }
+      });
+    }
+  });
+}
+
+function getCode() {
+  getCodeImg().then(res => {
+    captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled;
+    if (captchaEnabled.value) {
+      codeUrl.value = "data:image/gif;base64," + res.img;
+      loginForm.value.uuid = res.uuid;
+    }
+  });
+}
+
+function getCookie() {
+  const username = Cookies.get("username");
+  const password = Cookies.get("password");
+  const rememberMe = Cookies.get("rememberMe");
+  loginForm.value = {
+    username: username === undefined ? loginForm.value.username : username,
+    password: password === undefined ? loginForm.value.password : decrypt(password),
+    rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
+  };
+}
+
+getCode();
+getCookie();
+</script>
+
+<style lang='scss' scoped>
+.login {
+  display: flex;
+  position: relative;
+  justify-content: center;
+  align-items: center;
+  height: 100%;
+  background-image: url("../assets/images/login-bg.jpg");
+}
+.pics1{
+  position: absolute;
+  width: 500px;
+  bottom: 0;
+  right: 0;
+  opacity: 0.5;
+}
+.pics2{
+  position: absolute;
+  width: 500px;
+  top: 20px;
+  left: 20px;
+  opacity: 0.5;
+}
+.title {
+  margin: 0px auto 30px auto;
+  text-align: center;
+  color: #333;
+  font-size: 1.4rem;
+}
+.login-panel{
+  border-radius: 1.2rem;
+  background: #ffffff;
+  width: 800px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  transform: translateY(-20%);
+  box-shadow: 15px 15px 30px rgba(0,0,0,.1);
+}
+.login-img{
+  flex: 1;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  img{
+    width: 80%;
+  }
+}
+.login-form {
+  flex: 1;
+  padding: 25px;
+  .el-input {
+    height: 44px;
+    input {
+      height: 44px;
+    }
+  }
+  .input-icon {
+    height: 39px;
+    width: 14px;
+    margin-left: 0px;
+  }
+}
+.login-tip {
+  font-size: 13px;
+  text-align: center;
+  color: #bfbfbf;
+}
+.login-code {
+  width: 33%;
+  height: 40px;
+  float: right;
+  img {
+    cursor: pointer;
+    vertical-align: middle;
+  }
+}
+
+.el-form-item--default{
+  margin-bottom: 24px;
+}
+
+::v-deep(.el-form-item__content){
+  display: flex;
+  justify-content: space-between;
+}
+.el-login-footer {
+  height: 40px;
+  line-height: 40px;
+  position: fixed;
+  bottom: 0;
+  width: 100%;
+  text-align: center;
+  color: #fff;
+  font-family: Arial;
+  font-size: 12px;
+  letter-spacing: 1px;
+}
+.login-code-img {
+  height: 40px;
+  padding-left: 12px;
+}
+</style>

--
Gitblit v1.9.2