fix: 优化图书推荐系统

This commit is contained in:
Shu Guang 2025-04-13 19:58:22 +08:00
parent 6a69f05269
commit 779948ec47
10 changed files with 1257 additions and 719 deletions

View File

@ -4,74 +4,75 @@
<div class="login_box"> <div class="login_box">
<!-- 头像区域 --> <!-- 头像区域 -->
<div class="avatar_box"> <div class="avatar_box">
<img src="https://xxx.xiaobaitiao.icu/img/icu/202312211243634.jpg" alt=""/> <img
src="https://minio-img.933999.xyz/images-lankong/lankong/2025/04/13/67fba08cd075b.jpeg"
alt=""
/>
</div> </div>
<!-- 登录表单区域 --> <!-- 登录表单区域 -->
<el-form <el-form
ref="loginFormRef" ref="loginFormRef"
:model="loginForm" :model="loginForm"
:rules="loginFormRules" :rules="loginFormRules"
label-width="0px" label-width="0px"
class="login_form" class="login_form"
> >
<!-- 用户名 --> <!-- 用户名 -->
<el-form-item prop="username"> <el-form-item prop="username">
<el-input <el-input
v-model.trim="loginForm.username" v-model.trim="loginForm.username"
prefix-icon="iconfont icon-gerenxinxi" prefix-icon="iconfont icon-gerenxinxi"
></el-input> ></el-input>
</el-form-item> </el-form-item>
<!-- 密码 --> <!-- 密码 -->
<el-form-item prop="password"> <el-form-item prop="password">
<el-input <el-input
v-model="loginForm.password" v-model="loginForm.password"
prefix-icon="iconfont icon-tianchongxing-" prefix-icon="iconfont icon-tianchongxing-"
type="password" type="password"
@keyup.enter.native="login" @keyup.enter.native="login"
:show-password="true" :show-password="true"
></el-input> ></el-input>
</el-form-item> </el-form-item>
<!-- 按钮区域 --> <!-- 按钮区域 -->
<el-form-item class="btns"> <el-form-item class="btns">
<el-button type="primary" @click="login" :loading="loginLoading">登录</el-button> <el-button type="primary" @click="login" :loading="loginLoading"
>登录</el-button
>
<el-button type="info" @click="resetLoginForm">重置</el-button> <el-button type="info" @click="resetLoginForm">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<vue-particles <vue-particles
class="login-bg" class="login-bg"
color="#39AFFD" color="#39AFFD"
:particleOpacity="0.7" :particleOpacity="0.7"
:particlesNumber="100" :particlesNumber="100"
shapeType="circle" shapeType="circle"
:particleSize="4" :particleSize="4"
linesColor="#8DD1FE" linesColor="#8DD1FE"
:linesWidth="1" :linesWidth="1"
:lineLinked="true" :lineLinked="true"
:lineOpacity="0.4" :lineOpacity="0.4"
:linesDistance="150" :linesDistance="150"
:moveSpeed="3" :moveSpeed="3"
:hoverEffect="true" :hoverEffect="true"
hoverMode="grab" hoverMode="grab"
:clickEffect="true" :clickEffect="true"
clickMode="push" clickMode="push"
> >
</vue-particles> </vue-particles>
<div class="footer"> <div class="footer">
<span style="font-weight: bold;color:white;margin-bottom: 10px"> <span style="font-weight: bold; color: white; margin-bottom: 10px">
登录页面切换 登录页面切换
</span> </span>
<span><i class="iconfont icon-haoyou" @click="goUser"></i></span> <span><i class="iconfont icon-haoyou" @click="goUser"></i></span>
</div>
<div class="footer2">
</div> </div>
<div class="footer2"></div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
@ -83,7 +84,7 @@ export default {
// //
loginFormRules: { loginFormRules: {
username: [ username: [
{required: true, message: "用户名不能为空", trigger: "blur"}, { required: true, message: "用户名不能为空", trigger: "blur" },
{ {
min: 3, min: 3,
max: 20, max: 20,
@ -92,7 +93,7 @@ export default {
}, },
], ],
password: [ password: [
{required: true, message: "密码不能为空", trigger: "blur"}, { required: true, message: "密码不能为空", trigger: "blur" },
{ {
min: 6, min: 6,
max: 15, max: 15,
@ -101,7 +102,7 @@ export default {
}, },
], ],
}, },
loginLoading: false loginLoading: false,
}; };
}, },
methods: { methods: {
@ -119,13 +120,10 @@ export default {
const username = this.loginForm.username; const username = this.loginForm.username;
const password = this.loginForm.password; const password = this.loginForm.password;
//axios //axios
const {data: res} = await this.$http.post( const { data: res } = await this.$http.post("admin/login", {
"admin/login", username,
{ password,
username, });
password
}
);
if (res.status !== 200) { if (res.status !== 200) {
this.loginLoading = false; this.loginLoading = false;
return this.$message.error(res.msg); return this.$message.error(res.msg);
@ -159,7 +157,8 @@ export default {
.login_container { .login_container {
// background-color: #2b4b6b; // background-color: #2b4b6b;
background: url(https://xxx.xiaobaitiao.icu/img/icu/202312211236280.jpg) no-repeat 0px 0px; background: url(https://xxx.xiaobaitiao.icu/img/icu/202312211236280.jpg)
no-repeat 0px 0px;
background-size: cover; background-size: cover;
height: 100%; height: 100%;
} }

View File

@ -5,7 +5,7 @@
<!-- 头像区域 --> <!-- 头像区域 -->
<div class="avatar_box"> <div class="avatar_box">
<img <img
src="https://xxx.xiaobaitiao.icu/img/icu/202312211243634.jpg" src="https://minio-img.933999.xyz/images-lankong/lankong/2025/04/13/67fba08cd075b.jpeg"
alt="" alt=""
/> />
</div> </div>
@ -63,22 +63,17 @@
> >
</vue-particles> </vue-particles>
<div class="footer"> <div class="footer">
<span style="font-weight: bold;color:white;"> <span style="font-weight: bold; color: white"> 登录页面切换 </span>
登录页面切换
</span>
<span><i class="iconfont icon-haoyou" @click="goUser"></i></span> <span><i class="iconfont icon-haoyou" @click="goUser"></i></span>
<span> <span>
<i class="iconfont icon-guanliyuanrenzheng" @click="goAdmin"></i> <i class="iconfont icon-guanliyuanrenzheng" @click="goAdmin"></i>
</span> </span>
</div> </div>
<div class="footer2"> <div class="footer2"></div>
</div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
@ -169,8 +164,8 @@ export default {
.login_container { .login_container {
// background-color: #2b4b6b; // background-color: #2b4b6b;
background: url(https://xxx.xiaobaitiao.icu/img/icu/202312211236280.jpg) no-repeat background: url(https://xxx.xiaobaitiao.icu/img/icu/202312211236280.jpg)
0px 0px; no-repeat 0px 0px;
background-size: cover; background-size: cover;
height: 100%; height: 100%;
} }

View File

@ -28,20 +28,18 @@ export default {
"bookadmin/query_book/" + this.bookNumber "bookadmin/query_book/" + this.bookNumber
); );
if (res.status !== 200) { if (res.status !== 200) {
return this.$message.error( return this.$message.error({
{ message: res.msg,
message:res.msg, duration: 1000,
duration:1000 });
}
);
} }
// console.log(res); // console.log(res);
// this.$message.success(res.msg); // this.$message.success(res.msg);
this.$router.push({ this.$router.push({
name:"bookexpire", name: "bookexpire",
query:{ query: {
bookNumber:this.bookNumber bookNumber: this.bookNumber,
} },
}); });
}, },
}, },
@ -83,4 +81,4 @@ export default {
} }
} }
} }
</style> </style>

View File

@ -3,7 +3,7 @@
<el-header> <el-header>
<div class="logo-container"> <div class="logo-container">
<img src="" alt="" class="logo" /> <img src="" alt="" class="logo" />
<span class="title">图书管理系统</span> <span class="title">图书推荐系统</span>
<span class="subtitle">借阅者界面</span> <span class="subtitle">借阅者界面</span>
</div> </div>
<div class="user-info"> <div class="user-info">
@ -43,7 +43,7 @@
> >
<div class="menu-header"> <div class="menu-header">
<i class="el-icon-reading menu-icon"></i> <i class="el-icon-reading menu-icon"></i>
<span v-if="!isCollapse" class="menu-title">图书管理系统</span> <span v-if="!isCollapse" class="menu-title">图书推荐系统</span>
</div> </div>
<el-menu-item index="index" @click="saveNavState('index')"> <el-menu-item index="index" @click="saveNavState('index')">

View File

@ -1,44 +1,54 @@
<template> <template>
<el-container class="home-container"> <el-container class="home-container">
<!-- 头部区域 -->
<el-header> <el-header>
<div> <div class="logo-container">
<!-- <img src="../assets/heima.png" alt="" /> --> <!-- <img src="../assets/logo.png" alt="" class="logo" /> -->
<span>欢迎登录图书管理系统</span> <span class="title">图书推荐系统</span>
<span style="color: #ccc; font-size: 16px">系统管理人员页面</span> <span class="subtitle">系统管理人员页面</span>
</div> </div>
<div> <div class="user-info">
<el-avatar
<div> src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"
<el-avatar :size="40"
src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" class="avatar"
:size="35" ></el-avatar>
style="margin-right: 10px" <div class="user">管理员{{ this.admin.adminName }}</div>
></el-avatar> <el-button type="primary" size="medium" @click="logout" plain
</div> >退出</el-button
<div class="user">管理员:{{ this.admin.adminName }}</div> >
<el-button type="info" @click="logout">退出</el-button>
</div> </div>
</el-header> </el-header>
<!-- 页面主体区域 --> <!-- 页面主体区域 -->
<el-container> <el-container>
<!-- 侧边栏 --> <!-- 侧边栏 -->
<el-aside :width="isCollapse ? '64px' : '200px'"> <el-aside
<div class="toggle-button" @click="toggleCollapse">|||</div> :width="isCollapse ? '64px' : '240px'"
class="sidebar-container"
>
<div class="toggle-button" @click="toggleCollapse">
<i :class="isCollapse ? 'el-icon-s-unfold' : 'el-icon-s-fold'"></i>
</div>
<!-- 侧边栏菜单区域 --> <!-- 侧边栏菜单区域 -->
<el-menu <el-menu
:default-active="activePath" :default-active="activePath"
class="el-menu-vertical-demo" class="el-menu-vertical"
background-color="#fff" background-color="#001529"
text-color="black" text-color="rgba(255,255,255,0.65)"
active-text-color="#ffd04b" active-text-color="#fff"
:router="true" :router="true"
:collapse="isCollapse" :collapse="isCollapse"
:collapse-transition="false" :collapse-transition="true"
unique-opened
> >
<div class="menu-header">
<i class="el-icon-s-tools menu-icon"></i>
<span v-if="!isCollapse" class="menu-title">系统管理</span>
</div>
<el-menu-item index="bookmanage" @click="saveNavState('bookmanage')"> <el-menu-item index="bookmanage" @click="saveNavState('bookmanage')">
<i class="el-icon-notebook-1"></i> <i class="el-icon-notebook-1"></i>
<span slo="title">书籍管理</span> <span slot="title">书籍管理</span>
</el-menu-item> </el-menu-item>
<el-menu-item index="booktype" @click="saveNavState('booktype')"> <el-menu-item index="booktype" @click="saveNavState('booktype')">
<i class="el-icon-notebook-2"></i> <i class="el-icon-notebook-2"></i>
@ -80,27 +90,24 @@
<span slot="title">系统管理</span> <span slot="title">系统管理</span>
</el-menu-item> </el-menu-item>
<el-menu-item <el-menu-item
index="intelligent_analysis" index="intelligent_analysis"
@click="saveNavState('intelligent_analysis')" @click="saveNavState('intelligent_analysis')"
> >
<i class="el-icon-data-line"></i> <i class="el-icon-data-line"></i>
<span slot="title">智能分析</span> <span slot="title">智能分析</span>
</el-menu-item> </el-menu-item>
</el-menu> </el-menu>
</el-aside> </el-aside>
<!-- 右侧内容主体 -->
<el-main> <el-main>
<!-- 路由占位符 -->
<router-view></router-view> <router-view></router-view>
<div class="footer"> <div class="footer"></div>
</div>
</el-main> </el-main>
</el-container> </el-container>
</el-container> </el-container>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
@ -160,68 +167,186 @@ export default {
}; };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.footer {
position: fixed;
bottom: 0px;
left: 40%;
color:#ccc;
a {
color:#ccc;
}
}
.home-container { .home-container {
height: 100%; height: 100vh;
background-color: #f0f2f5;
} }
.el-header { .el-header {
background-color: rgb(34, 34, 34); background: linear-gradient(90deg, #1890ff 0%, #36cfc9 100%);
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding-left: 0px;
align-items: center; align-items: center;
color: #fff; padding: 0 20px;
font-size: 20px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
border-radius: 10px;
> div { .logo-container {
display: flex; display: flex;
align-items: center; align-items: center;
span {
.logo {
height: 40px;
margin-right: 15px;
}
.title {
font-size: 22px;
font-weight: 600;
color: #fff;
}
.subtitle {
margin-left: 15px; margin-left: 15px;
font-size: 16px;
color: rgba(255, 255, 255, 0.85);
}
}
.user-info {
display: flex;
align-items: center;
.avatar {
margin-right: 12px;
border: 2px solid rgba(255, 255, 255, 0.3);
}
.user {
margin-right: 20px;
color: #fff;
font-size: 16px;
} }
} }
} }
.el-aside { .el-aside {
background-color: #fff; background-color: #fff;
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.05);
.toggle-button {
background: #002140;
color: #fff;
text-align: center;
line-height: 32px;
height: 32px;
cursor: pointer;
transition: all 0.3s;
&:hover {
background: #002849;
}
i {
font-size: 16px;
}
}
.el-menu { .el-menu {
border-right: none; border-right: none;
} }
.el-menu-item {
margin: 4px 0;
&:hover {
background-color: #e6f7ff !important;
color: #1890ff !important;
}
&.is-active {
background-color: #1890ff !important;
color: #fff !important;
border-right: 3px solid #fff;
}
}
} }
.el-main { .el-main {
background-color: #eaedf1; background-color: #f0f2f5;
padding: 20px; padding: 20px;
.footer {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
color: #999;
font-size: 14px;
}
} }
.iconfont { .iconfont {
margin-right: 10px; margin-right: 12px;
font-size: 18px;
} }
.toggle-button {
background-color: #4a5064; .sidebar-container {
font-size: 10px; transition: width 0.3s;
line-height: 24px; background-color: #001529;
color: #fff; overflow: hidden;
text-align: center;
// .menu-header {
letter-spacing: 0.2em; height: 56px;
cursor: pointer; padding: 0 16px;
display: flex;
align-items: center;
color: #fff;
.menu-icon {
font-size: 20px;
margin-right: 10px;
}
.menu-title {
font-size: 16px;
font-weight: 600;
white-space: nowrap;
}
}
.el-menu {
border: none;
&:not(.el-menu--collapse) {
width: 240px;
}
}
.el-menu-item {
height: 50px;
line-height: 50px;
&:hover {
background: rgba(255, 255, 255, 0.08) !important;
color: #fff !important;
}
&.is-active {
background: #1890ff !important;
color: #fff !important;
&::before {
content: "";
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 3px;
background: #fff;
}
}
i {
color: inherit;
font-size: 18px;
margin-right: 10px;
}
}
} }
.user {
margin-right: 15px; .el-main {
color: #ccc; padding: 20px;
font-size: 16px; background: #f0f2f5;
} }
.el-menu-item:hover {
background-color: rgb(51, 122, 183) !important;
}
// .el-menu-item{
// color:rgb(135, 206, 235) !important;
// }
</style> </style>

View File

@ -1,44 +1,54 @@
<template> <template>
<el-container class="home-container"> <el-container class="home-container">
<!-- 头部区域 -->
<el-header> <el-header>
<div> <div class="logo-container">
<!-- <img src="../assets/heima.png" alt="" /> --> <!-- <img src="../assets/logo.png" alt="" class="logo" /> -->
<span>欢迎登录图书管理系统</span> <span class="title">图书推荐系统</span>
<span style="color: #ccc; font-size: 16px">图书馆管理人员页面</span> <span class="subtitle">图书管理员页面</span>
</div> </div>
<div> <div class="user-info">
<el-avatar
<div> src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"
<el-avatar :size="40"
src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" class="avatar"
:size="35" ></el-avatar>
style="margin-right: 10px" <div class="user">管理员{{ this.bookAdmin.bookAdminName }}</div>
></el-avatar> <el-button type="primary" size="medium" @click="logout" plain
</div> >退出</el-button
<div class="user">管理员:{{ this.bookAdmin.bookAdminName }}</div> >
<el-button type="info" @click="logout">退出</el-button>
</div> </div>
</el-header> </el-header>
<!-- 页面主体区域 --> <!-- 页面主体区域 -->
<el-container> <el-container>
<!-- 侧边栏 --> <!-- 侧边栏 -->
<el-aside :width="isCollapse ? '64px' : '200px'"> <el-aside
<div class="toggle-button" @click="toggleCollapse">|||</div> :width="isCollapse ? '64px' : '240px'"
class="sidebar-container"
>
<div class="toggle-button" @click="toggleCollapse">
<i :class="isCollapse ? 'el-icon-s-unfold' : 'el-icon-s-fold'"></i>
</div>
<!-- 侧边栏菜单区域 --> <!-- 侧边栏菜单区域 -->
<el-menu <el-menu
:default-active="activePath" :default-active="activePath"
class="el-menu-vertical-demo" class="el-menu-vertical"
background-color="#fff" background-color="#001529"
text-color="black" text-color="rgba(255,255,255,0.65)"
active-text-color="#ffd04b" active-text-color="#fff"
:router="true" :router="true"
:collapse="isCollapse" :collapse="isCollapse"
:collapse-transition="false" :collapse-transition="true"
unique-opened
> >
<div class="menu-header">
<i class="el-icon-collection menu-icon"></i>
<span v-if="!isCollapse" class="menu-title">图书管理</span>
</div>
<el-menu-item index="borrowbook" @click="saveNavState('borrowbook')"> <el-menu-item index="borrowbook" @click="saveNavState('borrowbook')">
<i class="el-icon-collection"></i> <i class="el-icon-collection"></i>
<span slo="title">借阅图书</span> <span slot="title">借阅图书</span>
</el-menu-item> </el-menu-item>
<el-menu-item index="returnbook" @click="saveNavState('returnbook')"> <el-menu-item index="returnbook" @click="saveNavState('returnbook')">
<i class="el-icon-collection"></i> <i class="el-icon-collection"></i>
@ -67,19 +77,16 @@
</el-menu-item> </el-menu-item>
</el-menu> </el-menu>
</el-aside> </el-aside>
<!-- 右侧内容主体 -->
<el-main> <el-main>
<!-- 路由占位符 -->
<router-view></router-view> <router-view></router-view>
<div class="footer"> <div class="footer"></div>
</div>
</el-main> </el-main>
</el-container> </el-container>
</el-container> </el-container>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
@ -96,16 +103,16 @@ export default {
isCollapse: false, isCollapse: false,
// //
activePath: "", activePath: "",
bookAdmin:{ bookAdmin: {
bookAdminId:Number, bookAdminId: Number,
status:Number, status: Number,
username:"", username: "",
password:"", password: "",
bookAdminName:"", bookAdminName: "",
email:"", email: "",
createTime:"", createTime: "",
updateTime:"" updateTime: "",
} },
}; };
}, },
async created() { async created() {
@ -116,7 +123,10 @@ export default {
const stringId = window.sessionStorage.getItem("bookAdminId"); const stringId = window.sessionStorage.getItem("bookAdminId");
const id = parseInt(stringId); const id = parseInt(stringId);
this.bookAdmin.bookAdminId = id; this.bookAdmin.bookAdminId = id;
const { data: res } = await this.$http.post("bookadmin/getData", this.bookAdmin); const { data: res } = await this.$http.post(
"bookadmin/getData",
this.bookAdmin
);
// console.log(res); // console.log(res);
this.bookAdmin = res.data; this.bookAdmin = res.data;
}, },
@ -141,69 +151,186 @@ export default {
}; };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.footer {
position: fixed;
bottom: 0px;
left: 40%;
color:#ccc;
a {
color:#ccc;
}
}
.home-container { .home-container {
height: 100%; height: 100vh;
background-color: #f0f2f5;
} }
.el-header { .el-header {
background-color: rgb(34, 34, 34); background: linear-gradient(90deg, #1890ff 0%, #36cfc9 100%);
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding-left: 0px;
align-items: center; align-items: center;
color: #fff; padding: 0 20px;
font-size: 20px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
border-radius: 10px;
> div { .logo-container {
display: flex; display: flex;
align-items: center; align-items: center;
span {
.logo {
height: 40px;
margin-right: 15px;
}
.title {
font-size: 22px;
font-weight: 600;
color: #fff;
}
.subtitle {
margin-left: 15px; margin-left: 15px;
font-size: 16px;
color: rgba(255, 255, 255, 0.85);
}
}
.user-info {
display: flex;
align-items: center;
.avatar {
margin-right: 12px;
border: 2px solid rgba(255, 255, 255, 0.3);
}
.user {
margin-right: 20px;
color: #fff;
font-size: 16px;
} }
} }
} }
.el-aside { .el-aside {
background-color: #fff; background-color: #fff;
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.05);
.toggle-button {
background: #002140;
color: #fff;
text-align: center;
line-height: 32px;
height: 32px;
cursor: pointer;
transition: all 0.3s;
&:hover {
background: #002849;
}
i {
font-size: 16px;
}
}
.el-menu { .el-menu {
border-right: none; border-right: none;
} }
.el-menu-item {
margin: 4px 0;
&:hover {
background-color: #e6f7ff !important;
color: #1890ff !important;
}
&.is-active {
background-color: #1890ff !important;
color: #fff !important;
border-right: 3px solid #fff;
}
}
} }
.el-main { .el-main {
background-color: #eaedf1; background-color: #f0f2f5;
padding: 20px; padding: 20px;
.footer {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
color: #999;
font-size: 14px;
}
} }
.iconfont { .iconfont {
margin-right: 10px; margin-right: 12px;
font-size: 18px;
} }
.toggle-button {
background-color: #4a5064; .sidebar-container {
font-size: 10px; transition: width 0.3s;
line-height: 24px; background-color: #001529;
color: #fff; overflow: hidden;
text-align: center;
// .menu-header {
letter-spacing: 0.2em; height: 56px;
cursor: pointer; padding: 0 16px;
display: flex;
align-items: center;
color: #fff;
.menu-icon {
font-size: 20px;
margin-right: 10px;
}
.menu-title {
font-size: 16px;
font-weight: 600;
white-space: nowrap;
}
}
.el-menu {
border: none;
&:not(.el-menu--collapse) {
width: 240px;
}
}
.el-menu-item {
height: 50px;
line-height: 50px;
&:hover {
background: rgba(255, 255, 255, 0.08) !important;
color: #fff !important;
}
&.is-active {
background: #1890ff !important;
color: #fff !important;
&::before {
content: "";
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 3px;
background: #fff;
}
}
i {
color: inherit;
font-size: 18px;
margin-right: 10px;
}
}
} }
.user {
margin-right: 15px; .el-main {
color: #ccc; padding: 20px;
font-size: 16px; background: #f0f2f5;
} }
.el-menu-item:hover {
background-color: rgb(51, 122, 183) !important;
}
// .el-menu-item{
// color:rgb(135, 206, 235) !important;
// }
</style> </style>

View File

@ -1,60 +1,59 @@
<template> <template>
<div class="comment_container"> <div class="comment-container">
<div class="backgroundImg"> <div class="background-wrapper"></div>
<img
src="https://xxx.xiaobaitiao.icu/img/icu/202312211243628.jpg" <div class="content-wrapper">
alt="" <div class="barrage-box">
/> <vue-baberrage
</div> :isShow="barrageIsShow"
<div class="barrages-drop"> :barrageList="barrageList"
<vue-baberrage :maxWordCount="50"
:isShow="barrageIsShow" :throttleGap="2000"
:barrageList="barrageList" :loop="false"
:maxWordCount="maxWordCount" :boxHeight="600"
:throttleGap="throttleGap" :messageHeight="50"
:loop="barrageLoop" :lanesCount="8"
:boxHeight="boxHeight" class="barrage-component"
:boxWidth="boxWidth"
:messageHeight="messageHeight"
:lanesCount="lanesCount"
style="width: 1330px; height: 750px"
>
</vue-baberrage>
<div class="addMain">
<el-input
placeholder="请输入内容"
v-model.trim="input"
class="input-with-select"
@keyup.enter.native="addContent"
> >
</vue-baberrage>
</div>
<div class="input-box">
<el-input
v-model.trim="input"
placeholder="发送一条友善的评论吧~"
maxlength="50"
show-word-limit
class="comment-input"
>
<template slot="prepend">
<i class="el-icon-chat-line-round"></i>
</template>
<el-button <el-button
slot="append" slot="append"
icon="el-icon-edit" type="primary"
:loading="sending"
@click="addContent" @click="addContent"
></el-button> >
发送弹幕
</el-button>
</el-input> </el-input>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { MESSAGE_TYPE } from "vue-baberrage"; import { MESSAGE_TYPE } from "vue-baberrage";
import { nanoid, random } from "nanoid"; import _ from "lodash";
export default { export default {
name: "Comment",
data() { data() {
return { return {
barrageIsShow: true, // barrageIsShow: true,
messageHeight: 3, //()
barrageLoop: false, //
maxWordCount: 2, //()
lanesCount: 1, //()
boxWidth: 1600, //
boxHeight: 200, //()
throttleGap: 3000, //
input: "", input: "",
// sending: false,
barrageList: [], barrageList: [],
barrage: { barrage: {
id: "", id: "",
@ -63,81 +62,179 @@ export default {
msg: "", msg: "",
time: "", time: "",
type: MESSAGE_TYPE.NORMAL, type: MESSAGE_TYPE.NORMAL,
barrageStyle: "", barrageStyle: {
fontSize: "16px",
padding: "5px 10px",
backgroundColor: "rgba(0, 0, 0, 0.6)",
color: "#fff",
borderRadius: "4px",
},
}, },
}; };
}, },
methods: { methods: {
addContent:_.throttle(async function(){ addContent: _.throttle(
// async function () {
if(this.input.trim()===''||/^\d+$/.test(this.input)||/^[a-zA-Z]+$/.test(this.input)){ if (
this.$message.info({ !this.input.trim() ||
message: "请不要输入无意义的内容", /^\d+$/.test(this.input) ||
duration:1000 /^[a-zA-Z]+$/.test(this.input)
}) ) {
return; this.$message.warning("请输入有意义的评论内容");
} return;
// barrage }
this.barrage.msg = this.input;
// addComment try {
const {data:res} = await this.$http.post('user/add_comment',this.barrage); this.sending = true;
if(res.status !== 200){ this.barrage.msg = this.input;
return this.$message.error(res.msg) const { data: res } = await this.$http.post(
} "user/add_comment",
// this.barrage
this.getCommentList(); );
//
this.input = ""; if (res.status !== 200) {
this.$message.success(res.msg); throw new Error(res.msg);
},5000,{ trailing: false }), }
await this.getCommentList();
this.input = "";
this.$message.success("发送成功");
} catch (error) {
this.$message.error(error.message || "发送失败");
} finally {
this.sending = false;
}
},
3000,
{ trailing: false }
),
async getCommentList() { async getCommentList() {
// axios try {
const { data: res } = await this.$http.get("user/get_commentlist"); const { data: res } = await this.$http.get("user/get_commentlist");
// console.log(res); if (res.status !== 200) {
if (res.status !== 200) { throw new Error(res.msg);
return this.$message.error(res.msg); }
this.barrageList = [...res.data, {}];
} catch (error) {
this.$message.error("获取评论列表失败");
} }
this.$message.success(res.msg);
this.barrageList = res.data
//
this.barrageList.push({})
}, },
}, },
mounted() {
mounted(){
this.getCommentList(); this.getCommentList();
} //
setInterval(() => {
this.getCommentList();
}, 30000);
},
beforeDestroy() {
clearInterval(this.timer);
},
}; };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.comment-container {
.comment_container {
position: relative; position: relative;
height: 100%; height: 100vh;
width: 100%; width: 100%;
overflow: hidden;
} }
.backgroundImg {
position: absolute; .background-wrapper {
height: 100%; position: fixed;
top: 0;
left: 0;
width: 100%; width: 100%;
height: 100%;
z-index: 0;
img { img {
height: 100%;
width: 100%; width: 100%;
opacity: 0.5; height: 100%;
object-fit: cover;
opacity: 0.3;
filter: blur(5px);
}
&::after {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(
to bottom,
rgba(255, 255, 255, 0.1),
rgba(255, 255, 255, 0.3)
);
} }
} }
.barrages-drop {
.content-wrapper {
position: relative; position: relative;
z-index: 1;
// height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 20px;
} }
.addMain {
position: absolute; .barrage-box {
width: 300px; width: 100vw;
height: 100%; width: 100%;
background-color: pink; height: 600px;
top: 450px; margin-bottom: 30px;
left: 50%;
transform: translate(-50%, -50%); .barrage-component {
background: rgba(0, 0, 0, 0.1);
border-radius: 8px;
}
}
.input-box {
width: 100%;
max-width: 600px;
padding: 20px;
.comment-input {
/deep/ .el-input-group__prepend {
background: #fff;
padding: 0 15px;
i {
font-size: 18px;
color: #409eff;
}
}
/deep/ .el-input__inner {
height: 45px;
font-size: 16px;
}
/deep/ .el-button {
padding: 12px 20px;
font-size: 16px;
}
}
}
//
@media screen and (max-width: 768px) {
.input-box {
padding: 10px;
.comment-input {
/deep/ .el-input__inner {
height: 40px;
font-size: 14px;
}
}
}
} }
</style> </style>

View File

@ -1,96 +1,117 @@
<template> <template>
<div class="information_container"> <div class="information-container">
<div class="backgroundImg"> <el-card class="info-card">
<img <div class="info-header">
src="https://xxx.xiaobaitiao.icu/img/icu/202312211243635.jpg" <h2>个人信息</h2>
alt="背景图片" <p class="motto">
/> <i class="el-icon-reading"></i>
</div> By reading we enrich the mind, by conversation we polish it.
<div class="information_header"> </p>
<p>个人信息</p>
<p>
<i class="el-icon-s-flag"></i> By reading we enrich the mind, by
conversation we polish it.
</p>
</div>
<div class="information_banner"
v-loading="loading"
element-loading-text="拼命加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.8)">
<div class="information_banner_left" >
<div class="banner_left_main" v-if="show">
<div class="number">
<i class="el-icon-collection-tag"></i> 借阅证编号:
{{ this.user.cardNumber }}
</div>
<div class="name">
<i class="iconfont icon-gerenxinxi"></i> 借阅证姓名:
{{ this.user.cardName }}
</div>
<div class="rule">
<i class="iconfont icon-guizeshezhi"></i> 规则编号:
{{ this.user.ruleNumber }}
</div>
<div class="status">
<i class="el-icon-refresh"></i> 状态:
{{ this.user.status === 1 ? "可用" : "禁用" }}
</div>
</div>
</div> </div>
<div class="information_banner_right">
<el-button type="primary" class="changePWD" @click="showEditDialog" v-if="show" <div
>修改密码</el-button class="info-content"
> v-loading="loading"
</div> element-loading-text="加载中..."
<el-dialog
title="修改密码"
:visible.sync="editDialogVisible"
width="50%"
@close="editDialogClosed"
> >
<el-form <template v-if="show">
:model="editForm" <el-row :gutter="20">
ref="editFormRef" <el-col :span="24">
:rules="editFormRules" <div class="info-item">
label-width="120px" <i class="el-icon-collection-tag"></i>
> <span class="label">借阅证编号</span>
<el-form-item label="新密码" prop="password"> <span class="value">{{ user.cardNumber }}</span>
<el-input v-model="editForm.password" type="password" placeholder="请输入新密码"></el-input> </div>
</el-form-item> <div class="info-item">
<el-form-item label="新密码" prop="confirmPassword"> <i class="el-icon-user"></i>
<el-input v-model="editForm.confirmPassword" type="password" placeholder="请再次输入新密码"></el-input> <span class="label">借阅证姓名</span>
</el-form-item> <span class="value">{{ user.cardName }}</span>
</el-form> </div>
<span slot="footer" class="dialog-footer"> <div class="info-item">
<el-button @click="editDialogVisible = false"> </el-button> <i class="el-icon-document"></i>
<el-button type="primary" @click="changePassword" <span class="label">规则编号</span>
> </el-button <span class="value">{{ user.ruleNumber }}</span>
> </div>
</span> <div class="info-item">
</el-dialog> <i class="el-icon-circle-check"></i>
</div> <span class="label">状态</span>
<el-tag :type="user.status === 1 ? 'success' : 'danger'">
{{ user.status === 1 ? "可用" : "禁用" }}
</el-tag>
</div>
</el-col>
</el-row>
<div class="action-buttons">
<el-button
type="primary"
@click="showEditDialog"
icon="el-icon-key"
>
修改密码
</el-button>
</div>
</template>
</div>
</el-card>
<el-dialog
title="修改密码"
:visible.sync="editDialogVisible"
width="40%"
@close="editDialogClosed"
center
>
<el-form
:model="editForm"
ref="editFormRef"
:rules="editFormRules"
label-width="100px"
>
<el-form-item label="新密码" prop="password">
<el-input
v-model="editForm.password"
type="password"
placeholder="请输入新密码"
show-password
></el-input>
</el-form-item>
<el-form-item label="确认密码" prop="confirmPassword">
<el-input
v-model="editForm.confirmPassword"
type="password"
placeholder="请再次输入新密码"
show-password
></el-input>
</el-form-item>
</el-form>
<span slot="footer">
<el-button @click="editDialogVisible = false"> </el-button>
<el-button type="primary" @click="changePassword"> </el-button>
</span>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
name: "Information",
data() { data() {
var validatePass2 = (rule, value, callback) => { const validatePass2 = (rule, value, callback) => {
if (value === '') { if (value === "") {
callback(new Error('请再次输入密码')); callback(new Error("请再次输入密码"));
} else if (value !== this.editForm.password) { } else if (value !== this.editForm.password) {
callback(new Error('两次输入密码不一致!')); callback(new Error("两次输入密码不一致!"));
} else { } else {
callback(); callback();
} }
}; };
return { return {
user: { user: {
ruleNumber: Number, ruleNumber: "",
cardNumber: Number, cardNumber: "",
status: Number, status: 0,
userId: Number, userId: "",
cardName: "", cardName: "",
username: "", username: "",
password: "", password: "",
@ -101,67 +122,70 @@ export default {
password: "", password: "",
confirmPassword: "", confirmPassword: "",
}, },
editFormRules:{ editFormRules: {
password:[ password: [
{required:true,message:"请输入新密码",trigger:"blur"}, { required: true, message: "请输入新密码", trigger: "blur" },
{min:6,max:15,message:"新密码长度在6-15个字符",trigger:"blur"} {
min: 6,
max: 15,
message: "长度在 6 到 15 个字符",
trigger: "blur",
},
], ],
confirmPassword:[ confirmPassword: [{ validator: validatePass2, trigger: "blur" }],
{validator:validatePass2,trigger:"blur"} },
]
},
editDialogVisible: false, editDialogVisible: false,
show:false, show: false,
loading:true loading: true,
}; };
}, },
methods: { methods: {
//,
showEditDialog() { showEditDialog() {
//
this.editDialogVisible = true; this.editDialogVisible = true;
}, },
//
editDialogClosed() { editDialogClosed() {
this.$refs.editFormRef.resetFields(); this.$refs.editFormRef.resetFields();
}, },
async getUserInformaton() { async getUserInformaton() {
// sessionStorageid try {
const userId = window.sessionStorage.getItem("userId"); const userId = window.sessionStorage.getItem("userId");
// axiosid const { data: res } = await this.$http.get(
this.loading = true; `user/get_information/${userId}`
const { data: res } = await this.$http.get( );
"user/get_information/" + userId
);
if (res.status !== 200) {
return this.$message.error(res.msg); if (res.status !== 200) {
return this.$message.error(res.msg);
}
this.user = res.data;
this.show = true;
this.$message.success({ message: res.msg, duration: 1000 });
} catch (error) {
this.$message.error("获取用户信息失败");
} finally {
this.loading = false;
} }
this.$message.success({
message: res.msg,
duration: 1000,
});
this.user = res.data;
this.show = true;
this.loading = false;
}, },
async changePassword(){ async changePassword() {
try {
const { data: res } = await this.$http.post("user/update_password", {
password: this.editForm.password,
userId: window.sessionStorage.getItem("userId"),
});
const {data:res} = await this.$http.post('user/update_password',{ if (res.status !== 200) {
password:this.editForm.password, return this.$message.error(res.msg);
userId:window.sessionStorage.getItem('userId') }
})
if(res.status !== 200){ this.$message.success(res.msg);
return this.$message.error(res.msg); this.editDialogVisible = false;
this.$refs.editFormRef.resetFields();
window.sessionStorage.clear();
this.$router.push("/login");
} catch (error) {
this.$message.error("修改密码失败");
} }
this.$message.success(res.msg) },
this.editDialogVisible = false;
this.$refs.editFormRef.resetFields();
window.sessionStorage.clear();
this.$router.push("/login");
}
}, },
created() { created() {
this.getUserInformaton(); this.getUserInformaton();
@ -170,62 +194,123 @@ export default {
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.information_container { .information-container {
height: 100vh;
padding: 20px;
box-sizing: border-box;
position: relative; position: relative;
height: 100%; background: #f0f2f5;
}
.backgroundImg { .background-wrapper {
position: absolute; position: fixed;
width: 100%; top: 0;
height: 100%; left: 0;
img {
width: 100%; width: 100%;
height: 100%; height: 100%;
opacity: 0.3; z-index: 0;
img {
width: 100%;
height: 100%;
object-fit: cover;
opacity: 0.3;
}
}
.info-card {
position: relative;
z-index: 1;
max-width: 800px;
margin: 40px auto;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
background: rgba(255, 255, 255, 0.95);
.info-header {
text-align: center;
padding: 20px 0;
border-bottom: 1px solid #eee;
h2 {
font-size: 28px;
color: #303133;
margin-bottom: 10px;
}
.motto {
color: #606266;
font-size: 16px;
i {
margin-right: 5px;
color: #409eff;
}
}
}
.info-content {
padding: 30px;
.info-item {
margin-bottom: 20px;
padding: 15px;
background: #f8f9fa;
border-radius: 6px;
transition: all 0.3s;
&:hover {
transform: translateX(5px);
background: #f0f7ff;
}
i {
color: #409eff;
margin-right: 10px;
font-size: 18px;
}
.label {
color: #606266;
margin-right: 10px;
font-weight: 500;
}
.value {
color: #303133;
}
}
.action-buttons {
text-align: center;
margin-top: 30px;
.el-button {
padding: 12px 30px;
font-size: 16px;
}
}
}
} }
} }
.information_header {
height: 200px; //
// background-color: pink; @media screen and (max-width: 768px) {
text-align: center; .information-container {
p:nth-child(1) { padding: 10px;
line-height: 140px;
color: black; .info-card {
font-size: 36px; margin: 20px auto;
.info-header {
h2 {
font-size: 24px;
}
}
.info-content {
padding: 15px;
}
}
} }
p:nth-child(2) {
color: black;
font-size: 24px;
}
}
.information_banner {
display: flex;
flex-direction: row;
height: 400px;
// background-color: pink;
.information_banner_left {
flex: 0.5;
// background-color: brown;
text-align: center;
}
.information_banner_right {
flex: 0.5;
// background-color: skyblue;
text-align: left;
line-height: 400px;
}
}
.banner_left_main {
margin-top: 120px;
color: black;
font-size: 20px;
div {
margin-top: 15px;
}
}
.changePWD {
position: absolute;
top: 50%;
left: 50%;
} }
</style> </style>

View File

@ -1,98 +1,185 @@
<template> <template>
<div class="notice_container"> <div class="notice-container">
<div class="header"> <el-card class="notice-card">
<div class="scroll-text" ref="scrollText"> <!-- 顶部滚动通知 -->
<i class="el-icon-s-opportunity"></i> {{ text }} <div class="notice-header">
<i class="el-icon-s-opportunity"></i> <div class="scroll-text" ref="scrollText">
</div> <i class="el-icon-bell"></i>
</div> <span>{{ text }}</span>
<div class="banner"> <i class="el-icon-bell"></i>
<div class="banner_header"><p>近期公告</p></div>
<div class="banner_main"
v-loading="loading"
element-loading-text="拼命加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.8)">
<div class="banner_main_item" v-for="item in noticeList" :key="item.noticeId">
<div class="banner_main_item_header"> <p> {{ item.noticeTitle }} {{ item.createTime }}</p></div>
<div class="banner_main_item_main">
<p>{{ item.noticeContent }}</p>
</div>
</div> </div>
</div> </div>
</div>
<!-- 公告列表 -->
<div class="notice-content">
<div class="section-title">
<i class="el-icon-message"></i>
<span>近期公告</span>
</div>
<el-timeline v-loading="loading">
<el-timeline-item
v-for="item in noticeList"
:key="item.noticeId"
:timestamp="item.createTime"
placement="top"
:type="getTimelineItemType(item.noticeId)"
>
<el-card class="notice-item">
<div class="notice-item-title">
<i class="el-icon-document"></i>
<span>{{ item.noticeTitle }}</span>
</div>
<div class="notice-item-content">
{{ item.noticeContent }}
</div>
</el-card>
</el-timeline-item>
</el-timeline>
</div>
</el-card>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
name: "Notice",
data() { data() {
return { return {
text: "图书馆公告栏,记得查收公告呀!小项目请勿恶意攻击,谢谢", text: "欢迎访问图书馆公告栏,请及时查看最新公告!",
noticeList:[ noticeList: [],
{ loading: true,
noticeId:0,
noticeAdminId:Number,
noticeTitle:"",
noticeContent:"",
createTime:"",
updateTime:""
}
],
loading:true
}; };
}, },
methods: { methods: {
async getRuleList(){ async getRuleList() {
this.loading = true; try {
const {data:res} = await this.$http.get('user/get_noticelist') const { data: res } = await this.$http.get("user/get_noticelist");
if(res.status!== 200){ if (res.status !== 200) {
return this.$message.error(res.msg);
}
this.noticeList = res.data;
this.$message.success({
message: res.msg,
duration: 1000,
});
} catch (error) {
this.$message.error("获取公告列表失败");
} finally {
this.loading = false; this.loading = false;
return this.$message.error(res.msg)
} }
this.$message.success({ },
message:res.msg, getTimelineItemType(id) {
duration:1000 const types = ["primary", "success", "warning", "danger"];
}) return types[id % types.length];
this.noticeList = res.data; },
this.loading = false; initScrollText() {
} const containerWidth = this.$refs.scrollText.offsetWidth;
const textWidth = this.$refs.scrollText.scrollWidth;
if (textWidth > containerWidth) {
this.$refs.scrollText.style.animation = "scroll 15s linear infinite";
}
},
}, },
mounted() { mounted() {
const containerWidth = this.$refs.scrollText.offsetWidth; this.$nextTick(() => {
const textWidth = this.$refs.scrollText.scrollWidth; this.initScrollText();
});
// If the text is longer than the container, start the animation
if (textWidth > containerWidth) {
this.$refs.scrollText.style.animation = "scroll 10s linear infinite";
}
}, },
created(){ created() {
this.getRuleList(); this.getRuleList();
} },
}; };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.notice_container { .notice-container {
overflow: hidden; padding: 20px;
} min-height: calc(100vh - 120px);
.header { background: #f5f7fa;
width: 100%;
height: 50px; .notice-card {
background-color: rgb(70, 130, 180); border-radius: 8px;
border-radius: 15px; box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
// box-shadow: 0px 0px 5px 5px rgb(66, 142, 5); }
color: white;
text-align: center; .notice-header {
line-height: 50px; background: linear-gradient(135deg, #1890ff 0%, #36cfc9 100%);
font-size: 24px; padding: 15px;
} border-radius: 8px;
.scroll-text { margin-bottom: 30px;
white-space: nowrap;
animation: scroll 10s linear infinite; .scroll-text {
color: white;
font-size: 18px;
display: flex;
align-items: center;
justify-content: center;
white-space: nowrap;
overflow: hidden;
i {
margin: 0 10px;
font-size: 20px;
}
}
}
.section-title {
display: flex;
align-items: center;
margin-bottom: 30px;
padding-bottom: 15px;
border-bottom: 2px solid #f0f2f5;
i {
font-size: 24px;
color: #1890ff;
margin-right: 10px;
}
span {
font-size: 20px;
font-weight: 600;
color: #303133;
}
}
.notice-item {
margin-bottom: 20px;
transition: all 0.3s;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.notice-item-title {
display: flex;
align-items: center;
margin-bottom: 10px;
padding-bottom: 10px;
border-bottom: 1px solid #ebeef5;
i {
color: #1890ff;
margin-right: 8px;
}
span {
font-size: 16px;
font-weight: 500;
color: #303133;
}
}
.notice-item-content {
color: #606266;
line-height: 1.6;
font-size: 14px;
padding: 10px 0;
}
}
} }
@keyframes scroll { @keyframes scroll {
@ -103,71 +190,27 @@ export default {
transform: translateX(-100%); transform: translateX(-100%);
} }
} }
.banner {
width: 100%;
height: 100%;
// background-color: pink;
margin-top:30px;
}
.banner_header {
width: 100%;
height: 80px;
// background-color: brown;
p {
color:black;
font-size: 30px;
text-align: center;
line-height: 80px;
}
}
.banner_main{
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
color:skyblue;
} //
@media screen and (max-width: 768px) {
.notice-container {
padding: 10px;
.banner_main_item:nth-child(n+2) { .notice-header {
margin-top: 30px; padding: 10px;
}
.banner_main_item:nth-child(n+2){
background-color: #D1EEEE;
}
.banner_main_item:nth-child(1){
background-color: pink;
}
.banner_main_item { .scroll-text {
width: 80%; font-size: 16px;
height: 120px; }
// background-color: aqua;
.banner_main_item_header {
width: 100%;
height: 50px;
// background-color: pink;
border:1px solid skyblue;
box-sizing: border-box;
p {
color:rgb(175, 129, 143);
text-align: center;
line-height: 50px;
font-size: 16px;
} }
}
.banner_main_item_main{ .section-title {
width: 100%; margin-bottom: 20px;
height: 70px;
background-color: white; span {
border:1px solid skyblue; font-size: 18px;
box-sizing: border-box; }
text-align: center;
p {
line-height: 70px;
} }
} }
} }
</style> </style>

View File

@ -1,114 +1,183 @@
<template> <template>
<div class="rule_container"> <div class="rule-container">
<div class="header"> <el-card class="rule-card">
<p>读者规则信息查看</p> <div slot="header" class="header">
</div> <i class="el-icon-reading"></i>
<div class="banner"> <span>读者规则信息查看</span>
<el-tooltip </div>
v-for="item in ruleList"
v-loading="loading" <el-row
element-loading-text="拼命加载中" :gutter="20"
element-loading-spinner="el-icon-loading" v-loading="loading"
element-loading-background="rgba(0, 0, 0, 0.8)" element-loading-text="加载中..."
:key="item.ruleId" element-loading-spinner="el-icon-loading"
effect="dark" element-loading-background="rgba(0, 0, 0, 0.7)"
placement="right"
> >
<div slot="content" class="content_tip">可借阅数量: {{ item.bookLimitNumber }}<br/>可借阅天数: {{ item.bookDays }} <el-col :span="12" v-for="(item, index) in ruleList" :key="item.ruleId">
<br/>可借阅图书馆: {{ item.bookLimitLibrary }}<br/>过期扣费/: {{ item.bookOverdueFee }}</div> <el-card
<el-button style="font-size:16px">借阅证规则编号: {{ item.bookRuleId }}</el-button> class="rule-item"
</el-tooltip> :class="{ 'rule-item-odd': index % 2 === 0 }"
>
</div> <div class="rule-title">
<i class="el-icon-document"></i>
<span>借阅证规则 #{{ item.bookRuleId }}</span>
</div>
<div class="rule-content">
<el-descriptions :column="1" border>
<el-descriptions-item label="可借阅数量">
<el-tag size="medium">{{ item.bookLimitNumber }} </el-tag>
</el-descriptions-item>
<el-descriptions-item label="可借阅天数">
<el-tag size="medium" type="success"
>{{ item.bookDays }} </el-tag
>
</el-descriptions-item>
<el-descriptions-item label="可借阅图书馆">
<el-tag size="medium" type="warning">{{
item.bookLimitLibrary
}}</el-tag>
</el-descriptions-item>
<el-descriptions-item label="过期扣费/天">
<el-tag size="medium" type="danger"
>{{ item.bookOverdueFee }}</el-tag
>
</el-descriptions-item>
</el-descriptions>
</div>
</el-card>
</el-col>
</el-row>
</el-card>
</div> </div>
</template> </template>
<script> <script>
import { Loading } from 'element-ui';
export default { export default {
data(){ name: "Rule",
data() {
return { return {
ruleList:[ ruleList: [],
{ loading: true,
ruleId:0, };
bookRuleId:Number, },
bookDays:Number, methods: {
bookLimitNumber:Number, async getRuleList() {
bookOverdueFee:Number, try {
bookLimitLibrary:"", const { data: res } = await this.$http.get("user/get_rulelist");
createTime:"", if (res.status !== 200) {
updateTime:"", return this.$message.error(res.msg);
} }
this.ruleList = res.data;
], this.$message.success({
loading:true message: res.msg,
} duration: 1000,
}, });
methods:{ } catch (error) {
async getRuleList(){ this.$message.error("获取规则列表失败");
const {data:res} = await this.$http.get("user/get_rulelist") } finally {
if(res.status !== 200){
this.loading = false; this.loading = false;
return this.$message.error(res.msg);
} }
this.$message.success({ },
message:res.msg, },
duration:1000 created() {
}) this.getRuleList();
this.loading = false;
this.ruleList = res.data
}
}, },
created(){
this.getRuleList()
}
}; };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.rule_container { .rule-container {
position: relative; padding: 20px;
}
.header { .rule-card {
position: absolute; background: #f5f7fa;
left: 50%; border: none;
transform: translate(-50%); border-radius: 8px;
p {
font-size: 36px; .header {
color: rgb(70, 130, 180); display: flex;
align-items: center;
font-size: 24px;
color: #303133;
margin-bottom: 20px;
i {
margin-right: 10px;
font-size: 28px;
color: #409eff;
}
}
}
.rule-item {
margin-bottom: 20px;
border-radius: 8px;
transition: all 0.3s;
&:hover {
transform: translateY(-5px);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
}
&.rule-item-odd {
background: linear-gradient(135deg, #e6f3ff 0%, #ffffff 100%);
}
.rule-title {
font-size: 18px;
font-weight: 600;
margin-bottom: 20px;
color: #303133;
display: flex;
align-items: center;
i {
color: #409eff;
margin-right: 8px;
}
}
.rule-content {
/deep/ .el-descriptions {
.el-descriptions-item__label {
width: 120px;
color: #606266;
background: #f5f7fa;
}
.el-descriptions-item__content {
padding: 12px 15px;
}
.el-tag {
font-size: 14px;
padding: 0 12px;
height: 28px;
line-height: 26px;
}
}
}
} }
} }
.banner {
display: flex;
flex-direction: column;
position:absolute;
left:50%;
transform: translate(-50%);
//
@media screen and (max-width: 768px) {
.rule-container {
padding: 10px;
.rule-card {
.header {
font-size: 20px;
}
}
.rule-item {
margin-bottom: 15px;
.rule-title {
font-size: 16px;
}
}
}
} }
.el-tooltip{ </style>
width: 500px;
font-size: 16px;
color:white;
}
.el-tooltip:hover{
color:black;
}
.el-tooltip:nth-child(1){
margin-top:100px;
}
.el-tooltip:nth-child(n+2){
margin-top:50px;
margin-left:0px;
}
.el-tooltip:nth-child(odd){
background-color: pink;
}
.el-tooltip:nth-child(even){
background-color: rgb(49, 176, 213)
}
.content_tip {
font-size: 16px;
}
</style>