天马学航——智慧教务系统(移动端)开发日志三
日志摘要:更新了学生选课模块、我的课程模块以及退课的功能,优化了后端数据库的缓存
1、学生选课模块
学生选课模块主要实现,学生根据需求进行选课操作,通过后端查询到所有教师的课程,展示在前端,然后根据前端进行选择,选择后发给后端,后端再进行判断,将选课信息返回前端
界面效果
![image-20240620111914879](https://img-blog.csdnimg.cn/img_convert/8cdc2679a4f620c5fb7048d5357858e3.png)
前端源码
struct SelectCourse {
@State courses:SCourse[] = []
aboutToAppear(){
this.getCourse()
}
build() {
Column({ space: 5 }) {
Text(" ")
Row({ space: 10 }) {
Text(" ")
Image($r('app.media.back'))
.width(30)
.height(30)
.onClick(function () {
//返回上一页
router.back() //直接返回
})
Text("学生选课")
.fontSize(30)
.fontWeight(FontWeight.Bolder)
}
.width('100%')
Text("----------------------------------------------")
Text(" ")
List({space:50}){
ForEach(
this.courses,
course=>{
ListItem(){
Row({space:30}){
Text(" ")
Column({space:20}){
Text(course.cname)
.fontColor(Color.Green)
.fontSize(15)
.fontWeight(FontWeight.Bolder)
.fontFamily("楷体")
Text("课程号:"+course.cid)
.fontSize(10)
.fontColor(Color.Red)
Text("任课教师:"+course.tname)
.fontSize(10)
.fontColor(Color.Green)
}
.justifyContent(FlexAlign.Start)
.alignItems(HorizontalAlign.Start)
Blank()
Button("选择")
.onClick(()=>{
console.log("学生点击了:"+course.cname)
StudentAddCourse.STA(course.cid,course.cname,course.tname)
.then(resp=>{
console.log("前端收到消息!"+resp)
promptAction.showToast({
message: resp,
duration: 2000,
bottom: 50
});
})
})
}
.width('95%')
.height(150)
//.padding(20)
.backgroundColor(Color.White)
.borderRadius(15)
.shadow({ radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4 })
}
}
)
}
.width('100%')
}
.width('100%')
}
getCourse(){
GetCourse.GC()
.then(resp=>{
console.log("请求成功"+resp)
if(resp.length === 0){
promptAction.showToast({
message: '暂无可选课程',
duration: 2000,
bottom: 50
});
}
this.courses = resp;
})
}
}
请求源码
请求所有课程部分
class GetCourse {
baseURL: string = IP.ip
GC(): Promise<SCourse[]> {
return new Promise((resolve, reject) => {
let Http = http.createHttp()
Http.request(
`${this.baseURL}/GCourse`,
{
method: http.RequestMethod.GET,
connectTimeout: 10000,
readTimeout: 10000
}
)
.then(resp=>{
if(resp.responseCode === 200){
console.log("请求成功"+resp.result)
resolve(JSON.parse(resp.result.toString()))
}
else {
console.log("请求发现异常"+resp.responseCode)
}
})
.catch(error=>{
console.log("请求失败")
})
})
}
}
const gc = new GetCourse()
export default gc as GetCourse
向后端发送选课结果部分
class StudentAddCourse{
baseURL: string = IP.ip
STA(cid:string,cname:string,cteacher:string):Promise<string>{
const data = {
cid:cid,
cname:cname,
cteacher:cteacher
}
return new Promise((resolve, reject) => {
let httpRequest = http.createHttp()
httpRequest.request(
`${this.baseURL}/StuSelectcourse`,
{
method:http.RequestMethod.GET,
extraData:data,
connectTimeout: 10000,
readTimeout:10000
},
)
.then(resp=>{
if(resp.responseCode === 200){
console.log("请求成功:"+resp.result)
resolve(resp.result.toString())
}
else {
console.log("请求失败:"+resp.responseCode)
}
})
.catch(error=>{
console.log("检查链接!")
})
})
}
}
const aa = new StudentAddCourse()
export default aa as StudentAddCourse
后端源码
请求所有课程部分
public class getCourse extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("application/json");
resp.setCharacterEncoding("UTF-8");
//Mybatis
SqlSession sql = MybatisUntills.getSqlSession();
CourseMapper mapper = sql.getMapper(CourseMapper.class);
List<SelectCourse> allCourse = mapper.getAllCourse();//执行并返回数据
for (SelectCourse selectCourse : allCourse) {
System.out.println(selectCourse.getCid()+selectCourse.getCname()+selectCourse.getTname());
}
sql.close();
//打包
Gson gson = new Gson();
String JsonData = gson.toJson(allCourse);
//发送
resp.getWriter().write(JsonData);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
接收学生选课信息部分
public class StuSelectCourse extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("application/json");
resp.setCharacterEncoding("UTF-8");
ServletContext c = getServletContext();
HttpSession session = req.getSession();
String username = (String) session.getAttribute("username");
if(username == null){
username = (String) c.getAttribute("username");
}
String cid = req.getParameter("cid");
String cname = req.getParameter("cname");
String ct = req.getParameter("cteacher");
System.out.println("课程号"+cid);
//Mybatis
SqlSession sql = MybatisUntills.getSqlSession();
CourseMapper mapper = sql.getMapper(CourseMapper.class);
Map<String,Object> map1 = new HashMap<String, Object>();
map1.put("cid",cid);
map1.put("sid",username);
String strings = mapper.showStudentCourse(map1);
if(strings!=null){
resp.getWriter().write("后端返回信息:该课程已存在!");
sql.close();
}
else {
Map<String,Object> map = new HashMap<String, Object>();
map.put("cid",cid);
map.put("sid",username);
int i = mapper.addStudentCourse(map);
sql.commit();
if(i==1){
resp.getWriter().write("后端返回信息:选课成功!");
System.out.println("成!");
}
else {
resp.getWriter().write("后端返回信息:选课失败!");
}
sql.close();
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
2、我的课程(退课模块)
主要显示该用户选择的所有课程,并提供退课的选项,后端查询,前端显示,前端选择,后端判断,将信息返回前端
界面效果
![image-20240620111914879](https://img-blog.csdnimg.cn/img_convert/8cdc2679a4f620c5fb7048d5357858e3.png)
前端源码
struct MyCourse{
@State courses:StudentMyCourse[] = []
aboutToAppear(){
this.MyCourses()
}
build() {
Column({ space: 5 }) {
Text(" ")
Row({ space: 10 }) {
Text(" ")
Image($r('app.media.back'))
.width(30)
.height(30)
.onClick(function () {
//返回上一页
router.back() //直接返回
})
Text("我的课程")
.fontSize(30)
.fontWeight(FontWeight.Bolder)
}
.width('100%')
Text("----------------------------------------------")
Text(" ")
List({space:50}){
ForEach(
this.courses,
course=>{
ListItem(){
Row({space:30}){
Text(" ")
Column({space:20}){
Text(course.cname)
.fontColor(Color.Green)
.fontSize(15)
.fontWeight(FontWeight.Bolder)
.fontFamily("楷体")
Text("课程号:"+course.cid)
.fontSize(10)
.fontColor(Color.Red)
Text("任课教师:"+course.tname)
.fontSize(10)
.fontColor(Color.Green)
Text("上课时间:"+course.ctime)
.fontSize(10)
.fontColor(Color.Green)
}
.justifyContent(FlexAlign.Start)
.alignItems(HorizontalAlign.Start)
Blank()
Button("退课")
.backgroundColor(Color.Red)
.onClick(()=>{
console.log("学生点击了:"+course.cname)
DeletCourse.STA(course.cname,course.cid,course.tname,course.ctime)
.then(resp=>{
console.log("返回成功"+resp)
promptAction.showToast({
message: resp,
duration: 2000,
bottom: 50
});
})
})
}
.width('95%')
.height(150)
//.padding(20)
.backgroundColor(Color.White)
.borderRadius(15)
.shadow({ radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4 })
}
}
)
}
.width('100%')
}
}
MyCourses(){
GetStudentCourse.GC()
.then(resp=>{
console.log("返回信息成功"+resp.toString())
if(resp.length === 0){
promptAction.showToast({
message: '您还没有选课哦~',
duration: 2000,
bottom: 50
});
}
this.courses = resp
})
}
}
请求源码
请求所选课程
class GetStudentCourse {
baseURL: string = IP.ip
GC(): Promise<StudentMyCourse[]> {
return new Promise((resolve, reject) => {
let Http = http.createHttp()
Http.request(
`${this.baseURL}/GetMyCourse`,
{
method: http.RequestMethod.GET,
connectTimeout: 10000,
readTimeout: 10000
}
)
.then(resp => {
if (resp.responseCode === 200) {
console.log("请求成功" + resp.result)
resolve(JSON.parse(resp.result.toString()))
}
else {
console.log("请求成功,但是出现问题" + resp.responseCode)
}
})
.catch(error => {
console.log("请求失败" + error)
})
})
}
}
const sc = new GetStudentCourse()
export default sc as GetStudentCourse
向后端发送退课信息
class DeletCourse {
baseURL: string = IP.ip
STA(cname: string, cid: string, tname: string,ctime: string): Promise<string> {
const data = {
cname: cname,
cid: cid,
tname: tname,
ctime:ctime
}
return new Promise((resolve, reject) => {
let httpRequest = http.createHttp()
httpRequest.request(
`${this.baseURL}/DeletMyCourse`,
{
method: http.RequestMethod.GET,
extraData: data,
connectTimeout: 10000,
readTimeout: 10000
},
)
.then(resp=>{
if(resp.responseCode===200){
console.log("请求成功!"+resp.result)
resolve(resp.result.toString())
}
else {
console.log("请求发生错误"+resp.responseCode)
}
})
.catch(err=>{
console.log("请求失败"+err)
})
})
}
}
const sc = new DeletCourse()
export default sc as DeletCourse
后端代码与选课部分相同,这里不再赘述
3、BUG修复
修复了Mybatis二级缓存溢出导致查询变慢的问题
天马学航——智慧教务系统(移动端)开发日志二
日志摘要:更新了学生选课模块、我的课程模块以及退课的功能,优化了后端数据库的缓存
1、学生选课模块
学生选课模块主要实现,学生根据需求进行选课操作,通过后端查询到所有教师的课程,展示在前端,然后根据前端进行选择,选择后发给后端,后端再进行判断,将选课信息返回前端
界面效果
![image-20240620111914879](https://img-blog.csdnimg.cn/img_convert/8cdc2679a4f620c5fb7048d5357858e3.png)
前端源码
struct SelectCourse {
@State courses:SCourse[] = []
aboutToAppear(){
this.getCourse()
}
build() {
Column({ space: 5 }) {
Text(" ")
Row({ space: 10 }) {
Text(" ")
Image($r('app.media.back'))
.width(30)
.height(30)
.onClick(function () {
//返回上一页
router.back() //直接返回
})
Text("学生选课")
.fontSize(30)
.fontWeight(FontWeight.Bolder)
}
.width('100%')
Text("----------------------------------------------")
Text(" ")
List({space:50}){
ForEach(
this.courses,
course=>{
ListItem(){
Row({space:30}){
Text(" ")
Column({space:20}){
Text(course.cname)
.fontColor(Color.Green)
.fontSize(15)
.fontWeight(FontWeight.Bolder)
.fontFamily("楷体")
Text("课程号:"+course.cid)
.fontSize(10)
.fontColor(Color.Red)
Text("任课教师:"+course.tname)
.fontSize(10)
.fontColor(Color.Green)
}
.justifyContent(FlexAlign.Start)
.alignItems(HorizontalAlign.Start)
Blank()
Button("选择")
.onClick(()=>{
console.log("学生点击了:"+course.cname)
StudentAddCourse.STA(course.cid,course.cname,course.tname)
.then(resp=>{
console.log("前端收到消息!"+resp)
promptAction.showToast({
message: resp,
duration: 2000,
bottom: 50
});
})
})
}
.width('95%')
.height(150)
//.padding(20)
.backgroundColor(Color.White)
.borderRadius(15)
.shadow({ radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4 })
}
}
)
}
.width('100%')
}
.width('100%')
}
getCourse(){
GetCourse.GC()
.then(resp=>{
console.log("请求成功"+resp)
if(resp.length === 0){
promptAction.showToast({
message: '暂无可选课程',
duration: 2000,
bottom: 50
});
}
this.courses = resp;
})
}
}
请求源码
请求所有课程部分
class GetCourse {
baseURL: string = IP.ip
GC(): Promise<SCourse[]> {
return new Promise((resolve, reject) => {
let Http = http.createHttp()
Http.request(
`${this.baseURL}/GCourse`,
{
method: http.RequestMethod.GET,
connectTimeout: 10000,
readTimeout: 10000
}
)
.then(resp=>{
if(resp.responseCode === 200){
console.log("请求成功"+resp.result)
resolve(JSON.parse(resp.result.toString()))
}
else {
console.log("请求发现异常"+resp.responseCode)
}
})
.catch(error=>{
console.log("请求失败")
})
})
}
}
const gc = new GetCourse()
export default gc as GetCourse
向后端发送选课结果部分
class StudentAddCourse{
baseURL: string = IP.ip
STA(cid:string,cname:string,cteacher:string):Promise<string>{
const data = {
cid:cid,
cname:cname,
cteacher:cteacher
}
return new Promise((resolve, reject) => {
let httpRequest = http.createHttp()
httpRequest.request(
`${this.baseURL}/StuSelectcourse`,
{
method:http.RequestMethod.GET,
extraData:data,
connectTimeout: 10000,
readTimeout:10000
},
)
.then(resp=>{
if(resp.responseCode === 200){
console.log("请求成功:"+resp.result)
resolve(resp.result.toString())
}
else {
console.log("请求失败:"+resp.responseCode)
}
})
.catch(error=>{
console.log("检查链接!")
})
})
}
}
const aa = new StudentAddCourse()
export default aa as StudentAddCourse
后端源码
请求所有课程部分
public class getCourse extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("application/json");
resp.setCharacterEncoding("UTF-8");
//Mybatis
SqlSession sql = MybatisUntills.getSqlSession();
CourseMapper mapper = sql.getMapper(CourseMapper.class);
List<SelectCourse> allCourse = mapper.getAllCourse();//执行并返回数据
for (SelectCourse selectCourse : allCourse) {
System.out.println(selectCourse.getCid()+selectCourse.getCname()+selectCourse.getTname());
}
sql.close();
//打包
Gson gson = new Gson();
String JsonData = gson.toJson(allCourse);
//发送
resp.getWriter().write(JsonData);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
接收学生选课信息部分
public class StuSelectCourse extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("application/json");
resp.setCharacterEncoding("UTF-8");
ServletContext c = getServletContext();
HttpSession session = req.getSession();
String username = (String) session.getAttribute("username");
if(username == null){
username = (String) c.getAttribute("username");
}
String cid = req.getParameter("cid");
String cname = req.getParameter("cname");
String ct = req.getParameter("cteacher");
System.out.println("课程号"+cid);
//Mybatis
SqlSession sql = MybatisUntills.getSqlSession();
CourseMapper mapper = sql.getMapper(CourseMapper.class);
Map<String,Object> map1 = new HashMap<String, Object>();
map1.put("cid",cid);
map1.put("sid",username);
String strings = mapper.showStudentCourse(map1);
if(strings!=null){
resp.getWriter().write("后端返回信息:该课程已存在!");
sql.close();
}
else {
Map<String,Object> map = new HashMap<String, Object>();
map.put("cid",cid);
map.put("sid",username);
int i = mapper.addStudentCourse(map);
sql.commit();
if(i==1){
resp.getWriter().write("后端返回信息:选课成功!");
System.out.println("成!");
}
else {
resp.getWriter().write("后端返回信息:选课失败!");
}
sql.close();
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
2、我的课程(退课模块)
主要显示该用户选择的所有课程,并提供退课的选项,后端查询,前端显示,前端选择,后端判断,将信息返回前端
界面效果
![image-20240620111914879](https://img-blog.csdnimg.cn/img_convert/8cdc2679a4f620c5fb7048d5357858e3.png)
前端源码
struct MyCourse{
@State courses:StudentMyCourse[] = []
aboutToAppear(){
this.MyCourses()
}
build() {
Column({ space: 5 }) {
Text(" ")
Row({ space: 10 }) {
Text(" ")
Image($r('app.media.back'))
.width(30)
.height(30)
.onClick(function () {
//返回上一页
router.back() //直接返回
})
Text("我的课程")
.fontSize(30)
.fontWeight(FontWeight.Bolder)
}
.width('100%')
Text("----------------------------------------------")
Text(" ")
List({space:50}){
ForEach(
this.courses,
course=>{
ListItem(){
Row({space:30}){
Text(" ")
Column({space:20}){
Text(course.cname)
.fontColor(Color.Green)
.fontSize(15)
.fontWeight(FontWeight.Bolder)
.fontFamily("楷体")
Text("课程号:"+course.cid)
.fontSize(10)
.fontColor(Color.Red)
Text("任课教师:"+course.tname)
.fontSize(10)
.fontColor(Color.Green)
Text("上课时间:"+course.ctime)
.fontSize(10)
.fontColor(Color.Green)
}
.justifyContent(FlexAlign.Start)
.alignItems(HorizontalAlign.Start)
Blank()
Button("退课")
.backgroundColor(Color.Red)
.onClick(()=>{
console.log("学生点击了:"+course.cname)
DeletCourse.STA(course.cname,course.cid,course.tname,course.ctime)
.then(resp=>{
console.log("返回成功"+resp)
promptAction.showToast({
message: resp,
duration: 2000,
bottom: 50
});
})
})
}
.width('95%')
.height(150)
//.padding(20)
.backgroundColor(Color.White)
.borderRadius(15)
.shadow({ radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4 })
}
}
)
}
.width('100%')
}
}
MyCourses(){
GetStudentCourse.GC()
.then(resp=>{
console.log("返回信息成功"+resp.toString())
if(resp.length === 0){
promptAction.showToast({
message: '您还没有选课哦~',
duration: 2000,
bottom: 50
});
}
this.courses = resp
})
}
}
请求源码
请求所选课程
class GetStudentCourse {
baseURL: string = IP.ip
GC(): Promise<StudentMyCourse[]> {
return new Promise((resolve, reject) => {
let Http = http.createHttp()
Http.request(
`${this.baseURL}/GetMyCourse`,
{
method: http.RequestMethod.GET,
connectTimeout: 10000,
readTimeout: 10000
}
)
.then(resp => {
if (resp.responseCode === 200) {
console.log("请求成功" + resp.result)
resolve(JSON.parse(resp.result.toString()))
}
else {
console.log("请求成功,但是出现问题" + resp.responseCode)
}
})
.catch(error => {
console.log("请求失败" + error)
})
})
}
}
const sc = new GetStudentCourse()
export default sc as GetStudentCourse
向后端发送退课信息
class DeletCourse {
baseURL: string = IP.ip
STA(cname: string, cid: string, tname: string,ctime: string): Promise<string> {
const data = {
cname: cname,
cid: cid,
tname: tname,
ctime:ctime
}
return new Promise((resolve, reject) => {
let httpRequest = http.createHttp()
httpRequest.request(
`${this.baseURL}/DeletMyCourse`,
{
method: http.RequestMethod.GET,
extraData: data,
connectTimeout: 10000,
readTimeout: 10000
},
)
.then(resp=>{
if(resp.responseCode===200){
console.log("请求成功!"+resp.result)
resolve(resp.result.toString())
}
else {
console.log("请求发生错误"+resp.responseCode)
}
})
.catch(err=>{
console.log("请求失败"+err)
})
})
}
}
const sc = new DeletCourse()
export default sc as DeletCourse
后端代码与选课部分相同,这里不再赘述
3、BUG修复
修复了Mybatis二级缓存溢出导致查询变慢的问题