本文没有全部代码,需要全部代码可私信我
设计题目:图书馆管理系统的设计
研究内容及要求:
研究内容:
(1)书籍信息录入
图书管理员录入书籍的书号、名称,修改录入的出错(维护),形成图书表。
(2)读者信息录入
系统管理员录入读者的个人信息,修改录入的出错(维护),形成读者表。
(3)借阅情况的录入
图书管理员在读者借阅图书时录入信息,修改录入的出错(维护),形成借阅表和历史借阅表。
(4)计算扣款金额
图书管理员按读者借书时间、还书时间和借阅时长判断读者是否需要扣费,然后生成信息到历史借阅表中。
(5)读者、图书管理员及图书信息的查询
读者可以根据自己的读者号查询自己的个人信息;图书管理员可以根据自己的管理员号查询自己的个人信息(包括工资);所有人都可以登录之后无条件查询图书的信息包括馆藏册数。
目 录
一、需求分析 …………………………………………………………………………1
1、任务概述 …………………………………………………………………………1
2、需求功能介绍….......................................................................................… 2
二、数据库设计 …………………………………………………………………… 5
1、数据库设计与实现……………………………………………………………… 5
(1)数据库设计……….........................................................………………… 5
①绘制E-R图 ……………………………………………………………………6
②写出关系模式 …………………………………………………………………6
(2)数据库、数据表的创建 ………………………………………………..……6
- 系统详细设计 …………………………………………………………………11
(1)登录界面 ……………………………………………………………………11
①程序代码 ………………………………………………………………………11
②运行结果(系统测试)…………………………………………...….……… 12
(2)系统主界面 ……………………………………………………..…………12
①程序代码……...…………………………………………...............….………12
②运行结果(系统测试) ……………………………………………..……… 22
(3)用户借阅信息模块快设计........................……………………...............23
①运行代码 ...............…………...............…………...............………..…......23
②运行结果(系统测试)...............…………...…………................…………27
(4)用户个人修改信息模块设计........................….….…………….............28
①运行代码................….……….....….....................................….…………..28
②运行结果(系统测试)........................….………………..........................30
- 权限分配模块设计...….………………........….………………........…..31
①PermissionServiceImpl权限认证实现类配置…….......……................…31
②securityconfig配置........................….……..…………...........................30
- 小结……………………………………………………………….…………35
- 参考文献………………………………………....……………….…………35
一、需求分析
1、任务概述
自从人类步入到信息时代,创造的信息就爆炸式的增长,而图书馆作为这些信息的集散地,需要不断的更新新出现的图书信息,图书的流通情况。但是图书馆的管理人员是有限的,在计算机尚未在图书管理系统广泛使用之前,管理人员仅仅基于文本和表格的纸质方式去记录图书信息和流通信息已经不能适应快速增长的图书数量,另一方面,人工的统计方式并不能保证数据的正确性,有时会非常容易出现错误。出错的时候,还得一本本的查阅纸质文档,这显得非常的耗费人力财力和物力,效果也不明显,因此仅仅依靠手工操作方式在今天已经不能适应信息量庞大的图书馆了。
2、需求功能介绍
二、数据库设计
1、数据库设计与实现
(1)数据库的设计
① E-R图
② 关系模式
(1)图书:编号、名称、价格、上架时间、借阅人编号、借阅时间、状态
(2)用户:编号、名称、状态。
(3)借阅记录:编号、图书编号、借阅人编号、借阅时间、归还时间。
(2)数据库、数据表的创建
① CREATE DATABASE library;
② CREATE TABLE `user` (
`user_id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`user_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户账号',
`nick_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_bg_0900_ai_ci NOT NULL COMMENT '用户昵称',
`email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '用户邮箱',
`phone_number` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '手机号码',
`avatar` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '头像地址',
`password` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '密码',
`status` tinyint(1) unsigned zerofill DEFAULT '0' COMMENT '帐号状态(1正常 0停用)',
`login_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '最后登录IP',
`login_date` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后登录时间',
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注',
`credit` bigint DEFAULT NULL COMMENT '余额',
`sex` tinyint(1) unsigned zerofill DEFAULT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
③ CREATE TABLE `user_role` (
`user_id` bigint NOT NULL,
`role_id` bigint NOT NULL,
PRIMARY KEY (`user_id`,`role_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
④ CREATE TABLE `book` (
`book_id` bigint NOT NULL AUTO_INCREMENT,
`book_name` varchar(255) NOT NULL,
`order_num` int DEFAULT NULL,
`parent_id` bigint DEFAULT NULL,
`status` tinyint(1) DEFAULT '0' COMMENT '部门状态(1正常 0停用)',
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`press` varchar(255) DEFAULT NULL COMMENT '出版社',
`price` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '价格',
`remark` varchar(255) DEFAULT NULL COMMENT '简介',
`stock` int DEFAULT NULL COMMENT '库存',
PRIMARY KEY (`book_id`)
) ENGINE=InnoDB AUTO_INCREMENT=114 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
⑤`borrow` (
`borrow_id` int NOT NULL AUTO_INCREMENT,
`borrow_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '',
`borrow_time` datetime DEFAULT CURRENT_TIMESTAMP,
`status` int DEFAULT NULL,
`book_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '',
`book_price` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '',
`book_press` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '',
`restore_time` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '归还日期',
PRIMARY KEY (`borrow_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
⑥`menu` (
`menu_id` bigint NOT NULL AUTO_INCREMENT COMMENT '菜单ID',
`menu_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '菜单名称',
`parent_id` bigint DEFAULT '0' COMMENT '父菜单ID',
`order_num` int DEFAULT '0' COMMENT '显示顺序',
`path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '路由地址',
`menu_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '菜单类型(M目录 C菜单 F按钮)',
`status` tinyint(1) DEFAULT '0' COMMENT '菜单状态(1正常 0停用)',
`perms` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '权限标识',
`icon` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '#' COMMENT '菜单图标',
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '备注',
PRIMARY KEY (`menu_id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
⑦`role` (
`role_id` bigint NOT NULL AUTO_INCREMENT COMMENT '角色ID',
`role_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色名称',
`role_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色权限字符串',
`role_sort` int NOT NULL COMMENT '显示顺序',
`status` tinyint NOT NULL COMMENT '角色状态(1正常 0停用)',
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
⑧CREATE TABLE `role_menu` (
`role_id` bigint NOT NULL,
`menu_id` bigint NOT NULL,
PRIMARY KEY (`role_id`,`menu_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
2、系统详细设计
(1)登录界面
① 程序代码
<template>
<div class="login">
<h1>登录</h1>
<el-form :inline="true">
<el-form-item label="账号" class="overall" prop="username">
<el-input v-model="loginForm.username" placeholder="账号" @keydown.enter="submitUser()" clearable
prefix-icon="User" class="leng" />
</el-form-item>
<el-form-item label="密码" prop="password" class="overall" @keydown.enter="submitUser()">
<el-input v-model="loginForm.password" type="password" autocomplete="off" prefix-icon="lock" placeholder="密码"
class="leng" />
</el-form-item>
<el-form-item label="验证码" class="overall" @keydown.enter="submitUser()" style="margin-left: -45px;">
<el-input placeholder="验证码" v-model="sidentifyMode" clearable style="width: 130px; margin-top: -17px;"
prefix-icon="SuccessFilled" />
<div class="code" @click="refreshCode">
<sidentify :identifyCode="identifyCode"></sidentify>
</div>
</el-form-item>
<el-checkbox v-model="loginForm.rememberMe" name="rememberMe"
style="margin: -11px 0px 20px 8px">记住密码</el-checkbox>
<el-button type="primary" class="btn" @click="loading()" :loading="loginForm.loading">
<span v-if="!loginForm.loading">登 录</span>
<span v-else>登 录 中...</span>
</el-button>
</el-form>
</div>
</template>
② 运行结果(系统测试)
(2)系统主界面
① 程序代码
书籍管理界面:
<template>
<el-form :inline="true">
<el-form-item label="书籍名称 ">
<el-input v-model="searchBook[0].bookName" placeholder="请输入书籍名称" @input="searchByName()" clearable
style="width: 200px; margin-right: 40px;" />
</el-form-item>
<el-form-item label="出版社名称 ">
<el-input v-model="searchBook[0].press" placeholder="请输入出版社名称" @input="searchByPress()" clearable
style="width: 200px; margin-right: 40px;" />
</el-form-item>
<el-form-item label="状态:">
<el-select-v2 v-model="searchBook[0].status" :options="options" @change="searchByStatus()" placeholder="部门状态"
style="width: 200px; vertical-align: middle" clearable />
</el-form-item>
<el-button type="primary" style="margin: -20px 20px 0 50px;" @click="search()"><el-icon>
<Search />
</el-icon>搜索</el-button>
<el-button plain style="margin: -20px 20px 0 50px;" @click="reset()"><el-icon>
<Refresh />
</el-icon>重置</el-button>
</el-form>
<!-- 信息打印 -->
<el-table ref="In" :data="bookData" row-key="bookName" style="width: 100%; margin-top: 20px;" default-expand-all
:header-cell-style="{ background: '#F0F0F1', color: 'gray', fontweight: 400 }" empty-text="暂无数据">
<el-table-column prop="bookName" label="书籍名称" width="250" />
<el-table-column prop="press" label="出版社" width="200" align="center" />
<el-table-column prop="orderNum" label="排序" width="100" align="center" />
<el-table-column prop="price" label="价格" width="100" align="center" />
<el-table-column prop="stock" label="库存" width="100" align="center" />
<el-table-column prop="status" label="状态" width="100" align="center">
<template v-slot="scope" v-model="scope.row.status">
<el-button type='primary' plain bg v-if="scope.row.status == 1" size="small">正常</el-button>
<el-button type='danger' plain bg v-if="scope.row.status == 0" size="small">停用</el-button>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间" align="center" width="200" />
<el-table-column label="操作" width="200" align="center">
<template v-slot="scope" v-model="scope.row.bookName">
<el-link type="primary" :underline="false" @click="changeBook(scope.row)"
style="margin: 2px; font-size: 12px;"><el-icon>
<EditPen />
</el-icon>修改</el-link>
<el-link type="primary" :underline="false" style="margin: 2px; font-size: 12px;" v-if="scope.row.price != null"
@click="addBook(scope.row)"><el-icon>
<Plus />
</el-icon>新增</el-link>
<el-link type="primary" :underline="false" style="margin: 2px; font-size: 12px;"
@click="delBook(scope.row)"><el-icon>
<Delete />
</el-icon>删除</el-link>
<el-link type="primary" :underline="false" style="margin: 2px; font-size: 12px;" v-if="scope.row.price != null"
@click="borrow(scope.row)"><el-icon>
<Memo />
</el-icon>借阅</el-link>
</template>
</el-table-column>
</el-table>
<el-dialog v-model="open" :title="title" width="25%" center :close-on-click-modal="false">
<el-form ref="formRef" :model="bookList[0]" :rules="rules" label-width="100px" :size="formSize" status-icon>
<el-form-item label="类别" prop="parentId">
<el-tree-select v-model="bookList[0].parentId" ref="formRef" :load="loadNode"
:props="{ value: 'bookId', label: 'bookName' }" value-key="bookId" node-key="bookId"
:placeholder="bookList[0].bookName" check-strictly highlight-current :data="bookData" />
</el-form-item>
<el-form-item label="书籍名称" prop="bookName">
<el-input v-model="bookList[0].bookName" placeholder="请输入书籍名称" />
</el-form-item>
<el-form-item label="显示顺序" prop="orderNum">
<el-input-number v-model="bookList[0].orderNum" :min="1" :max="100" controls-position="right" size="large" />
</el-form-item>
<el-col :span="24" v-if="bookList[0].price != null">
<el-form-item label="价格" prop="price">
<el-input v-model="bookList[0].price" placeholder="请输入价格" />
</el-form-item>
<el-form-item label="出版社" prop="press">
<el-input v-model="bookList[0].press" placeholder="请输入出版社" />
</el-form-item>
<el-form-item label="库存" prop="stock">
<el-input v-model="bookList[0].stock" placeholder="请输入库存" />
</el-form-item>
</el-col>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="bookList[0].status" style="margin-top: -4px;">
<el-radio :label=1 size="large">正常</el-radio>
<el-radio :label=0 size="large">停用</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="open = false">取消</el-button>
<el-button type="primary" @click="submitData()">确认</el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="delOpen" :title="title" width="25%" center :close-on-click-modal="false">
<h3>您确定{{ title }}" {{ bookList[0].bookName }} "书籍吗?</h3>
<template #footer>
<span class="dialog-footer">
<el-button @click="delOpen = false">取消</el-button>
<el-button type="primary" @click="submitDelData()">确认</el-button>
</span>
</template>
</el-dialog>
</template>
用户界面:
<template>
<el-form :inline="true">
<el-form-item label="用户名称 ">
<el-input v-model="searchUser[0].userName" placeholder="请输入用户名称" @input="searchByName()" clearable
style="width: 200px; margin-right: 40px;" />
</el-form-item>
<el-form-item label="状态:">
<el-select-v2 v-model="searchUser[0].status" :options="options" placeholder="用户状态" @change="searchByStatus()"
style="width: 180px; vertical-align: middle" clearable />
</el-form-item>
<el-button type="primary" style="margin: -20px 20px 0 50px;" @click="search()"><el-icon>
<Search />
</el-icon>搜索</el-button>
<el-button plain style="margin: -20px 20px 0 50px;" @click="reset()"><el-icon>
<Refresh />
</el-icon>重置</el-button>
</el-form>
<el-button type="primary" style="margin-right: 10px;" @click="addUser()" plain><el-icon>
<Plus />
</el-icon>增加</el-button>
<el-button type="success" :disabled="disabled" plain @click="changeUserButton()" style="margin-right: 10px;"><el-icon>
<EditPen />
</el-icon>修改</el-button>
<el-button type="danger" :disabled="del" plain @click="DelUserButton()" style="margin-right: 10px;"><el-icon>
<Delete />
</el-icon>删除</el-button>
<el-table ref="In" :data="userData" style="width: 100%; margin-top: 20px;" @selection-change="handleSelectionChange"
:header-cell-style="{ background: '#F0F0F1', color: 'gray', fontweight: 400 }" empty-text="暂无数据">
<el-table-column type="selection" width="55" />
<el-table-column prop="userName" label="用户名称" align="center" width="100" />
<el-table-column prop="nickName" label="用户昵称" align="center" :show-overflow-tooltip="true" width="150" />
<el-table-column prop="phoneNumber" label="手机号码" align="center" :show-overflow-tooltip="true" width="150" />
<el-table-column prop="email" label="邮箱" align="center" :show-overflow-tooltip="true" width="150" />
<el-table-column prop="credit" label="余额" align="center" :show-overflow-tooltip="true" width="150" />
<el-table-column prop="status" label="状态" width="100" align="center">
<template v-slot="scope" v-model="scope.row.status">
<el-button type='primary' plain bg v-if="scope.row.status == 1" size="small">正常</el-button>
<el-button type='danger' plain bg v-if="scope.row.status == 0" size="small">停用</el-button>
</template>
</el-table-column>
<el-table-column prop="createTime" label="注册时间" align="center" width="200" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template v-slot="scope">
<el-link type="primary" :underline="false" style="margin: 2px; font-size: 12px;"
@click="changeUser(scope.row)"><el-icon>
<EditPen />
</el-icon>修改</el-link>
<el-link type="primary" :underline="false" style="margin: 2px; font-size: 12px;"
@click="delUser(scope.row)"><el-icon>
<Delete />
</el-icon>删除</el-link>
</template>
</el-table-column>
</el-table>
<el-pagination :current-page="searchData.current" :page-size="searchData.limit" :total="total"
style="text-align: center; margin-top: 20px; float: right; margin-right: 30px;"
layout="jumper, prev, pager, next, total" @current-change="getData" />
<el-dialog v-model="open" :title="title" width="25%" center :close-on-click-modal="false">
<el-form ref="formRef" :model="userList[0]" label-width="100px" :size="formSize" status-icon>
<el-form-item label="用户名称" prop="userName">
<el-input v-model="userList[0].userName" placeholder="请输入用户名称" />
</el-form-item>
<el-form-item label="用户昵称" prop="nickName">
<el-input v-model="userList[0].nickName" placeholder="请输入用户昵称" />
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="userList[0].email" placeholder="请输入邮箱" />
</el-form-item>
<el-form-item label="电话号码" prop="phoneNumber">
<el-input v-model="userList[0].phoneNumber" placeholder="请输入电话号码" />
</el-form-item>
<el-form-item label="余额" prop="credit">
<el-input v-model="userList[0].credit" placeholder="请输入余额" />
</el-form-item>
<el-col :span="24" v-if="userList[0].userId == ''">
<el-form-item label="用户密码" prop="password">
<el-input v-model="userList[0].password" type="password" placeholder="请输入密码" />
</el-form-item>
</el-col>
<el-form-item label="性别" prop="sex">
<el-select-v2 v-model="userList[0].sex" style="width: 200px" :options="optionSex" placeholder="用户性别"
clearable />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="userList[0].status" style="margin-top: -4px;">
<el-radio :label=1 size="large">正常</el-radio>
<el-radio :label=0 size="large">停用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="角色" prop="roleId">
<el-select v-model="RoleList[0].roleId" multiple placeholder="请选择角色">
<template v-for="item in roleData">
<el-option :label="item.roleName" :value="item.roleId" />
</template>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="open = false">取消</el-button>
<el-button type="primary" @click="submitData()">确认</el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="delOpen" :title="title" width="25%" center :close-on-click-modal="false">
<h3>您确定{{ title }}" <span v-for="item in userList">"{{ item.userName }}" </span> "用户吗?</h3>
<template #footer>
<span class="dialog-footer">
<el-button @click="delOpen = false">取消</el-button>
<el-button type="primary" @click="submitDelData()">确认</el-button>
</span>
</template>
</el-dialog>
</template>
个人主页页面:
<template>
<div class="box">
<div class="left_box">
<el-col :span="6" :xs="24">
<h2 class="title">个人信息</h2>
<el-upload action="/api/tjc/files/upload" :on-success="successUpload" style="width:315px; margin-left:10px">
<el-avatar v-bind:src="'/api/tjc/files/' + user[0].avatar" class="img_" />
</el-upload>
<ul class="left_ul">
<li>
<el-icon>
<User />
</el-icon> 用户名称
<span class="user">{{ user[0].userName }}</span>
</li>
<li>
<el-icon>
<Iphone />
</el-icon>手机号码
<span class="user">{{ user[0].phoneNumber }}</span>
</li>
<li>
<el-icon>
<Message />
</el-icon>用户邮箱
<span class="user">{{ user[0].email }}</span>
</li>
<li>
<el-icon>
<Avatar />
</el-icon>所属角色
<span class="user">
<template v-for="item in roleGroup">
{{ item.roleName }}
</template>
</span>
</li>
<li>
<el-icon>
<Finished />
</el-icon>创建时间
<span class="user">{{ user[0].createTime }}</span>
</li>
</ul>
</el-col>
</div>
<div class="right_box">
<el-card>
<div slot="header" class="clearfix">
<span style="font-size: 18px;">基本资料</span>
</div>
<el-tabs v-model="activeTab">
<el-tab-pane label="基本资料" name="userinfo">
<el-form ref="formIn" :model="form" label-width="80px">
<el-form-item label="用户昵称" prop="nickName">
<el-input v-model="form.nickName" maxlength="30" />
</el-form-item>
<el-form-item label="手机号码" prop="phonenumber">
<el-input v-model="form.phoneNumber" maxlength="11" />
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" maxlength="50" />
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="form.sex">
<el-radio label="1">男</el-radio>
<el-radio label="0">女</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submit()">保存</el-button>
<el-button type="danger" @click="close()">关闭</el-button>
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane label="修改密码" name="resetPwd">
<el-form ref="formIn" :model="userPass" :rules="rulesPass" label-width="80px">
<el-form-item label="旧密码" prop="oldPassword">
<el-input v-model="userPass.oldPassword" placeholder="请输入旧密码" type="password" show-password />
</el-form-item>
<el-form-item label="新密码" prop="newPassword">
<el-input v-model="userPass.newPassword" placeholder="请输入新密码" type="password" show-password />
</el-form-item>
<el-form-item label="确认密码" prop="confirmPassword">
<el-input v-model="userPass.confirmPassword" placeholder="请确认新密码" type="password" show-password />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitPass()">保存</el-button>
<el-button type="danger" @click="close()">关闭</el-button>
</el-form-item>
</el-form>
</el-tab-pane>
</el-tabs>
</el-card>
</div>
</div>
</template>
② 运行结果(系统测试)
(3)用户借阅信息模块快设计
① 程序代码
<template>
<el-form :inline="true">
<el-form-item label="书籍名称 ">
<el-input v-model="searchBook[0].bookName" placeholder="请输入书籍名称" @input="searchByName()" clearable
style="width: 200px; margin-right: 40px;" />
</el-form-item>
<el-form-item label="出版社名称 ">
<el-input v-model="searchBook[0].press" placeholder="请输入出版社名称" @input="searchByPress()" clearable
style="width: 200px; margin-right: 40px;" />
</el-form-item>
<el-button type="primary" style="margin: -20px 20px 0 50px;" @click="search()"><el-icon>
<Search />
</el-icon>搜索</el-button>
<el-button plain style="margin: -20px 20px 0 50px;" @click="reset()"><el-icon>
<Refresh />
</el-icon>重置</el-button>
</el-form>
<el-button @click="restoreButton()" :disabled="disabled" type="primary" style="margin-right: 10px;" plain><el-icon>
<Select />
</el-icon>归还</el-button>
<el-button type="success" :disabled="disabled" @click="renewalButton()" plain style="margin-right: 10px;"><el-icon>
<EditPen />
</el-icon>续借</el-button>
<el-table ref="In" :data="BorrowData" style="width: 100%; margin-top: 20px;" @selection-change="handleSelectionChange"
:header-cell-style="{ background: '#F0F0F1', color: 'gray', fontweight: 400 }" empty-text="暂无数据">
<el-table-column type="selection" width="55" />
<el-table-column type="index" label="借阅编号" align="center" width="100" />
<el-table-column prop="bookName" label="书籍名称" align="center" :show-overflow-tooltip="true" width="150" />
<el-table-column prop="borrowName" label="借阅人" align="center" :show-overflow-tooltip="true" width="100" />
<el-table-column prop="bookPress" label="出版社" align="center" :show-overflow-tooltip="true" width="100" />
<el-table-column prop="bookPrice" label="价格" align="center" :show-overflow-tooltip="true" width="150" />
<el-table-column prop="status" label="是否归还" width="100" align="center">
<template v-slot="scope" v-model="scope.row.status">
<el-button type='primary' plain bg v-if="scope.row.status == 0" size="small">是</el-button>
<el-button type='danger' plain bg v-if="scope.row.status == 1" size="small">否</el-button>
</template>
</el-table-column>
<el-table-column prop="borrowTime" label="借阅时间" align="center" width="180" />
<el-table-column prop="restoreTime" label="截止时间" align="center" width="180" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template v-slot="scope">
<el-link type="primary" :underline="false" style="margin: 2px; font-size: 12px;"
@click="restore(scope.row)"><el-icon>
<EditPen />
</el-icon>归还</el-link>
<el-link type="primary" :underline="false" style="margin: 2px; font-size: 12px;"
@click="renewal(scope.row)"><el-icon>
<Delete />
</el-icon>续期</el-link>
</template>
</el-table-column>
</el-table>
<el-pagination :current-page="searchData.current" :page-size="searchData.limit" :total="total"
style="text-align: center; margin-top: 20px; float: right; margin-right: 30px;"
layout="jumper, prev, pager, next, total" @current-change="getData" />
<el-dialog v-model="open" :title="title" width="25%" center :close-on-click-modal="false">
<h3>您确定{{ title }}" {{ bookList[0].bookName }} "书籍吗?</h3>
<template #footer>
<span class="dialog-footer">
<el-button @click="open = false">取消</el-button>
<el-button type="primary" @click="submitData()">确认</el-button>
</span>
</template>
</el-dialog>
</template>
查询:
public interface BookMapper extends BaseMapper<Book> {
default List<Book> data() {
List<Book> ft=selectList(null);
return ft;
}
default List<Book> searchByName(String bookName) {
QueryWrapper<Book> wrapper = new QueryWrapper<>();
wrapper.like("book_name",bookName);
List<Book> ft = selectList(wrapper);
return ft;
}
default List<Book> searchByPress(String press) {
QueryWrapper<Book> wrapper = new QueryWrapper<>();
wrapper.like("press",press);
List<Book> ft = selectList(wrapper);
return ft;
}
default List<Book> searchByStatus(int status) {
QueryWrapper<Book> wrapper = new QueryWrapper<>();
wrapper.like("status",status);
List<Book> ft = selectList(wrapper);
return ft;
}
default List<Book> search(String bookName,String press,int status) {
HashMap<String,Object> map=new HashMap<>();
map.put("book_name",bookName);
map.put("press",press);
map.put("status",status);
List<Book> ft=selectByMap(map);
return ft;
}
default List<Book> searchById(int bookId) {
HashMap<String,Object> map=new HashMap<>();
map.put("book_id",bookId);
List<Book> ft=selectByMap(map);
return ft;
}
}
② 运行结果(系统测试)
(4)用户个人修改信息模块设计
- 程序代码:
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Autowired
private UserMapper userMapper;
@Autowired
private RoleMenuMapper roleMenuMapper;
@Autowired
private UserRoleMapper userRoleMapper;
@Autowired
private MenuMapper menuMapper;
@Override
public List<User> data() {
return userMapper.data();
}
@Override
public int add(User user) {
String encode = new BCryptPasswordEncoder().encode(user.getPassword());
user.setPassword(encode);
return userMapper.insert(user);
}
@Override
public int change(User user) {
UpdateWrapper<User> wrapper = new UpdateWrapper<User>();
wrapper.eq("user_id",user.getUserId());
return userMapper.update(user, wrapper);
}
@Override
public int changePass(User user) {
String encode = new BCryptPasswordEncoder().encode(user.getPassword());
user.setPassword(encode);
UpdateWrapper<User> wrapper = new UpdateWrapper<User>();
wrapper.eq("user_id",user.getUserId());
return userMapper.update(user, wrapper);
}
@Override
public List<User> searchByStatus(int status) {
return userMapper.searchByStatus(status);
}
@Override
public List<User> search(String userName, int status) {
return userMapper.search(userName,status);
}
@Override
public List<User> searchById(long userId) {
return userMapper.searchByUserId(userId);
}
@Override
public int del(long userId) {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("user_id", userId);
return userMapper.delete(wrapper);
}
@Override
public List<User> searchByName(String userName) {
return userMapper.searchByName(userName);
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_name",username);
User user = userMapper.selectOne(queryWrapper);
//先根据用户id查询用户角色id
HashMap<String,Object> map = new HashMap<>();
map.put("user_id",user.getUserId());
List<UserRole> userRoleList = userRoleMapper.selectByMap(map);
long roleId = userRoleList.get(0).getRoleId();
//根据用户角色id查询菜单id
HashMap<String,Object> map1 = new HashMap<>();
map1.put("role_id",roleId);
List<RoleMenu> roleMenus = roleMenuMapper.selectByMap(map1);
List<Long> menuList = new ArrayList<>();
//提取菜单id
for (RoleMenu roleMenu : roleMenus) {
menuList.add(roleMenu.getMenuId());
}
//根据菜单id获取菜单信息
QueryWrapper<Menu> queryWrapper1 = new QueryWrapper<>();
queryWrapper1.in("menu_id",menuList);
List<Menu> menus = menuMapper.selectList(queryWrapper1);
//提取菜单权限
Set<String> perms = new HashSet<>();
for (Menu menu : menus) {
if(StringUtils.isNoneEmpty(menu.getPerms())) {
perms.add(menu.getPerms());
}
}
LoginUser loginUser = new LoginUser(user.getUserId(),user.getNickName(),user.getUserName(),user.getPassword(),user.getStatus(), AuthorityUtils.createAuthorityList(perms));
return loginUser;
}
}
②运行结果(系统测试)
(5)权限分配模块设计
①PermissionServiceImpl权限认证实现类配置
@Service("ss")
public class PermissionServiceImpl {
/**
* 验证用户是否具备某权限
*
* @param permission 权限字符串
* @return 用户是否具备某权限
*/
public boolean hasPermi(String permission)
{
SecurityContext context = SecurityContextHolder.getContext();
if (permission.isEmpty())
{
return false;
}
Collection<? extends GrantedAuthority> authorities = context.getAuthentication().getAuthorities();
for (GrantedAuthority authority : authorities) {
if(authority.toString().equals(permission)) {
return true;
}
}
return false;
}
}
②securityconfig配置
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(authorizeHttpRequests ->
authorizeHttpRequests
.requestMatchers("/tjc/login").permitAll() //:具有所有权限,就可以匿名访问
.anyRequest().authenticated() //任何请求都需要登录
);
http.exceptionHandling(e->e.accessDeniedHandler(new AccessDeniedHandler() {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("异常"+accessDeniedException.getMessage());
}
}));
http.formLogin(formLogin ->
formLogin
.loginProcessingUrl("/tjc/login") //指定登录接口
.successHandler(new LoginSuccessHandler())
.failureHandler(new LoginFailHandler())
);
// //session禁用配置
http.sessionManagement(e->e.maximumSessions(1).sessionRegistry(sessionRegistry()));
//权限配置
http.exceptionHandling(e -> e.accessDeniedHandler(new CustomAccessDeniedHandler()));
//跨域漏洞防御:关闭
http.csrf(csrf -> csrf.disable());
//跨域拦截关闭
http.cors(cors ->cors.disable());
return http.build();
}
/**
* 密码加密验证
* @return
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/**
* 获取当前所有以及登录的用户
* @return
*/
@Bean
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
}
三、小结
图书馆管理系统的学习是对我近期的学习成果的综合考验,说实话对我来说确实是很困难,各种第一次都迎面而来,第一次使用输出输入流,第一次使用对一个程序修改这么多次,第一次对一个程序的修改这么长时间,但历经的千辛万苦换来了最终还是换来了甘甜的成果.
掌握了一些框架的使用,使开发过程变得事半功倍,以及对代码格式的规范,项目结构的条理化,方便后期维护,对于一个完整的程序来说,现在的还差着不少东西,比如对于登录的实现,实现其封装性,防止一个用户对两个账号进行操作,再者还应该用上多态和继承,是程序更加简练和灵活,这些都是自己之后需要去做的,通过这次的学习,自己对于的程序的实现过程有了进一步的了解,懂得了考虑问题要周全,要时时刻刻的联系实际,从现实生活出发去完善软件,只有这样我们的软件才能有真真正正的意义.