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