Browse Source

1.聊天修改

Steven 2 years ago
parent
commit
3b2ce83c09
92 changed files with 2687 additions and 332 deletions
  1. 80 0
      KulexiuForTeacher/KulexiuForTeacher.xcodeproj/project.pbxproj
  2. BIN
      KulexiuForTeacher/KulexiuForTeacher.xcworkspace/xcuserdata/wangzhi.xcuserdatad/UserInterfaceState.xcuserstate
  3. 134 38
      KulexiuForTeacher/KulexiuForTeacher.xcworkspace/xcuserdata/wangzhi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
  4. 1 1
      KulexiuForTeacher/KulexiuForTeacher/AppDelegate.m
  5. 6 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/Contents.json
  6. 2 2
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/chat_talentList.imageset/Contents.json
  7. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/chat_talentList.imageset/chat_talentList@2x.png
  8. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/chat_talentList.imageset/chat_talentList@3x.png
  9. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/chat_talentTag.imageset/Contents.json
  10. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/chat_talentTag.imageset/chat_talentTag@2x.png
  11. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/chat_talentTag.imageset/chat_talentTag@3x.png
  12. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/group_ownerList.imageset/Contents.json
  13. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/group_ownerList.imageset/chat_ownerList@2x.png
  14. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/group_ownerList.imageset/chat_ownerList@3x.png
  15. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/group_ownerTag.imageset/Contents.json
  16. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/group_ownerTag.imageset/group_ownerTag@2x.png
  17. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/group_ownerTag.imageset/group_ownerTag@3x.png
  18. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/group_owner.imageset/group_owner@2x.png
  19. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/group_owner.imageset/group_owner@3x.png
  20. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/group_ownerList.imageset/group_ownerList@2x.png
  21. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/group_ownerList.imageset/group_ownerList@3x.png
  22. 2 2
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/user_detailBg.imageset/Contents.json
  23. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/user_detailBg.imageset/user_detailBg@2x.png
  24. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/user_detailBg.imageset/user_detailBg@3x.png
  25. 18 0
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.h
  26. 27 0
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.m
  27. 13 1
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSRCIMDataSource.m
  28. 1 1
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSWebNavView.m
  29. 1 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Controller/ChatAddressViewController.m
  30. 95 11
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Controller/KSChatConversationViewController.m
  31. 24 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Controller/KSChatListViewController.m
  32. 18 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Controller/KSChatUserDetailViewController.h
  33. 175 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Controller/KSChatUserDetailViewController.m
  34. 7 3
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Group/Controller/GroupMemberViewController.m
  35. 7 3
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Group/Controller/GroupSettingViewController.m
  36. 11 2
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Group/View/GroupMemberListCell.m
  37. 14 3
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Group/View/GroupMemberListCell.xib
  38. 23 3
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Group/View/GroupSettingBodyView.m
  39. 44 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Model/ChatUserInfo/ChatUserInfo.h
  40. 263 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Model/ChatUserInfo/ChatUserInfo.m
  41. 70 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Model/ChatUserInfo/RecentPracticeModel.h
  42. 445 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Model/ChatUserInfo/RecentPracticeModel.m
  43. 2 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Model/FriendListModel.h
  44. 16 6
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Model/FriendListModel.m
  45. 1 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Model/GroupMemberModel.h
  46. 7 4
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Model/GroupMemberModel.m
  47. 2 2
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatAddressBodyView.m
  48. 24 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/RecentMusicView.h
  49. 185 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/RecentMusicView.m
  50. 132 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/RecentMusicView.xib
  51. 26 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/UserDetailBodyView.h
  52. 100 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/UserDetailBodyView.m
  53. 262 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/UserDetailBodyView.xib
  54. 18 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/UserDetailBottomView.h
  55. 25 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/UserDetailBottomView.m
  56. 37 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/UserDetailBottomView.xib
  57. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/UserDetailNavView.h
  58. 44 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/UserDetailNavView.m
  59. 69 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/UserDetailNavView.xib
  60. 10 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ContractListCell.m
  61. 14 3
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ContractListCell.xib
  62. 16 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/KSChatTagView.h
  63. 20 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/KSChatTagView.m
  64. 1 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/AccompanyCourse/Controller/AccompanyDetailViewController.m
  65. 1 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/Controller/CourseViewController.m
  66. 1 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/Model/TableCourseModel.h
  67. 8 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/Model/TableCourseModel.m
  68. 4 26
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/Controller/HomeViewController.m
  69. 1 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/Homework/Model/HomeworkDetailModel.h
  70. 8 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/Homework/Model/HomeworkDetailModel.m
  71. 1 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/Homework/Model/HomeworkListModel.h
  72. 7 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/Homework/Model/HomeworkListModel.m
  73. 2 2
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/Homework/View/HomeworkBodyView.m
  74. 1 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/Homework/View/HomeworkListCell.h
  75. 3 3
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/Homework/View/HomeworkListCell.m
  76. 1 44
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/Music/View/MusicMessageCell.m
  77. 7 19
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/Music/View/MusicMessageCell.xib
  78. 4 6
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/Music/View/MyMusicBodyView.m
  79. 1 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/Model/AccompanyLessonModel.h
  80. 7 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/Model/AccompanyLessonModel.m
  81. 1 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MyLessonBodyView.m
  82. 7 4
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/View/HomeHotAlbumCell.xib
  83. 0 40
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/View/HomeMusic/HomeHotMusicCellView.m
  84. 9 24
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/View/HomeMusic/HomeHotMusicCellView.xib
  85. 8 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Login/Model/UserInfoManager.m
  86. 1 1
      KulexiuForTeacher/KulexiuForTeacher/Module/MidiPlayer/ShareInChat/View/ShareChooseMainView.m
  87. 4 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/CreateStyle/Controller/MyStyleViewController.m
  88. 4 7
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/MinePageCourseView.m
  89. 0 43
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/MinePageMusicCell.m
  90. 7 19
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/MinePageMusicCell.xib
  91. 5 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Setting/Controller/ModifyNameViewController.m
  92. 4 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Setting/Controller/UserSettingViewController.m

+ 80 - 0
KulexiuForTeacher/KulexiuForTeacher.xcodeproj/project.pbxproj

@@ -457,6 +457,17 @@
 		BC1191F3280EAB9600A716F7 /* AccompanyDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BC1191F1280EAB9600A716F7 /* AccompanyDetailViewController.m */; };
 		BC1191F6280EBC7D00A716F7 /* AccompanyDetailBottomView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC1191F5280EBC7D00A716F7 /* AccompanyDetailBottomView.m */; };
 		BC1191F8280EBC8600A716F7 /* AccompanyDetailBottomView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC1191F7280EBC8600A716F7 /* AccompanyDetailBottomView.xib */; };
+		BC12637E28FEB5B900509E90 /* UserDetailNavView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC12637228FEB5B900509E90 /* UserDetailNavView.xib */; };
+		BC12637F28FEB5B900509E90 /* UserDetailBodyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC12637428FEB5B900509E90 /* UserDetailBodyView.xib */; };
+		BC12638028FEB5B900509E90 /* UserDetailNavView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC12637528FEB5B900509E90 /* UserDetailNavView.m */; };
+		BC12638128FEB5B900509E90 /* UserDetailBottomView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC12637828FEB5B900509E90 /* UserDetailBottomView.m */; };
+		BC12638228FEB5B900509E90 /* RecentMusicView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC12637928FEB5B900509E90 /* RecentMusicView.xib */; };
+		BC12638328FEB5B900509E90 /* UserDetailBottomView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC12637A28FEB5B900509E90 /* UserDetailBottomView.xib */; };
+		BC12638428FEB5B900509E90 /* RecentMusicView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC12637B28FEB5B900509E90 /* RecentMusicView.m */; };
+		BC12638528FEB5B900509E90 /* UserDetailBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC12637D28FEB5B900509E90 /* UserDetailBodyView.m */; };
+		BC12638C28FEB5E600509E90 /* ChatUserInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = BC12638A28FEB5E600509E90 /* ChatUserInfo.m */; };
+		BC12638D28FEB5E600509E90 /* RecentPracticeModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BC12638B28FEB5E600509E90 /* RecentPracticeModel.m */; };
+		BC12639028FEC8C200509E90 /* KSChatTagView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC12638F28FEC8C200509E90 /* KSChatTagView.m */; };
 		BC1365B8280D130C00EB03E2 /* MyVideoCourseBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC1365B7280D130C00EB03E2 /* MyVideoCourseBodyView.m */; };
 		BC1365BB280D162400EB03E2 /* MyVideoSearchView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC1365BA280D162400EB03E2 /* MyVideoSearchView.m */; };
 		BC1365BD280D163200EB03E2 /* MyVideoSearchView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC1365BC280D163200EB03E2 /* MyVideoSearchView.xib */; };
@@ -822,6 +833,7 @@
 		BCC03F9A2805681100461B7C /* MyLessonSearchView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCC03F992805681100461B7C /* MyLessonSearchView.xib */; };
 		BCC03F9E280579A500461B7C /* MyLiveCourseCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC03F9C280579A500461B7C /* MyLiveCourseCell.m */; };
 		BCC03F9F280579A500461B7C /* MyLiveCourseCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCC03F9D280579A500461B7C /* MyLiveCourseCell.xib */; };
+		BCC305F828FD4C0800C39762 /* KSChatUserDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC305F728FD4C0800C39762 /* KSChatUserDetailViewController.m */; };
 		BCC583F428A9FA8100BAB4CF /* cloud_animation_9.png in Resources */ = {isa = PBXBuildFile; fileRef = BCC583D528A9FA8100BAB4CF /* cloud_animation_9.png */; };
 		BCC583F528A9FA8100BAB4CF /* cloud_animation_8.png in Resources */ = {isa = PBXBuildFile; fileRef = BCC583D628A9FA8100BAB4CF /* cloud_animation_8.png */; };
 		BCC583F628A9FA8100BAB4CF /* cloud_animation_20.png in Resources */ = {isa = PBXBuildFile; fileRef = BCC583D728A9FA8100BAB4CF /* cloud_animation_20.png */; };
@@ -1853,6 +1865,24 @@
 		BC1191F4280EBC7D00A716F7 /* AccompanyDetailBottomView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AccompanyDetailBottomView.h; sourceTree = "<group>"; };
 		BC1191F5280EBC7D00A716F7 /* AccompanyDetailBottomView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AccompanyDetailBottomView.m; sourceTree = "<group>"; };
 		BC1191F7280EBC8600A716F7 /* AccompanyDetailBottomView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AccompanyDetailBottomView.xib; sourceTree = "<group>"; };
+		BC12637228FEB5B900509E90 /* UserDetailNavView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UserDetailNavView.xib; sourceTree = "<group>"; };
+		BC12637328FEB5B900509E90 /* UserDetailBottomView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserDetailBottomView.h; sourceTree = "<group>"; };
+		BC12637428FEB5B900509E90 /* UserDetailBodyView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UserDetailBodyView.xib; sourceTree = "<group>"; };
+		BC12637528FEB5B900509E90 /* UserDetailNavView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserDetailNavView.m; sourceTree = "<group>"; };
+		BC12637628FEB5B900509E90 /* RecentMusicView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecentMusicView.h; sourceTree = "<group>"; };
+		BC12637728FEB5B900509E90 /* UserDetailBodyView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserDetailBodyView.h; sourceTree = "<group>"; };
+		BC12637828FEB5B900509E90 /* UserDetailBottomView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserDetailBottomView.m; sourceTree = "<group>"; };
+		BC12637928FEB5B900509E90 /* RecentMusicView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RecentMusicView.xib; sourceTree = "<group>"; };
+		BC12637A28FEB5B900509E90 /* UserDetailBottomView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UserDetailBottomView.xib; sourceTree = "<group>"; };
+		BC12637B28FEB5B900509E90 /* RecentMusicView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RecentMusicView.m; sourceTree = "<group>"; };
+		BC12637C28FEB5B900509E90 /* UserDetailNavView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserDetailNavView.h; sourceTree = "<group>"; };
+		BC12637D28FEB5B900509E90 /* UserDetailBodyView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserDetailBodyView.m; sourceTree = "<group>"; };
+		BC12638828FEB5E600509E90 /* ChatUserInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatUserInfo.h; sourceTree = "<group>"; };
+		BC12638928FEB5E600509E90 /* RecentPracticeModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecentPracticeModel.h; sourceTree = "<group>"; };
+		BC12638A28FEB5E600509E90 /* ChatUserInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChatUserInfo.m; sourceTree = "<group>"; };
+		BC12638B28FEB5E600509E90 /* RecentPracticeModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RecentPracticeModel.m; sourceTree = "<group>"; };
+		BC12638E28FEC8C200509E90 /* KSChatTagView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSChatTagView.h; sourceTree = "<group>"; };
+		BC12638F28FEC8C200509E90 /* KSChatTagView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSChatTagView.m; sourceTree = "<group>"; };
 		BC1365B6280D130C00EB03E2 /* MyVideoCourseBodyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyVideoCourseBodyView.h; sourceTree = "<group>"; };
 		BC1365B7280D130C00EB03E2 /* MyVideoCourseBodyView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MyVideoCourseBodyView.m; sourceTree = "<group>"; };
 		BC1365B9280D162400EB03E2 /* MyVideoSearchView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyVideoSearchView.h; sourceTree = "<group>"; };
@@ -2414,6 +2444,8 @@
 		BCC03F9B280579A500461B7C /* MyLiveCourseCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyLiveCourseCell.h; sourceTree = "<group>"; };
 		BCC03F9C280579A500461B7C /* MyLiveCourseCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MyLiveCourseCell.m; sourceTree = "<group>"; };
 		BCC03F9D280579A500461B7C /* MyLiveCourseCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MyLiveCourseCell.xib; sourceTree = "<group>"; };
+		BCC305F628FD4C0800C39762 /* KSChatUserDetailViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSChatUserDetailViewController.h; sourceTree = "<group>"; };
+		BCC305F728FD4C0800C39762 /* KSChatUserDetailViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSChatUserDetailViewController.m; sourceTree = "<group>"; };
 		BCC583D528A9FA8100BAB4CF /* cloud_animation_9.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = cloud_animation_9.png; sourceTree = "<group>"; };
 		BCC583D628A9FA8100BAB4CF /* cloud_animation_8.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = cloud_animation_8.png; sourceTree = "<group>"; };
 		BCC583D728A9FA8100BAB4CF /* cloud_animation_20.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = cloud_animation_20.png; sourceTree = "<group>"; };
@@ -4118,6 +4150,8 @@
 				275B16FC27EB083C0081FDEF /* ChatAddressViewController.m */,
 				275B16F827EB08220081FDEF /* CreateFansGroupViewController.h */,
 				275B16F927EB08230081FDEF /* CreateFansGroupViewController.m */,
+				BCC305F628FD4C0800C39762 /* KSChatUserDetailViewController.h */,
+				BCC305F728FD4C0800C39762 /* KSChatUserDetailViewController.m */,
 			);
 			path = Controller;
 			sourceTree = "<group>";
@@ -4125,6 +4159,7 @@
 		2779360427E32BBF0010E277 /* Model */ = {
 			isa = PBXGroup;
 			children = (
+				BC12638728FEB5E600509E90 /* ChatUserInfo */,
 				BCED5CA8284F5D8D009A42DE /* FriendListModel.h */,
 				BCED5CA9284F5D8D009A42DE /* FriendListModel.m */,
 				27F9CB0D27EC5DF4003E0FE4 /* KSRCloudMediaManager.h */,
@@ -4144,11 +4179,14 @@
 		2779360527E32BBF0010E277 /* View */ = {
 			isa = PBXGroup;
 			children = (
+				BC12637128FEB5B900509E90 /* ChatUserInfo */,
 				BCDE3590289A7E4900A9A560 /* KSGroupTagImageView.h */,
 				BCDE358F289A7E4900A9A560 /* KSGroupTagImageView.m */,
 				275B16ED27EAF9B10081FDEF /* ChatNavView.h */,
 				275B16EE27EAF9B10081FDEF /* ChatNavView.m */,
 				275B16F027EAF9DD0081FDEF /* ChatNavView.xib */,
+				BC12638E28FEC8C200509E90 /* KSChatTagView.h */,
+				BC12638F28FEC8C200509E90 /* KSChatTagView.m */,
 				275B170927EB14A00081FDEF /* KSChatListSearchView.h */,
 				275B170A27EB14A00081FDEF /* KSChatListSearchView.m */,
 				275B170C27EB14AC0081FDEF /* KSChatListSearchView.xib */,
@@ -4843,6 +4881,36 @@
 			path = ClassroomSong;
 			sourceTree = "<group>";
 		};
+		BC12637128FEB5B900509E90 /* ChatUserInfo */ = {
+			isa = PBXGroup;
+			children = (
+				BC12637628FEB5B900509E90 /* RecentMusicView.h */,
+				BC12637B28FEB5B900509E90 /* RecentMusicView.m */,
+				BC12637928FEB5B900509E90 /* RecentMusicView.xib */,
+				BC12637728FEB5B900509E90 /* UserDetailBodyView.h */,
+				BC12637D28FEB5B900509E90 /* UserDetailBodyView.m */,
+				BC12637428FEB5B900509E90 /* UserDetailBodyView.xib */,
+				BC12637328FEB5B900509E90 /* UserDetailBottomView.h */,
+				BC12637828FEB5B900509E90 /* UserDetailBottomView.m */,
+				BC12637A28FEB5B900509E90 /* UserDetailBottomView.xib */,
+				BC12637C28FEB5B900509E90 /* UserDetailNavView.h */,
+				BC12637528FEB5B900509E90 /* UserDetailNavView.m */,
+				BC12637228FEB5B900509E90 /* UserDetailNavView.xib */,
+			);
+			path = ChatUserInfo;
+			sourceTree = "<group>";
+		};
+		BC12638728FEB5E600509E90 /* ChatUserInfo */ = {
+			isa = PBXGroup;
+			children = (
+				BC12638828FEB5E600509E90 /* ChatUserInfo.h */,
+				BC12638928FEB5E600509E90 /* RecentPracticeModel.h */,
+				BC12638A28FEB5E600509E90 /* ChatUserInfo.m */,
+				BC12638B28FEB5E600509E90 /* RecentPracticeModel.m */,
+			);
+			path = ChatUserInfo;
+			sourceTree = "<group>";
+		};
 		BC1365BE280D44D500EB03E2 /* NotiferMessage */ = {
 			isa = PBXGroup;
 			children = (
@@ -6890,6 +6958,7 @@
 				BCC5841C28AA36D700BAB4CF /* BadgeIntroduceView.xib in Resources */,
 				BCC583F728A9FA8100BAB4CF /* cloud_animation_21.png in Resources */,
 				BCE06F2D2818147000234817 /* KSConfirmAlertView.xib in Resources */,
+				BC12638328FEB5B900509E90 /* UserDetailBottomView.xib in Resources */,
 				BC71D295288811BF0010F14B /* tabbar4.json in Resources */,
 				BCA7C34428476533009D20EC /* KSBoardAddStaffView.xib in Resources */,
 				BCA353E52859797500377661 /* MusicRoomStudentCell.xib in Resources */,
@@ -6934,6 +7003,7 @@
 				BC71D1EB2887FDD40010F14B /* img_1.png in Resources */,
 				BC3673DB28A606A500059721 /* live_animation_1.png in Resources */,
 				BCC583FB28A9FA8100BAB4CF /* cloud_animation_27.png in Resources */,
+				BC12637E28FEB5B900509E90 /* UserDetailNavView.xib in Resources */,
 				BCB9FA4F28717BBD005D766B /* MyMusicSearchView.xib in Resources */,
 				BCC5840A28A9FA8100BAB4CF /* cloud_animation_6.png in Resources */,
 				BC483233282A6473005F534C /* HomeRecentCourseView.xib in Resources */,
@@ -7019,6 +7089,7 @@
 				BC0A22B82847523E0065C1AB /* MemberListCell.xib in Resources */,
 				BCB9FA632872C8D2005D766B /* UnderwayLiveCell.xib in Resources */,
 				BC71D1ED2887FDD40010F14B /* img_11.png in Resources */,
+				BC12638228FEB5B900509E90 /* RecentMusicView.xib in Resources */,
 				BCA9CE3A27FD93EB00D558C6 /* AccompanyStudentEvaCell.xib in Resources */,
 				BCE6A09627F823DC00C97704 /* MinePageMusicCell.xib in Resources */,
 				BC4BCE722823A03A00522C8B /* AddressBottomView.xib in Resources */,
@@ -7056,6 +7127,7 @@
 				BC1191F8280EBC8600A716F7 /* AccompanyDetailBottomView.xib in Resources */,
 				BCDE3596289B960A00A9A560 /* HomeAlbumView.xib in Resources */,
 				BCA9CE3027FD8A9900D558C6 /* AccompanyNavView.xib in Resources */,
+				BC12637F28FEB5B900509E90 /* UserDetailBodyView.xib in Resources */,
 				BCA9CE3527FD93C700D558C6 /* AccompanyEvaluateCell.xib in Resources */,
 				27D5D5D227EDBA9400B4720C /* NoticeEditBodyView.xib in Resources */,
 				BC7CFFD7281801B700CAEB21 /* CardBandBodyView.xib in Resources */,
@@ -7180,6 +7252,7 @@
 				BCA9CE3927FD93EB00D558C6 /* AccompanyStudentEvaCell.m in Sources */,
 				2779324027E30FC30010E277 /* VoNetworking+RequestManager.m in Sources */,
 				2723B68C27F1685600E0B90B /* HomeNavView.m in Sources */,
+				BC12638D28FEB5E600509E90 /* RecentPracticeModel.m in Sources */,
 				BCB633FB27F6A18200ACFDCF /* ClassVideoListCell.m in Sources */,
 				27BC3B2927F2DB8600D81E30 /* MusicUploadView.m in Sources */,
 				277931F327E30FC20010E277 /* UIView+Hints.m in Sources */,
@@ -7211,6 +7284,7 @@
 				BC245704286C434800D1F7C0 /* MidiPlayerEngine.m in Sources */,
 				BCA1135328A242FD007FAFB9 /* HomeBannerView.m in Sources */,
 				BC8831042873D67C00C702A0 /* LiveVideoCollectionViewCell.m in Sources */,
+				BC12638428FEB5B900509E90 /* RecentMusicView.m in Sources */,
 				BCB633F527F6A18200ACFDCF /* NewClassRoomViewController.m in Sources */,
 				BC4BCE6C28239EEB00522C8B /* MyAddressListCell.m in Sources */,
 				BCD6D16228195A17009A773E /* WithdrawApplyViewController.m in Sources */,
@@ -7225,6 +7299,7 @@
 				27F9CAFB27EC1AF3003E0FE4 /* ContractListCell.m in Sources */,
 				BCC9F44227F69BD200647449 /* TurnPageMessage.m in Sources */,
 				BCDB093728058BBE00D0BDAD /* AccompanyLessonModel.m in Sources */,
+				BC12639028FEC8C200509E90 /* KSChatTagView.m in Sources */,
 				BC3744D428DB156F004EDFCF /* KSImageShareViewController.m in Sources */,
 				27FC2F6627F1BBFE00FCC239 /* MyMusicViewController.m in Sources */,
 				277D432827E9A48000107DB7 /* ModifyPhoneChangeController.m in Sources */,
@@ -7329,6 +7404,7 @@
 				2779324127E30FC30010E277 /* VoNetWorking.m in Sources */,
 				275E3DF127F467D80010EC30 /* SeatContentView.m in Sources */,
 				BCE6A09F27F84E4500C97704 /* MineIntroduceCell.m in Sources */,
+				BC12638C28FEB5E600509E90 /* ChatUserInfo.m in Sources */,
 				BCF1BA5A27F5CF3C00FA36C4 /* LiveSeatApplyCell.m in Sources */,
 				BCC9F43527F69BD200647449 /* DisplayCommandMessage.m in Sources */,
 				BC7CFFAF2817E6C900CAEB21 /* IncomeCountBottomView.m in Sources */,
@@ -7461,6 +7537,7 @@
 				BCB633F727F6A18200ACFDCF /* ClassroomTimerManager.m in Sources */,
 				275B172F27EB27860081FDEF /* GroupCreateView.m in Sources */,
 				BC41104D280678E600800BD9 /* HomeworkSortView.m in Sources */,
+				BC12638128FEB5B900509E90 /* UserDetailBottomView.m in Sources */,
 				2779361827E32C200010E277 /* ShopMallViewController.m in Sources */,
 				BCB633FE27F6A18200ACFDCF /* ClassTitleView.m in Sources */,
 				2779326927E30FD80010E277 /* FSCalendarCollectionViewLayout.m in Sources */,
@@ -7543,6 +7620,7 @@
 				277931CB27E30FC20010E277 /* KSGifRefreshHeader.m in Sources */,
 				2755C07E27EC95CC007D9070 /* GroupNoticeViewController.m in Sources */,
 				2779328F27E30FEB0010E277 /* MSSBrowseLocalViewController.m in Sources */,
+				BCC305F828FD4C0800C39762 /* KSChatUserDetailViewController.m in Sources */,
 				BC1365C4280D44EB00EB03E2 /* NotiferMessageViewController.m in Sources */,
 				27A54CF127E9BD3B007309A3 /* FeedbackViewController.m in Sources */,
 				BC7705FD287676D3003EFA7F /* HomeActionView.m in Sources */,
@@ -7653,6 +7731,7 @@
 				BC7CFFA22817D72200CAEB21 /* IncomeListModel.m in Sources */,
 				BC0A22A9284751F80065C1AB /* FullVideoView.m in Sources */,
 				2755C06C27EC7F0E007D9070 /* KSChatComplainController.m in Sources */,
+				BC12638528FEB5B900509E90 /* UserDetailBodyView.m in Sources */,
 				BC14A61728A0B0440086395C /* MineBottomView.m in Sources */,
 				27F9CB1127EC60D0003E0FE4 /* GroupListModel.m in Sources */,
 				27FC2F5F27F1930400FCC239 /* KSStarView.m in Sources */,
@@ -7793,6 +7872,7 @@
 				2708565627ED8BD000EC8E72 /* ApplyBottomView.m in Sources */,
 				277931EE27E30FC20010E277 /* UIView+Dealloc.m in Sources */,
 				2779320B27E30FC30010E277 /* KSFullDatePicker.m in Sources */,
+				BC12638028FEB5B900509E90 /* UserDetailNavView.m in Sources */,
 				BCB9FA1C286D537E005D766B /* KSScanViewController.m in Sources */,
 				277931F427E30FC20010E277 /* NSDate+Extension.m in Sources */,
 				277931C127E30FC20010E277 /* NSDictionary+KSSafe.m in Sources */,

BIN
KulexiuForTeacher/KulexiuForTeacher.xcworkspace/xcuserdata/wangzhi.xcuserdatad/UserInterfaceState.xcuserstate


+ 134 - 38
KulexiuForTeacher/KulexiuForTeacher.xcworkspace/xcuserdata/wangzhi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -119,22 +119,6 @@
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
-            uuid = "D730210B-8BDA-4804-AFA5-45F85F31834B"
-            shouldBeEnabled = "Yes"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "KulexiuForTeacher/Module/Live/View/SeatContentView.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "122"
-            endingLineNumber = "122"
-            landmarkName = "-queryUserInfoWithUserId:"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
             uuid = "2B6124D7-B34B-4117-9E4D-5F25E9D8E541"
             shouldBeEnabled = "No"
             ignoreCount = "0"
@@ -167,22 +151,6 @@
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
-            uuid = "14DD535F-C194-4907-BF6B-0DB631D7DAF7"
-            shouldBeEnabled = "Yes"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "KulexiuForTeacher/Module/Live/Controller/LiveRoomViewController.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "893"
-            endingLineNumber = "893"
-            landmarkName = "-subscribeRemoteResource:isTiny:"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
             uuid = "29B4C94C-1FAE-45F6-A9F8-D242F8A85B94"
             shouldBeEnabled = "Yes"
             ignoreCount = "0"
@@ -286,8 +254,8 @@
             filePath = "KulexiuForTeacher/Module/Home/Music/View/MyMusicBodyView.m"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "118"
-            endingLineNumber = "118"
+            startingLineNumber = "117"
+            endingLineNumber = "117"
             landmarkName = "-requestData"
             landmarkType = "7">
          </BreakpointContent>
@@ -302,8 +270,8 @@
             filePath = "KulexiuForTeacher/Module/Mine/Setting/Controller/UserSettingViewController.m"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "274"
-            endingLineNumber = "274"
+            startingLineNumber = "277"
+            endingLineNumber = "277"
             landmarkName = "-clearUMCount"
             landmarkType = "7">
          </BreakpointContent>
@@ -318,8 +286,8 @@
             filePath = "KulexiuForTeacher/Module/Home/Controller/HomeViewController.m"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "456"
-            endingLineNumber = "456"
+            startingLineNumber = "452"
+            endingLineNumber = "452"
             landmarkName = "-requestAlbumSource"
             landmarkType = "7">
          </BreakpointContent>
@@ -340,5 +308,133 @@
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "D53471D3-69FC-48A6-9CDF-A73778A2E5DE"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "KulexiuForTeacher/Common/Base/KSBaseWKWebViewController.m"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "541"
+            endingLineNumber = "541"
+            landmarkName = "-handleScriptMessageSource:"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "C1BEF3F0-175C-4838-A6B5-201C5A1A02A0"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "KulexiuForTeacher/Module/Home/Homework/View/HomeworkBodyView.m"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "111"
+            endingLineNumber = "111"
+            landmarkName = "-requestData"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "8F974F5B-7269-465A-A239-12043F9C29D5"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "KulexiuForTeacher/Module/Mine/MinePage/View/MinePageCourseView.m"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "132"
+            endingLineNumber = "132"
+            landmarkName = "-requestData"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "097FD29F-08F9-4A57-AC47-D3DD8CB51524"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "KulexiuForTeacher/Module/Live/View/SeatContentView.m"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "115"
+            endingLineNumber = "115"
+            landmarkName = "-queryUserInfoWithUserId:"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "A08F4159-44C7-4301-877A-A8C99940217D"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "KulexiuForTeacher/Module/Live/View/SeatContentView.m"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "40"
+            endingLineNumber = "40"
+            landmarkName = "-setupUI"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "B2AB1EC5-3EFA-4681-86A0-1FA80EA94E73"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "KulexiuForTeacher/Module/Live/View/SeatContentView.m"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "131"
+            endingLineNumber = "131"
+            landmarkName = "-queryUserInfoWithUserId:"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "6CD69290-5546-460A-B946-330EF6B65309"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "KulexiuForTeacher/Module/Chat/Controller/KSChatConversationViewController.m"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "831"
+            endingLineNumber = "831"
+            landmarkName = "-didTapCellPortrait:"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "02FBB038-735F-450B-B1C0-DD0B6609CA34"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "KulexiuForTeacher/Module/Chat/Controller/KSChatConversationViewController.m"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "840"
+            endingLineNumber = "840"
+            landmarkName = "-didTapCellPortrait:"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
    </Breakpoints>
 </Bucket>

+ 1 - 1
KulexiuForTeacher/KulexiuForTeacher/AppDelegate.m

@@ -305,7 +305,7 @@
     RCKitConfigCenter.ui.globalMessagePortraitSize = CGSizeMake(40, 40);
     // 会话列表头像设置
     RCKitConfigCenter.ui.globalConversationAvatarStyle = RC_USER_AVATAR_RECTANGLE;
-    RCKitConfigCenter.ui.globalConversationPortraitSize = CGSizeMake(48, 48);
+    RCKitConfigCenter.ui.globalConversationPortraitSize = CGSizeMake(44, 44);
     
     //开启消息撤回功能
     RCKitConfigCenter.message.enableMessageRecall = YES;

+ 6 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/Contents.json

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

+ 2 - 2
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/group_ownerList.imageset/Contents.json → KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/chat_talentList.imageset/Contents.json

@@ -5,12 +5,12 @@
       "scale" : "1x"
     },
     {
-      "filename" : "group_ownerList@2x.png",
+      "filename" : "chat_talentList@2x.png",
       "idiom" : "universal",
       "scale" : "2x"
     },
     {
-      "filename" : "group_ownerList@3x.png",
+      "filename" : "chat_talentList@3x.png",
       "idiom" : "universal",
       "scale" : "3x"
     }

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/chat_talentList.imageset/chat_talentList@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/chat_talentList.imageset/chat_talentList@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/chat_talentTag.imageset/Contents.json

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

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/chat_talentTag.imageset/chat_talentTag@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/chat_talentTag.imageset/chat_talentTag@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/group_ownerList.imageset/Contents.json

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

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/group_ownerList.imageset/chat_ownerList@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/group_ownerList.imageset/chat_ownerList@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/group_ownerTag.imageset/Contents.json

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

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/group_ownerTag.imageset/group_ownerTag@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/ChatTag/group_ownerTag.imageset/group_ownerTag@3x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/group_owner.imageset/group_owner@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/group_owner.imageset/group_owner@3x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/group_ownerList.imageset/group_ownerList@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/group_ownerList.imageset/group_ownerList@3x.png


+ 2 - 2
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/group_owner.imageset/Contents.json → KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/user_detailBg.imageset/Contents.json

@@ -5,12 +5,12 @@
       "scale" : "1x"
     },
     {
-      "filename" : "group_owner@2x.png",
+      "filename" : "user_detailBg@2x.png",
       "idiom" : "universal",
       "scale" : "2x"
     },
     {
-      "filename" : "group_owner@3x.png",
+      "filename" : "user_detailBg@3x.png",
       "idiom" : "universal",
       "scale" : "3x"
     }

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/user_detailBg.imageset/user_detailBg@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/user_detailBg.imageset/user_detailBg@3x.png


+ 18 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.h

@@ -1264,5 +1264,23 @@ NS_ASSUME_NONNULL_BEGIN
 /// @param success 成功
 /// @param faliure 失败
 + (void)checkReceiveRewardRequest:(NSString *)get success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
+// api-teacher/student/queryUserById 参数 rongCloudUserId
+
+/// 查询指定学员信息-融云token
+/// @param get get
+/// @param rongCloudUserId rongCloudUserId
+/// @param success 成功
+/// @param faliure 失败
++ (void)queryUserById:(NSString *)get rongCloudUserId:(NSString *)rongCloudUserId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
+// /api-teacher/music/sheet/user/practice
+/// 查看指定最近练习记录
+/// @param get get
+/// @param userId 用户id
+/// @param success 成功
+/// @param faliure 失败
++ (void)queryUserRecentRequest:(NSString *)get userId:(NSString *)userId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
 @end
 NS_ASSUME_NONNULL_END

+ 27 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.m

@@ -2337,4 +2337,31 @@
     [self request:get andWithUrl:url and:nil success:success faliure:faliure];
 }
 
+// api-teacher/student/queryUserById 参数 rongCloudUserId
+
+/// 查询指定学员信息-融云token
+/// @param get get
+/// @param rongCloudUserId rongCloudUserId
+/// @param success 成功
+/// @param faliure 失败
++ (void)queryUserById:(NSString *)get rongCloudUserId:(NSString *)rongCloudUserId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    NSString *url = [NSString stringWithFormat:@"%@%@", hostURL, @"/api-teacher/student/queryUserById"];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:rongCloudUserId forKey:@"rongCloudUserId"];
+    [self request:get andWithUrl:url and:parm success:success faliure:faliure];
+}
+
+// /api-teacher/music/sheet/user/practice
+/// 查看指定最近练习记录
+/// @param get get
+/// @param userId 用户id
+/// @param success 成功
+/// @param faliure 失败
++ (void)queryUserRecentRequest:(NSString *)get userId:(NSString *)userId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    NSString *url = [NSString stringWithFormat:@"%@%@", hostURL, @"/api-teacher/music/sheet/user/practice"];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:userId forKey:@"userId"];
+    [self request:get andWithUrl:url and:parm success:success faliure:faliure];
+}
+
 @end

+ 13 - 1
KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSRCIMDataSource.m

@@ -82,6 +82,10 @@
                 
                 NSDictionary *userDic = [dic dictionaryValueForKey:@"data"];
                 RCUserInfo *user = [[RCUserInfo alloc] initWithUserId:userId name:[userDic stringValueForKey:@"friendNickname"] portrait:[userDic stringValueForKey:@"friendAvatar"]];
+                // 附加字段
+                NSMutableDictionary *extraDic = [NSMutableDictionary dictionary];
+                [extraDic setValue:[userDic stringValueForKey:@"roleType"] forKey:@"role"];
+                user.extra = [extraDic mj_JSONString];
                 completion(user);
             }
             else {
@@ -95,6 +99,10 @@
     }
     else {
         RCUserInfo *user = [[RCUserInfo alloc] initWithUserId:UserDefault(UIDKey) name:UserDefault(NicknameKey) portrait:UserDefault(AvatarUrlKey)];
+        // 附加字段
+        NSMutableDictionary *extraDic = [NSMutableDictionary dictionary];
+        [extraDic setValue:@"TEACHER" forKey:@"role"];
+        user.extra = [extraDic mj_JSONString];
         return completion(user);
     }
 }
@@ -114,9 +122,13 @@
             NSDictionary *result = [dic dictionaryValueForKey:@"data"];
             NSString *name = [result stringValueForKey:@"nickname"];
             RCUserInfo *user = [[RCUserInfo alloc] initWithUserId:userId name:name portrait:[result stringValueForKey:@"avatar"]];
+            // 附加字段
+            NSMutableDictionary *extraDic = [NSMutableDictionary dictionary];
             if ([result boolValueForKey:@"isAdmin"]) {
-                user.extra = @"owner";
+                [extraDic setValue:@"owner" forKey:@"groupOwner"];
             }
+            [extraDic setValue:[result stringValueForKey:@"roleType"] forKey:@"role"];
+            user.extra = [extraDic mj_JSONString];
             completion(user);
         }
         else {

+ 1 - 1
KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSWebNavView.m

@@ -35,7 +35,7 @@
         make.bottom.mas_equalTo(self.mas_bottom);
         make.centerX.mas_equalTo(self.mas_centerX);
         make.left.mas_equalTo(self.mas_left).offset(70);
-        make.right.mas_equalTo(self.mas_right).offset(-50);
+        make.right.mas_equalTo(self.mas_right).offset(-70);
         make.height.mas_equalTo(44);
     }];
 }

+ 1 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Controller/ChatAddressViewController.m

@@ -193,6 +193,7 @@
     ChatAddressBodyView *listView = self.listViewArray[selectedIndex];
     NSString *searchKey = listView.searchKey;
     self.headView.searchField.text = searchKey;
+    [self.view endEditing:YES];
 }
 
 

+ 95 - 11
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Controller/KSChatConversationViewController.m

@@ -25,6 +25,9 @@
 
 #import "KSPublicAlertView.h"
 #import "KSGroupTagImageView.h"
+#import "KSChatUserDetailViewController.h"
+#import "MinePageViewController.h"
+
 #define SHARE_MUSIC_TAG (2001)
 
 @interface RCNaviDataInfo : NSObject
@@ -318,6 +321,11 @@
                 if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
                     NSDictionary *userDic = [dic dictionaryValueForKey:@"data"];
                     RCUserInfo *user = [[RCUserInfo alloc] initWithUserId:self.targetId name:[userDic stringValueForKey:@"friendNickname"] portrait:[userDic stringValueForKey:@"friendAvatar"]];
+                    // 附加字段
+                    NSMutableDictionary *extraDic = [NSMutableDictionary dictionary];
+                    [extraDic setValue:[userDic stringValueForKey:@"roleType"] forKey:@"role"];
+                    user.extra = [extraDic mj_JSONString];
+                    
                     [[RCIM sharedRCIM] refreshUserInfoCache:user withUserId:self.targetId];
                     [self refreshTitle];
                 }
@@ -328,6 +336,14 @@
                 
             }];
         }
+        else {
+            RCUserInfo *user = [RCIM sharedRCIM].currentUserInfo;
+            // 附加字段
+            NSMutableDictionary *extraDic = [NSMutableDictionary dictionary];
+            [extraDic setValue:@"TEACHER" forKey:@"role"];
+            user.extra = [extraDic mj_JSONString];
+            [[RCIM sharedRCIM] refreshUserInfoCache:user withUserId:UserDefault(UIDKey)];
+        }
     }
     else if (self.conversationType == ConversationType_GROUP) {
         // 获取群成员
@@ -341,11 +357,16 @@
                     }
                     GroupMemberModel *model = [[GroupMemberModel alloc] initWithDictionary:parm];
                     // 刷新缓存
-                    RCUserInfo *user = [[RCUserInfo alloc] initWithUserId:model.userId name:model.nickname portrait:model.avatar];
+                    RCUserInfo *user = [[RCUserInfo alloc] initWithUserId:model.imUserId name:model.nickname portrait:model.avatar];
+                    // 附加字段
+                    NSMutableDictionary *extraDic = [NSMutableDictionary dictionary];
                     if (model.isAdmin) {
-                        user.extra = @"owner";
+                        [extraDic setValue:@"owner" forKey:@"groupOwner"];
                     }
-                    [[RCIM sharedRCIM] refreshGroupUserInfoCache:user withUserId:model.userId withGroupId:self.targetId];
+                    [extraDic setValue:model.roleType forKey:@"role"];
+                    user.extra = [extraDic mj_JSONString];
+
+                    [[RCIM sharedRCIM] refreshGroupUserInfoCache:user withUserId:model.imUserId withGroupId:self.targetId];
                 }
                 [self.conversationMessageCollectionView reloadData];
             }
@@ -390,14 +411,12 @@
     if (self.conversationType == ConversationType_GROUP) {
         RCGroup *group = [[RCIM sharedRCIM] getGroupInfoCache:self.targetId];
         if (![NSString isEmptyString:group.groupName]) {
-//            self.title = group.groupName;
             [self allocTitle:group.groupName withColor:[UIColor blackColor]];
         }
     }
     else {
         RCUserInfo *userInfo = [[RCIM sharedRCIM] getUserInfoCache:self.targetId];
         if (![NSString isEmptyString:userInfo.name]) {
-//            self.title = userInfo.name;
             [self allocTitle:userInfo.name withColor:[UIColor blackColor]];
         }
     }
@@ -480,18 +499,41 @@
             for (UIView *subView in contentView.subviews) {
                 if ([subView isKindOfClass:[KSGroupTagImageView class]]) {
                     [subView removeFromSuperview];
-                    break;
                 }
             }
             RCUserInfo *user = [[RCIM sharedRCIM] getGroupUserInfoCache:model.senderUserId withGroupId:self.targetId];
-            if ([user.extra isEqualToString:@"owner"]) {
-                KSGroupTagImageView *avatarImage = [[KSGroupTagImageView alloc] initWithImage:[UIImage imageNamed:@"group_owner"]];
+            NSDictionary *extraDic = [user.extra mj_JSONObject];
+            
+            if ([[extraDic stringValueForKey:@"role"] isEqualToString:@"TEACHER"]) {
+                KSGroupTagImageView *avatarImage = [[KSGroupTagImageView alloc] initWithImage:[UIImage imageNamed:@"chat_talentTag"]];
+                [contentView addSubview:avatarImage];
+                [avatarImage mas_makeConstraints:^(MASConstraintMaker *make) {
+                    make.width.mas_equalTo(40);
+                    make.height.mas_equalTo(13);
+                    make.centerX.mas_equalTo(imageView.mas_centerX);
+                    make.bottom.mas_equalTo(imageView.mas_bottom);
+                }];
+            }
+        }
+        else if (self.conversationType == ConversationType_PRIVATE) {
+            UIView *contentView = (UIView *)((RCMessageCell *)cell).messageContentView;
+            for (UIView *subView in contentView.subviews) {
+                if ([subView isKindOfClass:[KSGroupTagImageView class]]) {
+                    [subView removeFromSuperview];
+                    break;
+                }
+            }
+            RCMessageModel *model = self.conversationDataRepository[indexPath.row];
+            RCUserInfo *user = [[RCIM sharedRCIM] getUserInfoCache:model.senderUserId];
+            NSDictionary *extraDic = [user.extra mj_JSONObject];
+            if ([[extraDic stringValueForKey:@"role"] isEqualToString:@"TEACHER"]) {
+                KSGroupTagImageView *avatarImage = [[KSGroupTagImageView alloc] initWithImage:[UIImage imageNamed:@"chat_talentTag"]];
                 [contentView addSubview:avatarImage];
                 [avatarImage mas_makeConstraints:^(MASConstraintMaker *make) {
-                    make.width.mas_equalTo(36);
-                    make.height.mas_equalTo(16);
+                    make.width.mas_equalTo(40);
+                    make.height.mas_equalTo(13);
                     make.centerX.mas_equalTo(imageView.mas_centerX);
-                    make.centerY.mas_equalTo(imageView.mas_bottom);
+                    make.bottom.mas_equalTo(imageView.mas_bottom);
                 }];
             }
         }
@@ -776,6 +818,48 @@
     return path;
 }
 
+- (void)didTapCellPortrait:(NSString *)userId {
+    if ([userId isEqualToString:UserDefault(UIDKey)]) {
+        [self displayMineInfo];
+    }
+    else {
+        
+        if (self.conversationType == ConversationType_PRIVATE) {
+            RCUserInfo *user = [[RCIM sharedRCIM] getUserInfoCache:userId];
+            
+            NSDictionary *extraDic = [user.extra mj_JSONObject];
+            if ([[extraDic stringValueForKey:@"role"] isEqualToString:@"STUDENT"]) {
+                [self displayStudent:userId];
+            }
+            else {
+                [self displayMineInfo];
+            }
+        }
+        else {
+            RCUserInfo *user = [[RCIM sharedRCIM] getGroupUserInfoCache:userId withGroupId:self.targetId];
+            NSDictionary *extraDic = [user.extra mj_JSONObject];
+            if ([[extraDic stringValueForKey:@"role"] isEqualToString:@"STUDENT"]) {
+                [self displayStudent:userId];
+            }
+            else {
+                [self displayMineInfo];
+            }
+            
+        }
+    }
+}
+
+- (void)displayMineInfo {
+    MinePageViewController *pageCtrl = [[MinePageViewController alloc] init];
+    [self.navigationController pushViewController:pageCtrl animated:YES];
+}
+
+- (void)displayStudent:(NSString *)stuentId {
+    KSChatUserDetailViewController *ctrl = [[KSChatUserDetailViewController alloc] init];
+    ctrl.rongCloudId = stuentId;
+    [self.navigationController pushViewController:ctrl animated:YES];
+}
+
 /*
 #pragma mark - Navigation
 

+ 24 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Controller/KSChatListViewController.m

@@ -11,6 +11,7 @@
 #import "KSSearchHistoryMessageController.h"
 #import "KSChatConversationViewController.h"
 #import "KSTabBarViewController.h"
+#import "KSChatTagView.h"
 
 @interface KSChatListViewController ()
 
@@ -137,6 +138,7 @@
             [[RCIMClient sharedRCIMClient] clearMessagesUnreadStatus:ConversationType_GROUP targetId:model.targetId];
         }
         else {
+            
             [array addObject:model];
         }
     }
@@ -187,7 +189,11 @@
     UIView *tagView = (UIView *)((RCConversationCell *)cell).conversationTagView;
     imageView.contentMode = UIViewContentModeScaleAspectFill;
     imageView.layer.masksToBounds = YES;
-    
+    for (UIView *view in cell.contentView.subviews) {
+        if ([view isKindOfClass:[KSChatTagView class]]) {
+            [view removeFromSuperview];
+        }
+    }
     RCConversationModel *model = self.conversationListDataSource[indexPath.row];
     if (model.conversationType == ConversationType_GROUP) {
         if ([model.targetId containsString:@"FAN"]) { // 粉丝群
@@ -205,6 +211,23 @@
             tagImage.frame = CGRectMake(0, 2, 45, 17);
         }
     }
+    else if (model.conversationType == ConversationType_PRIVATE) {
+        UIView *contentView = (UIView *)((RCConversationCell *)cell).contentView;
+        RCUserInfo *user = [[RCIM sharedRCIM] getUserInfoCache:model.targetId];
+        NSDictionary *extraDic = [user.extra mj_JSONObject];
+        if ([[extraDic stringValueForKey:@"role"] isEqualToString:@"TEACHER"]) {
+            KSChatTagView *avatarImage = [[KSChatTagView alloc] initWithImage:[UIImage imageNamed:@"chat_talentList"]];
+            [contentView addSubview:avatarImage];
+            [avatarImage mas_makeConstraints:^(MASConstraintMaker *make) {
+                make.width.mas_equalTo(44);
+                make.height.mas_equalTo(13);
+                make.centerX.mas_equalTo(imageView.mas_centerX);
+                make.bottom.mas_equalTo(imageView.mas_bottom);
+            }];
+        }
+        
+    }
+    
 }
 
 - (UIView *)stateView {

+ 18 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Controller/KSChatUserDetailViewController.h

@@ -0,0 +1,18 @@
+//
+//  KSChatUserDetailViewController.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2022/10/17.
+//
+
+#import "KSBaseViewController.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSChatUserDetailViewController : KSBaseViewController
+
+@property (nonatomic, strong) NSString *rongCloudId;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 175 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Controller/KSChatUserDetailViewController.m

@@ -0,0 +1,175 @@
+//
+//  KSChatUserDetailViewController.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/10/18.
+//
+
+#import "KSChatUserDetailViewController.h"
+#import "UserDetailNavView.h"
+#import "ChatUserInfo.h"
+#import "UserDetailBodyView.h"
+#import "UserDetailBottomView.h"
+#import "RecentPracticeModel.h"
+#import "KSBaseWKWebViewController.h"
+
+@interface KSChatUserDetailViewController ()<UIScrollViewDelegate>
+
+@property (nonatomic, strong) UserDetailNavView *navView;
+
+@property (nonatomic, strong) ChatUserInfo *userInfo;
+
+@property (nonatomic, strong) UserDetailBodyView *bodyView;
+
+@property (nonatomic, strong) UserDetailBottomView *bottomView;
+@end
+
+@implementation KSChatUserDetailViewController
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    self.ks_prefersNavigationBarHidden = YES;
+    [self configUI];
+    
+}
+
+- (void)configUI {
+    
+    UIImage *bgImage = [UIImage imageNamed:@"user_detailBg"];
+    CGFloat height = bgImage.size.height / bgImage.size.width * kScreenWidth;
+    UIImageView *imageView = [[UIImageView alloc] initWithImage:bgImage];
+    imageView.frame = CGRectMake(0, 0, kScreenWidth, height);
+    [self.view addSubview:imageView];
+    
+    [self.view addSubview:self.navView];
+    
+    self.scrollView.backgroundColor = [UIColor clearColor];
+    self.scrollView.delegate = self;
+    
+    [self.view bringSubviewToFront:self.scrollView];
+    [self.view bringSubviewToFront:self.navView];
+    [self.scrollView mas_remakeConstraints:^(MASConstraintMaker *make) {
+        make.top.mas_equalTo(self.view.mas_top);
+        make.left.right.mas_equalTo(self.view);
+        make.bottom.mas_equalTo(self.view.mas_bottom);
+    }];
+    
+    UIView *headView = [[UIView alloc] init];
+    headView.backgroundColor = [UIColor clearColor];
+    [self.scrollView addSubview:headView];
+    [headView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.mas_equalTo(self.scrollView.mas_top);
+        make.left.right.mas_equalTo(self.view);
+        make.height.mas_equalTo(kNaviBarHeight);
+    }];
+    
+    [self.view addSubview:self.bodyView];
+    CGFloat bodyViewHeight = [UserDetailBodyView getViewHeight];
+    if (bodyViewHeight < KPortraitHeight - kNaviBarHeight - 70) {
+        bodyViewHeight = KPortraitHeight - kNaviBarHeight - 70;
+    }
+    [self.bodyView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.mas_equalTo(headView.mas_bottom);
+        make.left.right.mas_equalTo(self.view);
+        make.height.mas_equalTo(bodyViewHeight);
+    }];
+    [self.view addSubview:self.bottomView];
+    [self.bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.mas_equalTo(self.view);
+        make.top.mas_equalTo(self.bodyView.mas_bottom);
+        make.bottom.mas_equalTo(self.scrollView.mas_bottom);
+        make.height.mas_equalTo(70);
+    }];
+}
+
+- (void)viewWillAppear:(BOOL)animated {
+    [super viewWillAppear:animated];
+    [self requestUserMessage];
+}
+
+- (void)requestUserMessage {
+    [self showhud];
+    [KSNetworkingManager queryUserById:KS_GET rongCloudUserId:self.rongCloudId success:^(NSDictionary * _Nonnull dic) {
+        if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
+            self.userInfo = [[ChatUserInfo alloc] initWithDictionary:[dic dictionaryValueForKey:@"data"]];
+            [self requestRecentPractice];
+        }
+        else {
+            
+        }
+        
+    } faliure:^(NSError * _Nonnull error) {
+        [self removehub];
+    }];
+}
+
+- (void)requestRecentPractice {
+    
+    [KSNetworkingManager queryUserRecentRequest:KS_GET userId:[NSString stringWithFormat:@"%.0f",self.userInfo.userId] success:^(NSDictionary * _Nonnull dic) {
+        [self removehub];
+        NSLog(@"%@", [dic mj_JSONString]);
+        if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
+            NSArray *sourceArray = [[dic dictionaryValueForKey:@"data"] arrayValueForKey:@"rows"];
+            [self evaluateSource:sourceArray];
+        }
+        else {
+            
+        }
+    } faliure:^(NSError * _Nonnull error) {
+        [self removehub];
+    }];
+}
+
+- (void)evaluateSource:(NSArray *)musicArray {
+    NSMutableArray *source = [NSMutableArray array];
+    for (NSDictionary *dic in musicArray) {
+        RecentPracticeModel *model = [[RecentPracticeModel alloc] initWithDictionary:dic];
+        [source addObject:model];
+    }
+    MJWeakSelf;
+    [self.bodyView configUserMessage:self.userInfo musicArray:source callback:^(NSString *songId) {
+        KSBaseWKWebViewController *ctrl = [[KSBaseWKWebViewController alloc] init];
+        ctrl.url = [NSString stringWithFormat:@"%@%@%@", WEBHOST, @"/#/music-detail?id=",songId];
+        [weakSelf.navigationController pushViewController:ctrl animated:YES];
+    }];
+}
+
+#pragma mark ----- lazying
+
+- (UserDetailNavView *)navView {
+    if (!_navView) {
+        _navView = [UserDetailNavView shareInstance];
+        MJWeakSelf;
+        [_navView navAction:^{
+            [weakSelf backAction];
+        }];
+    }
+    return _navView;
+}
+
+- (UserDetailBodyView *)bodyView {
+    if (!_bodyView) {
+        _bodyView = [UserDetailBodyView shareInstance];
+        
+    }
+    return _bodyView;
+}
+
+- (UserDetailBottomView *)bottomView {
+    if (!_bottomView) {
+        _bottomView = [UserDetailBottomView shareInstance];
+    }
+    return _bottomView;
+}
+/*
+#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

+ 7 - 3
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Group/Controller/GroupMemberViewController.m

@@ -55,11 +55,15 @@
                 [self.sourceArray addObject:model];
                 
                 // 刷新缓存
-                RCUserInfo *user = [[RCUserInfo alloc] initWithUserId:model.userId name:model.nickname portrait:model.avatar];
+                RCUserInfo *user = [[RCUserInfo alloc] initWithUserId:model.imUserId name:model.nickname portrait:model.avatar];
+                // 附加字段
+                NSMutableDictionary *extraDic = [NSMutableDictionary dictionary];
                 if (model.isAdmin) {
-                    user.extra = @"owner";
+                    [extraDic setValue:@"owner" forKey:@"groupOwner"];
                 }
-                [[RCIM sharedRCIM] refreshGroupUserInfoCache:user withUserId:model.userId withGroupId:self.groupId];
+                [extraDic setValue:model.roleType forKey:@"role"];
+                user.extra = [extraDic mj_JSONString];
+                [[RCIM sharedRCIM] refreshGroupUserInfoCache:user withUserId:model.imUserId withGroupId:self.groupId];
             }
             [self evaluateMessge];
         }

+ 7 - 3
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Group/Controller/GroupSettingViewController.m

@@ -114,11 +114,15 @@
                 [self.sourceArray addObject:model];
                 
                 // 刷新缓存
-                RCUserInfo *user = [[RCUserInfo alloc] initWithUserId:model.userId name:model.nickname portrait:model.avatar];
+                RCUserInfo *user = [[RCUserInfo alloc] initWithUserId:model.imUserId name:model.nickname portrait:model.avatar];
+                // 附加字段
+                NSMutableDictionary *extraDic = [NSMutableDictionary dictionary];
                 if (model.isAdmin) {
-                    user.extra = @"owner";
+                    [extraDic setValue:@"owner" forKey:@"groupOwner"];
                 }
-                [[RCIM sharedRCIM] refreshGroupUserInfoCache:user withUserId:model.userId withGroupId:self.groupId];
+                [extraDic setValue:model.roleType forKey:@"role"];
+                user.extra = [extraDic mj_JSONString];
+                [[RCIM sharedRCIM] refreshGroupUserInfoCache:user withUserId:model.imUserId withGroupId:self.groupId];
             }
             [self evaluateMessge];
         }

+ 11 - 2
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Group/View/GroupMemberListCell.m

@@ -24,6 +24,8 @@
 
 @property (weak, nonatomic) IBOutlet UIButton *chatButton;
 
+@property (weak, nonatomic) IBOutlet UIImageView *typeView;
+
 @end
 
 @implementation GroupMemberListCell
@@ -66,18 +68,25 @@
             self.ownerWidth.constant = 0.0f;
             self.ownerImage.hidden = YES;
         }
+        
+        if ([model.roleType isEqualToString:@"TEACHER"]) {
+            self.typeView.hidden = NO;
+        }
+        else {
+            self.typeView.hidden = YES;
+        }
     }
 }
 - (IBAction)chatAction:(id)sender {
     if (self.callback && self.sourceModel) {
         NSString *name = @"";
         if ([NSString isEmptyString:self.sourceModel.nickname]) {
-            name = [NSString stringWithFormat:@"用户:%@",self.sourceModel.userId];
+            name = [NSString stringWithFormat:@"用户:%@",self.sourceModel.imUserId];
         }
         else {
             name = self.sourceModel.nickname;
         }
-        self.callback(self.sourceModel.userId, name);
+        self.callback(self.sourceModel.imUserId, name);
     }
 }
 

+ 14 - 3
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Group/View/GroupMemberListCell.xib

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21225" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
     <device id="retina6_1" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21207"/>
         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
         <capability name="System colors in document resources" minToolsVersion="11.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@@ -29,7 +29,7 @@
                                 </constraints>
                                 <userDefinedRuntimeAttributes>
                                     <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                        <real key="value" value="6"/>
+                                        <real key="value" value="4"/>
                                     </userDefinedRuntimeAttribute>
                                 </userDefinedRuntimeAttributes>
                             </imageView>
@@ -61,10 +61,18 @@
                                     <constraint firstAttribute="height" constant="18" id="j6N-l8-9Rq"/>
                                 </constraints>
                             </imageView>
+                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="chat_talentList" translatesAutoresizingMaskIntoConstraints="NO" id="YnH-PP-xYM">
+                                <rect key="frame" x="14" y="40" width="44" height="14"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="14" id="t60-hF-4xp"/>
+                                    <constraint firstAttribute="width" constant="44" id="uA9-XN-LGN"/>
+                                </constraints>
+                            </imageView>
                         </subviews>
                         <color key="backgroundColor" systemColor="systemBackgroundColor"/>
                         <constraints>
                             <constraint firstItem="Vhp-Wi-YsA" firstAttribute="centerY" secondItem="GW3-Oz-aPr" secondAttribute="centerY" id="4jm-Nc-ex4"/>
+                            <constraint firstItem="YnH-PP-xYM" firstAttribute="bottom" secondItem="GW3-Oz-aPr" secondAttribute="bottom" id="5mE-Nx-LMv"/>
                             <constraint firstItem="C2d-wO-ajH" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Vhp-Wi-YsA" secondAttribute="trailing" constant="12" id="Aoh-be-l3n"/>
                             <constraint firstItem="GW3-Oz-aPr" firstAttribute="centerY" secondItem="3bd-Vo-rTM" secondAttribute="centerY" id="Mw8-KH-Nlc"/>
                             <constraint firstItem="Nfh-Ew-S6J" firstAttribute="leading" secondItem="GW3-Oz-aPr" secondAttribute="trailing" constant="11" id="ONQ-qG-Yor"/>
@@ -73,6 +81,7 @@
                             <constraint firstItem="C2d-wO-ajH" firstAttribute="centerY" secondItem="Vhp-Wi-YsA" secondAttribute="centerY" id="cZb-Vp-Luy"/>
                             <constraint firstItem="GW3-Oz-aPr" firstAttribute="leading" secondItem="3bd-Vo-rTM" secondAttribute="leading" constant="14" id="g2u-Nh-Bgq"/>
                             <constraint firstItem="Vhp-Wi-YsA" firstAttribute="centerY" secondItem="Nfh-Ew-S6J" secondAttribute="centerY" id="i5y-pn-1hh"/>
+                            <constraint firstItem="YnH-PP-xYM" firstAttribute="centerX" secondItem="GW3-Oz-aPr" secondAttribute="centerX" id="qfF-7x-9Ag"/>
                         </constraints>
                         <userDefinedRuntimeAttributes>
                             <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
@@ -97,12 +106,14 @@
                 <outlet property="nameLeft" destination="ZeM-2h-Bbf" id="b7i-RH-9Rk"/>
                 <outlet property="ownerImage" destination="Nfh-Ew-S6J" id="lQ9-xF-fQe"/>
                 <outlet property="ownerWidth" destination="BzO-fB-1mA" id="Fcm-vU-JYW"/>
+                <outlet property="typeView" destination="YnH-PP-xYM" id="hA7-Rh-UmY"/>
             </connections>
             <point key="canvasLocation" x="131.8840579710145" y="63.616071428571423"/>
         </tableViewCell>
     </objects>
     <resources>
         <image name="chat_chat" width="19" height="18"/>
+        <image name="chat_talentList" width="44" height="14"/>
         <image name="group_ownerList" width="34" height="18"/>
         <systemColor name="systemBackgroundColor">
             <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>

+ 23 - 3
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Group/View/GroupSettingBodyView.m

@@ -19,9 +19,12 @@ typedef void(^ChooseMemberCallback)(NSString *targetId);
 
 @property (nonatomic, strong) NSString *targetId;
 
+@property (nonatomic, strong) UIImageView *roleTypeView;
+
+
 @property (nonatomic, copy) ChooseMemberCallback callback;
 
-- (void)configMemberWithUrl:(NSString *)url name:(NSString *)name targetId:(NSString *)targetId callback:(ChooseMemberCallback)callback;
+- (void)configMemberWithUrl:(NSString *)url name:(NSString *)name targetId:(NSString *)targetId roleType:(NSString *)roleType callback:(ChooseMemberCallback)callback;
 
 @end
 
@@ -65,6 +68,16 @@ typedef void(^ChooseMemberCallback)(NSString *targetId);
     UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
     [self addGestureRecognizer:tapGesture];
     
+    self.roleTypeView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"chat_talentTag"]];
+    [self addSubview:self.roleTypeView];
+    [self.roleTypeView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.width.mas_equalTo(40);
+        make.centerX.mas_equalTo(self.memberLogo.mas_centerX);
+        make.height.mas_equalTo(13);
+        make.bottom.mas_equalTo(self.memberLogo.mas_bottom);
+    }];
+    self.roleTypeView.hidden = YES;
+    
 }
 
 - (void)tapAction:(UITapGestureRecognizer *)gesture {
@@ -73,13 +86,20 @@ typedef void(^ChooseMemberCallback)(NSString *targetId);
     }
 }
 
-- (void)configMemberWithUrl:(NSString *)url name:(NSString *)name targetId:(NSString *)targetId  callback:(ChooseMemberCallback)callback {
+- (void)configMemberWithUrl:(NSString *)url name:(NSString *)name targetId:(NSString *)targetId roleType:(NSString *)roleType callback:(ChooseMemberCallback)callback {
     if (callback) {
         self.callback = callback;
     }
     [self.memberLogo sd_setImageWithURL:[NSURL URLWithString:[url getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:CHAT_USER_DEFAULT_LOGO]];
     self.memberLabel.text = [NSString returnNoNullStringWithString:name];
     self.targetId = targetId;
+    
+    if ([roleType isEqualToString:@"TEACHER"]) {
+        self.roleTypeView.hidden = NO;
+    }
+    else {
+        self.roleTypeView.hidden = YES;
+    }
 }
 @end
 
@@ -156,7 +176,7 @@ typedef void(^ChooseMemberCallback)(NSString *targetId);
         GroupMemberModel *model = [studentArray objectAtIndex:i];
         MemberView *view = [[MemberView alloc] initWithFrame:frame];
 
-        [view configMemberWithUrl:model.avatar name:model.nickname targetId:model.userId callback:^(NSString *targetId) {
+        [view configMemberWithUrl:model.avatar name:model.nickname targetId:model.imUserId roleType:model.roleType callback:^(NSString *targetId) {
 
         }];
         [self.memberView addSubview:view];

+ 44 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Model/ChatUserInfo/ChatUserInfo.h

@@ -0,0 +1,44 @@
+//
+//  ChatUserInfo.h
+//
+//  Created by Steven  on 2022/10/18
+//  Copyright (c) 2022 __MyCompanyName__. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+
+
+@interface ChatUserInfo : NSObject <NSCoding, NSCopying>
+
+@property (nonatomic, assign) double userId;
+@property (nonatomic, assign) double isReal;
+@property (nonatomic, assign) double cloudStudySequenceDays;
+@property (nonatomic, strong) NSString *membershipStartTime;
+@property (nonatomic, strong) NSString *userStatus;
+@property (nonatomic, strong) NSString *membershipEndTime;
+@property (nonatomic, assign) double isVip;
+@property (nonatomic, assign) double lockFlag;
+@property (nonatomic, strong) NSString *updateTime;
+@property (nonatomic, strong) NSString *realName;
+@property (nonatomic, strong) NSString *userType;
+@property (nonatomic, assign) id delFlag;
+@property (nonatomic, strong) NSString *subjectName;
+@property (nonatomic, strong) NSString *cloudStudyUseLastDay;
+@property (nonatomic, assign) double memberRankSettingId;
+@property (nonatomic, assign) double gender;
+@property (nonatomic, strong) NSString *subjectId;
+@property (nonatomic, strong) NSString *birthdate;
+@property (nonatomic, strong) NSString *phone;
+@property (nonatomic, strong) NSString *idCardNo;
+@property (nonatomic, strong) NSString *avatar;
+@property (nonatomic, assign) double age;
+@property (nonatomic, strong) NSString *createTime;
+@property (nonatomic, strong) NSString *isBank;
+@property (nonatomic, strong) NSString *username;
+
++ (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
+- (instancetype)initWithDictionary:(NSDictionary *)dict;
+- (NSDictionary *)dictionaryRepresentation;
+
+@end

+ 263 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Model/ChatUserInfo/ChatUserInfo.m

@@ -0,0 +1,263 @@
+//
+//  ChatUserInfo.m
+//
+//  Created by Steven  on 2022/10/18
+//  Copyright (c) 2022 __MyCompanyName__. All rights reserved.
+//
+
+#import "ChatUserInfo.h"
+
+
+NSString *const kChatUserInfoUserId = @"userId";
+NSString *const kChatUserInfoIsReal = @"isReal";
+NSString *const kChatUserInfoCloudStudySequenceDays = @"cloudStudySequenceDays";
+NSString *const kChatUserInfoMembershipStartTime = @"membershipStartTime";
+NSString *const kChatUserInfoUserStatus = @"userStatus";
+NSString *const kChatUserInfoMembershipEndTime = @"membershipEndTime";
+NSString *const kChatUserInfoIsVip = @"isVip";
+NSString *const kChatUserInfoLockFlag = @"lockFlag";
+NSString *const kChatUserInfoUpdateTime = @"updateTime";
+NSString *const kChatUserInfoRealName = @"realName";
+NSString *const kChatUserInfoUserType = @"userType";
+NSString *const kChatUserInfoDelFlag = @"delFlag";
+NSString *const kChatUserInfoSubjectName = @"subjectName";
+NSString *const kChatUserInfoCloudStudyUseLastDay = @"cloudStudyUseLastDay";
+NSString *const kChatUserInfoMemberRankSettingId = @"memberRankSettingId";
+NSString *const kChatUserInfoGender = @"gender";
+NSString *const kChatUserInfoSubjectId = @"subjectId";
+NSString *const kChatUserInfoBirthdate = @"birthdate";
+NSString *const kChatUserInfoPhone = @"phone";
+NSString *const kChatUserInfoIdCardNo = @"idCardNo";
+NSString *const kChatUserInfoAvatar = @"avatar";
+NSString *const kChatUserInfoAge = @"age";
+NSString *const kChatUserInfoCreateTime = @"createTime";
+NSString *const kChatUserInfoIsBank = @"isBank";
+NSString *const kChatUserInfoUsername = @"username";
+
+
+@interface ChatUserInfo ()
+
+- (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict;
+
+@end
+
+@implementation ChatUserInfo
+
+@synthesize userId = _userId;
+@synthesize isReal = _isReal;
+@synthesize cloudStudySequenceDays = _cloudStudySequenceDays;
+@synthesize membershipStartTime = _membershipStartTime;
+@synthesize userStatus = _userStatus;
+@synthesize membershipEndTime = _membershipEndTime;
+@synthesize isVip = _isVip;
+@synthesize lockFlag = _lockFlag;
+@synthesize updateTime = _updateTime;
+@synthesize realName = _realName;
+@synthesize userType = _userType;
+@synthesize delFlag = _delFlag;
+@synthesize subjectName = _subjectName;
+@synthesize cloudStudyUseLastDay = _cloudStudyUseLastDay;
+@synthesize memberRankSettingId = _memberRankSettingId;
+@synthesize gender = _gender;
+@synthesize subjectId = _subjectId;
+@synthesize birthdate = _birthdate;
+@synthesize phone = _phone;
+@synthesize idCardNo = _idCardNo;
+@synthesize avatar = _avatar;
+@synthesize age = _age;
+@synthesize createTime = _createTime;
+@synthesize isBank = _isBank;
+@synthesize username = _username;
+
+
++ (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.userId = [[self objectOrNilForKey:kChatUserInfoUserId fromDictionary:dict] doubleValue];
+            self.isReal = [[self objectOrNilForKey:kChatUserInfoIsReal fromDictionary:dict] doubleValue];
+            self.cloudStudySequenceDays = [[self objectOrNilForKey:kChatUserInfoCloudStudySequenceDays fromDictionary:dict] doubleValue];
+            self.membershipStartTime = [self objectOrNilForKey:kChatUserInfoMembershipStartTime fromDictionary:dict];
+            self.userStatus = [self objectOrNilForKey:kChatUserInfoUserStatus fromDictionary:dict];
+            self.membershipEndTime = [self objectOrNilForKey:kChatUserInfoMembershipEndTime fromDictionary:dict];
+            self.isVip = [[self objectOrNilForKey:kChatUserInfoIsVip fromDictionary:dict] doubleValue];
+            self.lockFlag = [[self objectOrNilForKey:kChatUserInfoLockFlag fromDictionary:dict] doubleValue];
+            self.updateTime = [self objectOrNilForKey:kChatUserInfoUpdateTime fromDictionary:dict];
+            self.realName = [self objectOrNilForKey:kChatUserInfoRealName fromDictionary:dict];
+            self.userType = [self objectOrNilForKey:kChatUserInfoUserType fromDictionary:dict];
+            self.delFlag = [self objectOrNilForKey:kChatUserInfoDelFlag fromDictionary:dict];
+            self.subjectName = [self objectOrNilForKey:kChatUserInfoSubjectName fromDictionary:dict];
+            self.cloudStudyUseLastDay = [self objectOrNilForKey:kChatUserInfoCloudStudyUseLastDay fromDictionary:dict];
+            self.memberRankSettingId = [[self objectOrNilForKey:kChatUserInfoMemberRankSettingId fromDictionary:dict] doubleValue];
+            self.gender = [[self objectOrNilForKey:kChatUserInfoGender fromDictionary:dict] doubleValue];
+            self.subjectId = [self objectOrNilForKey:kChatUserInfoSubjectId fromDictionary:dict];
+            self.birthdate = [self objectOrNilForKey:kChatUserInfoBirthdate fromDictionary:dict];
+            self.phone = [self objectOrNilForKey:kChatUserInfoPhone fromDictionary:dict];
+            self.idCardNo = [self objectOrNilForKey:kChatUserInfoIdCardNo fromDictionary:dict];
+            self.avatar = [self objectOrNilForKey:kChatUserInfoAvatar fromDictionary:dict];
+            self.age = [[self objectOrNilForKey:kChatUserInfoAge fromDictionary:dict] doubleValue];
+            self.createTime = [self objectOrNilForKey:kChatUserInfoCreateTime fromDictionary:dict];
+            self.isBank = [self objectOrNilForKey:kChatUserInfoIsBank fromDictionary:dict];
+            self.username = [self objectOrNilForKey:kChatUserInfoUsername fromDictionary:dict];
+
+    }
+    
+    return self;
+    
+}
+
+- (NSDictionary *)dictionaryRepresentation
+{
+    NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.userId] forKey:kChatUserInfoUserId];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.isReal] forKey:kChatUserInfoIsReal];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.cloudStudySequenceDays] forKey:kChatUserInfoCloudStudySequenceDays];
+    [mutableDict setValue:self.membershipStartTime forKey:kChatUserInfoMembershipStartTime];
+    [mutableDict setValue:self.userStatus forKey:kChatUserInfoUserStatus];
+    [mutableDict setValue:self.membershipEndTime forKey:kChatUserInfoMembershipEndTime];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.isVip] forKey:kChatUserInfoIsVip];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.lockFlag] forKey:kChatUserInfoLockFlag];
+    [mutableDict setValue:self.updateTime forKey:kChatUserInfoUpdateTime];
+    [mutableDict setValue:self.realName forKey:kChatUserInfoRealName];
+    [mutableDict setValue:self.userType forKey:kChatUserInfoUserType];
+    [mutableDict setValue:self.delFlag forKey:kChatUserInfoDelFlag];
+    [mutableDict setValue:self.subjectName forKey:kChatUserInfoSubjectName];
+    [mutableDict setValue:self.cloudStudyUseLastDay forKey:kChatUserInfoCloudStudyUseLastDay];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.memberRankSettingId] forKey:kChatUserInfoMemberRankSettingId];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.gender] forKey:kChatUserInfoGender];
+    [mutableDict setValue:self.subjectId forKey:kChatUserInfoSubjectId];
+    [mutableDict setValue:self.birthdate forKey:kChatUserInfoBirthdate];
+    [mutableDict setValue:self.phone forKey:kChatUserInfoPhone];
+    [mutableDict setValue:self.idCardNo forKey:kChatUserInfoIdCardNo];
+    [mutableDict setValue:self.avatar forKey:kChatUserInfoAvatar];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.age] forKey:kChatUserInfoAge];
+    [mutableDict setValue:self.createTime forKey:kChatUserInfoCreateTime];
+    [mutableDict setValue:self.isBank forKey:kChatUserInfoIsBank];
+    [mutableDict setValue:self.username forKey:kChatUserInfoUsername];
+
+    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];
+    return [object isEqual:[NSNull null]] ? nil : object;
+}
+
+
+#pragma mark - NSCoding Methods
+
+- (id)initWithCoder:(NSCoder *)aDecoder
+{
+    self = [super init];
+
+    self.userId = [aDecoder decodeDoubleForKey:kChatUserInfoUserId];
+    self.isReal = [aDecoder decodeDoubleForKey:kChatUserInfoIsReal];
+    self.cloudStudySequenceDays = [aDecoder decodeDoubleForKey:kChatUserInfoCloudStudySequenceDays];
+    self.membershipStartTime = [aDecoder decodeObjectForKey:kChatUserInfoMembershipStartTime];
+    self.userStatus = [aDecoder decodeObjectForKey:kChatUserInfoUserStatus];
+    self.membershipEndTime = [aDecoder decodeObjectForKey:kChatUserInfoMembershipEndTime];
+    self.isVip = [aDecoder decodeDoubleForKey:kChatUserInfoIsVip];
+    self.lockFlag = [aDecoder decodeDoubleForKey:kChatUserInfoLockFlag];
+    self.updateTime = [aDecoder decodeObjectForKey:kChatUserInfoUpdateTime];
+    self.realName = [aDecoder decodeObjectForKey:kChatUserInfoRealName];
+    self.userType = [aDecoder decodeObjectForKey:kChatUserInfoUserType];
+    self.delFlag = [aDecoder decodeObjectForKey:kChatUserInfoDelFlag];
+    self.subjectName = [aDecoder decodeObjectForKey:kChatUserInfoSubjectName];
+    self.cloudStudyUseLastDay = [aDecoder decodeObjectForKey:kChatUserInfoCloudStudyUseLastDay];
+    self.memberRankSettingId = [aDecoder decodeDoubleForKey:kChatUserInfoMemberRankSettingId];
+    self.gender = [aDecoder decodeDoubleForKey:kChatUserInfoGender];
+    self.subjectId = [aDecoder decodeObjectForKey:kChatUserInfoSubjectId];
+    self.birthdate = [aDecoder decodeObjectForKey:kChatUserInfoBirthdate];
+    self.phone = [aDecoder decodeObjectForKey:kChatUserInfoPhone];
+    self.idCardNo = [aDecoder decodeObjectForKey:kChatUserInfoIdCardNo];
+    self.avatar = [aDecoder decodeObjectForKey:kChatUserInfoAvatar];
+    self.age = [aDecoder decodeDoubleForKey:kChatUserInfoAge];
+    self.createTime = [aDecoder decodeObjectForKey:kChatUserInfoCreateTime];
+    self.isBank = [aDecoder decodeObjectForKey:kChatUserInfoIsBank];
+    self.username = [aDecoder decodeObjectForKey:kChatUserInfoUsername];
+    return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder
+{
+
+    [aCoder encodeDouble:_userId forKey:kChatUserInfoUserId];
+    [aCoder encodeDouble:_isReal forKey:kChatUserInfoIsReal];
+    [aCoder encodeDouble:_cloudStudySequenceDays forKey:kChatUserInfoCloudStudySequenceDays];
+    [aCoder encodeObject:_membershipStartTime forKey:kChatUserInfoMembershipStartTime];
+    [aCoder encodeObject:_userStatus forKey:kChatUserInfoUserStatus];
+    [aCoder encodeObject:_membershipEndTime forKey:kChatUserInfoMembershipEndTime];
+    [aCoder encodeDouble:_isVip forKey:kChatUserInfoIsVip];
+    [aCoder encodeDouble:_lockFlag forKey:kChatUserInfoLockFlag];
+    [aCoder encodeObject:_updateTime forKey:kChatUserInfoUpdateTime];
+    [aCoder encodeObject:_realName forKey:kChatUserInfoRealName];
+    [aCoder encodeObject:_userType forKey:kChatUserInfoUserType];
+    [aCoder encodeObject:_delFlag forKey:kChatUserInfoDelFlag];
+    [aCoder encodeObject:_subjectName forKey:kChatUserInfoSubjectName];
+    [aCoder encodeObject:_cloudStudyUseLastDay forKey:kChatUserInfoCloudStudyUseLastDay];
+    [aCoder encodeDouble:_memberRankSettingId forKey:kChatUserInfoMemberRankSettingId];
+    [aCoder encodeDouble:_gender forKey:kChatUserInfoGender];
+    [aCoder encodeObject:_subjectId forKey:kChatUserInfoSubjectId];
+    [aCoder encodeObject:_birthdate forKey:kChatUserInfoBirthdate];
+    [aCoder encodeObject:_phone forKey:kChatUserInfoPhone];
+    [aCoder encodeObject:_idCardNo forKey:kChatUserInfoIdCardNo];
+    [aCoder encodeObject:_avatar forKey:kChatUserInfoAvatar];
+    [aCoder encodeDouble:_age forKey:kChatUserInfoAge];
+    [aCoder encodeObject:_createTime forKey:kChatUserInfoCreateTime];
+    [aCoder encodeObject:_isBank forKey:kChatUserInfoIsBank];
+    [aCoder encodeObject:_username forKey:kChatUserInfoUsername];
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+    ChatUserInfo *copy = [[ChatUserInfo alloc] init];
+    
+    if (copy) {
+
+        copy.userId = self.userId;
+        copy.isReal = self.isReal;
+        copy.cloudStudySequenceDays = self.cloudStudySequenceDays;
+        copy.membershipStartTime = [self.membershipStartTime copyWithZone:zone];
+        copy.userStatus = [self.userStatus copyWithZone:zone];
+        copy.membershipEndTime = [self.membershipEndTime copyWithZone:zone];
+        copy.isVip = self.isVip;
+        copy.lockFlag = self.lockFlag;
+        copy.updateTime = [self.updateTime copyWithZone:zone];
+        copy.realName = [self.realName copyWithZone:zone];
+        copy.userType = [self.userType copyWithZone:zone];
+        copy.delFlag = [self.delFlag copyWithZone:zone];
+        copy.subjectName = [self.subjectName copyWithZone:zone];
+        copy.cloudStudyUseLastDay = [self.cloudStudyUseLastDay copyWithZone:zone];
+        copy.memberRankSettingId = self.memberRankSettingId;
+        copy.gender = self.gender;
+        copy.subjectId = [self.subjectId copyWithZone:zone];
+        copy.birthdate = [self.birthdate copyWithZone:zone];
+        copy.phone = [self.phone copyWithZone:zone];
+        copy.idCardNo = [self.idCardNo copyWithZone:zone];
+        copy.avatar = [self.avatar copyWithZone:zone];
+        copy.age = self.age;
+        copy.createTime = [self.createTime copyWithZone:zone];
+        copy.isBank = [self.isBank copyWithZone:zone];
+        copy.username = [self.username copyWithZone:zone];
+    }
+    
+    return copy;
+}
+
+
+@end

+ 70 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Model/ChatUserInfo/RecentPracticeModel.h

@@ -0,0 +1,70 @@
+//
+//  RecentPracticeModel.h
+//
+//  Created by Steven  on 2022/10/18
+//  Copyright (c) 2022 __MyCompanyName__. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+
+
+@interface RecentPracticeModel : NSObject <NSCoding, NSCopying>
+
+@property (nonatomic, strong) NSString *metronomeUrl;
+@property (nonatomic, strong) NSString *musicSheetName;
+@property (nonatomic, assign) double albumNums;
+@property (nonatomic, assign) double internalBaseClassIdentifier;
+@property (nonatomic, strong) NSString *xmlFileUrl;
+@property (nonatomic, assign) double showFingering;
+@property (nonatomic, assign) double albumSortNumber;
+@property (nonatomic, assign) double state;
+@property (nonatomic, strong) NSString *remark;
+@property (nonatomic, strong) NSString *titleImg;
+@property (nonatomic, assign) double notation;
+@property (nonatomic, strong) NSString *musicImg;
+@property (nonatomic, assign) double favoriteCount;
+@property (nonatomic, strong) NSString *url;
+@property (nonatomic, assign) double musicPrice;
+@property (nonatomic, assign) double sortNumber;
+@property (nonatomic, assign) double exquisiteFlag;
+@property (nonatomic, assign) id play;
+@property (nonatomic, strong) NSString *addUserAvatar;
+@property (nonatomic, strong) NSString *audioType;
+@property (nonatomic, assign) double canEvaluate;
+@property (nonatomic, assign) BOOL delFlag;
+@property (nonatomic, strong) NSString *musicTagNames;
+@property (nonatomic, strong) NSString *subjectNames;
+@property (nonatomic, strong) NSString *chargeType;
+@property (nonatomic, strong) NSString *updateTime;
+@property (nonatomic, assign) double updateBy;
+@property (nonatomic, strong) NSString *musicTag;
+@property (nonatomic, strong) NSString *extConfigJson;
+@property (nonatomic, strong) NSString *addName;
+@property (nonatomic, strong) NSString *paymentType;
+@property (nonatomic, strong) NSString *accompanimentType;
+@property (nonatomic, assign) double favorite;
+@property (nonatomic, strong) NSString *auditStatus;
+@property (nonatomic, assign) double createBy;
+@property (nonatomic, assign) double topFlag;
+@property (nonatomic, strong) NSString *midiUrl;
+@property (nonatomic, strong) NSString *composer;
+@property (nonatomic, strong) NSString *sourceType;
+@property (nonatomic, strong) NSString *firstPassAuditTime;
+@property (nonatomic, strong) NSString *mp3Type;
+@property (nonatomic, assign) id hotFlag;
+@property (nonatomic, strong) NSString *createTime;
+@property (nonatomic, assign) double playSpeed;
+@property (nonatomic, strong) NSString *audioFileUrl;
+@property (nonatomic, assign) double hasBeat;
+@property (nonatomic, strong) NSString *reason;
+@property (nonatomic, assign) double auditVersion;
+@property (nonatomic, strong) NSString *musicSubject;
+@property (nonatomic, assign) double userId;
+@property (nonatomic, strong) NSString *submitAuditTime;
+
++ (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
+- (instancetype)initWithDictionary:(NSDictionary *)dict;
+- (NSDictionary *)dictionaryRepresentation;
+
+@end

+ 445 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Model/ChatUserInfo/RecentPracticeModel.m

@@ -0,0 +1,445 @@
+//
+//  RecentPracticeModel.m
+//
+//  Created by Steven  on 2022/10/18
+//  Copyright (c) 2022 __MyCompanyName__. All rights reserved.
+//
+
+#import "RecentPracticeModel.h"
+
+
+NSString *const kRecentPracticeModelMetronomeUrl = @"metronomeUrl";
+NSString *const kRecentPracticeModelMusicSheetName = @"musicSheetName";
+NSString *const kRecentPracticeModelAlbumNums = @"albumNums";
+NSString *const kRecentPracticeModelId = @"id";
+NSString *const kRecentPracticeModelXmlFileUrl = @"xmlFileUrl";
+NSString *const kRecentPracticeModelShowFingering = @"showFingering";
+NSString *const kRecentPracticeModelAlbumSortNumber = @"albumSortNumber";
+NSString *const kRecentPracticeModelState = @"state";
+NSString *const kRecentPracticeModelRemark = @"remark";
+NSString *const kRecentPracticeModelTitleImg = @"titleImg";
+NSString *const kRecentPracticeModelNotation = @"notation";
+NSString *const kRecentPracticeModelMusicImg = @"musicImg";
+NSString *const kRecentPracticeModelFavoriteCount = @"favoriteCount";
+NSString *const kRecentPracticeModelUrl = @"url";
+NSString *const kRecentPracticeModelMusicPrice = @"musicPrice";
+NSString *const kRecentPracticeModelSortNumber = @"sortNumber";
+NSString *const kRecentPracticeModelExquisiteFlag = @"exquisiteFlag";
+NSString *const kRecentPracticeModelPlay = @"play";
+NSString *const kRecentPracticeModelAddUserAvatar = @"addUserAvatar";
+NSString *const kRecentPracticeModelAudioType = @"audioType";
+NSString *const kRecentPracticeModelCanEvaluate = @"canEvaluate";
+NSString *const kRecentPracticeModelDelFlag = @"delFlag";
+NSString *const kRecentPracticeModelMusicTagNames = @"musicTagNames";
+NSString *const kRecentPracticeModelSubjectNames = @"subjectNames";
+NSString *const kRecentPracticeModelChargeType = @"chargeType";
+NSString *const kRecentPracticeModelUpdateTime = @"updateTime";
+NSString *const kRecentPracticeModelUpdateBy = @"updateBy";
+NSString *const kRecentPracticeModelMusicTag = @"musicTag";
+NSString *const kRecentPracticeModelExtConfigJson = @"extConfigJson";
+NSString *const kRecentPracticeModelAddName = @"addName";
+NSString *const kRecentPracticeModelPaymentType = @"paymentType";
+NSString *const kRecentPracticeModelAccompanimentType = @"accompanimentType";
+NSString *const kRecentPracticeModelFavorite = @"favorite";
+NSString *const kRecentPracticeModelAuditStatus = @"auditStatus";
+NSString *const kRecentPracticeModelCreateBy = @"createBy";
+NSString *const kRecentPracticeModelTopFlag = @"topFlag";
+NSString *const kRecentPracticeModelMidiUrl = @"midiUrl";
+NSString *const kRecentPracticeModelComposer = @"composer";
+NSString *const kRecentPracticeModelSourceType = @"sourceType";
+NSString *const kRecentPracticeModelFirstPassAuditTime = @"firstPassAuditTime";
+NSString *const kRecentPracticeModelMp3Type = @"mp3Type";
+NSString *const kRecentPracticeModelHotFlag = @"hotFlag";
+NSString *const kRecentPracticeModelCreateTime = @"createTime";
+NSString *const kRecentPracticeModelPlaySpeed = @"playSpeed";
+NSString *const kRecentPracticeModelAudioFileUrl = @"audioFileUrl";
+NSString *const kRecentPracticeModelHasBeat = @"hasBeat";
+NSString *const kRecentPracticeModelReason = @"reason";
+NSString *const kRecentPracticeModelAuditVersion = @"auditVersion";
+NSString *const kRecentPracticeModelMusicSubject = @"musicSubject";
+NSString *const kRecentPracticeModelUserId = @"userId";
+NSString *const kRecentPracticeModelSubmitAuditTime = @"submitAuditTime";
+
+
+@interface RecentPracticeModel ()
+
+- (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict;
+
+@end
+
+@implementation RecentPracticeModel
+
+@synthesize metronomeUrl = _metronomeUrl;
+@synthesize musicSheetName = _musicSheetName;
+@synthesize albumNums = _albumNums;
+@synthesize internalBaseClassIdentifier = _internalBaseClassIdentifier;
+@synthesize xmlFileUrl = _xmlFileUrl;
+@synthesize showFingering = _showFingering;
+@synthesize albumSortNumber = _albumSortNumber;
+@synthesize state = _state;
+@synthesize remark = _remark;
+@synthesize titleImg = _titleImg;
+@synthesize notation = _notation;
+@synthesize musicImg = _musicImg;
+@synthesize favoriteCount = _favoriteCount;
+@synthesize url = _url;
+@synthesize musicPrice = _musicPrice;
+@synthesize sortNumber = _sortNumber;
+@synthesize exquisiteFlag = _exquisiteFlag;
+@synthesize play = _play;
+@synthesize addUserAvatar = _addUserAvatar;
+@synthesize audioType = _audioType;
+@synthesize canEvaluate = _canEvaluate;
+@synthesize delFlag = _delFlag;
+@synthesize musicTagNames = _musicTagNames;
+@synthesize subjectNames = _subjectNames;
+@synthesize chargeType = _chargeType;
+@synthesize updateTime = _updateTime;
+@synthesize updateBy = _updateBy;
+@synthesize musicTag = _musicTag;
+@synthesize extConfigJson = _extConfigJson;
+@synthesize addName = _addName;
+@synthesize paymentType = _paymentType;
+@synthesize accompanimentType = _accompanimentType;
+@synthesize favorite = _favorite;
+@synthesize auditStatus = _auditStatus;
+@synthesize createBy = _createBy;
+@synthesize topFlag = _topFlag;
+@synthesize midiUrl = _midiUrl;
+@synthesize composer = _composer;
+@synthesize sourceType = _sourceType;
+@synthesize firstPassAuditTime = _firstPassAuditTime;
+@synthesize mp3Type = _mp3Type;
+@synthesize hotFlag = _hotFlag;
+@synthesize createTime = _createTime;
+@synthesize playSpeed = _playSpeed;
+@synthesize audioFileUrl = _audioFileUrl;
+@synthesize hasBeat = _hasBeat;
+@synthesize reason = _reason;
+@synthesize auditVersion = _auditVersion;
+@synthesize musicSubject = _musicSubject;
+@synthesize userId = _userId;
+@synthesize submitAuditTime = _submitAuditTime;
+
+
++ (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.metronomeUrl = [self objectOrNilForKey:kRecentPracticeModelMetronomeUrl fromDictionary:dict];
+            self.musicSheetName = [self objectOrNilForKey:kRecentPracticeModelMusicSheetName fromDictionary:dict];
+            self.albumNums = [[self objectOrNilForKey:kRecentPracticeModelAlbumNums fromDictionary:dict] doubleValue];
+            self.internalBaseClassIdentifier = [[self objectOrNilForKey:kRecentPracticeModelId fromDictionary:dict] doubleValue];
+            self.xmlFileUrl = [self objectOrNilForKey:kRecentPracticeModelXmlFileUrl fromDictionary:dict];
+            self.showFingering = [[self objectOrNilForKey:kRecentPracticeModelShowFingering fromDictionary:dict] doubleValue];
+            self.albumSortNumber = [[self objectOrNilForKey:kRecentPracticeModelAlbumSortNumber fromDictionary:dict] doubleValue];
+            self.state = [[self objectOrNilForKey:kRecentPracticeModelState fromDictionary:dict] doubleValue];
+            self.remark = [self objectOrNilForKey:kRecentPracticeModelRemark fromDictionary:dict];
+            self.titleImg = [self objectOrNilForKey:kRecentPracticeModelTitleImg fromDictionary:dict];
+            self.notation = [[self objectOrNilForKey:kRecentPracticeModelNotation fromDictionary:dict] doubleValue];
+            self.musicImg = [self objectOrNilForKey:kRecentPracticeModelMusicImg fromDictionary:dict];
+            self.favoriteCount = [[self objectOrNilForKey:kRecentPracticeModelFavoriteCount fromDictionary:dict] doubleValue];
+            self.url = [self objectOrNilForKey:kRecentPracticeModelUrl fromDictionary:dict];
+            self.musicPrice = [[self objectOrNilForKey:kRecentPracticeModelMusicPrice fromDictionary:dict] doubleValue];
+            self.sortNumber = [[self objectOrNilForKey:kRecentPracticeModelSortNumber fromDictionary:dict] doubleValue];
+            self.exquisiteFlag = [[self objectOrNilForKey:kRecentPracticeModelExquisiteFlag fromDictionary:dict] doubleValue];
+            self.play = [self objectOrNilForKey:kRecentPracticeModelPlay fromDictionary:dict];
+            self.addUserAvatar = [self objectOrNilForKey:kRecentPracticeModelAddUserAvatar fromDictionary:dict];
+            self.audioType = [self objectOrNilForKey:kRecentPracticeModelAudioType fromDictionary:dict];
+            self.canEvaluate = [[self objectOrNilForKey:kRecentPracticeModelCanEvaluate fromDictionary:dict] doubleValue];
+            self.delFlag = [[self objectOrNilForKey:kRecentPracticeModelDelFlag fromDictionary:dict] boolValue];
+            self.musicTagNames = [self objectOrNilForKey:kRecentPracticeModelMusicTagNames fromDictionary:dict];
+            self.subjectNames = [self objectOrNilForKey:kRecentPracticeModelSubjectNames fromDictionary:dict];
+            self.chargeType = [self objectOrNilForKey:kRecentPracticeModelChargeType fromDictionary:dict];
+            self.updateTime = [self objectOrNilForKey:kRecentPracticeModelUpdateTime fromDictionary:dict];
+            self.updateBy = [[self objectOrNilForKey:kRecentPracticeModelUpdateBy fromDictionary:dict] doubleValue];
+            self.musicTag = [self objectOrNilForKey:kRecentPracticeModelMusicTag fromDictionary:dict];
+            self.extConfigJson = [self objectOrNilForKey:kRecentPracticeModelExtConfigJson fromDictionary:dict];
+            self.addName = [self objectOrNilForKey:kRecentPracticeModelAddName fromDictionary:dict];
+            self.paymentType = [self objectOrNilForKey:kRecentPracticeModelPaymentType fromDictionary:dict];
+            self.accompanimentType = [self objectOrNilForKey:kRecentPracticeModelAccompanimentType fromDictionary:dict];
+            self.favorite = [[self objectOrNilForKey:kRecentPracticeModelFavorite fromDictionary:dict] doubleValue];
+            self.auditStatus = [self objectOrNilForKey:kRecentPracticeModelAuditStatus fromDictionary:dict];
+            self.createBy = [[self objectOrNilForKey:kRecentPracticeModelCreateBy fromDictionary:dict] doubleValue];
+            self.topFlag = [[self objectOrNilForKey:kRecentPracticeModelTopFlag fromDictionary:dict] doubleValue];
+            self.midiUrl = [self objectOrNilForKey:kRecentPracticeModelMidiUrl fromDictionary:dict];
+            self.composer = [self objectOrNilForKey:kRecentPracticeModelComposer fromDictionary:dict];
+            self.sourceType = [self objectOrNilForKey:kRecentPracticeModelSourceType fromDictionary:dict];
+            self.firstPassAuditTime = [self objectOrNilForKey:kRecentPracticeModelFirstPassAuditTime fromDictionary:dict];
+            self.mp3Type = [self objectOrNilForKey:kRecentPracticeModelMp3Type fromDictionary:dict];
+            self.hotFlag = [self objectOrNilForKey:kRecentPracticeModelHotFlag fromDictionary:dict];
+            self.createTime = [self objectOrNilForKey:kRecentPracticeModelCreateTime fromDictionary:dict];
+            self.playSpeed = [[self objectOrNilForKey:kRecentPracticeModelPlaySpeed fromDictionary:dict] doubleValue];
+            self.audioFileUrl = [self objectOrNilForKey:kRecentPracticeModelAudioFileUrl fromDictionary:dict];
+            self.hasBeat = [[self objectOrNilForKey:kRecentPracticeModelHasBeat fromDictionary:dict] doubleValue];
+            self.reason = [self objectOrNilForKey:kRecentPracticeModelReason fromDictionary:dict];
+            self.auditVersion = [[self objectOrNilForKey:kRecentPracticeModelAuditVersion fromDictionary:dict] doubleValue];
+            self.musicSubject = [self objectOrNilForKey:kRecentPracticeModelMusicSubject fromDictionary:dict];
+            self.userId = [[self objectOrNilForKey:kRecentPracticeModelUserId fromDictionary:dict] doubleValue];
+            self.submitAuditTime = [self objectOrNilForKey:kRecentPracticeModelSubmitAuditTime fromDictionary:dict];
+
+    }
+    
+    return self;
+    
+}
+
+- (NSDictionary *)dictionaryRepresentation
+{
+    NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
+    [mutableDict setValue:self.metronomeUrl forKey:kRecentPracticeModelMetronomeUrl];
+    [mutableDict setValue:self.musicSheetName forKey:kRecentPracticeModelMusicSheetName];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.albumNums] forKey:kRecentPracticeModelAlbumNums];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.internalBaseClassIdentifier] forKey:kRecentPracticeModelId];
+    [mutableDict setValue:self.xmlFileUrl forKey:kRecentPracticeModelXmlFileUrl];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.showFingering] forKey:kRecentPracticeModelShowFingering];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.albumSortNumber] forKey:kRecentPracticeModelAlbumSortNumber];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.state] forKey:kRecentPracticeModelState];
+    [mutableDict setValue:self.remark forKey:kRecentPracticeModelRemark];
+    [mutableDict setValue:self.titleImg forKey:kRecentPracticeModelTitleImg];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.notation] forKey:kRecentPracticeModelNotation];
+    [mutableDict setValue:self.musicImg forKey:kRecentPracticeModelMusicImg];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.favoriteCount] forKey:kRecentPracticeModelFavoriteCount];
+    [mutableDict setValue:self.url forKey:kRecentPracticeModelUrl];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.musicPrice] forKey:kRecentPracticeModelMusicPrice];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.sortNumber] forKey:kRecentPracticeModelSortNumber];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.exquisiteFlag] forKey:kRecentPracticeModelExquisiteFlag];
+    [mutableDict setValue:self.play forKey:kRecentPracticeModelPlay];
+    [mutableDict setValue:self.addUserAvatar forKey:kRecentPracticeModelAddUserAvatar];
+    [mutableDict setValue:self.audioType forKey:kRecentPracticeModelAudioType];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.canEvaluate] forKey:kRecentPracticeModelCanEvaluate];
+    [mutableDict setValue:[NSNumber numberWithBool:self.delFlag] forKey:kRecentPracticeModelDelFlag];
+    [mutableDict setValue:self.musicTagNames forKey:kRecentPracticeModelMusicTagNames];
+    [mutableDict setValue:self.subjectNames forKey:kRecentPracticeModelSubjectNames];
+    [mutableDict setValue:self.chargeType forKey:kRecentPracticeModelChargeType];
+    [mutableDict setValue:self.updateTime forKey:kRecentPracticeModelUpdateTime];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.updateBy] forKey:kRecentPracticeModelUpdateBy];
+    [mutableDict setValue:self.musicTag forKey:kRecentPracticeModelMusicTag];
+    [mutableDict setValue:self.extConfigJson forKey:kRecentPracticeModelExtConfigJson];
+    [mutableDict setValue:self.addName forKey:kRecentPracticeModelAddName];
+    [mutableDict setValue:self.paymentType forKey:kRecentPracticeModelPaymentType];
+    [mutableDict setValue:self.accompanimentType forKey:kRecentPracticeModelAccompanimentType];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.favorite] forKey:kRecentPracticeModelFavorite];
+    [mutableDict setValue:self.auditStatus forKey:kRecentPracticeModelAuditStatus];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.createBy] forKey:kRecentPracticeModelCreateBy];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.topFlag] forKey:kRecentPracticeModelTopFlag];
+    [mutableDict setValue:self.midiUrl forKey:kRecentPracticeModelMidiUrl];
+    [mutableDict setValue:self.composer forKey:kRecentPracticeModelComposer];
+    [mutableDict setValue:self.sourceType forKey:kRecentPracticeModelSourceType];
+    [mutableDict setValue:self.firstPassAuditTime forKey:kRecentPracticeModelFirstPassAuditTime];
+    [mutableDict setValue:self.mp3Type forKey:kRecentPracticeModelMp3Type];
+    [mutableDict setValue:self.hotFlag forKey:kRecentPracticeModelHotFlag];
+    [mutableDict setValue:self.createTime forKey:kRecentPracticeModelCreateTime];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.playSpeed] forKey:kRecentPracticeModelPlaySpeed];
+    [mutableDict setValue:self.audioFileUrl forKey:kRecentPracticeModelAudioFileUrl];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.hasBeat] forKey:kRecentPracticeModelHasBeat];
+    [mutableDict setValue:self.reason forKey:kRecentPracticeModelReason];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.auditVersion] forKey:kRecentPracticeModelAuditVersion];
+    [mutableDict setValue:self.musicSubject forKey:kRecentPracticeModelMusicSubject];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.userId] forKey:kRecentPracticeModelUserId];
+    [mutableDict setValue:self.submitAuditTime forKey:kRecentPracticeModelSubmitAuditTime];
+
+    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];
+    return [object isEqual:[NSNull null]] ? nil : object;
+}
+
+
+#pragma mark - NSCoding Methods
+
+- (id)initWithCoder:(NSCoder *)aDecoder
+{
+    self = [super init];
+
+    self.metronomeUrl = [aDecoder decodeObjectForKey:kRecentPracticeModelMetronomeUrl];
+    self.musicSheetName = [aDecoder decodeObjectForKey:kRecentPracticeModelMusicSheetName];
+    self.albumNums = [aDecoder decodeDoubleForKey:kRecentPracticeModelAlbumNums];
+    self.internalBaseClassIdentifier = [aDecoder decodeDoubleForKey:kRecentPracticeModelId];
+    self.xmlFileUrl = [aDecoder decodeObjectForKey:kRecentPracticeModelXmlFileUrl];
+    self.showFingering = [aDecoder decodeDoubleForKey:kRecentPracticeModelShowFingering];
+    self.albumSortNumber = [aDecoder decodeDoubleForKey:kRecentPracticeModelAlbumSortNumber];
+    self.state = [aDecoder decodeDoubleForKey:kRecentPracticeModelState];
+    self.remark = [aDecoder decodeObjectForKey:kRecentPracticeModelRemark];
+    self.titleImg = [aDecoder decodeObjectForKey:kRecentPracticeModelTitleImg];
+    self.notation = [aDecoder decodeDoubleForKey:kRecentPracticeModelNotation];
+    self.musicImg = [aDecoder decodeObjectForKey:kRecentPracticeModelMusicImg];
+    self.favoriteCount = [aDecoder decodeDoubleForKey:kRecentPracticeModelFavoriteCount];
+    self.url = [aDecoder decodeObjectForKey:kRecentPracticeModelUrl];
+    self.musicPrice = [aDecoder decodeDoubleForKey:kRecentPracticeModelMusicPrice];
+    self.sortNumber = [aDecoder decodeDoubleForKey:kRecentPracticeModelSortNumber];
+    self.exquisiteFlag = [aDecoder decodeDoubleForKey:kRecentPracticeModelExquisiteFlag];
+    self.play = [aDecoder decodeObjectForKey:kRecentPracticeModelPlay];
+    self.addUserAvatar = [aDecoder decodeObjectForKey:kRecentPracticeModelAddUserAvatar];
+    self.audioType = [aDecoder decodeObjectForKey:kRecentPracticeModelAudioType];
+    self.canEvaluate = [aDecoder decodeDoubleForKey:kRecentPracticeModelCanEvaluate];
+    self.delFlag = [aDecoder decodeBoolForKey:kRecentPracticeModelDelFlag];
+    self.musicTagNames = [aDecoder decodeObjectForKey:kRecentPracticeModelMusicTagNames];
+    self.subjectNames = [aDecoder decodeObjectForKey:kRecentPracticeModelSubjectNames];
+    self.chargeType = [aDecoder decodeObjectForKey:kRecentPracticeModelChargeType];
+    self.updateTime = [aDecoder decodeObjectForKey:kRecentPracticeModelUpdateTime];
+    self.updateBy = [aDecoder decodeDoubleForKey:kRecentPracticeModelUpdateBy];
+    self.musicTag = [aDecoder decodeObjectForKey:kRecentPracticeModelMusicTag];
+    self.extConfigJson = [aDecoder decodeObjectForKey:kRecentPracticeModelExtConfigJson];
+    self.addName = [aDecoder decodeObjectForKey:kRecentPracticeModelAddName];
+    self.paymentType = [aDecoder decodeObjectForKey:kRecentPracticeModelPaymentType];
+    self.accompanimentType = [aDecoder decodeObjectForKey:kRecentPracticeModelAccompanimentType];
+    self.favorite = [aDecoder decodeDoubleForKey:kRecentPracticeModelFavorite];
+    self.auditStatus = [aDecoder decodeObjectForKey:kRecentPracticeModelAuditStatus];
+    self.createBy = [aDecoder decodeDoubleForKey:kRecentPracticeModelCreateBy];
+    self.topFlag = [aDecoder decodeDoubleForKey:kRecentPracticeModelTopFlag];
+    self.midiUrl = [aDecoder decodeObjectForKey:kRecentPracticeModelMidiUrl];
+    self.composer = [aDecoder decodeObjectForKey:kRecentPracticeModelComposer];
+    self.sourceType = [aDecoder decodeObjectForKey:kRecentPracticeModelSourceType];
+    self.firstPassAuditTime = [aDecoder decodeObjectForKey:kRecentPracticeModelFirstPassAuditTime];
+    self.mp3Type = [aDecoder decodeObjectForKey:kRecentPracticeModelMp3Type];
+    self.hotFlag = [aDecoder decodeObjectForKey:kRecentPracticeModelHotFlag];
+    self.createTime = [aDecoder decodeObjectForKey:kRecentPracticeModelCreateTime];
+    self.playSpeed = [aDecoder decodeDoubleForKey:kRecentPracticeModelPlaySpeed];
+    self.audioFileUrl = [aDecoder decodeObjectForKey:kRecentPracticeModelAudioFileUrl];
+    self.hasBeat = [aDecoder decodeDoubleForKey:kRecentPracticeModelHasBeat];
+    self.reason = [aDecoder decodeObjectForKey:kRecentPracticeModelReason];
+    self.auditVersion = [aDecoder decodeDoubleForKey:kRecentPracticeModelAuditVersion];
+    self.musicSubject = [aDecoder decodeObjectForKey:kRecentPracticeModelMusicSubject];
+    self.userId = [aDecoder decodeDoubleForKey:kRecentPracticeModelUserId];
+    self.submitAuditTime = [aDecoder decodeObjectForKey:kRecentPracticeModelSubmitAuditTime];
+    return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder
+{
+
+    [aCoder encodeObject:_metronomeUrl forKey:kRecentPracticeModelMetronomeUrl];
+    [aCoder encodeObject:_musicSheetName forKey:kRecentPracticeModelMusicSheetName];
+    [aCoder encodeDouble:_albumNums forKey:kRecentPracticeModelAlbumNums];
+    [aCoder encodeDouble:_internalBaseClassIdentifier forKey:kRecentPracticeModelId];
+    [aCoder encodeObject:_xmlFileUrl forKey:kRecentPracticeModelXmlFileUrl];
+    [aCoder encodeDouble:_showFingering forKey:kRecentPracticeModelShowFingering];
+    [aCoder encodeDouble:_albumSortNumber forKey:kRecentPracticeModelAlbumSortNumber];
+    [aCoder encodeDouble:_state forKey:kRecentPracticeModelState];
+    [aCoder encodeObject:_remark forKey:kRecentPracticeModelRemark];
+    [aCoder encodeObject:_titleImg forKey:kRecentPracticeModelTitleImg];
+    [aCoder encodeDouble:_notation forKey:kRecentPracticeModelNotation];
+    [aCoder encodeObject:_musicImg forKey:kRecentPracticeModelMusicImg];
+    [aCoder encodeDouble:_favoriteCount forKey:kRecentPracticeModelFavoriteCount];
+    [aCoder encodeObject:_url forKey:kRecentPracticeModelUrl];
+    [aCoder encodeDouble:_musicPrice forKey:kRecentPracticeModelMusicPrice];
+    [aCoder encodeDouble:_sortNumber forKey:kRecentPracticeModelSortNumber];
+    [aCoder encodeDouble:_exquisiteFlag forKey:kRecentPracticeModelExquisiteFlag];
+    [aCoder encodeObject:_play forKey:kRecentPracticeModelPlay];
+    [aCoder encodeObject:_addUserAvatar forKey:kRecentPracticeModelAddUserAvatar];
+    [aCoder encodeObject:_audioType forKey:kRecentPracticeModelAudioType];
+    [aCoder encodeDouble:_canEvaluate forKey:kRecentPracticeModelCanEvaluate];
+    [aCoder encodeBool:_delFlag forKey:kRecentPracticeModelDelFlag];
+    [aCoder encodeObject:_musicTagNames forKey:kRecentPracticeModelMusicTagNames];
+    [aCoder encodeObject:_subjectNames forKey:kRecentPracticeModelSubjectNames];
+    [aCoder encodeObject:_chargeType forKey:kRecentPracticeModelChargeType];
+    [aCoder encodeObject:_updateTime forKey:kRecentPracticeModelUpdateTime];
+    [aCoder encodeDouble:_updateBy forKey:kRecentPracticeModelUpdateBy];
+    [aCoder encodeObject:_musicTag forKey:kRecentPracticeModelMusicTag];
+    [aCoder encodeObject:_extConfigJson forKey:kRecentPracticeModelExtConfigJson];
+    [aCoder encodeObject:_addName forKey:kRecentPracticeModelAddName];
+    [aCoder encodeObject:_paymentType forKey:kRecentPracticeModelPaymentType];
+    [aCoder encodeObject:_accompanimentType forKey:kRecentPracticeModelAccompanimentType];
+    [aCoder encodeDouble:_favorite forKey:kRecentPracticeModelFavorite];
+    [aCoder encodeObject:_auditStatus forKey:kRecentPracticeModelAuditStatus];
+    [aCoder encodeDouble:_createBy forKey:kRecentPracticeModelCreateBy];
+    [aCoder encodeDouble:_topFlag forKey:kRecentPracticeModelTopFlag];
+    [aCoder encodeObject:_midiUrl forKey:kRecentPracticeModelMidiUrl];
+    [aCoder encodeObject:_composer forKey:kRecentPracticeModelComposer];
+    [aCoder encodeObject:_sourceType forKey:kRecentPracticeModelSourceType];
+    [aCoder encodeObject:_firstPassAuditTime forKey:kRecentPracticeModelFirstPassAuditTime];
+    [aCoder encodeObject:_mp3Type forKey:kRecentPracticeModelMp3Type];
+    [aCoder encodeObject:_hotFlag forKey:kRecentPracticeModelHotFlag];
+    [aCoder encodeObject:_createTime forKey:kRecentPracticeModelCreateTime];
+    [aCoder encodeDouble:_playSpeed forKey:kRecentPracticeModelPlaySpeed];
+    [aCoder encodeObject:_audioFileUrl forKey:kRecentPracticeModelAudioFileUrl];
+    [aCoder encodeDouble:_hasBeat forKey:kRecentPracticeModelHasBeat];
+    [aCoder encodeObject:_reason forKey:kRecentPracticeModelReason];
+    [aCoder encodeDouble:_auditVersion forKey:kRecentPracticeModelAuditVersion];
+    [aCoder encodeObject:_musicSubject forKey:kRecentPracticeModelMusicSubject];
+    [aCoder encodeDouble:_userId forKey:kRecentPracticeModelUserId];
+    [aCoder encodeObject:_submitAuditTime forKey:kRecentPracticeModelSubmitAuditTime];
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+    RecentPracticeModel *copy = [[RecentPracticeModel alloc] init];
+    
+    if (copy) {
+
+        copy.metronomeUrl = [self.metronomeUrl copyWithZone:zone];
+        copy.musicSheetName = [self.musicSheetName copyWithZone:zone];
+        copy.albumNums = self.albumNums;
+        copy.internalBaseClassIdentifier = self.internalBaseClassIdentifier;
+        copy.xmlFileUrl = [self.xmlFileUrl copyWithZone:zone];
+        copy.showFingering = self.showFingering;
+        copy.albumSortNumber = self.albumSortNumber;
+        copy.state = self.state;
+        copy.remark = [self.remark copyWithZone:zone];
+        copy.titleImg = [self.titleImg copyWithZone:zone];
+        copy.notation = self.notation;
+        copy.musicImg = [self.musicImg copyWithZone:zone];
+        copy.favoriteCount = self.favoriteCount;
+        copy.url = [self.url copyWithZone:zone];
+        copy.musicPrice = self.musicPrice;
+        copy.sortNumber = self.sortNumber;
+        copy.exquisiteFlag = self.exquisiteFlag;
+        copy.play = [self.play copyWithZone:zone];
+        copy.addUserAvatar = [self.addUserAvatar copyWithZone:zone];
+        copy.audioType = [self.audioType copyWithZone:zone];
+        copy.canEvaluate = self.canEvaluate;
+        copy.delFlag = self.delFlag;
+        copy.musicTagNames = [self.musicTagNames copyWithZone:zone];
+        copy.subjectNames = [self.subjectNames copyWithZone:zone];
+        copy.chargeType = [self.chargeType copyWithZone:zone];
+        copy.updateTime = [self.updateTime copyWithZone:zone];
+        copy.updateBy = self.updateBy;
+        copy.musicTag = [self.musicTag copyWithZone:zone];
+        copy.extConfigJson = [self.extConfigJson copyWithZone:zone];
+        copy.addName = [self.addName copyWithZone:zone];
+        copy.paymentType = [self.paymentType copyWithZone:zone];
+        copy.accompanimentType = [self.accompanimentType copyWithZone:zone];
+        copy.favorite = self.favorite;
+        copy.auditStatus = [self.auditStatus copyWithZone:zone];
+        copy.createBy = self.createBy;
+        copy.topFlag = self.topFlag;
+        copy.midiUrl = [self.midiUrl copyWithZone:zone];
+        copy.composer = [self.composer copyWithZone:zone];
+        copy.sourceType = [self.sourceType copyWithZone:zone];
+        copy.firstPassAuditTime = [self.firstPassAuditTime copyWithZone:zone];
+        copy.mp3Type = [self.mp3Type copyWithZone:zone];
+        copy.hotFlag = [self.hotFlag copyWithZone:zone];
+        copy.createTime = [self.createTime copyWithZone:zone];
+        copy.playSpeed = self.playSpeed;
+        copy.audioFileUrl = [self.audioFileUrl copyWithZone:zone];
+        copy.hasBeat = self.hasBeat;
+        copy.reason = [self.reason copyWithZone:zone];
+        copy.auditVersion = self.auditVersion;
+        copy.musicSubject = [self.musicSubject copyWithZone:zone];
+        copy.userId = self.userId;
+        copy.submitAuditTime = [self.submitAuditTime copyWithZone:zone];
+    }
+    
+    return copy;
+}
+
+
+@end

+ 2 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Model/FriendListModel.h

@@ -20,6 +20,8 @@
 @property (nonatomic, strong) NSString *updateTime;
 @property (nonatomic, strong) NSString *createTime;
 @property (nonatomic, strong) NSString *firstLetter;
+@property (nonatomic, strong) NSString *imFriendId;
+@property (nonatomic, strong) NSString *roleType;
 
 + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
 - (instancetype)initWithDictionary:(NSDictionary *)dict;

+ 16 - 6
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Model/FriendListModel.m

@@ -16,7 +16,8 @@ NSString *const kFriendListModelMemo = @"memo";
 NSString *const kFriendListModelFriendAvatar = @"friendAvatar";
 NSString *const kFriendListModelUpdateTime = @"updateTime";
 NSString *const kFriendListModelCreateTime = @"createTime";
-
+NSString *const kFriendListModelImFriendId = @"imFriendId";
+NSString *const kFriendListModelRoleType = @"roleType";
 
 @interface FriendListModel ()
 
@@ -34,7 +35,8 @@ NSString *const kFriendListModelCreateTime = @"createTime";
 @synthesize friendAvatar = _friendAvatar;
 @synthesize updateTime = _updateTime;
 @synthesize createTime = _createTime;
-
+@synthesize imFriendId = _imFriendId;
+@synthesize roleType = _roleType;
 
 + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
 {
@@ -56,7 +58,8 @@ NSString *const kFriendListModelCreateTime = @"createTime";
             self.friendAvatar = [self objectOrNilForKey:kFriendListModelFriendAvatar fromDictionary:dict];
             self.updateTime = [self objectOrNilForKey:kFriendListModelUpdateTime fromDictionary:dict];
             self.createTime = [self objectOrNilForKey:kFriendListModelCreateTime fromDictionary:dict];
-
+            self.imFriendId = [self objectOrNilForKey:kFriendListModelImFriendId fromDictionary:dict];
+        self.roleType = [self objectOrNilForKey:kFriendListModelRoleType fromDictionary:dict];
     }
     
     return self;
@@ -74,11 +77,12 @@ NSString *const kFriendListModelCreateTime = @"createTime";
     [mutableDict setValue:self.friendAvatar forKey:kFriendListModelFriendAvatar];
     [mutableDict setValue:self.updateTime forKey:kFriendListModelUpdateTime];
     [mutableDict setValue:self.createTime forKey:kFriendListModelCreateTime];
-
+    [mutableDict setValue:self.imFriendId forKey:kFriendListModelImFriendId];
+    [mutableDict setValue:self.roleType forKey:kFriendListModelRoleType];
     return [NSDictionary dictionaryWithDictionary:mutableDict];
 }
 
-- (NSString *)description 
+- (NSString *)description
 {
     return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]];
 }
@@ -109,6 +113,8 @@ NSString *const kFriendListModelCreateTime = @"createTime";
     self.friendAvatar = [aDecoder decodeObjectForKey:kFriendListModelFriendAvatar];
     self.updateTime = [aDecoder decodeObjectForKey:kFriendListModelUpdateTime];
     self.createTime = [aDecoder decodeObjectForKey:kFriendListModelCreateTime];
+    self.imFriendId = [aDecoder decodeObjectForKey:kFriendListModelImFriendId];
+    self.roleType = [aDecoder decodeObjectForKey:kFriendListModelRoleType];
     return self;
 }
 
@@ -123,6 +129,8 @@ NSString *const kFriendListModelCreateTime = @"createTime";
     [aCoder encodeObject:_friendAvatar forKey:kFriendListModelFriendAvatar];
     [aCoder encodeObject:_updateTime forKey:kFriendListModelUpdateTime];
     [aCoder encodeObject:_createTime forKey:kFriendListModelCreateTime];
+    [aCoder encodeObject:_imFriendId forKey:kFriendListModelImFriendId];
+    [aCoder encodeObject:_roleType forKey:kFriendListModelRoleType];
 }
 
 - (id)copyWithZone:(NSZone *)zone
@@ -130,7 +138,7 @@ NSString *const kFriendListModelCreateTime = @"createTime";
     FriendListModel *copy = [[FriendListModel alloc] init];
     
     if (copy) {
-
+        
         copy.userId = [self.userId copyWithZone:zone];
         copy.friendNickname = [self.friendNickname copyWithZone:zone];
         copy.internalBaseClassIdentifier = [self.internalBaseClassIdentifier copyWithZone:zone];
@@ -139,6 +147,8 @@ NSString *const kFriendListModelCreateTime = @"createTime";
         copy.friendAvatar = [self.friendAvatar copyWithZone:zone];
         copy.updateTime = [self.updateTime copyWithZone:zone];
         copy.createTime = [self.createTime copyWithZone:zone];
+        copy.imFriendId = [self.createTime copyWithZone:zone];
+        copy.roleType = [self.roleType copyWithZone:zone];
     }
     
     return copy;

+ 1 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Model/GroupMemberModel.h

@@ -22,6 +22,7 @@
 @property (nonatomic, strong) NSString *createTime;
 
 @property (nonatomic, strong) NSString *firstLetter;
+@property (nonatomic, strong) NSString *imUserId;
 
 + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
 - (instancetype)initWithDictionary:(NSDictionary *)dict;

+ 7 - 4
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/Model/GroupMemberModel.m

@@ -17,7 +17,7 @@ NSString *const kGroupMemberModelNickname = @"nickname";
 NSString *const kGroupMemberModelIsAdmin = @"isAdmin";
 NSString *const kGroupMemberModelGroupId = @"groupId";
 NSString *const kGroupMemberModelCreateTime = @"createTime";
-
+NSString *const kGroupMemberModelImUserId = @"imUserId";
 
 @interface GroupMemberModel ()
 
@@ -36,7 +36,7 @@ NSString *const kGroupMemberModelCreateTime = @"createTime";
 @synthesize isAdmin = _isAdmin;
 @synthesize groupId = _groupId;
 @synthesize createTime = _createTime;
-
+@synthesize imUserId = _imUserId;
 
 + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
 {
@@ -59,7 +59,7 @@ NSString *const kGroupMemberModelCreateTime = @"createTime";
             self.isAdmin = [[self objectOrNilForKey:kGroupMemberModelIsAdmin fromDictionary:dict] boolValue];
             self.groupId = [self objectOrNilForKey:kGroupMemberModelGroupId fromDictionary:dict];
             self.createTime = [self objectOrNilForKey:kGroupMemberModelCreateTime fromDictionary:dict];
-
+            self.imUserId = [self objectOrNilForKey:kGroupMemberModelImUserId fromDictionary:dict];
     }
     
     return self;
@@ -78,7 +78,7 @@ NSString *const kGroupMemberModelCreateTime = @"createTime";
     [mutableDict setValue:[NSNumber numberWithBool:self.isAdmin] forKey:kGroupMemberModelIsAdmin];
     [mutableDict setValue:self.groupId forKey:kGroupMemberModelGroupId];
     [mutableDict setValue:self.createTime forKey:kGroupMemberModelCreateTime];
-
+    [mutableDict setValue:self.imUserId forKey:kGroupMemberModelImUserId];
     return [NSDictionary dictionaryWithDictionary:mutableDict];
 }
 
@@ -114,6 +114,7 @@ NSString *const kGroupMemberModelCreateTime = @"createTime";
     self.isAdmin = [aDecoder decodeBoolForKey:kGroupMemberModelIsAdmin];
     self.groupId = [aDecoder decodeObjectForKey:kGroupMemberModelGroupId];
     self.createTime = [aDecoder decodeObjectForKey:kGroupMemberModelCreateTime];
+    self.imUserId = [aDecoder decodeObjectForKey:kGroupMemberModelImUserId];
     return self;
 }
 
@@ -129,6 +130,7 @@ NSString *const kGroupMemberModelCreateTime = @"createTime";
     [aCoder encodeBool:_isAdmin forKey:kGroupMemberModelIsAdmin];
     [aCoder encodeObject:_groupId forKey:kGroupMemberModelGroupId];
     [aCoder encodeObject:_createTime forKey:kGroupMemberModelCreateTime];
+    [aCoder encodeObject:_imUserId forKey:kGroupMemberModelImUserId];
 }
 
 - (id)copyWithZone:(NSZone *)zone
@@ -146,6 +148,7 @@ NSString *const kGroupMemberModelCreateTime = @"createTime";
         copy.isAdmin = self.isAdmin;
         copy.groupId = [self.groupId copyWithZone:zone];
         copy.createTime = [self.createTime copyWithZone:zone];
+        copy.imUserId = [self.imUserId copyWithZone:zone];
     }
     
     return copy;

+ 2 - 2
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatAddressBodyView.m

@@ -287,10 +287,10 @@
         NSArray *filterArray = self.studentArray[indexPath.section];
         FriendListModel *model = filterArray[indexPath.row];
         if (_isShareImage) { // 分享
-            [self sendMessageWithTargetId:model.friendId isGroup:NO];
+            [self sendMessageWithTargetId:model.imFriendId isGroup:NO];
         }
         else { // 聊天
-            [self chatConversationWithTargetId:model.friendId targetName:model.friendNickname isGroup:NO];
+            [self chatConversationWithTargetId:model.imFriendId targetName:model.friendNickname isGroup:NO];
         }
     }
     else { // 群聊

+ 24 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/RecentMusicView.h

@@ -0,0 +1,24 @@
+//
+//  RecentMusicView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/10/18.
+//
+
+#import <UIKit/UIKit.h>
+#import "RecentPracticeModel.h"
+
+typedef void(^RecentMusicDetailBlock)(NSString * _Nonnull songId);
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface RecentMusicView : UIView
+
++ (instancetype)shareInstance;
+
+- (void)configWithMusicModel:(RecentPracticeModel *)sourceModel hiddenLineView:(BOOL)hideLineView callback:(RecentMusicDetailBlock)callback;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 185 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/RecentMusicView.m

@@ -0,0 +1,185 @@
+//
+//  RecentMusicView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/10/18.
+//
+
+#import "RecentMusicView.h"
+#import "MusicTagView.h"
+
+@interface RecentMusicView ()
+
+@property (weak, nonatomic) IBOutlet UILabel *songNameLabel;
+@property (weak, nonatomic) IBOutlet UILabel *songAuth;
+@property (weak, nonatomic) IBOutlet UILabel *uploadName;
+
+@property (weak, nonatomic) IBOutlet UIView *tagView;
+@property (weak, nonatomic) IBOutlet UIView *lineView;
+
+@property (nonatomic, copy) RecentMusicDetailBlock callback;
+
+@property (nonatomic, strong) RecentPracticeModel *model;
+
+@property (weak, nonatomic) IBOutlet UIImageView *qualityMusicTag;
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *qualityTagWidth;
+
+@property (weak, nonatomic) IBOutlet UIImageView *albumTag;
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *albumTagWidth;
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *albumTagLeft;
+
+@end
+
+@implementation RecentMusicView
+
++ (instancetype)shareInstance {
+    RecentMusicView *view = [[[NSBundle mainBundle] loadNibNamed:@"RecentMusicView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)configWithMusicModel:(RecentPracticeModel *)sourceModel hiddenLineView:(BOOL)hideLineView callback:(RecentMusicDetailBlock)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+    self.model = sourceModel;
+    if (sourceModel.exquisiteFlag) {
+        self.qualityMusicTag.hidden = NO;
+        self.qualityTagWidth.constant = 14.0f;
+    }
+    else {
+        self.qualityMusicTag.hidden = NO;
+        self.qualityTagWidth.constant = 0.0f;
+    }
+    
+    if (sourceModel.albumNums > 0) {
+        self.albumTag.hidden = NO;
+        self.albumTagWidth.constant = 15.0f;
+        self.albumTagLeft.constant = 5.0f;
+    }
+    else {
+        self.albumTag.hidden = YES;
+        self.albumTagWidth.constant = 0.0f;
+        self.albumTagLeft.constant = 0.0f;
+    }
+    
+    if ([NSString isEmptyString:sourceModel.musicSheetName]) {
+        self.songNameLabel.text = @"";
+    }
+    else {
+        NSString *musicName = @"";
+        if (sourceModel.musicSheetName.length > 10) {
+            musicName = [NSString stringWithFormat:@"%@...",[sourceModel.musicSheetName substringToIndex:9]];
+        }
+        else {
+            musicName = sourceModel.musicSheetName;
+        }
+        self.songNameLabel.text = musicName;
+    }
+    if ([NSString isEmptyString:sourceModel.composer]) {
+        self.songAuth.text = @"";
+    }
+    else {
+        NSString *songAuth = @"";
+        if (sourceModel.composer.length > 4) {
+            songAuth = [NSString stringWithFormat:@"-%@...",[sourceModel.composer substringToIndex:4]];
+        }
+        else {
+            songAuth = [NSString stringWithFormat:@"-%@",sourceModel.composer];
+        }
+        self.songAuth.text = songAuth;
+    }
+    NSArray *tagArray = nil;
+    if (![NSString isEmptyString:sourceModel.subjectNames]) {
+        tagArray = [sourceModel.subjectNames componentsSeparatedByString:@","];
+    }
+    
+    NSString *owner = @"";
+    if ([NSString isEmptyString:sourceModel.addName]) {
+        owner = [NSString stringWithFormat:@"上传者:游客%.0f",sourceModel.userId];
+    }
+    else {
+        owner = sourceModel.addName;
+        if (sourceModel.addName.length > 4) {
+            owner = [NSString stringWithFormat:@"上传者:%@...",[sourceModel.addName substringToIndex:4]];
+        }
+        else {
+            owner = [NSString stringWithFormat:@"上传者:%@",sourceModel.addName];
+        }
+    }
+    self.uploadName.text = owner;
+
+    CGFloat maxWidth = [self getTagViewMaxWidth:owner];
+    [self configTagViewWithTagArray:tagArray maxWidth:maxWidth];
+    self.lineView.hidden = hideLineView;
+}
+
+- (CGFloat)getWidthWithTypeCount:(NSInteger)count singleWidth:(CGFloat)singleWidth space:(CGFloat)space {
+    if (count == 1) {
+        return singleWidth;
+    }
+    else {
+        return singleWidth + (singleWidth + space) * (count - 1);
+    }
+}
+
+- (CGFloat)getTagViewMaxWidth:(NSString *)teacherName {
+    CGFloat width = [self getStringWidthInLabel:teacherName font:[UIFont systemFontOfSize:12.0f]];
+    return KPortraitWidth - 48 - width - 12;
+}
+
+- (void)configTagViewWithTagArray:(NSArray *)tagArray maxWidth:(CGFloat)maxWidth {
+    [self.tagView removeAllSubViews];
+    CGFloat width = maxWidth;
+    CGFloat xSpace = 0.0f;
+    for (NSInteger i = 0; i < tagArray.count; i++) {
+        NSString *tagString = tagArray[i];
+        CGFloat labelWidth = [self getStringWidthInLabel:tagString font:[UIFont systemFontOfSize:10.0f]];
+        CGFloat viewWidth = labelWidth + 10;
+        if (xSpace + viewWidth > width) {
+            return;
+        }
+        CGRect frame = CGRectMake(xSpace, 0, viewWidth, 16.0f);
+        [self createTagLabelViewWithName:tagString frame:frame];
+        xSpace += (viewWidth + 5);
+    }
+}
+
+- (CGFloat)getStringWidthInLabel:(NSString *)tagString font:(UIFont *)font {
+    CGFloat width = [tagString boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, 16.0f) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil].size.width+1;
+    return width;
+}
+
+- (void)createTagLabelViewWithName:(NSString *)name frame:(CGRect)frame {
+    UIView *bgView = [[UIView alloc] initWithFrame:frame];
+    bgView.backgroundColor = HexRGB(0xEFFBF9);
+    bgView.layer.cornerRadius = 8.0f;
+    [self.tagView addSubview:bgView];
+    
+    UILabel *tagLabel = [[UILabel alloc] init];
+    tagLabel.text = name;
+    tagLabel.textColor = THEMECOLOR;
+    tagLabel.font = [UIFont systemFontOfSize:10.0f];
+    tagLabel.textAlignment = NSTextAlignmentCenter;
+    [bgView addSubview:tagLabel];
+    [tagLabel mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.mas_equalTo(bgView.mas_left).offset(5);
+        make.right.mas_equalTo(bgView.mas_right).offset(-5);
+        make.top.bottom.mas_equalTo(bgView);
+    }];
+}
+
+- (IBAction)buttonAction:(id)sender {
+    if (self.callback) {
+        NSString *songId = [NSString stringWithFormat:@"%.0f",self.model.internalBaseClassIdentifier];
+        self.callback(songId);
+    }
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 132 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/RecentMusicView.xib

@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21225" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_0" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21207"/>
+        <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="RecentMusicView">
+            <rect key="frame" x="0.0" y="0.0" width="390" height="84"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="最伟大的作品" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Shl-oF-wvN">
+                    <rect key="frame" x="57" y="21.666666666666671" width="98" height="22"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="22" id="yEu-dU-wB3"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
+                    <color key="textColor" red="0.1019607843" green="0.1019607843" blue="0.1019607843" 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="43W-cg-jr5">
+                    <rect key="frame" x="160" y="25" width="43" height="15"/>
+                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                    <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" 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="hvc-Gg-1Zz">
+                    <rect key="frame" x="18" y="53.666666666666664" width="123" height="16.999999999999993"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="17" id="rS3-rz-IW0"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                    <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="home_music_play" translatesAutoresizingMaskIntoConstraints="NO" id="4gu-v4-wJm">
+                    <rect key="frame" x="342" y="30" width="24" height="24"/>
+                    <constraints>
+                        <constraint firstAttribute="width" constant="24" id="aJX-AJ-O25"/>
+                        <constraint firstAttribute="height" constant="24" id="gcw-w5-2ob"/>
+                    </constraints>
+                </imageView>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8Xo-oO-3x3">
+                    <rect key="frame" x="153" y="54" width="184" height="16"/>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="16" id="3RW-fM-J0s"/>
+                    </constraints>
+                </view>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="R2e-lE-ZM6">
+                    <rect key="frame" x="18" y="83.666666666666671" width="354" height="0.3333333333333286"/>
+                    <color key="backgroundColor" red="0.90980392160000001" green="0.90980392160000001" blue="0.90980392160000001" alpha="1" colorSpace="calibratedRGB"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="0.5" id="Ifk-5G-zlF"/>
+                    </constraints>
+                </view>
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="quality_tag" translatesAutoresizingMaskIntoConstraints="NO" id="8fL-Jy-bgr">
+                    <rect key="frame" x="18" y="24" width="14" height="17"/>
+                    <constraints>
+                        <constraint firstAttribute="width" constant="14" id="BIZ-8m-Xog"/>
+                        <constraint firstAttribute="height" constant="17" id="Vyh-lk-Y2u"/>
+                    </constraints>
+                </imageView>
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="music_albumTag" translatesAutoresizingMaskIntoConstraints="NO" id="Uca-W8-cUY">
+                    <rect key="frame" x="37" y="25" width="15" height="15"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="15" id="nIS-wf-l8i"/>
+                        <constraint firstAttribute="width" constant="15" id="rso-cD-zs9"/>
+                    </constraints>
+                </imageView>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="UvT-Ln-7qo">
+                    <rect key="frame" x="0.0" y="0.0" width="390" height="84"/>
+                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                    <connections>
+                        <action selector="buttonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="Xiw-64-8rM"/>
+                    </connections>
+                </button>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="UvT-Ln-7qo" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="0z4-iF-ucd"/>
+                <constraint firstItem="4gu-v4-wJm" firstAttribute="leading" secondItem="8Xo-oO-3x3" secondAttribute="trailing" constant="5" id="2bH-bi-rsd"/>
+                <constraint firstItem="4gu-v4-wJm" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="43W-cg-jr5" secondAttribute="trailing" constant="5" id="6dq-x6-1RP"/>
+                <constraint firstItem="43W-cg-jr5" firstAttribute="centerY" secondItem="8fL-Jy-bgr" secondAttribute="centerY" id="8kf-kw-cS9"/>
+                <constraint firstItem="hvc-Gg-1Zz" firstAttribute="leading" secondItem="8fL-Jy-bgr" secondAttribute="leading" id="9nd-TU-kyn"/>
+                <constraint firstItem="UvT-Ln-7qo" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="Fh8-eQ-jxk"/>
+                <constraint firstItem="8fL-Jy-bgr" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="24" id="Kpm-kV-SRi"/>
+                <constraint firstItem="43W-cg-jr5" firstAttribute="leading" secondItem="Shl-oF-wvN" secondAttribute="trailing" constant="5" id="MuV-qV-dVg"/>
+                <constraint firstAttribute="trailing" secondItem="4gu-v4-wJm" secondAttribute="trailing" constant="24" id="N6e-ub-5Cc"/>
+                <constraint firstAttribute="trailing" secondItem="UvT-Ln-7qo" secondAttribute="trailing" id="Syk-cV-CFd"/>
+                <constraint firstItem="Uca-W8-cUY" firstAttribute="leading" secondItem="8fL-Jy-bgr" secondAttribute="trailing" constant="5" id="TSx-tA-rAn"/>
+                <constraint firstItem="Uca-W8-cUY" firstAttribute="centerY" secondItem="8fL-Jy-bgr" secondAttribute="centerY" id="TmH-4n-nH4"/>
+                <constraint firstItem="hvc-Gg-1Zz" firstAttribute="top" secondItem="Shl-oF-wvN" secondAttribute="bottom" constant="10" id="VkD-Y3-BSf"/>
+                <constraint firstItem="8Xo-oO-3x3" firstAttribute="leading" secondItem="hvc-Gg-1Zz" secondAttribute="trailing" constant="12" id="WYh-zk-vte"/>
+                <constraint firstItem="R2e-lE-ZM6" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="18" id="XZj-xi-1FR"/>
+                <constraint firstItem="8Xo-oO-3x3" firstAttribute="centerY" secondItem="hvc-Gg-1Zz" secondAttribute="centerY" id="cPs-M6-keN"/>
+                <constraint firstAttribute="trailing" secondItem="R2e-lE-ZM6" secondAttribute="trailing" constant="18" id="fx0-GH-hQe"/>
+                <constraint firstItem="8fL-Jy-bgr" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="18" id="kt6-OU-oYn"/>
+                <constraint firstAttribute="bottom" secondItem="R2e-lE-ZM6" secondAttribute="bottom" id="pMe-In-6YX"/>
+                <constraint firstItem="Shl-oF-wvN" firstAttribute="leading" secondItem="Uca-W8-cUY" secondAttribute="trailing" constant="5" id="pmf-Eg-NCR"/>
+                <constraint firstItem="Shl-oF-wvN" firstAttribute="centerY" secondItem="8fL-Jy-bgr" secondAttribute="centerY" id="sZG-qc-hWe"/>
+                <constraint firstAttribute="bottom" secondItem="UvT-Ln-7qo" secondAttribute="bottom" id="t3d-MK-BUM"/>
+                <constraint firstItem="4gu-v4-wJm" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="zPb-kf-uh1"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="albumTag" destination="Uca-W8-cUY" id="eGx-WB-SJc"/>
+                <outlet property="albumTagLeft" destination="TSx-tA-rAn" id="8JH-hI-qO6"/>
+                <outlet property="albumTagWidth" destination="rso-cD-zs9" id="YMh-Cx-I5Q"/>
+                <outlet property="lineView" destination="R2e-lE-ZM6" id="qmg-Ew-0Ut"/>
+                <outlet property="qualityMusicTag" destination="8fL-Jy-bgr" id="XUR-m4-TKf"/>
+                <outlet property="qualityTagWidth" destination="BIZ-8m-Xog" id="fBy-eq-HMV"/>
+                <outlet property="songAuth" destination="43W-cg-jr5" id="LK6-4t-gGK"/>
+                <outlet property="songNameLabel" destination="Shl-oF-wvN" id="Fi7-Gb-vEF"/>
+                <outlet property="tagView" destination="8Xo-oO-3x3" id="WHd-26-x2X"/>
+                <outlet property="uploadName" destination="hvc-Gg-1Zz" id="TyX-af-akM"/>
+            </connections>
+            <point key="canvasLocation" x="101.53846153846153" y="-60.426540284360186"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="home_music_play" width="24" height="24"/>
+        <image name="music_albumTag" width="15" height="15"/>
+        <image name="quality_tag" width="14" height="17"/>
+    </resources>
+</document>

+ 26 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/UserDetailBodyView.h

@@ -0,0 +1,26 @@
+//
+//  UserDetailBodyView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/10/18.
+//
+
+#import <UIKit/UIKit.h>
+#import "ChatUserInfo.h"
+
+typedef void(^RecentMusicCallback)(NSString *songId);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface UserDetailBodyView : UIView
+
++ (instancetype)shareInstance;
+
+- (void)configUserMessage:(ChatUserInfo *)userInfo musicArray:(NSMutableArray *)musicArray callback:(RecentMusicCallback)callback;
+
+
++ (CGFloat)getViewHeight;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 100 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/UserDetailBodyView.m

@@ -0,0 +1,100 @@
+//
+//  UserDetailBodyView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/10/18.
+//
+
+#import "UserDetailBodyView.h"
+#import "RecentMusicView.h"
+
+@interface UserDetailBodyView ()
+
+@property (weak, nonatomic) IBOutlet UIImageView *userAvatar;
+
+@property (weak, nonatomic) IBOutlet UILabel *userName;
+
+@property (weak, nonatomic) IBOutlet UIImageView *memberImage;
+
+@property (weak, nonatomic) IBOutlet UILabel *userSex;
+
+@property (weak, nonatomic) IBOutlet UILabel *userSubject;
+
+@property (weak, nonatomic) IBOutlet UIView *subjectView;
+
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *subjectViewHeight;
+
+@property (weak, nonatomic) IBOutlet UILabel *userIdLabel;
+
+@property (nonatomic, copy) RecentMusicCallback callback;
+
+@end
+
+@implementation UserDetailBodyView
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+}
+
++ (instancetype)shareInstance {
+    UserDetailBodyView *view = [[[NSBundle mainBundle] loadNibNamed:@"UserDetailBodyView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)configUserMessage:(ChatUserInfo *)userInfo musicArray:(NSMutableArray *)musicArray callback:(RecentMusicCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+    NSString *viperImage = @"";
+    if (userInfo.isVip == 1) {
+        self.userAvatar.layer.borderColor = HexRGB(0xFFE0B9).CGColor;
+        viperImage = @"mine_vip";
+    }
+    else {
+        self.userAvatar.layer.borderColor = HexRGB(0xffffff).CGColor;
+        viperImage = @"mine_nomal";
+    }
+    
+    [self.memberImage setImage:[UIImage imageNamed:viperImage]];
+    
+    [self.userAvatar sd_setImageWithURL:[NSURL URLWithString:[userInfo.avatar getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:USERDEFAULT_LOGO]];
+    self.userName.text = [NSString returnNoNullStringWithString:userInfo.username];
+    self.userIdLabel.text = [NSString stringWithFormat:@"学号:%.0f",userInfo.userId];
+    self.userSubject.text = [NSString returnNoNullStringWithString:userInfo.subjectName];
+    NSString *sexString = userInfo.gender == 1 ? @"男生" : @"女生";
+    self.userSex.text = sexString;
+    
+    [self evaluateSource:musicArray];
+}
+
+- (void)evaluateSource:(NSArray *)musicArray {
+    [self.subjectView removeAllSubViews];
+    NSInteger count = musicArray.count > 3 ? 3 : musicArray.count;
+    for (NSInteger i = 0; i < count; i++) {
+        // 添加按钮
+        RecentMusicView *musicView = [RecentMusicView shareInstance];
+        musicView.frame = CGRectMake(0, 84 * i, KPortraitWidth - 28, 84);
+        BOOL hideLineView = i == count - 1 ? YES : NO;
+        MJWeakSelf;
+        [musicView configWithMusicModel:musicArray[i] hiddenLineView:hideLineView callback:^(NSString * _Nonnull songId) {
+            if (weakSelf.callback) {
+                weakSelf.callback(songId);
+            }
+        }];
+        [self.subjectView addSubview:musicView];
+    }
+}
+
+
++ (CGFloat)getViewHeight {
+    return 590.0f;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 262 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/UserDetailBodyView.xib

@@ -0,0 +1,262 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21225" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_0" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21207"/>
+        <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="UserDetailBodyView">
+            <rect key="frame" x="0.0" y="0.0" width="390" height="590"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="PZG-4f-DTT">
+                    <rect key="frame" x="14" y="14" width="362" height="260"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="user_default_avatal" translatesAutoresizingMaskIntoConstraints="NO" id="GcD-Ic-cNt">
+                            <rect key="frame" x="20" y="18" width="60" height="60"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="60" id="JVv-tN-XaL"/>
+                                <constraint firstAttribute="height" constant="60" id="Wba-Pj-zV9"/>
+                            </constraints>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="30"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                        </imageView>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="mine_nomal" translatesAutoresizingMaskIntoConstraints="NO" id="jg5-7G-Opf">
+                            <rect key="frame" x="33" y="70.666666666666671" width="34" height="15"/>
+                        </imageView>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="小学生" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="uqG-dv-SFP">
+                            <rect key="frame" x="102" y="28" width="250" height="28"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="28" id="gND-vy-QU4"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="20"/>
+                            <nil key="textColor"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="mine_uid" translatesAutoresizingMaskIntoConstraints="NO" id="lQk-hY-YEs">
+                            <rect key="frame" x="102" y="58" width="11" height="11"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="11" id="1C1-5S-Xgd"/>
+                                <constraint firstAttribute="width" constant="11" id="oAT-cl-3w2"/>
+                            </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="DqI-wn-gqn">
+                            <rect key="frame" x="119" y="56.666666666666671" width="26" height="14"/>
+                            <fontDescription key="fontDescription" type="system" pointSize="11"/>
+                            <color key="textColor" red="0.41568627450980389" green="0.41568627450980389" blue="0.41568627450980389" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="12B-UP-hU5">
+                            <rect key="frame" x="14" y="104" width="334" height="140"/>
+                            <subviews>
+                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="hj1-nm-c6u">
+                                    <rect key="frame" x="0.0" y="0.0" width="334" height="70"/>
+                                    <subviews>
+                                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qQE-Ie-jl3">
+                                            <rect key="frame" x="32" y="69" width="270" height="1"/>
+                                            <color key="backgroundColor" red="0.92156862745098034" green="0.92156862745098034" blue="0.92156862745098034" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                            <constraints>
+                                                <constraint firstAttribute="height" constant="1" id="oX0-Vo-8dT"/>
+                                            </constraints>
+                                        </view>
+                                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="chat_use_sex" translatesAutoresizingMaskIntoConstraints="NO" id="0IW-8X-S9p">
+                                            <rect key="frame" x="16" y="25" width="20" height="20"/>
+                                            <constraints>
+                                                <constraint firstAttribute="width" constant="20" id="1Hn-XA-lU9"/>
+                                                <constraint firstAttribute="height" constant="20" id="rsl-FF-840"/>
+                                            </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="ix6-yj-abW">
+                                            <rect key="frame" x="48" y="24.666666666666657" width="46" height="21"/>
+                                            <constraints>
+                                                <constraint firstAttribute="height" constant="21" id="iYb-XU-9n5"/>
+                                            </constraints>
+                                            <fontDescription key="fontDescription" type="system" pointSize="15"/>
+                                            <color key="textColor" red="0.41568627450980389" green="0.41568627450980389" blue="0.41568627450980389" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                            <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="yzA-J6-60W">
+                                            <rect key="frame" x="96" y="24.666666666666657" width="0.0" height="21"/>
+                                            <constraints>
+                                                <constraint firstAttribute="height" constant="21" id="ex4-d4-aaT"/>
+                                            </constraints>
+                                            <fontDescription key="fontDescription" type="system" pointSize="15"/>
+                                            <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                            <nil key="highlightedColor"/>
+                                        </label>
+                                    </subviews>
+                                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                    <constraints>
+                                        <constraint firstItem="ix6-yj-abW" firstAttribute="leading" secondItem="0IW-8X-S9p" secondAttribute="trailing" constant="12" id="Apc-un-raT"/>
+                                        <constraint firstItem="0IW-8X-S9p" firstAttribute="leading" secondItem="hj1-nm-c6u" secondAttribute="leading" constant="16" id="B1I-A3-C5j"/>
+                                        <constraint firstAttribute="bottom" secondItem="qQE-Ie-jl3" secondAttribute="bottom" id="C07-uC-YMx"/>
+                                        <constraint firstItem="yzA-J6-60W" firstAttribute="leading" secondItem="ix6-yj-abW" secondAttribute="trailing" constant="2" id="Fh2-3H-lq5"/>
+                                        <constraint firstItem="ix6-yj-abW" firstAttribute="centerY" secondItem="0IW-8X-S9p" secondAttribute="centerY" id="QaC-OO-Q9I"/>
+                                        <constraint firstAttribute="trailing" secondItem="qQE-Ie-jl3" secondAttribute="trailing" constant="32" id="ZYu-6L-IMQ"/>
+                                        <constraint firstAttribute="height" constant="70" id="b9w-WV-Lu1"/>
+                                        <constraint firstItem="qQE-Ie-jl3" firstAttribute="leading" secondItem="hj1-nm-c6u" secondAttribute="leading" constant="32" id="jgA-eJ-D08"/>
+                                        <constraint firstItem="yzA-J6-60W" firstAttribute="centerY" secondItem="ix6-yj-abW" secondAttribute="centerY" id="lXh-bB-Kzd"/>
+                                        <constraint firstItem="0IW-8X-S9p" firstAttribute="top" secondItem="hj1-nm-c6u" secondAttribute="top" constant="25" id="xGr-WD-exr"/>
+                                    </constraints>
+                                </view>
+                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9Tm-F6-cRH">
+                                    <rect key="frame" x="0.0" y="70" width="334" height="70"/>
+                                    <subviews>
+                                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="chat_user_subject" translatesAutoresizingMaskIntoConstraints="NO" id="UAH-63-z5x">
+                                            <rect key="frame" x="16" y="26" width="20" height="20"/>
+                                            <constraints>
+                                                <constraint firstAttribute="height" constant="20" id="mcV-aA-1d5"/>
+                                                <constraint firstAttribute="width" constant="20" id="wXX-gX-zou"/>
+                                            </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="m0W-G0-lyK">
+                                            <rect key="frame" x="48" y="25.666666666666657" width="46" height="21"/>
+                                            <constraints>
+                                                <constraint firstAttribute="height" constant="21" id="ZpX-6w-BFn"/>
+                                            </constraints>
+                                            <fontDescription key="fontDescription" type="system" pointSize="15"/>
+                                            <color key="textColor" red="0.41568627450980389" green="0.41568627450980389" blue="0.41568627450980389" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                            <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="ab0-kc-WGQ">
+                                            <rect key="frame" x="96" y="25.666666666666657" width="0.0" height="21"/>
+                                            <constraints>
+                                                <constraint firstAttribute="height" constant="21" id="UID-JK-AxO"/>
+                                            </constraints>
+                                            <fontDescription key="fontDescription" type="system" pointSize="15"/>
+                                            <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                            <nil key="highlightedColor"/>
+                                        </label>
+                                    </subviews>
+                                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                    <constraints>
+                                        <constraint firstItem="m0W-G0-lyK" firstAttribute="centerY" secondItem="UAH-63-z5x" secondAttribute="centerY" id="5pP-U1-Bam"/>
+                                        <constraint firstAttribute="bottom" secondItem="UAH-63-z5x" secondAttribute="bottom" constant="24" id="DMw-no-t76"/>
+                                        <constraint firstAttribute="height" constant="70" id="VPx-An-l21"/>
+                                        <constraint firstItem="m0W-G0-lyK" firstAttribute="leading" secondItem="UAH-63-z5x" secondAttribute="trailing" constant="12" id="fVJ-PH-AuK"/>
+                                        <constraint firstItem="ab0-kc-WGQ" firstAttribute="leading" secondItem="m0W-G0-lyK" secondAttribute="trailing" constant="2" id="iPn-Dx-uIF"/>
+                                        <constraint firstItem="ab0-kc-WGQ" firstAttribute="centerY" secondItem="m0W-G0-lyK" secondAttribute="centerY" id="ttd-3q-Pnt"/>
+                                        <constraint firstItem="UAH-63-z5x" firstAttribute="leading" secondItem="9Tm-F6-cRH" secondAttribute="leading" constant="16" id="zoy-Jj-brJ"/>
+                                    </constraints>
+                                </view>
+                            </subviews>
+                            <color key="backgroundColor" red="0.98431372549019602" green="0.98431372549019602" blue="0.98431372549019602" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <constraints>
+                                <constraint firstItem="hj1-nm-c6u" firstAttribute="leading" secondItem="12B-UP-hU5" secondAttribute="leading" id="Dhd-cE-bQZ"/>
+                                <constraint firstAttribute="bottom" secondItem="9Tm-F6-cRH" secondAttribute="bottom" id="G5t-fa-o3t"/>
+                                <constraint firstItem="9Tm-F6-cRH" firstAttribute="leading" secondItem="12B-UP-hU5" secondAttribute="leading" id="GVz-DI-Unz"/>
+                                <constraint firstAttribute="height" constant="140" id="HrN-xc-PpS"/>
+                                <constraint firstAttribute="trailing" secondItem="9Tm-F6-cRH" secondAttribute="trailing" id="S31-dv-6T3"/>
+                                <constraint firstItem="hj1-nm-c6u" firstAttribute="top" secondItem="12B-UP-hU5" secondAttribute="top" id="T8N-N8-q7O"/>
+                                <constraint firstAttribute="trailing" secondItem="hj1-nm-c6u" secondAttribute="trailing" id="oxR-Wc-y9H"/>
+                            </constraints>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="12"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                        </view>
+                    </subviews>
+                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                    <constraints>
+                        <constraint firstAttribute="trailing" secondItem="uqG-dv-SFP" secondAttribute="trailing" constant="10" id="5kI-Jt-1ZK"/>
+                        <constraint firstItem="GcD-Ic-cNt" firstAttribute="top" secondItem="PZG-4f-DTT" secondAttribute="top" constant="18" id="A7Y-Nv-r6T"/>
+                        <constraint firstAttribute="bottom" secondItem="12B-UP-hU5" secondAttribute="bottom" constant="16" id="Muy-ZG-G0i"/>
+                        <constraint firstItem="jg5-7G-Opf" firstAttribute="centerY" secondItem="GcD-Ic-cNt" secondAttribute="bottom" id="Nro-XE-qIB"/>
+                        <constraint firstItem="lQk-hY-YEs" firstAttribute="top" secondItem="uqG-dv-SFP" secondAttribute="bottom" constant="2" id="UoT-Yy-bZY"/>
+                        <constraint firstItem="jg5-7G-Opf" firstAttribute="centerX" secondItem="GcD-Ic-cNt" secondAttribute="centerX" id="WMk-9B-Rph"/>
+                        <constraint firstItem="jg5-7G-Opf" firstAttribute="centerX" secondItem="GcD-Ic-cNt" secondAttribute="centerX" id="XXW-0R-FeT"/>
+                        <constraint firstItem="DqI-wn-gqn" firstAttribute="centerY" secondItem="lQk-hY-YEs" secondAttribute="centerY" id="Zss-Ml-3Pg"/>
+                        <constraint firstItem="GcD-Ic-cNt" firstAttribute="leading" secondItem="PZG-4f-DTT" secondAttribute="leading" constant="20" id="Zxm-3W-KTH"/>
+                        <constraint firstItem="uqG-dv-SFP" firstAttribute="leading" secondItem="GcD-Ic-cNt" secondAttribute="trailing" constant="22" id="hed-Y5-7uo"/>
+                        <constraint firstItem="12B-UP-hU5" firstAttribute="leading" secondItem="PZG-4f-DTT" secondAttribute="leading" constant="14" id="lYx-aq-8hM"/>
+                        <constraint firstItem="lQk-hY-YEs" firstAttribute="leading" secondItem="uqG-dv-SFP" secondAttribute="leading" id="m4h-Dp-o7j"/>
+                        <constraint firstAttribute="height" constant="260" id="nNJ-Bm-ZKA"/>
+                        <constraint firstItem="DqI-wn-gqn" firstAttribute="leading" secondItem="lQk-hY-YEs" secondAttribute="trailing" constant="6" id="ncp-Rd-256"/>
+                        <constraint firstItem="uqG-dv-SFP" firstAttribute="top" secondItem="GcD-Ic-cNt" secondAttribute="top" constant="10" id="rmL-EW-AQF"/>
+                        <constraint firstAttribute="trailing" secondItem="12B-UP-hU5" secondAttribute="trailing" constant="14" id="wZj-Kh-Ydp"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="16"/>
+                        </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="bhE-25-YYz">
+                    <rect key="frame" x="40" y="290" width="66" height="22"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="22" id="F6D-gT-EVx"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
+                    <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="home_left" translatesAutoresizingMaskIntoConstraints="NO" id="Jaj-wc-QDp">
+                    <rect key="frame" x="28" y="294" width="4" height="14"/>
+                    <constraints>
+                        <constraint firstAttribute="width" constant="4" id="aMk-us-iHn"/>
+                        <constraint firstAttribute="height" constant="14" id="ek9-ya-EuK"/>
+                    </constraints>
+                </imageView>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="JQZ-qL-qfG">
+                    <rect key="frame" x="14" y="328" width="362" height="252"/>
+                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="252" id="12e-F9-uGR"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="16"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="Jaj-wc-QDp" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="28" id="57y-60-JMr"/>
+                <constraint firstAttribute="trailing" secondItem="JQZ-qL-qfG" secondAttribute="trailing" constant="14" id="6ra-2M-rfP"/>
+                <constraint firstAttribute="trailing" secondItem="PZG-4f-DTT" secondAttribute="trailing" constant="14" id="D1K-zh-6wT"/>
+                <constraint firstItem="JQZ-qL-qfG" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="14" id="EOI-s2-CoO"/>
+                <constraint firstItem="Jaj-wc-QDp" firstAttribute="top" secondItem="PZG-4f-DTT" secondAttribute="bottom" constant="20" id="Fe6-GE-aJU"/>
+                <constraint firstItem="PZG-4f-DTT" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="14" id="ITv-tX-SAD"/>
+                <constraint firstItem="bhE-25-YYz" firstAttribute="centerY" secondItem="Jaj-wc-QDp" secondAttribute="centerY" id="PQr-vE-aih"/>
+                <constraint firstItem="bhE-25-YYz" firstAttribute="leading" secondItem="Jaj-wc-QDp" secondAttribute="trailing" constant="8" id="Ppz-Sd-W4W"/>
+                <constraint firstItem="PZG-4f-DTT" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="14" id="W87-6D-MF1"/>
+                <constraint firstItem="JQZ-qL-qfG" firstAttribute="top" secondItem="bhE-25-YYz" secondAttribute="bottom" constant="16" id="YQ8-Bi-xhj"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="memberImage" destination="jg5-7G-Opf" id="KTP-VB-YuG"/>
+                <outlet property="subjectView" destination="JQZ-qL-qfG" id="53i-9H-Tem"/>
+                <outlet property="subjectViewHeight" destination="12e-F9-uGR" id="laI-yK-4Ze"/>
+                <outlet property="userAvatar" destination="GcD-Ic-cNt" id="Y4k-qy-4L4"/>
+                <outlet property="userIdLabel" destination="DqI-wn-gqn" id="UO0-J2-gy1"/>
+                <outlet property="userName" destination="uqG-dv-SFP" id="7BT-p0-2Ri"/>
+                <outlet property="userSex" destination="yzA-J6-60W" id="0Rv-2j-Tpc"/>
+                <outlet property="userSubject" destination="ab0-kc-WGQ" id="3aw-Ip-Xr2"/>
+            </connections>
+            <point key="canvasLocation" x="101.53846153846153" y="0.35545023696682465"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="chat_use_sex" width="20" height="20"/>
+        <image name="chat_user_subject" width="20" height="20"/>
+        <image name="home_left" width="4" height="12"/>
+        <image name="mine_nomal" width="34" height="15"/>
+        <image name="mine_uid" width="11" height="11"/>
+        <image name="user_default_avatal" width="52" height="52"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 18 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/UserDetailBottomView.h

@@ -0,0 +1,18 @@
+//
+//  UserDetailBottomView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/10/18.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface UserDetailBottomView : UIView
+
++ (instancetype)shareInstance;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 25 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/UserDetailBottomView.m

@@ -0,0 +1,25 @@
+//
+//  UserDetailBottomView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/10/18.
+//
+
+#import "UserDetailBottomView.h"
+
+@implementation UserDetailBottomView
+
+
++ (instancetype)shareInstance {
+    UserDetailBottomView *view = [[[NSBundle mainBundle] loadNibNamed:@"UserDetailBottomView" owner:nil options:nil] firstObject];
+    return view;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 37 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/UserDetailBottomView.xib

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21225" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_0" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21207"/>
+        <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="UserDetailBottomView">
+            <rect key="frame" x="0.0" y="0.0" width="390" height="50"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="——最多显示3首最近练习曲目——" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HjU-rU-MRE">
+                    <rect key="frame" x="102.66666666666669" y="10" width="185" height="17"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="17" id="hAN-8A-cAE"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                    <color key="textColor" red="0.84705882352941175" green="0.84705882352941175" blue="0.84705882352941175" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                    <nil key="highlightedColor"/>
+                </label>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="HjU-rU-MRE" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="10" id="e9c-yn-o5Y"/>
+                <constraint firstItem="HjU-rU-MRE" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="wBY-p3-nzh"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <point key="canvasLocation" x="101.53846153846153" y="-294.31279620853081"/>
+        </view>
+    </objects>
+</document>

+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/UserDetailNavView.h

@@ -0,0 +1,22 @@
+//
+//  UserDetailNavView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/10/18.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef void(^UserDetailCallback)(void);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface UserDetailNavView : UIView
+
++ (instancetype)shareInstance;
+
+- (void)navAction:(UserDetailCallback)callback;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 44 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/UserDetailNavView.m

@@ -0,0 +1,44 @@
+//
+//  UserDetailNavView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/10/18.
+//
+
+#import "UserDetailNavView.h"
+
+@interface UserDetailNavView ()
+
+@property (nonatomic, copy) UserDetailCallback callback;
+
+@end
+
+@implementation UserDetailNavView
+
+
++ (instancetype)shareInstance {
+    UserDetailNavView *view = [[[NSBundle mainBundle] loadNibNamed:@"UserDetailNavView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)navAction:(UserDetailCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (IBAction)navBack:(id)sender {
+    if (self.callback) {
+        self.callback();
+    }
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 69 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ChatUserInfo/UserDetailNavView.xib

@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21225" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_0" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21207"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.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="UserDetailNavView">
+            <rect key="frame" x="0.0" y="0.0" width="390" height="99"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cmT-0r-dtM">
+                    <rect key="frame" x="0.0" y="55" width="390" height="44"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="back_black" translatesAutoresizingMaskIntoConstraints="NO" id="oFb-jc-rdF">
+                            <rect key="frame" x="15" y="12" width="12" height="20"/>
+                        </imageView>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="zKt-ob-UOF">
+                            <rect key="frame" x="0.0" y="2" width="40" height="40"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="40" id="FY2-IW-0aw"/>
+                                <constraint firstAttribute="height" constant="40" id="qdY-9n-Jyq"/>
+                            </constraints>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="navBack:" destination="iN0-l3-epB" eventType="touchUpInside" id="med-KT-Eh5"/>
+                            </connections>
+                        </button>
+                        <label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="用户信息" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qeQ-Mp-wpl">
+                            <rect key="frame" x="158" y="11" width="74" height="22"/>
+                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="18"/>
+                            <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                    </subviews>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstItem="qeQ-Mp-wpl" firstAttribute="centerX" secondItem="cmT-0r-dtM" secondAttribute="centerX" id="3og-nk-hMl"/>
+                        <constraint firstItem="zKt-ob-UOF" firstAttribute="leading" secondItem="cmT-0r-dtM" secondAttribute="leading" id="A3m-xm-Gie"/>
+                        <constraint firstAttribute="height" constant="44" id="CMG-cf-z7o"/>
+                        <constraint firstItem="oFb-jc-rdF" firstAttribute="leading" secondItem="cmT-0r-dtM" secondAttribute="leading" constant="15" id="QJG-dR-rbA"/>
+                        <constraint firstItem="zKt-ob-UOF" firstAttribute="centerY" secondItem="cmT-0r-dtM" secondAttribute="centerY" id="dh7-1N-2Ie"/>
+                        <constraint firstItem="qeQ-Mp-wpl" firstAttribute="centerY" secondItem="cmT-0r-dtM" secondAttribute="centerY" id="ruV-G5-w80"/>
+                        <constraint firstItem="zKt-ob-UOF" firstAttribute="centerY" secondItem="oFb-jc-rdF" secondAttribute="centerY" id="uDO-d6-JEH"/>
+                    </constraints>
+                </view>
+            </subviews>
+            <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="cmT-0r-dtM" secondAttribute="trailing" id="Z0Y-10-LJj"/>
+                <constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="cmT-0r-dtM" secondAttribute="bottom" id="elp-pb-Di9"/>
+                <constraint firstItem="cmT-0r-dtM" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="s4K-nc-Krq"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <point key="canvasLocation" x="101.53846153846153" y="13.151658767772512"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="back_black" width="12" height="20"/>
+    </resources>
+</document>

+ 10 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ContractListCell.m

@@ -14,6 +14,9 @@
 
 @property (weak, nonatomic) IBOutlet UILabel *friendName;
 
+@property (weak, nonatomic) IBOutlet UIImageView *roleTypeView;
+
+
 @end
 
 @implementation ContractListCell
@@ -35,6 +38,13 @@
             self.friendName.text = model.friendNickname;
         }
         self.friendName.text = [NSString returnNoNullStringWithString:model.friendNickname];
+        
+        if ([model.roleType isEqualToString:@"TEACHER"]) {
+            self.roleTypeView.hidden = NO;
+        }
+        else {
+            self.roleTypeView.hidden = YES;
+        }
     }
 }
 

+ 14 - 3
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/ContractListCell.xib

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21225" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
     <device id="retina6_1" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21207"/>
         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
@@ -25,7 +25,7 @@
                         </constraints>
                         <userDefinedRuntimeAttributes>
                             <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                <real key="value" value="6"/>
+                                <real key="value" value="4"/>
                             </userDefinedRuntimeAttribute>
                         </userDefinedRuntimeAttributes>
                     </imageView>
@@ -45,13 +45,22 @@
                             <constraint firstAttribute="height" constant="1" id="pLM-MY-tjk"/>
                         </constraints>
                     </view>
+                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="chat_talentList" translatesAutoresizingMaskIntoConstraints="NO" id="Bwf-x7-UK4">
+                        <rect key="frame" x="14" y="50.5" width="44" height="14"/>
+                        <constraints>
+                            <constraint firstAttribute="width" constant="44" id="Obq-lp-4a7"/>
+                            <constraint firstAttribute="height" constant="14" id="hrG-lt-tyy"/>
+                        </constraints>
+                    </imageView>
                 </subviews>
                 <constraints>
                     <constraint firstItem="8fl-pa-IHx" firstAttribute="centerY" secondItem="vI1-v5-uMm" secondAttribute="centerY" id="9PL-c3-9J3"/>
                     <constraint firstItem="ZD7-0R-OoK" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="72" id="DPF-fF-mtx"/>
                     <constraint firstAttribute="bottom" secondItem="ZD7-0R-OoK" secondAttribute="bottom" id="Qy0-N6-dQU"/>
+                    <constraint firstItem="Bwf-x7-UK4" firstAttribute="centerX" secondItem="vI1-v5-uMm" secondAttribute="centerX" id="RO3-iq-GLY"/>
                     <constraint firstItem="8fl-pa-IHx" firstAttribute="leading" secondItem="vI1-v5-uMm" secondAttribute="trailing" constant="11" id="fdz-o1-pUv"/>
                     <constraint firstAttribute="trailing" secondItem="ZD7-0R-OoK" secondAttribute="trailing" id="qkd-cr-TeW"/>
+                    <constraint firstItem="Bwf-x7-UK4" firstAttribute="bottom" secondItem="vI1-v5-uMm" secondAttribute="bottom" id="sIv-jy-rKN"/>
                     <constraint firstItem="vI1-v5-uMm" firstAttribute="centerY" secondItem="H2p-sc-9uM" secondAttribute="centerY" id="vgm-ZS-Nds"/>
                     <constraint firstItem="vI1-v5-uMm" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="14" id="yHs-ea-3Xd"/>
                 </constraints>
@@ -61,11 +70,13 @@
             <connections>
                 <outlet property="friendAvatar" destination="vI1-v5-uMm" id="Nob-dw-1A8"/>
                 <outlet property="friendName" destination="8fl-pa-IHx" id="o2J-m8-ozl"/>
+                <outlet property="roleTypeView" destination="Bwf-x7-UK4" id="34w-ot-hZ6"/>
             </connections>
             <point key="canvasLocation" x="178.2608695652174" y="95.424107142857139"/>
         </tableViewCell>
     </objects>
     <resources>
         <image name="chat_personLogo" width="44" height="44"/>
+        <image name="chat_talentList" width="44" height="14"/>
     </resources>
 </document>

+ 16 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/KSChatTagView.h

@@ -0,0 +1,16 @@
+//
+//  KSChatTagView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/10/18.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSChatTagView : UIImageView
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 20 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/KSChatTagView.m

@@ -0,0 +1,20 @@
+//
+//  KSChatTagView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/10/18.
+//
+
+#import "KSChatTagView.h"
+
+@implementation KSChatTagView
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 1 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/Course/AccompanyCourse/Controller/AccompanyDetailViewController.m

@@ -230,7 +230,7 @@
 - (void)chatAction {
     if (self.homeworkModel && ![NSString isEmptyString:self.homeworkModel.studentId]) {
         KSChatConversationViewController *conversationVC = [[KSChatConversationViewController alloc] init];
-        conversationVC.targetId = self.homeworkModel.studentId;
+        conversationVC.targetId = self.homeworkModel.imUserId;
         conversationVC.title = self.homeworkModel.studentName;
         conversationVC.conversationType = ConversationType_PRIVATE;
         [self.navigationController pushViewController:conversationVC animated:YES];

+ 1 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/Course/Controller/CourseViewController.m

@@ -485,7 +485,7 @@
     switch (action) {
         case ACCOMPANY_TYPE_CHAT:
         {
-            [self chatAction:source.userId groupName:source.name isGroup:NO];
+            [self chatAction:source.imUserId groupName:source.name isGroup:NO];
         }
             break;
         case ACCOMPANY_TYPE_ADJUST:

+ 1 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Course/Model/TableCourseModel.h

@@ -27,6 +27,7 @@
 @property (nonatomic, strong) NSString *imGroupId;
 @property (nonatomic, strong) NSString *studentReplied;
 @property (nonatomic, strong) NSString *teacherReplied;
+@property (nonatomic, strong) NSString *imUserId;
 
 + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
 - (instancetype)initWithDictionary:(NSDictionary *)dict;

+ 8 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Course/Model/TableCourseModel.m

@@ -24,6 +24,8 @@ NSString *const kTableCourseModelStartTime = @"startTime";
 NSString *const kTableCourseModelImGroupId = @"imGroupId";
 NSString *const kTableCourseModelStudentReplied= @"studentReplied";
 NSString *const kTableCourseModelTeacherReplied = @"teacherReplied";
+NSString *const kTableCourseModelImUserId = @"imUserId";
+
 
 @interface TableCourseModel ()
 
@@ -49,6 +51,7 @@ NSString *const kTableCourseModelTeacherReplied = @"teacherReplied";
 @synthesize imGroupId = _imGroupId;
 @synthesize teacherReplied = _teacherReplied;
 @synthesize studentReplied = _studentReplied;
+@synthesize imUserId = _imUserId;
 
 + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
 {
@@ -78,6 +81,7 @@ NSString *const kTableCourseModelTeacherReplied = @"teacherReplied";
             self.imGroupId = [self objectOrNilForKey:kTableCourseModelImGroupId fromDictionary:dict];
             self.teacherReplied = [self objectOrNilForKey:kTableCourseModelTeacherReplied fromDictionary:dict];
             self.studentReplied = [self objectOrNilForKey:kTableCourseModelStudentReplied fromDictionary:dict];
+            self.imUserId = [self objectOrNilForKey:kTableCourseModelImUserId fromDictionary:dict];
     }
     
     return self;
@@ -103,6 +107,7 @@ NSString *const kTableCourseModelTeacherReplied = @"teacherReplied";
     [mutableDict setValue:self.imGroupId forKey:kTableCourseModelImGroupId];
     [mutableDict setValue:self.teacherReplied forKey:kTableCourseModelTeacherReplied];
     [mutableDict setValue:self.studentReplied forKey:kTableCourseModelStudentReplied];
+    [mutableDict setValue:self.imUserId forKey:kTableCourseModelImUserId];
     
     return [NSDictionary dictionaryWithDictionary:mutableDict];
 }
@@ -146,6 +151,7 @@ NSString *const kTableCourseModelTeacherReplied = @"teacherReplied";
     self.imGroupId = [aDecoder decodeObjectForKey:kTableCourseModelImGroupId];
     self.studentReplied = [aDecoder decodeObjectForKey:kTableCourseModelStudentReplied];
     self.teacherReplied = [aDecoder decodeObjectForKey:kTableCourseModelTeacherReplied];
+    self.imUserId = [aDecoder decodeObjectForKey:kTableCourseModelImUserId];
     return self;
 }
 
@@ -168,6 +174,7 @@ NSString *const kTableCourseModelTeacherReplied = @"teacherReplied";
     [aCoder encodeObject:_imGroupId forKey:kTableCourseModelImGroupId];
     [aCoder encodeObject:_studentReplied forKey:kTableCourseModelStudentReplied];
     [aCoder encodeObject:_teacherReplied forKey:kTableCourseModelTeacherReplied];
+    [aCoder encodeObject:_imUserId forKey:kTableCourseModelImUserId];
     
 }
 
@@ -193,6 +200,7 @@ NSString *const kTableCourseModelTeacherReplied = @"teacherReplied";
         copy.imGroupId = [self.imGroupId copyWithZone:zone];
         copy.teacherReplied = [self.teacherReplied copyWithZone:zone];
         copy.studentReplied = [self.studentReplied copyWithZone:zone];
+        copy.imUserId = [self.imUserId copyWithZone:zone];
     }
     
     return copy;

+ 4 - 26
KulexiuForTeacher/KulexiuForTeacher/Module/Home/Controller/HomeViewController.m

@@ -42,10 +42,6 @@
 #import "HomeHotAlbumCell.h"
 #import "HomeHotMusicModel.h"
 
-#import "KSPremissionAlert.h"
-#import "RecordCheckManager.h"
-#import "KSAccompanyWebViewController.h"
-
 #import "HomeHotMusicView.h"
 #import "HomeHotMusicCollectionCell.h"
 
@@ -1019,28 +1015,10 @@
 
 
 - (void)displaySongDetail:(NSString *)songId {
-    // 检测权限
-    PREMISSIONTYPE micEnable = [RecordCheckManager checkPermissionShowAlert:NO showInView:nil];
-    PREMISSIONTYPE cameraEnable = [RecordCheckManager checkCameraPremissionAvaiable:NO showInView:nil];
-    if (micEnable == PREMISSIONTYPE_YES && cameraEnable == PREMISSIONTYPE_YES) { // 如果麦克风和摄像头权限都有
-        // 跳转到播放页面
-        KSAccompanyWebViewController *detailCtrl = [[KSAccompanyWebViewController alloc] init];
-        detailCtrl.url = [NSString stringWithFormat:@"%@/accompany?id=%@",hostURL, songId];
-        detailCtrl.hiddenNavBar = YES;
-        detailCtrl.parmDic = @{@"isOpenLight" : @(YES), @"orientation" : @(0),@"isHideTitle" : @(YES)};
-        [self.navigationController pushViewController:detailCtrl animated:YES];
-    }
-    else {
-        if (micEnable == PREMISSIONTYPE_NO && cameraEnable == PREMISSIONTYPE_NO) { // 如果麦克风权限和摄像头权限都没有
-            [self showAlertWithMessage:@"请开启相机和麦克风访问权限" type:CHECKDEVICETYPE_BOTH];
-        }
-        else if (micEnable == PREMISSIONTYPE_NO) { // 如果没有麦克风权限
-            [self showAlertWithMessage:@"请开启麦克风访问权限" type:CHECKDEVICETYPE_MIC];
-        }
-        else if (cameraEnable == PREMISSIONTYPE_NO) { // 如果没有摄像头权限
-            [self showAlertWithMessage:@"请开启相机访问权限" type:CHECKDEVICETYPE_CAMREA];
-        }
-    }
+    
+    KSBaseWKWebViewController *ctrl = [[KSBaseWKWebViewController alloc] init];
+    ctrl.url = [NSString stringWithFormat:@"%@%@%@", WEBHOST, @"/#/music-detail?id=",songId];
+    [self.navigationController pushViewController:ctrl animated:YES];
 }
 
 #pragma mark ---- scroll view delegate

+ 1 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/Homework/Model/HomeworkDetailModel.h

@@ -37,6 +37,7 @@
 @property (nonatomic, assign) double reviewHomework;
 @property (nonatomic, strong) NSString *studentId;
 @property (nonatomic, assign) NSInteger homeworkExpire;
+@property (nonatomic, strong) NSString *imUserId;
 
 + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
 - (instancetype)initWithDictionary:(NSDictionary *)dict;

+ 8 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/Home/Homework/Model/HomeworkDetailModel.m

@@ -34,6 +34,8 @@ NSString *const kHomeworkDetailModelTeacherAvatar = @"teacherAvatar";
 NSString *const kHomeworkDetailModelReviewHomework = @"reviewHomework";
 NSString *const kHomeworkDetailModelStudentId = @"studentId";
 NSString *const kHomeworkDetailModelHomeworkExpire = @"homeworkExpire";
+NSString *const kHomeworkDetailModelImUserId = @"imUserId";
+
 
 @interface HomeworkDetailModel ()
 
@@ -69,7 +71,7 @@ NSString *const kHomeworkDetailModelHomeworkExpire = @"homeworkExpire";
 @synthesize reviewHomework = _reviewHomework;
 @synthesize studentId = _studentId;
 @synthesize homeworkExpire = _homeworkExpire;
-
+@synthesize imUserId = _imUserId;
 
 + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
 {
@@ -109,6 +111,7 @@ NSString *const kHomeworkDetailModelHomeworkExpire = @"homeworkExpire";
             self.reviewHomework = [[self objectOrNilForKey:kHomeworkDetailModelReviewHomework fromDictionary:dict] doubleValue];
         self.studentId = [self objectOrNilForKey:kHomeworkDetailModelStudentId fromDictionary:dict];
         self.homeworkExpire = [[self objectOrNilForKey:kHomeworkDetailModelHomeworkExpire fromDictionary:dict] integerValue];
+        self.imUserId = [self objectOrNilForKey:kHomeworkDetailModelImUserId fromDictionary:dict];
     }
     
     return self;
@@ -144,6 +147,7 @@ NSString *const kHomeworkDetailModelHomeworkExpire = @"homeworkExpire";
     [mutableDict setValue:[NSNumber numberWithDouble:self.reviewHomework] forKey:kHomeworkDetailModelReviewHomework];
     [mutableDict setValue:self.studentId forKey:kHomeworkDetailModelStudentId];
     [mutableDict setValue:[NSNumber numberWithInteger:self.homeworkExpire] forKey:kHomeworkDetailModelHomeworkExpire];
+    [mutableDict setValue:self.imUserId forKey:kHomeworkDetailModelImUserId];
     return [NSDictionary dictionaryWithDictionary:mutableDict];
 }
 
@@ -196,6 +200,7 @@ NSString *const kHomeworkDetailModelHomeworkExpire = @"homeworkExpire";
     self.reviewHomework = [aDecoder decodeDoubleForKey:kHomeworkDetailModelReviewHomework];
     self.studentId = [aDecoder decodeObjectForKey:kHomeworkDetailModelStudentId];
     self.homeworkExpire = [aDecoder decodeIntegerForKey:kHomeworkDetailModelHomeworkExpire];
+    self.imUserId = [aDecoder decodeObjectForKey:kHomeworkDetailModelImUserId];
     return self;
 }
 
@@ -228,6 +233,7 @@ NSString *const kHomeworkDetailModelHomeworkExpire = @"homeworkExpire";
     [aCoder encodeDouble:_reviewHomework forKey:kHomeworkDetailModelReviewHomework];
     [aCoder encodeObject:_studentId forKey:kHomeworkDetailModelStudentId];
     [aCoder encodeInteger:_homeworkExpire forKey:kHomeworkDetailModelHomeworkExpire];
+    [aCoder encodeObject:_imUserId forKey:kHomeworkDetailModelImUserId];
 }
 
 - (id)copyWithZone:(NSZone *)zone
@@ -262,6 +268,7 @@ NSString *const kHomeworkDetailModelHomeworkExpire = @"homeworkExpire";
         copy.reviewHomework = self.reviewHomework;
         copy.studentId = [self.studentId copyWithZone:zone];
         copy.homeworkExpire = self.homeworkExpire;
+        copy.imUserId = [self.imUserId copyWithZone:zone];
     }
     
     return copy;

+ 1 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/Homework/Model/HomeworkListModel.h

@@ -33,6 +33,7 @@
 @property (nonatomic, strong) NSString *teacherAvatar;
 @property (nonatomic, strong) NSString *homeworkStatus;
 @property (nonatomic, strong) NSString *imGroupId;
+@property (nonatomic, strong) NSString *imUserId;
 
 + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
 - (instancetype)initWithDictionary:(NSDictionary *)dict;

+ 7 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/Homework/Model/HomeworkListModel.m

@@ -30,6 +30,7 @@ NSString *const kHomeworkListModelStartTime = @"startTime";
 NSString *const kHomeworkListModelTeacherAvatar = @"teacherAvatar";
 NSString *const kHomeworkListModelHomeworkStatus = @"homeworkStatus";
 NSString *const kHomeworkListModelImGroupId = @"imGroupId";
+NSString *const kHomeworkListModelImUserId = @"imUserId";
 
 @interface HomeworkListModel ()
 
@@ -61,6 +62,7 @@ NSString *const kHomeworkListModelImGroupId = @"imGroupId";
 @synthesize teacherAvatar = _teacherAvatar;
 @synthesize homeworkStatus = _homeworkStatus;
 @synthesize imGroupId = _imGroupId;
+@synthesize imUserId = _imUserId;
 
 + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
 {
@@ -96,6 +98,7 @@ NSString *const kHomeworkListModelImGroupId = @"imGroupId";
             self.teacherAvatar = [self objectOrNilForKey:kHomeworkListModelTeacherAvatar fromDictionary:dict];
             self.homeworkStatus = [self objectOrNilForKey:kHomeworkListModelHomeworkStatus fromDictionary:dict];
             self.imGroupId = [self objectOrNilForKey:kHomeworkListModelImGroupId fromDictionary:dict];
+        self.imUserId = [self objectOrNilForKey:kHomeworkListModelImUserId fromDictionary:dict];
     }
     
     return self;
@@ -127,6 +130,7 @@ NSString *const kHomeworkListModelImGroupId = @"imGroupId";
     [mutableDict setValue:self.teacherAvatar forKey:kHomeworkListModelTeacherAvatar];
     [mutableDict setValue:self.homeworkStatus forKey:kHomeworkListModelHomeworkStatus];
     [mutableDict setValue:self.imGroupId forKey:kHomeworkListModelImGroupId];
+    [mutableDict setValue:self.imUserId forKey:kHomeworkListModelImUserId];
     return [NSDictionary dictionaryWithDictionary:mutableDict];
 }
 
@@ -175,6 +179,7 @@ NSString *const kHomeworkListModelImGroupId = @"imGroupId";
     self.teacherAvatar = [aDecoder decodeObjectForKey:kHomeworkListModelTeacherAvatar];
     self.homeworkStatus = [aDecoder decodeObjectForKey:kHomeworkListModelHomeworkStatus];
     self.imGroupId = [aDecoder decodeObjectForKey:kHomeworkListModelImGroupId];
+    self.imUserId = [aDecoder decodeObjectForKey:kHomeworkListModelImUserId];
     return self;
 }
 
@@ -203,6 +208,7 @@ NSString *const kHomeworkListModelImGroupId = @"imGroupId";
     [aCoder encodeObject:_teacherAvatar forKey:kHomeworkListModelTeacherAvatar];
     [aCoder encodeObject:_homeworkStatus forKey:kHomeworkListModelHomeworkStatus];
     [aCoder encodeObject:_imGroupId forKey:kHomeworkListModelImGroupId];
+    [aCoder encodeObject:_imUserId forKey:kHomeworkListModelImUserId];
 }
 
 - (id)copyWithZone:(NSZone *)zone
@@ -233,6 +239,7 @@ NSString *const kHomeworkListModelImGroupId = @"imGroupId";
         copy.teacherAvatar = [self.teacherAvatar copyWithZone:zone];
         copy.homeworkStatus = [self.homeworkStatus copyWithZone:zone];
         copy.imGroupId = [self.imGroupId copyWithZone:zone];
+        copy.imUserId = [self.imUserId copyWithZone:zone];
     }
     
     return copy;

+ 2 - 2
KulexiuForTeacher/KulexiuForTeacher/Module/Home/Homework/View/HomeworkBodyView.m

@@ -192,8 +192,8 @@
         HomeworkListCell *cell = [tableView dequeueReusableCellWithIdentifier:@"HomeworkListCell"];
         [cell configWithSource:model];
         MJWeakSelf;
-        [cell chatWithStudent:^(NSString * _Nonnull userId, NSString * _Nonnull userName) {
-            [weakSelf chatStudent:userId name:userName];
+        [cell chatWithStudent:^(NSString * _Nonnull targetId, NSString * _Nonnull userName) {
+            [weakSelf chatStudent:targetId name:userName];
         }];
         return cell;
     }

+ 1 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/Home/Homework/View/HomeworkListCell.h

@@ -8,7 +8,7 @@
 #import <UIKit/UIKit.h>
 #import "HomeworkListModel.h"
 
-typedef void(^HomeworkChatCallback)(NSString * _Nonnull userId, NSString * _Nonnull userName);
+typedef void(^HomeworkChatCallback)(NSString * _Nonnull targetId, NSString * _Nonnull userName);
 
 NS_ASSUME_NONNULL_BEGIN
 

+ 3 - 3
KulexiuForTeacher/KulexiuForTeacher/Module/Home/Homework/View/HomeworkListCell.m

@@ -21,7 +21,7 @@
 
 @property (nonatomic, copy) HomeworkChatCallback callback;
 
-@property (nonatomic, strong) NSString *userId;
+@property (nonatomic, strong) NSString *targetId;
 
 @property (nonatomic, strong) NSString *userName;
 
@@ -56,7 +56,7 @@
     [self.studentAvatal sd_setImageWithURL:[NSURL URLWithString:[sourceModel.studentAvatar getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:USERDEFAULT_LOGO]];
     self.subjectLabel.text = [NSString returnNoNullStringWithString:sourceModel.subjectName];
 
-    self.userId = sourceModel.studentId;
+    self.targetId = sourceModel.imUserId;
     self.userName = sourceModel.studentName;
     
     // 判断是否布置了作业
@@ -92,7 +92,7 @@
 
 - (IBAction)chatAction:(id)sender {
     if (self.callback) {
-        self.callback(self.userId, self.userName);
+        self.callback(self.targetId, self.userName);
     }
 }
 

+ 1 - 44
KulexiuForTeacher/KulexiuForTeacher/Module/Home/Music/View/MusicMessageCell.m

@@ -18,11 +18,6 @@
 
 @property (weak, nonatomic) IBOutlet UIImageView *playImage;
 
-@property (weak, nonatomic) IBOutlet UIView *typeView; // 类型
-@property (weak, nonatomic) IBOutlet NSLayoutConstraint *typeViewWidth;
-
-
-
 @property (weak, nonatomic) IBOutlet UILabel *songName;
 @property (weak, nonatomic) IBOutlet UILabel *songAuth;
 
@@ -37,7 +32,6 @@
 
 @property (weak, nonatomic) IBOutlet UIImageView *qualityMusicTag;
 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *qualityTagWidth;
-@property (weak, nonatomic) IBOutlet NSLayoutConstraint *qualityLeft;
 
 @property (weak, nonatomic) IBOutlet UIImageView *albumTag;
 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *albumTagWidth;
@@ -62,12 +56,10 @@
     if (songMessage.exquisiteFlag) {
         self.qualityMusicTag.hidden = NO;
         self.qualityTagWidth.constant = 14.0f;
-        self.qualityLeft.constant = 5.0f;
     }
     else {
         self.qualityMusicTag.hidden = NO;
         self.qualityTagWidth.constant = 0.0f;
-        self.qualityLeft.constant = 0.0f;
     }
     
     if (songMessage.albumNums > 0) {
@@ -147,8 +139,7 @@
     
     CGFloat maxWidth = [self getTagViewMaxWidth:authString];
     [self configTagViewWithTagArray:tagArray maxWidth:maxWidth];
-
-    [self configTypeView:songMessage.paymentType];
+    
     [self.musicCover sd_setImageWithURL:[NSURL URLWithString:[songMessage.titleImg getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:@"music_logo"]];
     
     if (rowIndex == ROWINDEX_TOP) {
@@ -185,40 +176,6 @@
     }
 }
 
-- (void)configTypeView:(NSString *)musicType {
-    [self.typeView removeAllSubViews];
-    NSArray * chargeArray = [musicType componentsSeparatedByString:@","];
-    CGFloat singleWidth = 30.0f;
-    CGFloat space = 5.0f;
-    CGFloat height = 17.0f;
-    for (NSInteger index = 0; index < chargeArray.count; index++) {
-        NSString *desc = chargeArray[index];
-        NSString *title = nil;
-        UIColor *borderColor = nil;
-        UIColor *titleColor = nil;
-        if ([desc isEqualToString:@"VIP"]) {
-            borderColor = HexRGB(0xD38535);
-            title = @"会员";
-            titleColor = HexRGB(0xCD863E);
-            
-        }
-        else if ([desc isEqualToString:@"CHARGE"]) {
-            borderColor = HexRGB(0x50A2D8);
-            title = @"点播";
-            titleColor = HexRGB(0x3591CE);
-        }
-        else {
-            borderColor = HexRGB(0x01B84F);
-            title = @"免费";
-            titleColor = HexRGB(0x01B84F);
-        }
-        CGRect frame = CGRectMake((singleWidth + space) * index, 0, singleWidth, height);
-        MusicTagView *typeView = [[MusicTagView alloc] initWithTitle:title titleColor:titleColor borderColor:borderColor];
-        typeView.frame = frame;
-        [self.typeView addSubview:typeView];
-    }
-    self.typeViewWidth.constant = [self getWidthWithTypeCount:chargeArray.count singleWidth:singleWidth space:space];
-}
 
 - (CGFloat)getWidthWithTypeCount:(NSInteger)count singleWidth:(CGFloat)singleWidth space:(CGFloat)space {
     if (count == 1) {

+ 7 - 19
KulexiuForTeacher/KulexiuForTeacher/Module/Home/Music/View/MusicMessageCell.xib

@@ -34,7 +34,7 @@
                                 </userDefinedRuntimeAttributes>
                             </imageView>
                             <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="野蜂飞舞" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dl5-Bm-goQ">
-                                <rect key="frame" x="144" y="16" width="57.5" height="17"/>
+                                <rect key="frame" x="109" y="16" width="57.5" height="17"/>
                                 <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="14"/>
                                 <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
                                 <nil key="highlightedColor"/>
@@ -55,14 +55,6 @@
                                     <constraint firstAttribute="height" constant="16" id="IV6-At-KXT"/>
                                 </constraints>
                             </view>
-                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0sg-Qr-0or">
-                                <rect key="frame" x="70" y="16" width="30" height="17"/>
-                                <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                                <constraints>
-                                    <constraint firstAttribute="height" constant="17" id="OPA-je-PeY"/>
-                                    <constraint firstAttribute="width" constant="30" id="sG9-Hf-9Fa"/>
-                                </constraints>
-                            </view>
                             <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Zm8-lb-ZEo">
                                 <rect key="frame" x="14" y="79.5" width="318" height="0.5"/>
                                 <color key="backgroundColor" red="0.90980392160000001" green="0.90980392160000001" blue="0.90980392160000001" alpha="1" colorSpace="calibratedRGB"/>
@@ -129,14 +121,14 @@
                                 </constraints>
                             </imageView>
                             <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="quality_tag" translatesAutoresizingMaskIntoConstraints="NO" id="efH-vf-n5D">
-                                <rect key="frame" x="105" y="16" width="14" height="17"/>
+                                <rect key="frame" x="70" y="16" width="14" height="17"/>
                                 <constraints>
                                     <constraint firstAttribute="width" constant="14" id="uo4-Yf-NAJ"/>
                                     <constraint firstAttribute="height" constant="17" id="ysN-Wh-zu7"/>
                                 </constraints>
                             </imageView>
                             <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="music_albumTag" translatesAutoresizingMaskIntoConstraints="NO" id="Gc5-5a-gxz">
-                                <rect key="frame" x="124" y="17" width="15" height="15"/>
+                                <rect key="frame" x="89" y="17" width="15" height="15"/>
                                 <constraints>
                                     <constraint firstAttribute="height" constant="15" id="7in-dV-GCa"/>
                                     <constraint firstAttribute="width" constant="15" id="git-tP-3Tg"/>
@@ -146,29 +138,28 @@
                         <color key="backgroundColor" systemColor="systemBackgroundColor"/>
                         <constraints>
                             <constraint firstAttribute="bottom" secondItem="Zm8-lb-ZEo" secondAttribute="bottom" id="7NW-eL-QbL"/>
+                            <constraint firstItem="efH-vf-n5D" firstAttribute="top" secondItem="7XK-Ip-4nf" secondAttribute="top" id="7ZI-UH-wXf"/>
                             <constraint firstAttribute="trailing" secondItem="ZTx-7w-9HF" secondAttribute="trailing" constant="14" id="A59-EX-Pwf"/>
-                            <constraint firstItem="0sg-Qr-0or" firstAttribute="top" secondItem="7XK-Ip-4nf" secondAttribute="top" id="DcX-XV-hYx"/>
                             <constraint firstAttribute="trailing" secondItem="bva-Fc-J3U" secondAttribute="trailing" constant="12" id="DqR-tq-mTT"/>
                             <constraint firstItem="ZTx-7w-9HF" firstAttribute="centerY" secondItem="sfm-yS-y7g" secondAttribute="centerY" id="EOH-Nv-6oY"/>
-                            <constraint firstItem="0sg-Qr-0or" firstAttribute="leading" secondItem="7XK-Ip-4nf" secondAttribute="trailing" constant="11" id="GMO-Kg-sl1"/>
                             <constraint firstItem="dl5-Bm-goQ" firstAttribute="centerY" secondItem="Gc5-5a-gxz" secondAttribute="centerY" id="Gcu-kB-2dH"/>
                             <constraint firstItem="RpH-mG-bAV" firstAttribute="bottom" secondItem="7XK-Ip-4nf" secondAttribute="bottom" id="JEt-PA-q5v"/>
                             <constraint firstItem="zQo-zL-Uo4" firstAttribute="centerY" secondItem="sfm-yS-y7g" secondAttribute="centerY" id="KR0-7u-JUu"/>
-                            <constraint firstItem="dl5-Bm-goQ" firstAttribute="centerY" secondItem="0sg-Qr-0or" secondAttribute="centerY" id="MlC-5R-Fe3"/>
                             <constraint firstItem="RpH-mG-bAV" firstAttribute="leading" secondItem="7XK-Ip-4nf" secondAttribute="trailing" constant="11" id="Mp7-f0-ZO7"/>
                             <constraint firstItem="zQo-zL-Uo4" firstAttribute="trailing" secondItem="u0Q-lP-CEF" secondAttribute="trailing" id="N32-3C-GRm"/>
-                            <constraint firstItem="efH-vf-n5D" firstAttribute="centerY" secondItem="0sg-Qr-0or" secondAttribute="centerY" id="a0E-ob-qWA"/>
                             <constraint firstItem="7XK-Ip-4nf" firstAttribute="centerY" secondItem="sfm-yS-y7g" secondAttribute="centerY" id="gC0-wR-eHn"/>
                             <constraint firstItem="bva-Fc-J3U" firstAttribute="centerY" secondItem="RpH-mG-bAV" secondAttribute="centerY" id="hFT-pZ-tvT"/>
+                            <constraint firstItem="efH-vf-n5D" firstAttribute="leading" secondItem="7XK-Ip-4nf" secondAttribute="trailing" constant="11" id="hqJ-Yg-38A"/>
                             <constraint firstItem="dl5-Bm-goQ" firstAttribute="leading" secondItem="Gc5-5a-gxz" secondAttribute="trailing" constant="5" id="l6M-X2-dii"/>
                             <constraint firstItem="Zm8-lb-ZEo" firstAttribute="leading" secondItem="sfm-yS-y7g" secondAttribute="leading" constant="14" id="lcg-jT-vjD"/>
                             <constraint firstItem="Gc5-5a-gxz" firstAttribute="leading" secondItem="efH-vf-n5D" secondAttribute="trailing" constant="5" id="llw-uj-pTi"/>
                             <constraint firstItem="zQo-zL-Uo4" firstAttribute="bottom" secondItem="u0Q-lP-CEF" secondAttribute="bottom" id="mdH-Xd-Com"/>
-                            <constraint firstItem="efH-vf-n5D" firstAttribute="leading" secondItem="0sg-Qr-0or" secondAttribute="trailing" constant="5" id="mkh-Ux-PW1"/>
+                            <constraint firstItem="dl5-Bm-goQ" firstAttribute="centerY" secondItem="efH-vf-n5D" secondAttribute="centerY" id="q0N-zi-0Yd"/>
                             <constraint firstAttribute="trailing" secondItem="Zm8-lb-ZEo" secondAttribute="trailing" constant="15" id="sCS-HL-jo0"/>
                             <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="dl5-Bm-goQ" secondAttribute="trailing" constant="10" id="sap-V4-hyb"/>
                             <constraint firstItem="zQo-zL-Uo4" firstAttribute="leading" secondItem="u0Q-lP-CEF" secondAttribute="leading" id="tMw-2C-LzA"/>
                             <constraint firstItem="zQo-zL-Uo4" firstAttribute="top" secondItem="u0Q-lP-CEF" secondAttribute="top" id="vFa-Bi-Li9"/>
+                            <constraint firstItem="Gc5-5a-gxz" firstAttribute="centerY" secondItem="efH-vf-n5D" secondAttribute="centerY" id="vJ2-6z-7mo"/>
                             <constraint firstItem="7XK-Ip-4nf" firstAttribute="leading" secondItem="sfm-yS-y7g" secondAttribute="leading" constant="11" id="wWE-uW-GBd"/>
                             <constraint firstAttribute="trailing" secondItem="zQo-zL-Uo4" secondAttribute="trailing" constant="13" id="yrx-j1-I2z"/>
                             <constraint firstItem="bva-Fc-J3U" firstAttribute="leading" secondItem="RpH-mG-bAV" secondAttribute="trailing" constant="7" id="z8B-DS-OF4"/>
@@ -197,14 +188,11 @@
                 <outlet property="lineView" destination="Zm8-lb-ZEo" id="442-Ky-3TP"/>
                 <outlet property="musicCover" destination="7XK-Ip-4nf" id="eLL-Uh-TYx"/>
                 <outlet property="playImage" destination="ZTx-7w-9HF" id="b4d-YC-5QM"/>
-                <outlet property="qualityLeft" destination="mkh-Ux-PW1" id="z3e-EE-3eV"/>
                 <outlet property="qualityMusicTag" destination="efH-vf-n5D" id="vtP-Nc-7QR"/>
                 <outlet property="qualityTagWidth" destination="uo4-Yf-NAJ" id="bCv-Yj-dxq"/>
                 <outlet property="songAuth" destination="RpH-mG-bAV" id="KhE-Bc-yps"/>
                 <outlet property="songName" destination="dl5-Bm-goQ" id="bec-Nd-9g2"/>
                 <outlet property="tagView" destination="bva-Fc-J3U" id="E48-ph-0x7"/>
-                <outlet property="typeView" destination="0sg-Qr-0or" id="bll-P9-6T7"/>
-                <outlet property="typeViewWidth" destination="sG9-Hf-9Fa" id="ajC-k4-Lo8"/>
             </connections>
             <point key="canvasLocation" x="131.15942028985509" y="91.071428571428569"/>
         </tableViewCell>

+ 4 - 6
KulexiuForTeacher/KulexiuForTeacher/Module/Home/Music/View/MyMusicBodyView.m

@@ -10,7 +10,6 @@
 #import "MusicMessageCell.h"
 #import "KSBaseWKWebViewController.h"
 #import "AuthDisplayView.h"
-#import "KSAccompanyWebViewController.h"
 #import "KSPublicAlertView.h"
 
 @interface MyMusicBodyView ()<UITableViewDelegate,UITableViewDataSource>
@@ -256,11 +255,10 @@
     }
     else { // 播放曲谱
         MusicMessageModel *model = self.dataArray[indexPath.row];
-        KSAccompanyWebViewController *detailCtrl = [[KSAccompanyWebViewController alloc] init];
-        detailCtrl.url = [NSString stringWithFormat:@"%@/accompany?id=%.0f&client=teacher",hostURL, model.internalBaseClassIdentifier];
-        detailCtrl.hiddenNavBar = YES;
-        detailCtrl.parmDic = @{@"isOpenLight" : @(YES), @"orientation" : @(0),@"isHideTitle" : @(YES)};
-        [self.naviController pushViewController:detailCtrl animated:YES];
+        
+        KSBaseWKWebViewController *ctrl = [[KSBaseWKWebViewController alloc] init];
+        ctrl.url = [NSString stringWithFormat:@"%@%@%.0f", WEBHOST, @"/#/music-detail?id=",model.internalBaseClassIdentifier];
+        [self.naviController pushViewController:ctrl animated:YES];
     }
 }
 

+ 1 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/Model/AccompanyLessonModel.h

@@ -25,6 +25,7 @@
 @property (nonatomic, strong) NSString *startTime;
 @property (nonatomic, strong) NSString *status;
 @property (nonatomic, strong) NSString *teacherReplied;
+@property (nonatomic, strong) NSString *imUserId;
 
 + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
 - (instancetype)initWithDictionary:(NSDictionary *)dict;

+ 7 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/Model/AccompanyLessonModel.m

@@ -22,6 +22,7 @@ NSString *const kAccompanyLessonModelUserName = @"userName";
 NSString *const kAccompanyLessonModelStartTime = @"startTime";
 NSString *const kAccompanyLessonModelStatus = @"status";
 NSString *const kAccompanyLessonModelTeacherReplied = @"teacherReplied";
+NSString *const kAccompanyLessonModelImUserId = @"imUserId";
 
 @interface AccompanyLessonModel ()
 
@@ -45,6 +46,7 @@ NSString *const kAccompanyLessonModelTeacherReplied = @"teacherReplied";
 @synthesize startTime = _startTime;
 @synthesize status = _status;
 @synthesize teacherReplied = _teacherReplied;
+@synthesize imUserId = _imUserId;
 
 + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
 {
@@ -72,6 +74,7 @@ NSString *const kAccompanyLessonModelTeacherReplied = @"teacherReplied";
             self.startTime = [self objectOrNilForKey:kAccompanyLessonModelStartTime fromDictionary:dict];
             self.status = [self objectOrNilForKey:kAccompanyLessonModelStatus fromDictionary:dict];
             self.teacherReplied = [self objectOrNilForKey:kAccompanyLessonModelTeacherReplied fromDictionary:dict];
+            self.imUserId = [self objectOrNilForKey:kAccompanyLessonModelImUserId fromDictionary:dict];
     }
     
     return self;
@@ -95,6 +98,7 @@ NSString *const kAccompanyLessonModelTeacherReplied = @"teacherReplied";
     [mutableDict setValue:self.startTime forKey:kAccompanyLessonModelStartTime];
     [mutableDict setValue:self.status forKey:kAccompanyLessonModelStatus];
     [mutableDict setValue:self.teacherReplied forKey:kAccompanyLessonModelTeacherReplied];
+    [mutableDict setValue:self.imUserId forKey:kAccompanyLessonModelImUserId];
     
     return [NSDictionary dictionaryWithDictionary:mutableDict];
 }
@@ -136,6 +140,7 @@ NSString *const kAccompanyLessonModelTeacherReplied = @"teacherReplied";
     self.startTime = [aDecoder decodeObjectForKey:kAccompanyLessonModelStartTime];
     self.status = [aDecoder decodeObjectForKey:kAccompanyLessonModelStatus];
     self.teacherReplied = [aDecoder decodeObjectForKey:kAccompanyLessonModelTeacherReplied];
+    self.imUserId = [aDecoder decodeObjectForKey:kAccompanyLessonModelImUserId];
     return self;
 }
 
@@ -156,6 +161,7 @@ NSString *const kAccompanyLessonModelTeacherReplied = @"teacherReplied";
     [aCoder encodeObject:_startTime forKey:kAccompanyLessonModelStartTime];
     [aCoder encodeObject:_status forKey:kAccompanyLessonModelStatus];
     [aCoder encodeObject:_teacherReplied forKey:kAccompanyLessonModelTeacherReplied];
+    [aCoder encodeObject:_imUserId forKey:kAccompanyLessonModelImUserId];
 }
 
 - (id)copyWithZone:(NSZone *)zone
@@ -178,6 +184,7 @@ NSString *const kAccompanyLessonModelTeacherReplied = @"teacherReplied";
         copy.startTime = [self.startTime copyWithZone:zone];
         copy.status = [self.status copyWithZone:zone];
         copy.teacherReplied = [self.teacherReplied copyWithZone:zone];
+        copy.imUserId = [self.imUserId copyWithZone:zone];
     }
     
     return copy;

+ 1 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MyLessonBodyView.m

@@ -420,7 +420,7 @@
         case ACCOMPANY_TYPE_CHAT: // 聊天
         {
             KSChatConversationViewController *conversationVC = [[KSChatConversationViewController alloc] init];
-            conversationVC.targetId = model.userId;
+            conversationVC.targetId = model.imUserId;
             conversationVC.conversationType = ConversationType_PRIVATE;
             [self.naviController pushViewController:conversationVC animated:YES];
         }

+ 7 - 4
KulexiuForTeacher/KulexiuForTeacher/Module/Home/View/HomeHotAlbumCell.xib

@@ -29,9 +29,6 @@
                             </userDefinedRuntimeAttribute>
                         </userDefinedRuntimeAttributes>
                     </imageView>
-                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="albumTag_VIP" translatesAutoresizingMaskIntoConstraints="NO" id="E1s-oA-ark">
-                        <rect key="frame" x="3" y="10" width="26" height="14"/>
-                    </imageView>
                     <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="萨克斯新手…" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1bh-Zm-ov0">
                         <rect key="frame" x="3" y="114" width="94" height="20"/>
                         <constraints>
@@ -85,6 +82,13 @@
                             </userDefinedRuntimeAttribute>
                         </userDefinedRuntimeAttributes>
                     </view>
+                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="E1s-oA-ark">
+                        <rect key="frame" x="3" y="10" width="26" height="14"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="14" id="b4Q-3I-ers"/>
+                            <constraint firstAttribute="width" constant="26" id="ywB-hP-fl5"/>
+                        </constraints>
+                    </imageView>
                 </subviews>
             </view>
             <viewLayoutGuide key="safeArea" id="SEy-5g-ep8"/>
@@ -111,7 +115,6 @@
         </collectionViewCell>
     </objects>
     <resources>
-        <image name="albumTag_VIP" width="26" height="14"/>
         <image name="album_collect" width="8" height="8"/>
         <image name="video_placeholder" width="103" height="72"/>
     </resources>

+ 0 - 40
KulexiuForTeacher/KulexiuForTeacher/Module/Home/View/HomeMusic/HomeHotMusicCellView.m

@@ -10,8 +10,6 @@
 
 @interface HomeHotMusicCellView ()
 
-@property (weak, nonatomic) IBOutlet UIView *typeView;
-@property (weak, nonatomic) IBOutlet NSLayoutConstraint *typeViewWidth;
 
 @property (weak, nonatomic) IBOutlet UILabel *songNameLabel;
 @property (weak, nonatomic) IBOutlet UILabel *songAuth;
@@ -26,7 +24,6 @@
 
 @property (weak, nonatomic) IBOutlet UIImageView *qualityMusicTag;
 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *qualityTagWidth;
-@property (weak, nonatomic) IBOutlet NSLayoutConstraint *qualityLeft;
 
 @property (weak, nonatomic) IBOutlet UIImageView *albumTag;
 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *albumTagWidth;
@@ -48,12 +45,10 @@
     if (sourceModel.exquisiteFlag) {
         self.qualityMusicTag.hidden = NO;
         self.qualityTagWidth.constant = 14.0f;
-        self.qualityLeft.constant = 5.0f;
     }
     else {
         self.qualityMusicTag.hidden = NO;
         self.qualityTagWidth.constant = 0.0f;
-        self.qualityLeft.constant = 0.0f;
     }
     
     if (sourceModel.albumNums > 0) {
@@ -115,41 +110,6 @@
     CGFloat maxWidth = [self getTagViewMaxWidth:owner];
     [self configTagViewWithTagArray:tagArray maxWidth:maxWidth];
     self.lineView.hidden = hideLineView;
-    [self configTypeView:sourceModel.paymentType];
-}
-- (void)configTypeView:(NSString *)musicType {
-    [self.typeView removeAllSubViews];
-    NSArray * chargeArray = [musicType componentsSeparatedByString:@","];
-    CGFloat singleWidth = 30.0f;
-    CGFloat space = 5.0f;
-    CGFloat height = 17.0f;
-    for (NSInteger index = 0; index < chargeArray.count; index++) {
-        NSString *desc = chargeArray[index];
-        NSString *title = nil;
-        UIColor *borderColor = nil;
-        UIColor *titleColor = nil;
-        if ([desc isEqualToString:@"VIP"]) {
-            borderColor = HexRGB(0xD38535);
-            title = @"会员";
-            titleColor = HexRGB(0xCD863E);
-            
-        }
-        else if ([desc isEqualToString:@"CHARGE"]) {
-            borderColor = HexRGB(0x50A2D8);
-            title = @"点播";
-            titleColor = HexRGB(0x3591CE);
-        }
-        else {
-            borderColor = HexRGB(0x01B84F);
-            title = @"免费";
-            titleColor = HexRGB(0x01B84F);
-        }
-        CGRect frame = CGRectMake((singleWidth + space) * index, 0, singleWidth, height);
-        MusicTagView *typeView = [[MusicTagView alloc] initWithTitle:title titleColor:titleColor borderColor:borderColor];
-        typeView.frame = frame;
-        [self.typeView addSubview:typeView];
-    }
-    self.typeViewWidth.constant = [self getWidthWithTypeCount:chargeArray.count singleWidth:singleWidth space:space];
 }
 
 - (CGFloat)getWidthWithTypeCount:(NSInteger)count singleWidth:(CGFloat)singleWidth space:(CGFloat)space {

+ 9 - 24
KulexiuForTeacher/KulexiuForTeacher/Module/Home/View/HomeMusic/HomeHotMusicCellView.xib

@@ -4,7 +4,6 @@
     <dependencies>
         <deployment identifier="iOS"/>
         <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21207"/>
-        <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,22 +13,14 @@
             <rect key="frame" x="0.0" y="0.0" width="414" height="93"/>
             <autoresizingMask key="autoresizingMask"/>
             <subviews>
-                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="N1D-TV-iWW">
-                    <rect key="frame" x="11" y="19" width="30" height="17"/>
-                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                    <constraints>
-                        <constraint firstAttribute="width" constant="30" id="Fkh-p3-6cV"/>
-                        <constraint firstAttribute="height" constant="17" id="ibb-Fp-9vJ"/>
-                    </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="7xw-r5-qc1">
-                    <rect key="frame" x="85" y="17.5" width="98" height="20"/>
+                    <rect key="frame" x="50" y="17.5" width="98" height="20"/>
                     <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
                     <color key="textColor" red="0.1019607843" green="0.1019607843" blue="0.1019607843" 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="jm2-P7-5K9">
-                    <rect key="frame" x="188" y="20" width="43" height="15"/>
+                    <rect key="frame" x="153" y="20" width="43" height="15"/>
                     <fontDescription key="fontDescription" type="system" pointSize="12"/>
                     <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
                     <nil key="highlightedColor"/>
@@ -62,14 +53,14 @@
                     </constraints>
                 </view>
                 <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="quality_tag" translatesAutoresizingMaskIntoConstraints="NO" id="KtS-XT-IOh">
-                    <rect key="frame" x="46" y="19" width="14" height="17"/>
+                    <rect key="frame" x="11" y="19" width="14" height="17"/>
                     <constraints>
                         <constraint firstAttribute="width" constant="14" id="qbi-AW-4Ra"/>
                         <constraint firstAttribute="height" constant="17" id="xIf-1B-dUw"/>
                     </constraints>
                 </imageView>
                 <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="music_albumTag" translatesAutoresizingMaskIntoConstraints="NO" id="5nH-uA-3wQ">
-                    <rect key="frame" x="65" y="20" width="15" height="15"/>
+                    <rect key="frame" x="30" y="20" width="15" height="15"/>
                     <constraints>
                         <constraint firstAttribute="width" constant="15" id="NYn-2M-U8C"/>
                         <constraint firstAttribute="height" constant="15" id="dhl-LE-p9a"/>
@@ -85,21 +76,20 @@
             </subviews>
             <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
             <constraints>
-                <constraint firstItem="KtS-XT-IOh" firstAttribute="centerY" secondItem="N1D-TV-iWW" secondAttribute="centerY" id="8MH-KV-lh8"/>
+                <constraint firstItem="7xw-r5-qc1" firstAttribute="centerY" secondItem="KtS-XT-IOh" secondAttribute="centerY" id="6Kh-wM-WGF"/>
                 <constraint firstItem="6eO-qE-g8x" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="jm2-P7-5K9" secondAttribute="trailing" constant="10" id="BiV-XL-Qww"/>
                 <constraint firstAttribute="bottom" secondItem="28W-1K-xs7" secondAttribute="bottom" id="EEi-j6-bXC"/>
-                <constraint firstItem="N1D-TV-iWW" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="19" id="Gyv-2L-yeF"/>
                 <constraint firstItem="7xw-r5-qc1" firstAttribute="leading" secondItem="5nH-uA-3wQ" secondAttribute="trailing" constant="5" id="H0v-BS-VTD"/>
-                <constraint firstItem="KtS-XT-IOh" firstAttribute="leading" secondItem="N1D-TV-iWW" secondAttribute="trailing" constant="5" id="ISl-Jb-v2z"/>
                 <constraint firstItem="qrG-kH-VRz" firstAttribute="leading" secondItem="yx5-8B-fUi" secondAttribute="trailing" constant="12" id="Jbt-JJ-kdQ"/>
                 <constraint firstAttribute="trailing" secondItem="6eO-qE-g8x" secondAttribute="trailing" constant="19" id="OFX-bH-zcc"/>
-                <constraint firstItem="N1D-TV-iWW" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="11" id="Q0e-D9-JXV"/>
                 <constraint firstItem="6eO-qE-g8x" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="Rjr-rO-hGW"/>
                 <constraint firstItem="5nH-uA-3wQ" firstAttribute="centerY" secondItem="KtS-XT-IOh" secondAttribute="centerY" id="Sgz-3n-bdI"/>
                 <constraint firstItem="28W-1K-xs7" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="11" id="XMy-D4-KQK"/>
+                <constraint firstItem="5nH-uA-3wQ" firstAttribute="centerY" secondItem="KtS-XT-IOh" secondAttribute="centerY" id="bbs-C0-Xjs"/>
                 <constraint firstItem="qrG-kH-VRz" firstAttribute="centerY" secondItem="yx5-8B-fUi" secondAttribute="centerY" id="cMa-5P-a2v"/>
                 <constraint firstItem="6eO-qE-g8x" firstAttribute="leading" secondItem="qrG-kH-VRz" secondAttribute="trailing" constant="5" id="cPj-aW-vdE"/>
                 <constraint firstAttribute="trailing" secondItem="28W-1K-xs7" secondAttribute="trailing" constant="13" id="dez-R9-Ydg"/>
+                <constraint firstItem="KtS-XT-IOh" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="11" id="gZR-8J-Dht"/>
                 <constraint firstAttribute="trailing" secondItem="fGG-J1-J8q" secondAttribute="trailing" id="j3e-Gz-5as"/>
                 <constraint firstAttribute="bottom" secondItem="fGG-J1-J8q" secondAttribute="bottom" id="jNd-iF-vI9"/>
                 <constraint firstItem="fGG-J1-J8q" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="kze-In-Wh4"/>
@@ -108,8 +98,9 @@
                 <constraint firstItem="jm2-P7-5K9" firstAttribute="centerY" secondItem="7xw-r5-qc1" secondAttribute="centerY" id="rq7-V0-xTf"/>
                 <constraint firstItem="yx5-8B-fUi" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="11" id="tKz-3F-Rw0"/>
                 <constraint firstItem="fGG-J1-J8q" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="vln-aR-Mmc"/>
+                <constraint firstItem="jm2-P7-5K9" firstAttribute="centerY" secondItem="KtS-XT-IOh" secondAttribute="centerY" id="x7f-f4-qmu"/>
                 <constraint firstItem="5nH-uA-3wQ" firstAttribute="leading" secondItem="KtS-XT-IOh" secondAttribute="trailing" constant="5" id="xVQ-RR-dnF"/>
-                <constraint firstItem="7xw-r5-qc1" firstAttribute="centerY" secondItem="N1D-TV-iWW" secondAttribute="centerY" id="xew-7a-geL"/>
+                <constraint firstItem="KtS-XT-IOh" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="19" id="z25-XN-QgT"/>
             </constraints>
             <nil key="simulatedTopBarMetrics"/>
             <nil key="simulatedBottomBarMetrics"/>
@@ -119,14 +110,11 @@
                 <outlet property="albumTagLeft" destination="xVQ-RR-dnF" id="3QW-aY-jxe"/>
                 <outlet property="albumTagWidth" destination="NYn-2M-U8C" id="eX5-LR-LTm"/>
                 <outlet property="lineView" destination="28W-1K-xs7" id="4mk-r2-0Cz"/>
-                <outlet property="qualityLeft" destination="ISl-Jb-v2z" id="sib-ac-sIO"/>
                 <outlet property="qualityMusicTag" destination="KtS-XT-IOh" id="iJb-sj-SzP"/>
                 <outlet property="qualityTagWidth" destination="qbi-AW-4Ra" id="UMO-DU-Z6o"/>
                 <outlet property="songAuth" destination="jm2-P7-5K9" id="rS6-tU-qwV"/>
                 <outlet property="songNameLabel" destination="7xw-r5-qc1" id="fzV-Mi-66B"/>
                 <outlet property="tagView" destination="qrG-kH-VRz" id="za1-QD-1A2"/>
-                <outlet property="typeView" destination="N1D-TV-iWW" id="NlJ-g6-aro"/>
-                <outlet property="typeViewWidth" destination="Fkh-p3-6cV" id="wLC-I3-akC"/>
                 <outlet property="uploadName" destination="yx5-8B-fUi" id="WSv-Gx-SCl"/>
             </connections>
             <point key="canvasLocation" x="101.44927536231884" y="67.299107142857139"/>
@@ -136,8 +124,5 @@
         <image name="home_music_play" width="24" height="24"/>
         <image name="music_albumTag" width="15" height="15"/>
         <image name="quality_tag" width="14" height="17"/>
-        <systemColor name="systemBackgroundColor">
-            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-        </systemColor>
     </resources>
 </document>

+ 8 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Login/Model/UserInfoManager.m

@@ -283,13 +283,21 @@
     // 融云登录
     [[RCIM sharedRCIM] connectWithToken:UserDefault(RongTokenKey) dbOpened:^(RCDBErrorCode code) {
         
+        // 移除部分会话
+        // 只删除一次
+//        [[RCCoreClient sharedCoreClient] clearConversations:@[@(ConversationType_PRIVATE)]];
+        
     } success:^(NSString *userId) {
         
         [RCConnectionManager shareManager].isConnected = YES;
         // 设置个人信息
         RCUserInfo *currentUserInfo =
         [[RCUserInfo alloc] initWithUserId:userId name:UserDefault(NicknameKey) portrait:UserDefault(AvatarUrlKey)];
+        NSMutableDictionary *extraDic = [NSMutableDictionary dictionary];
+        [extraDic setValue:@"TEACHER" forKey:@"role"];
+        currentUserInfo.extra = [extraDic mj_JSONString];
         [RCIM sharedRCIM].currentUserInfo = currentUserInfo;
+        
     } error:^(RCConnectErrorCode errorCode) {
         
         if (errorCode == RC_CONN_TOKEN_INCORRECT) {

+ 1 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/MidiPlayer/ShareInChat/View/ShareChooseMainView.m

@@ -287,7 +287,7 @@
         NSArray *filterArray = self.studentArray[indexPath.section];
         FriendListModel *model = filterArray[indexPath.row];
         if (self.callback) {
-            self.callback(model.friendId, NO);
+            self.callback(model.imFriendId, NO);
         }
     }
     else { // 群聊

+ 4 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/CreateStyle/Controller/MyStyleViewController.m

@@ -761,8 +761,11 @@
     // 设置个人信息
     RCUserInfo *currentUserInfo =
     [[RCUserInfo alloc] initWithUserId:UserDefault(UIDKey) name:UserDefault(NicknameKey) portrait:UserDefault(AvatarUrlKey)];
+    NSMutableDictionary *extraDic = [NSMutableDictionary dictionary];
+    [extraDic setValue:@"TEACHER" forKey:@"role"];
+    currentUserInfo.extra = [extraDic mj_JSONString];
     [RCIM sharedRCIM].currentUserInfo = currentUserInfo;
-    [[RCIM sharedRCIM] clearGroupUserInfoCache];
+    [[RCIM sharedRCIM] refreshUserInfoCache:currentUserInfo withUserId:UserDefault(UIDKey)];
 }
 
 

+ 4 - 7
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/MinePageCourseView.m

@@ -19,7 +19,6 @@
 #import "KSFullDatePicker.h"
 #import "MusicSortView.h"
 #import "KSChoosePicker.h"
-#import "KSAccompanyWebViewController.h"
 
 @interface MinePageCourseView ()<UITableViewDelegate,UITableViewDataSource>
 
@@ -326,7 +325,7 @@
         case ACCOMPANY_TYPE_CHAT: // 聊天
         {
             KSChatConversationViewController *conversationVC = [[KSChatConversationViewController alloc] init];
-            conversationVC.targetId = model.userId;
+            conversationVC.targetId = model.imUserId;
             conversationVC.conversationType = ConversationType_PRIVATE;
             [self.naviController pushViewController:conversationVC animated:YES];
         }
@@ -383,11 +382,9 @@
     }
     else if (self.selectIndex == 4) { // 曲谱详情
         MusicMessageModel *model = self.dataArray[indexPath.row];
-        KSAccompanyWebViewController *detailCtrl = [[KSAccompanyWebViewController alloc] init];
-        detailCtrl.url = [NSString stringWithFormat:@"%@/accompany?id=%.0f&client=teacher",hostURL, model.internalBaseClassIdentifier];
-        detailCtrl.hiddenNavBar = YES;
-        detailCtrl.parmDic = @{@"isOpenLight" : @(YES), @"orientation" : @(0),@"isHideTitle" : @(YES)};
-        [self.naviController pushViewController:detailCtrl animated:YES];
+        KSBaseWKWebViewController *ctrl = [[KSBaseWKWebViewController alloc] init];
+        ctrl.url = [NSString stringWithFormat:@"%@%@%.0f", WEBHOST, @"/#/music-detail?id=",model.internalBaseClassIdentifier];
+        [self.naviController pushViewController:ctrl animated:YES];
     }
 }
 

+ 0 - 43
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/MinePageMusicCell.m

@@ -16,8 +16,6 @@
 
 @property (weak, nonatomic) IBOutlet UIImageView *musicCover;
 
-@property (weak, nonatomic) IBOutlet UIView *typeView;
-@property (weak, nonatomic) IBOutlet NSLayoutConstraint *typeViewWidth;
 
 @property (weak, nonatomic) IBOutlet UIView *bgView;
 
@@ -25,7 +23,6 @@
 
 @property (weak, nonatomic) IBOutlet UIImageView *qualityMusicTag;
 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *qualityTagWidth;
-@property (weak, nonatomic) IBOutlet NSLayoutConstraint *qualityLeft;
 
 @property (weak, nonatomic) IBOutlet UIImageView *albumTag;
 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *albumTagWidth;
@@ -79,12 +76,10 @@
     if (songMessage.exquisiteFlag) {
         self.qualityMusicTag.hidden = NO;
         self.qualityTagWidth.constant = 14.0f;
-        self.qualityLeft.constant = 5.0f;
     }
     else {
         self.qualityMusicTag.hidden = NO;
         self.qualityTagWidth.constant = 0.0f;
-        self.qualityLeft.constant = 0.0f;
     }
     
     if (songMessage.albumNums > 0) {
@@ -110,47 +105,9 @@
     CGFloat maxWidth = [self getTagViewMaxWidth:authSting];
     [self configTagViewWithTagArray:tagArray maxWidth:maxWidth];
 
-    [self configTypeView:songMessage.paymentType];
     [self.musicCover sd_setImageWithURL:[NSURL URLWithString:[songMessage.titleImg getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:@"music_logo"]];
 }
 
-
-
-- (void)configTypeView:(NSString *)musicType {
-    [self.typeView removeAllSubViews];
-    NSArray * chargeArray = [musicType componentsSeparatedByString:@","];
-    CGFloat singleWidth = 30.0f;
-    CGFloat space = 5.0f;
-    CGFloat height = 17.0f;
-    for (NSInteger index = 0; index < chargeArray.count; index++) {
-        NSString *desc = chargeArray[index];
-        NSString *title = nil;
-        UIColor *borderColor = nil;
-        UIColor *titleColor = nil;
-        if ([desc isEqualToString:@"VIP"]) {
-            borderColor = HexRGB(0xD38535);
-            title = @"会员";
-            titleColor = HexRGB(0xCD863E);
-            
-        }
-        else if ([desc isEqualToString:@"CHARGE"]) {
-            borderColor = HexRGB(0x50A2D8);
-            title = @"点播";
-            titleColor = HexRGB(0x3591CE);
-        }
-        else {
-            borderColor = HexRGB(0x01B84F);
-            title = @"免费";
-            titleColor = HexRGB(0x01B84F);
-        }
-        CGRect frame = CGRectMake((singleWidth + space) * index, 0, singleWidth, height);
-        MusicTagView *typeView = [[MusicTagView alloc] initWithTitle:title titleColor:titleColor borderColor:borderColor];
-        typeView.frame = frame;
-        [self.typeView addSubview:typeView];
-    }
-    self.typeViewWidth.constant = [self getWidthWithTypeCount:chargeArray.count singleWidth:singleWidth space:space];
-}
-
 - (CGFloat)getWidthWithTypeCount:(NSInteger)count singleWidth:(CGFloat)singleWidth space:(CGFloat)space {
     if (count == 1) {
         return singleWidth;

+ 7 - 19
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/MinePageMusicCell.xib

@@ -29,7 +29,7 @@
                                 </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="5wX-Qg-UK0">
-                                <rect key="frame" x="144" y="16" width="57.5" height="17"/>
+                                <rect key="frame" x="109" y="16" width="57.5" height="17"/>
                                 <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="14"/>
                                 <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
                                 <nil key="highlightedColor"/>
@@ -50,14 +50,6 @@
                                     <constraint firstAttribute="height" constant="16" id="gHY-Dt-fsS"/>
                                 </constraints>
                             </view>
-                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vUL-Jj-5Vt">
-                                <rect key="frame" x="70" y="16" width="30" height="17"/>
-                                <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                                <constraints>
-                                    <constraint firstAttribute="width" constant="30" id="8yi-He-ckM"/>
-                                    <constraint firstAttribute="height" constant="17" id="k4z-6g-o13"/>
-                                </constraints>
-                            </view>
                             <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="home_music_play" translatesAutoresizingMaskIntoConstraints="NO" id="qyC-cX-e8b">
                                 <rect key="frame" x="347" y="28" width="24" height="24"/>
                                 <constraints>
@@ -73,14 +65,14 @@
                                 </constraints>
                             </view>
                             <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="quality_tag" translatesAutoresizingMaskIntoConstraints="NO" id="V5J-Oe-JUu">
-                                <rect key="frame" x="105" y="16" width="14" height="17"/>
+                                <rect key="frame" x="70" y="16" width="14" height="17"/>
                                 <constraints>
                                     <constraint firstAttribute="height" constant="17" id="xdw-Ba-Xol"/>
                                     <constraint firstAttribute="width" constant="14" id="zIi-7h-39m"/>
                                 </constraints>
                             </imageView>
                             <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="music_albumTag" translatesAutoresizingMaskIntoConstraints="NO" id="bS2-6F-Dlf">
-                                <rect key="frame" x="124" y="17" width="15" height="15"/>
+                                <rect key="frame" x="89" y="17" width="15" height="15"/>
                                 <constraints>
                                     <constraint firstAttribute="width" constant="15" id="bzd-5z-FHf"/>
                                     <constraint firstAttribute="height" constant="15" id="inM-ti-NXZ"/>
@@ -89,8 +81,12 @@
                         </subviews>
                         <color key="backgroundColor" systemColor="systemBackgroundColor"/>
                         <constraints>
+                            <constraint firstItem="5wX-Qg-UK0" firstAttribute="centerY" secondItem="bS2-6F-Dlf" secondAttribute="centerY" id="0aR-CG-9DL"/>
+                            <constraint firstItem="V5J-Oe-JUu" firstAttribute="leading" secondItem="xBX-sV-7hK" secondAttribute="trailing" constant="11" id="2Kg-B5-VdV"/>
                             <constraint firstItem="bS2-6F-Dlf" firstAttribute="leading" secondItem="V5J-Oe-JUu" secondAttribute="trailing" constant="5" id="Ao9-gq-Sbk"/>
                             <constraint firstAttribute="bottom" secondItem="0z5-RP-2Hy" secondAttribute="bottom" id="EdW-Qt-gFP"/>
+                            <constraint firstItem="V5J-Oe-JUu" firstAttribute="top" secondItem="xBX-sV-7hK" secondAttribute="top" id="IGY-yN-8PM"/>
+                            <constraint firstItem="bS2-6F-Dlf" firstAttribute="centerY" secondItem="V5J-Oe-JUu" secondAttribute="centerY" id="LXc-IA-yRk"/>
                             <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="5wX-Qg-UK0" secondAttribute="trailing" constant="10" id="SV6-Ua-YmU"/>
                             <constraint firstItem="KNo-AM-8Um" firstAttribute="bottom" secondItem="xBX-sV-7hK" secondAttribute="bottom" id="WM8-AX-Frc"/>
                             <constraint firstItem="qyC-cX-e8b" firstAttribute="centerY" secondItem="eZd-kc-RgJ" secondAttribute="centerY" id="XHu-lk-zgJ"/>
@@ -99,16 +95,11 @@
                             <constraint firstItem="KNo-AM-8Um" firstAttribute="leading" secondItem="xBX-sV-7hK" secondAttribute="trailing" constant="11" id="c1W-4A-lpJ"/>
                             <constraint firstItem="5wX-Qg-UK0" firstAttribute="leading" secondItem="bS2-6F-Dlf" secondAttribute="trailing" constant="5" id="efM-ol-o41"/>
                             <constraint firstItem="xBX-sV-7hK" firstAttribute="leading" secondItem="eZd-kc-RgJ" secondAttribute="leading" constant="11" id="fgT-Ph-1JC"/>
-                            <constraint firstItem="vUL-Jj-5Vt" firstAttribute="top" secondItem="xBX-sV-7hK" secondAttribute="top" id="h4t-lc-arZ"/>
                             <constraint firstItem="qyC-cX-e8b" firstAttribute="leading" secondItem="qO5-Vi-5dQ" secondAttribute="trailing" constant="5" id="ipq-5V-J1w"/>
                             <constraint firstItem="qO5-Vi-5dQ" firstAttribute="leading" secondItem="KNo-AM-8Um" secondAttribute="trailing" constant="7" id="kc8-4f-j6V"/>
                             <constraint firstItem="xBX-sV-7hK" firstAttribute="centerY" secondItem="eZd-kc-RgJ" secondAttribute="centerY" id="mAT-vQ-rp9"/>
                             <constraint firstItem="qO5-Vi-5dQ" firstAttribute="centerY" secondItem="KNo-AM-8Um" secondAttribute="centerY" id="mUc-zy-UY8"/>
                             <constraint firstAttribute="trailing" secondItem="0z5-RP-2Hy" secondAttribute="trailing" constant="15" id="ndn-cE-AmF"/>
-                            <constraint firstItem="5wX-Qg-UK0" firstAttribute="centerY" secondItem="vUL-Jj-5Vt" secondAttribute="centerY" id="pXr-De-Tat"/>
-                            <constraint firstItem="V5J-Oe-JUu" firstAttribute="centerY" secondItem="vUL-Jj-5Vt" secondAttribute="centerY" id="ptT-II-Bnj"/>
-                            <constraint firstItem="V5J-Oe-JUu" firstAttribute="leading" secondItem="vUL-Jj-5Vt" secondAttribute="trailing" constant="5" id="rRi-zb-jyg"/>
-                            <constraint firstItem="vUL-Jj-5Vt" firstAttribute="leading" secondItem="xBX-sV-7hK" secondAttribute="trailing" constant="11" id="vcR-WX-hCx"/>
                             <constraint firstAttribute="trailing" secondItem="qyC-cX-e8b" secondAttribute="trailing" constant="14" id="z9c-xm-3Bm"/>
                         </constraints>
                     </view>
@@ -129,14 +120,11 @@
                 <outlet property="bgView" destination="eZd-kc-RgJ" id="DDC-wq-TIl"/>
                 <outlet property="lineView" destination="0z5-RP-2Hy" id="8tz-Y9-pUv"/>
                 <outlet property="musicCover" destination="xBX-sV-7hK" id="Xce-kE-ajH"/>
-                <outlet property="qualityLeft" destination="rRi-zb-jyg" id="yt8-Qa-rwM"/>
                 <outlet property="qualityMusicTag" destination="V5J-Oe-JUu" id="Sdf-ds-B2Y"/>
                 <outlet property="qualityTagWidth" destination="zIi-7h-39m" id="Rlc-20-guN"/>
                 <outlet property="songAuth" destination="KNo-AM-8Um" id="sE3-sB-pLo"/>
                 <outlet property="songName" destination="5wX-Qg-UK0" id="ibp-Xx-gL2"/>
                 <outlet property="tagView" destination="qO5-Vi-5dQ" id="Jau-UE-yYr"/>
-                <outlet property="typeView" destination="vUL-Jj-5Vt" id="Epk-ot-lUA"/>
-                <outlet property="typeViewWidth" destination="8yi-He-ckM" id="hDo-BG-yP9"/>
             </connections>
             <point key="canvasLocation" x="199.27536231884059" y="123.21428571428571"/>
         </tableViewCell>

+ 5 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Setting/Controller/ModifyNameViewController.m

@@ -126,8 +126,12 @@
     // 设置个人信息
     RCUserInfo *currentUserInfo =
     [[RCUserInfo alloc] initWithUserId:UserDefault(UIDKey) name:UserDefault(NicknameKey) portrait:UserDefault(AvatarUrlKey)];
+    // 附加字段
+    NSMutableDictionary *extraDic = [NSMutableDictionary dictionary];
+    [extraDic setValue:@"TEACHER" forKey:@"role"];
+    currentUserInfo.extra = [extraDic mj_JSONString];
     [RCIM sharedRCIM].currentUserInfo = currentUserInfo;
-    [[RCIM sharedRCIM] clearGroupUserInfoCache];
+    [[RCIM sharedRCIM] refreshUserInfoCache:currentUserInfo withUserId:UserDefault(UIDKey)];
 }
 
 /*

+ 4 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Setting/Controller/UserSettingViewController.m

@@ -220,8 +220,11 @@
     // 设置个人信息
     RCUserInfo *currentUserInfo =
     [[RCUserInfo alloc] initWithUserId:UserDefault(UIDKey) name:UserDefault(NicknameKey) portrait:UserDefault(AvatarUrlKey)];
+    NSMutableDictionary *extraDic = [NSMutableDictionary dictionary];
+    [extraDic setValue:@"TEACHER" forKey:@"role"];
+    currentUserInfo.extra = [extraDic mj_JSONString];
     [RCIM sharedRCIM].currentUserInfo = currentUserInfo;
-    [[RCIM sharedRCIM] clearGroupUserInfoCache];
+    [[RCIM sharedRCIM] refreshUserInfoCache:currentUserInfo withUserId:UserDefault(UIDKey)];
 }
 
 - (void)showModifySexAlert {