2
0

CourseMemberController.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Http\Api\UserApi;
  4. use App\Http\Resources\CourseMemberResource;
  5. use App\Models\Course;
  6. use App\Models\CourseMember;
  7. use App\Models\UserInfo;
  8. use App\Services\AuthService;
  9. use Illuminate\Http\Request;
  10. use Illuminate\Http\Response;
  11. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  12. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  13. class CourseMemberController extends Controller
  14. {
  15. /**
  16. * Display a listing of the resource.
  17. *
  18. * @return Response
  19. */
  20. public function index(Request $request)
  21. {
  22. //
  23. $user = AuthService::current($request);
  24. if (! $user) {
  25. return $this->error(__('auth.failed', [403], 403));
  26. }
  27. // 判断当前用户是否有指定的 course 的权限
  28. $role = CourseMember::where('course_id', $request->input('id', $request->input('course')))
  29. ->where('user_id', $user['user_uid'])
  30. ->value('role');
  31. if (empty($role)) {
  32. return $this->error(__('auth.failed', [403], 403));
  33. }
  34. $result = false;
  35. $indexCol = [
  36. 'id',
  37. 'user_id',
  38. 'course_id',
  39. 'channel_id',
  40. 'role',
  41. 'editor_uid',
  42. 'updated_at',
  43. 'created_at',
  44. ];
  45. switch ($request->input('view')) {
  46. case 'course':
  47. // 获取 course 内所有 成员
  48. $table = CourseMember::where('course_id', $request->input('id'))
  49. ->where('is_current', true);
  50. break;
  51. case 'timeline':
  52. /**
  53. * 编辑时间线
  54. */
  55. $table = CourseMember::where('user_id', $request->input('userId'));
  56. if ($request->input('timeline', 'current') === 'current') {
  57. $table = $table->where('course_id', $request->input('course'));
  58. }
  59. break;
  60. default:
  61. return $this->error('无法识别的参数view', 400, 400);
  62. break;
  63. }
  64. if (! empty($request->input('role')) && $request->input('role') !== 'all') {
  65. $table = $table->where('role', $request->input('role'));
  66. }
  67. if (! empty($request->input('status'))) {
  68. $table = $table->whereIn('status', explode(',', $request->input('status')));
  69. }
  70. if (! empty($request->input('search'))) {
  71. $usersId = UserInfo::where('nickname', 'like', '%'.$request->input('search').'%')
  72. ->select('userid')
  73. ->get();
  74. $table = $table->whereIn('user_id', $usersId);
  75. }
  76. $count = $table->count();
  77. $table = $table->orderBy(
  78. $request->input('order', 'created_at'),
  79. $request->input('dir', 'asc')
  80. );
  81. $table = $table->skip($request->input('offset', 0))
  82. ->take($request->input('limit', 1000));
  83. $result = $table->get();
  84. // 获取当前用户角色
  85. $role = CourseMember::where('course_id', $request->input('id'))
  86. ->where('user_id', $user['user_uid'])
  87. ->where('is_current', true)
  88. ->value('role');
  89. return $this->ok(['rows' => CourseMemberResource::collection($result), 'role' => $role, 'count' => $count]);
  90. }
  91. /**
  92. * Store a newly created resource in storage.
  93. *
  94. * @return Response
  95. */
  96. public function store(Request $request)
  97. {
  98. //
  99. $user = AuthService::current($request);
  100. if (! $user) {
  101. return $this->error(__('auth.failed', [403], 403));
  102. }
  103. $validated = $request->validate([
  104. 'user_id' => 'required',
  105. 'course_id' => 'required',
  106. 'role' => 'required',
  107. 'status' => 'required',
  108. ]);
  109. // 查找重复的
  110. if ($validated['status'] !== 'invited') {
  111. if (CourseMember::where('course_id', $validated['course_id'])
  112. ->where('user_id', $validated['user_id'])
  113. ->exists()
  114. ) {
  115. return $this->error('member exists', [200], 200);
  116. }
  117. }
  118. if ($validated['status'] === 'invited') {
  119. $userId = $validated['user_id'];
  120. } else {
  121. $userId = $user['user_uid'];
  122. }
  123. CourseMember::where('course_id', $validated['course_id'])
  124. ->where('user_id', $userId)
  125. ->update(['is_current' => false]);
  126. $newMember = new CourseMember;
  127. $newMember->course_id = $validated['course_id'];
  128. $newMember->role = $validated['role'];
  129. $newMember->editor_uid = $user['user_uid'];
  130. $newMember->status = $validated['status'];
  131. $newMember->user_id = $userId;
  132. /**
  133. * 查找course 信息,根据加入方式设置状态
  134. * open : accepted
  135. * manual: progressing
  136. */
  137. $course = Course::find($validated['course_id']);
  138. if (! $course) {
  139. return $this->error('invalid course');
  140. }
  141. switch ($course->join) {
  142. case 'open': // 开放学习课程
  143. if (
  144. $validated['status'] !== 'joined' &&
  145. $validated['status'] !== 'invited'
  146. ) {
  147. return $this->error('invalid course', [200], 200);
  148. }
  149. break;
  150. case 'manual': // 人工审核课程
  151. if (
  152. $validated['status'] !== 'applied' &&
  153. $validated['status'] !== 'invited'
  154. ) {
  155. return $this->error('invalid course', [200], 200);
  156. }
  157. break;
  158. }
  159. $newMember->save();
  160. return $this->ok(new CourseMemberResource($newMember));
  161. }
  162. /**
  163. * Display the specified resource.
  164. *
  165. * @return Response
  166. */
  167. public function show(Request $request, string $courseId)
  168. {
  169. //
  170. $user = AuthService::current($request);
  171. if (! $user) {
  172. return $this->error(__('auth.failed'));
  173. }
  174. $userId = $user['user_uid'];
  175. if (! empty($request->input('user_uid'))) {
  176. $userId = $request->input('user_uid');
  177. }
  178. $member = CourseMember::where('course_id', $courseId)
  179. ->where('user_id', $userId)
  180. ->where('is_current', true)
  181. ->first();
  182. if ($member) {
  183. return $this->ok(new CourseMemberResource($member));
  184. } else {
  185. return $this->error('no result', 200, 200);
  186. }
  187. }
  188. /**
  189. * Update the specified resource in storage.
  190. *
  191. * @return Response
  192. */
  193. public function update(Request $request, CourseMember $courseMember)
  194. {
  195. /**
  196. * 保留原有记录
  197. * 增加一条新纪录
  198. * 原有记录变为历史记录
  199. */
  200. $user = AuthService::current($request);
  201. if (! $user) {
  202. return $this->error(__('auth.failed'));
  203. }
  204. $newMember = new CourseMember;
  205. $newMember->user_id = $courseMember->user_id;
  206. $newMember->course_id = $courseMember->course_id;
  207. $newMember->role = $courseMember->role;
  208. $newMember->status = $courseMember->status;
  209. $newMember->channel_id = $courseMember->channel_id;
  210. $newMember->editor_uid = $user['user_uid'];
  211. $courseMember->is_current = false;
  212. $courseMember->save();
  213. if ($request->has('channel_id')) {
  214. if ($newMember->user_id !== $user['user_uid']) {
  215. return $this->error(__('auth.failed'));
  216. }
  217. $newMember->channel_id = $request->input('channel_id');
  218. }
  219. if ($request->has('status')) {
  220. $newMember->status = $request->input('status');
  221. }
  222. $newMember->save();
  223. return $this->ok(new CourseMemberResource($newMember));
  224. }
  225. public function set_channel(Request $request)
  226. {
  227. //
  228. $user = AuthService::current($request);
  229. if (! $user) {
  230. return $this->error(__('auth.failed'));
  231. }
  232. if ($request->has('channel_id')) {
  233. $courseMember = CourseMember::where('course_id', $request->input('course_id'))
  234. ->where('user_id', $user['user_uid'])
  235. ->where('is_current', true)
  236. ->first();
  237. if ($courseMember) {
  238. $courseMember->channel_id = $request->input('channel_id');
  239. $courseMember->save();
  240. return $this->ok(new CourseMemberResource($courseMember));
  241. } else {
  242. return $this->error(__('auth.failed'));
  243. }
  244. } else {
  245. return $this->error(__('auth.failed'));
  246. }
  247. }
  248. /**
  249. * Remove the specified resource from storage.
  250. *
  251. * @return Response
  252. */
  253. public function destroy(Request $request, CourseMember $courseMember)
  254. {
  255. // 查看删除者有没有删除权限
  256. // 查询删除者的权限
  257. $user = AuthService::current($request);
  258. if (! $user) {
  259. return $this->error(__('auth.failed'));
  260. }
  261. $isOwner = Course::where('id', $courseMember->course_id)->where('studio_id', $user['user_uid'])->exists();
  262. if (! $isOwner) {
  263. $courseUser = CourseMember::where('course_id', $courseMember->course_id)
  264. ->where('user_id', $user['user_uid'])
  265. ->select('role')->first();
  266. // open 课程 可以删除自己
  267. if (! $courseUser) {
  268. // 被删除的不是自己
  269. if ($courseUser->role === 'student') {
  270. // 普通成员没有删除权限
  271. return $this->error(__('auth.failed'));
  272. }
  273. }
  274. }
  275. $delete = $courseMember->delete();
  276. return $this->ok($delete);
  277. }
  278. /**
  279. * 获取当前用户权限
  280. *
  281. * @return Response
  282. */
  283. public function curr(Request $request)
  284. {
  285. $user = AuthService::current($request);
  286. if (! $user) {
  287. return $this->error(__('auth.failed'));
  288. }
  289. $courseUser = CourseMember::where('course_id', $request->input('course_id'))
  290. ->where('user_id', $user['user_uid'])
  291. ->where('is_current', true)
  292. ->select(['role', 'channel_id'])->first();
  293. if ($courseUser) {
  294. return $this->ok($courseUser);
  295. } else {
  296. return $this->error('not member');
  297. }
  298. }
  299. public function export(Request $request)
  300. {
  301. $courseUser = CourseMember::where('course_id', $request->input('course_id'))
  302. ->where('is_current', true)
  303. ->get();
  304. $spreadsheet = new Spreadsheet;
  305. $activeWorksheet = $spreadsheet->getActiveSheet();
  306. $activeWorksheet->setCellValue('A1', 'nickname');
  307. $activeWorksheet->setCellValue('B1', 'username');
  308. $activeWorksheet->setCellValue('C1', 'role');
  309. $activeWorksheet->setCellValue('D1', 'status');
  310. $activeWorksheet->setCellValue('E1', 'created_at');
  311. $currLine = 2;
  312. foreach ($courseUser as $key => $row) {
  313. $user = UserApi::getByUuid($row->user_id);
  314. $activeWorksheet->setCellValue("A{$currLine}", $user['nickName']);
  315. $activeWorksheet->setCellValue("B{$currLine}", $user['userName']);
  316. $activeWorksheet->setCellValue("C{$currLine}", $row->role);
  317. $activeWorksheet->setCellValue("D{$currLine}", $row->status);
  318. $activeWorksheet->setCellValue("E{$currLine}", $row->created_at);
  319. $currLine++;
  320. }
  321. $writer = new Xlsx($spreadsheet);
  322. header('Content-Type: application/vnd.ms-excel');
  323. header('Content-Disposition: attachment; filename="course_member.xlsx"');
  324. $writer->save('php://output');
  325. }
  326. }