个人介绍
hello hello~ ,这里是 code袁~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹
🦁作者简介:一名喜欢分享和记录学习的在校大学生
💥个人主页:code袁
💥 个人QQ:2647996100
🐯 个人wechat:code8896
专栏导航
code袁系列专栏导航
1.毕业设计与课程设计:本专栏分享一些毕业设计的源码以及项目成果。🥰🥰🥰
2.微信小程序开发:本专栏从基础到入门的一系开发流程,并且分享了自己在开发中遇到的一系列问题。🤹🤹🤹
3.vue开发系列全程线路:本专栏分享自己的vue的学习历程。非常期待和您一起在这个小小的互联网世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨
1、前言介绍
图书馆预约小程序是一款方便学生和读者预约图书馆资源的便捷工具。随着数字化时代的到来,传统的图书馆预约方式已经无法满足人们的需求,因此开发了这款小程序,旨在提供更高效、便捷的图书馆资源预约服务。
通过图书馆预约小程序,用户可以轻松浏览图书馆的资源信息,包括图书、期刊、报纸等各类文献资料。用户可以根据自己的需求和兴趣,在小程序中查找并选择想要借阅或预约的图书馆资源。同时,小程序还提供了实时的资源可用性信息,帮助用户更好地安排自己的阅读计划。
除了资源浏览和预约功能,图书馆预约小程序还具有个人化推荐功能,根据用户的借阅历史和兴趣偏好,为用户推荐相关的图书馆资源,提升用户体验。此外,小程序还提供了预约管理功能,用户可以查看自己的预约记录、借阅历史等信息,方便管理自己的阅读计划。
总的来说,图书馆预约小程序为用户提供了一个便捷、高效的图书馆资源预约平台,帮助用户更好地利用图书馆资源,丰富自己的阅读生活。无论是学生还是社会读者,都可以通过这款小程序轻松预约所需的图书馆资源,享受阅读的乐趣。
2、开发技术简介
本节介绍场馆预约平台用到的一些技术和开发环境的简介,用到开发技术主要包括:
(1)前端用到Element UI组件库、Vue框架和微信小程序
(2)后端用到Node
(3)包管理器Npm
(4)中间件Express
(5)数据库MySQL
系统开发环境主要是:前端开发工具Vscode,Hbuilder、操作系统Win10、CPU i5-9300H、内存8G。
3、系统功能图
图书馆预约小程序提供了多项便捷的系统功能,以满足用户对图书馆资源的预约和管理需求。主要功能包括:
- 资源浏览:用户可以浏览图书馆的各类资源信息,包括图书、期刊、报纸等,了解资源的详细信息和可用性情况。
预约功能:用户可以通过小程序预约自己感兴趣的图书馆资源,选择借阅时间和地点,方便快捷。
个性化推荐:根据用户的借阅历史和兴趣偏好,系统会智能推荐相关的图书馆资源,提升用户体验。
预约管理:用户可以查看自己的预约记录、借阅历史等信息,方便管理自己的阅读计划。
消息通知:系统会及时向用户发送预约成功、借阅到期等消息通知,提醒用户注意借阅情况。
通过这些功能,用户可以方便地预约和管理图书馆资源,提升阅读效率和体验。4、功能实现
系统登录功能是程序必不可少的功能,在登录页面必填的数据有两项,一项就是账号,另一项数据就是密码,当管理员正确填写并提交这二者数据之后,管理员就可以进入系统后台功能操作区。下图就是管理员登录页面。
5、库表设计
程序设计是离不开对应数据库的设计操作的,这样的做法就是减少数据对程序的依赖性,所以数据库的设计也是需要花费大量的日常时间来进行设计的,在设计中对程序开发需要存储的数据信息进行实体划分,先确认实体,然后设计实体的属性等操作,这种设计就是数据库设计里面不能少的必须有的E-R模型设计。为了降低程序设计的对应的数据库设计难度,开发人员也可以使用相应的工具来进行E-R模型设计,现在市面上设计E-R模型的工具有PowerDesigner建模工具,Navicat制作工具,还有微软的Visio绘图工具。为了简便起见,本程序在设计E-R模型的时候,就选用了微软的Visio这款功能强大,操作便利的绘图工具。
1.预约实体及其附属图
2.管理员实体及其附属图
6、性能测试
性能测试是软件测试的一种重要形式,旨在评估系统在特定条件下的性能表现。通过模拟用户负载、并发访问等场景,性能测试可以帮助确定系统的稳定性、吞吐量、响应时间等关键性能指标,以确保系统在实际使用中能够正常运行并满足用户需求。
性能测试通常包括负载测试、压力测试、稳定性测试等不同类型,每种类型测试着重于评估系统在不同条件下的性能表现。测试样例可以是模拟多用户同时访问系统的情况,观察系统在高负载下的响应时间和资源利用情况。以下是一个简单的性能测试样例:
```java
1.from base.data_read import ReadData
2.from base.response import method_post
3.import pytest
4.# ====测试数据读取====
5.def data_read():
6. # 1. 将yaml文件读取
7. data_dict = ReadData('data.yaml').read_data()
8. # 2. 从字典中取数据 url accounts
9. url = data_dict['test_user_login']['url']
10. accounts = data_dict['test_user_login']['accounts']
11. # 3. 返回数据 供测试用例调用
12. return url, accounts
13.
14.
15.class TestLogin():
16. @pytest.mark.parametrize('url', [data_read()[0]])
17. @pytest.mark.parametrize('accounts', data_read()[1])
18. def test_login(self, url, accounts):
19. # 1. 注意这里的account是列表格式
20. print('\n>>>', type(accounts))
21. print(accounts)
22. # 2. 发请求
23. response = method_post(url, json=accounts)
24. # 3. 判断是否请求成功
25. assert response.status_code == 200
26. # 4. 根据返回的code判断是否登录成功
27. code = response.json().get('code')
28. print(response.json())
29. assert code == 0, '登录失败!'
30.# =============测试结果==============
31.========= 1 failed, 1 passed in 11.81s ==========
7、关键代码
<template>
<div>
<el-row>
<el-col :span="6">
<el-card style="height: 150px; margin: 10px; color: #67c23a">
<div>
<i class="el-icon-user-solid" style="margin-right: 10px"></i
>用户总数
</div>
<div style="margin: 30px 0; text-align: center; font-weight: bold">
{
{
tableData.length }}
</div>
</el-card>
</el-col>
<el-col :span="6">
<el-card style="height: 150px; margin: 10px; color: #e6a23c">
<div>
<i class="el-icon-menu" style="margin-right: 10px"></i
>可预约座位总数
</div>
<div style="margin: 30px 0; text-align: center; font-weight: bold">
{
{
labList.length }}
</div>
</el-card>
</el-col>
<el-col :span="6">
<el-card style="height: 150px; margin: 10px; color: #409eff">
<div>
<i class="el-icon-s-platform" style="margin-right: 10px"></i
>区域总数
</div>
<div style="margin: 30px 0; text-align: center; font-weight: bold">
{
{
facilityList.length }}
</div>
</el-card>
</el-col>
<el-col :span="6">
<el-card style="height: 150px; margin: 10px; color: #f56c6c">
<div>
<i class="el-icon-s-comment" style="margin-right: 10px"></i>取消预约
</div>
<div style="margin: 30px 0; text-align: center; font-weight: bold">
{
{
delectList.length }}
</div>
</el-card>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-card style="margin: 10px 10px; height: 400px">
<div
class="echarts2"
style="height: 350px; width: 500rpx"
ref="echarts2"
></div>
</el-card>
</el-col>
<el-col :span="12">
<el-card style="margin: 10px 10px; height: 400px">
<div
class="echarts1"
style="height: 350px; width: 500rpx"
ref="echarts1"
></div>
</el-card>
</el-col>
</el-row>
<router-view></router-view>
</div>
</template>
<script>
import {
getAllReservation, getCancel } from "@/api/reservation";
import {
allReservationTable } from "@/api/reservation";
import * as echarts from "echarts";
import {
getUser } from "@/api/user";
import {
getPlace, getSteat } from "@/api/index";
// import { getfk } from "@/api/sign";
const moment = require("moment");
export default {
data() {
return {
day: "",
tableData: [],
numList: [],
labList: [],
facilityList: [],
delectList: [],
tableName: {
username: "用户名",
phone: "手机号",
department: "院系",
},
};
},
components: {
},
computed: {
tableData() {
return this.tableData.slice(0, 3);
},
},
methods: {
},
mounted() {
//或群登录时间
let day = new Date();
this.day = `${
day.getFullYear()}-${
day.getMonth() + 1}-${
day.getDate()}`;
// 代用封装的接口
getUser().then((res) => {
this.tableData = res.data.data.data;
});
getPlace().then((res) => {
this.facilityList = res.data.data.data;
});
getSteat().then((res) => {
let data = res.data.data.data;
let labList = [];
for (let i = 0; i < data.length; i++) {
if (data[i].status == 0) {
labList.push(data[i]);
}
}
this.labList = labList;
});
getAllReservation().then((res) => {
console.log(res.data.data.data);
let data = res.data.data.data;
// 使用reduce方法计算同一category的个数并添加到新的数组对象中
const resultArray = data.reduce((acc, curr) => {
const found = acc.find((item) => item.name === curr.placeName);
if (found) {
found.value++;
} else {
acc.push({
name: curr.placeName, value: 1 });
}
return acc;
}, []);
console.log(resultArray);
var echarts1 = echarts.init(this.$refs.echarts1);
var option = {
title: {
text: "图书馆预约概述",
subtext: "数据统计",
left: "center",
},
tooltip: {
trigger: "item",
},
legend: {
orient: "vertical",
left: "left",
},
series: [
{
name: "统计数据",
type: "pie",
radius: "50%",
data: resultArray,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: "rgba(0, 0, 0, 0.5)",
},
},
},
],
};
echarts1.setOption(option);
// 原始数组对象
});
//获取用户数据
getCancel().then((res) => {
let data = res.data.data.data;
this.delectList = data;
const resultArray = data.reduce((acc, curr) => {
acc.find((item) => item.name === curr.reason);
acc.push(curr.reason);
return acc;
}, []);
var newArr = resultArray.filter(function (item, index) {
return resultArray.indexOf(item) === index; // 因为indexOf 只能查找到第一个
});
console.log(newArr);
const resultArray1 = data.reduce((acc1, curr) => {
const found = acc1.find((item) => item.name === curr.reason);
if (found) {
found.value++;
} else {
acc1.push({
name: curr.reason, value: 1 });
}
return acc1;
}, []);
console.log(resultArray1);
let yData = [];
for (let i = 0; i < resultArray1.length; i++) {
let data = resultArray1[i].value;
yData.push(data);
}
var echarts2 = echarts.init(this.$refs.echarts2);
var option = {
title: {
text: "图书馆预约取消",
subtext: "数据统计",
left: "center",
},
xAxis: {
type: "category",
data: newArr,
},
yAxis: {
type: "value",
},
series: [
{
data: yData,
type: "line",
},
{
data: yData,
type: "bar",
},
],
};
echarts2.setOption(option);
});
},
};
</script>
<style lang="less">
.user {
display: flex;
align-items: center;
padding-bottom: 20px;
margin-bottom: 20px;
border-bottom: 1px solid #ccc;
img {
margin-right: 40px;
width: 150px;
height: 150px;
border-radius: 50%;
}
.userinfo {
p {
font-size: 32px;
}
}
}
.user-login {
p {
line-height: 28px;
font-size: 14px;
color: #999;
span {
color: #666;
margin-left: 60px;
}
}
}
.graph {
display: flex;
justify-content: space-between;
margin-top: 10px;
.el-card {
width: 48%;
}
}
</style>
<!--pages/index/index.wxml-->
<view class="banner">
<swiper class="swip_main" indicator-dots="true" autoplay='true' interval="3000" circular='true'>
<block wx:for="{
{mglist}}">
<swiper-item>
<image style="width: 100%;height: 100%;" mode="aspectFill" src="{
{item.imgUrl}}"></image>
</swiper-item>
</block>
</swiper>
</view>
<view class="body_yy">
<view class="body_yy_zz">自助约定</view>
<view class="body_yy_ms">安心学习,给你一个舒服的学习环境</view>
<button class="body_yy_bt" bindtap="my_yy">预定</button>
</view>
<view class="news-bar">
<view class="newa-bar-title">
图书馆公约
</view>
<view class="news-bar-box" wx:for="{
{msgList}}" wx:for-item="item" wx:key="_id" bindtap="sjowbs" id="{
{item.id}}" wx:if="{
{index<10}}">
<view class="news-box-img">
<image src="{
{item.imgUrl}}"></image>
</view>
<view class="news-box-text">
<view class="news-box-text-title">
{
{
item.title}}
</view>
<rich-text class="concent" nodes="{
{item.concent}}"></rich-text>
<view class="news-bar-box-time">
{
{
item.uploadTime}}
</view>
</view>
</view>
</view>
8、源码获取
大家点赞、收藏、关注、评论啦 、查看👇🏻获取联系方式👇🏻
🎉写在最后
🍻伙伴们,如果你已经看到了这里,觉得这篇文章有帮助到你的话不妨点赞👍或 Star ✨支持一下哦!手动码字,如有错误,欢迎在评论区指正💬~
你的支持就是我更新的最大动力💪~