iOS端课程管理系统代码(SQLite)

完整项目已上传至GitHub(上传的步骤好繁琐,现学的嘿嘿嘿)
https://github.com/qzj-ui/database
演示视频:https://www.bilibili.com/video/BV13K4y1b78E/
1.database文件:用于定义学生、管理员、课程、成绩表以及增删改查方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
//
//  Database.swift
//  JSP-HBU
//
//  Created by 齐子佳 on 2020/4/26.
//  Copyright ? 2020 齐子佳. All rights reserved.
//

import Foundation
import SQLite

struct Database {
    var db:Connection!
   
    struct student
    {
        var id:Int64
        var name:String
        var sex:String
        var age:Int64
        var department:String
       
        init(id:Int64,name:String,sex:String,age:Int64,department:String) {
            self.id = id
            self.name = name
            self.sex = sex
            self.age = age
            self.department = department
        }
    }
   
    struct admin {
        var id:Int64
        var name:String
        var department:String
        init(id:Int64,name:String,department:String) {
            self.id = id
            self.name = name
            self.department = department
        }
    }
   
   
    struct Course {
        var id:Int64
        var name:String
        var credit:Int64
        var pno:Int64
       
        init(id:Int64,name:String,credit:Int64,pno:Int64) {
            self.id = id
            self.name = name
            self.credit = credit
            self.pno = pno
        }
    }
   
    struct SC {
        var sno:Int64
        var cno:Int64
        var grade:Int64
       
        init(sno:Int64,cno:Int64,grade:Int64) {
            self.sno = sno
            self.cno = cno
            self.grade = grade
        }
    }
   
    init(){
        connectDatabase()
    }
    mutating func connectDatabase(filePath: String = "/Documents") -> Void {

            let sqlFilePath = NSHomeDirectory() + filePath + "/db.sqlite3"

            do { // 与数据库建立连接
                db = try Connection(sqlFilePath)
                print("与数据库建立连接 成功")
            } catch {
                print("与数据库建立连接 失败:\(error)")
            }
    }
        let TABLE_STUDENT = Table("student")
        let TABLE_STUDENT_ID = Expression<Int64>("student_id")
        let TABLE_STUDENT_PASSWORD = Expression<String>("student_pwd")
        let TABLE_STUDENT_NAME = Expression<String>("student_name")
        let TABLE_STUDENT_SEX = Expression<String>("student_sex")
        let TABLE_STUDENT_AGE = Expression<Int64>("student_age")
        let TABLE_STUDENT_DEPARTMENT = Expression<String>("student_department")
   
   
        let TABLE_ADMIN = Table("admin")
        let TABLE_ADMIN_ID = Expression<Int64>("admin_id")
        let TABLE_ADMIN_PASSWORD = Expression<String>("admin_pwd")
        let TABLE_ADMIN_NAME = Expression<String>("admin_name")
        let TABLE_ADMIN_DEPARTMENT = Expression<String>("admin_department")
   
   
        let TABLE_COURSE = Table("course")
        let TABLE_COURSE_ID = Expression<Int64>("course_id")
        let TABLE_COURSE_NAME = Expression<String>("course_name")
        let TABLE_COURSE_CERDIT = Expression<Int64>("course_credit")
        let TABLE_COURSE_PNO = Expression<Int64>("course_pno")
   
        let TABLE_SC = Table("SC")
        let TABLE_SC_Sno = Expression<Int64>("SC_Sno")
        let TABLE_SC_Cno = Expression<Int64>("SC_Cno")
        let TABLE_SC_GRADE = Expression<Int64>("SC_GRADE")

        // 建表
   
    func tableStudentCreate() -> Void{
        do{
            try db.run(TABLE_STUDENT.create{ table in
                table.column(TABLE_STUDENT_ID,primaryKey: true)
                table.column(TABLE_STUDENT_PASSWORD)
                table.column(TABLE_STUDENT_NAME)
                table.column(TABLE_STUDENT_SEX)
                table.column(TABLE_STUDENT_AGE)
                table.column(TABLE_STUDENT_DEPARTMENT)
            })
            print("创建Student表成功")
        }catch{
            print("创建Student表失败:\(error)")
        }
    }
   
    func tableAdminCreate() -> Void{
        do{
            try db.run(TABLE_ADMIN.create{ table in
                table.column(TABLE_ADMIN_ID,primaryKey: true)
                table.column(TABLE_ADMIN_PASSWORD)
                table.column(TABLE_ADMIN_NAME)
                table.column(TABLE_ADMIN_DEPARTMENT)
            })
            print("创建Admin表成功")
        }catch{
            print("创建Admin表失败:\(error)")
        }
    }
   
    func tableCourseCreate() -> Void{
        do{
            try db.run(TABLE_COURSE.create{ table in
                table.column(TABLE_COURSE_ID,primaryKey: true)
                table.column(TABLE_COURSE_NAME)
                table.column(TABLE_COURSE_PNO)
                table.column(TABLE_COURSE_CERDIT)
            })
            print("创建Course表成功")
        }catch{
            print("创建Course表失败:\(error)")
        }
    }
   
    func tableSCCreate() -> Void{
        do{
            try db.run(TABLE_SC.create{ table in
                table.column(TABLE_SC_Sno,references: TABLE_STUDENT,TABLE_STUDENT_ID)
                table.column(TABLE_SC_Cno,primaryKey: true)
                table.column(TABLE_SC_GRADE)
               
            })
            print("创建SC表成功")
        }catch{
            print("创建SC表失败:\(error)")
        }
    }
   
        // 插入
   
    func tableStudentInsertItem(id:Int64,password:String,name:String,sex:String,age:Int64,department:String) -> Void{
       
        let insert = TABLE_STUDENT.insert(TABLE_STUDENT_ID <- id,TABLE_STUDENT_PASSWORD <- password,TABLE_STUDENT_NAME <- name,TABLE_STUDENT_SEX <- sex,TABLE_STUDENT_AGE <- age,TABLE_STUDENT_DEPARTMENT <- department)
        do{
            _ = try db.run(insert)
            print("插入Student数据成功,学号为\(id)")
        }catch{
            print("插入Student数据失败,学号为\(id),\(error)")
        }
       
    }
   
    func tableAdminInsertItem(id:Int64,password:String,name:String,department:String) -> Void{
           
           let insert = TABLE_ADMIN.insert(TABLE_ADMIN_ID <- id,TABLE_ADMIN_PASSWORD <- password,TABLE_ADMIN_NAME <- name,TABLE_ADMIN_DEPARTMENT <- department)
           do{
               _ = try db.run(insert)
               print("插入Admin数据成功,工号为\(id)")
           }catch{
               print("插入Student数据失败,工号为\(id),\(error)")
           }
           
       }
   
   
    func tableCourseInsertItem(id:Int64,name:String,credit:Int64,pno:Int64) -> Bool{
        let insert = TABLE_COURSE.insert(TABLE_COURSE_ID <- id,TABLE_COURSE_NAME <- name,TABLE_COURSE_CERDIT <- credit,TABLE_COURSE_PNO <- pno)
        do{
            _ = try db.run(insert)
            print("插入Course数据成功,课程号为\(id)")
            return true
        }catch{
            print("插入Course数据失败,课程号为\(id),\(error)")
            return false
        }
    }
   
    func tableSCInsertItem(sno:Int64,cno:Int64,grade:Int64) -> Bool{
        let insert = TABLE_SC.insert(TABLE_SC_Cno <- cno,TABLE_SC_Sno <- sno,TABLE_SC_GRADE <- grade)
        do{
            _ = try db.run(insert)
            print("插入SC数据成功,学号为\(sno)")
            return true
        }catch{
            print("插入SC数据失败,学号为\(sno),\(error)")
            return false
        }
    }
   
        // 遍历
   
    func queryTableStudent() -> [student] {

       
        var studentArray = [student]()
        for item in (try! db.prepare(TABLE_STUDENT)){
            var s:student
            s = student(id: item[TABLE_STUDENT_ID], name: item[TABLE_STUDENT_NAME], sex: item[TABLE_STUDENT_SEX], age: item[TABLE_STUDENT_AGE], department: item[TABLE_STUDENT_DEPARTMENT])
            studentArray.append(s)
           
        }
        return studentArray
    }
   
    func queryTableCourse() -> [Course] {
       
        var courseArray = [Course]()
        for item in (try! db.prepare(TABLE_COURSE)){
            var c:Course
            c = Course(id: item[TABLE_COURSE_ID], name: item[TABLE_COURSE_NAME], credit: item[TABLE_COURSE_CERDIT], pno: item[TABLE_COURSE_PNO])
            courseArray.append(c)
        }
       
        return courseArray
    }
   
    func queryTableSC() -> [SC] {
        var SCArray = [SC]()
        for item in (try! db.prepare(TABLE_SC)){
            var sc:SC
            sc = SC(sno: item[TABLE_SC_Sno], cno: item[TABLE_SC_Cno], grade: item[TABLE_SC_GRADE])
            SCArray.append(sc)
        }
       
        return SCArray
    }
    func queryTableSC(student_id:Int64) -> [SC]{
        var SCArray = [SC]()
        for item in (try! db.prepare(TABLE_SC)){
            if item[TABLE_SC_Sno] == student_id{
            var sc:SC
            sc = SC(sno: item[TABLE_SC_Sno], cno: item[TABLE_SC_Cno], grade: item[TABLE_SC_GRADE])
                SCArray.append(sc)
            }
        }
       
        return SCArray
    }
        // 读取
    func searchTableStudent(id:Int64) -> Bool{
        for _ in try!
        db.prepare(TABLE_STUDENT.filter(TABLE_STUDENT_ID == id)){
            return true
        }
        return false
    }
   
    func searchTableAdmin(id:Int64) -> Bool{
           for _ in try!
           db.prepare(TABLE_ADMIN.filter(TABLE_ADMIN_ID == id)){
               return true
           }
           return false
    }
    func searchTableSC(course_id:Int64,student_id:Int64) -> Bool{
        for _ in try!
            db.prepare(TABLE_SC.filter(TABLE_SC_Cno == course_id && TABLE_SC_Sno == student_id)){
                return true
            }
        return false
    }
   
    func studentVertify(id:Int64,pwd:String) -> Bool{
        for item in try!
        db.prepare(TABLE_STUDENT.filter(TABLE_STUDENT_ID == id)){
            if(item[TABLE_STUDENT_PASSWORD] == pwd){
                return true
            }
            else
            {
                return false
            }
        }
        return false
    }
   
    func AdminVertify(id:Int64,pwd:String) -> Bool{
        for item in try!
        db.prepare(TABLE_ADMIN.filter(TABLE_ADMIN_ID == id)){
            if(item[TABLE_ADMIN_PASSWORD] == pwd){
                return true
            }
            else
            {
                return false
            }
        }
        return false
    }
   
    func readTableStudent(id:Int64) -> student?{
        var s:student?
        for item in try! db.prepare(TABLE_STUDENT.filter(TABLE_STUDENT_ID == id)){
           
            s = student(id: id, name: item[TABLE_STUDENT_NAME], sex: item[TABLE_STUDENT_SEX], age: item[TABLE_STUDENT_AGE], department: item[TABLE_STUDENT_DEPARTMENT])
        }
        return s
    }
   
    func readTableAdmin(id:Int64) -> admin?{
        var a:admin?
        for item in try! db.prepare(TABLE_ADMIN.filter(TABLE_ADMIN_ID == id)){
           
            a = admin(id: id, name: item[TABLE_ADMIN_NAME], department: item[TABLE_ADMIN_DEPARTMENT])
        }
        return a
    }
   
    func readTableCourse(id:Int64) -> Course?{
        var c:Course?
        for item in try! db.prepare(TABLE_COURSE.filter(TABLE_COURSE_ID == id)){
            c = Course(id: id, name: item[TABLE_COURSE_NAME], credit: item[TABLE_COURSE_CERDIT], pno: item[TABLE_COURSE_PNO])
        }
        return c
    }
   
    func readTableSC(cno:Int64,sno:Int64) -> SC?{
        var sc:SC?
        for item in try! db.prepare(TABLE_SC.filter(TABLE_SC_Cno == cno && TABLE_SC_Sno == sno)){
            sc = SC(sno: sno, cno: cno, grade: item[TABLE_SC_GRADE])
        }
       
        return sc
    }

    func tableSCUpdateItem(sno:Int64,cno:Int64,grade:Int64) -> Void{
        let item = TABLE_SC.filter(TABLE_SC_Cno == cno && TABLE_SC_Sno == sno)
        do{
            if try db.run(item.update(TABLE_SC_GRADE <- grade)) > 0{
                print("成绩更新成功")
            }else{
                print("没有发现该SC数据")
            }
        }catch{
                print("成绩更新失败")
            }
        }
        // 删除
   
    func tableSCDeleteItem(student_id:Int64,course_id:Int64) -> Bool{
        let item = TABLE_SC.filter(TABLE_SC_Cno == course_id && TABLE_SC_Sno == student_id)
        do{
            if try db.run(item.delete()) > 0{
                return true
            }
            else{
                return false
            }
        }catch{
            return false
        }
    }
    }

2.学生登录、注册
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//
//  StudentsLogViewController.swift
//  JSP-HBU
//
//  Created by 齐子佳 on 2020/4/29.
//  Copyright ? 2020 齐子佳. All rights reserved.
//

import UIKit
import Foundation
import SCLAlertView

class StudentsLogInViewController: UIViewController {
   
    var database:Database!
   
    @IBOutlet weak var studentID: UITextField!
    @IBOutlet weak var pwd: UITextField!
    @IBAction func `return`(_ sender: Any) {
        self.navigationController?.popToRootViewController(animated: true)
    }
    @IBAction func logIn(_ sender: Any) {
        if studentID.text!.isBlank || pwd.text!.isBlank
        {
            SCLAlertView().showError("学号或密码不能为空!",subTitle: "请检查输入!",closeButtonTitle: "好的")
        }
        else{
            let id:Int64 = Int64(studentID.text!)!
            if(self.database.searchTableStudent(id: id))
            {
                if(self.database.studentVertify(id: id, pwd: pwd.text!.md5()))
                {
                    let sb = UIStoryboard(name:"Main",bundle: Bundle.main)
                    let secondViewController = sb.instantiateViewController(withIdentifier: "student") as! studentsViewController
                    secondViewController.modalPresentationStyle = .fullScreen
                    secondViewController.studentID = id
                    self.present(secondViewController,animated: true,completion: nil)
                }
                else
                {
                    SCLAlertView().showError("密码错误",subTitle: "请重新输入!",closeButtonTitle: "好的")
                    pwd.text = ""
                }
            }
            else
            {
                SCLAlertView().showError("学号不存在!",subTitle: "请重新输入!",closeButtonTitle: "好的")
                studentID.text = ""
                pwd.text = ""
            }
        }
    }
   
    @IBAction func register(_ sender: Any) {
        let appearance = SCLAlertView.SCLAppearance(
             showCloseButton: false
        )
        let alertView = SCLAlertView(appearance: appearance)
        let idTextField = alertView.addTextField("学号(11位)")
        idTextField.keyboardType = UIKeyboardType.numberPad
        let nameTextField = alertView.addTextField("姓名")
        let sexTextField = alertView.addTextField("性别")
        let ageTextField = alertView.addTextField("年龄")
        let departmentTextField = alertView.addTextField("所在系")
        ageTextField.keyboardType = UIKeyboardType.numberPad
        let pwdTextField = alertView.addTextField("密码(8-16位)")
        pwdTextField.keyboardType = UIKeyboardType.asciiCapable
        alertView.addButton("确定", action: {
           
            if idTextField.text!.isBlank || nameTextField.text!.isBlank || sexTextField.text!.isBlank || ageTextField.text!.isBlank || departmentTextField.text!.isBlank
            {
                SCLAlertView().showError("输入不可为空",subTitle: "请检查输入",closeButtonTitle: "好的")
            }
            else
            {
                if idTextField.text!.count != 11
                {
                    SCLAlertView().showError("学号输入有误",subTitle: "应为11位",closeButtonTitle: "好的")
                }else if pwdTextField.text!.count < 8 || pwdTextField.text!.count > 16
                {
                    SCLAlertView().showError("密码位数有误",subTitle: "应为8-16位",closeButtonTitle: "好的")
                }
               
                else
                {
                    let id:Int64 = Int64(idTextField.text!)!
                    let age:Int64 = Int64(ageTextField.text!)!
                    if(self.database.searchTableStudent(id: id))
                    {
                        SCLAlertView().showError("学号已存在",subTitle: "请重新输入",closeButtonTitle: "好的")
                    }
                    else
                    {
                        self.database.tableStudentInsertItem(id: id, password: pwdTextField.text!.md5(), name: nameTextField.text!, sex: sexTextField.text!, age: age, department: departmentTextField.text!)
                        SCLAlertView().showSuccess("注册成功!",closeButtonTitle: "好的")
                    }
                   
                }
            }
        })
           
        alertView.addButton("返回", action: {
           
        })
        alertView.showInfo("学生注册",subTitle:"请输入个人信息")
       
    }
   
   
   
   

    override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
    self.navigationController?.navigationBar.shadowImage = UIImage()
    self.navigationController?.navigationBar.isTranslucent = true
    self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
    self.navigationController?.navigationItem.leftBarButtonItem?.customView?.isHidden = true
       
    self.hideKeyboardWhenTappedAround()
        database = Database()
    }

}




extension StudentsLogInViewController{
    //隐藏键盘
    func hideKeyboardWhenTappedAround() {
        let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(StudentsLogInViewController.dismissKeyboard))
        tap.cancelsTouchesInView = false
        view.addGestureRecognizer(tap)
    }
   
    @objc private func dismissKeyboard() {
        view.endEditing(true)
    }
   
}

3.管理员登录、注册
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//
//  adminLogViewController.swift
//  JSP-HBU
//
//  Created by 齐子佳 on 2020/4/29.
//  Copyright ? 2020 齐子佳. All rights reserved.
//

import UIKit
import SCLAlertView
import Foundation

class adminLogInViewController: UIViewController {
   
    var database: Database!
   
    @IBOutlet weak var adminID: UITextField!
    @IBOutlet weak var pwd: UITextField!
    @IBAction func back(_ sender: Any) {
        self.navigationController?.popToRootViewController(animated: true)
    }
   
    @IBAction func logIn(_ sender: Any) {
        if adminID.text!.isBlank || pwd.text!.isBlank{
            SCLAlertView().showError("工号或密码不能为空!",subTitle: "请检查输入!",closeButtonTitle: "好的")
        }
        else{
            let id:Int64 = Int64(adminID.text!)!
            if(self.database.searchTableAdmin(id: id))
            {
                if(self.database.AdminVertify(id: id, pwd: pwd.text!.md5())){
                    let sb = UIStoryboard(name:"Main",bundle: Bundle.main)
                    let secondViewController = sb.instantiateViewController(withIdentifier: "admin") as! adminViewController
                    secondViewController.modalPresentationStyle = .fullScreen
                    secondViewController.adminID = id
                    self.present(secondViewController,animated: true,completion: nil)
                }
                else{
                    SCLAlertView().showError("密码错误",subTitle: "请重新输入!",closeButtonTitle: "好的")
                    pwd.text = ""
                }
            }
            else{
                SCLAlertView().showError("工号不存在!",subTitle: "请重新输入!",closeButtonTitle: "好的")
                adminID.text = ""
                pwd.text = ""
            }
        }
    }
   
    @IBAction func register(_ sender: Any) {
        let appearance = SCLAlertView.SCLAppearance(
             showCloseButton: false
        )
        let alertView = SCLAlertView(appearance: appearance)
        let idTextField = alertView.addTextField("工号(5位)")
        idTextField.keyboardType = UIKeyboardType.numberPad
        let nameTextField = alertView.addTextField("姓名")
        let departmentTextField = alertView.addTextField("所在系")
        let pwdTextField = alertView.addTextField("密码(8-16位)")
        pwdTextField.keyboardType = UIKeyboardType.asciiCapable
        alertView.addButton("确定", action: {
           
            if idTextField.text!.isBlank || nameTextField.text!.isBlank ||  departmentTextField.text!.isBlank
            {
                SCLAlertView().showError("输入不可为空",subTitle: "请检查输入",closeButtonTitle: "好的")
            }
            else
            {
                if idTextField.text!.count != 5
                {
                    SCLAlertView().showError("工号输入有误",subTitle: "应为5位",closeButtonTitle: "好的")
                }else if pwdTextField.text!.count < 8 || pwdTextField.text!.count > 16
                {
                    SCLAlertView().showError("密码位数有误",subTitle: "应为8-16位",closeButtonTitle: "好的")
                }
               
                else
                {
                    let id:Int64 = Int64(idTextField.text!)!
                    if(self.database.searchTableStudent(id: id))
                    {
                        SCLAlertView().showError("工号已存在",subTitle: "请重新输入",closeButtonTitle: "好的")
                    }
                    else
                    {
                        self.database.tableAdminInsertItem(id: id, password: pwdTextField.text!.md5(), name: nameTextField.text!,  department: departmentTextField.text!)
                        SCLAlertView().showSuccess("注册成功!",closeButtonTitle: "好的")
                    }
                   
                }
            }
        })
           
        alertView.addButton("返回", action: {
           
        })
        alertView.showInfo("管理员注册",subTitle:"请输入个人信息")
    }
   
   
   
    override func viewDidLoad() {
        super.viewDidLoad()
       
        database = Database()
        self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
        self.navigationController?.navigationBar.shadowImage = UIImage()
        self.navigationController?.navigationBar.isTranslucent = true
        self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
        self.navigationController?.navigationItem.leftBarButtonItem?.customView?.isHidden = true
        self.hideKeyboardWhenTappedAround()
    }


}
extension adminLogInViewController{
    //隐藏键盘
    func hideKeyboardWhenTappedAround() {
        let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(adminLogInViewController.dismissKeyboard))
        tap.cancelsTouchesInView = false
        view.addGestureRecognizer(tap)
    }
   
    @objc private func dismissKeyboard() {
        view.endEditing(true)
    }
   
}

4.字符串判断是否为空、转换md5:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import Foundation

extension String {
   
    var isBlank: Bool {
        let trimmedStr = self.trimmingCharacters(in: .whitespacesAndNewlines)
        return trimmedStr.isEmpty
    }
   
    func md5() -> String {
           let str = self.cString(using: String.Encoding.utf8)
           let strLen = CUnsignedInt(self.lengthOfBytes(using: String.Encoding.utf8))
           let digestLen = Int(CC_MD5_DIGEST_LENGTH)
           let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
           CC_MD5(str!, strLen, result)
           let hash = NSMutableString()
           for i in 0 ..< digestLen {
               hash.appendFormat("%02x", result[i])
           }
            result.deinitialize(count: 16)
   
           return String(format: hash as String)
       }
}

5.学生主页面代码:显示学生的姓名以及四个按钮
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//
//  studentsViewController.swift
//  JSP-HBU
//
//  Created by 齐子佳 on 2020/5/13.
//  Copyright ? 2020 齐子佳. All rights reserved.
//

import UIKit
import SCLAlertView
import Foundation

class studentsViewController: UIViewController {
   
    @IBAction func quit(_ sender: Any) {
        let sb = UIStoryboard(name:"Main",bundle: Bundle.main)
        let secondViewController = sb.instantiateViewController(withIdentifier: "First")
        secondViewController.modalPresentationStyle = .fullScreen
        self.present(secondViewController,animated: true,completion: nil)
    }
   
    var database:Database!
   
    @IBOutlet weak var userName: UILabel!
   
    var studentID:Int64?

    override func viewDidLoad() {
        super.viewDidLoad()
        database = Database()
        let student = database.readTableStudent(id: studentID!)
        userName.text = "欢迎\(student!.name)同学!"
        print(student!.name)
        print(student!.age)
        print(student!.department)
       
    }
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "studentsTabBar"
        {
            let detailVC = segue.destination as! StuTabBarViewController
            detailVC.stuID = studentID
        }
        if segue.identifier == "grades"{
            let detailVC = segue.destination as! GradesViewController
            detailVC.stuID = studentID
        }
    }
   
}

6.管理员主页面代码:显示管理员的姓名以及四个按钮
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//
//  adminViewController.swift
//  JSP-HBU
//
//  Created by 齐子佳 on 2020/5/13.
//  Copyright ? 2020 齐子佳. All rights reserved.
//

import UIKit
import SCLAlertView
import Foundation
import SQLite

class adminViewController: UIViewController {
   
    @IBOutlet weak var userName: UILabel!
   
    var database:Database!
   
    var adminID:Int64?

    @IBAction func quit(_ sender: Any) {
        let sb = UIStoryboard(name:"Main",bundle: Bundle.main)
        let secondViewController = sb.instantiateViewController(withIdentifier: "First")
        secondViewController.modalPresentationStyle = .fullScreen
        self.present(secondViewController,animated: true,completion: nil)
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        database = Database()
        let admin = database.readTableAdmin(id: adminID!)
        userName.text = "欢迎\(admin!.name)老师!"
        print(admin!.id)
        print(admin!.name)
        print(admin!.department)
       
    }
}

7.流式表格布局类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//多列表格组件(通过CollectionView实现)
class UICollectionGridViewController: UICollectionViewController {
    //表头数据
    var cols: [String]! = []
    //行数据
    var rows: [[Any]]! = []
     
    //排序代理
    weak var sortDelegate: UICollectionGridViewSortDelegate?
     
    //选中的表格列(-1表示没有选中的)
    private var selectedColIdx = -1
    //列排序顺序
    private var asc = true
     
    init() {
        //初始化表格布局
        let layout = UICollectionGridViewLayout()
        super.init(collectionViewLayout: layout)
        layout.viewController = self
        collectionView!.backgroundColor = UIColor.white
        collectionView!.register(UICollectionGridViewCell.self,
                                      forCellWithReuseIdentifier: "cell")
        collectionView!.delegate = self
        collectionView!.dataSource = self
        collectionView!.isDirectionalLockEnabled = true
        //collectionView!.contentInset = UIEdgeInsetsMake(0, 10, 0, 10)
        collectionView!.bounces = false
    }
     
    required init?(coder aDecoder: NSCoder) {
        fatalError("UICollectionGridViewController.init(coder:) has not been implemented")
    }
     
    //设置列头数据
    func setColumns(columns: [String]) {
        cols = columns
    }
     
    //添加行数据
    func addRow(row: [Any]) {
        rows.append(row)
        collectionView!.collectionViewLayout.invalidateLayout()
        collectionView!.reloadData()
    }
     
    override func viewDidLoad() {
        super.viewDidLoad()
    }
     
    override func viewDidLayoutSubviews() {
        collectionView!.frame = CGRect(x:0, y:0,
                                       width:view.frame.width, height:view.frame.height)
    }
     
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
     
    //返回表格总行数
    override func numberOfSections(in collectionView: UICollectionView) -> Int {
            if cols.isEmpty {
                return 0
            }
            //总行数是:记录数+1个表头
            return rows.count + 1
    }
     
    //返回表格的列数
    override func collectionView(_ collectionView: UICollectionView,
                                 numberOfItemsInSection section: Int) -> Int {
        return cols.count
    }
     
    //单元格内容创建
    override func collectionView(_ collectionView: UICollectionView,
                            cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell",for: indexPath) as! UICollectionGridViewCell
         
        //设置列头单元格,内容单元格的数据
        if indexPath.section == 0 {
            cell.label.font = UIFont.systemFont(ofSize: 15, weight: UIFont.Weight.bold)
            cell.label.text = cols[indexPath.row]
            cell.label.textColor = UIColor.white
        } else {
            cell.label.font = UIFont.systemFont(ofSize: 15)
            cell.label.text = "\(rows[indexPath.section-1][indexPath.row])"
            cell.label.textColor = UIColor.black
        }
         
        //表头单元格背景色
        if indexPath.section == 0 {
            cell.backgroundColor = UIColor(red: 0x91/255, green: 0xDA/255,
                                           blue: 0x51/255, alpha: 1)
            //排序列列头显示升序降序图标
            if indexPath.row == selectedColIdx {
                let iconType = asc ? FAType.FALongArrowUp : FAType.FALongArrowDown
                cell.imageView.setFAIconWithName(icon: iconType, textColor: UIColor.white)
            }else{
                cell.imageView.image = nil
            }
        }
        //内容单元格背景色
        else {
            //排序列的单元格背景会变色
            if indexPath.row == selectedColIdx {
                //排序列的单元格背景会变色
                cell.backgroundColor = UIColor(red: 0xCC/255, green: 0xF8/255,
                                               blue: 0xFF/255, alpha: 1)
            }
            //数据区域每行单元格背景色交替显示
            else if indexPath.section % 2 == 0 {
                cell.backgroundColor = UIColor(white: 242/255.0, alpha: 1)
            } else {
                cell.backgroundColor = UIColor.white
            }
        }
         
        return cell
    }
     
    //单元格选中事件
    override func collectionView(_ collectionView: UICollectionView,
                                 didSelectItemAt indexPath: IndexPath) {
        //打印出点击单元格的[行,列]坐标
        print("点击单元格的[行,列]坐标: [\(indexPath.section),\(indexPath.row)]")
        if indexPath.section == 0 && sortDelegate != nil {
            //如果点击的是表头单元格,则默认该列升序排列,再次点击则变降序排列,以此交替
            asc = (selectedColIdx != indexPath.row) ? true : !asc
            selectedColIdx = indexPath.row
            rows = sortDelegate?.sort(colIndex: indexPath.row, asc: asc, rows: rows)
            collectionView.reloadData()
           
        }
    }
}

8.课程修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
class CourseModifyViewController: UIViewController,UICollectionGridViewSortDelegate {
   
    var gridViewController: UICollectionGridViewController!
   
    @IBOutlet weak var please: UILabel!
   
    var database:Database!

    override func viewDidLoad() {
        super.viewDidLoad()
        database = Database()

        update()
       

    }
    override func viewDidLayoutSubviews() {
//        gridViewController.view.frame = CGRect(x:0, y:64, width:view.frame.width,height:view.frame.height-64)
    }
    override func viewDidAppear(_ animated: Bool) {
        update()
    }
    func update() -> Void{
        let courses = database.queryTableCourse()
        if courses.count == 0{
            please.isHidden = false
        }
        else{
            gridViewController = UICollectionGridViewController()
            gridViewController.sortDelegate = self
            gridViewController.setColumns(columns: ["课程编号","课程名", "课程学分", "课序号"])
            for course in courses{
                let id = String(course.id)
                gridViewController.addRow(row:[ id,course.name,course.credit,course.pno])
            }
            view.addSubview(gridViewController.view)
        }
    }
    func sort(colIndex: Int, asc: Bool, rows: [[Any]]) -> [[Any]] {
        let sortedRows = rows.sorted { (firstRow: [Any], secondRow: [Any])
            -> Bool in
            let firstRowValue = firstRow[colIndex] as! String
            let secondRowValue = secondRow[colIndex] as! String
            if colIndex == 1 {
                //首例、姓名使用字典排序法
                if asc {
                    return firstRowValue < secondRowValue
                }
                return firstRowValue > secondRowValue
            } else if colIndex == 2 || colIndex == 3 || colIndex == 0{
                //中间两列使用数字排序
                if asc {
                    return Int(firstRowValue)! < Int(secondRowValue)!
                }
                return Int(firstRowValue)! > Int(secondRowValue)!
            }
            return true
        }
        return sortedRows
    }

}

9.添加课程
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//
//  courseAddViewController.swift
//  JSP-HBU
//
//  Created by 齐子佳 on 2020/5/18.
//  Copyright ? 2020 齐子佳. All rights reserved.
//

import UIKit
import SCLAlertView

class courseAddViewController: UIViewController {
   
    var database:Database!
   
    @IBOutlet weak var id: UITextField!
    @IBOutlet weak var name: UITextField!
    @IBOutlet weak var credit: UITextField!
    @IBOutlet weak var num: UITextField!
   
   
    @IBAction func clean(_ sender: Any) {
        id.text = ""
        name.text = ""
        credit.text = ""
        num.text = ""
    }
   
    @IBAction func add(_ sender: Any) {
        if id.text!.isBlank || name.text!.isBlank || credit.text!.isBlank || num.text!.isBlank{
            SCLAlertView().showError("课程信息不能为空!",subTitle: "请检查输入!",closeButtonTitle: "好的")
        }else{
            let c:Int64 = Int64(credit.text!)!
            let n:Int64 = Int64(num.text!)!
            if id.text!.count != 5{
                SCLAlertView().showError("课程号输入有误",subTitle: "应为5位",closeButtonTitle: "好的")
            }
            else if c<1 || c>10{
                SCLAlertView().showError("学分输入有误!",subTitle: "应为1~10的整数",closeButtonTitle: "重新输入")
            }
            else if n<1 || n>10{
                SCLAlertView().showError("课序号输入有误!",subTitle: "应为1~10的整数",closeButtonTitle: "重新输入")
            }
            else{
                let _id = Int64(id.text!)!
                if database.tableCourseInsertItem(id: _id, name: name.text!, credit: c, pno: n){
                    SCLAlertView().showSuccess("课程插入成功",subTitle: "课程号为\(id.text!)",closeButtonTitle: "好的")
                   
                }
                else{
                    SCLAlertView().showError("课程插入失败",subTitle:"请检查输入",closeButtonTitle: "好的")
                }

            }
        }
    }
   
   
   
    override func viewDidLoad() {
        super.viewDidLoad()
       
        database = Database()
       
    }
   

}

10.学生选课

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
//
//  selectCourseViewController.swift
//  JSP-HBU
//
//  Created by 齐子佳 on 2020/5/20.
//  Copyright ? 2020 齐子佳. All rights reserved.
//

import UIKit
import SCLAlertView
//表格排序协议
protocol UICollectionGridViewSortDelegate1: class {
    func sort(colIndex: Int, asc: Bool, rows: [[Any]]) -> [[Any]]
}

class selectCourseViewController: UIViewController,UICollectionGridViewSortDelegate1 {
   
    var stuID:Int64?
   
    @IBOutlet weak var please: UILabel!
    var gridViewController: UICollectionGridViewController1!
    var database:Database!
   
    func update() -> Void{
        let courses = database.queryTableCourse()
        if courses.count == 0{
            please.isHidden = false
        }
        else{
            gridViewController = UICollectionGridViewController1()
            gridViewController.stuID = stuID
            gridViewController.sortDelegate = self
            gridViewController.setColumns(columns: ["课程编号","课程名", "课程学分", "课序号"])
            for course in courses{
                let id = String(course.id)
                gridViewController.addRow(row:[ id,course.name,course.credit,course.pno])
            }
            view.addSubview(gridViewController.view)
        }
    }
   
    func sort(colIndex: Int, asc: Bool, rows: [[Any]]) -> [[Any]] {
        let sortedRows = rows.sorted { (firstRow: [Any], secondRow: [Any])
            -> Bool in
            let firstRowValue = firstRow[colIndex] as! String
            let secondRowValue = secondRow[colIndex] as! String
            if colIndex == 1 {
                //首例、姓名使用字典排序法
                if asc {
                    return firstRowValue < secondRowValue
                }
                return firstRowValue > secondRowValue
            } else if colIndex == 2 || colIndex == 3 || colIndex == 0{
                //中间两列使用数字排序
                if asc {
                    return Int(firstRowValue)! < Int(secondRowValue)!
                }
                return Int(firstRowValue)! > Int(secondRowValue)!
            }
            return true
        }
        return sortedRows
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        database = Database()
        update()
    }
    override func viewDidAppear(_ animated: Bool) {
        update()
    }

}
//多列表格组件(通过CollectionView实现)
class UICollectionGridViewController1: UICollectionViewController {
   
    var stuID:Int64?
   
    var database:Database!
    //表头数据
    var cols: [String]! = []
    //行数据
    var rows: [[Any]]! = []
     
    //排序代理
    weak var sortDelegate: UICollectionGridViewSortDelegate1?
     
    //选中的表格列(-1表示没有选中的)
    private var selectedColIdx = -1
    //列排序顺序
    private var asc = true
     
    init() {
        //初始化表格布局
        let layout = UICollectionGridViewLayout1()
        super.init(collectionViewLayout: layout)
        layout.viewController = self
        collectionView!.backgroundColor = UIColor.white
        collectionView!.register(UICollectionGridViewCell.self,
                                      forCellWithReuseIdentifier: "cell")
        collectionView!.delegate = self
        collectionView!.dataSource = self
        collectionView!.isDirectionalLockEnabled = true
        //collectionView!.contentInset = UIEdgeInsetsMake(0, 10, 0, 10)
        collectionView!.bounces = false
    }
     
    required init?(coder aDecoder: NSCoder) {
        fatalError("UICollectionGridViewController.init(coder:) has not been implemented")
    }
     
    //设置列头数据
    func setColumns(columns: [String]) {
        cols = columns
    }
     
    //添加行数据
    func addRow(row: [Any]) {
        rows.append(row)
        collectionView!.collectionViewLayout.invalidateLayout()
        collectionView!.reloadData()
    }
     
    override func viewDidLoad() {
        super.viewDidLoad()
        database = Database()
    }
     
    override func viewDidLayoutSubviews() {
        collectionView!.frame = CGRect(x:0, y:0,
                                       width:view.frame.width, height:view.frame.height)
    }
     
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
     
    //返回表格总行数
    override func numberOfSections(in collectionView: UICollectionView) -> Int {
            if cols.isEmpty {
                return 0
            }
            //总行数是:记录数+1个表头
            return rows.count + 1
    }
     
    //返回表格的列数
    override func collectionView(_ collectionView: UICollectionView,
                                 numberOfItemsInSection section: Int) -> Int {
        return cols.count
    }
     
    //单元格内容创建
    override func collectionView(_ collectionView: UICollectionView,
                            cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell",for: indexPath) as! UICollectionGridViewCell
         
        //设置列头单元格,内容单元格的数据
        if indexPath.section == 0 {
            cell.label.font = UIFont.systemFont(ofSize: 15, weight: UIFont.Weight.bold)
            cell.label.text = cols[indexPath.row]
            cell.label.textColor = UIColor.white
        } else {
            cell.label.font = UIFont.systemFont(ofSize: 15)
            cell.label.text = "\(rows[indexPath.section-1][indexPath.row])"
            cell.label.textColor = UIColor.black
        }
         
        //表头单元格背景色
        if indexPath.section == 0 {
            cell.backgroundColor = UIColor(red: 0x91/255, green: 0xDA/255,
                                           blue: 0x51/255, alpha: 1)
            //排序列列头显示升序降序图标
            if indexPath.row == selectedColIdx {
                let iconType = asc ? FAType.FALongArrowUp : FAType.FALongArrowDown
                cell.imageView.setFAIconWithName(icon: iconType, textColor: UIColor.white)
            }else{
                cell.imageView.image = nil
            }
        }
        //内容单元格背景色
        else {
            //排序列的单元格背景会变色
            if indexPath.row == selectedColIdx {
                //排序列的单元格背景会变色
                cell.backgroundColor = UIColor(red: 0xCC/255, green: 0xF8/255,
                                               blue: 0xFF/255, alpha: 1)
            }
            //数据区域每行单元格背景色交替显示
            else if indexPath.section % 2 == 0 {
                cell.backgroundColor = UIColor(white: 242/255.0, alpha: 1)
            } else {
                cell.backgroundColor = UIColor.white
            }
        }
         
        return cell
    }
     
    //单元格选中事件
    override func collectionView(_ collectionView: UICollectionView,
                                 didSelectItemAt indexPath: IndexPath) {
        //打印出点击单元格的[行,列]坐标
        print("点击单元格的[行,列]坐标: [\(indexPath.section),\(indexPath.row)]")
        if indexPath.section == 0 && sortDelegate != nil {
            //如果点击的是表头单元格,则默认该列升序排列,再次点击则变降序排列,以此交替
            asc = (selectedColIdx != indexPath.row) ? true : !asc
            selectedColIdx = indexPath.row
            rows = sortDelegate?.sort(colIndex: indexPath.row, asc: asc, rows: rows)
            collectionView.reloadData()
           
        }
        else{
            if(indexPath.section != 0 && indexPath.row == 0){
                let cell = collectionView.cellForItem(at: indexPath) as! UICollectionGridViewCell
                print(cell.label.text!)
               
                let course_id = Int64(cell.label.text!)!
                let course = database.readTableCourse(id: course_id)
                if database.searchTableSC(course_id: course_id, student_id: stuID!){
                    SCLAlertView().showError("您已经选过此课程",subTitle:"请勿重复选择!",closeButtonTitle: "好的")
                }else{
                    if(database.tableSCInsertItem(sno: stuID!, cno: course_id, grade: -1))
                    {
                        SCLAlertView().showSuccess("选课成功!",subTitle: "课程名称:\(String(describing: course!.name))",closeButtonTitle: "好的")
                    }else{
                        SCLAlertView().showError("选课失败",subTitle: "发生未知错误!",closeButtonTitle: "好的")
                    }
                }
               
            }
        }
    }
}

11.学生退课

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
class quitCourseViewController: UIViewController,UICollectionGridViewSortDelegate2 {
    var stuID:Int64?
    @IBOutlet weak var please: UILabel!
    var gridViewController:UICollectionGridViewController2!
    var database:Database!
   
    @objc func update() -> Void{
        let courses = database.queryTableSC(student_id: stuID!)
        if courses.count == 0{
            please.isHidden = false
        }
        else{
            gridViewController = UICollectionGridViewController2()
            gridViewController.stuID = stuID
            gridViewController.sortDelegate = self
            gridViewController.setColumns(columns: ["课程编号","课程名", "课程学分", "课序号"])
            for course in courses{
                let id = Int64(course.cno)
                let c = database.readTableCourse(id: id)!
                gridViewController.addRow(row:[ c.id,c.name,c.credit,c.pno])
            }
            view.addSubview(gridViewController.view)
           
        }
    }
    override func viewWillAppear(_ animated: Bool) {
        let name = NSNotification.Name(rawValue:"quitUpdate")
        NotificationCenter.default.addObserver(self, selector: #selector(update), name: name, object: nil)
        update()
    }
    override func viewDidAppear(_ animated: Bool) {
        update()
    }
    func sort(colIndex: Int, asc: Bool, rows: [[Any]]) -> [[Any]] {
            let sortedRows = rows.sorted { (firstRow: [Any], secondRow: [Any])
            -> Bool in
            let firstRowValue = firstRow[colIndex] as! String
            let secondRowValue = secondRow[colIndex] as! String
            if colIndex == 1 {
                //首例、姓名使用字典排序法
                if asc {
                    return firstRowValue < secondRowValue
                }
                return firstRowValue > secondRowValue
            } else if colIndex == 2 || colIndex == 3 || colIndex == 0{
                //中间两列使用数字排序
                if asc {
                    return Int(firstRowValue)! < Int(secondRowValue)!
                }
                return Int(firstRowValue)! > Int(secondRowValue)!
            }
            return true
        }
        return sortedRows
    }
   
    override func viewDidLoad() {
        super.viewDidLoad()
        database = Database()
       
    }
   
//    deinit {
//        //记得移除通知监听
//        NotificationCenter.default.removeObserver(self)
//    }
}

12.成绩录入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
//
//  gradeViewController.swift
//  JSP-HBU
//
//  Created by 齐子佳 on 2020/5/18.
//  Copyright ? 2020 齐子佳. All rights reserved.
//

import UIKit
import SCLAlertView
//表格排序协议
protocol UICollectionGridViewSortDelegate4: class {
    func sort(colIndex: Int, asc: Bool, rows: [[Any]]) -> [[Any]]
}

class gradeViewController: UIViewController,UICollectionGridViewSortDelegate4 {
    @IBOutlet weak var please: UILabel!
    func sort(colIndex: Int, asc: Bool, rows: [[Any]]) -> [[Any]] {
        let sortedRows = rows.sorted { (firstRow: [Any], secondRow: [Any])
            -> Bool in
            let firstRowValue = firstRow[colIndex] as! String
            let secondRowValue = secondRow[colIndex] as! String
            if colIndex == 1 {
                //首例、姓名使用字典排序法
                if asc {
                    return firstRowValue < secondRowValue
                }
                return firstRowValue > secondRowValue
            } else if colIndex == 2 || colIndex == 3 || colIndex == 0{
                //中间两列使用数字排序
                if asc {
                    return Int(firstRowValue)! < Int(secondRowValue)!
                }
                return Int(firstRowValue)! > Int(secondRowValue)!
            }
            return true
        }
        return sortedRows
    }
   
   
    var database:Database!
    var gridViewController: UICollectionGridViewController4!

    override func viewDidLoad() {
        super.viewDidLoad()
        database = Database()
        update()
       
    }
    override func viewWillAppear(_ animated: Bool) {
        update()
    }
    func update() -> Void{
        let scs = database.queryTableSC()
        if scs.count == 0{
            please.isHidden = false
        }
        else{
            gridViewController = UICollectionGridViewController4()
            //gridViewController.stuID = stuID
            gridViewController.sortDelegate = self
            gridViewController.setColumns(columns: ["学生姓名","学生学号", "课程名","课程号", "课程学分","当前成绩"])
            for sc in scs{
                let student = database.readTableStudent(id: sc.sno)
                let course = database.readTableCourse(id: sc.cno)
                print(sc.grade)
                if sc.grade == -1{
                    gridViewController.addRow(row: [student!.name,student!.id,course!.name,course!.id,course!.credit,"成绩未录入"])
                }else{
                    gridViewController.addRow(row: [student!.name,student!.id,course!.name,course!.id,course!.credit,sc.grade])
                }
               
//                let id = String(course.id)
//                gridViewController.addRow(row:[ id,course.name,course.credit,course.pno])
            }
            view.addSubview(gridViewController.view)
        }
    }
   
   
}
//多列表格组件(通过CollectionView实现)
class UICollectionGridViewController4: UICollectionViewController {
   
    var stuID:Int64?
   
    var database:Database!
    //表头数据
    var cols: [String]! = []
    //行数据
    var rows: [[Any]]! = []
     
    //排序代理
    weak var sortDelegate: UICollectionGridViewSortDelegate4?
     
    //选中的表格列(-1表示没有选中的)
    private var selectedColIdx = -1
    //列排序顺序
    private var asc = true
     
    init() {
        //初始化表格布局
        let layout = UICollectionGridViewLayout4()
        super.init(collectionViewLayout: layout)
        layout.viewController = self
        collectionView!.backgroundColor = UIColor.white
        collectionView!.register(UICollectionGridViewCell.self,
                                      forCellWithReuseIdentifier: "cell")
        collectionView!.delegate = self
        collectionView!.dataSource = self
        collectionView!.isDirectionalLockEnabled = true
        //collectionView!.contentInset = UIEdgeInsetsMake(0, 10, 0, 10)
        collectionView!.bounces = false
    }
     
    required init?(coder aDecoder: NSCoder) {
        fatalError("UICollectionGridViewController.init(coder:) has not been implemented")
    }
     
    //设置列头数据
    func setColumns(columns: [String]) {
        cols = columns
    }
     
    //添加行数据
    func addRow(row: [Any]) {
        rows.append(row)
        collectionView!.collectionViewLayout.invalidateLayout()
        collectionView!.reloadData()
    }
     
    override func viewDidLoad() {
        super.viewDidLoad()
        database = Database()
    }
     
    override func viewDidLayoutSubviews() {
        collectionView!.frame = CGRect(x:0, y:0,
                                       width:view.frame.width, height:view.frame.height)
    }
     
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
     
    //返回表格总行数
    override func numberOfSections(in collectionView: UICollectionView) -> Int {
            if cols.isEmpty {
                return 0
            }
            //总行数是:记录数+1个表头
            return rows.count + 1
    }
     
    //返回表格的列数
    override func collectionView(_ collectionView: UICollectionView,
                                 numberOfItemsInSection section: Int) -> Int {
        return cols.count
    }
     
    //单元格内容创建
    override func collectionView(_ collectionView: UICollectionView,
                            cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell",for: indexPath) as! UICollectionGridViewCell
         
        //设置列头单元格,内容单元格的数据
        if indexPath.section == 0 {
            cell.label.font = UIFont.systemFont(ofSize: 15, weight: UIFont.Weight.bold)
            cell.label.text = cols[indexPath.row]
            cell.label.textColor = UIColor.white
        } else {
            cell.label.font = UIFont.systemFont(ofSize: 15)
            cell.label.text = "\(rows[indexPath.section-1][indexPath.row])"
            cell.label.textColor = UIColor.black
        }
         
        //表头单元格背景色
        if indexPath.section == 0 {
            cell.backgroundColor = UIColor(red: 0x91/255, green: 0xDA/255,
                                           blue: 0x51/255, alpha: 1)
            //排序列列头显示升序降序图标
            if indexPath.row == selectedColIdx {
                let iconType = asc ? FAType.FALongArrowUp : FAType.FALongArrowDown
                cell.imageView.setFAIconWithName(icon: iconType, textColor: UIColor.white)
            }else{
                cell.imageView.image = nil
            }
        }
        //内容单元格背景色
        else {
            //排序列的单元格背景会变色
            if indexPath.row == selectedColIdx {
                //排序列的单元格背景会变色
                cell.backgroundColor = UIColor(red: 0xCC/255, green: 0xF8/255,
                                               blue: 0xFF/255, alpha: 1)
            }
            //数据区域每行单元格背景色交替显示
            else if indexPath.section % 2 == 0 {
                cell.backgroundColor = UIColor(white: 242/255.0, alpha: 1)
            } else {
                cell.backgroundColor = UIColor.white
            }
        }
         
        return cell
    }
     
    //单元格选中事件
    override func collectionView(_ collectionView: UICollectionView,
                                 didSelectItemAt indexPath: IndexPath) {
        //打印出点击单元格的[行,列]坐标
        print("点击单元格的[行,列]坐标: [\(indexPath.section),\(indexPath.row)]")
        if indexPath.section == 0 && sortDelegate != nil {
            //如果点击的是表头单元格,则默认该列升序排列,再次点击则变降序排列,以此交替
            asc = (selectedColIdx != indexPath.row) ? true : !asc
            selectedColIdx = indexPath.row
            rows = sortDelegate?.sort(colIndex: indexPath.row, asc: asc, rows: rows)
            collectionView.reloadData()
           
        }
        else{
            if indexPath.section != 0{
                let cell = collectionView.cellForItem(at: indexPath) as! UICollectionGridViewCell
                var sno:IndexPath = indexPath
                var cno:IndexPath = indexPath
               
                sno.row = 1
                cno.row = 3
                let snoCell = collectionView.cellForItem(at: sno) as! UICollectionGridViewCell
                let cnoCell = collectionView.cellForItem(at: cno) as! UICollectionGridViewCell
                let stu_name = database.readTableStudent(id: Int64(snoCell.label.text!)!)!.name
                let course_name = database.readTableCourse(id: Int64(cnoCell.label.text!)!)!.name
                print(cell.label.text!)
                let alertView = SCLAlertView()
                let dailyGradeTextField = alertView.addTextField("平时成绩")
                let finalGradeTextField = alertView.addTextField("期末成绩")
                let proportionTextField = alertView.addTextField("平时成绩占比")
                dailyGradeTextField.keyboardType = .numberPad
                finalGradeTextField.keyboardType = .numberPad
                proportionTextField.keyboardType = .numberPad
                alertView.addButton("确定", action: {
                    let dailyGrade = Float(dailyGradeTextField.text!)!
                    let finalGrade = Float(finalGradeTextField.text!)!
                    let proportion = Float(proportionTextField.text!)!
                    let grade_temp = dailyGrade * proportion + finalGrade * (1-proportion)
                    let grade = Int64(lroundf(grade_temp))
                    self.database.tableSCUpdateItem(sno: Int64(snoCell.label.text!)!, cno: Int64(cnoCell.label.text!)!, grade: grade)
                    SCLAlertView().showSuccess("成绩录入成功!",closeButtonTitle: "好的")
                   
                   
                })
                alertView.showInfo("请输入学生\(stu_name)的\(course_name)成绩",closeButtonTitle: "取消")
               
            }
        }
    }
}

13.成绩显示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
//
//  GradesViewController.swift
//  JSP-HBU
//
//  Created by 齐子佳 on 6/6/20.
//  Copyright ? 2020 齐子佳. All rights reserved.
//

import UIKit
import SCLAlertView
protocol UICollectionGridViewSortDelegate5: class {
    func sort(colIndex: Int, asc: Bool, rows: [[Any]]) -> [[Any]]
}
class GradesViewController: UITabBarController,UICollectionGridViewSortDelegate5 {
   
   
    @IBOutlet weak var please: UILabel!
    var database:Database!
    var stuID:Int64?
    var gridViewController:UICollectionGridViewController5!
    func sort(colIndex: Int, asc: Bool, rows: [[Any]]) -> [[Any]] {
        let sortedRows = rows.sorted { (firstRow: [Any], secondRow: [Any])
            -> Bool in
            let firstRowValue = firstRow[colIndex] as! String
            let secondRowValue = secondRow[colIndex] as! String
            if colIndex == 1 {
                //首例、姓名使用字典排序法
                if asc {
                    return firstRowValue < secondRowValue
                }
                return firstRowValue > secondRowValue
            } else if colIndex == 2 || colIndex == 3 || colIndex == 0{
                //中间两列使用数字排序
                if asc {
                    return Int(firstRowValue)! < Int(secondRowValue)!
                }
                return Int(firstRowValue)! > Int(secondRowValue)!
            }
            return true
        }
        return sortedRows
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        database = Database()
    }
    override func viewDidAppear(_ animated: Bool) {
        update()
    }
    @objc func update() -> Void{
        let courses = database.queryTableSC(student_id: stuID!)
        if courses.count == 0{
            please.isHidden = false
        }
        else{
            gridViewController = UICollectionGridViewController5()
            gridViewController.stuID = stuID
            gridViewController.sortDelegate = self
            gridViewController.setColumns(columns: ["课程编号","课程名", "课程学分", "成绩"])
            for course in courses{
                let id = Int64(course.cno)
                let c = database.readTableCourse(id: id)!
                let sc = database.readTableSC(cno: c.id, sno: stuID!)
                if sc?.grade == -1{
                    gridViewController.addRow(row:[ c.id,c.name,c.credit,"暂无"])
                }else{
                gridViewController.addRow(row:[ c.id,c.name,c.credit,sc!.grade])
                }
            }
            view.addSubview(gridViewController.view)
           
        }
    }
}
//多列表格组件(通过CollectionView实现)
class UICollectionGridViewController5: UICollectionViewController {
   
    var stuID:Int64?
   
    var database:Database!
    //表头数据
    var cols: [String]! = []
    //行数据
    var rows: [[Any]]! = []
     
    //排序代理
    weak var sortDelegate: UICollectionGridViewSortDelegate5?
     
    //选中的表格列(-1表示没有选中的)
    private var selectedColIdx = -1
    //列排序顺序
    private var asc = true
     
    init() {
        //初始化表格布局
        let layout = UICollectionGridViewLayout5()
        super.init(collectionViewLayout: layout)
        layout.viewController = self
        collectionView!.backgroundColor = UIColor.white
        collectionView!.register(UICollectionGridViewCell.self,
                                      forCellWithReuseIdentifier: "cell")
        collectionView!.delegate = self
        collectionView!.dataSource = self
        collectionView!.isDirectionalLockEnabled = true
        //collectionView!.contentInset = UIEdgeInsetsMake(0, 10, 0, 10)
        collectionView!.bounces = false
    }
     
    required init?(coder aDecoder: NSCoder) {
        fatalError("UICollectionGridViewController.init(coder:) has not been implemented")
    }
     
    //设置列头数据
    func setColumns(columns: [String]) {
        cols = columns
    }
     
    //添加行数据
    func addRow(row: [Any]) {
        rows.append(row)
        collectionView!.collectionViewLayout.invalidateLayout()
        collectionView!.reloadData()
    }
     
    override func viewDidLoad() {
        super.viewDidLoad()
        database = Database()
       
    }
     
    override func viewDidLayoutSubviews() {
        collectionView!.frame = CGRect(x:0, y:0,
                                       width:view.frame.width, height:view.frame.height)
    }
     
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
     
    //返回表格总行数
    override func numberOfSections(in collectionView: UICollectionView) -> Int {
            if cols.isEmpty {
                return 0
            }
            //总行数是:记录数+1个表头
            return rows.count + 1
    }
     
    //返回表格的列数
    override func collectionView(_ collectionView: UICollectionView,
                                 numberOfItemsInSection section: Int) -> Int {
        return cols.count
    }
     
    //单元格内容创建
    override func collectionView(_ collectionView: UICollectionView,
                            cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell",for: indexPath) as! UICollectionGridViewCell
         
        //设置列头单元格,内容单元格的数据
        if indexPath.section == 0 {
            cell.label.font = UIFont.systemFont(ofSize: 15, weight: UIFont.Weight.bold)
            cell.label.text = cols[indexPath.row]
            cell.label.textColor = UIColor.white
        } else {
            cell.label.font = UIFont.systemFont(ofSize: 15)
            cell.label.text = "\(rows[indexPath.section-1][indexPath.row])"
            cell.label.textColor = UIColor.black
        }
         
        //表头单元格背景色
        if indexPath.section == 0 {
            cell.backgroundColor = UIColor(red: 0x91/255, green: 0xDA/255,
                                           blue: 0x51/255, alpha: 1)
            //排序列列头显示升序降序图标
            if indexPath.row == selectedColIdx {
                let iconType = asc ? FAType.FALongArrowUp : FAType.FALongArrowDown
                cell.imageView.setFAIconWithName(icon: iconType, textColor: UIColor.white)
            }else{
                cell.imageView.image = nil
            }
        }
        //内容单元格背景色
        else {
            //排序列的单元格背景会变色
            if indexPath.row == selectedColIdx {
                //排序列的单元格背景会变色
                cell.backgroundColor = UIColor(red: 0xCC/255, green: 0xF8/255,
                                               blue: 0xFF/255, alpha: 1)
            }
            //数据区域每行单元格背景色交替显示
            else if indexPath.section % 2 == 0 {
                cell.backgroundColor = UIColor(white: 242/255.0, alpha: 1)
            } else {
                cell.backgroundColor = UIColor.white
            }
        }
         
        return cell
    }
     
    //单元格选中事件
    override func collectionView(_ collectionView: UICollectionView,
                                 didSelectItemAt indexPath: IndexPath) {
        //打印出点击单元格的[行,列]坐标
        print("点击单元格的[行,列]坐标: [\(indexPath.section),\(indexPath.row)]")
        if indexPath.section == 0 && sortDelegate != nil {
            //如果点击的是表头单元格,则默认该列升序排列,再次点击则变降序排列,以此交替
            asc = (selectedColIdx != indexPath.row) ? true : !asc
            selectedColIdx = indexPath.row
            rows = sortDelegate?.sort(colIndex: indexPath.row, asc: asc, rows: rows)
            collectionView.reloadData()
           
        }
        else{
        }
       
       
    }
   
}

14.学生退课

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
//
//  quitCourseViewController.swift
//  JSP-HBU
//
//  Created by 齐子佳 on 2020/5/20.
//  Copyright ? 2020 齐子佳. All rights reserved.
//

import UIKit
import SCLAlertView
protocol UICollectionGridViewSortDelegate2: class {
    func sort(colIndex: Int, asc: Bool, rows: [[Any]]) -> [[Any]]
}

class quitCourseViewController: UIViewController,UICollectionGridViewSortDelegate2 {
    var stuID:Int64?
    @IBOutlet weak var please: UILabel!
    var gridViewController:UICollectionGridViewController2!
    var database:Database!
   
    @objc func update() -> Void{
        let courses = database.queryTableSC(student_id: stuID!)
        if courses.count == 0{
            please.isHidden = false
        }
        else{
            gridViewController = UICollectionGridViewController2()
            gridViewController.stuID = stuID
            gridViewController.sortDelegate = self
            gridViewController.setColumns(columns: ["课程编号","课程名", "课程学分", "课序号"])
            for course in courses{
                let id = Int64(course.cno)
                let c = database.readTableCourse(id: id)!
                gridViewController.addRow(row:[ c.id,c.name,c.credit,c.pno])
            }
            view.addSubview(gridViewController.view)
           
        }
    }
    override func viewWillAppear(_ animated: Bool) {
        let name = NSNotification.Name(rawValue:"quitUpdate")
        NotificationCenter.default.addObserver(self, selector: #selector(update), name: name, object: nil)
        update()
    }
    override func viewDidAppear(_ animated: Bool) {
        update()
    }
    func sort(colIndex: Int, asc: Bool, rows: [[Any]]) -> [[Any]] {
            let sortedRows = rows.sorted { (firstRow: [Any], secondRow: [Any])
            -> Bool in
            let firstRowValue = firstRow[colIndex] as! String
            let secondRowValue = secondRow[colIndex] as! String
            if colIndex == 1 {
                //首例、姓名使用字典排序法
                if asc {
                    return firstRowValue < secondRowValue
                }
                return firstRowValue > secondRowValue
            } else if colIndex == 2 || colIndex == 3 || colIndex == 0{
                //中间两列使用数字排序
                if asc {
                    return Int(firstRowValue)! < Int(secondRowValue)!
                }
                return Int(firstRowValue)! > Int(secondRowValue)!
            }
            return true
        }
        return sortedRows
    }
   
    override func viewDidLoad() {
        super.viewDidLoad()
        database = Database()
       
    }
   
//    deinit {
//        //记得移除通知监听
//        NotificationCenter.default.removeObserver(self)
//    }
}
//多列表格组件(通过CollectionView实现)
class UICollectionGridViewController2: UICollectionViewController {
   
    var stuID:Int64?
   
    var database:Database!
    //表头数据
    var cols: [String]! = []
    //行数据
    var rows: [[Any]]! = []
     
    //排序代理
    weak var sortDelegate: UICollectionGridViewSortDelegate2?
     
    //选中的表格列(-1表示没有选中的)
    private var selectedColIdx = -1
    //列排序顺序
    private var asc = true
     
    init() {
        //初始化表格布局
        let layout = UICollectionGridViewLayout2()
        super.init(collectionViewLayout: layout)
        layout.viewController = self
        collectionView!.backgroundColor = UIColor.white
        collectionView!.register(UICollectionGridViewCell.self,
                                      forCellWithReuseIdentifier: "cell")
        collectionView!.delegate = self
        collectionView!.dataSource = self
        collectionView!.isDirectionalLockEnabled = true
        //collectionView!.contentInset = UIEdgeInsetsMake(0, 10, 0, 10)
        collectionView!.bounces = false
    }
     
    required init?(coder aDecoder: NSCoder) {
        fatalError("UICollectionGridViewController.init(coder:) has not been implemented")
    }
     
    //设置列头数据
    func setColumns(columns: [String]) {
        cols = columns
    }
     
    //添加行数据
    func addRow(row: [Any]) {
        rows.append(row)
        collectionView!.collectionViewLayout.invalidateLayout()
        collectionView!.reloadData()
    }
     
    override func viewDidLoad() {
        super.viewDidLoad()
        database = Database()
       
    }
     
    override func viewDidLayoutSubviews() {
        collectionView!.frame = CGRect(x:0, y:0,
                                       width:view.frame.width, height:view.frame.height)
    }
     
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
     
    //返回表格总行数
    override func numberOfSections(in collectionView: UICollectionView) -> Int {
            if cols.isEmpty {
                return 0
            }
            //总行数是:记录数+1个表头
            return rows.count + 1
    }
     
    //返回表格的列数
    override func collectionView(_ collectionView: UICollectionView,
                                 numberOfItemsInSection section: Int) -> Int {
        return cols.count
    }
     
    //单元格内容创建
    override func collectionView(_ collectionView: UICollectionView,
                            cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell",for: indexPath) as! UICollectionGridViewCell
         
        //设置列头单元格,内容单元格的数据
        if indexPath.section == 0 {
            cell.label.font = UIFont.systemFont(ofSize: 15, weight: UIFont.Weight.bold)
            cell.label.text = cols[indexPath.row]
            cell.label.textColor = UIColor.white
        } else {
            cell.label.font = UIFont.systemFont(ofSize: 15)
            cell.label.text = "\(rows[indexPath.section-1][indexPath.row])"
            cell.label.textColor = UIColor.black
        }
         
        //表头单元格背景色
        if indexPath.section == 0 {
            cell.backgroundColor = UIColor(red: 0x91/255, green: 0xDA/255,
                                           blue: 0x51/255, alpha: 1)
            //排序列列头显示升序降序图标
            if indexPath.row == selectedColIdx {
                let iconType = asc ? FAType.FALongArrowUp : FAType.FALongArrowDown
                cell.imageView.setFAIconWithName(icon: iconType, textColor: UIColor.white)
            }else{
                cell.imageView.image = nil
            }
        }
        //内容单元格背景色
        else {
            //排序列的单元格背景会变色
            if indexPath.row == selectedColIdx {
                //排序列的单元格背景会变色
                cell.backgroundColor = UIColor(red: 0xCC/255, green: 0xF8/255,
                                               blue: 0xFF/255, alpha: 1)
            }
            //数据区域每行单元格背景色交替显示
            else if indexPath.section % 2 == 0 {
                cell.backgroundColor = UIColor(white: 242/255.0, alpha: 1)
            } else {
                cell.backgroundColor = UIColor.white
            }
        }
         
        return cell
    }
     
    //单元格选中事件
    override func collectionView(_ collectionView: UICollectionView,
                                 didSelectItemAt indexPath: IndexPath) {
        //打印出点击单元格的[行,列]坐标
        print("点击单元格的[行,列]坐标: [\(indexPath.section),\(indexPath.row)]")
        if indexPath.section == 0 && sortDelegate != nil {
            //如果点击的是表头单元格,则默认该列升序排列,再次点击则变降序排列,以此交替
            asc = (selectedColIdx != indexPath.row) ? true : !asc
            selectedColIdx = indexPath.row
            rows = sortDelegate?.sort(colIndex: indexPath.row, asc: asc, rows: rows)
            collectionView.reloadData()
           
        }
        else{
            if(indexPath.section != 0 && indexPath.row == 0){
                let cell = collectionView.cellForItem(at: indexPath) as! UICollectionGridViewCell
                print(cell.label.text!)
               
                let course_id = Int64(cell.label.text!)!
                let course = database.readTableCourse(id: course_id)
                let appearance = SCLAlertView.SCLAppearance(
                     showCloseButton: false
                )
                let alertView = SCLAlertView(appearance: appearance)
                alertView.addButton("确定", action: {
                    if self.database.tableSCDeleteItem(student_id: self.stuID!, course_id: course!.id){
                        SCLAlertView().showSuccess("退课成功!",closeButtonTitle: "好的")
                        // 发送通知
                         //通知名称常量
//                        let name = NSNotification.Name(rawValue: "quitUpdate")
//                        NotificationCenter.default.post(name: name, object: nil)
                    }else{
                        SCLAlertView().showError("退课失败",subTitle: "您还未选这门课!",closeButtonTitle: "好的")
                    }
                })
                alertView.addButton("取消", action: {})
                alertView.showInfo("确定要退掉这门课吗?",subTitle: "课程名:\(course!.name)")
            }
        }
       
        let name = NSNotification.Name(rawValue: "quitUpdate")
        NotificationCenter.default.post(name: name, object: nil)
    }
   
}

15.学生选课

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
//
//  selectCourseViewController.swift
//  JSP-HBU
//
//  Created by 齐子佳 on 2020/5/20.
//  Copyright ? 2020 齐子佳. All rights reserved.
//

import UIKit
import SCLAlertView
//表格排序协议
protocol UICollectionGridViewSortDelegate1: class {
    func sort(colIndex: Int, asc: Bool, rows: [[Any]]) -> [[Any]]
}

class selectCourseViewController: UIViewController,UICollectionGridViewSortDelegate1 {
   
    var stuID:Int64?
   
    @IBOutlet weak var please: UILabel!
    var gridViewController: UICollectionGridViewController1!
    var database:Database!
   
    func update() -> Void{
        let courses = database.queryTableCourse()
        if courses.count == 0{
            please.isHidden = false
        }
        else{
            gridViewController = UICollectionGridViewController1()
            gridViewController.stuID = stuID
            gridViewController.sortDelegate = self
            gridViewController.setColumns(columns: ["课程编号","课程名", "课程学分", "课序号"])
            for course in courses{
                let id = String(course.id)
                gridViewController.addRow(row:[ id,course.name,course.credit,course.pno])
            }
            view.addSubview(gridViewController.view)
        }
    }
   
    func sort(colIndex: Int, asc: Bool, rows: [[Any]]) -> [[Any]] {
        let sortedRows = rows.sorted { (firstRow: [Any], secondRow: [Any])
            -> Bool in
            let firstRowValue = firstRow[colIndex] as! String
            let secondRowValue = secondRow[colIndex] as! String
            if colIndex == 1 {
                //首例、姓名使用字典排序法
                if asc {
                    return firstRowValue < secondRowValue
                }
                return firstRowValue > secondRowValue
            } else if colIndex == 2 || colIndex == 3 || colIndex == 0{
                //中间两列使用数字排序
                if asc {
                    return Int(firstRowValue)! < Int(secondRowValue)!
                }
                return Int(firstRowValue)! > Int(secondRowValue)!
            }
            return true
        }
        return sortedRows
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        database = Database()
        update()
    }
    override func viewDidAppear(_ animated: Bool) {
        update()
    }

}
//多列表格组件(通过CollectionView实现)
class UICollectionGridViewController1: UICollectionViewController {
   
    var stuID:Int64?
   
    var database:Database!
    //表头数据
    var cols: [String]! = []
    //行数据
    var rows: [[Any]]! = []
     
    //排序代理
    weak var sortDelegate: UICollectionGridViewSortDelegate1?
     
    //选中的表格列(-1表示没有选中的)
    private var selectedColIdx = -1
    //列排序顺序
    private var asc = true
     
    init() {
        //初始化表格布局
        let layout = UICollectionGridViewLayout1()
        super.init(collectionViewLayout: layout)
        layout.viewController = self
        collectionView!.backgroundColor = UIColor.white
        collectionView!.register(UICollectionGridViewCell.self,
                                      forCellWithReuseIdentifier: "cell")
        collectionView!.delegate = self
        collectionView!.dataSource = self
        collectionView!.isDirectionalLockEnabled = true
        //collectionView!.contentInset = UIEdgeInsetsMake(0, 10, 0, 10)
        collectionView!.bounces = false
    }
     
    required init?(coder aDecoder: NSCoder) {
        fatalError("UICollectionGridViewController.init(coder:) has not been implemented")
    }
     
    //设置列头数据
    func setColumns(columns: [String]) {
        cols = columns
    }
     
    //添加行数据
    func addRow(row: [Any]) {
        rows.append(row)
        collectionView!.collectionViewLayout.invalidateLayout()
        collectionView!.reloadData()
    }
     
    override func viewDidLoad() {
        super.viewDidLoad()
        database = Database()
    }
     
    override func viewDidLayoutSubviews() {
        collectionView!.frame = CGRect(x:0, y:0,
                                       width:view.frame.width, height:view.frame.height)
    }
     
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
     
    //返回表格总行数
    override func numberOfSections(in collectionView: UICollectionView) -> Int {
            if cols.isEmpty {
                return 0
            }
            //总行数是:记录数+1个表头
            return rows.count + 1
    }
     
    //返回表格的列数
    override func collectionView(_ collectionView: UICollectionView,
                                 numberOfItemsInSection section: Int) -> Int {
        return cols.count
    }
     
    //单元格内容创建
    override func collectionView(_ collectionView: UICollectionView,
                            cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell",for: indexPath) as! UICollectionGridViewCell
         
        //设置列头单元格,内容单元格的数据
        if indexPath.section == 0 {
            cell.label.font = UIFont.systemFont(ofSize: 15, weight: UIFont.Weight.bold)
            cell.label.text = cols[indexPath.row]
            cell.label.textColor = UIColor.white
        } else {
            cell.label.font = UIFont.systemFont(ofSize: 15)
            cell.label.text = "\(rows[indexPath.section-1][indexPath.row])"
            cell.label.textColor = UIColor.black
        }
         
        //表头单元格背景色
        if indexPath.section == 0 {
            cell.backgroundColor = UIColor(red: 0x91/255, green: 0xDA/255,
                                           blue: 0x51/255, alpha: 1)
            //排序列列头显示升序降序图标
            if indexPath.row == selectedColIdx {
                let iconType = asc ? FAType.FALongArrowUp : FAType.FALongArrowDown
                cell.imageView.setFAIconWithName(icon: iconType, textColor: UIColor.white)
            }else{
                cell.imageView.image = nil
            }
        }
        //内容单元格背景色
        else {
            //排序列的单元格背景会变色
            if indexPath.row == selectedColIdx {
                //排序列的单元格背景会变色
                cell.backgroundColor = UIColor(red: 0xCC/255, green: 0xF8/255,
                                               blue: 0xFF/255, alpha: 1)
            }
            //数据区域每行单元格背景色交替显示
            else if indexPath.section % 2 == 0 {
                cell.backgroundColor = UIColor(white: 242/255.0, alpha: 1)
            } else {
                cell.backgroundColor = UIColor.white
            }
        }
         
        return cell
    }
     
    //单元格选中事件
    override func collectionView(_ collectionView: UICollectionView,
                                 didSelectItemAt indexPath: IndexPath) {
        //打印出点击单元格的[行,列]坐标
        print("点击单元格的[行,列]坐标: [\(indexPath.section),\(indexPath.row)]")
        if indexPath.section == 0 && sortDelegate != nil {
            //如果点击的是表头单元格,则默认该列升序排列,再次点击则变降序排列,以此交替
            asc = (selectedColIdx != indexPath.row) ? true : !asc
            selectedColIdx = indexPath.row
            rows = sortDelegate?.sort(colIndex: indexPath.row, asc: asc, rows: rows)
            collectionView.reloadData()
           
        }
        else{
            if(indexPath.section != 0 && indexPath.row == 0){
                let cell = collectionView.cellForItem(at: indexPath) as! UICollectionGridViewCell
                print(cell.label.text!)
               
                let course_id = Int64(cell.label.text!)!
                let course = database.readTableCourse(id: course_id)
                if database.searchTableSC(course_id: course_id, student_id: stuID!){
                    SCLAlertView().showError("您已经选过此课程",subTitle:"请勿重复选择!",closeButtonTitle: "好的")
                }else{
                    if(database.tableSCInsertItem(sno: stuID!, cno: course_id, grade: -1))
                    {
                        SCLAlertView().showSuccess("选课成功!",subTitle: "课程名称:\(String(describing: course!.name))",closeButtonTitle: "好的")
                    }else{
                        SCLAlertView().showError("选课失败",subTitle: "发生未知错误!",closeButtonTitle: "好的")
                    }
                }
               
            }
        }
    }
}

以上是实现功能的核心代码,其中还有大量与页面布局有关的代码,在这里就不展示了。