memberClassList.vue 19 KB

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