memberClassList.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. <template>
  2. <div class="m-container">
  3. <div class="line"></div>
  4. <h2>
  5. <el-page-header @back="goBack" :content="$route.query.name">
  6. </el-page-header>
  7. </h2>
  8. <div class="topWrap">
  9. <el-form :inline="true" :model="topForm">
  10. <el-form-item label="班级类型">
  11. <el-select
  12. v-model.trim="topForm.classType"
  13. clearable
  14. filterable
  15. @change="changeMixClass"
  16. >
  17. <el-option
  18. v-for="(item, index) in musicClassTypeList"
  19. :key="index"
  20. :label="item.label"
  21. :value="item.value"
  22. ></el-option>
  23. </el-select>
  24. </el-form-item>
  25. </el-form>
  26. </div>
  27. <div class="btnList">
  28. <el-form :inline="true">
  29. <el-form-item label="开课日期:">
  30. <p>{{ form.startCourseDate }}</p>
  31. </el-form-item>
  32. <el-form-item>
  33. <auth auths="musicGroupSchoolTermCourseDetail/upset/4444">
  34. <el-button type="primary" @click="resetStartTime">修改</el-button>
  35. </auth>
  36. </el-form-item>
  37. <el-form-item v-if="form.endSchoolTerm">
  38. <p style="color: red">该学期结束日期为:{{ form.endSchoolTerm }}</p>
  39. </el-form-item>
  40. </el-form>
  41. </div>
  42. <div class="tableWrap" style>
  43. <el-table
  44. :data="activeSingleList"
  45. @expand-change="changeDetail"
  46. style
  47. ref="multipleTable"
  48. row-key="id"
  49. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  50. tooltip-effect="dark"
  51. :row-class-name="getClassName"
  52. ><el-table-column type="expand">
  53. <template slot-scope="props">
  54. <el-table
  55. :data="props.row.courseData"
  56. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  57. >
  58. <el-table-column align="center" prop="name" label="课程类型">
  59. <template slot-scope="scope">
  60. <div>{{ scope.row.type | courseTypeFormat }}</div>
  61. </template>
  62. </el-table-column>
  63. <el-table-column align="center" prop="name" label="课程名称">
  64. <template slot-scope="scope">
  65. <div>{{ scope.row.name }}</div>
  66. </template>
  67. </el-table-column>
  68. <el-table-column
  69. align="center"
  70. prop="name"
  71. label="预开始时间"
  72. width="200px"
  73. >
  74. <template slot-scope="scope"
  75. >{{
  76. scope.row.startClassTime
  77. ? scope.row.startClassTime.substr(0, 16)
  78. : ""
  79. }}-{{
  80. scope.row.endClassTime
  81. ? scope.row.endClassTime.substr(11, 5)
  82. : ""
  83. }}</template
  84. >
  85. </el-table-column>
  86. <el-table-column
  87. align="center"
  88. prop="name"
  89. label="课程时长(分钟)"
  90. >
  91. <template slot-scope="scope">
  92. <div>
  93. {{ getCourseTime(scope.row) }}
  94. </div>
  95. </template>
  96. </el-table-column>
  97. <el-table-column
  98. align="center"
  99. prop="actualTeacherName"
  100. label="主教老师"
  101. ></el-table-column>
  102. <el-table-column
  103. align="center"
  104. prop="teachingTeacherNames"
  105. label="助教老师"
  106. ></el-table-column>
  107. </el-table>
  108. </template>
  109. </el-table-column>
  110. <el-table-column
  111. align="center"
  112. prop="name"
  113. label="班级名称"
  114. ></el-table-column>
  115. <el-table-column align="center" prop="type" label="班级类型">
  116. <template slot-scope="scope">
  117. <div>{{ scope.row.type | classType }}</div>
  118. </template>
  119. </el-table-column>
  120. <el-table-column align="center" prop="studentNum" label="当前班级人数">
  121. <template slot-scope="scope">
  122. <div>{{ scope.row.studentNum }}人</div>
  123. </template>
  124. </el-table-column>
  125. <el-table-column align="center" prop label="主教老师">
  126. <template slot-scope="scope">
  127. <div v-if="scope.row.classGroupTeacherMapperList">
  128. <p
  129. v-for="(item, index) in scope.row.classGroupTeacherMapperList"
  130. :key="index"
  131. >
  132. <span v-if="item.teacherRole == 'BISHOP'">
  133. {{ item.userName }}
  134. </span>
  135. </p>
  136. </div>
  137. </template>
  138. </el-table-column>
  139. <el-table-column align="center" label="助教老师">
  140. <template slot-scope="scope">
  141. <div v-if="scope.row.classGroupTeacherMapperList">
  142. <p
  143. v-for="(item, index) in scope.row.classGroupTeacherMapperList"
  144. :key="index"
  145. >
  146. <span v-if="item.teacherRole == 'TEACHING'">
  147. {{ item.userName }}
  148. </span>
  149. </p>
  150. </div>
  151. </template>
  152. </el-table-column>
  153. <el-table-column align="center" label="已预排课次(节)">
  154. <template slot-scope="scope">
  155. <div>{{ scope.row.preTotalClassTimes }}</div>
  156. </template>
  157. </el-table-column>
  158. <el-table-column align="center" label="已预排课时长(分钟)">
  159. <template slot-scope="scope">
  160. <div>{{ scope.row.preMinutes }}</div>
  161. </template>
  162. </el-table-column>
  163. <el-table-column align="center" label="剩余可排课时长(分钟)">
  164. <template slot-scope="scope">
  165. <div>{{ scope.row.preSubMinutes }}</div>
  166. </template>
  167. </el-table-column>
  168. <el-table-column
  169. align="center"
  170. width="240px"
  171. label="操作"
  172. v-if="team_status == 'PREPARE' || team_status == 'PROGRESS'"
  173. >
  174. <template slot-scope="scope" v-if="scope.row.lockFlag != 1">
  175. <div>
  176. <el-button
  177. type="text"
  178. v-if="scope.row.preTotalClassTimes == 0"
  179. @click="planCourse(scope.row)"
  180. >预排课</el-button
  181. >
  182. <el-button type="text" v-else @click="cancleCourse(scope.row)"
  183. >取消排课</el-button
  184. >
  185. </div>
  186. </template>
  187. </el-table-column>
  188. </el-table>
  189. <div class="lastBtnWrap">
  190. <el-button type="primary" @click="submitCourse">确认排课</el-button>
  191. </div>
  192. </div>
  193. <el-dialog
  194. title="请设置开课日期"
  195. :visible.sync="startVisible"
  196. width="500px"
  197. >
  198. <el-form :model="form" ref="form">
  199. <el-form-item
  200. label="开课日期"
  201. prop="startCourseDate"
  202. :rules="[{ required: true, message: '请选择开课日期' }]"
  203. >
  204. <el-date-picker
  205. v-model.trim="form.startCourseDate"
  206. type="date"
  207. :picker-options="pickerOptions"
  208. value-format="yyyy-MM-dd"
  209. placeholder="请选择时间"
  210. />
  211. </el-form-item>
  212. </el-form>
  213. <div slot="footer" class="dialog-footer">
  214. <el-button type="primary" @click="setStartTime">确 定</el-button>
  215. </div>
  216. </el-dialog>
  217. <!-- /**
  218. :classType="classType" // 调整类型
  219. :teacherList="teacherList"
  220. :cooperationList="cooperationList" // 助教列表
  221. :musicGroupId="teamid"
  222. :activeType="activeType" // 班级类型
  223. :courseTypeList="courseTypeList" // 班级可排课类型
  224. :detail="infoDetail" // activeRow
  225. :studentSubmitedData="studentSubmitedData" 班级的学生信息
  226. @close="infoVisible = false" // 显示隐藏
  227. @submited="getList" 刷新列表 */ -->
  228. <el-dialog
  229. title="班级排课"
  230. width="1200px"
  231. :modal-append-to-body="false"
  232. :visible.sync="courseVisible"
  233. >
  234. <memberClassSetting
  235. v-if="courseVisible"
  236. :musicGroupSchoolTermCourseDetailId="musicGroupSchoolTermCourseDetailId"
  237. :teacherList="teacherList"
  238. :cooperationList="cooperationList"
  239. :courseTypeList="courseTypeList"
  240. :musicGroupId="teamid"
  241. :activeType="activeType"
  242. :detail="classDteail"
  243. :startCourseDate="form.startCourseDate"
  244. :endSchoolTerm="form.endSchoolTerm"
  245. @close="courseVisible = false"
  246. @submited="getList"
  247. />
  248. </el-dialog>
  249. </div>
  250. </template>
  251. <script>
  252. import {
  253. getAllSignClassandTeacher,
  254. getTeamBaseInfo,
  255. musicGroupSchoolTermCourseDetail,
  256. getTeacher,
  257. cancelPreCourseSchedule,
  258. getPreCourseList,
  259. confirmPreCourseSchedule,
  260. } from "@/api/buildTeam";
  261. import { classTimeList, musicClassTypeList } from "@/utils/searchArray";
  262. import memberClassSetting from "./modals/member-class-setting.vue";
  263. import { getCourseType } from "@/utils/utils";
  264. import { diffTimerFormMinute } from "@/utils/date";
  265. import dayjs from "dayjs";
  266. export default {
  267. components: { memberClassSetting },
  268. data() {
  269. return {
  270. musicClassTypeList,
  271. topForm: {
  272. classType: "",
  273. },
  274. team_status: "",
  275. activeSingleList: [],
  276. form: { startCourseDate: "", endSchoolTerm: "" },
  277. startVisible: false,
  278. pickerOptions: {
  279. firstDayOfWeek: 1,
  280. disabledDate(time) {
  281. return time.getTime() + 86400000 <= new Date().getTime(); //开始时间不选时,结束时间最大值小于等于当天
  282. },
  283. },
  284. lastDate: "",
  285. musicGroupSchoolTermCourseDetailId: "",
  286. courseVisible: false,
  287. teacherList: [],
  288. courseTypeList: [],
  289. cooperationList: [],
  290. activeType: "",
  291. teamid: "",
  292. classDteail: null,
  293. };
  294. },
  295. mounted() {
  296. this.init();
  297. this.$route.meta.nogo = true;
  298. // console.log()
  299. },
  300. methods: {
  301. async init() {
  302. this.teamid = this.$route.query.id;
  303. this.team_status = this.$route.query.team_status;
  304. if (this.musicGroupInfo) {
  305. this.organId = this.musicGroupInfos.organId;
  306. this.chargeTypeId = this.musicGroupInfos.chargeTypeId;
  307. this.courseViewType = this.musicGroupInfos.courseViewType;
  308. } else {
  309. getTeamBaseInfo({ musicGroupId: this.teamid }).then((res) => {
  310. if (res.code == 200) {
  311. this.musicGroupInfos = res.data.musicGroup;
  312. this.organId = this.musicGroupInfos.organId;
  313. this.chargeTypeId = this.musicGroupInfos.chargeTypeId;
  314. this.courseViewType = this.musicGroupInfos.courseViewType;
  315. }
  316. });
  317. }
  318. // 请求接口 获取乐团排课时长
  319. try {
  320. const res = await musicGroupSchoolTermCourseDetail({
  321. musicGroupId: this.teamid,
  322. });
  323. if (!res.data) {
  324. // 说明没有设置时间 弹窗设置
  325. this.startVisible = true;
  326. } else {
  327. this.form.startCourseDate = dayjs(res.data.startCourseDate).format(
  328. "YYYY-MM-DD"
  329. );
  330. this.form.endSchoolTerm = dayjs(res.data.endSchoolTerm).format(
  331. "YYYY-MM-DD"
  332. );
  333. this.musicGroupSchoolTermCourseDetailId = res.data.id;
  334. }
  335. } catch (e) {
  336. console.log(e);
  337. }
  338. // 获取主教老师和助教老师
  339. getTeacher({ organId: this.organId }).then((res) => {
  340. if (res.code == 200) {
  341. this.cooperationList = res.data;
  342. this.teacherList = res.data;
  343. }
  344. });
  345. await this.getList();
  346. },
  347. changeMixClass(val) {
  348. // 根据合奏班id获取合奏班下的所有声部班
  349. console.log(val);
  350. this.getList(val);
  351. this.activeMixClass = val;
  352. },
  353. getList(val) {
  354. return getAllSignClassandTeacher({
  355. musicGroupId: this.teamid,
  356. type: val,
  357. }).then((res) => {
  358. if (res.code == 200) {
  359. this.activeSingleList = [];
  360. res.data.map((item) => {
  361. if (
  362. item.type != "HIGH" &&
  363. item.type != "DEMO" &&
  364. item.type != "HIGH_ONLINE" &&
  365. item.type != "MUSIC_NETWORK"&&
  366. item.type != "SNAP"
  367. ) {
  368. this.activeSingleList.push(item);
  369. }
  370. });
  371. // this.topForm.count = this.activeSingleList.length
  372. }
  373. });
  374. },
  375. goBack() {
  376. this.$router.push({
  377. path: "/business/resetTeaming",
  378. query: { ...this.$route.query },
  379. });
  380. },
  381. setStartTime() {
  382. this.$refs.form.validate(async (res) => {
  383. if (res) {
  384. try {
  385. const res = await musicGroupSchoolTermCourseDetail({
  386. musicGroupId: this.teamid,
  387. startCourseDate: this.form.startCourseDate,
  388. });
  389. if (res.code == 207) {
  390. this.$confirm(res.msg, "提示", {
  391. confirmButtonText: "确定",
  392. cancelButtonText: "取消",
  393. type: "warning",
  394. })
  395. .then(async () => {
  396. try {
  397. const res = await musicGroupSchoolTermCourseDetail({
  398. musicGroupId: this.teamid,
  399. startCourseDate: this.form.startCourseDate,
  400. cleanPreCourseFlag: true,
  401. });
  402. if (res.data) {
  403. this.$message.success("修改成功");
  404. this.form.startCourseDate = dayjs(
  405. res.data.startCourseDate
  406. ).format("YYYY-MM-DD");
  407. this.form.endSchoolTerm = dayjs(
  408. res.data.endSchoolTerm
  409. ).format("YYYY-MM-DD");
  410. this.musicGroupSchoolTermCourseDetailId = res.data.id;
  411. this.startVisible = false;
  412. this.getList();
  413. }
  414. } catch (e) {
  415. this.form.startCourseDate = this.lastDate;
  416. }
  417. })
  418. .catch(() => {
  419. this.form.startCourseDate = this.lastDate;
  420. });
  421. }
  422. console.log(res);
  423. if (res.code == 200) {
  424. if (res.data) {
  425. this.form.startCourseDate = dayjs(
  426. res.data.startCourseDate
  427. ).format("YYYY-MM-DD");
  428. this.form.endSchoolTerm = dayjs(res.data.endSchoolTerm).format(
  429. "YYYY-MM-DD"
  430. );
  431. this.musicGroupSchoolTermCourseDetailId = res.data.id;
  432. this.$message.success("修改成功");
  433. this.startVisible = false;
  434. this.getList();
  435. }
  436. }
  437. } catch (e) {
  438. this.form.startCourseDate = this.lastDate;
  439. console.log(e);
  440. }
  441. }
  442. });
  443. },
  444. resetStartTime() {
  445. this.lastDate = JSON.parse(JSON.stringify(this.form.startCourseDate));
  446. this.startVisible = true;
  447. },
  448. planCourse(row) {
  449. this.classDteail = row;
  450. this.activeType = row.type;
  451. this.setType(row.type);
  452. this.courseVisible = true;
  453. },
  454. setType(type) {
  455. this.courseTypeList = getCourseType(type);
  456. },
  457. cancleCourse(row) {
  458. this.$confirm("是否取消预排课", "提示", {
  459. confirmButtonText: "确定",
  460. cancelButtonText: "取消",
  461. type: "warning",
  462. })
  463. .then(async () => {
  464. try {
  465. const res = await cancelPreCourseSchedule({
  466. classGroupId: row.id,
  467. musicGroupSchoolTermCourseDetailId:
  468. this.musicGroupSchoolTermCourseDetailId,
  469. });
  470. this.$message.success("取消成功");
  471. this.$refs.multipleTable.toggleRowExpansion(row,false)
  472. this.getList();
  473. } catch (e) {}
  474. // musicGroupSchoolTermCourseDetailId
  475. })
  476. .catch(() => {});
  477. },
  478. async changeDetail(row, expandedRows) {
  479. if (expandedRows.length > 0) {
  480. // 展开 请求接口
  481. try {
  482. const res = await getPreCourseList({ classGroupId: row.id });
  483. this.activeSingleList.forEach((item, index) => {
  484. if (item.id == row.id) {
  485. // this.activeSingleList[index].courseData = res.data;
  486. this.$set(this.activeSingleList[index], "courseData", res.data);
  487. }
  488. });
  489. } catch (e) {
  490. console.log(e);
  491. }
  492. }
  493. },
  494. submitCourse() {
  495. // confirmPreCourseSchedule
  496. this.$confirm("确定提交预排课列表", "提示", {
  497. confirmButtonText: "确定",
  498. cancelButtonText: "取消",
  499. type: "warning",
  500. })
  501. .then(async () => {
  502. try {
  503. const res = await confirmPreCourseSchedule({
  504. musicGroupSchoolTermCourseDetailId:
  505. this.musicGroupSchoolTermCourseDetailId,
  506. });
  507. this.$message.success("提交成功");
  508. await this.getList();
  509. this.goBack();
  510. } catch (e) {}
  511. //
  512. })
  513. .catch(() => {});
  514. },
  515. getCourseTime(row) {
  516. return diffTimerFormMinute(
  517. dayjs(row.classDate).format("YYYY-MM-DD"),
  518. dayjs(row.startClassTime).format("HH:mm"),
  519. dayjs(row.endClassTime).format("HH:mm")
  520. );
  521. },
  522. getClassName({ row, index }) {
  523. return row.preTotalClassTimes ? "" : "noShow";
  524. },
  525. },
  526. async beforeRouteLeave(to, from, next) {
  527. let flag = false;
  528. // if (this.activeSingleList.length > 0) {
  529. // }
  530. this.activeSingleList.forEach((item) => {
  531. if (item.preTotalClassTimes != 0) {
  532. flag = true;
  533. }
  534. });
  535. if (flag) {
  536. this.$confirm("预排课程尚未提交,是否确认跳转其他页面?", "提示", {
  537. confirmButtonText: "确定",
  538. cancelButtonText: "取消",
  539. type: "warning",
  540. })
  541. .then(async () => {
  542. this.$store.dispatch("delVisitedViews", this.$route);
  543. next();
  544. // musicGroupSchoolTermCourseDetailId
  545. })
  546. .catch(() => {});
  547. } else {
  548. this.$store.dispatch("delVisitedViews", this.$route);
  549. next();
  550. }
  551. },
  552. };
  553. </script>
  554. <style lang="scss" scoped>
  555. .lastBtnWrap {
  556. margin-top: 20px;
  557. display: flex;
  558. flex-direction: row;
  559. align-items: center;
  560. justify-content: flex-end;
  561. margin-right: 1%;
  562. }
  563. /deep/ .el-table .noShow .cell .el-table__expand-icon {
  564. display: none;
  565. }
  566. // /deep/.el-table__row.noShow {
  567. // /deep/.el-table__expand-column {
  568. // visibility:hidden;
  569. // }
  570. // }
  571. </style>