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