天马学航——智慧教务系统(移动端)开发日志四
日志摘要:优化了教师端界面的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.day
if(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.ip
STA(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 {
@Override
protected 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);
//Mybatis
SqlSession 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();
}
@Override
protected 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 = resp
if(resp.length === 0){
promptAction.showToast({
message: "您已上传完所有成绩~",
duration: 2000,
bottom: 50
});
}
})
}
}
请求源码
请求课程
class GetCourse {
baseURL: string = IP.ip
GT(): 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.ip
STA(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 {
@Override
protected 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);
//Mybatis
SqlSession 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();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3、BUG修复
修复了一些已知的BUG
4、UI优化
优化教师端图标和界面布局,使得更加人性化