teamClassList.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. <!-- -->
  2. <template>
  3. <div class="m-container">
  4. <h2>
  5. <div class="squrt"></div>
  6. 班级管理
  7. <filter-search
  8. v-if="permission('/teamCLassList/abnormal')"
  9. :keys="['lessThenThreeHighOnline']"
  10. @reload="reloadSearch"
  11. :moreKeys="['organId']"
  12. />
  13. </h2>
  14. <div class="m-core">
  15. <save-form
  16. ref="searchForm"
  17. :inline="true"
  18. :model="searchForm"
  19. @submit="search"
  20. @reset="onReSet"
  21. >
  22. <el-form-item prop="search">
  23. <el-input
  24. v-model.trim="searchForm.search"
  25. clearable
  26. @keyup.enter.native="
  27. (e) => {
  28. e.target.blur();
  29. $refs.searchForm.save();
  30. search();
  31. }
  32. "
  33. placeholder="乐团&班级编号名称"
  34. ></el-input>
  35. </el-form-item>
  36. <el-form-item prop="organIdList">
  37. <select-all
  38. class="multiple"
  39. filterable
  40. multiple
  41. v-model.trim="searchForm.organIdList"
  42. clearable
  43. placeholder="请选择分部"
  44. >
  45. <el-option
  46. v-for="(item, index) in selects.branchs"
  47. :key="index"
  48. :label="item.name"
  49. :value="item.id"
  50. ></el-option>
  51. </select-all>
  52. </el-form-item>
  53. <el-form-item>
  54. <el-select
  55. v-model.trim="searchForm.groupType"
  56. @change="
  57. () => {
  58. searchForm.type = '';
  59. }
  60. "
  61. filterable
  62. placeholder="课程组类型"
  63. >
  64. <el-option
  65. v-for="(item, index) in courseListType"
  66. :key="index"
  67. :value="item.value"
  68. :label="item.label"
  69. ></el-option>
  70. </el-select>
  71. </el-form-item>
  72. <!-- musicClassTypeList -->
  73. <el-form-item prop="type">
  74. <el-select
  75. v-model.trim="searchForm.type"
  76. filterable
  77. clearable
  78. :disabled="searchForm.groupType != 'MUSIC'"
  79. placeholder="班级类型"
  80. >
  81. <el-option
  82. v-for="(item, index) in musicClassTypeList"
  83. :key="index"
  84. :label="item.label"
  85. :value="item.value"
  86. ></el-option>
  87. </el-select>
  88. </el-form-item>
  89. <el-form-item prop="mainTeacherUserId">
  90. <remote-search
  91. :commit="'setTeachers'"
  92. v-model="searchForm.mainTeacherUserId"
  93. :demissionFlag="true"
  94. :isForzenWithQueryCondition="true"
  95. />
  96. </el-form-item>
  97. <el-form-item>
  98. <el-button native-type="submit" type="primary">搜索</el-button>
  99. <el-button native-type="reset" type="danger">重置</el-button>
  100. <el-button
  101. type="primary"
  102. v-permission="'export/classGroup'"
  103. @click="exportClassGroup"
  104. >导出</el-button
  105. >
  106. </el-form-item>
  107. </save-form>
  108. <div class="tableWrap">
  109. <el-table
  110. style="width: 100%"
  111. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  112. :data="tableList"
  113. >
  114. <el-table-column
  115. align="center"
  116. prop="musicGroupId"
  117. label="课程组编号"
  118. >
  119. <template slot-scope="scope">
  120. <copy-text>{{ scope.row.musicGroupId }}</copy-text>
  121. </template>
  122. </el-table-column>
  123. <!-- <el-table-column align="center" prop="musicGroupId" label="课程编号">
  124. <template slot-scope="scope">
  125. <copy-text>{{ scope.row.id }}</copy-text>
  126. </template>
  127. </el-table-column> -->
  128. <el-table-column
  129. align="center"
  130. prop="musicGroupName"
  131. label="课程组名称"
  132. ></el-table-column>
  133. <el-table-column align="center" prop="organName" label="分部名称">
  134. <template slot-scope="scope">
  135. <copy-text>{{ scope.row.organName }}</copy-text>
  136. </template>
  137. </el-table-column>
  138. <el-table-column
  139. align="center"
  140. prop="name"
  141. label="班级名称"
  142. ></el-table-column>
  143. <el-table-column align="center" prop="type" label="班级类型">
  144. <template slot-scope="scope">
  145. <div>{{ scope.row.type | classType }}</div>
  146. </template>
  147. </el-table-column>
  148. <el-table-column
  149. align="center"
  150. prop="studentNum"
  151. label="当前班级人数"
  152. >
  153. <template slot-scope="scope">
  154. <div>{{ scope.row.studentNum }}人</div>
  155. </template>
  156. </el-table-column>
  157. <el-table-column align="center" prop label="主教老师">
  158. <template slot-scope="scope">
  159. <div v-if="scope.row.classGroupTeacherMapperList">
  160. <p
  161. v-for="(item, index) in scope.row.classGroupTeacherMapperList"
  162. v-if="item.teacherRole == 'BISHOP'"
  163. :key="index"
  164. >
  165. {{ item.userName }}
  166. </p>
  167. </div>
  168. </template>
  169. </el-table-column>
  170. <el-table-column align="center" label="助教老师">
  171. <template slot-scope="scope">
  172. <div v-if="scope.row.classGroupTeacherMapperList">
  173. <p
  174. v-for="(item, index) in scope.row.classGroupTeacherMapperList"
  175. v-if="item.teacherRole == 'TEACHING'"
  176. :key="index"
  177. >
  178. {{ item.userName }}
  179. </p>
  180. </div>
  181. </template>
  182. </el-table-column>
  183. <el-table-column align="center" label="已上课时">
  184. <template slot-scope="scope">
  185. <div>{{ scope.row.currentClassTimes }}</div>
  186. </template>
  187. </el-table-column>
  188. <el-table-column align="center" label="总课数">
  189. <template slot-scope="scope">
  190. <div>{{ scope.row.totalClassTimes }}</div>
  191. </template>
  192. </el-table-column>
  193. <el-table-column
  194. fixed="right"
  195. width="160px"
  196. align="center"
  197. label="操作"
  198. >
  199. <template slot-scope="scope">
  200. <el-button
  201. type="text"
  202. v-if="
  203. permission('classGroup/update')
  204. "
  205. @click="resetClassName(scope.row,true)"
  206. >班级名称调整</el-button
  207. >
  208. <el-button
  209. type="text"
  210. v-if="
  211. permission('classGroup/update')
  212. "
  213. @click="resetClassName(scope.row,false)"
  214. >备注</el-button
  215. >
  216. <el-button
  217. type="text"
  218. @click="addCompound(scope.row)"
  219. v-if="
  220. scope.row.type != 'MUSIC_NETWORK' &&
  221. scope.row.groupType == 'MUSIC' &&
  222. !isAddCom(scope.row) &&
  223. permission('classGroup/spanGroupMergeClassSplitClassAffirm')
  224. "
  225. >添加合班</el-button
  226. >
  227. <el-button
  228. type="text"
  229. v-if="
  230. isAddCom(scope.row) &&
  231. permission('classGroup/spanGroupMergeClassSplitClassAffirm')
  232. "
  233. @click="cancleCompound(scope.row)"
  234. >取消合班</el-button
  235. >
  236. <el-button
  237. type="text"
  238. v-if="
  239. permission('classGroup/delSingle?page=teamCLassList') &&
  240. scope.row.groupType === 'MUSIC' &&
  241. (scope.row.studentNum == '0' ||
  242. scope.row.totalClassTimes == '0')
  243. "
  244. @click="removeClass(scope)"
  245. >删除</el-button
  246. >
  247. </template>
  248. </el-table-column>
  249. </el-table>
  250. <pagination
  251. sync
  252. :total.sync="rules.total"
  253. :page.sync="rules.page"
  254. :limit.sync="rules.limit"
  255. :page-sizes="rules.page_size"
  256. @pagination="getList"
  257. />
  258. </div>
  259. </div>
  260. <classCompound
  261. :compoundList="compoundList"
  262. v-if="
  263. permission('classGroup/spanGroupMergeClassSplitClassAffirm') &&
  264. compoundList.length > 0
  265. "
  266. @clearCom="clearCom"
  267. @getList="getList"
  268. @cancleCompound="cancleCompound"
  269. />
  270. <!-- 修改班级名称 -->
  271. <el-dialog
  272. :title="!resetName?'班级名称调整':'备注'"
  273. width="500px"
  274. :visible.sync="classNameVisible"
  275. v-if="classNameVisible"
  276. >
  277. <changeClassName
  278. :classGroupId="activeClass"
  279. :detail="classDetail"
  280. @submited="submitedResetClassName"
  281. :resetName="resetName"
  282. @close="classNameVisible = false"
  283. />
  284. </el-dialog>
  285. </div>
  286. </template>
  287. <script>
  288. import axios from "axios";
  289. import { getToken } from "@/utils/auth";
  290. import pagination from "@/components/Pagination/index";
  291. import load from "@/utils/loading";
  292. import { courseListType } from "@/utils/searchArray";
  293. import { musicClassTypeList } from "@/utils/searchArray";
  294. import {
  295. getClassGroupPage,
  296. removeSingleClass,
  297. getAgreement,
  298. } from "@/api/buildTeam";
  299. import { permission } from "@/utils/directivePage";
  300. import classCompound from "./componentClass/classCompound";
  301. import { Export } from "@/utils/downLoadFile";
  302. import changeClassName from "@/views/teamDetail/components/modals/class-resetclass-name.vue";
  303. import {resetClassName} from '@/views/teamDetail/api'
  304. import qs from "qs";
  305. export default {
  306. components: { pagination, classCompound,changeClassName },
  307. data() {
  308. return {
  309. searchForm: {
  310. search: null,
  311. organIdList: [],
  312. type: "",
  313. groupType: "MUSIC",
  314. mainTeacherUserId:''
  315. },
  316. courseListType: courseListType,
  317. musicClassTypeList,
  318. tableList: [],
  319. compoundList: [],
  320. hightCount: 0,
  321. hightOnlineCount: 0,
  322. rules: {
  323. // 分页规则
  324. limit: 10, // 限制显示条数
  325. page: 1, // 当前页
  326. total: 0, // 总条数
  327. page_size: [10, 20, 40, 50], // 选择限制显示条数
  328. },
  329. classNameVisible:false,
  330. classDetail:null,
  331. activeClass:'',
  332. resetName:false
  333. };
  334. },
  335. //生命周期 - 创建完成(可以访问当前this实例)
  336. created() {},
  337. //生命周期 - 挂载完成(可以访问DOM元素)
  338. mounted() {
  339. const { query, params } = this.$route;
  340. if (params.search) {
  341. this.searchForm.search = params.search;
  342. }
  343. if (query.type) {
  344. this.searchForm.type = query.type;
  345. }
  346. if (query.organId) {
  347. this.searchForm.organIdList = [Number(query.organId)];
  348. }
  349. // 获取分部
  350. this.$store.dispatch("setBranchs");
  351. this.init();
  352. },
  353. methods: {
  354. async getAgreement() {
  355. try {
  356. const res = await getAgreement();
  357. if (!res.data) {
  358. this.$bus.$emit("showguide", ["agreement"]);
  359. }
  360. } catch (e) {}
  361. },
  362. reloadSearch() {
  363. this.rules.page = 1;
  364. this.getList();
  365. },
  366. init() {
  367. this.getList();
  368. this.getAgreement();
  369. },
  370. async getList() {
  371. try {
  372. let { organIdList, ...result } = this.searchForm;
  373. let obj = {
  374. ...result,
  375. lessThenThreeHighOnline: this.$route.query.lessThenThreeHighOnline,
  376. organIds: this.searchForm.organIdList.join(","),
  377. page: this.rules.page,
  378. rows: this.rules.limit,
  379. };
  380. const res = await getClassGroupPage(obj);
  381. this.rules.total = res.data.total;
  382. this.tableList = res.data.rows;
  383. } catch (err) {
  384. console.log(err);
  385. }
  386. },
  387. search() {
  388. this.rules.page = 1;
  389. this.getList();
  390. },
  391. onReSet() {
  392. this.$refs.searchForm.resetFields();
  393. this.searchForm.groupType = "MUSIC";
  394. this.search();
  395. },
  396. async removeClass(scope) {
  397. try {
  398. await this.$confirm("是否确定删除该班级?", "提示", {
  399. type: "warning",
  400. });
  401. await removeSingleClass({ classGroupId: scope.row.id });
  402. this.$message.success("删除成功");
  403. this.getList();
  404. } catch (error) {}
  405. },
  406. addCompound(row) {
  407. // scope.row.type != 'HIGH_ONLINE' &&scope.row.type != 'HIGH'&&
  408. this.hightOnlineCount = 0;
  409. this.hightCount = 0;
  410. this.compoundList.push(row);
  411. this.compoundList = [...new Set(this.compoundList)];
  412. this.compoundList.forEach((classes) => {
  413. if (classes.type == "HIGH") {
  414. this.hightCount++;
  415. }
  416. if (classes.type == "HIGH_ONLINE") {
  417. this.hightOnlineCount++;
  418. }
  419. });
  420. if (
  421. this.hightOnlineCount &&
  422. this.hightOnlineCount != this.compoundList.length
  423. ) {
  424. this.$message.error("线上基础技能班仅能和线上基础技能班合并");
  425. // this.hightOnlineCount = 0;
  426. // this.hightCount = 0;
  427. // this.compoundList = [];
  428. this.compoundList.splice(this.compoundList.length - 1, 1);
  429. }
  430. if (this.hightCount && this.hightCount != this.compoundList.length) {
  431. this.$message.error("基础技能班仅能和基础技能班合并");
  432. this.compoundList.splice(this.compoundList.length - 1, 1);
  433. // this.hightOnlineCount = 0;
  434. // this.hightCount = 0;
  435. // this.compoundList = [];
  436. }
  437. },
  438. isAddCom(row) {
  439. let flag = false;
  440. this.compoundList.forEach((com) => {
  441. if (com.id == row.id) {
  442. flag = true;
  443. }
  444. });
  445. return flag;
  446. },
  447. cancleCompound(row) {
  448. let indexNum = null;
  449. this.compoundList.forEach((com, index) => {
  450. if (com.id == row.id) {
  451. indexNum = index;
  452. if (row.type == "HIGH") this.hightCount--;
  453. if (row.type == "HIGH_ONLINE") this.hightOnlineCount--;
  454. }
  455. });
  456. if (indexNum + "") {
  457. this.compoundList.splice(indexNum, 1);
  458. }
  459. },
  460. clearCom() {
  461. this.compoundList = [];
  462. this.hightOnlineCount = 0;
  463. this.hightCount = 0;
  464. },
  465. permission(str, parent) {
  466. return permission(str, parent);
  467. },
  468. exportClassGroup() {
  469. let params = this.searchForm;
  470. Export(
  471. this,
  472. {
  473. method: "post",
  474. url: "/api-web/export/classGroup",
  475. params: qs.stringify({
  476. ...params,
  477. organIds: this.searchForm.organIdList.join(","),
  478. lessThenThreeHighOnline: this.$route.query.lessThenThreeHighOnline,
  479. }),
  480. },
  481. "是否确认导出报表?"
  482. );
  483. },
  484. resetClassName(row,flag) {
  485. this.classDetail = row;
  486. this.resetName = !flag;
  487. this.classNameVisible = true;
  488. },
  489. async submitedResetClassName(data) {
  490. const obj = {...data};
  491. resetClassName(obj).then((res) => {
  492. if (res.code == 200) {
  493. this.$message.success("修改成功");
  494. this.classNameVisible = false;
  495. this.getList();
  496. }
  497. });
  498. },
  499. },
  500. };
  501. </script>
  502. <style lang='scss' scoped>
  503. </style>