天马学航——智慧教务系统(移动端)开发日志四
日志摘要:优化了教师端界面的UI,更新了教师端添加课程,提交成绩等功能,修复了一些已知的BUG
1、教师添加课程设计
教师在此界面添加课程,并将数据提交后端进行审核
界面效果
前端源码
@Entry
@Component
struct AddCourse {selectedDate: Date = new Date("2010-1-1")@State time:string = '请选择时间'@State cid:string = '-111'@State cname:string = '-111'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(" ")Column({space:30}){Text("申请发布课程").fontSize(30).fontWeight(FontWeight.Bolder).fontSize(30)Row({space:20}){Text("课程号 ").fontSize(15)TextInput().width('70%').height(50).type(InputType.Normal).onChange(value=>{this.cid = value})}.width('100%')Row({space:20}){Text("课程名称").fontSize(15)TextInput().width('70%').height(50).type(InputType.Normal).onChange(value=>{this.cname = value})}.width('100%')Row({space:20}){Text("上课时间").fontSize(15)Button("选择时间").width(100).margin(20).onClick(() => {DatePickerDialog.show({start: new Date("2023-1-1"), // 设置选择器的起始日期end: new Date("2055-12-31"), // 设置选择器的结束日期selected: this.selectedDate, // 设置当前选中的日期lunar: false,onAccept: (value: DatePickerResult) => { // 点击弹窗中的“确定”按钮时触发该回调// 通过Date的setFullYear方法设置按下确定按钮时的日期,这样当弹窗再次弹出时显示选中的是上一次确定的日期this.selectedDate.setFullYear(value.year, value.month, value.day)console.info("DatePickerDialog:onAccept()" + JSON.stringify(value))this.time=value.year+"-"+(value.month+1)+"-"+ value.dayif(value.month+1>0&&value.month+1<10){this.time=value.year+"-0"+(value.month+1)+"-"+ value.day}if(value.day>0&&value.day<10){this.time=value.year+"-"+(value.month+1)+"-0"+ value.day}if((value.month+1>0&&value.month+1<10)&&(value.day>0&&value.day<10)){this.time=value.year+"-0"+(value.month+1)+"-0"+ value.day}},onCancel: () => { // 点击弹窗中的“取消”按钮时触发该回调console.info("DatePickerDialog:onCancel()")},onChange: (value: DatePickerResult) => { // 滑动弹窗中的滑动选择器使当前选中项改变时触发该回调console.info("DatePickerDialog:onChange()" + JSON.stringify(value))}})})Text(this.time).fontSize(15)}.width('100%')Column({space:20}){Text("*注意:请确认信息后再提交,否则可能导致审核不通过!").fontSize(15).fontColor(Color.Red)Button("提交申请").width(200).onClick(()=>{if(this.time === "请选择时间" || this.cid === '-111' || this.cname === '-111'){promptAction.showToast({message: "请完成表单的填写",duration: 2000,bottom: 50});}else {AddCourses.STA(this.cid,this.cname,this.time).then(resp=>{console.log("后端返回"+resp)promptAction.showToast({message: resp,duration: 2000,bottom: 50});})}})}}.width('80%')}}
}
请求源码
class AddCourses {baseURL: string = IP.ipSTA(cid: string, cname: string, ctime: string): Promise<string> {const data = {cid: cid,cname: cname,ctime: ctime}return new Promise((resolve, reject) => {let httpRequest = http.createHttp()httpRequest.request(`${this.baseURL}/InsertCourse`,{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("请求失败")})})}
}const sc1 = new AddCourses()
export default sc1 as AddCourses
后端源码
public class TeacherInsertCourse extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("application/json");resp.setCharacterEncoding("UTF-8");String sid = req.getParameter("sid");String cid = req.getParameter("cid");String grade = req.getParameter("grade");System.out.println("教师提交成绩"+sid+cid+grade);//MybatisSqlSession sql = MybatisUntills.getSqlSession();CourseMapper mapper = sql.getMapper(CourseMapper.class);Map<String,Object> map = new HashMap<String, Object>();map.put("sid",sid);map.put("cid",cid);map.put("grade",grade);int i = mapper.TeacherInsertGrade(map);sql.commit();if(i==1){resp.getWriter().write("上传成功");}else {resp.getWriter().write("上传失败");}sql.close();}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}
2、教师提交成绩功能设置
前端从后端获取本教师任教的课程,并显示在前端,前端通过表单收集每门课程的评分,并向后端发送请求
前端源码
struct AddGrade {@State grades:Grade[] = []@State g:string = '000'aboutToAppear(){this.getinfo()}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:20}){ForEach(this.grades,grade=>{ListItem(){Row({space:30}){Text(" ")Column({space:10}){Text("学号:"+grade.sid)Text("姓名:"+grade.sname)Text("课程名称:"+grade.cname)Text("课程号:"+grade.cid)Row(){Text("成绩:")TextInput({placeholder:"给分有理,扣分有据"}).width(200).type(InputType.Number).onChange(value=>{this.g = value})}Button("提交").onClick(()=>{InsertGrade.STA(grade.sid,grade.cid,this.g).then(resp=>{promptAction.showToast({message: resp,duration: 2000,bottom: 50});})router.pushUrl({url:"pages/view/Teacher/AddGrade"},router.RouterMode.Single,err => {if(err){console.log("跳转失败")}})})}.width('100%').justifyContent(FlexAlign.Start).alignItems(HorizontalAlign.Start)}.width('95%').padding(20).backgroundColor(Color.White).borderRadius(15).shadow({ radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4 })}})}}}getinfo(){GetCourse.GT().then(resp=>{console.log("前端收到数据"+resp);this.grades = respif(resp.length === 0){promptAction.showToast({message: "您已上传完所有成绩~",duration: 2000,bottom: 50});}})}
}
请求源码
请求课程
class GetCourse {baseURL: string = IP.ipGT(): Promise<Grade[]> {return new Promise((resolve, reject) => {let Http = http.createHttp()Http.request(`${this.baseURL}/GetTeacherCourse`,{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(err=>{console.log("请求失败"+err)})})}
}const sc = new GetCourse()
export default sc as GetCourse
向后端返回成绩
class InsertGrade {baseURL: string = IP.ipSTA(sid: string, cid: string, grade: string): Promise<string> {const data = {cid: cid,sid: sid,grade: grade}return new Promise((resolve, reject) => {let httpRequest = http.createHttp()httpRequest.request(`${this.baseURL}/TeacherInertCourse`,{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 InsertGrade()
export default sc as InsertGrade
后端源码
请求课程部分与学生选课第一部分业务逻辑相似,这里不再赘述
这里只写出后端处理前端返回成绩的部分
public class TeacherInsertCourse extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("application/json");resp.setCharacterEncoding("UTF-8");String sid = req.getParameter("sid");String cid = req.getParameter("cid");String grade = req.getParameter("grade");System.out.println("教师提交成绩"+sid+cid+grade);//MybatisSqlSession sql = MybatisUntills.getSqlSession();CourseMapper mapper = sql.getMapper(CourseMapper.class);Map<String,Object> map = new HashMap<String, Object>();map.put("sid",sid);map.put("cid",cid);map.put("grade",grade);int i = mapper.TeacherInsertGrade(map);sql.commit();if(i==1){resp.getWriter().write("上传成功");}else {resp.getWriter().write("上传失败");}sql.close();}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}
3、BUG修复
修复了一些已知的BUG
4、UI优化
优化教师端图标和界面布局,使得更加人性化