图书订阅管理系统——管理员管理用户
1.这是界面设计(可能有亿点丑,重在这个过程)

2.图片1
当用户点击用户管理时,将进入该页面,灵活使用less、以及阿里图标库,在路由层级上,这一页与4个模块作为同级,继承主页面的footer,

3.图片2
用户信息页,我通过竖向列表的形式进行展示,这是页面设计依旧是flex属性的灵活运用,组件逻辑如下:
练习这么些组件下来,已经养成了习惯:组件临时存储需要创建状态,这个组件比较简单,输入用户名,点击搜索,和数据库进行交互拿到数据返回,前端一接到数据就改变临时状态userInfo,交互统一的形式在上一节管理员管理书籍那里说过,再顺一次:
前端发送一个ajax请求(axios二次封装的)-----后端服务器通过监听端口,截取信息,通过后端注册的路由进行匹配-----调用后端XX服务的接口函数,处理数据并返回-----前端采用同步实现异步的形式 async。。。await与try。。。catch搭配,轻松获取后端返回数据,这就是大致的前后端数据处理过程。
import React, { useState } from 'react'
import IconToFirstPage from '../../../../components/IconToFirstPage'
import './style.less'
import { Input } from 'antd';
import { reqSearchUser } from '../../../../api/index-ajax';
const { Search } = Input;
export default function UserInfo() {
const [userInfo, setUserInfo] = useState([]);
const onSearch = async (value) => {
console.log(value);
try {
const response = await reqSearchUser({ value: value });
console.log(response)
setUserInfo(response.data.userInfo)
} catch (error) {
console.log("请求错误", error)
}
}
return (
<div>
<div className="userInfoHead">
<IconToFirstPage />
<div className="userInfoTitle"><span>用户信息</span></div>
</div>
<div className="manageUsersBody">
<div className='search-wrapper'>
<div className="search">
<Search
placeholder="请输入用户名,点击搜索"
onSearch={onSearch}
style={{
width: 250,
}}
/>
</div>
</div>
</div>
<div className="userInfoWrapper">
<div className='userInfoListTitle'>
<div className="title"><span>类别</span></div>
<div className="data"><span>数据</span></div>
</div>
{
userInfo.length !== 0 ? userInfo.map((userInfoObj) => {
return (
<div key={userInfoObj._id}>
<div className="username">
<div className="title"><span>姓名</span></div>
<div className="data"><span>{userInfoObj.username}</span></div>
</div>
<div className="password">
<div className="title"><span>密码</span></div>
<div className="data"><span>{userInfoObj.password}</span></div>
</div>
<div className="jobNum">
<div className="title"><span>学工号</span></div>
<div className="data"><span>{userInfoObj.jobnum}</span></div>
</div>
<div className="identify">
<div className="title"><span>身份</span></div>
<div className="data"><span>{userInfoObj.identify}</span></div>
</div>
<div className="phone">
<div className="title"><span>联系方式</span></div>
<div className="data"><span>{userInfoObj.phone}</span></div>
</div>
<div className="email">
<div className="title"><span>电子邮件</span></div>
<div className="data"><span>{userInfoObj.email}</span></div>
</div>
</div>
)
}):<div>暂时无数据</div>
}
</div>
</div>
)
}
4、图片3
申请列表页,主要是展示用户还在申请中的项目,需要完成用户订阅才能做,目下已经全部做完才总结这里的。它的业务逻辑是,把后端数据库里存储的用户订阅状态还在申请中订阅申请拿出来,放在前端,并进行拒绝或者同意操作。
本页,由于这些数据只是一个页面使用,并且需要不停刷新,我并没有进行本地缓存,节省本地也就是客户端localStorage资源(这个单词之前有拼错的莫介意哈)这一页的组件实现逻辑等同于3个图片2:点击按钮——发送请求(reqXXXXX)——后端处理——返回数据(ersponse)
import React, { useState } from 'react'
import IconToFirstPage from '../../../../components/IconToFirstPage'
import './style.less'
import { Button } from 'antd'
import { reqagreeSub, reqGetApplyList, reqrejectSub } from '../../../../api/index-ajax';
export default function ApplyList() {
const [applyList, setapplyList] = useState([]);
const toShift = async () => {
let username = document.getElementsByClassName("username1")[0];
if(username.value==='') alert("您尚未填写您想查询的用户名,直接刷新将返回所有数据")
try {
const response = await reqGetApplyList({ value: username.value });
console.log(response)
setapplyList(response.data.data)
} catch (error) {
console.log("请求错误", error)
}
}
console.log(JSON.parse(localStorage.getItem('userInfo')).username)
const rejectSub = async(oneApply)=>{
const response = await reqrejectSub({applyPerson:oneApply.applyPerson,applyBook:oneApply.applyBook,optionPerson:JSON.parse(localStorage.getItem('userInfo')).username});
console.log(response)
alert(response.data.msg);
}
const agreeSub = async(oneApply)=>{
const response = await reqagreeSub({applyPerson:oneApply.applyPerson,applyBook:oneApply.applyBook,optionPerson:JSON.parse(localStorage.getItem('userInfo')).username});
console.log(response)
alert(response.data.msg);
}
return (
<div>
<div className="applyListHeader">
<IconToFirstPage />
<div className="applyListTitle">
<span>申请列表</span>
</div>
</div>
<div className="applyListBody">
<div className="title-data">
<div className="applyListBodyTitle">
<div className="applyPerson"><span>申请人</span></div>
<div className="applyBook"><span>申请书籍</span></div>
<div className="applyBookTime"><span>申请时间</span></div>
<div className="subStartTime"><span>订阅开始</span></div>
<div className="subEndTime"><span>订阅结束</span></div>
<div className="option"><span>操作</span></div>
</div>
<div className="applyListwrapper">
{
applyList.length !== 0 ? applyList.map((oneApply) => {
return (
<div className="applyListData" key={oneApply._id}>
<div className="applyPerson"><span>{oneApply.applyPerson}</span></div>
<div className="applyBook"><span>{oneApply.applyBook}</span></div>
<div className="applyBookTime"><span>{oneApply.applyBookTime}</span></div>
<div className="subStartTime"><span>{oneApply.subStartTime}</span></div>
<div className="subEndTime"><span>{oneApply.subEndTime}</span></div>
<div className="option"><Button type="primary" htmlType="submit" onClick={()=>agreeSub(oneApply)}>同意</Button><Button type="primary" htmlType="submit" onClick={()=>rejectSub(oneApply)}>拒绝</Button></div>
</div>
)
}) : <div>暂无数据</div>
}
</div>
</div>
</div>
<div className="shift">
<input type="text" className='username1' placeholder='用户名: ' />
<Button type="primary" htmlType="submit" onClick={() => toShift()}>
刷新
</Button>
</div>
</div>
)
}
5.图片4
订阅流水,管理员可以返回所有的订阅记录,也可以用户名筛选。不做本地缓存,管理员刷新,就会将数据显示。实现逻辑依旧和上面一样。
总结一下:
1.页面设计上的不足,我是一个人做,所以设计如此,这个是可以后天跟上的,进了公司,做的多了,自然就广阔了,主要是组件的灵活穿梭和信息传递;个人觉得本地localStorage应该慎用,存储一些即时性的数据、就算是缓存清理了,数据库里也能拿的数据,根据需要,有时候能减少访问数据库的频率,能提高性能。
2.这一节主要是点击按钮——发送请求(reqXXXXX)——后端处理——返回数据(ersponse),没有过复杂的逻辑。

浙公网安备 33010602011771号