Steven преди 1 година
родител
ревизия
965d32593c
променени са 57 файла, в които са добавени 3272 реда и са изтрити 239 реда
  1. 124 20
      KulexiuForTeacher/KulexiuForTeacher.xcodeproj/project.pbxproj
  2. 10 0
      KulexiuForTeacher/KulexiuForTeacher/AppDelegate.m
  3. 6 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/Contents.json
  4. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/feedback_icon.imageset/Contents.json
  5. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/feedback_icon.imageset/feedback_icon@2x.png
  6. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/feedback_icon.imageset/feedback_icon@3x.png
  7. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/mine_down.imageset/Contents.json
  8. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/mine_down.imageset/mine_down@2x.png
  9. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/mine_down.imageset/mine_down@3x.png
  10. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/sort_down.imageset/Contents.json
  11. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/sort_down.imageset/sort_down@2x.png
  12. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/sort_down.imageset/sort_down@3x.png
  13. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/sort_up_blue.imageset/Contents.json
  14. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/sort_up_blue.imageset/sort_up_blue@2x.png
  15. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/sort_up_blue.imageset/sort_up_blue@3x.png
  16. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/sort_up_grey.imageset/Contents.json
  17. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/sort_up_grey.imageset/sort_up_grey@2x.png
  18. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/sort_up_grey.imageset/sort_up_grey@3x.png
  19. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/upload_image_bg.imageset/Contents.json
  20. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/upload_image_bg.imageset/upload_image_bg@2x.png
  21. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/upload_image_bg.imageset/upload_image_bg@3x.png
  22. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/video_deleteMask.imageset/Contents.json
  23. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/video_deleteMask.imageset/video_deleteMask@2x.png
  24. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/video_deleteMask.imageset/video_deleteMask@3x.png
  25. 34 12
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.h
  26. 63 21
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.m
  27. 15 15
      KulexiuForTeacher/KulexiuForTeacher/Common/Define/KSDomain.h
  28. 2 0
      KulexiuForTeacher/KulexiuForTeacher/Common/Tools/Custom/LLPhotoBrowser/LLPhotoBrowser.h
  29. 20 14
      KulexiuForTeacher/KulexiuForTeacher/Common/Tools/Custom/LLPhotoBrowser/LLPhotoBrowser.m
  30. 16 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/Controller/FeedbackListViewController.h
  31. 302 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/Controller/FeedbackListViewController.m
  32. 2 2
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/Controller/FeedbackViewController.h
  33. 404 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/Controller/FeedbackViewController.m
  34. 41 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/Model/FeedbackListModel.h
  35. 246 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/Model/FeedbackListModel.m
  36. 31 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/CourseFileDisplayView.h
  37. 73 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/CourseFileDisplayView.m
  38. 97 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/CourseFileDisplayView.xib
  39. 11 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackBodyView.h
  40. 35 5
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackBodyView.m
  41. 111 56
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackBodyView.xib
  42. 21 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackListCell.h
  43. 187 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackListCell.m
  44. 161 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackListCell.xib
  45. 36 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackListNavView.h
  46. 71 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackListNavView.m
  47. 100 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackListNavView.xib
  48. 24 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackNavView.h
  49. 55 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackNavView.m
  50. 89 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackNavView.xib
  51. 34 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackSortView.h
  52. 285 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackSortView.m
  53. 260 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackSortView.xib
  54. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/KSSortButtonView.h
  55. 60 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/KSSortButtonView.m
  56. 70 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/KSSortButtonView.xib
  57. 0 93
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Setting/Controller/FeedbackViewController.m

+ 124 - 20
KulexiuForTeacher/KulexiuForTeacher.xcodeproj/project.pbxproj

@@ -346,10 +346,7 @@
 		27A54CE427E9B144007309A3 /* ModifyNameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 27A54CE327E9B144007309A3 /* ModifyNameViewController.m */; };
 		27A54CEC27E9B96F007309A3 /* ModifyNameBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = 27A54CEB27E9B96E007309A3 /* ModifyNameBodyView.m */; };
 		27A54CEE27E9B986007309A3 /* ModifyNameBodyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 27A54CED27E9B986007309A3 /* ModifyNameBodyView.xib */; };
-		27A54CF127E9BD3B007309A3 /* FeedbackViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 27A54CF027E9BD3B007309A3 /* FeedbackViewController.m */; };
 		27A54CF427E9BD53007309A3 /* AboutUsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 27A54CF327E9BD53007309A3 /* AboutUsViewController.m */; };
-		27A54CF727E9BD7C007309A3 /* FeedbackBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = 27A54CF627E9BD7C007309A3 /* FeedbackBodyView.m */; };
-		27A54CF927E9BD8B007309A3 /* FeedbackBodyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 27A54CF827E9BD8B007309A3 /* FeedbackBodyView.xib */; };
 		27A54CFC27E9BDB3007309A3 /* AboutUsBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = 27A54CFB27E9BDB2007309A3 /* AboutUsBodyView.m */; };
 		27A54CFE27E9BDC5007309A3 /* AboutUsBodyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 27A54CFD27E9BDC5007309A3 /* AboutUsBodyView.xib */; };
 		27A54D0427EAC891007309A3 /* TeacherInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 27A54D0227EAC890007309A3 /* TeacherInfo.m */; };
@@ -1224,6 +1221,23 @@
 		BCEA752D2819134400886A86 /* CardBindResultBodyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCEA752C2819134400886A86 /* CardBindResultBodyView.xib */; };
 		BCEA75302819336200886A86 /* WithdrawBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCEA752F2819336200886A86 /* WithdrawBodyView.m */; };
 		BCEA75322819336A00886A86 /* WithdrawBodyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCEA75312819336A00886A86 /* WithdrawBodyView.xib */; };
+		BCECE2122B3D5F0800C0D555 /* FeedbackListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCECE1F92B3D5F0800C0D555 /* FeedbackListViewController.m */; };
+		BCECE2132B3D5F0800C0D555 /* FeedbackViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCECE1FA2B3D5F0800C0D555 /* FeedbackViewController.m */; };
+		BCECE2142B3D5F0800C0D555 /* FeedbackListModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BCECE1FD2B3D5F0800C0D555 /* FeedbackListModel.m */; };
+		BCECE2152B3D5F0800C0D555 /* FeedbackBodyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCECE2022B3D5F0800C0D555 /* FeedbackBodyView.xib */; };
+		BCECE2162B3D5F0800C0D555 /* FeedbackNavView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCECE2032B3D5F0800C0D555 /* FeedbackNavView.xib */; };
+		BCECE2172B3D5F0800C0D555 /* FeedbackSortView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCECE2042B3D5F0800C0D555 /* FeedbackSortView.xib */; };
+		BCECE2182B3D5F0800C0D555 /* KSSortButtonView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCECE2062B3D5F0800C0D555 /* KSSortButtonView.xib */; };
+		BCECE2192B3D5F0800C0D555 /* FeedbackListNavView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCECE2082B3D5F0800C0D555 /* FeedbackListNavView.m */; };
+		BCECE21A2B3D5F0800C0D555 /* KSSortButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCECE20A2B3D5F0800C0D555 /* KSSortButtonView.m */; };
+		BCECE21B2B3D5F0800C0D555 /* FeedbackListCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCECE20B2B3D5F0800C0D555 /* FeedbackListCell.xib */; };
+		BCECE21C2B3D5F0800C0D555 /* FeedbackListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCECE20C2B3D5F0800C0D555 /* FeedbackListCell.m */; };
+		BCECE21D2B3D5F0800C0D555 /* FeedbackSortView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCECE20D2B3D5F0800C0D555 /* FeedbackSortView.m */; };
+		BCECE21E2B3D5F0800C0D555 /* FeedbackListNavView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCECE20E2B3D5F0800C0D555 /* FeedbackListNavView.xib */; };
+		BCECE21F2B3D5F0800C0D555 /* FeedbackBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCECE20F2B3D5F0800C0D555 /* FeedbackBodyView.m */; };
+		BCECE2202B3D5F0800C0D555 /* FeedbackNavView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCECE2102B3D5F0800C0D555 /* FeedbackNavView.m */; };
+		BCECE2242B3D648700C0D555 /* CourseFileDisplayView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCECE2222B3D648700C0D555 /* CourseFileDisplayView.xib */; };
+		BCECE2252B3D648700C0D555 /* CourseFileDisplayView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCECE2232B3D648700C0D555 /* CourseFileDisplayView.m */; };
 		BCED5CAA284F5D8D009A42DE /* FriendListModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BCED5CA9284F5D8D009A42DE /* FriendListModel.m */; };
 		BCED5CAE28507E5F009A42DE /* KSChatLiveMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = BCED5CAD28507E5F009A42DE /* KSChatLiveMessage.m */; };
 		BCED5CB128507E85009A42DE /* KSChatMusicMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = BCED5CB028507E85009A42DE /* KSChatMusicMessage.m */; };
@@ -1903,13 +1917,8 @@
 		27A54CEA27E9B96E007309A3 /* ModifyNameBodyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ModifyNameBodyView.h; sourceTree = "<group>"; };
 		27A54CEB27E9B96E007309A3 /* ModifyNameBodyView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ModifyNameBodyView.m; sourceTree = "<group>"; };
 		27A54CED27E9B986007309A3 /* ModifyNameBodyView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ModifyNameBodyView.xib; sourceTree = "<group>"; };
-		27A54CEF27E9BD3B007309A3 /* FeedbackViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FeedbackViewController.h; sourceTree = "<group>"; };
-		27A54CF027E9BD3B007309A3 /* FeedbackViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FeedbackViewController.m; sourceTree = "<group>"; };
 		27A54CF227E9BD53007309A3 /* AboutUsViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AboutUsViewController.h; sourceTree = "<group>"; };
 		27A54CF327E9BD53007309A3 /* AboutUsViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AboutUsViewController.m; sourceTree = "<group>"; };
-		27A54CF527E9BD7C007309A3 /* FeedbackBodyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FeedbackBodyView.h; sourceTree = "<group>"; };
-		27A54CF627E9BD7C007309A3 /* FeedbackBodyView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FeedbackBodyView.m; sourceTree = "<group>"; };
-		27A54CF827E9BD8B007309A3 /* FeedbackBodyView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FeedbackBodyView.xib; sourceTree = "<group>"; };
 		27A54CFA27E9BDB2007309A3 /* AboutUsBodyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AboutUsBodyView.h; sourceTree = "<group>"; };
 		27A54CFB27E9BDB2007309A3 /* AboutUsBodyView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AboutUsBodyView.m; sourceTree = "<group>"; };
 		27A54CFD27E9BDC5007309A3 /* AboutUsBodyView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AboutUsBodyView.xib; sourceTree = "<group>"; };
@@ -3340,6 +3349,33 @@
 		BCEA752E2819336200886A86 /* WithdrawBodyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WithdrawBodyView.h; sourceTree = "<group>"; };
 		BCEA752F2819336200886A86 /* WithdrawBodyView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WithdrawBodyView.m; sourceTree = "<group>"; };
 		BCEA75312819336A00886A86 /* WithdrawBodyView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WithdrawBodyView.xib; sourceTree = "<group>"; };
+		BCECE1F82B3D5F0800C0D555 /* FeedbackViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FeedbackViewController.h; sourceTree = "<group>"; };
+		BCECE1F92B3D5F0800C0D555 /* FeedbackListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FeedbackListViewController.m; sourceTree = "<group>"; };
+		BCECE1FA2B3D5F0800C0D555 /* FeedbackViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FeedbackViewController.m; sourceTree = "<group>"; };
+		BCECE1FB2B3D5F0800C0D555 /* FeedbackListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FeedbackListViewController.h; sourceTree = "<group>"; };
+		BCECE1FD2B3D5F0800C0D555 /* FeedbackListModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FeedbackListModel.m; sourceTree = "<group>"; };
+		BCECE1FE2B3D5F0800C0D555 /* FeedbackListModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FeedbackListModel.h; sourceTree = "<group>"; };
+		BCECE2002B3D5F0800C0D555 /* FeedbackListCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FeedbackListCell.h; sourceTree = "<group>"; };
+		BCECE2012B3D5F0800C0D555 /* KSSortButtonView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSSortButtonView.h; sourceTree = "<group>"; };
+		BCECE2022B3D5F0800C0D555 /* FeedbackBodyView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FeedbackBodyView.xib; sourceTree = "<group>"; };
+		BCECE2032B3D5F0800C0D555 /* FeedbackNavView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FeedbackNavView.xib; sourceTree = "<group>"; };
+		BCECE2042B3D5F0800C0D555 /* FeedbackSortView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FeedbackSortView.xib; sourceTree = "<group>"; };
+		BCECE2052B3D5F0800C0D555 /* FeedbackSortView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FeedbackSortView.h; sourceTree = "<group>"; };
+		BCECE2062B3D5F0800C0D555 /* KSSortButtonView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KSSortButtonView.xib; sourceTree = "<group>"; };
+		BCECE2072B3D5F0800C0D555 /* FeedbackBodyView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FeedbackBodyView.h; sourceTree = "<group>"; };
+		BCECE2082B3D5F0800C0D555 /* FeedbackListNavView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FeedbackListNavView.m; sourceTree = "<group>"; };
+		BCECE2092B3D5F0800C0D555 /* FeedbackNavView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FeedbackNavView.h; sourceTree = "<group>"; };
+		BCECE20A2B3D5F0800C0D555 /* KSSortButtonView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSSortButtonView.m; sourceTree = "<group>"; };
+		BCECE20B2B3D5F0800C0D555 /* FeedbackListCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FeedbackListCell.xib; sourceTree = "<group>"; };
+		BCECE20C2B3D5F0800C0D555 /* FeedbackListCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FeedbackListCell.m; sourceTree = "<group>"; };
+		BCECE20D2B3D5F0800C0D555 /* FeedbackSortView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FeedbackSortView.m; sourceTree = "<group>"; };
+		BCECE20E2B3D5F0800C0D555 /* FeedbackListNavView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FeedbackListNavView.xib; sourceTree = "<group>"; };
+		BCECE20F2B3D5F0800C0D555 /* FeedbackBodyView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FeedbackBodyView.m; sourceTree = "<group>"; };
+		BCECE2102B3D5F0800C0D555 /* FeedbackNavView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FeedbackNavView.m; sourceTree = "<group>"; };
+		BCECE2112B3D5F0800C0D555 /* FeedbackListNavView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FeedbackListNavView.h; sourceTree = "<group>"; };
+		BCECE2212B3D648700C0D555 /* CourseFileDisplayView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CourseFileDisplayView.h; sourceTree = "<group>"; };
+		BCECE2222B3D648700C0D555 /* CourseFileDisplayView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CourseFileDisplayView.xib; sourceTree = "<group>"; };
+		BCECE2232B3D648700C0D555 /* CourseFileDisplayView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CourseFileDisplayView.m; sourceTree = "<group>"; };
 		BCED5CA8284F5D8D009A42DE /* FriendListModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FriendListModel.h; sourceTree = "<group>"; };
 		BCED5CA9284F5D8D009A42DE /* FriendListModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FriendListModel.m; sourceTree = "<group>"; };
 		BCED5CAC28507E5F009A42DE /* KSChatLiveMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSChatLiveMessage.h; sourceTree = "<group>"; };
@@ -4701,6 +4737,7 @@
 		277935FE27E32BBF0010E277 /* Mine */ = {
 			isa = PBXGroup;
 			children = (
+				BCECE1F62B3D5F0800C0D555 /* Feedback */,
 				BC38C4642AFA1F4B00ABFCC2 /* Works */,
 				BC81F0DF29232BFD004106AF /* Courseware */,
 				BCB9FA502872BA6D005D766B /* LiveList */,
@@ -5027,8 +5064,6 @@
 				277D432427E9A46A00107DB7 /* ModifyPhoneCheckController.m */,
 				277D432627E9A48000107DB7 /* ModifyPhoneChangeController.h */,
 				277D432727E9A48000107DB7 /* ModifyPhoneChangeController.m */,
-				27A54CEF27E9BD3B007309A3 /* FeedbackViewController.h */,
-				27A54CF027E9BD3B007309A3 /* FeedbackViewController.m */,
 				27A54CF227E9BD53007309A3 /* AboutUsViewController.h */,
 				27A54CF327E9BD53007309A3 /* AboutUsViewController.m */,
 				BC542E3128406EA400633781 /* UserAuthViewController.h */,
@@ -5072,9 +5107,6 @@
 				277D432A27E9A50400107DB7 /* PhoneCheckBodyView.h */,
 				277D432E27E9A50800107DB7 /* PhoneCheckBodyView.m */,
 				277D432D27E9A50700107DB7 /* PhoneCheckBodyView.xib */,
-				27A54CF527E9BD7C007309A3 /* FeedbackBodyView.h */,
-				27A54CF627E9BD7C007309A3 /* FeedbackBodyView.m */,
-				27A54CF827E9BD8B007309A3 /* FeedbackBodyView.xib */,
 				27A54CFA27E9BDB2007309A3 /* AboutUsBodyView.h */,
 				27A54CFB27E9BDB2007309A3 /* AboutUsBodyView.m */,
 				27A54CFD27E9BDC5007309A3 /* AboutUsBodyView.xib */,
@@ -7986,6 +8018,64 @@
 			path = ZoomControl;
 			sourceTree = "<group>";
 		};
+		BCECE1F62B3D5F0800C0D555 /* Feedback */ = {
+			isa = PBXGroup;
+			children = (
+				BCECE1F72B3D5F0800C0D555 /* Controller */,
+				BCECE1FC2B3D5F0800C0D555 /* Model */,
+				BCECE1FF2B3D5F0800C0D555 /* View */,
+			);
+			path = Feedback;
+			sourceTree = "<group>";
+		};
+		BCECE1F72B3D5F0800C0D555 /* Controller */ = {
+			isa = PBXGroup;
+			children = (
+				BCECE1FB2B3D5F0800C0D555 /* FeedbackListViewController.h */,
+				BCECE1F92B3D5F0800C0D555 /* FeedbackListViewController.m */,
+				BCECE1F82B3D5F0800C0D555 /* FeedbackViewController.h */,
+				BCECE1FA2B3D5F0800C0D555 /* FeedbackViewController.m */,
+			);
+			path = Controller;
+			sourceTree = "<group>";
+		};
+		BCECE1FC2B3D5F0800C0D555 /* Model */ = {
+			isa = PBXGroup;
+			children = (
+				BCECE1FD2B3D5F0800C0D555 /* FeedbackListModel.m */,
+				BCECE1FE2B3D5F0800C0D555 /* FeedbackListModel.h */,
+			);
+			path = Model;
+			sourceTree = "<group>";
+		};
+		BCECE1FF2B3D5F0800C0D555 /* View */ = {
+			isa = PBXGroup;
+			children = (
+				BCECE2212B3D648700C0D555 /* CourseFileDisplayView.h */,
+				BCECE2232B3D648700C0D555 /* CourseFileDisplayView.m */,
+				BCECE2222B3D648700C0D555 /* CourseFileDisplayView.xib */,
+				BCECE2072B3D5F0800C0D555 /* FeedbackBodyView.h */,
+				BCECE20F2B3D5F0800C0D555 /* FeedbackBodyView.m */,
+				BCECE2022B3D5F0800C0D555 /* FeedbackBodyView.xib */,
+				BCECE2002B3D5F0800C0D555 /* FeedbackListCell.h */,
+				BCECE20C2B3D5F0800C0D555 /* FeedbackListCell.m */,
+				BCECE20B2B3D5F0800C0D555 /* FeedbackListCell.xib */,
+				BCECE2112B3D5F0800C0D555 /* FeedbackListNavView.h */,
+				BCECE2082B3D5F0800C0D555 /* FeedbackListNavView.m */,
+				BCECE20E2B3D5F0800C0D555 /* FeedbackListNavView.xib */,
+				BCECE2092B3D5F0800C0D555 /* FeedbackNavView.h */,
+				BCECE2102B3D5F0800C0D555 /* FeedbackNavView.m */,
+				BCECE2032B3D5F0800C0D555 /* FeedbackNavView.xib */,
+				BCECE2052B3D5F0800C0D555 /* FeedbackSortView.h */,
+				BCECE20D2B3D5F0800C0D555 /* FeedbackSortView.m */,
+				BCECE2042B3D5F0800C0D555 /* FeedbackSortView.xib */,
+				BCECE2012B3D5F0800C0D555 /* KSSortButtonView.h */,
+				BCECE20A2B3D5F0800C0D555 /* KSSortButtonView.m */,
+				BCECE2062B3D5F0800C0D555 /* KSSortButtonView.xib */,
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
 		BCED5CB5285087A9009A42DE /* ShareMusic */ = {
 			isa = PBXGroup;
 			children = (
@@ -8220,6 +8310,7 @@
 				BCC5840C28A9FA8100BAB4CF /* cloud_animation_5.png in Resources */,
 				BC8418452AC2D9FB00D8F90E /* PasswordCheckBodyView.xib in Resources */,
 				BC38C42E2AF900E100ABFCC2 /* KSPlayerSliderView.xib in Resources */,
+				BCECE2182B3D5F0800C0D555 /* KSSortButtonView.xib in Resources */,
 				BCE6A09127F823BE00C97704 /* LiveCourseCell.xib in Resources */,
 				BC3673D828A606A500059721 /* accomapny_animation_1.png in Resources */,
 				275B172B27EB269F0081FDEF /* ChatAddressHeaderView.xib in Resources */,
@@ -8248,6 +8339,7 @@
 				2779335627E316DD0010E277 /* WMPlayer.bundle in Resources */,
 				BC71DF0A2A89F470003F165E /* MainToolButton.xib in Resources */,
 				275E8A7427E18F2800DD3F6E /* Assets.xcassets in Resources */,
+				BCECE2242B3D648700C0D555 /* CourseFileDisplayView.xib in Resources */,
 				2755C06927EC71C8007D9070 /* GroupSettingBodyView.xib in Resources */,
 				BC71D1EF2887FDD40010F14B /* img_2.png in Resources */,
 				BC8B641D28F3E8D800A08D16 /* KSAwardAlertView.xib in Resources */,
@@ -8290,6 +8382,7 @@
 				BC71D2052887FDD40010F14B /* img_27.png in Resources */,
 				BC542E3828406F8000633781 /* UserAuthBodyView.xib in Resources */,
 				27A54CEE27E9B986007309A3 /* ModifyNameBodyView.xib in Resources */,
+				BCECE2172B3D5F0800C0D555 /* FeedbackSortView.xib in Resources */,
 				BC221FA128C72B9500F99802 /* MyStyleVideoView.xib in Resources */,
 				BCC583FA28A9FA8100BAB4CF /* cloud_animation_26.png in Resources */,
 				2708565E27EDA83100EC8E72 /* GroupMemberListCell.xib in Resources */,
@@ -8330,6 +8423,8 @@
 				BCF425EA2AB96BE400BCD942 /* HomeTenantView.xib in Resources */,
 				BCA353E52859797500377661 /* MusicRoomStudentCell.xib in Resources */,
 				BC9AA0F12ABC697800CD954D /* SmallPickerCell.xib in Resources */,
+				BCECE2162B3D5F0800C0D555 /* FeedbackNavView.xib in Resources */,
+				BCECE21B2B3D5F0800C0D555 /* FeedbackListCell.xib in Resources */,
 				BC31BF952B219C5700F7D538 /* ToneTuningBodyView.xib in Resources */,
 				BC31BF8C2B219C5700F7D538 /* SmallToolBodyView.xib in Resources */,
 				BC58E7DF281B96A4004B0893 /* MinePageTopView.xib in Resources */,
@@ -8448,7 +8543,6 @@
 				BC31BF902B219C5700F7D538 /* TunerSettingView.xib in Resources */,
 				BC14A60F28A0AAE80086395C /* MineFunctionView.xib in Resources */,
 				BC73A1F42809693F00FA8F6F /* EvaluateSortView.xib in Resources */,
-				27A54CF927E9BD8B007309A3 /* FeedbackBodyView.xib in Resources */,
 				BC542E4828407B4400633781 /* UseBodyView.xib in Resources */,
 				BCC5841628A9FA9D00BAB4CF /* AccompanyLoadingView.xib in Resources */,
 				BC2456EA286BEF8000D1F7C0 /* MineEmptyGroupCell.xib in Resources */,
@@ -8519,6 +8613,7 @@
 				BC2456EF286BEFC600D1F7C0 /* MineEmptyIntroduceCell.xib in Resources */,
 				BC86CB192AC2E72500450EED /* KSNewConfirmAlertView.xib in Resources */,
 				BC3673DF28A606A500059721 /* musicRoom_animation_2.png in Resources */,
+				BCECE21E2B3D5F0800C0D555 /* FeedbackListNavView.xib in Resources */,
 				BC9070A928C71C8E00237958 /* MyCreateGroupHeadView.xib in Resources */,
 				BCC583F828A9FA8100BAB4CF /* cloud_animation_23.png in Resources */,
 				2779329827E30FEB0010E277 /* mss_browseLoading@3x.png in Resources */,
@@ -8562,6 +8657,7 @@
 				BC8C2C662824EB9800FBA5D5 /* NotiferHeadView.xib in Resources */,
 				BC3673D728A606A500059721 /* live_animation_3.png in Resources */,
 				BC9AA0D02ABC3D3A00CD954D /* KSComplainImageDisplayView.xib in Resources */,
+				BCECE2152B3D5F0800C0D555 /* FeedbackBodyView.xib in Resources */,
 				BC1263AA28FF98C300509E90 /* HomeRecommendMusicView.xib in Resources */,
 				2779329A27E30FEB0010E277 /* mss_browseLoading@2x.png in Resources */,
 				BC71D2042887FDD40010F14B /* img_26.png in Resources */,
@@ -8741,6 +8837,7 @@
 				BC76146D280D571B0080FD1F /* HomeworkVideoView.m in Sources */,
 				2755C07427EC905E007D9070 /* GroupMemberModel.m in Sources */,
 				2779321D27E30FC30010E277 /* StoreButton.m in Sources */,
+				BCECE2252B3D648700C0D555 /* CourseFileDisplayView.m in Sources */,
 				277931F527E30FC20010E277 /* NSString+Extension.m in Sources */,
 				BC31BF872B219C5700F7D538 /* KSMetronomePlayer.m in Sources */,
 				277931C227E30FC20010E277 /* NSMutableDictionary+KSSafe.m in Sources */,
@@ -8771,6 +8868,7 @@
 				2779320527E30FC30010E277 /* KSAudioRecordFileManager.m in Sources */,
 				BC15534E2AB325E200C1C347 /* TenantChooseMemberViewController.m in Sources */,
 				277931C627E30FC20010E277 /* NSObject+KSImpChangeTool.m in Sources */,
+				BCECE2132B3D5F0800C0D555 /* FeedbackViewController.m in Sources */,
 				275E3DAD27F45BE90010EC30 /* KSChatroomMessageCenter.m in Sources */,
 				BC14E46E2AB2A16A000C4983 /* HomeTenantPageView.m in Sources */,
 				BC106BAD2A8F45AA000759A9 /* TXLiveRoomHeadView.m in Sources */,
@@ -9008,6 +9106,7 @@
 				BC106B8D2A8F4586000759A9 /* TXLiveMessageWelcome.m in Sources */,
 				BC245706286C434800D1F7C0 /* CoreAudioUtils.c in Sources */,
 				BC7CFFC92817F2FF00CAEB21 /* CashRecordListCell.m in Sources */,
+				BCECE2122B3D5F0800C0D555 /* FeedbackListViewController.m in Sources */,
 				BC7CFFBE2817F1D200CAEB21 /* MyBankCardViewController.m in Sources */,
 				BCA9CE1E27FD5F9D00D558C6 /* MyLiveCourseViewController.m in Sources */,
 				27D83F4227F3EAA700062476 /* MinePageVideoView.m in Sources */,
@@ -9083,10 +9182,12 @@
 				BCA353E92859A6FB00377661 /* MusicRoomHomeworkCell.m in Sources */,
 				BCEA752028190CEB00886A86 /* CardBandResultViewController.m in Sources */,
 				BC106BA92A8F45AA000759A9 /* TXLiveDownSeatView.m in Sources */,
+				BCECE21C2B3D5F0800C0D555 /* FeedbackListCell.m in Sources */,
 				BCB9FA4D28717BB2005D766B /* MyMusicSearchView.m in Sources */,
 				275B170527EB13420081FDEF /* KSChatListViewController.m in Sources */,
 				BC106B7C2A8F4586000759A9 /* TXLiveMessageSeatControl.m in Sources */,
 				277931C827E30FC20010E277 /* KSVideoEditor.m in Sources */,
+				BCECE2202B3D5F0800C0D555 /* FeedbackNavView.m in Sources */,
 				BCA193B5282A80AA004A585D /* RecentCourseModel.m in Sources */,
 				2779326B27E30FD80010E277 /* FSCalendarSeparatorDecorationView.m in Sources */,
 				BC14E47F2AB2EE58000C4983 /* UnbindBottomView.m in Sources */,
@@ -9129,7 +9230,6 @@
 				BCC305F828FD4C0800C39762 /* KSChatUserDetailViewController.m in Sources */,
 				BC0D951D2AC2868400E54D3F /* KSWebLoadRefreshView.m in Sources */,
 				BC1365C4280D44EB00EB03E2 /* NotiferMessageViewController.m in Sources */,
-				27A54CF127E9BD3B007309A3 /* FeedbackViewController.m in Sources */,
 				BC106B7B2A8F4586000759A9 /* TXLiveMessageUnBlockUser.m in Sources */,
 				BC7705FD287676D3003EFA7F /* HomeActionView.m in Sources */,
 				275E3DE127F467410010EC30 /* KSChatInputView.m in Sources */,
@@ -9149,7 +9249,6 @@
 				BC32E10C286AB31C001434DD /* KSPublicAlertView.m in Sources */,
 				BC5EB5B6280402CB00B4A3B0 /* MyStyleInstrumentCell.m in Sources */,
 				277931C527E30FC20010E277 /* NSObject+KSSwizzling.m in Sources */,
-				27A54CF727E9BD7C007309A3 /* FeedbackBodyView.m in Sources */,
 				277932BD27E30FFE0010E277 /* SDQWMaskCustomView.m in Sources */,
 				277931E027E30FC20010E277 /* UIDevice+zhDeviceType.m in Sources */,
 				BC71DEF22A89F470003F165E /* TXChatBottomView.m in Sources */,
@@ -9173,6 +9272,7 @@
 				275E3DF627F467ED0010EC30 /* KSChatroomTextCell.m in Sources */,
 				BC0A22B72847523E0065C1AB /* MemberBottomView.m in Sources */,
 				BC02BCDA28B3243F005CB483 /* LiveSeatActionView.m in Sources */,
+				BCECE21A2B3D5F0800C0D555 /* KSSortButtonView.m in Sources */,
 				2779323D27E30FC30010E277 /* VoDiskCache.m in Sources */,
 				BCDF820B2A8A2955005F8B82 /* ClassMemberSettingView.m in Sources */,
 				BC7CFFC52817F29800CAEB21 /* CashRecordViewController.m in Sources */,
@@ -9262,6 +9362,7 @@
 				2779329027E30FEB0010E277 /* MSSBrowseCollectionViewCell.m in Sources */,
 				277D432227E99EAC00107DB7 /* VeriCheckView.m in Sources */,
 				277931E927E30FC20010E277 /* pinyin.c in Sources */,
+				BCECE21D2B3D5F0800C0D555 /* FeedbackSortView.m in Sources */,
 				275FA55827F30AE300EB6240 /* VideoCourseModel.m in Sources */,
 				BC38C47C2AFA1F4B00ABFCC2 /* KSDraftMergeViewController.m in Sources */,
 				275B172927EB26920081FDEF /* ChatAddressHeaderView.m in Sources */,
@@ -9351,6 +9452,7 @@
 				2779323627E30FC30010E277 /* LLImageCache.m in Sources */,
 				277931D527E30FC20010E277 /* UIView+KSLayer.m in Sources */,
 				BC1365CF280D48B800EB03E2 /* HomeworkListModel.m in Sources */,
+				BCECE2142B3D5F0800C0D555 /* FeedbackListModel.m in Sources */,
 				BC38C42A2AF900E100ABFCC2 /* KSAudioPlayAnimationView.m in Sources */,
 				BC71DF0E2A89F470003F165E /* KSRateSliderView.m in Sources */,
 				2779326427E30FD80010E277 /* FSCalendarDelegationProxy.m in Sources */,
@@ -9442,6 +9544,7 @@
 				277931C127E30FC20010E277 /* NSDictionary+KSSafe.m in Sources */,
 				277931FF27E30FC30010E277 /* GRCreateManager.m in Sources */,
 				BC14A62428A212C50086395C /* HomeHotMusicView.m in Sources */,
+				BCECE21F2B3D5F0800C0D555 /* FeedbackBodyView.m in Sources */,
 				2779326627E30FD80010E277 /* FSCalendarCell.m in Sources */,
 				BC3ACD9A2890D88600060E97 /* IncomeRecordHeadView.m in Sources */,
 				BC0A22B92847523E0065C1AB /* ClassMemberListView.m in Sources */,
@@ -9476,6 +9579,7 @@
 				2779331D27E311A10010E277 /* KSNetworkingManager.m in Sources */,
 				BC1263AE28FF9A0300509E90 /* HomeMusicModel.m in Sources */,
 				BCDE3594289B960100A9A560 /* HomeAlbumView.m in Sources */,
+				BCECE2192B3D5F0800C0D555 /* FeedbackListNavView.m in Sources */,
 				BC245705286C434800D1F7C0 /* GCDTimer.m in Sources */,
 				2779362C27E33C2B0010E277 /* LoginBodyView.m in Sources */,
 				BC1191F3280EAB9600A716F7 /* AccompanyDetailViewController.m in Sources */,
@@ -9684,7 +9788,7 @@
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_ENTITLEMENTS = KulexiuForTeacher/KulexiuForTeacher.entitlements;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 1.5.5;
+				CURRENT_PROJECT_VERSION = 1.5.6;
 				DEVELOPMENT_TEAM = B2AP53HHTU;
 				ENABLE_BITCODE = NO;
 				ENABLE_MODULE_VERIFIER = YES;
@@ -9730,7 +9834,7 @@
 					"$(PROJECT_DIR)/KulexiuForTeacher/Common/ThirdPart/UMSocialSDK/share/share_ios_6.10.4/SocialLibraries/QQ",
 					"$(PROJECT_DIR)/KulexiuForTeacher/Common/ThirdPart/UMSocialSDK/share/share_ios_6.10.4/UMSocialSDKPlugin",
 				);
-				MARKETING_VERSION = 1.5.5;
+				MARKETING_VERSION = 1.5.6;
 				MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
 				MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17";
 				OTHER_LDFLAGS = (
@@ -9885,7 +9989,7 @@
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_ENTITLEMENTS = KulexiuForTeacher/KulexiuForTeacher.entitlements;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 1.5.5;
+				CURRENT_PROJECT_VERSION = 1.5.6;
 				DEVELOPMENT_TEAM = B2AP53HHTU;
 				ENABLE_BITCODE = NO;
 				ENABLE_MODULE_VERIFIER = YES;
@@ -9931,7 +10035,7 @@
 					"$(PROJECT_DIR)/KulexiuForTeacher/Common/ThirdPart/UMSocialSDK/share/share_ios_6.10.4/SocialLibraries/QQ",
 					"$(PROJECT_DIR)/KulexiuForTeacher/Common/ThirdPart/UMSocialSDK/share/share_ios_6.10.4/UMSocialSDKPlugin",
 				);
-				MARKETING_VERSION = 1.5.5;
+				MARKETING_VERSION = 1.5.6;
 				MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
 				MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17";
 				OTHER_LDFLAGS = (

+ 10 - 0
KulexiuForTeacher/KulexiuForTeacher/AppDelegate.m

@@ -41,6 +41,7 @@
 #import <TUICore/TUIConfig.h>
 #import <TUIChat/TUIChat.h>
 
+#import "FeedbackListViewController.h"
 
 @interface AppDelegate ()<JPUSHRegisterDelegate>
 
@@ -879,6 +880,9 @@ didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
                     [navCtrl pushViewController:ctrl animated:YES];
                 }
             }
+            else if ([pageType isEqualToString:@"feedback"]) { //反馈
+                [self toFeedback];
+            }
             else {  // 统一跳转消息列表
                 UIViewController *vc = [UIApplication sharedApplication].keyWindow.rootViewController;
                 if ([vc isKindOfClass:[UITabBarController class]]) {
@@ -916,6 +920,12 @@ didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
     }
 }
 
+- (void)toFeedback {
+    FeedbackListViewController *ctrl = [[FeedbackListViewController alloc] init];
+    CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
+    [navCtrl pushViewController:ctrl animated:YES];
+}
+
 // 统计消息数量
 - (void)countUnreadMessage {
     if ([TXIM_LINSENTER isCurrentUserLoginIM]) {

+ 6 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/feedback_icon.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "feedback_icon@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "feedback_icon@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/feedback_icon.imageset/feedback_icon@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/feedback_icon.imageset/feedback_icon@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/mine_down.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "mine_down@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "mine_down@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/mine_down.imageset/mine_down@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/mine_down.imageset/mine_down@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/sort_down.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "sort_down@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "sort_down@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/sort_down.imageset/sort_down@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/sort_down.imageset/sort_down@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/sort_up_blue.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "sort_up_blue@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "sort_up_blue@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/sort_up_blue.imageset/sort_up_blue@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/sort_up_blue.imageset/sort_up_blue@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/sort_up_grey.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "sort_up_grey@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "sort_up_grey@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/sort_up_grey.imageset/sort_up_grey@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/sort_up_grey.imageset/sort_up_grey@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/upload_image_bg.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "upload_image_bg@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "upload_image_bg@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/upload_image_bg.imageset/upload_image_bg@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/upload_image_bg.imageset/upload_image_bg@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/video_deleteMask.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "video_deleteMask@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "video_deleteMask@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/video_deleteMask.imageset/video_deleteMask@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/Feedback/video_deleteMask.imageset/video_deleteMask@3x.png


+ 34 - 12
KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.h

@@ -354,18 +354,6 @@ NS_ASSUME_NONNULL_BEGIN
 /// @param faliure 失败
 + (void)querySubjectItemRequest:(NSString *)post success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
 
-// /api-teacher/sysSuggestion/add
-/**
- 意见反馈
- 
- @param post post
- @param content 内容
- @param mobileNo 手机号
- @param success 成功
- @param faliure 失败
- */
-+ (void)suggestionAddRequest:(NSString *)post content:(NSString *)content mobileNo:(NSString *)mobileNo success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
-
 
 // /api-teacher/courseSchedule/selectRoomConfig
 
@@ -1487,5 +1475,39 @@ NS_ASSUME_NONNULL_BEGIN
 /// @param faliure 失败
 + (void)updateRemotePushInfoRequest:(NSString *)post pushDeviceId:(NSString *)pushDeviceId access_token:(NSString *)access_token success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
 
+#pragma mark --- 意见反馈
+
+// api-teacher/sysSuggestionV2/save
+/**
+ 意见反馈
+ 
+ @param post post
+ @param content 内容
+ @param attachmentUrls 附件
+ @param success 成功
+ @param faliure 失败
+ */
++ (void)suggestionAddRequest:(NSString *)post content:(NSString *)content attachmentUrls:(NSString *)attachmentUrls suggestionTypeId:(NSString *)suggestionTypeId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
+// /sysSuggestionType/page
+
+/// 查询平台反馈意见类型
+/// @param post post
+/// @param success 成功
+/// @param faliure 失败
++ (void)sysSuggestionTypeRequest:(NSString *)post success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
+// /sysSuggestionV2/page
+
+/// 反馈列表
+/// @param post post
+/// @param suggestionType 建议类型
+/// @param startTime 开始时间
+/// @param endTime 结束时间
+/// @param page page
+/// @param rows row
+/// @param success 成功
+/// @param faliure 失败
++ (void)sysSuggestionListRequest:(NSString *)post suggestionType:(NSString *)suggestionType startTime:(NSString *)startTime endTime:(NSString *)endTime page:(NSInteger)page rows:(NSInteger)rows success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
 @end
 NS_ASSUME_NONNULL_END

+ 63 - 21
KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.m

@@ -819,27 +819,6 @@
     [self request:post andWithUrl:url and:parm success:success faliure:faliure];
 }
 
-// /api-teacher/sysSuggestion/add
-/**
- 意见反馈
- 
- @param post post
- @param content 内容
- @param mobileNo 手机号
- @param success 成功
- @param faliure 失败
- */
-+ (void)suggestionAddRequest:(NSString *)post content:(NSString *)content mobileNo:(NSString *)mobileNo success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
-    [self configRequestMethodForm];
-    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
-    [parm setValue:@"iOS" forKey:@"clientType"];
-    [parm setValue:content forKey:@"content"];
-//    [parm setValue:mobileNo forKey:@"mobileNo"];
-    [parm setValue:@"APP" forKey:@"type"];
-    NSString *url = [NSString stringWithFormat:@"%@%@",hostURL, @"/api-teacher/sysSuggestion/add"];
-    [self request:post andWithUrl:url and:parm success:success faliure:faliure];
-}
-
 // /api-teacher/courseSchedule/selectRoomConfig
 
 /// 获取网络教室进入房间参数
@@ -2730,4 +2709,67 @@
     [self request:post andWithUrl:url and:parm success:success faliure:faliure];
 }
 
+#pragma mark --- 意见反馈
+
+// api-teacher/sysSuggestionV2/save
+/**
+ 意见反馈
+ 
+ @param post post
+ @param content 内容
+ @param attachmentUrls 附件
+ @param success 成功
+ @param faliure 失败
+ */
++ (void)suggestionAddRequest:(NSString *)post content:(NSString *)content attachmentUrls:(NSString *)attachmentUrls suggestionTypeId:(NSString *)suggestionTypeId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    [self configRequestMethodJSON];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:content forKey:@"content"];
+    [parm setValue:UserDefault(PHONEKEY) forKey:@"mobileNo"];
+    [parm setValue:attachmentUrls forKey:@"attachmentUrls"];
+    [parm setValue:suggestionTypeId forKey:@"suggestionTypeId"];
+    [parm setValue:@"APP" forKey:@"type"];
+
+    NSString *url = [NSString stringWithFormat:@"%@%@",hostURL, @"/api-teacher/sysSuggestionV2/save"];
+    [self request:post andWithUrl:url and:parm success:success faliure:faliure];
+}
+
+// /sysSuggestionType/page
+
+/// 查询平台反馈意见类型
+/// @param post post
+/// @param success 成功
+/// @param faliure 失败
++ (void)sysSuggestionTypeRequest:(NSString *)post success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    [self configRequestMethodJSON];
+    NSString *url = [NSString stringWithFormat:@"%@%@",hostURL, @"/api-teacher/sysSuggestionType/page"];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:@(1) forKey:@"page"];
+    [parm setValue:@(100) forKey:@"rows"];
+    [self request:post andWithUrl:url and:parm success:success faliure:faliure];
+}
+
+// /sysSuggestionV2/page
+
+/// 反馈列表
+/// @param post post
+/// @param suggestionType 建议类型
+/// @param startTime 开始时间
+/// @param endTime 结束时间
+/// @param page page
+/// @param rows row
+/// @param success 成功
+/// @param faliure 失败
++ (void)sysSuggestionListRequest:(NSString *)post suggestionType:(NSString *)suggestionType startTime:(NSString *)startTime endTime:(NSString *)endTime page:(NSInteger)page rows:(NSInteger)rows success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    [self configRequestMethodJSON];
+    NSString *url = [NSString stringWithFormat:@"%@%@",hostURL, @"/api-teacher/sysSuggestionV2/page"];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:@(page) forKey:@"page"];
+    [parm setValue:@(rows) forKey:@"rows"];
+    [parm setValue:suggestionType forKey:@"suggestionTypeId"];
+    [parm setValue:startTime forKey:@"startTime"];
+    [parm setValue:endTime forKey:@"endTime"];
+    [self request:post andWithUrl:url and:parm success:success faliure:faliure];
+}
+
 @end

+ 15 - 15
KulexiuForTeacher/KulexiuForTeacher/Common/Define/KSDomain.h

@@ -13,27 +13,27 @@
 //#ifdef DEBUG
 
 // 开发环境
-//#define hostURL (@"https://dev.colexiu.com")
-//#define SEALCLASSHOST (@"https://dev.colexiu.com/api-classroom")
-//#define WEBHOST (@"https://dev.colexiu.com/teacher")
-//#define SOCKET_URL (@"wss://dev.colexiu.com/audioAnalysis")
-//#define JSPUSH_ENVIRONMENT (NO)
-//#define RCIM_KEY (@"0vnjpoad0jbdz")
-//#define SUBMIT_UUID (NO)
-//#define CONFIG_TXSDKAPPID (1400805079)
-//#define TXOfflinePushCertificateIDForAPNS (39559)
-
-// 测试环境
-#define hostURL (@"https://test.colexiu.com")
-#define SEALCLASSHOST (@"https://test.colexiu.com/api-classroom")
-#define WEBHOST (@"https://test.colexiu.com/teacher")
-#define SOCKET_URL (@"wss://test.colexiu.com/audioAnalysis")
+#define hostURL (@"https://dev.colexiu.com")
+#define SEALCLASSHOST (@"https://dev.colexiu.com/api-classroom")
+#define WEBHOST (@"https://dev.colexiu.com/teacher")
+#define SOCKET_URL (@"wss://dev.colexiu.com/audioAnalysis")
 #define JSPUSH_ENVIRONMENT (NO)
 #define RCIM_KEY (@"0vnjpoad0jbdz")
 #define SUBMIT_UUID (NO)
 #define CONFIG_TXSDKAPPID (1400805079)
 #define TXOfflinePushCertificateIDForAPNS (39559)
 
+// 测试环境
+//#define hostURL (@"https://test.colexiu.com")
+//#define SEALCLASSHOST (@"https://test.colexiu.com/api-classroom")
+//#define WEBHOST (@"https://test.colexiu.com/teacher")
+//#define SOCKET_URL (@"wss://test.colexiu.com/audioAnalysis")
+//#define JSPUSH_ENVIRONMENT (NO)
+//#define RCIM_KEY (@"0vnjpoad0jbdz")
+//#define SUBMIT_UUID (NO)
+//#define CONFIG_TXSDKAPPID (1400805079)
+//#define TXOfflinePushCertificateIDForAPNS (39559)
+
 // 预生产
 //#define hostURL (@"https://ponline.colexiu.com")
 //#define SEALCLASSHOST (@"https://ponline.colexiu.com/api-classroom")

+ 2 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/Tools/Custom/LLPhotoBrowser/LLPhotoBrowser.h

@@ -11,6 +11,8 @@
 
 @interface LLPhotoBrowser : UIViewController
 
+@property (nonatomic, assign) BOOL hideDeleteButton;
+
 @property (nonatomic, weak) id<LLPhotoBrowserDelegate> delegate;
 
 - (instancetype)initWithImages:(NSArray *)images currentIndex:(NSInteger)currentIndex;

+ 20 - 14
KulexiuForTeacher/KulexiuForTeacher/Common/Tools/Custom/LLPhotoBrowser/LLPhotoBrowser.m

@@ -31,7 +31,9 @@
     }
     return self;
 }
-
+- (void)setHideDeleteButton:(BOOL)hideDeleteButton {
+    _hideDeleteButton = hideDeleteButton;
+}
 - (void)viewDidLoad {
     [super viewDidLoad];
     self.view.backgroundColor = [UIColor blackColor];
@@ -60,7 +62,8 @@
     
     /******自定义界面******/
     _navigationBar = [[UIView alloc] initWithFrame:CGRectZero];
-    _navigationBar.backgroundColor = HexRGBAlpha(0x14928a, .5);
+//    _navigationBar.backgroundColor = HexRGBAlpha(0x14928a, .5);
+    _navigationBar.backgroundColor = HexRGBAlpha(0x000000, 0.5f);
     _navigationBar.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleWidth;
     [self.view addSubview:_navigationBar];
     [_navigationBar mas_makeConstraints:^(MASConstraintMaker *make) {
@@ -92,16 +95,18 @@
         make.height.mas_equalTo(30);
     }];
     // 删除按钮
-    UIButton *deleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
-    [deleteButton setImage:[UIImage imageNamed:@"image_delete"] forState:UIControlStateNormal];
-    [deleteButton addTarget:self action:@selector(deleteAction) forControlEvents:UIControlEventTouchUpInside];
-    [_navigationBar addSubview:deleteButton];
-    [deleteButton mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.left.mas_equalTo(self->_navigationBar.mas_right).offset(-50);
-        make.top.mas_equalTo(backImageView.mas_centerY).offset(-15);
-        make.width.mas_equalTo(40);
-        make.height.mas_equalTo(30);
-    }];
+    if (self.hideDeleteButton == NO) {
+        UIButton *deleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
+        [deleteButton setImage:[UIImage imageNamed:@"image_delete"] forState:UIControlStateNormal];
+        [deleteButton addTarget:self action:@selector(deleteAction) forControlEvents:UIControlEventTouchUpInside];
+        [_navigationBar addSubview:deleteButton];
+        [deleteButton mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.mas_equalTo(self->_navigationBar.mas_right).offset(-50);
+            make.top.mas_equalTo(backImageView.mas_centerY).offset(-15);
+            make.width.mas_equalTo(40);
+            make.height.mas_equalTo(30);
+        }];
+    }
     
     _titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
 
@@ -118,7 +123,8 @@
     }];
     
     _tabBar = [[UIView alloc] initWithFrame:CGRectZero];
-    _tabBar.backgroundColor = HexRGBAlpha(0x14928a, .5);
+//    _tabBar.backgroundColor = HexRGBAlpha(0x14928a, .5);
+    _tabBar.backgroundColor = HexRGBAlpha(0x000000, 0.5f);
     _tabBar.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleTopMargin;
     [self.view addSubview:_tabBar];
     [_tabBar mas_makeConstraints:^(MASConstraintMaker *make) {
@@ -169,7 +175,7 @@
             self->_tabBar.transform = CGAffineTransformIdentity;
         }
         else {
-            self->_navigationBar.transform = CGAffineTransformMakeTranslation(0, -64);
+            self->_navigationBar.transform = CGAffineTransformMakeTranslation(0, -kNaviBarHeight);
             self->_tabBar.transform = CGAffineTransformMakeTranslation(0, 44);
         }
     } completion:^(BOOL finished) {

+ 16 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/Controller/FeedbackListViewController.h

@@ -0,0 +1,16 @@
+//
+//  FeedbackListViewController.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/12/25.
+//
+
+#import "KSBaseViewController.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface FeedbackListViewController : KSBaseViewController
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 302 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/Controller/FeedbackListViewController.m

@@ -0,0 +1,302 @@
+//
+//  FeedbackListViewController.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/12/25.
+//
+
+#import "FeedbackListViewController.h"
+#import "FeedbackListNavView.h"
+#import "KSNewGifRefreshFooter.h"
+#import "FeedbackSortView.h"
+#import "FeedbackListCell.h"
+#import "FeedbackListModel.h"
+#import "LLPhotoBrowser.h"
+
+@interface FeedbackListViewController ()<UITableViewDelegate, UITableViewDataSource>
+
+@property (nonatomic, strong) FeedbackListNavView *navView;
+
+@property (nonatomic, strong) UITableView *tableView;
+
+@property (nonatomic, strong) NSMutableArray *typeArray;
+
+@property (nonatomic, strong) NSMutableArray *typeNameArray;
+
+@property (nonatomic, strong) FeedbackSortView *sortView;
+
+@property (nonatomic, strong) NSString *type;
+
+@property (nonatomic, strong) NSString *startTime;
+
+@property (nonatomic, strong) NSString *endTime;
+
+
+@end
+
+@implementation FeedbackListViewController
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    [self configUI];
+    [self requestFeedbackType];
+    [self resetSourceAndRequest];
+}
+
+- (void)requestFeedbackType {
+    self.typeArray = [NSMutableArray array];
+    self.typeNameArray = [NSMutableArray array];
+    [KSNetworkingManager sysSuggestionTypeRequest:KS_POST success:^(NSDictionary * _Nonnull dic) {
+        if ([dic ks_integerValueForKey:@"code"] == 200) {
+            NSArray *source = [[dic ks_dictionaryValueForKey:@"data"] ks_arrayValueForKey:@"rows"];
+            for (NSDictionary *parm in source) {
+                [self.typeArray addObject:[parm ks_stringValueForKey:@"id"]];
+                [self.typeNameArray addObject:[parm ks_stringValueForKey:@"name"]];
+            }
+            [self.sortView configWithSource:self.typeArray typeNameArray:self.typeNameArray];
+        }
+        else {
+            
+        }
+    } faliure:^(NSError * _Nonnull error) {
+        
+    }];
+}
+
+- (void)viewWillDisappear:(BOOL)animated {
+    [super viewWillDisappear:animated];
+    if (self.navView.isSort) {
+        [self.navView changeArrow:NO];
+        [self.sortView hideSortView];
+    }
+}
+
+- (void)configUI {
+    [self.scrollView removeFromSuperview];
+    
+    self.ks_prefersNavigationBarHidden = YES;
+    [self.view addSubview:self.navView];
+    CGFloat navHeight = [FeedbackListNavView getViewHeight];
+    [self.navView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.mas_equalTo(self.view);
+        make.height.mas_equalTo(navHeight);
+    }];
+    [self.view addSubview:self.tableView];
+    [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.mas_equalTo(self.navView.mas_bottom);
+        make.left.right.bottom.mas_equalTo(self.view);
+    }];
+    MJWeakSelf;
+    self.tableView.mj_header = [KSGifRefreshHeader headerWithRefreshingBlock:^{
+        [weakSelf resetSourceAndRequest];
+    }];
+    
+    self.tableView.mj_footer = [KSNewGifRefreshFooter footerWithRefreshingBlock:^{
+        if (weakSelf.isLoadMore) {
+            weakSelf.pages += 1;
+            [weakSelf requestData];
+        }
+        else {
+            [weakSelf.tableView.mj_footer endRefreshingWithNoMoreData];
+        }
+    }];
+    self.tableView.mj_footer.ignoredScrollViewContentInsetBottom = IS_iPhoneX ? iPhoneXSafeBottomMargin : 0;
+
+}
+
+- (void)resetSourceAndRequest {
+    [self resetParamenter];
+    [self requestData];
+}
+
+- (void)resetParamenter {
+    self.pages = 1;
+    self.rows = 10;
+    self.isLoadMore = YES;
+    self.dataArray = [NSMutableArray array];
+    [self.tableView.mj_footer resetNoMoreData];
+    [self setPromptString:@"暂无内容~" imageName:@"wd_img_zwsj" inView:self.tableView];
+    [self.tableView reloadData];
+}
+
+- (void)endRefresh {
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+        [self.tableView.mj_header endRefreshing];
+        [self.tableView.mj_footer endRefreshing];
+    });
+}
+
+- (void)requestData {
+    NSString *beginTime = self.startTime;
+    NSString *endTime = self.endTime;
+    if (![NSString isEmptyString:beginTime]) {
+        beginTime = [NSString stringWithFormat:@"%@ 00:00:00", beginTime];
+    }
+    if (![NSString isEmptyString:endTime]) {
+        endTime = [NSString stringWithFormat:@"%@ 23:59:00", endTime];
+    }
+    [KSNetworkingManager sysSuggestionListRequest:KS_POST suggestionType:self.type startTime:beginTime endTime:endTime page:self.pages rows:self.rows success:^(NSDictionary * _Nonnull dic) {
+        [self endRefresh];
+        if ([dic ks_integerValueForKey:@"code"] == 200) {
+            // rows
+            NSArray *sourceArray = [[dic ks_dictionaryValueForKey:@"data"] ks_arrayValueForKey:@"rows"];
+            for (NSDictionary *parm in sourceArray) {
+                FeedbackListModel *model = [[FeedbackListModel alloc] initWithDictionary:parm];
+                [self.dataArray addObject:model];
+            }
+            if ([[dic ks_dictionaryValueForKey:@"data"] ks_boolValueForKey:@"next"] == NO) {
+                self.isLoadMore = NO;
+            }
+        }
+        else {
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
+        }
+        [self.tableView reloadData];
+        [self changePromptLabelState];
+        
+    } faliure:^(NSError * _Nonnull error) {
+        [self endRefresh];
+        if (self.networkAvaiable == NO) {
+            [self setPromptString:@"暂无网络" imageName:@"no_networking" inView:self.tableView];
+        }
+        [self.dataArray removeAllObjects];
+        [self.tableView reloadData];
+        [self changePromptLabelState];
+    }];
+}
+#pragma mark ----- table data source
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    return self.dataArray.count;
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    FeedbackListModel *model = self.dataArray[indexPath.row];
+    FeedbackListCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FeedbackListCell"];
+    MJWeakSelf;
+    [cell configWithSource:model callback:^(NSInteger imageIndex, UIImageView *imageView, NSArray *imagesArray) {
+        [weakSelf displayImage:imageIndex displayView:imageView source:imagesArray];
+    }];
+    return cell;
+}
+
+- (void)displayImage:(NSInteger)index displayView:(UIImageView *)iamgeView source:(NSArray *)imgsArray {
+    // 展示大图
+    LLPhotoBrowser *photoBrowser = [[LLPhotoBrowser alloc] initWithImages:imgsArray currentIndex:index];
+    photoBrowser.hideDeleteButton = YES;
+    photoBrowser.modalPresentationStyle = UIModalPresentationFullScreen;
+    [self presentViewController:photoBrowser animated:YES completion:nil];
+}
+
+#pragma mark ---- lazying
+- (FeedbackListNavView *)navView {
+    if (!_navView) {
+        _navView = [FeedbackListNavView shareInstance];
+        MJWeakSelf;
+        [_navView sortCallback:^(RECORDLIST type) {
+            [weakSelf sortAction:type];
+        }];
+    }
+    return _navView;
+}
+
+- (void)sortAction:(RECORDLIST)type {
+    switch (type) {
+        case RECORDLIST_BACK:
+        {
+            [self backAction];
+        }
+            break;
+        case RECORDLIST_SORT:
+        {
+            if (self.navView.isSort) {
+                [self.navView changeArrow:NO];
+                [self.sortView hideSortView];
+            }
+            else {
+                [self.navView changeArrow:YES];
+                [self.sortView showSortView];
+            }
+        }
+            break;
+        default:
+            break;
+    }
+}
+
+- (FeedbackSortView *)sortView {
+    if (!_sortView) {
+        _sortView = [FeedbackSortView shareInstance];
+        MJWeakSelf;
+        [_sortView feedbackSort:^(FEEDBACKSORT type, NSString * _Nullable sortType, NSString * _Nullable sortName, NSString * _Nullable beginTime, NSString * _Nullable endTime) {
+            [weakSelf sortAction:type sortType:sortType sortName:sortName beginTime:beginTime endTime:endTime];
+        }];
+    }
+    return _sortView;
+}
+
+- (void)sortAction:(FEEDBACKSORT)type sortType:(NSString *)sortType sortName:(NSString *)sortName
+         beginTime:(NSString *)beginTime endTime:(NSString *)endTime {
+    [self.navView changeArrow:NO];
+    switch (type) {
+        case FEEDBACKSORT_CANCEL:
+        {
+            
+        }
+            break;
+        case FEEDBACKSORT_SURE:
+        {
+            [self sortWithType:sortType startTime:beginTime endTime:endTime];
+        }
+            break;;
+        case FEEDBACKSORT_RESET:
+        {
+            
+        }
+            break;
+        default:
+            break;
+    }
+}
+
+- (void)sortWithType:(NSString *)type startTime:(NSString *)startTime endTime:(NSString *)endTime {
+    self.type = type;
+    self.startTime = startTime;
+    self.endTime = endTime;
+    [self resetSourceAndRequest];
+}
+
+
+- (UITableView *)tableView {
+    if (!_tableView) {
+        _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
+        _tableView.backgroundColor = [UIColor clearColor];
+        _tableView.delegate = self;
+        _tableView.dataSource = self;
+        _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+        _tableView.showsVerticalScrollIndicator = NO;
+        [_tableView registerNib:[UINib nibWithNibName:@"FeedbackListCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"FeedbackListCell"];
+        _tableView.estimatedRowHeight = 200.0f;
+        _tableView.rowHeight = UITableViewAutomaticDimension;
+        
+        UIView *headView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 12)];
+        headView.backgroundColor = [UIColor clearColor];
+        _tableView.tableHeaderView = headView;
+        
+        UIView *bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 15)];
+        bottomView.backgroundColor = [UIColor clearColor];
+        _tableView.tableFooterView = bottomView;
+    }
+    return _tableView;
+}
+/*
+#pragma mark - Navigation
+
+// In a storyboard-based application, you will often want to do a little preparation before navigation
+- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
+    // Get the new view controller using [segue destinationViewController].
+    // Pass the selected object to the new view controller.
+}
+*/
+
+@end

+ 2 - 2
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Setting/Controller/FeedbackViewController.h → KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/Controller/FeedbackViewController.h

@@ -1,8 +1,8 @@
 //
 //  FeedbackViewController.h
-//  KulexiuForTeacher
+//  GuanYueTeamManager
 //
-//  Created by Kyle on 2022/3/22.
+//  Created by 王智 on 2022/11/30.
 //
 
 #import "KSBaseViewController.h"

+ 404 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/Controller/FeedbackViewController.m

@@ -0,0 +1,404 @@
+//
+//  FeedbackViewController.m
+//  GuanYueTeamManager
+//
+//  Created by 王智 on 2022/11/30.
+//
+
+#import "FeedbackViewController.h"
+#import "FeedbackBodyView.h"
+#import "UserInfoManager.h"
+#import "LLPhotoBrowser.h"
+
+#import "KSMediaManager.h"
+#import "CourseFileDisplayView.h"
+#import "KSChoosePicker.h"
+
+#import "FeedbackNavView.h"
+#import "FeedbackListViewController.h"
+#import "KSUploadManager.h"
+
+#define MAXPHOTONUMBER (5)
+
+#define ROWCOUNT (IS_IPAD ? 5 : 4)
+
+@interface FeedbackViewController ()<LLPhotoBrowserDelegate>
+
+@property (nonatomic, strong) FeedbackNavView *navView;
+
+@property (nonatomic, strong) FeedbackBodyView *bodyView;
+
+@property (nonatomic, strong) KSMediaManager *mediaManager;
+
+
+@property (nonatomic, strong) NSMutableArray *imageArray;    // 图片数组
+@property (nonatomic, strong) NSMutableArray *imageAsset;    // 图片 asset
+
+@property (nonatomic, assign) NSInteger chooseIndex;
+
+@property (nonatomic, strong) NSString *feedbackType;
+
+@property (nonatomic, strong) NSMutableArray *typeArray;
+@property (nonatomic, strong) NSMutableArray *typeNameArray;
+
+@property (nonatomic, strong) KSChoosePicker *picker;
+
+@end
+
+@implementation FeedbackViewController
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    [self allocTitle:@"意见反馈"];
+    [self configUI];
+    [self requestData];
+    [self requestFeedbackType];
+}
+
+- (void)configUI {
+    self.ks_prefersNavigationBarHidden = YES;
+    [self.view addSubview:self.navView];
+    CGFloat navHeight = [FeedbackNavView getViewHeight];
+    [self.navView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.mas_equalTo(self.view);
+        make.height.mas_equalTo(navHeight);
+    }];
+    [self.scrollView mas_remakeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.mas_equalTo(self.view);
+        make.top.mas_equalTo(self.navView.mas_bottom);
+        make.bottom.mas_equalTo(self.view.mas_bottom);
+    }];
+    
+    self.bodyView = [FeedbackBodyView shareInstance];
+    [self.scrollView addSubview:self.bodyView];
+    CGFloat height = kScreenHeight - navHeight - iPhoneXSafeBottomMargin > 530 ?  kScreenHeight - navHeight - iPhoneXSafeBottomMargin : 530;
+    [self.bodyView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.mas_equalTo(self.scrollView.mas_top);
+        make.right.left.mas_equalTo(self.view);
+        make.height.mas_equalTo(height);
+    }];
+    KSWeakSelf(weakSelf);
+    [self.bodyView submitActionCallback:^(NSString *submitStr, NSString *contactStr) {
+        // 提交
+        NSString *phone = USER_MANAGER.userInfo.phone;
+        if (![NSString isEmptyString:contactStr]) {
+            phone = contactStr;
+        }
+        [weakSelf submitWithPhone:phone suggestion:submitStr];
+    }];
+    [self.scrollView setContentSize:CGSizeMake(kScreenWidth, height)];
+    [self createImageButtonAndPhotosButton];
+    
+    [self.bodyView chooseTypeCallback:^{
+        [weakSelf showPicker];
+    }];
+}
+
+- (void)showPicker {
+    MJWeakSelf;
+    self.picker = [[KSChoosePicker alloc] initWithTitle:@"" sourceData:self.typeNameArray lastChooseIndex:self.chooseIndex chooseReturnWithBlock:^(NSString * _Nonnull returnValue, NSInteger chooseIndex) {
+        weakSelf.chooseIndex = chooseIndex;
+        weakSelf.feedbackType = self.typeArray[chooseIndex];
+        [weakSelf.bodyView configFeedbackType:returnValue];
+    } cancel:^{
+        
+    }];
+    [self.picker showPicker];
+}
+
+- (void)requestFeedbackType {
+    self.typeArray = [NSMutableArray array];
+    self.typeNameArray = [NSMutableArray array];
+    [KSNetworkingManager sysSuggestionTypeRequest:KS_POST success:^(NSDictionary * _Nonnull dic) {
+        if ([dic ks_integerValueForKey:@"code"] == 200) {
+            NSArray *source = [[dic ks_dictionaryValueForKey:@"data"] ks_arrayValueForKey:@"rows"];
+            for (NSDictionary *parm in source) {
+                [self.typeArray addObject:[parm ks_stringValueForKey:@"id"]];
+                [self.typeNameArray addObject:[parm ks_stringValueForKey:@"name"]];
+            }
+        }
+        else {
+            
+        }
+    } faliure:^(NSError * _Nonnull error) {
+        
+    }];
+}
+
+- (void)requestData {
+    [KSNetworkingManager queryConfigRequest:KS_POST success:^(NSDictionary * _Nonnull dic) {
+        if ([dic ks_integerValueForKey:@"code"] == 200) {
+            NSDictionary *result = [dic ks_dictionaryValueForKey:@"data"];
+            NSString *phone = [result ks_stringValueForKey:@"customerServicePhone"];
+            NSString *email = [result ks_stringValueForKey:@"customerServiceEmail"];
+            [self.bodyView configWithPhone:phone email:email];
+        }
+        else {
+            
+        }
+    } faliure:^(NSError * _Nonnull error) {
+        
+    }];
+    
+}
+
+- (void)submitWithPhone:(NSString *)phone suggestion:(NSString *)suggession {
+    
+    if ([NSString isEmptyString:self.feedbackType]) {
+        [LOADING_MANAGER MBShowAUTOHidingInWindow:@"请选择反馈类型"];
+        return;
+    }
+    [LOADING_MANAGER showCustomLoading:@"加载中..."];
+    if (self.imageArray.count) {
+        NSMutableArray *imageDataArray = [NSMutableArray array];
+        for (UIImage *image in self.imageArray) {
+            NSData *imgData = [UIImage turnsImaegDataByImage:image];
+            [imageDataArray addObject:imgData];
+        }
+        [[KSUploadManager shareInstance] configBucketName:@"klx"];
+        [[KSUploadManager shareInstance] mutilUploadImage:imageDataArray fileName:@"complainImg" successCallback:^(NSMutableArray * _Nonnull fileUrlArray) {
+            NSMutableArray *urlArray = [NSMutableArray array];
+            for (NSString *url in fileUrlArray) {
+                [urlArray addObject:url];
+            }
+            NSString *attachments = [urlArray componentsJoinedByString:@","];
+            [self uploadMessage:suggession attachment:attachments];
+        } faliure:^(NSError * _Nullable error, NSString * _Nullable descMessaeg) {
+            [LOADING_MANAGER removeCustomLoading];
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:descMessaeg];
+        }];
+    }
+    else {
+        [self uploadMessage:suggession attachment:nil];
+    }
+    
+}
+
+- (void)uploadMessage:(NSString *)suggesstion attachment:(NSString *)attachments {
+    [KSNetworkingManager suggestionAddRequest:KS_POST content:suggesstion attachmentUrls:attachments suggestionTypeId:self.feedbackType success:^(NSDictionary * _Nonnull dic) {
+        [LOADING_MANAGER removeCustomLoading];
+        if ([dic ks_integerValueForKey:@"code"] == 200) {
+            
+            [LOADING_MANAGER KSShowMsg:@"提交成功" promptCompletion:^{
+                [self.navigationController popViewControllerAnimated:YES];
+            }];
+        }
+        else {
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
+        }
+    } faliure:^(NSError * _Nonnull error) {
+        [LOADING_MANAGER removeCustomLoading];
+        
+    }];
+}
+
+#pragma mark 点击+按钮
+- (void)addImgAction:(UIButton *)sender {
+    [self.view endEditing:YES];
+    BOOL isPad = [[UIDevice currentDevice].model hasPrefix:@"iPad"];
+    UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:isPad ? UIAlertControllerStyleAlert : UIAlertControllerStyleActionSheet];
+    [alertVC addAction:[UIAlertAction actionWithTitle:@"相机拍摄" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        // 调用相机
+        [self takePhotos];
+    }]];
+    
+    [alertVC addAction:[UIAlertAction actionWithTitle:@"从手机相册选择" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        // 调用相册
+        [self pushImagePickerController];
+        
+    }]];
+    [alertVC addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
+        
+    }]];
+    alertVC.modalPresentationStyle = UIModalPresentationFullScreen;
+    [self presentViewController:alertVC animated:true completion:nil];
+}
+
+- (void)takePhotos {
+    // 调用相册
+    self.mediaManager = [[KSMediaManager alloc] init];
+    self.mediaManager.mediaType = MEDIATYPE_PHOTO;
+    self.mediaManager.maxPhotoNumber = MAXPHOTONUMBER;
+    self.mediaManager.baseCtrl = self;
+    self.mediaManager.imageArray = [self.imageArray mutableCopy];
+    self.mediaManager.imageAsset = [self.imageAsset mutableCopy];
+    self.mediaManager.needCropImage = NO;
+    MJWeakSelf;
+    [self.mediaManager noAlertCallback:^(NSString * _Nullable videoUrl, NSMutableArray * _Nullable imageArray, NSMutableArray * _Nullable imageAsset) {
+        [weakSelf displayChooseImage:imageArray imageAsset:imageAsset];
+    }];
+    [self.mediaManager takePhoto];
+}
+
+- (void)pushImagePickerController {
+    // 调用相册
+    self.mediaManager = [[KSMediaManager alloc] init];
+    self.mediaManager.mediaType = MEDIATYPE_PHOTO;
+    self.mediaManager.maxPhotoNumber = MAXPHOTONUMBER;
+    self.mediaManager.baseCtrl = self;
+    self.mediaManager.imageArray = [self.imageArray mutableCopy];
+    self.mediaManager.imageAsset = [self.imageAsset mutableCopy];
+    self.mediaManager.needCropImage = NO;
+    MJWeakSelf;
+    [self.mediaManager noAlertCallback:^(NSString * _Nullable videoUrl, NSMutableArray * _Nullable imageArray, NSMutableArray * _Nullable imageAsset) {
+        [weakSelf displayChooseImage:imageArray imageAsset:imageAsset];
+    }];
+    [self.mediaManager pushImagePickerController];
+}
+
+- (void)displayChooseImage:(NSMutableArray *)imageArray imageAsset:(NSMutableArray *)imageAsset {
+    // 添加图片
+    self.imageArray = [imageArray mutableCopy];
+    self.imageAsset = [imageAsset mutableCopy];
+    // 重新布局
+    [self createImageButtonAndPhotosButton];
+}
+
+
+- (void)deleteImageWithIndex:(NSInteger)index {
+    [self.view endEditing:YES];
+    [self.imageArray  removeObjectAtIndex:index];
+    [self.imageAsset removeObjectAtIndex:index];
+    
+    // 重新布局
+    [self createImageButtonAndPhotosButton];
+}
+
+
+
+#pragma mark -- LLPhotoBrowserDelegate
+- (void)photoBrowser:(LLPhotoBrowser *)photoBrowser backImages:(NSMutableArray *)images {
+    NSMutableArray * returnImgArray = [images mutableCopy];
+    NSMutableArray *imageArray = [NSMutableArray array];
+    NSMutableArray *imageAsset = [NSMutableArray array];
+    for (NSInteger i = 0; i < returnImgArray.count; i++) {
+        id source = returnImgArray[i];
+        for (NSInteger i = 0; i < self.imageArray.count; i++) {
+            UIImage *imagePic = self.imageArray[i];
+            if ([imagePic isEqual:source]) {
+                [imageArray addObject:imagePic];
+                [imageAsset addObject:self.imageAsset[i]];
+            }
+        }
+    }
+    self.imageArray = [imageArray mutableCopy];
+    self.imageAsset = [imageAsset mutableCopy];
+    //布局
+    [self createImageButtonAndPhotosButton];
+}
+
+
+/**
+ 图片和按钮的布局
+ */
+#pragma marl 图片和按钮布局
+- (void)createImageButtonAndPhotosButton {
+    for (UIView *subView in self.bodyView.imageContainer.subviews) {
+        [subView removeFromSuperview];
+    }
+    
+    CGFloat midSpace = 10;
+    CGFloat leftSpace = 12;
+    CGFloat buttonWidth = IS_IPAD ? 112 : (KPortraitWidth - 14 - 12 - leftSpace *2 - midSpace * 3) / 4;
+    CGFloat buttonHeight = buttonWidth;
+    NSInteger section = IS_IPAD ? 1 : self.imageArray.count / ROWCOUNT + 1;
+    
+    CGFloat currentX = 0;
+    CGFloat currentY = 0;
+    for (NSInteger i = 0; i < self.imageArray.count; i++) {
+        currentX = i % ROWCOUNT * (buttonWidth + midSpace);
+        currentY = i / ROWCOUNT * (buttonHeight + midSpace);
+        UIImage *image = self.imageArray [i];
+        CGRect frame = CGRectMake(currentX, currentY, buttonWidth, buttonHeight);
+        MJWeakSelf;
+        CourseFileDisplayView *displayView = [CourseFileDisplayView shareInstance];
+        displayView.tag = 1000+i;
+        displayView.frame = frame;
+        [displayView displayImage:image callback:^(FILETYPE fileType, BOOL isPlay, NSInteger viewIndex) {
+            if (isPlay) {
+                LLPhotoBrowser *photoBrowser = [[LLPhotoBrowser alloc] initWithImages:weakSelf.imageArray currentIndex:viewIndex];
+                photoBrowser.delegate = weakSelf;
+                photoBrowser.modalPresentationStyle = UIModalPresentationFullScreen;
+                [weakSelf presentViewController:photoBrowser animated:YES completion:nil];
+            }
+            else {
+                [weakSelf removeImage:viewIndex];
+            }
+        }];
+        [self.bodyView.imageContainer addSubview:displayView];
+    }
+    currentX = self.imageArray .count % ROWCOUNT * (buttonWidth + midSpace);
+    if (self.imageArray.count != MAXPHOTONUMBER) {
+        //计算下一个添加按钮位置
+        if (self.imageArray.count % ROWCOUNT == 0) {
+            currentY = (self.imageArray.count + 1) / ROWCOUNT * (buttonHeight + midSpace);
+        }
+        UIButton *cameraButton = [UIButton buttonWithType:UIButtonTypeCustom];
+        cameraButton.frame = CGRectMake(currentX, currentY, buttonWidth, buttonHeight);
+        [cameraButton setBackgroundImage:[UIImage imageNamed:@"upload_image_bg"] forState:UIControlStateNormal];
+        [cameraButton setBackgroundImage:[UIImage imageNamed:@"upload_image_bg"] forState:UIControlStateHighlighted];
+        [cameraButton addTarget:self action:@selector(addImgAction:) forControlEvents:UIControlEventTouchUpInside];
+        [self.bodyView.imageContainer addSubview:cameraButton];
+    }
+    
+    self.bodyView.containerHeight.constant = section * buttonHeight + (section - 1) * midSpace;
+}
+
+- (void)removeImage:(NSInteger)imageIndex {
+    [self.imageArray  removeObjectAtIndex:imageIndex];
+    [self.imageAsset removeObjectAtIndex:imageIndex];
+    [self createImageButtonAndPhotosButton];
+}
+
+
+#pragma mark - 懒加载
+- (FeedbackNavView *)navView {
+    if (!_navView) {
+        _navView = [FeedbackNavView shareInstance];
+        MJWeakSelf;
+        [_navView navCallback:^(BOOL isBack) {
+            [weakSelf navViewAction:isBack];
+        }];
+    }
+    return _navView;
+}
+
+- (void)navViewAction:(BOOL)isBack {
+    if (isBack) {
+        [self backAction];
+    }
+    else {
+        [self displayFeedbackList];
+    }
+}
+
+- (void)displayFeedbackList {
+    FeedbackListViewController *ctrl = [[FeedbackListViewController alloc] init];
+    [self.navigationController pushViewController:ctrl animated:YES];
+}
+
+- (NSMutableArray *)imageArray {
+    if (!_imageArray) {
+        _imageArray = [NSMutableArray array];
+    }
+    return _imageArray;
+}
+
+- (NSMutableArray *)imageAsset {
+    if (!_imageAsset) {
+        _imageAsset = [NSMutableArray array];
+    }
+    return _imageAsset;
+}
+/*
+#pragma mark - Navigation
+
+// In a storyboard-based application, you will often want to do a little preparation before navigation
+- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
+    // Get the new view controller using [segue destinationViewController].
+    // Pass the selected object to the new view controller.
+}
+*/
+
+@end

+ 41 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/Model/FeedbackListModel.h

@@ -0,0 +1,41 @@
+//
+//  FeedbackListModel.h
+//
+//  Created by Steven  on 2023/12/26
+//  Copyright (c) 2023 __MyCompanyName__. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+
+
+@interface FeedbackListModel : NSObject <NSCoding, NSCopying>
+
+@property (nonatomic, strong) NSString *handleAttitude;
+@property (nonatomic, strong) NSString *clientType;
+@property (nonatomic, strong) NSString *title;
+@property (nonatomic, strong) NSString *schoolId;
+@property (nonatomic, strong) NSString *nickname;
+@property (nonatomic, strong) NSString *suggestionTypeName;
+@property (nonatomic, strong) NSString *feedback;
+@property (nonatomic, strong) NSString *schoolName;
+@property (nonatomic, strong) NSString *feedbackContent;
+@property (nonatomic, assign) BOOL handleStatus;
+@property (nonatomic, strong) NSString *type;
+@property (nonatomic, strong) NSString *suggestionTypeId;
+@property (nonatomic, strong) NSString *internalBaseClassIdentifier;
+@property (nonatomic, strong) NSString *attachmentUrls;
+@property (nonatomic, strong) NSString *userAgent;
+@property (nonatomic, strong) NSString *mobileNo;
+@property (nonatomic, strong) NSString *handleBy;
+@property (nonatomic, strong) NSString *handleName;
+@property (nonatomic, strong) NSString *handleTime;
+@property (nonatomic, strong) NSString *createTime;
+@property (nonatomic, strong) NSString *content;
+@property (nonatomic, strong) NSString *userId;
+
++ (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
+- (instancetype)initWithDictionary:(NSDictionary *)dict;
+- (NSDictionary *)dictionaryRepresentation;
+
+@end

+ 246 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/Model/FeedbackListModel.m

@@ -0,0 +1,246 @@
+//
+//  FeedbackListModel.m
+//
+//  Created by Steven  on 2023/12/26
+//  Copyright (c) 2023 __MyCompanyName__. All rights reserved.
+//
+
+#import "FeedbackListModel.h"
+
+
+NSString *const kFeedbackListModelHandleAttitude = @"handleAttitude";
+NSString *const kFeedbackListModelClientType = @"clientType";
+NSString *const kFeedbackListModelTitle = @"title";
+NSString *const kFeedbackListModelSchoolId = @"schoolId";
+NSString *const kFeedbackListModelNickname = @"nickname";
+NSString *const kFeedbackListModelSuggestionTypeName = @"suggestionTypeName";
+NSString *const kFeedbackListModelFeedback = @"feedback";
+NSString *const kFeedbackListModelSchoolName = @"schoolName";
+NSString *const kFeedbackListModelFeedbackContent = @"feedbackContent";
+NSString *const kFeedbackListModelHandleStatus = @"handleStatus";
+NSString *const kFeedbackListModelType = @"type";
+NSString *const kFeedbackListModelSuggestionTypeId = @"suggestionTypeId";
+NSString *const kFeedbackListModelId = @"id";
+NSString *const kFeedbackListModelAttachmentUrls = @"attachmentUrls";
+NSString *const kFeedbackListModelUserAgent = @"userAgent";
+NSString *const kFeedbackListModelMobileNo = @"mobileNo";
+NSString *const kFeedbackListModelHandleBy = @"handleBy";
+NSString *const kFeedbackListModelHandleName = @"handleName";
+NSString *const kFeedbackListModelHandleTime = @"handleTime";
+NSString *const kFeedbackListModelCreateTime = @"createTime";
+NSString *const kFeedbackListModelContent = @"content";
+NSString *const kFeedbackListModelUserId = @"userId";
+
+
+@interface FeedbackListModel ()
+
+- (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict;
+
+@end
+
+@implementation FeedbackListModel
+
+@synthesize handleAttitude = _handleAttitude;
+@synthesize clientType = _clientType;
+@synthesize title = _title;
+@synthesize schoolId = _schoolId;
+@synthesize nickname = _nickname;
+@synthesize suggestionTypeName = _suggestionTypeName;
+@synthesize feedback = _feedback;
+@synthesize schoolName = _schoolName;
+@synthesize feedbackContent = _feedbackContent;
+@synthesize handleStatus = _handleStatus;
+@synthesize type = _type;
+@synthesize suggestionTypeId = _suggestionTypeId;
+@synthesize internalBaseClassIdentifier = _internalBaseClassIdentifier;
+@synthesize attachmentUrls = _attachmentUrls;
+@synthesize userAgent = _userAgent;
+@synthesize mobileNo = _mobileNo;
+@synthesize handleBy = _handleBy;
+@synthesize handleName = _handleName;
+@synthesize handleTime = _handleTime;
+@synthesize createTime = _createTime;
+@synthesize content = _content;
+@synthesize userId = _userId;
+
+
++ (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
+{
+    return [[self alloc] initWithDictionary:dict];
+}
+
+- (instancetype)initWithDictionary:(NSDictionary *)dict
+{
+    self = [super init];
+    
+    // This check serves to make sure that a non-NSDictionary object
+    // passed into the model class doesn't break the parsing.
+    if(self && [dict isKindOfClass:[NSDictionary class]]) {
+            self.handleAttitude = [self objectOrNilForKey:kFeedbackListModelHandleAttitude fromDictionary:dict];
+            self.clientType = [self objectOrNilForKey:kFeedbackListModelClientType fromDictionary:dict];
+            self.title = [self objectOrNilForKey:kFeedbackListModelTitle fromDictionary:dict];
+            self.schoolId = [self objectOrNilForKey:kFeedbackListModelSchoolId fromDictionary:dict];
+            self.nickname = [self objectOrNilForKey:kFeedbackListModelNickname fromDictionary:dict];
+            self.suggestionTypeName = [self objectOrNilForKey:kFeedbackListModelSuggestionTypeName fromDictionary:dict];
+            self.feedback = [self objectOrNilForKey:kFeedbackListModelFeedback fromDictionary:dict];
+            self.schoolName = [self objectOrNilForKey:kFeedbackListModelSchoolName fromDictionary:dict];
+            self.feedbackContent = [self objectOrNilForKey:kFeedbackListModelFeedbackContent fromDictionary:dict];
+            self.handleStatus = [[self objectOrNilForKey:kFeedbackListModelHandleStatus fromDictionary:dict] boolValue];
+            self.type = [self objectOrNilForKey:kFeedbackListModelType fromDictionary:dict];
+            self.suggestionTypeId = [self objectOrNilForKey:kFeedbackListModelSuggestionTypeId fromDictionary:dict];
+            self.internalBaseClassIdentifier = [self objectOrNilForKey:kFeedbackListModelId fromDictionary:dict];
+            self.attachmentUrls = [self objectOrNilForKey:kFeedbackListModelAttachmentUrls fromDictionary:dict];
+            self.userAgent = [self objectOrNilForKey:kFeedbackListModelUserAgent fromDictionary:dict];
+            self.mobileNo = [self objectOrNilForKey:kFeedbackListModelMobileNo fromDictionary:dict];
+            self.handleBy = [self objectOrNilForKey:kFeedbackListModelHandleBy fromDictionary:dict];
+            self.handleName = [self objectOrNilForKey:kFeedbackListModelHandleName fromDictionary:dict];
+            self.handleTime = [self objectOrNilForKey:kFeedbackListModelHandleTime fromDictionary:dict];
+            self.createTime = [self objectOrNilForKey:kFeedbackListModelCreateTime fromDictionary:dict];
+            self.content = [self objectOrNilForKey:kFeedbackListModelContent fromDictionary:dict];
+            self.userId = [self objectOrNilForKey:kFeedbackListModelUserId fromDictionary:dict];
+
+    }
+    
+    return self;
+    
+}
+
+- (NSDictionary *)dictionaryRepresentation
+{
+    NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
+    [mutableDict setValue:self.handleAttitude forKey:kFeedbackListModelHandleAttitude];
+    [mutableDict setValue:self.clientType forKey:kFeedbackListModelClientType];
+    [mutableDict setValue:self.title forKey:kFeedbackListModelTitle];
+    [mutableDict setValue:self.schoolId forKey:kFeedbackListModelSchoolId];
+    [mutableDict setValue:self.nickname forKey:kFeedbackListModelNickname];
+    [mutableDict setValue:self.suggestionTypeName forKey:kFeedbackListModelSuggestionTypeName];
+    [mutableDict setValue:self.feedback forKey:kFeedbackListModelFeedback];
+    [mutableDict setValue:self.schoolName forKey:kFeedbackListModelSchoolName];
+    [mutableDict setValue:self.feedbackContent forKey:kFeedbackListModelFeedbackContent];
+    [mutableDict setValue:[NSNumber numberWithBool:self.handleStatus] forKey:kFeedbackListModelHandleStatus];
+    [mutableDict setValue:self.type forKey:kFeedbackListModelType];
+    [mutableDict setValue:self.suggestionTypeId forKey:kFeedbackListModelSuggestionTypeId];
+    [mutableDict setValue:self.internalBaseClassIdentifier forKey:kFeedbackListModelId];
+    [mutableDict setValue:self.attachmentUrls forKey:kFeedbackListModelAttachmentUrls];
+    [mutableDict setValue:self.userAgent forKey:kFeedbackListModelUserAgent];
+    [mutableDict setValue:self.mobileNo forKey:kFeedbackListModelMobileNo];
+    [mutableDict setValue:self.handleBy forKey:kFeedbackListModelHandleBy];
+    [mutableDict setValue:self.handleName forKey:kFeedbackListModelHandleName];
+    [mutableDict setValue:self.handleTime forKey:kFeedbackListModelHandleTime];
+    [mutableDict setValue:self.createTime forKey:kFeedbackListModelCreateTime];
+    [mutableDict setValue:self.content forKey:kFeedbackListModelContent];
+    [mutableDict setValue:self.userId forKey:kFeedbackListModelUserId];
+
+    return [NSDictionary dictionaryWithDictionary:mutableDict];
+}
+
+- (NSString *)description 
+{
+    return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]];
+}
+
+#pragma mark - Helper Method
+- (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict
+{
+    id object = [dict objectForKey:aKey];
+    if ([object isKindOfClass:[NSNumber class]]) {
+        NSNumber *number = object;
+        object = [number stringValue];
+    }
+    return [object isEqual:[NSNull null]] ? nil : object;
+}
+
+
+#pragma mark - NSCoding Methods
+
+- (id)initWithCoder:(NSCoder *)aDecoder
+{
+    self = [super init];
+
+    self.handleAttitude = [aDecoder decodeObjectForKey:kFeedbackListModelHandleAttitude];
+    self.clientType = [aDecoder decodeObjectForKey:kFeedbackListModelClientType];
+    self.title = [aDecoder decodeObjectForKey:kFeedbackListModelTitle];
+    self.schoolId = [aDecoder decodeObjectForKey:kFeedbackListModelSchoolId];
+    self.nickname = [aDecoder decodeObjectForKey:kFeedbackListModelNickname];
+    self.suggestionTypeName = [aDecoder decodeObjectForKey:kFeedbackListModelSuggestionTypeName];
+    self.feedback = [aDecoder decodeObjectForKey:kFeedbackListModelFeedback];
+    self.schoolName = [aDecoder decodeObjectForKey:kFeedbackListModelSchoolName];
+    self.feedbackContent = [aDecoder decodeObjectForKey:kFeedbackListModelFeedbackContent];
+    self.handleStatus = [aDecoder decodeBoolForKey:kFeedbackListModelHandleStatus];
+    self.type = [aDecoder decodeObjectForKey:kFeedbackListModelType];
+    self.suggestionTypeId = [aDecoder decodeObjectForKey:kFeedbackListModelSuggestionTypeId];
+    self.internalBaseClassIdentifier = [aDecoder decodeObjectForKey:kFeedbackListModelId];
+    self.attachmentUrls = [aDecoder decodeObjectForKey:kFeedbackListModelAttachmentUrls];
+    self.userAgent = [aDecoder decodeObjectForKey:kFeedbackListModelUserAgent];
+    self.mobileNo = [aDecoder decodeObjectForKey:kFeedbackListModelMobileNo];
+    self.handleBy = [aDecoder decodeObjectForKey:kFeedbackListModelHandleBy];
+    self.handleName = [aDecoder decodeObjectForKey:kFeedbackListModelHandleName];
+    self.handleTime = [aDecoder decodeObjectForKey:kFeedbackListModelHandleTime];
+    self.createTime = [aDecoder decodeObjectForKey:kFeedbackListModelCreateTime];
+    self.content = [aDecoder decodeObjectForKey:kFeedbackListModelContent];
+    self.userId = [aDecoder decodeObjectForKey:kFeedbackListModelUserId];
+    return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder
+{
+
+    [aCoder encodeObject:_handleAttitude forKey:kFeedbackListModelHandleAttitude];
+    [aCoder encodeObject:_clientType forKey:kFeedbackListModelClientType];
+    [aCoder encodeObject:_title forKey:kFeedbackListModelTitle];
+    [aCoder encodeObject:_schoolId forKey:kFeedbackListModelSchoolId];
+    [aCoder encodeObject:_nickname forKey:kFeedbackListModelNickname];
+    [aCoder encodeObject:_suggestionTypeName forKey:kFeedbackListModelSuggestionTypeName];
+    [aCoder encodeObject:_feedback forKey:kFeedbackListModelFeedback];
+    [aCoder encodeObject:_schoolName forKey:kFeedbackListModelSchoolName];
+    [aCoder encodeObject:_feedbackContent forKey:kFeedbackListModelFeedbackContent];
+    [aCoder encodeBool:_handleStatus forKey:kFeedbackListModelHandleStatus];
+    [aCoder encodeObject:_type forKey:kFeedbackListModelType];
+    [aCoder encodeObject:_suggestionTypeId forKey:kFeedbackListModelSuggestionTypeId];
+    [aCoder encodeObject:_internalBaseClassIdentifier forKey:kFeedbackListModelId];
+    [aCoder encodeObject:_attachmentUrls forKey:kFeedbackListModelAttachmentUrls];
+    [aCoder encodeObject:_userAgent forKey:kFeedbackListModelUserAgent];
+    [aCoder encodeObject:_mobileNo forKey:kFeedbackListModelMobileNo];
+    [aCoder encodeObject:_handleBy forKey:kFeedbackListModelHandleBy];
+    [aCoder encodeObject:_handleName forKey:kFeedbackListModelHandleName];
+    [aCoder encodeObject:_handleTime forKey:kFeedbackListModelHandleTime];
+    [aCoder encodeObject:_createTime forKey:kFeedbackListModelCreateTime];
+    [aCoder encodeObject:_content forKey:kFeedbackListModelContent];
+    [aCoder encodeObject:_userId forKey:kFeedbackListModelUserId];
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+    FeedbackListModel *copy = [[FeedbackListModel alloc] init];
+    
+    if (copy) {
+
+        copy.handleAttitude = [self.handleAttitude copyWithZone:zone];
+        copy.clientType = [self.clientType copyWithZone:zone];
+        copy.title = [self.title copyWithZone:zone];
+        copy.schoolId = [self.schoolId copyWithZone:zone];
+        copy.nickname = [self.nickname copyWithZone:zone];
+        copy.suggestionTypeName = [self.suggestionTypeName copyWithZone:zone];
+        copy.feedback = [self.feedback copyWithZone:zone];
+        copy.schoolName = [self.schoolName copyWithZone:zone];
+        copy.feedbackContent = [self.feedbackContent copyWithZone:zone];
+        copy.handleStatus = self.handleStatus;
+        copy.type = [self.type copyWithZone:zone];
+        copy.suggestionTypeId = [self.suggestionTypeId copyWithZone:zone];
+        copy.internalBaseClassIdentifier = [self.internalBaseClassIdentifier copyWithZone:zone];
+        copy.attachmentUrls = [self.attachmentUrls copyWithZone:zone];
+        copy.userAgent = [self.userAgent copyWithZone:zone];
+        copy.mobileNo = [self.mobileNo copyWithZone:zone];
+        copy.handleBy = [self.handleBy copyWithZone:zone];
+        copy.handleName = [self.handleName copyWithZone:zone];
+        copy.handleTime = [self.handleTime copyWithZone:zone];
+        copy.createTime = [self.createTime copyWithZone:zone];
+        copy.content = [self.content copyWithZone:zone];
+        copy.userId = [self.userId copyWithZone:zone];
+    }
+    
+    return copy;
+}
+
+
+@end

+ 31 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/CourseFileDisplayView.h

@@ -0,0 +1,31 @@
+//
+//  CourseFileDisplayView.h
+//  GuanYueTeamTeacher
+//
+//  Created by 王智 on 2022/12/27.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(NSInteger, FILETYPE) {
+    FILETYPE_IMAGE,
+    FILETYPE_VIDEO,
+};
+
+typedef void(^FileDisplayAction)(FILETYPE fileType, BOOL isPlay, NSInteger viewIndex);
+
+@interface CourseFileDisplayView : UIView
+
+@property (nonatomic, assign) FILETYPE type;
+
++ (instancetype)shareInstance;
+
+- (void)displayImage:(UIImage *)image callback:(FileDisplayAction)callback;
+
+- (void)displayVideo:(NSString *)url displayType:(FILETYPE)type callback:(FileDisplayAction)callback;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 73 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/CourseFileDisplayView.m

@@ -0,0 +1,73 @@
+//
+//  CourseFileDisplayView.m
+//  GuanYueTeamTeacher
+//
+//  Created by 王智 on 2022/12/27.
+//
+
+#import "CourseFileDisplayView.h"
+#import "KSVideoHelper.h"
+
+@interface CourseFileDisplayView ()
+
+@property (weak, nonatomic) IBOutlet UIImageView *displayImage;
+
+@property (weak, nonatomic) IBOutlet UIButton *playButton;
+
+@property (nonatomic, copy) FileDisplayAction callback;
+
+@end
+
+@implementation CourseFileDisplayView
+
++ (instancetype)shareInstance {
+    CourseFileDisplayView *view = [[[NSBundle mainBundle] loadNibNamed:@"CourseFileDisplayView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)displayImage:(UIImage *)image callback:(FileDisplayAction)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+    self.type = FILETYPE_IMAGE;
+    self.playButton.hidden = YES;
+    self.playButton.userInteractionEnabled = NO;
+    [self.displayImage setImage:image];
+}
+
+- (void)displayVideo:(NSString *)url displayType:(FILETYPE)type callback:(FileDisplayAction)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+    self.type = type;
+    
+    self.playButton.hidden = NO;
+    self.playButton.userInteractionEnabled = YES;
+    [KSVideoHelper getVideoPreviewImageUrl:url forImageView:self.displayImage placeholder:[UIImage imageNamed:@"video_placeholder"]];
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+- (IBAction)playButtonAction:(id)sender {
+    if (self.callback) {
+        self.callback(self.type, YES, self.tag - 1000);
+    }
+}
+- (IBAction)showImageAction:(id)sender {
+    if (self.callback && self.type == FILETYPE_IMAGE) {
+        self.callback(self.type, YES, self.tag - 1000);
+    }
+}
+
+- (IBAction)deleteAction:(id)sender {
+    if (self.callback) {
+        self.callback(self.type, NO, self.tag - 1000);
+    }
+}
+
+@end

+ 97 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/CourseFileDisplayView.xib

@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="CourseFileDisplayView">
+            <rect key="frame" x="0.0" y="0.0" width="102" height="94"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="q9a-Nr-ahB">
+                    <rect key="frame" x="0.0" y="0.0" width="102" height="94"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="video_placeholder" translatesAutoresizingMaskIntoConstraints="NO" id="xr5-UI-0xn">
+                            <rect key="frame" x="0.0" y="0.0" width="102" height="94"/>
+                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <gestureRecognizers/>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="10"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                            <connections>
+                                <outletCollection property="gestureRecognizers" destination="08l-DI-tJY" appends="YES" id="blu-NO-2gt"/>
+                            </connections>
+                        </imageView>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WoC-m3-Tko">
+                            <rect key="frame" x="29" y="25" width="44" height="44"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="44" id="KY6-qT-5qD"/>
+                                <constraint firstAttribute="height" constant="44" id="aHN-9a-dS1"/>
+                            </constraints>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <state key="normal" image="playVideo_image"/>
+                            <connections>
+                                <action selector="playButtonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="guJ-98-bPr"/>
+                            </connections>
+                        </button>
+                    </subviews>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstAttribute="bottom" secondItem="xr5-UI-0xn" secondAttribute="bottom" id="5LQ-7l-ZZh"/>
+                        <constraint firstItem="xr5-UI-0xn" firstAttribute="top" secondItem="q9a-Nr-ahB" secondAttribute="top" id="8xa-jn-aHq"/>
+                        <constraint firstItem="xr5-UI-0xn" firstAttribute="leading" secondItem="q9a-Nr-ahB" secondAttribute="leading" id="DSj-1a-Gv2"/>
+                        <constraint firstItem="WoC-m3-Tko" firstAttribute="centerY" secondItem="q9a-Nr-ahB" secondAttribute="centerY" id="Tw1-jW-ebn"/>
+                        <constraint firstAttribute="trailing" secondItem="xr5-UI-0xn" secondAttribute="trailing" id="ejx-pY-vJC"/>
+                        <constraint firstItem="WoC-m3-Tko" firstAttribute="centerX" secondItem="q9a-Nr-ahB" secondAttribute="centerX" id="qvJ-Ns-14w"/>
+                    </constraints>
+                </view>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="YDM-3Q-nB3">
+                    <rect key="frame" x="76" y="2" width="24" height="24"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="24" id="T69-AF-hz4"/>
+                        <constraint firstAttribute="width" constant="24" id="hPH-AV-GRQ"/>
+                    </constraints>
+                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                    <state key="normal" image="video_deleteMask"/>
+                    <connections>
+                        <action selector="deleteAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="3Yx-Sr-dIf"/>
+                    </connections>
+                </button>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="q9a-Nr-ahB" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="0m6-Zg-Dh7"/>
+                <constraint firstItem="q9a-Nr-ahB" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="QMX-mg-LUr"/>
+                <constraint firstAttribute="trailing" secondItem="q9a-Nr-ahB" secondAttribute="trailing" id="h8u-OD-0my"/>
+                <constraint firstAttribute="trailing" secondItem="YDM-3Q-nB3" secondAttribute="trailing" constant="2" id="yVe-zy-hKN"/>
+                <constraint firstAttribute="bottom" secondItem="q9a-Nr-ahB" secondAttribute="bottom" id="yfW-V4-9pe"/>
+                <constraint firstItem="YDM-3Q-nB3" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="2" id="z9Q-on-EbS"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="displayImage" destination="xr5-UI-0xn" id="7KJ-Pm-nHY"/>
+                <outlet property="playButton" destination="WoC-m3-Tko" id="8b7-uz-Glc"/>
+            </connections>
+            <point key="canvasLocation" x="258.01526717557249" y="-86.971830985915503"/>
+        </view>
+        <tapGestureRecognizer id="08l-DI-tJY">
+            <connections>
+                <action selector="showImageAction:" destination="iN0-l3-epB" id="1cK-75-KqA"/>
+            </connections>
+        </tapGestureRecognizer>
+    </objects>
+    <resources>
+        <image name="playVideo_image" width="26" height="26"/>
+        <image name="video_deleteMask" width="18" height="18"/>
+        <image name="video_placeholder" width="103" height="72"/>
+    </resources>
+</document>

+ 11 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Setting/View/FeedbackBodyView.h → KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackBodyView.h

@@ -9,15 +9,25 @@
 
 typedef void(^SubmitAction)(NSString * _Nonnull submitStr, NSString * _Nonnull contactStr);
 
+typedef void(^ChooseFeedbackCallback)(void);
+
 NS_ASSUME_NONNULL_BEGIN
 
 @interface FeedbackBodyView : UIView
 
+@property (weak, nonatomic) IBOutlet UIView *imageContainer;
+
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *containerHeight;
+
 + (instancetype)shareInstance;
 
 - (void)submitActionCallback:(SubmitAction)action;
 
-- (void)configPhone:(NSString *)phone email:(NSString *)email;
+- (void)configWithPhone:(NSString *)phone email:(NSString *)email;
+
+- (void)chooseTypeCallback:(ChooseFeedbackCallback)callback;
+
+- (void)configFeedbackType:(NSString *)desc;
 
 @end
 

+ 35 - 5
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Setting/View/FeedbackBodyView.m → KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackBodyView.m

@@ -6,6 +6,7 @@
 //
 
 #import "FeedbackBodyView.h"
+#import "UIView+KSLayer.h"
 
 @interface FeedbackBodyView ()<UITextFieldDelegate, UITextViewDelegate>
 @property (weak, nonatomic) IBOutlet UITextView *inputText;
@@ -13,9 +14,13 @@
 @property (weak, nonatomic) IBOutlet UITextField *contactField;
 @property (weak, nonatomic) IBOutlet UILabel *wxContract;
 @property (weak, nonatomic) IBOutlet UILabel *emailContract;
+@property (weak, nonatomic) IBOutlet UIButton *sureButton;
+@property (weak, nonatomic) IBOutlet UITextField *feedbacktype;
 
 @property (nonatomic, copy) SubmitAction action;
 
+@property (nonatomic, copy) ChooseFeedbackCallback callback;
+
 @end
 
 @implementation FeedbackBodyView
@@ -24,7 +29,7 @@
     [super awakeFromNib];
     self.inputText.delegate = self;
     self.contactField.delegate = self;
-    self.contactField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"您的邮箱或手机号" attributes:@{NSForegroundColorAttributeName:HexRGB(0x777777), NSFontAttributeName:[UIFont systemFontOfSize:14.0f weight:UIFontWeightMedium]}];
+    self.contactField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"您的邮箱或手机号" attributes:@{NSForegroundColorAttributeName:HexRGB(0xAAAAAA), NSFontAttributeName:[UIFont systemFontOfSize:14.0f]}];
     
     NSString *orgEmail = UserDefaultObjectForKey(OrganizationEmailKey);
     if ([NSString isEmptyString:orgEmail]) {
@@ -36,10 +41,17 @@
     _emailContract.text = orgEmail;
 }
 
-- (void)configPhone:(NSString *)phone email:(NSString *)email {
-    if (![NSString isEmptyString:email]) {
-        self.emailContract.text = [NSString stringWithFormat:@"邮箱:%@", email];
+- (void)configWithPhone:(NSString *)phone email:(NSString *)email {
+    NSString *wxContract = [NSString stringWithFormat:@"客服电话:%@", [NSString returnNoNullStringWithString:phone]];
+    _wxContract.text = wxContract;
+
+    NSString *orgEmail = [NSString stringWithFormat:@"邮箱:%@", [NSString returnNoNullStringWithString:email]];
+    _emailContract.text = orgEmail;
+}
 
+- (void)configFeedbackType:(NSString *)desc {
+    if (![NSString isEmptyString:desc]) {
+        self.feedbacktype.text = desc;
     }
 }
 
@@ -53,17 +65,29 @@
         self.action = action;
     }
 }
+- (void)chooseTypeCallback:(ChooseFeedbackCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
 - (IBAction)submitAction:(id)sender {
     [self endEditing:YES];
     if (self.action) {
         if ([NSString isEmptyString:self.inputText.text]) {
-            [LOADING_MANAGER MBShowAUTOHidingInWindow:@"请输入反馈意见"];
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:@"请输入您的反馈意见"];
             return;
         }
         self.action(self.inputText.text, self.contactField.text);
         
     }
 }
+- (IBAction)chooseFeedbackType:(id)sender {
+    [self endEditing:YES];
+    if (self.callback) {
+        self.callback();
+    }
+}
 
 #pragma mark   ---- delegate
 
@@ -102,6 +126,12 @@
         [self endEditing:YES];
         return YES;
     }
+    
+    // 输入控制
+    NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
+    if (newString.length > 64) {
+        return NO;
+    }
     return YES;
 }
 

+ 111 - 56
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Setting/View/FeedbackBodyView.xib → KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackBodyView.xib

@@ -1,9 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina6_1" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
+        <capability name="System colors in document resources" minToolsVersion="11.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -14,128 +15,172 @@
             <autoresizingMask key="autoresizingMask"/>
             <subviews>
                 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="C3X-28-3eB">
-                    <rect key="frame" x="16" y="20" width="382" height="240"/>
+                    <rect key="frame" x="14" y="65" width="388" height="268"/>
                     <subviews>
                         <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Tc3-oC-ieM">
-                            <rect key="frame" x="10" y="0.0" width="362" height="240"/>
+                            <rect key="frame" x="10" y="0.0" width="368" height="166"/>
                             <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="166" id="sHc-QR-cFJ"/>
+                            </constraints>
                             <color key="textColor" red="0.2666666667" green="0.2666666667" blue="0.2666666667" alpha="1" colorSpace="calibratedRGB"/>
                             <fontDescription key="fontDescription" type="system" pointSize="16"/>
                             <textInputTraits key="textInputTraits" autocapitalizationType="sentences" returnKeyType="done" enablesReturnKeyAutomatically="YES"/>
                         </textView>
-                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="请输入您的反馈意见" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="42t-hr-WLQ">
-                            <rect key="frame" x="10" y="9" width="147" height="19.5"/>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="请输入您的反馈意见" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="42t-hr-WLQ">
+                            <rect key="frame" x="12" y="9" width="159.5" height="19.5"/>
                             <fontDescription key="fontDescription" type="system" pointSize="16"/>
-                            <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
+                            <color key="textColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="calibratedRGB"/>
                             <nil key="highlightedColor"/>
                         </label>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="g6h-Pf-q1h">
+                            <rect key="frame" x="12" y="176" width="364" height="74"/>
+                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="74" id="iB8-vq-9eG"/>
+                            </constraints>
+                        </view>
                     </subviews>
                     <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                     <constraints>
-                        <constraint firstAttribute="height" constant="240" id="ExQ-PF-eun"/>
                         <constraint firstAttribute="trailing" secondItem="Tc3-oC-ieM" secondAttribute="trailing" constant="10" id="MmQ-LA-gVB"/>
-                        <constraint firstItem="42t-hr-WLQ" firstAttribute="leading" secondItem="C3X-28-3eB" secondAttribute="leading" constant="10" id="U2o-c0-snm"/>
+                        <constraint firstAttribute="trailing" secondItem="g6h-Pf-q1h" secondAttribute="trailing" constant="12" id="Myu-V8-3gY"/>
+                        <constraint firstItem="42t-hr-WLQ" firstAttribute="leading" secondItem="C3X-28-3eB" secondAttribute="leading" constant="12" id="U2o-c0-snm"/>
                         <constraint firstItem="Tc3-oC-ieM" firstAttribute="leading" secondItem="C3X-28-3eB" secondAttribute="leading" constant="10" id="U4Z-69-D8m"/>
-                        <constraint firstAttribute="bottom" secondItem="Tc3-oC-ieM" secondAttribute="bottom" id="f3m-Qh-6FQ"/>
+                        <constraint firstAttribute="bottom" secondItem="g6h-Pf-q1h" secondAttribute="bottom" constant="18" id="c0f-vz-dyt"/>
+                        <constraint firstItem="g6h-Pf-q1h" firstAttribute="top" secondItem="Tc3-oC-ieM" secondAttribute="bottom" constant="10" id="cpC-HG-Mbh"/>
                         <constraint firstItem="42t-hr-WLQ" firstAttribute="top" secondItem="C3X-28-3eB" secondAttribute="top" constant="9" id="hM5-eD-z1m"/>
                         <constraint firstItem="Tc3-oC-ieM" firstAttribute="top" secondItem="C3X-28-3eB" secondAttribute="top" id="lAO-rG-eeI"/>
+                        <constraint firstItem="g6h-Pf-q1h" firstAttribute="leading" secondItem="C3X-28-3eB" secondAttribute="leading" constant="12" id="tKc-eU-Uw5"/>
                     </constraints>
                     <userDefinedRuntimeAttributes>
-                        <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
-                            <real key="value" value="1"/>
-                        </userDefinedRuntimeAttribute>
                         <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                            <real key="value" value="4"/>
-                        </userDefinedRuntimeAttribute>
-                        <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
-                            <color key="value" red="0.90196078430000004" green="0.8980392157" blue="0.8980392157" alpha="1" colorSpace="calibratedRGB"/>
+                            <real key="value" value="10"/>
                         </userDefinedRuntimeAttribute>
                     </userDefinedRuntimeAttributes>
                 </view>
                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="或通过以下方式联系我们:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="DoC-1c-3dy">
-                    <rect key="frame" x="16" y="283" width="161.5" height="17"/>
+                    <rect key="frame" x="14" y="356" width="161.5" height="17"/>
                     <fontDescription key="fontDescription" type="system" pointSize="14"/>
                     <color key="textColor" red="0.46666666670000001" green="0.46666666670000001" blue="0.46666666670000001" alpha="1" colorSpace="calibratedRGB"/>
                     <nil key="highlightedColor"/>
                 </label>
                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="h4X-Xm-3Ji">
-                    <rect key="frame" x="16" y="305" width="0.0" height="0.0"/>
+                    <rect key="frame" x="14" y="378" width="0.0" height="0.0"/>
                     <fontDescription key="fontDescription" type="system" pointSize="14"/>
                     <color key="textColor" red="0.46666666670000001" green="0.46666666670000001" blue="0.46666666670000001" alpha="1" colorSpace="calibratedRGB"/>
                     <nil key="highlightedColor"/>
                 </label>
                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ZfN-9l-0US">
-                    <rect key="frame" x="16" y="310" width="0.0" height="0.0"/>
+                    <rect key="frame" x="14" y="383" width="0.0" height="0.0"/>
                     <fontDescription key="fontDescription" type="system" pointSize="14"/>
                     <color key="textColor" red="0.46666666670000001" green="0.46666666670000001" blue="0.46666666670000001" alpha="1" colorSpace="calibratedRGB"/>
                     <nil key="highlightedColor"/>
                 </label>
-                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="T7Y-Q2-h52">
-                    <rect key="frame" x="28" y="360" width="358" height="44"/>
-                    <color key="backgroundColor" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="calibratedRGB"/>
+                <view hidden="YES" contentMode="scaleToFill" layoutMarginsFollowReadableWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xej-UK-bQu">
+                    <rect key="frame" x="14" y="343" width="388" height="0.0"/>
+                    <subviews>
+                        <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="您的邮箱或手机号" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="3kX-7o-QEP">
+                            <rect key="frame" x="10" y="0.0" width="368" height="0.0"/>
+                            <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                            <textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="numbersAndPunctuation" returnKeyType="done" enablesReturnKeyAutomatically="YES"/>
+                        </textField>
+                    </subviews>
+                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                     <constraints>
-                        <constraint firstAttribute="height" constant="44" id="Vng-I2-15J"/>
+                        <constraint firstItem="3kX-7o-QEP" firstAttribute="leading" secondItem="xej-UK-bQu" secondAttribute="leading" constant="10" id="Dfa-eF-Yuc"/>
+                        <constraint firstAttribute="trailing" secondItem="3kX-7o-QEP" secondAttribute="trailing" constant="10" id="YSc-Lq-dFW"/>
+                        <constraint firstAttribute="bottom" secondItem="3kX-7o-QEP" secondAttribute="bottom" id="d5x-CE-fFR"/>
+                        <constraint firstItem="3kX-7o-QEP" firstAttribute="top" secondItem="xej-UK-bQu" secondAttribute="top" id="eo9-g5-dF9"/>
+                        <constraint firstAttribute="height" id="zCA-w0-I46"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="4"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="P1V-KW-hig">
+                    <rect key="frame" x="25" y="433" width="364" height="44"/>
+                    <color key="backgroundColor" red="0.1764705882352941" green="0.7803921568627451" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="44" id="QWR-u8-rsc"/>
                     </constraints>
                     <fontDescription key="fontDescription" type="system" weight="medium" pointSize="18"/>
-                    <state key="normal" title="提交"/>
+                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                    <state key="normal" title="确定"/>
                     <userDefinedRuntimeAttributes>
                         <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
                             <real key="value" value="22"/>
                         </userDefinedRuntimeAttribute>
                     </userDefinedRuntimeAttributes>
                     <connections>
-                        <action selector="submitAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="Fm3-sQ-GCc"/>
+                        <action selector="submitAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="doB-jl-BMh"/>
                     </connections>
                 </button>
-                <view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xej-UK-bQu">
-                    <rect key="frame" x="16" y="270" width="382" height="0.0"/>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7dW-1z-Q7m">
+                    <rect key="frame" x="14" y="12" width="388" height="41"/>
                     <subviews>
-                        <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="您的邮箱或手机号" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="3kX-7o-QEP">
-                            <rect key="frame" x="10" y="0.0" width="362" height="0.0"/>
-                            <color key="textColor" red="0.2666666667" green="0.2666666667" blue="0.2666666667" alpha="1" colorSpace="calibratedRGB"/>
-                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
-                            <textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="numbersAndPunctuation" returnKeyType="done" enablesReturnKeyAutomatically="YES"/>
+                        <textField opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="反馈类型(必选)" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="ID8-4h-cal">
+                            <rect key="frame" x="12" y="10" width="338" height="21"/>
+                            <fontDescription key="fontDescription" type="system" pointSize="16"/>
+                            <textInputTraits key="textInputTraits"/>
                         </textField>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="mine_down" translatesAutoresizingMaskIntoConstraints="NO" id="iss-GU-vP9">
+                            <rect key="frame" x="362" y="16.5" width="13" height="8"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="13" id="LLD-2P-6WU"/>
+                                <constraint firstAttribute="height" constant="8" id="Z6v-0M-6fx"/>
+                            </constraints>
+                        </imageView>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="PDx-v5-ZHk">
+                            <rect key="frame" x="0.0" y="0.0" width="388" height="41"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="chooseFeedbackType:" destination="iN0-l3-epB" eventType="touchUpInside" id="vBD-Mm-M51"/>
+                            </connections>
+                        </button>
                     </subviews>
-                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
                     <constraints>
-                        <constraint firstItem="3kX-7o-QEP" firstAttribute="leading" secondItem="xej-UK-bQu" secondAttribute="leading" constant="10" id="Dfa-eF-Yuc"/>
-                        <constraint firstAttribute="trailing" secondItem="3kX-7o-QEP" secondAttribute="trailing" constant="10" id="YSc-Lq-dFW"/>
-                        <constraint firstAttribute="bottom" secondItem="3kX-7o-QEP" secondAttribute="bottom" id="d5x-CE-fFR"/>
-                        <constraint firstItem="3kX-7o-QEP" firstAttribute="top" secondItem="xej-UK-bQu" secondAttribute="top" id="eo9-g5-dF9"/>
-                        <constraint firstAttribute="height" id="zCA-w0-I46"/>
+                        <constraint firstItem="iss-GU-vP9" firstAttribute="centerY" secondItem="7dW-1z-Q7m" secondAttribute="centerY" id="3GX-Mf-gma"/>
+                        <constraint firstItem="iss-GU-vP9" firstAttribute="leading" secondItem="ID8-4h-cal" secondAttribute="trailing" constant="12" id="EmK-bB-d4x"/>
+                        <constraint firstItem="PDx-v5-ZHk" firstAttribute="leading" secondItem="7dW-1z-Q7m" secondAttribute="leading" id="K9a-Bz-fe7"/>
+                        <constraint firstAttribute="trailing" secondItem="iss-GU-vP9" secondAttribute="trailing" constant="13" id="L9S-fz-1DZ"/>
+                        <constraint firstAttribute="height" constant="41" id="UzF-bP-I83"/>
+                        <constraint firstItem="PDx-v5-ZHk" firstAttribute="top" secondItem="7dW-1z-Q7m" secondAttribute="top" id="Zdg-Nc-uEE"/>
+                        <constraint firstAttribute="bottom" secondItem="PDx-v5-ZHk" secondAttribute="bottom" id="Zym-Qh-Ifp"/>
+                        <constraint firstItem="ID8-4h-cal" firstAttribute="centerY" secondItem="7dW-1z-Q7m" secondAttribute="centerY" id="dAa-35-cmu"/>
+                        <constraint firstAttribute="trailing" secondItem="PDx-v5-ZHk" secondAttribute="trailing" id="ipH-rS-pd7"/>
+                        <constraint firstItem="ID8-4h-cal" firstAttribute="leading" secondItem="7dW-1z-Q7m" secondAttribute="leading" constant="12" id="kVd-JX-PJA"/>
                     </constraints>
                     <userDefinedRuntimeAttributes>
-                        <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
-                            <real key="value" value="0.5"/>
-                        </userDefinedRuntimeAttribute>
-                        <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
-                            <color key="value" red="0.90196078430000004" green="0.8980392157" blue="0.8980392157" alpha="1" colorSpace="calibratedRGB"/>
-                        </userDefinedRuntimeAttribute>
                         <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                            <real key="value" value="4"/>
+                            <real key="value" value="10"/>
                         </userDefinedRuntimeAttribute>
                     </userDefinedRuntimeAttributes>
                 </view>
             </subviews>
-            <color key="backgroundColor" red="0.96470588235294119" green="0.97254901960784312" blue="0.97647058823529409" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
             <constraints>
+                <constraint firstItem="C3X-28-3eB" firstAttribute="top" secondItem="7dW-1z-Q7m" secondAttribute="bottom" constant="12" id="0Z9-79-4tU"/>
                 <constraint firstItem="xej-UK-bQu" firstAttribute="top" secondItem="C3X-28-3eB" secondAttribute="bottom" constant="10" id="AOy-TT-LD9"/>
+                <constraint firstItem="P1V-KW-hig" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="25" id="GCp-Dm-9y5"/>
                 <constraint firstItem="xej-UK-bQu" firstAttribute="leading" secondItem="C3X-28-3eB" secondAttribute="leading" id="Him-df-kQK"/>
+                <constraint firstItem="7dW-1z-Q7m" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="12" id="KZp-dG-YWG"/>
                 <constraint firstItem="DoC-1c-3dy" firstAttribute="leading" secondItem="xej-UK-bQu" secondAttribute="leading" id="L7H-FM-5j8"/>
-                <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="h4X-Xm-3Ji" secondAttribute="trailing" constant="10" id="NLN-xp-vpf"/>
                 <constraint firstItem="DoC-1c-3dy" firstAttribute="top" secondItem="xej-UK-bQu" secondAttribute="bottom" constant="13" id="P7h-Ep-NPN"/>
-                <constraint firstItem="T7Y-Q2-h52" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="28" id="TXw-X5-Y1u"/>
-                <constraint firstAttribute="trailing" secondItem="C3X-28-3eB" secondAttribute="trailing" constant="16" id="X8w-Bf-zC7"/>
-                <constraint firstItem="T7Y-Q2-h52" firstAttribute="top" secondItem="ZfN-9l-0US" secondAttribute="bottom" constant="50" id="aAz-dB-TiZ"/>
-                <constraint firstItem="C3X-28-3eB" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="20" id="dh9-Of-IhS"/>
-                <constraint firstItem="C3X-28-3eB" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="16" id="h2u-9a-ba7"/>
-                <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="ZfN-9l-0US" secondAttribute="trailing" constant="10" id="q3n-0k-slY"/>
+                <constraint firstAttribute="trailing" secondItem="C3X-28-3eB" secondAttribute="trailing" constant="12" id="X8w-Bf-zC7"/>
+                <constraint firstAttribute="trailing" secondItem="P1V-KW-hig" secondAttribute="trailing" constant="25" id="ZAG-pD-KNE"/>
+                <constraint firstItem="7dW-1z-Q7m" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="14" id="ZFl-dN-OcC"/>
+                <constraint firstAttribute="trailing" secondItem="7dW-1z-Q7m" secondAttribute="trailing" constant="12" id="afb-Ur-4Lh"/>
+                <constraint firstItem="C3X-28-3eB" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="14" id="h2u-9a-ba7"/>
+                <constraint firstItem="P1V-KW-hig" firstAttribute="top" secondItem="ZfN-9l-0US" secondAttribute="bottom" constant="50" id="mzE-Ef-VUQ"/>
                 <constraint firstItem="h4X-Xm-3Ji" firstAttribute="top" secondItem="DoC-1c-3dy" secondAttribute="bottom" constant="5" id="rEp-T3-PWy"/>
                 <constraint firstItem="xej-UK-bQu" firstAttribute="trailing" secondItem="C3X-28-3eB" secondAttribute="trailing" id="rtR-RK-fdA"/>
                 <constraint firstItem="ZfN-9l-0US" firstAttribute="leading" secondItem="DoC-1c-3dy" secondAttribute="leading" id="sRD-xS-D9d"/>
                 <constraint firstItem="ZfN-9l-0US" firstAttribute="top" secondItem="h4X-Xm-3Ji" secondAttribute="bottom" constant="5" id="skw-3j-H4d"/>
-                <constraint firstAttribute="trailing" secondItem="T7Y-Q2-h52" secondAttribute="trailing" constant="28" id="zVF-uQ-UIv"/>
                 <constraint firstItem="h4X-Xm-3Ji" firstAttribute="leading" secondItem="DoC-1c-3dy" secondAttribute="leading" id="zsY-fs-Glh"/>
             </constraints>
             <nil key="simulatedTopBarMetrics"/>
@@ -143,12 +188,22 @@
             <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
             <connections>
                 <outlet property="contactField" destination="3kX-7o-QEP" id="KNA-rS-ptt"/>
+                <outlet property="containerHeight" destination="iB8-vq-9eG" id="McJ-Kn-gGh"/>
                 <outlet property="emailContract" destination="ZfN-9l-0US" id="Zmg-te-abb"/>
+                <outlet property="feedbacktype" destination="ID8-4h-cal" id="COl-4M-SIV"/>
+                <outlet property="imageContainer" destination="g6h-Pf-q1h" id="rI4-vW-G9e"/>
                 <outlet property="inputText" destination="Tc3-oC-ieM" id="sWS-s2-Bp8"/>
+                <outlet property="sureButton" destination="P1V-KW-hig" id="Bk8-cW-lEr"/>
                 <outlet property="tipsLabel" destination="42t-hr-WLQ" id="XoD-kY-m1K"/>
                 <outlet property="wxContract" destination="h4X-Xm-3Ji" id="zaN-Ae-5j1"/>
             </connections>
-            <point key="canvasLocation" x="132" y="58"/>
+            <point key="canvasLocation" x="131.8840579710145" y="57.589285714285708"/>
         </view>
     </objects>
+    <resources>
+        <image name="mine_down" width="13" height="8"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
 </document>

+ 21 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackListCell.h

@@ -0,0 +1,21 @@
+//
+//  FeedbackListCell.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/12/25.
+//
+
+#import <UIKit/UIKit.h>
+#import "FeedbackListModel.h"
+
+typedef void(^FeedbackCallback)(NSInteger imageIndex, UIImageView *imageView, NSArray *imagesArray);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface FeedbackListCell : UITableViewCell
+
+- (void)configWithSource:(FeedbackListModel *)model callback:(FeedbackCallback)callback;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 187 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackListCell.m

@@ -0,0 +1,187 @@
+//
+//  FeedbackListCell.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/12/25.
+//
+
+#import "FeedbackListCell.h"
+
+@interface FeedbackListCell ()
+
+@property (weak, nonatomic) IBOutlet UILabel *feedbackTypeName;
+
+@property (weak, nonatomic) IBOutlet UILabel *feedbackDesc;
+
+@property (weak, nonatomic) IBOutlet UIView *imageContainer;
+
+@property (weak, nonatomic) IBOutlet UIView *replyView;
+
+@property (weak, nonatomic) IBOutlet UILabel *replyDesc;
+
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *replyTitleHeight;
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *replyTitleTop;
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *replyBottom;
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *replyDescBottom;
+
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *imageTop;
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *imageBottom;
+
+@property (nonatomic, strong) NSMutableArray *imagesArray;
+
+@property (nonatomic, copy) FeedbackCallback callback;
+
+@property (nonatomic, strong) UIScrollView *imageScrollView;
+
+@end
+
+@implementation FeedbackListCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+    self.selectionStyle = UITableViewCellSelectionStyleNone;
+}
+
+- (void)configWithSource:(FeedbackListModel *)model callback:(FeedbackCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+    self.feedbackTypeName.text = [NSString returnNoNullStringWithString:model.suggestionTypeName];
+    // 用户反馈内容
+    NSString *userDesc = [NSString returnNoNullStringWithString:model.content];
+    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
+    [paragraphStyle setLineSpacing:4];//调整行间距
+    paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;
+    
+    NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:userDesc attributes:@{NSParagraphStyleAttributeName:paragraphStyle,NSFontAttributeName:[UIFont systemFontOfSize:14.0f],NSForegroundColorAttributeName:HexRGB(0x333333)}];
+    self.feedbackDesc.attributedText = attrStr;
+    
+    if (model.handleStatus == YES && ![NSString isEmptyString:model.feedbackContent]) {
+        self.replyView.hidden = NO;
+        NSString *replyString = model.feedbackContent;
+        NSMutableAttributedString *replyAttrStr = [[NSMutableAttributedString alloc] initWithString:replyString attributes:@{NSParagraphStyleAttributeName:paragraphStyle,NSFontAttributeName:[UIFont systemFontOfSize:14.0f],NSForegroundColorAttributeName:HexRGB(0x777777)}];
+        self.replyDesc.attributedText = replyAttrStr;
+        self.replyTitleHeight.constant = 18.0f;
+        self.replyTitleTop.constant = 6.0f;
+        self.replyBottom.constant = 6.0f;
+        self.replyDescBottom.constant = 6.0f;
+        self.imageBottom.constant = 12.0f;
+    }
+    else {
+        self.replyView.hidden = YES;
+        self.replyDesc.text = @"";
+        self.replyTitleHeight.constant = 0.0f;
+        self.replyTitleTop.constant = 0.0f;
+        self.replyBottom.constant = 0.0f;
+        self.replyDescBottom.constant = 0.0f;
+        self.imageBottom.constant = 0.0f;
+    }
+    // 处理图片
+    [self handleImage:model.attachmentUrls];
+}
+
+- (void)handleImage:(NSString *)attachmentUrls {
+    [self.imageScrollView removeAllSubViews];
+    [self.imageContainer removeAllSubViews];
+    [self.imageContainer addSubview:self.imageScrollView];
+    [self.imageScrollView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.top.bottom.mas_equalTo(self.imageContainer);
+        make.right.mas_equalTo(self.imageContainer.mas_right).offset(-12);
+    }];
+    if (![NSString isEmptyString:attachmentUrls]) {
+        self.imageTop.constant = 13.0f;
+        NSArray *urlArray = [attachmentUrls componentsSeparatedByString:@","];
+        self.imagesArray = [NSMutableArray arrayWithArray:urlArray];
+        NSInteger maxCount = IS_IPAD ? 5 : 4;
+        BOOL needShowTips = NO;
+        NSInteger totalCount = maxCount;
+        if (urlArray.count > maxCount) {
+            needShowTips = YES;
+        }
+        else {
+            totalCount = urlArray.count;
+        }
+        
+        CGFloat imageSpace = 10.0f;
+        CGFloat leftSpace = 12.0f;
+        CGFloat width = (KPortraitWidth - 13 * 2 - leftSpace * 2 - imageSpace * (maxCount - 1)) / maxCount;
+        CGFloat height = width;
+        for (NSInteger index = 0; index < urlArray.count; index++) {
+            NSString *url = urlArray[index];
+            CGFloat xSpace = leftSpace + (width + imageSpace) * index;
+            UIImageView *imageView = [[UIImageView alloc] init];
+            imageView.layer.cornerRadius = 8.0f;
+            [imageView.layer setMasksToBounds:YES];
+            imageView.contentMode = UIViewContentModeScaleAspectFill;
+            [imageView sd_setImageWithURL:[NSURL URLWithString:[url getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:@"empty_placeholder"]];
+            [self.imageScrollView addSubview:imageView];
+            [imageView mas_makeConstraints:^(MASConstraintMaker *make) {
+                make.top.bottom.mas_equalTo(self.imageContainer);
+                make.height.mas_equalTo(height);
+                make.width.mas_equalTo(width);
+                make.left.mas_equalTo(self.imageScrollView.mas_left).offset(xSpace);
+                if (index == urlArray.count - 1) {
+                    make.right.mas_equalTo(self.imageScrollView.mas_right);
+                }
+            }];
+            imageView.userInteractionEnabled = YES;
+            imageView.tag = 1000 + index;
+            UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(imageTapAction:)];
+            [imageView addGestureRecognizer:gesture];
+        }
+        
+        if (needShowTips) {
+            UIView *descView = [[UIView alloc] init];
+            descView.backgroundColor = HexRGBAlpha(0xffffff, 0.9f);
+            descView.layer.cornerRadius = 8.0f;
+            descView.layer.maskedCorners = kCALayerMaxXMinYCorner | kCALayerMaxXMaxYCorner;
+            [self.imageContainer addSubview:descView];
+            [descView mas_makeConstraints:^(MASConstraintMaker *make) {
+                make.top.bottom.mas_equalTo(self.imageContainer);
+                make.right.mas_equalTo(self.imageContainer.mas_right).offset(-12);
+                make.width.mas_equalTo(width/2.0);
+            }];
+            UILabel *tipsLabel = [[UILabel alloc] init];
+            tipsLabel.text = [NSString stringWithFormat:@"共%zd张",urlArray.count];
+            [descView addSubview:tipsLabel];
+            tipsLabel.textColor = HexRGB(0x777777);
+            tipsLabel.font = [UIFont systemFontOfSize:12.0f];
+            [descView addSubview:tipsLabel];
+            [tipsLabel mas_makeConstraints:^(MASConstraintMaker *make) {
+                make.height.mas_equalTo(17.0f);
+                make.right.mas_equalTo(descView.mas_right);
+                make.centerY.mas_equalTo(descView.mas_centerY);
+            }];
+        }
+    }
+    else {
+        self.imageTop.constant = 0.0f;
+    }
+}
+
+- (void)imageTapAction:(UITapGestureRecognizer *)gesture {
+    UIImageView *imageView = (UIImageView *)gesture.view;
+    NSInteger index = gesture.view.tag - 1000;
+    if (self.callback) {
+        self.callback(index, imageView,self.imagesArray);
+    }
+}
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
+- (UIScrollView *)imageScrollView {
+    if(!_imageScrollView) {
+        _imageScrollView = [[UIScrollView alloc] init];
+        _imageScrollView.bounces = NO;
+        _imageScrollView.backgroundColor = [UIColor clearColor];
+        _imageScrollView.showsHorizontalScrollIndicator = NO;
+        _imageScrollView.showsVerticalScrollIndicator = NO;
+    }
+    return _imageScrollView;
+}
+@end

+ 161 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackListCell.xib

@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
+        <capability name="System colors in document resources" minToolsVersion="11.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="362" id="KGk-i7-Jjw" customClass="FeedbackListCell">
+            <rect key="frame" x="0.0" y="0.0" width="402" height="362"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
+                <rect key="frame" x="0.0" y="0.0" width="402" height="362"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="OSD-YP-P2n">
+                        <rect key="frame" x="13" y="0.0" width="376" height="347"/>
+                        <subviews>
+                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="feedback_icon" translatesAutoresizingMaskIntoConstraints="NO" id="ceZ-fQ-dp3">
+                                <rect key="frame" x="13" y="15" width="14" height="14"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="14" id="gGX-rC-oKE"/>
+                                    <constraint firstAttribute="width" constant="14" id="h5M-d2-69b"/>
+                                </constraints>
+                            </imageView>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="反馈类型" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lHK-4Q-nhi">
+                                <rect key="frame" x="30" y="12" width="60" height="20"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="20" id="DXx-qx-vHJ"/>
+                                    <constraint firstAttribute="width" constant="60" id="c6W-xf-AED"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
+                                <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="体验优化" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5Xc-mR-vx1">
+                                <rect key="frame" x="100" y="12" width="264" height="20"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="20" id="pY4-XF-9bz"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
+                                <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8zO-17-5Sy">
+                                <rect key="frame" x="12" y="42" width="352" height="1"/>
+                                <color key="backgroundColor" red="0.94901960784313721" green="0.94901960784313721" blue="0.94901960784313721" alpha="1" colorSpace="calibratedRGB"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="1" id="frJ-sL-wLN"/>
+                                </constraints>
+                            </view>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="我觉得使用不流畅,我觉得使用不流畅,我觉得使用不流畅,我觉得使用不流畅,我觉得使用不流畅,我觉得使用不流畅," textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WAJ-rx-IGC">
+                                <rect key="frame" x="12" y="52" width="357" height="50.333333333333343"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                                <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="CVX-hJ-zJ1">
+                                <rect key="frame" x="0.0" y="115.33333333333334" width="376" height="113.33333333333334"/>
+                                <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                            </view>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="FLX-as-x6g">
+                                <rect key="frame" x="12" y="240.66666666666666" width="352" height="86.333333333333343"/>
+                                <subviews>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="处理结果" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VSY-ai-MXy">
+                                        <rect key="frame" x="10.000000000000004" y="6" width="53.333333333333343" height="18"/>
+                                        <constraints>
+                                            <constraint firstAttribute="height" constant="18" id="COK-E1-XFU"/>
+                                        </constraints>
+                                        <fontDescription key="fontDescription" type="system" weight="medium" pointSize="13"/>
+                                        <nil key="textColor"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="我觉得使用不流畅,我觉得使用不流畅,我觉得使用不流畅,我觉得使用不流畅,我觉得使用不流畅,我觉得使用不流畅," textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Z7E-Pa-Y3M">
+                                        <rect key="frame" x="10" y="30.000000000000032" width="335" height="50.333333333333343"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                                        <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" red="0.96470588235294119" green="0.96470588235294119" blue="0.96470588235294119" alpha="1" colorSpace="calibratedRGB"/>
+                                <constraints>
+                                    <constraint firstItem="Z7E-Pa-Y3M" firstAttribute="leading" secondItem="FLX-as-x6g" secondAttribute="leading" constant="10" id="9F4-3u-bfk"/>
+                                    <constraint firstItem="Z7E-Pa-Y3M" firstAttribute="top" secondItem="VSY-ai-MXy" secondAttribute="bottom" constant="6" id="LC5-EN-qMg"/>
+                                    <constraint firstAttribute="bottom" secondItem="Z7E-Pa-Y3M" secondAttribute="bottom" constant="6" id="QlI-uK-Nh4"/>
+                                    <constraint firstAttribute="trailing" secondItem="Z7E-Pa-Y3M" secondAttribute="trailing" constant="7" id="V0m-QO-5dr"/>
+                                    <constraint firstItem="VSY-ai-MXy" firstAttribute="top" secondItem="FLX-as-x6g" secondAttribute="top" constant="6" id="qQa-tb-6d5"/>
+                                    <constraint firstItem="VSY-ai-MXy" firstAttribute="leading" secondItem="FLX-as-x6g" secondAttribute="leading" constant="10" id="ttw-ec-SF4"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="4"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                        </subviews>
+                        <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                        <constraints>
+                            <constraint firstItem="CVX-hJ-zJ1" firstAttribute="top" secondItem="WAJ-rx-IGC" secondAttribute="bottom" constant="13" id="0Rc-Ch-wlh"/>
+                            <constraint firstItem="ceZ-fQ-dp3" firstAttribute="leading" secondItem="OSD-YP-P2n" secondAttribute="leading" constant="13" id="6py-Ix-mHK"/>
+                            <constraint firstItem="FLX-as-x6g" firstAttribute="top" secondItem="CVX-hJ-zJ1" secondAttribute="bottom" constant="12" id="8Vw-hb-K6G"/>
+                            <constraint firstAttribute="trailing" secondItem="8zO-17-5Sy" secondAttribute="trailing" constant="12" id="Lnx-Pl-vYD"/>
+                            <constraint firstAttribute="trailing" secondItem="5Xc-mR-vx1" secondAttribute="trailing" constant="12" id="McI-TV-tiG"/>
+                            <constraint firstItem="5Xc-mR-vx1" firstAttribute="top" secondItem="OSD-YP-P2n" secondAttribute="top" constant="12" id="QdY-vY-k5B"/>
+                            <constraint firstItem="ceZ-fQ-dp3" firstAttribute="top" secondItem="OSD-YP-P2n" secondAttribute="top" constant="15" id="Qmc-UU-wsQ"/>
+                            <constraint firstAttribute="trailing" secondItem="CVX-hJ-zJ1" secondAttribute="trailing" id="RMu-4D-CA3"/>
+                            <constraint firstAttribute="trailing" secondItem="FLX-as-x6g" secondAttribute="trailing" constant="12" id="SOC-GH-Ozp"/>
+                            <constraint firstItem="5Xc-mR-vx1" firstAttribute="leading" secondItem="lHK-4Q-nhi" secondAttribute="trailing" constant="10" id="TE8-As-C8p"/>
+                            <constraint firstItem="CVX-hJ-zJ1" firstAttribute="leading" secondItem="OSD-YP-P2n" secondAttribute="leading" id="TGz-Ko-cdm"/>
+                            <constraint firstItem="WAJ-rx-IGC" firstAttribute="leading" secondItem="OSD-YP-P2n" secondAttribute="leading" constant="12" id="Y5t-TR-C9Z"/>
+                            <constraint firstItem="WAJ-rx-IGC" firstAttribute="top" secondItem="8zO-17-5Sy" secondAttribute="bottom" constant="9" id="afJ-Pl-4m5"/>
+                            <constraint firstItem="lHK-4Q-nhi" firstAttribute="top" secondItem="OSD-YP-P2n" secondAttribute="top" constant="12" id="fBt-65-7B8"/>
+                            <constraint firstItem="lHK-4Q-nhi" firstAttribute="leading" secondItem="ceZ-fQ-dp3" secondAttribute="trailing" constant="3" id="fSH-MJ-6ud"/>
+                            <constraint firstItem="FLX-as-x6g" firstAttribute="leading" secondItem="OSD-YP-P2n" secondAttribute="leading" constant="12" id="hje-ES-epI"/>
+                            <constraint firstAttribute="trailing" secondItem="WAJ-rx-IGC" secondAttribute="trailing" constant="7" id="msP-NW-BwY"/>
+                            <constraint firstItem="8zO-17-5Sy" firstAttribute="top" secondItem="OSD-YP-P2n" secondAttribute="top" constant="42" id="q63-de-6qY"/>
+                            <constraint firstAttribute="bottom" secondItem="FLX-as-x6g" secondAttribute="bottom" constant="20" id="ul3-PM-Ttk"/>
+                            <constraint firstItem="8zO-17-5Sy" firstAttribute="leading" secondItem="OSD-YP-P2n" secondAttribute="leading" constant="12" id="vpC-aO-2s2"/>
+                        </constraints>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                <real key="value" value="10"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                    </view>
+                </subviews>
+                <constraints>
+                    <constraint firstItem="OSD-YP-P2n" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="7nY-iA-Vpb"/>
+                    <constraint firstAttribute="trailing" secondItem="OSD-YP-P2n" secondAttribute="trailing" constant="13" id="IXs-7o-3oJ"/>
+                    <constraint firstItem="OSD-YP-P2n" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="13" id="PPy-NC-YeU"/>
+                    <constraint firstAttribute="bottom" secondItem="OSD-YP-P2n" secondAttribute="bottom" constant="15" id="wAB-4w-OAB"/>
+                </constraints>
+            </tableViewCellContentView>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <connections>
+                <outlet property="feedbackDesc" destination="WAJ-rx-IGC" id="kfl-Uk-PWy"/>
+                <outlet property="feedbackTypeName" destination="5Xc-mR-vx1" id="ERa-5A-b4r"/>
+                <outlet property="imageBottom" destination="8Vw-hb-K6G" id="F2b-l5-AYg"/>
+                <outlet property="imageContainer" destination="CVX-hJ-zJ1" id="mct-Pl-Q1k"/>
+                <outlet property="imageTop" destination="0Rc-Ch-wlh" id="pcR-0k-Dej"/>
+                <outlet property="replyBottom" destination="LC5-EN-qMg" id="UxL-l9-PFM"/>
+                <outlet property="replyDesc" destination="Z7E-Pa-Y3M" id="PSW-6r-f1I"/>
+                <outlet property="replyDescBottom" destination="QlI-uK-Nh4" id="i7B-ke-53W"/>
+                <outlet property="replyTitleHeight" destination="COK-E1-XFU" id="7gN-dR-Ajt"/>
+                <outlet property="replyTitleTop" destination="qQa-tb-6d5" id="FaG-lJ-hYC"/>
+                <outlet property="replyView" destination="FLX-as-x6g" id="Ufv-V8-fHL"/>
+            </connections>
+            <point key="canvasLocation" x="1.5267175572519083" y="99.295774647887328"/>
+        </tableViewCell>
+    </objects>
+    <resources>
+        <image name="feedback_icon" width="14" height="14"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 36 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackListNavView.h

@@ -0,0 +1,36 @@
+//
+//  FeedbackListNavView.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/12/25.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef NS_ENUM(NSInteger, RECORDLIST) {
+    RECORDLIST_BACK,  // 返回
+    RECORDLIST_SORT,  // 筛选
+};
+
+typedef void(^FeedbackListSortCallback)(RECORDLIST type);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface FeedbackListNavView : UIView
+
+@property (weak, nonatomic) IBOutlet UILabel *sortLabel;
+
+@property (nonatomic, assign) BOOL isSort;
+
++ (instancetype)shareInstance;
+
+- (void)sortCallback:(FeedbackListSortCallback)callback;
+
+- (void)changeArrow:(BOOL)isSort;
+
++ (CGFloat)getViewHeight;
+
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 71 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackListNavView.m

@@ -0,0 +1,71 @@
+//
+//  FeedbackListNavView.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/12/25.
+//
+
+#import "FeedbackListNavView.h"
+
+@interface FeedbackListNavView ()
+
+@property (weak, nonatomic) IBOutlet UIImageView *arrowImage;
+
+@property (nonatomic, copy) FeedbackListSortCallback callback;
+
+@end
+
+@implementation FeedbackListNavView
+
++ (instancetype)shareInstance {
+    FeedbackListNavView *view = [[[NSBundle mainBundle] loadNibNamed:@"FeedbackListNavView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)sortCallback:(FeedbackListSortCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (IBAction)back:(id)sender {
+    if (self.callback) {
+        self.callback(RECORDLIST_BACK);
+    }
+}
+
+
+- (IBAction)sortAction:(id)sender {
+    if (self.callback) {
+        self.callback(RECORDLIST_SORT);
+    }
+}
+
+- (void)changeArrow:(BOOL)isSort {
+    self.isSort = isSort;
+}
+
++ (CGFloat)getViewHeight {
+    return kNaviBarHeight;
+}
+
+- (void)setIsSort:(BOOL)isSort {
+    _isSort = isSort;
+    if (isSort) {
+        self.sortLabel.textColor = THEMECOLOR;
+        [self.arrowImage setImage:[UIImage imageNamed:@"sort_up_blue"]];
+    }
+    else {
+        self.sortLabel.textColor = HexRGB(0x333333);
+        [self.arrowImage setImage:[UIImage imageNamed:@"sort_up_grey"]];
+    }
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 100 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackListNavView.xib

@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="FeedbackListNavView">
+            <rect key="frame" x="0.0" y="0.0" width="393" height="90"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="UK4-T2-a4y">
+                    <rect key="frame" x="0.0" y="46" width="393" height="44"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="back_black" translatesAutoresizingMaskIntoConstraints="NO" id="bKX-su-7nm">
+                            <rect key="frame" x="13" y="12" width="12" height="20"/>
+                        </imageView>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="BTV-sa-zFs">
+                            <rect key="frame" x="0.0" y="0.0" width="44" height="44"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="44" id="InE-ZO-cZ2"/>
+                            </constraints>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="back:" destination="iN0-l3-epB" eventType="touchUpInside" id="85Z-HL-kZu"/>
+                            </connections>
+                        </button>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="反馈记录" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pkv-xQ-phx">
+                            <rect key="frame" x="159" y="9.6666666666666643" width="75" height="25"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="25" id="4bQ-nA-UBl"/>
+                                <constraint firstAttribute="width" constant="75" id="P0u-7P-e5O"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="18"/>
+                            <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="筛选" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fmd-vA-gcd">
+                            <rect key="frame" x="339.33333333333331" y="13.666666666666664" width="28.666666666666686" height="17"/>
+                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                            <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="iQI-gt-pbi">
+                            <rect key="frame" x="339.33333333333331" y="0.0" width="53.666666666666686" height="44"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="sortAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="frh-cm-nNf"/>
+                            </connections>
+                        </button>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="sort_up_grey" translatesAutoresizingMaskIntoConstraints="NO" id="2vX-UI-bnk">
+                            <rect key="frame" x="372" y="19.666666666666671" width="9" height="5"/>
+                        </imageView>
+                    </subviews>
+                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstItem="BTV-sa-zFs" firstAttribute="leading" secondItem="UK4-T2-a4y" secondAttribute="leading" id="0ag-gc-Fzi"/>
+                        <constraint firstItem="BTV-sa-zFs" firstAttribute="top" secondItem="UK4-T2-a4y" secondAttribute="top" id="9bg-Vy-SdB"/>
+                        <constraint firstItem="2vX-UI-bnk" firstAttribute="centerY" secondItem="UK4-T2-a4y" secondAttribute="centerY" id="9dH-6k-kdy"/>
+                        <constraint firstItem="pkv-xQ-phx" firstAttribute="centerY" secondItem="UK4-T2-a4y" secondAttribute="centerY" id="HVG-9T-xSE"/>
+                        <constraint firstItem="fmd-vA-gcd" firstAttribute="centerY" secondItem="UK4-T2-a4y" secondAttribute="centerY" id="L1q-X4-jU6"/>
+                        <constraint firstItem="bKX-su-7nm" firstAttribute="leading" secondItem="UK4-T2-a4y" secondAttribute="leading" constant="13" id="MSg-PL-DKX"/>
+                        <constraint firstItem="pkv-xQ-phx" firstAttribute="centerX" secondItem="UK4-T2-a4y" secondAttribute="centerX" id="N5u-2V-Y38"/>
+                        <constraint firstAttribute="bottom" secondItem="BTV-sa-zFs" secondAttribute="bottom" id="ORl-EM-Bx3"/>
+                        <constraint firstAttribute="height" constant="44" id="QeS-Kd-CT9"/>
+                        <constraint firstAttribute="bottom" secondItem="iQI-gt-pbi" secondAttribute="bottom" id="bVr-ZU-J1A"/>
+                        <constraint firstAttribute="trailing" secondItem="iQI-gt-pbi" secondAttribute="trailing" id="g6y-G3-haI"/>
+                        <constraint firstItem="2vX-UI-bnk" firstAttribute="leading" secondItem="fmd-vA-gcd" secondAttribute="trailing" constant="4" id="gPc-ft-j1C"/>
+                        <constraint firstItem="iQI-gt-pbi" firstAttribute="top" secondItem="UK4-T2-a4y" secondAttribute="top" id="hFh-mm-2JU"/>
+                        <constraint firstItem="bKX-su-7nm" firstAttribute="centerY" secondItem="UK4-T2-a4y" secondAttribute="centerY" id="rdi-4t-ZEk"/>
+                        <constraint firstItem="iQI-gt-pbi" firstAttribute="leading" secondItem="fmd-vA-gcd" secondAttribute="leading" id="u7d-CZ-pkU"/>
+                        <constraint firstAttribute="trailing" secondItem="2vX-UI-bnk" secondAttribute="trailing" constant="12" id="zvR-j9-R6U"/>
+                    </constraints>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstAttribute="trailing" secondItem="UK4-T2-a4y" secondAttribute="trailing" id="MfW-ID-baS"/>
+                <constraint firstItem="UK4-T2-a4y" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="XvP-Ln-QNa"/>
+                <constraint firstAttribute="bottom" secondItem="UK4-T2-a4y" secondAttribute="bottom" id="cRb-dy-AG5"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="arrowImage" destination="2vX-UI-bnk" id="wWG-TQ-IRc"/>
+                <outlet property="sortLabel" destination="fmd-vA-gcd" id="TNg-wh-gPT"/>
+            </connections>
+            <point key="canvasLocation" x="-60.305343511450381" y="-74.647887323943664"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="back_black" width="12" height="20"/>
+        <image name="sort_up_grey" width="9" height="5"/>
+    </resources>
+</document>

+ 24 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackNavView.h

@@ -0,0 +1,24 @@
+//
+//  FeedbackNavView.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/12/25.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef void(^FeedbackNavCallback)(BOOL isBack);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface FeedbackNavView : UIView
+
++ (instancetype)shareInstance;
+
+- (void)navCallback:(FeedbackNavCallback)callback;
+
++ (CGFloat)getViewHeight;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 55 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackNavView.m

@@ -0,0 +1,55 @@
+//
+//  FeedbackNavView.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/12/25.
+//
+
+#import "FeedbackNavView.h"
+
+@interface FeedbackNavView ()
+
+@property (nonatomic, copy) FeedbackNavCallback callback;
+
+@end
+
+@implementation FeedbackNavView
+
++ (instancetype)shareInstance {
+    FeedbackNavView *view = [[[NSBundle mainBundle] loadNibNamed:@"FeedbackNavView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+
+- (void)navCallback:(FeedbackNavCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (IBAction)feedbackBack:(id)sender {
+    if (self.callback) {
+        self.callback(YES);
+    }
+}
+
+
+- (IBAction)suggesstionList:(id)sender {
+    if (self.callback) {
+        self.callback(NO);
+    }
+}
+
+
++ (CGFloat)getViewHeight {
+    return kNaviBarHeight;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 89 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackNavView.xib

@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="FeedbackNavView">
+            <rect key="frame" x="0.0" y="0.0" width="393" height="82"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="row-b6-UeW">
+                    <rect key="frame" x="0.0" y="38" width="393" height="44"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="back_black" translatesAutoresizingMaskIntoConstraints="NO" id="FdQ-AN-nFR">
+                            <rect key="frame" x="13" y="12" width="12" height="20"/>
+                        </imageView>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="d96-uR-Yw4">
+                            <rect key="frame" x="0.0" y="0.0" width="44" height="44"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="44" id="M3a-3q-V9n"/>
+                            </constraints>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="feedbackBack:" destination="iN0-l3-epB" eventType="touchUpInside" id="QJV-0w-VNI"/>
+                            </connections>
+                        </button>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="意见反馈" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9MA-XK-PFG">
+                            <rect key="frame" x="159.66666666666666" y="9.6666666666666643" width="74" height="25"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="25" id="poU-ge-wup"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="18"/>
+                            <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="反馈记录" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3rd-41-FGa">
+                            <rect key="frame" x="315.66666666666669" y="12.333333333333334" width="65.333333333333314" height="19.333333333333329"/>
+                            <fontDescription key="fontDescription" type="system" pointSize="16"/>
+                            <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="MgK-MY-700">
+                            <rect key="frame" x="315.66666666666669" y="0.0" width="77.333333333333314" height="44"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="suggesstionList:" destination="iN0-l3-epB" eventType="touchUpInside" id="zzo-pw-QPe"/>
+                            </connections>
+                        </button>
+                    </subviews>
+                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstAttribute="trailing" secondItem="MgK-MY-700" secondAttribute="trailing" id="092-Gn-K28"/>
+                        <constraint firstAttribute="bottom" secondItem="d96-uR-Yw4" secondAttribute="bottom" id="2qh-AV-HDC"/>
+                        <constraint firstItem="d96-uR-Yw4" firstAttribute="leading" secondItem="row-b6-UeW" secondAttribute="leading" id="4qO-sP-cHa"/>
+                        <constraint firstItem="9MA-XK-PFG" firstAttribute="centerX" secondItem="row-b6-UeW" secondAttribute="centerX" id="K3h-Dk-QTj"/>
+                        <constraint firstItem="FdQ-AN-nFR" firstAttribute="centerY" secondItem="row-b6-UeW" secondAttribute="centerY" id="M4W-IF-EHQ"/>
+                        <constraint firstItem="MgK-MY-700" firstAttribute="leading" secondItem="3rd-41-FGa" secondAttribute="leading" id="MgF-hh-r0N"/>
+                        <constraint firstItem="FdQ-AN-nFR" firstAttribute="leading" secondItem="row-b6-UeW" secondAttribute="leading" constant="13" id="V2N-vl-8HF"/>
+                        <constraint firstAttribute="trailing" secondItem="3rd-41-FGa" secondAttribute="trailing" constant="12" id="kUv-VH-Ga6"/>
+                        <constraint firstItem="MgK-MY-700" firstAttribute="top" secondItem="row-b6-UeW" secondAttribute="top" id="mmc-k0-f1C"/>
+                        <constraint firstAttribute="bottom" secondItem="MgK-MY-700" secondAttribute="bottom" id="ry1-e9-sYC"/>
+                        <constraint firstItem="3rd-41-FGa" firstAttribute="centerY" secondItem="row-b6-UeW" secondAttribute="centerY" id="sQd-LB-t2d"/>
+                        <constraint firstItem="9MA-XK-PFG" firstAttribute="centerY" secondItem="row-b6-UeW" secondAttribute="centerY" id="xkL-nX-AMX"/>
+                        <constraint firstAttribute="height" constant="44" id="ybw-1B-hOs"/>
+                        <constraint firstItem="d96-uR-Yw4" firstAttribute="top" secondItem="row-b6-UeW" secondAttribute="top" id="z5f-EC-PhJ"/>
+                    </constraints>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstAttribute="trailing" secondItem="row-b6-UeW" secondAttribute="trailing" id="BnF-af-BMU"/>
+                <constraint firstAttribute="bottom" secondItem="row-b6-UeW" secondAttribute="bottom" id="cO3-pv-yeV"/>
+                <constraint firstItem="row-b6-UeW" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="fvx-kW-RHc"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <point key="canvasLocation" x="-60.305343511450381" y="-113.38028169014085"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="back_black" width="12" height="20"/>
+    </resources>
+</document>

+ 34 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackSortView.h

@@ -0,0 +1,34 @@
+//
+//  FeedbackSortView.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/12/25.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef NS_ENUM(NSInteger, FEEDBACKSORT) {
+    FEEDBACKSORT_CANCEL,  // 取消
+    FEEDBACKSORT_SURE,    // 确认
+    FEEDBACKSORT_RESET,   // 重置
+};
+
+typedef void(^FeedbackSortCallback)(FEEDBACKSORT type, NSString * _Nullable sortType, NSString * _Nullable sortName, NSString * _Nullable beginTime, NSString * _Nullable endTime);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface FeedbackSortView : UIView
+
++ (instancetype)shareInstance;
+
+- (void)configWithSource:(NSMutableArray *)typeArray typeNameArray:(NSMutableArray *)typeNameArray;
+
+- (void)feedbackSort:(FeedbackSortCallback)callback;
+
+- (void)showSortView;
+
+- (void)hideSortView;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 285 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackSortView.m

@@ -0,0 +1,285 @@
+//
+//  FeedbackSortView.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/12/25.
+//
+
+#import "FeedbackSortView.h"
+#import "KSFullDatePicker.h"
+#import "NSDate+Transform.h"
+#import "KSSortButtonView.h"
+
+@interface FeedbackSortView ()<UIGestureRecognizerDelegate>
+
+@property (weak, nonatomic) IBOutlet UIView *typeView;
+
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *typeViewHeight;
+
+@property (weak, nonatomic) IBOutlet UIView *containerView;
+
+@property (weak, nonatomic) IBOutlet UILabel *beginLabel;
+@property (weak, nonatomic) IBOutlet UIView *beginView;
+
+@property (weak, nonatomic) IBOutlet UIView *endView;
+@property (weak, nonatomic) IBOutlet UILabel *endLabel;
+
+@property (nonatomic, copy) FeedbackSortCallback callback;
+
+@property (nonatomic, strong) NSString *sortType;
+
+@property (nonatomic, strong) NSString *sortName;
+
+@property (nonatomic, strong) NSString *beginTime;
+
+@property (nonatomic, strong) NSString *endTime;
+
+@property (nonatomic, strong) KSFullDatePicker *datePicker;
+
+@property (nonatomic, strong) NSDateFormatter *formatter;
+
+@property (nonatomic, strong) NSMutableArray *typeArray;
+
+@property (nonatomic, strong) NSMutableArray *typeNameArray;
+
+@property (nonatomic, assign) NSInteger lastChooseIndex;
+
+@end
+
+@implementation FeedbackSortView
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    self.containerView.layer.cornerRadius = 12.0f;
+    self.containerView.layer.maskedCorners = kCALayerMinXMaxYCorner | kCALayerMaxXMaxYCorner;
+    [self addGesture];
+}
+
+
++ (instancetype)shareInstance {
+    FeedbackSortView *view = [[[NSBundle mainBundle] loadNibNamed:@"FeedbackSortView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)configWithSource:(NSMutableArray *)typeArray typeNameArray:(NSMutableArray *)typeNameArray {
+    
+    self.typeArray = [NSMutableArray arrayWithArray:typeArray];
+    self.typeNameArray = [NSMutableArray arrayWithArray:typeNameArray];
+    NSInteger rowCount = IS_IPAD ? 3  : 2;
+    CGFloat leftSpace = 13;
+    CGFloat buttonHeight = 34.0f;
+    CGFloat buttonSpace = 12;
+    CGFloat lineSpace = 18;
+    CGFloat buttonWidth = (KPortraitWidth - leftSpace * 2 - (rowCount-1) * buttonSpace) / rowCount;
+
+    for (NSInteger index = 0; index < typeArray.count; index++) {
+        NSInteger tag = 1000 + index;
+        NSString *name = typeNameArray[index];
+        KSSortButtonView *button = [self createSortButton:tag buttonTitle:name];
+        [self.typeView addSubview:button];
+        CGFloat xSpace = leftSpace + (buttonWidth + buttonSpace) * (index % rowCount);
+        CGFloat ySpace = lineSpace + (buttonHeight + lineSpace) * (index / rowCount);
+        [button mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.mas_equalTo(self.typeView.mas_left).offset(xSpace);
+            make.width.mas_equalTo(buttonWidth);
+            make.height.mas_equalTo(buttonHeight);
+            make.top.mas_equalTo(self.typeView.mas_top).offset(ySpace);
+        }];
+    }
+    // 刷新高度
+    CGFloat containerHeight = 0.0f;
+    BOOL addRow = typeArray.count % rowCount > 0 ? YES : NO;
+    containerHeight = (addRow + typeArray.count / rowCount) * (buttonHeight + lineSpace);
+    self.typeViewHeight.constant = containerHeight;
+}
+
+- (KSSortButtonView *)createSortButton:(NSInteger)tag buttonTitle:(NSString *)buttonTitle {
+    KSSortButtonView *button = [KSSortButtonView shareInstance];
+    [button configTitle:buttonTitle font:[UIFont systemFontOfSize:13.0f weight:UIFontWeightRegular] titleColor:HexRGB(0x333333) cornerRadius:17.0f backgroudColor:HexRGB(0xF6F6F6) lineBreakMode:NSLineBreakByTruncatingMiddle tag:tag target:self action:@selector(buttonClickAction:)];
+    return button;
+}
+
+- (void)buttonClickAction:(UIButton *)sender {
+    // 取消上一个选择
+    if (self.lastChooseIndex > 0) {
+        [self modifyButtonStatus:NO buttonIndex:self.lastChooseIndex];
+    }
+    self.lastChooseIndex = sender.tag;
+    [self modifyButtonStatus:YES buttonIndex:sender.tag];
+    // 获取当前
+    NSInteger index = sender.tag - 1000;
+    self.sortType = self.typeArray[index];
+    self.sortName = self.typeNameArray[index];
+}
+
+- (void)modifyButtonStatus:(BOOL)isChoose buttonIndex:(NSInteger)buttonIndex {
+    KSSortButtonView *button = (KSSortButtonView *)[self.containerView viewWithTag:buttonIndex];
+    [button updateChooseStatus:isChoose];
+}
+
+- (void)feedbackSort:(FeedbackSortCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (void)showSortView {
+    UIView *displayView = [NSObject getKeyWindow];
+    [displayView addSubview:self];
+    [self mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.mas_equalTo(kNaviBarHeight);
+        make.left.right.bottom.mas_equalTo(displayView);
+    }];
+}
+
+- (void)hideSortView {
+    [self removeSortView];
+}
+
+- (IBAction)chooseBeginAction:(id)sender {
+    NSDate *data = [NSDate date];
+    if (![NSString isEmptyString:self.beginTime]) {
+        NSString *time = self.beginTime;
+        [self.formatter setDateFormat:@"yyyy-MM-dd"];
+        data = [self.formatter dateFromString:time];
+    }
+    MJWeakSelf;
+    self.datePicker = [[KSFullDatePicker alloc] initWithTitle:@"" date:data pickMode:KSDATEPICKER_MODE_DAY selectDateBlock:^(NSString *date) {
+        [weakSelf modifyTime:date isBegin:YES];
+    } cancleBlock:^{
+        
+    }];
+    [self.datePicker show];
+}
+
+- (void)modifyTime:(NSString *)date isBegin:(BOOL)isBegin {
+    if (isBegin) {
+        // 如果开始时间小于结束时间
+        if (![NSString isEmptyString:self.endTime]) {
+            NSTimeInterval interval = [NSDate countTimesTampWithBeginTime:date endTime:self.endTime format:@"yyyy-MM-dd"];
+            if (interval < 0) {
+                [LOADING_MANAGER MBShowAUTOHidingInWindow:@"开始时间需小于结束时间"];
+                return;
+            }
+        }
+        self.beginTime = date;
+        self.beginLabel.text = date;
+        self.beginLabel.textColor = THEMECOLOR;
+        self.beginLabel.font = [UIFont systemFontOfSize:16.0f weight:UIFontWeightMedium];
+        self.beginView.backgroundColor = THEMECOLOR;
+    }
+    else {
+        // 如果开始时间小于结束时间
+        if (![NSString isEmptyString:self.beginTime]) {
+            NSTimeInterval interval = [NSDate countTimesTampWithBeginTime:self.beginTime endTime:self.endTime format:@"yyyy-MM-dd"];
+            if (interval < 0) {
+                [LOADING_MANAGER MBShowAUTOHidingInWindow:@"开始时间需小于结束时间"];
+                return;
+            }
+        }
+        
+        self.endTime = date;
+        self.endLabel.text = date;
+        self.endLabel.textColor = THEMECOLOR;
+        self.endLabel.font = [UIFont systemFontOfSize:16.0f weight:UIFontWeightMedium];
+        self.endView.backgroundColor = THEMECOLOR;
+    }
+}
+
+
+
+- (IBAction)endTIme:(id)sender {
+    NSDate *data = [NSDate date];
+    if (![NSString isEmptyString:self.endTime]) {
+        NSString *time = self.endTime;
+        [self.formatter setDateFormat:@"yyyy-MM-dd"];
+        data = [self.formatter dateFromString:time];
+    }
+    MJWeakSelf;
+    self.datePicker = [[KSFullDatePicker alloc] initWithTitle:@"" date:data pickMode:KSDATEPICKER_MODE_DAY selectDateBlock:^(NSString *date) {
+        [weakSelf modifyTime:date isBegin:NO];
+    } cancleBlock:^{
+        
+    }];
+    [self.datePicker show];
+}
+
+- (void)resetAll {
+    self.sortType = nil;
+    self.sortName = nil;
+    self.beginTime = nil;
+    self.endTime = nil;
+    self.beginLabel.text = @"开始时间";
+    self.beginLabel.textColor = HexRGB(0xAAAAAA);
+    self.beginLabel.font = [UIFont systemFontOfSize:16.0f weight:UIFontWeightRegular];
+    self.beginView.backgroundColor = HexRGB(0x777777);
+    
+    self.endLabel.text = @"结束时间";
+    self.endLabel.textColor = HexRGB(0xAAAAAA);
+    self.endLabel.font = [UIFont systemFontOfSize:16.0f weight:UIFontWeightRegular];
+    self.endView.backgroundColor = HexRGB(0x777777);
+    
+    if (self.lastChooseIndex > 0) {
+        [self modifyButtonStatus:NO buttonIndex:self.lastChooseIndex];
+        self.lastChooseIndex = 0;
+    }
+}
+
+- (IBAction)resetAction:(id)sender {
+    [self resetAll];
+//    [self removeSortView];
+//    if (self.callback) {
+//        self.callback(FEEDBACKSORT_CANCEL,self.sortType, self.sortName, self.beginTime, self.endTime);
+//    }
+}
+
+- (IBAction)sureAction:(id)sender {
+    [self removeSortView];
+    if (self.callback) {
+        self.callback(FEEDBACKSORT_SURE,self.sortType, self.sortName, self.beginTime, self.endTime);
+    }
+}
+
+- (void)removeSortView {
+    [self removeFromSuperview];
+}
+
+
+#pragma mark ---- gesture
+- (void)addGesture {
+    UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
+    gesture.delegate = self;
+    [self addGestureRecognizer:gesture];
+}
+
+- (void)tapAction:(UITapGestureRecognizer *)gesture {
+    if (self.callback) {
+        self.callback(FEEDBACKSORT_CANCEL,self.sortType, self.sortName, self.beginTime, self.endTime);
+    }
+    [self removeSortView];
+}
+
+- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
+    if ([touch.view isDescendantOfView:self.containerView]) {
+        return NO;
+    }
+    return YES;
+}
+
+
+#pragma mark ---- lazying
+- (NSDateFormatter *)formatter {
+    if (!_formatter) {
+        _formatter = [NSObject getDateformatter];
+    }
+    return _formatter;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 260 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/FeedbackSortView.xib

@@ -0,0 +1,260 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
+        <capability name="System colors in document resources" minToolsVersion="11.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="FeedbackSortView">
+            <rect key="frame" x="0.0" y="0.0" width="393" height="751"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vJu-cl-3Nf">
+                    <rect key="frame" x="0.0" y="0.0" width="393" height="338"/>
+                    <subviews>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="反馈类型" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cS5-nE-eR6">
+                            <rect key="frame" x="13.000000000000004" y="12" width="61.333333333333343" height="21"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="21" id="oix-BF-Rt3"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="15"/>
+                            <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3ar-nb-ckZ">
+                            <rect key="frame" x="0.0" y="44" width="393" height="100"/>
+                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="100" id="QuA-Uc-8zK"/>
+                            </constraints>
+                        </view>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="s3p-WV-ZTE">
+                            <rect key="frame" x="0.0" y="258" width="393" height="80"/>
+                            <subviews>
+                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="aMq-Is-Nwx">
+                                    <rect key="frame" x="0.0" y="0.0" width="393" height="1"/>
+                                    <color key="backgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.94901960780000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                    <constraints>
+                                        <constraint firstAttribute="height" constant="1" id="Gnn-Fz-tqu"/>
+                                    </constraints>
+                                </view>
+                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="abx-g3-d1a">
+                                    <rect key="frame" x="13" y="18" width="176" height="44"/>
+                                    <fontDescription key="fontDescription" type="system" pointSize="16"/>
+                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                                    <state key="normal" title="重置">
+                                        <color key="titleColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                                    </state>
+                                    <userDefinedRuntimeAttributes>
+                                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                            <real key="value" value="22"/>
+                                        </userDefinedRuntimeAttribute>
+                                        <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                            <real key="value" value="1"/>
+                                        </userDefinedRuntimeAttribute>
+                                        <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                            <color key="value" red="0.85882352939999995" green="0.85882352939999995" blue="0.85882352939999995" alpha="1" colorSpace="calibratedRGB"/>
+                                        </userDefinedRuntimeAttribute>
+                                    </userDefinedRuntimeAttributes>
+                                    <connections>
+                                        <action selector="resetAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="4kl-yb-6w4"/>
+                                    </connections>
+                                </button>
+                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="R5j-GR-6TL">
+                                    <rect key="frame" x="204" y="18" width="176" height="44"/>
+                                    <color key="backgroundColor" red="0.1764705882352941" green="0.7803921568627451" blue="0.66666666666666663" alpha="1" colorSpace="calibratedRGB"/>
+                                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
+                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                                    <state key="normal" title="确定"/>
+                                    <userDefinedRuntimeAttributes>
+                                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                            <real key="value" value="22"/>
+                                        </userDefinedRuntimeAttribute>
+                                    </userDefinedRuntimeAttributes>
+                                    <connections>
+                                        <action selector="sureAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="AZM-Ka-3oy"/>
+                                    </connections>
+                                </button>
+                            </subviews>
+                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <constraints>
+                                <constraint firstItem="aMq-Is-Nwx" firstAttribute="leading" secondItem="s3p-WV-ZTE" secondAttribute="leading" id="45H-QA-jUI"/>
+                                <constraint firstAttribute="height" constant="80" id="8Mg-ES-ZLQ"/>
+                                <constraint firstItem="R5j-GR-6TL" firstAttribute="width" secondItem="abx-g3-d1a" secondAttribute="width" id="AYp-dj-cOS"/>
+                                <constraint firstItem="R5j-GR-6TL" firstAttribute="leading" secondItem="abx-g3-d1a" secondAttribute="trailing" constant="15" id="DEl-VD-egc"/>
+                                <constraint firstAttribute="trailing" secondItem="R5j-GR-6TL" secondAttribute="trailing" constant="13" id="EDS-Hq-BuY"/>
+                                <constraint firstItem="abx-g3-d1a" firstAttribute="top" secondItem="s3p-WV-ZTE" secondAttribute="top" constant="18" id="Rdh-tp-EQh"/>
+                                <constraint firstItem="abx-g3-d1a" firstAttribute="leading" secondItem="s3p-WV-ZTE" secondAttribute="leading" constant="13" id="WSc-m1-ham"/>
+                                <constraint firstAttribute="trailing" secondItem="aMq-Is-Nwx" secondAttribute="trailing" id="hQB-N1-k2U"/>
+                                <constraint firstItem="aMq-Is-Nwx" firstAttribute="top" secondItem="s3p-WV-ZTE" secondAttribute="top" id="hce-vq-BVY"/>
+                                <constraint firstAttribute="bottom" secondItem="abx-g3-d1a" secondAttribute="bottom" constant="18" id="mXi-qf-izU"/>
+                                <constraint firstItem="R5j-GR-6TL" firstAttribute="height" secondItem="abx-g3-d1a" secondAttribute="height" id="pgs-dy-n4V"/>
+                                <constraint firstItem="R5j-GR-6TL" firstAttribute="centerY" secondItem="abx-g3-d1a" secondAttribute="centerY" id="uFQ-Uy-0TB"/>
+                            </constraints>
+                        </view>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="时间选择" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sn7-2i-hZZ">
+                            <rect key="frame" x="13.000000000000004" y="168" width="61.333333333333343" height="21"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="21" id="1w7-QN-wgD"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="15"/>
+                            <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="至" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="26Y-S0-dkw">
+                            <rect key="frame" x="186.66666666666666" y="207" width="20" height="22"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="20" id="4XR-Mk-pqy"/>
+                                <constraint firstAttribute="height" constant="22" id="NQY-lZ-jlx"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
+                            <color key="textColor" red="0.074509803921568626" green="0.078431372549019607" blue="0.082352941176470587" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="SjH-lB-WlX">
+                            <rect key="frame" x="40.666666666666657" y="201" width="106" height="34"/>
+                            <subviews>
+                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="eIi-9q-VQt">
+                                    <rect key="frame" x="0.0" y="32" width="106" height="2"/>
+                                    <color key="backgroundColor" red="0.46666666666666667" green="0.46666666666666667" blue="0.46666666666666667" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                    <constraints>
+                                        <constraint firstAttribute="height" constant="2" id="gUk-rQ-IB3"/>
+                                    </constraints>
+                                    <userDefinedRuntimeAttributes>
+                                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                            <real key="value" value="1"/>
+                                        </userDefinedRuntimeAttribute>
+                                    </userDefinedRuntimeAttributes>
+                                </view>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="开始时间" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Cye-Rx-Q81">
+                                    <rect key="frame" x="0.0" y="0.0" width="106" height="32"/>
+                                    <fontDescription key="fontDescription" type="system" pointSize="16"/>
+                                    <color key="textColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="d7j-oQ-GbM">
+                                    <rect key="frame" x="0.0" y="0.0" width="106" height="34"/>
+                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                                    <connections>
+                                        <action selector="chooseBeginAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="i1x-6I-5Rt"/>
+                                    </connections>
+                                </button>
+                            </subviews>
+                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                            <constraints>
+                                <constraint firstItem="eIi-9q-VQt" firstAttribute="top" secondItem="Cye-Rx-Q81" secondAttribute="bottom" id="3aW-lg-mHI"/>
+                                <constraint firstAttribute="bottom" secondItem="eIi-9q-VQt" secondAttribute="bottom" id="3uh-aa-hei"/>
+                                <constraint firstAttribute="trailing" secondItem="eIi-9q-VQt" secondAttribute="trailing" id="57J-MR-qXs"/>
+                                <constraint firstAttribute="trailing" secondItem="Cye-Rx-Q81" secondAttribute="trailing" id="757-9H-L17"/>
+                                <constraint firstAttribute="width" constant="106" id="Ac9-UQ-mxJ"/>
+                                <constraint firstItem="Cye-Rx-Q81" firstAttribute="leading" secondItem="SjH-lB-WlX" secondAttribute="leading" id="RJa-el-ajR"/>
+                                <constraint firstItem="Cye-Rx-Q81" firstAttribute="top" secondItem="SjH-lB-WlX" secondAttribute="top" id="aZK-oN-sev"/>
+                                <constraint firstAttribute="trailing" secondItem="d7j-oQ-GbM" secondAttribute="trailing" id="cHB-WZ-Gnc"/>
+                                <constraint firstAttribute="bottom" secondItem="d7j-oQ-GbM" secondAttribute="bottom" id="mvy-gZ-LTy"/>
+                                <constraint firstItem="eIi-9q-VQt" firstAttribute="leading" secondItem="SjH-lB-WlX" secondAttribute="leading" id="rb1-3R-wUv"/>
+                                <constraint firstItem="d7j-oQ-GbM" firstAttribute="leading" secondItem="SjH-lB-WlX" secondAttribute="leading" id="v1a-i4-Zen"/>
+                                <constraint firstAttribute="height" constant="34" id="wAM-Bs-ui5"/>
+                                <constraint firstItem="d7j-oQ-GbM" firstAttribute="top" secondItem="SjH-lB-WlX" secondAttribute="top" id="zy6-mQ-Fdq"/>
+                            </constraints>
+                        </view>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="V6R-gr-Kd4">
+                            <rect key="frame" x="246.66666666666663" y="201" width="106" height="34"/>
+                            <subviews>
+                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="c6K-B2-0mV">
+                                    <rect key="frame" x="0.0" y="32" width="106" height="2"/>
+                                    <color key="backgroundColor" red="0.46666666666666667" green="0.46666666666666667" blue="0.46666666666666667" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                    <constraints>
+                                        <constraint firstAttribute="height" constant="2" id="pSq-ND-caJ"/>
+                                    </constraints>
+                                    <userDefinedRuntimeAttributes>
+                                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                            <real key="value" value="1"/>
+                                        </userDefinedRuntimeAttribute>
+                                    </userDefinedRuntimeAttributes>
+                                </view>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="结束时间" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3N9-PZ-mR6">
+                                    <rect key="frame" x="0.0" y="0.0" width="106" height="34"/>
+                                    <fontDescription key="fontDescription" type="system" pointSize="16"/>
+                                    <color key="textColor" red="0.66666666669999997" green="0.66666666669999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6Dd-nE-DpS">
+                                    <rect key="frame" x="0.0" y="0.0" width="106" height="34"/>
+                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                                    <connections>
+                                        <action selector="endTIme:" destination="iN0-l3-epB" eventType="touchUpInside" id="I8h-g5-YYB"/>
+                                    </connections>
+                                </button>
+                            </subviews>
+                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                            <constraints>
+                                <constraint firstAttribute="bottom" secondItem="6Dd-nE-DpS" secondAttribute="bottom" id="1mH-wI-37y"/>
+                                <constraint firstAttribute="bottom" secondItem="c6K-B2-0mV" secondAttribute="bottom" id="3RO-Zk-Mnc"/>
+                                <constraint firstAttribute="height" constant="34" id="5dR-Xs-unr"/>
+                                <constraint firstAttribute="trailing" secondItem="3N9-PZ-mR6" secondAttribute="trailing" id="95s-P8-fBc"/>
+                                <constraint firstAttribute="bottom" secondItem="3N9-PZ-mR6" secondAttribute="bottom" id="BfC-0b-YG7"/>
+                                <constraint firstAttribute="trailing" secondItem="c6K-B2-0mV" secondAttribute="trailing" id="Fs5-dt-n0B"/>
+                                <constraint firstAttribute="width" constant="106" id="P9g-Wr-9yg"/>
+                                <constraint firstItem="6Dd-nE-DpS" firstAttribute="top" secondItem="V6R-gr-Kd4" secondAttribute="top" id="Qxj-Va-dxP"/>
+                                <constraint firstAttribute="trailing" secondItem="6Dd-nE-DpS" secondAttribute="trailing" id="ahC-h6-eFD"/>
+                                <constraint firstItem="3N9-PZ-mR6" firstAttribute="leading" secondItem="V6R-gr-Kd4" secondAttribute="leading" id="eD2-2O-ebm"/>
+                                <constraint firstItem="c6K-B2-0mV" firstAttribute="leading" secondItem="V6R-gr-Kd4" secondAttribute="leading" id="mmq-A7-pwY"/>
+                                <constraint firstItem="3N9-PZ-mR6" firstAttribute="top" secondItem="V6R-gr-Kd4" secondAttribute="top" id="pbz-53-PHa"/>
+                                <constraint firstItem="6Dd-nE-DpS" firstAttribute="leading" secondItem="V6R-gr-Kd4" secondAttribute="leading" id="pjc-hD-4oe"/>
+                            </constraints>
+                        </view>
+                    </subviews>
+                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstItem="V6R-gr-Kd4" firstAttribute="leading" secondItem="26Y-S0-dkw" secondAttribute="trailing" constant="40" id="3U6-WH-zSC"/>
+                        <constraint firstItem="26Y-S0-dkw" firstAttribute="centerX" secondItem="vJu-cl-3Nf" secondAttribute="centerX" id="42s-MQ-LeB"/>
+                        <constraint firstAttribute="trailing" secondItem="3ar-nb-ckZ" secondAttribute="trailing" id="9ht-5U-GeM"/>
+                        <constraint firstItem="3ar-nb-ckZ" firstAttribute="leading" secondItem="vJu-cl-3Nf" secondAttribute="leading" id="CgP-Cw-tSm"/>
+                        <constraint firstItem="SjH-lB-WlX" firstAttribute="top" secondItem="sn7-2i-hZZ" secondAttribute="bottom" constant="12" id="D6S-SQ-yxh"/>
+                        <constraint firstItem="s3p-WV-ZTE" firstAttribute="top" secondItem="26Y-S0-dkw" secondAttribute="bottom" constant="29" id="Mjy-iM-YPA"/>
+                        <constraint firstItem="V6R-gr-Kd4" firstAttribute="centerY" secondItem="SjH-lB-WlX" secondAttribute="centerY" id="Ob8-75-7R8"/>
+                        <constraint firstAttribute="bottom" secondItem="s3p-WV-ZTE" secondAttribute="bottom" id="Oov-kU-Voi"/>
+                        <constraint firstItem="sn7-2i-hZZ" firstAttribute="leading" secondItem="vJu-cl-3Nf" secondAttribute="leading" constant="13" id="P30-0r-PNB"/>
+                        <constraint firstItem="26Y-S0-dkw" firstAttribute="centerY" secondItem="SjH-lB-WlX" secondAttribute="centerY" id="QHw-hH-NKP"/>
+                        <constraint firstItem="sn7-2i-hZZ" firstAttribute="top" secondItem="3ar-nb-ckZ" secondAttribute="bottom" constant="24" id="THR-99-FHM"/>
+                        <constraint firstItem="26Y-S0-dkw" firstAttribute="leading" secondItem="SjH-lB-WlX" secondAttribute="trailing" constant="40" id="UtQ-Yj-8J3"/>
+                        <constraint firstItem="cS5-nE-eR6" firstAttribute="leading" secondItem="vJu-cl-3Nf" secondAttribute="leading" constant="13" id="VSz-WH-AhQ"/>
+                        <constraint firstItem="s3p-WV-ZTE" firstAttribute="leading" secondItem="vJu-cl-3Nf" secondAttribute="leading" id="eMT-9T-6aK"/>
+                        <constraint firstItem="3ar-nb-ckZ" firstAttribute="top" secondItem="cS5-nE-eR6" secondAttribute="bottom" constant="11" id="jVs-xn-Wen"/>
+                        <constraint firstAttribute="trailing" secondItem="s3p-WV-ZTE" secondAttribute="trailing" id="qaR-bd-0Cf"/>
+                        <constraint firstItem="cS5-nE-eR6" firstAttribute="top" secondItem="vJu-cl-3Nf" secondAttribute="top" constant="12" id="t0L-Ak-rkm"/>
+                    </constraints>
+                </view>
+            </subviews>
+            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
+            <constraints>
+                <constraint firstItem="vJu-cl-3Nf" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="3NS-Qd-Fha"/>
+                <constraint firstItem="vJu-cl-3Nf" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="AFJ-Wn-ZC7"/>
+                <constraint firstAttribute="trailing" secondItem="vJu-cl-3Nf" secondAttribute="trailing" id="Cex-z6-rgw"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="beginLabel" destination="Cye-Rx-Q81" id="CCd-HZ-Tvi"/>
+                <outlet property="beginView" destination="eIi-9q-VQt" id="p0c-VN-fN4"/>
+                <outlet property="containerView" destination="vJu-cl-3Nf" id="bx6-U9-g55"/>
+                <outlet property="endLabel" destination="3N9-PZ-mR6" id="5jB-CI-wI8"/>
+                <outlet property="endView" destination="c6K-B2-0mV" id="dc4-Wx-zmN"/>
+                <outlet property="typeView" destination="3ar-nb-ckZ" id="eiC-Qc-D2J"/>
+                <outlet property="typeViewHeight" destination="QuA-Uc-8zK" id="e5C-q1-8p9"/>
+            </connections>
+            <point key="canvasLocation" x="-60.305343511450381" y="80.633802816901408"/>
+        </view>
+    </objects>
+    <resources>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/KSSortButtonView.h

@@ -0,0 +1,22 @@
+//
+//  KSSortButtonView.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/28.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSSortButtonView : UIView
+
++ (instancetype)shareInstance;
+
+- (void)configTitle:(NSString *)title font:(UIFont *)font titleColor:(UIColor *)titleColor cornerRadius:(CGFloat)cornerRadius backgroudColor:(UIColor *)backgroundColor lineBreakMode:(NSLineBreakMode)breakMode tag:(NSInteger)tag target:(id)target action:(SEL)action;
+
+- (void)updateChooseStatus:(BOOL)isChoose;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 60 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/KSSortButtonView.m

@@ -0,0 +1,60 @@
+//
+//  KSSortButtonView.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/28.
+//
+
+#import "KSSortButtonView.h"
+
+@interface KSSortButtonView ()
+
+@property (weak, nonatomic) IBOutlet UIView *bgView;
+
+@property (weak, nonatomic) IBOutlet UILabel *buttonTitle;
+
+@property (weak, nonatomic) IBOutlet UIButton *actionButton;
+
+@end
+
+@implementation KSSortButtonView
+
++ (instancetype)shareInstance {
+    KSSortButtonView *view = [[[NSBundle mainBundle] loadNibNamed:@"KSSortButtonView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)configTitle:(NSString *)title font:(UIFont *)font titleColor:(UIColor *)titleColor cornerRadius:(CGFloat)cornerRadius backgroudColor:(UIColor *)backgroundColor lineBreakMode:(NSLineBreakMode)breakMode tag:(NSInteger)tag target:(id)target action:(SEL)action {
+    self.bgView.backgroundColor = backgroundColor;
+    self.bgView.layer.cornerRadius = cornerRadius;
+    self.bgView.layer.borderWidth = 1.0f;
+    self.bgView.layer.borderColor = [UIColor clearColor].CGColor;
+    self.buttonTitle.text = title;
+    self.buttonTitle.font = font;
+    self.buttonTitle.textColor = titleColor;
+    self.buttonTitle.lineBreakMode = breakMode;
+    self.actionButton.tag = tag;
+    self.tag = tag;
+    [self.actionButton addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
+}
+- (void)updateChooseStatus:(BOOL)isChoose {
+    if (isChoose) {
+        [self.bgView setBackgroundColor:HexRGB(0xE0F7F3)];
+        [self.buttonTitle setTextColor:HexRGB(0x2DC7AA)];
+        self.bgView.layer.borderColor = HexRGB(0x2DC7AA).CGColor;
+    }
+    else {
+        [self.bgView setBackgroundColor:HexRGB(0xF6F6F6)];
+        [self.buttonTitle setTextColor:HexRGB(0x333333)];
+        self.bgView.layer.borderColor = [UIColor clearColor].CGColor;
+    }
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 70 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Feedback/View/KSSortButtonView.xib

@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
+        <capability name="System colors in document resources" minToolsVersion="11.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="KSSortButtonView">
+            <rect key="frame" x="0.0" y="0.0" width="241" height="57"/>
+            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Wfe-3V-pn5">
+                    <rect key="frame" x="0.0" y="0.0" width="241" height="57"/>
+                    <subviews>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="d1a-IE-9Cc">
+                            <rect key="frame" x="5" y="19.666666666666668" width="231" height="18.000000000000004"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="18" id="UoA-0H-5PB"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" pointSize="16"/>
+                            <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="roq-cS-zXm">
+                            <rect key="frame" x="0.0" y="0.0" width="241" height="57"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                        </button>
+                    </subviews>
+                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                    <constraints>
+                        <constraint firstItem="d1a-IE-9Cc" firstAttribute="centerY" secondItem="Wfe-3V-pn5" secondAttribute="centerY" id="6ma-zs-JmC"/>
+                        <constraint firstAttribute="bottom" secondItem="roq-cS-zXm" secondAttribute="bottom" id="7ge-9P-hhk"/>
+                        <constraint firstItem="d1a-IE-9Cc" firstAttribute="leading" secondItem="Wfe-3V-pn5" secondAttribute="leading" constant="5" id="QZA-P6-9y4"/>
+                        <constraint firstAttribute="trailing" secondItem="roq-cS-zXm" secondAttribute="trailing" id="UUo-2o-Xd7"/>
+                        <constraint firstItem="d1a-IE-9Cc" firstAttribute="centerX" secondItem="Wfe-3V-pn5" secondAttribute="centerX" id="aAT-vN-Roe"/>
+                        <constraint firstItem="roq-cS-zXm" firstAttribute="top" secondItem="Wfe-3V-pn5" secondAttribute="top" id="jff-BK-qjL"/>
+                        <constraint firstItem="roq-cS-zXm" firstAttribute="leading" secondItem="Wfe-3V-pn5" secondAttribute="leading" id="kYu-Fz-Fq4"/>
+                        <constraint firstAttribute="trailing" secondItem="d1a-IE-9Cc" secondAttribute="trailing" constant="5" id="lLV-K5-fdp"/>
+                    </constraints>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="Wfe-3V-pn5" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="JtW-n1-WQX"/>
+                <constraint firstAttribute="bottom" secondItem="Wfe-3V-pn5" secondAttribute="bottom" id="RbA-6x-UVO"/>
+                <constraint firstAttribute="trailing" secondItem="Wfe-3V-pn5" secondAttribute="trailing" id="TlQ-tG-1gr"/>
+                <constraint firstItem="Wfe-3V-pn5" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="kbB-C4-H7F"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="actionButton" destination="roq-cS-zXm" id="bob-68-4Ly"/>
+                <outlet property="bgView" destination="Wfe-3V-pn5" id="bNp-pi-ARJ"/>
+                <outlet property="buttonTitle" destination="d1a-IE-9Cc" id="kwq-wA-Drh"/>
+            </connections>
+            <point key="canvasLocation" x="-66.412213740458014" y="-117.25352112676057"/>
+        </view>
+    </objects>
+    <resources>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 0 - 93
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Setting/Controller/FeedbackViewController.m

@@ -1,93 +0,0 @@
-//
-//  FeedbackViewController.m
-//  KulexiuForTeacher
-//
-//  Created by Kyle on 2022/3/22.
-//
-
-#import "FeedbackViewController.h"
-#import "FeedbackBodyView.h"
-#import "UserInfoManager.h"
-
-@interface FeedbackViewController ()
-
-@property (nonatomic, strong) FeedbackBodyView *bodyView;
-
-@end
-
-@implementation FeedbackViewController
-
-- (void)viewDidLoad {
-    [super viewDidLoad];
-    // Do any additional setup after loading the view.
-    [self allocTitle:@"意见反馈"];
-    [self configUI];
-    [self countUMEvent];
-    [self requestConfig];
-}
-
-- (void)requestConfig {
-    [KSNetworkingManager queryConfigRequest:KS_POST success:^(NSDictionary * _Nonnull dic) {
-        if ([dic ks_integerValueForKey:@"code"] == 200) {
-            NSDictionary *result = [dic ks_dictionaryValueForKey:@"data"];
-            NSString *phone = [result ks_stringValueForKey:@"customerServicePhone"];
-            NSString *email = [result ks_stringValueForKey:@"customerServiceEmail"];
-            [self.bodyView configPhone:phone email:email];
-        }
-        else {
-            
-        }
-    } faliure:^(NSError * _Nonnull error) {
-        
-    }];
-}
-
-- (void)countUMEvent {
-    [USER_MANAGER sendUMEvent:@"klx_feedback"];
-}
-
-- (void)configUI {
-    self.bodyView = [FeedbackBodyView shareInstance];
-    [self.scrollView addSubview:self.bodyView];
-    CGFloat height = kScreenHeight - kNaviBarHeight - iPhoneXSafeBottomMargin > 530 ?  kScreenHeight - kNaviBarHeight - iPhoneXSafeBottomMargin : 530;
-    [self.bodyView mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.top.mas_equalTo(self.scrollView.mas_top);
-        make.right.left.mas_equalTo(self.view);
-        make.height.mas_equalTo(height);
-    }];
-    KSWeakSelf(weakSelf);
-    [self.bodyView submitActionCallback:^(NSString *submitStr, NSString *contactStr) {
-        // 提交
-        [weakSelf submitWithPhone:contactStr suggestion:submitStr];
-    }];
-    [self.scrollView setContentSize:CGSizeMake(kScreenWidth, height)];
-}
-
-- (void)submitWithPhone:(NSString *)phone suggestion:(NSString *)suggession {
-    [LOADING_MANAGER showHUD];
-    [KSNetworkingManager suggestionAddRequest:KS_POST content:suggession mobileNo:phone success:^(NSDictionary * _Nonnull dic) {
-        [LOADING_MANAGER removeHUD];
-        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
-            [LOADING_MANAGER KSShowMsg:@"提交成功" promptCompletion:^{
-                [self.navigationController popViewControllerAnimated:YES];
-            }];
-        }
-        else {
-            [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
-        }
-    } faliure:^(NSError * _Nonnull error) {
-        [LOADING_MANAGER removeHUD];
-    }];
-}
-
-/*
-#pragma mark - Navigation
-
-// In a storyboard-based application, you will often want to do a little preparation before navigation
-- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
-    // Get the new view controller using [segue destinationViewController].
-    // Pass the selected object to the new view controller.
-}
-*/
-
-@end