classroom-setting.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. <template>
  2. <div>
  3. <el-form
  4. :model="form"
  5. inline
  6. ref="form"
  7. label-suffix=": "
  8. label-width="130px"
  9. >
  10. <el-row v-if="classType == 5">
  11. <el-form-item
  12. label="班级名称"
  13. prop="className"
  14. label-width="88px"
  15. :rules="[{ required: true, message: '请填写班级名称' }]"
  16. >
  17. <el-input
  18. v-model.trim="form.className"
  19. placeholder="请输入班级名称"
  20. style="width: 180px"
  21. ></el-input>
  22. </el-form-item>
  23. </el-row>
  24. <el-form-item
  25. label="主教老师"
  26. prop="coreTeacher"
  27. label-width="88px"
  28. :rules="[{ required: true, message: '请选择主教老师' }]"
  29. >
  30. <el-select
  31. v-model.trim="form.coreTeacher"
  32. placeholder="请选择主教老师"
  33. clearable
  34. filterable
  35. @change="changecoreTeacher"
  36. >
  37. <el-option
  38. v-for="(item, index) in teacherList"
  39. :key="index"
  40. :label="item.realName"
  41. :value="String(item.id)"
  42. ></el-option>
  43. </el-select>
  44. <!-- <remote-search :commit="'setTeachers'" v-model="form.coreTeacher" /> -->
  45. </el-form-item>
  46. <el-form-item
  47. label="助教老师"
  48. prop="assistant"
  49. v-if="
  50. activeType != 'HIGH' &&
  51. activeType != 'HIGH_ONLINE' &&
  52. activeType != 'MUSIC_NETWORK'
  53. "
  54. >
  55. <!-- <remote-search :commit="'setTeachers'" v-model="form.assistant" :multiple='true'/> -->
  56. <el-select
  57. v-model.trim="form.assistant"
  58. placeholder="请选择助教老师"
  59. filterable
  60. clearable
  61. multiple
  62. >
  63. <el-option
  64. v-for="(item, index) in cooperationList"
  65. :key="index"
  66. :label="item.realName"
  67. :value="item.id"
  68. ></el-option>
  69. </el-select>
  70. </el-form-item>
  71. <el-form-item
  72. v-if="!!Object.keys(allClasss).length"
  73. style="display: block"
  74. label="排课类型"
  75. label-width="88px"
  76. >
  77. <el-tag
  78. class="tag"
  79. :effect="form.classs[key] ? 'dark' : 'plain'"
  80. v-for="(item, key) in allClasss"
  81. :key="key"
  82. @click="changeTag(key)"
  83. >{{ courseTypeListByName[key] }}</el-tag
  84. >
  85. </el-form-item>
  86. <empty v-if="isEmpty" desc="暂无可排课时长" />
  87. <el-collapse v-model="collapses" @change="collapseChange">
  88. <el-collapse-item
  89. v-for="(item, key, index) in form.classs"
  90. :name="index"
  91. :key="key"
  92. >
  93. <template #title>
  94. <p class="title">
  95. {{ courseTypeListByName[key] }},
  96. <span>可排课时长{{ musicCourseSettings[key] }}分钟</span>
  97. </p>
  98. </template>
  99. <courseItem
  100. :surplustime="surplustime[key]"
  101. :type="key"
  102. :form="item"
  103. :prices="prices"
  104. :selectPrice="selectPrices ? selectPrices[key] : ''"
  105. />
  106. </el-collapse-item>
  107. </el-collapse>
  108. </el-form>
  109. <div slot="footer" class="dialog-footer" v-if="classType != 5">
  110. <el-button @click="$listeners.close">取 消</el-button>
  111. <el-button type="primary" :disabled="isEmpty" @click="submit"
  112. >确 定</el-button
  113. >
  114. </div>
  115. </div>
  116. </template>
  117. <script>
  118. import {
  119. getMusicCourseSettingsWithStudents,
  120. classGroupUpdate,
  121. revisionClassGroup,
  122. revisionAddClassGroup,
  123. findClassCourseMinute,
  124. mergeClassSplitClassAffirm,
  125. } from "@/api/buildTeam";
  126. import courseItem from "./classroom-setting-item";
  127. import { classTimeList } from "@/utils/searchArray";
  128. import MusicStore from "@/views/resetTeaming/store";
  129. import { queryByOrganIdAndCourseType } from "@/views/resetTeaming/api";
  130. import { isEmpty } from "lodash";
  131. const classTimeListByType = {};
  132. for (const item of classTimeList) {
  133. classTimeListByType[item.value] = item.label;
  134. }
  135. const formatClassGroupTeacherMapperList = (core, ass) => {
  136. const list = [];
  137. if (core) {
  138. list.push({ userId: core, teacherRole: "BISHOP" });
  139. }
  140. if (ass) {
  141. for (const item of ass) {
  142. list.push({ userId: item, teacherRole: "TEACHING" });
  143. }
  144. }
  145. return list;
  146. };
  147. const plusNum = (items = [], key) => {
  148. let money = 0;
  149. for (const item of items) {
  150. money += parseFloat(parseFloat(item[key] || 0).toFixed(2) || 0);
  151. }
  152. return money;
  153. };
  154. export default {
  155. props: [
  156. "activeType",
  157. "courseTypeList",
  158. "musicGroupId",
  159. "detail",
  160. "studentSubmitedData",
  161. "classType",
  162. "musicGroupPaymentCalenderDtos",
  163. "classIdList",
  164. "classGroupStudents",
  165. "selectPrices",
  166. "classCouresTimeList",
  167. "teacherList",
  168. "cooperationList",
  169. ],
  170. components: {
  171. courseItem,
  172. },
  173. data() {
  174. return {
  175. form: {
  176. coreTeacher: "",
  177. assistant: "",
  178. classs: {},
  179. },
  180. allClasss: {},
  181. prices: {},
  182. collapses: [0],
  183. courseTimes: {},
  184. courseTypeListByName: {},
  185. classTimeListByType,
  186. musicCourseSettings: {},
  187. };
  188. },
  189. watch: {
  190. courseTypeList() {
  191. this.setCourseTypeListByName();
  192. },
  193. studentSubmitedData() {
  194. this.formatClasss();
  195. },
  196. detail() {
  197. this.formatClasss();
  198. },
  199. },
  200. computed: {
  201. surplustime() {
  202. const _ = {};
  203. for (const key in this.form.classs) {
  204. if (this.form.classs.hasOwnProperty(key)) {
  205. const item = this.form.classs[key];
  206. _[key] = item.courseTotalMinuties - plusNum(item.cycle, "time");
  207. }
  208. }
  209. return _;
  210. },
  211. isEmpty() {
  212. return isEmpty(this.form.classs);
  213. },
  214. musicGroup() {
  215. return MusicStore.state.musicGroup;
  216. },
  217. },
  218. async mounted() {
  219. try {
  220. await MusicStore.dispatch("getBaseInfo", {
  221. data: { musicGroupId: this.musicGroupId },
  222. });
  223. const res = await queryByOrganIdAndCourseType({
  224. organId: this.musicGroup.organId,
  225. });
  226. this.prices = res.data;
  227. } catch (error) {}
  228. this.setCourseTypeListByName();
  229. this.formatClasss();
  230. },
  231. methods: {
  232. setCourseTypeListByName() {
  233. const courseTypeListByName = {};
  234. for (const item of this.courseTypeList) {
  235. courseTypeListByName[item.value] = item.label;
  236. }
  237. this.courseTypeListByName = courseTypeListByName;
  238. },
  239. async formatClasss() {
  240. if (this.detail) {
  241. let coreid = "";
  242. const assistant = [];
  243. const { classGroupTeacherMapperList } = this.detail;
  244. for (const item of classGroupTeacherMapperList || []) {
  245. if (item.teacherRole === "BISHOP") {
  246. coreid = String(item.userId);
  247. }
  248. if (item.teacherRole === "TEACHING") {
  249. assistant.push(item.userId);
  250. }
  251. }
  252. this.$set(this.form, "coreTeacher", String(coreid));
  253. this.$set(this.form, "assistant", assistant);
  254. }
  255. const studentIds = this.detail
  256. ? undefined
  257. : this.studentSubmitedData?.seleched.join(",");
  258. const classGroupId = this.detail?.id;
  259. if (!studentIds && !classGroupId) {
  260. return;
  261. }
  262. let res = {};
  263. if (this.classType == 5) {
  264. // res = await findClassCourseMinute(this.classIdList);
  265. res.data = this.classCouresTimeList;
  266. } else {
  267. try {
  268. res = await getMusicCourseSettingsWithStudents({
  269. musicGroupId: this.musicGroupId,
  270. studentIds,
  271. classGroupId,
  272. });
  273. } catch (error) {
  274. console.log(error);
  275. }
  276. }
  277. // console.log(res);
  278. if (Object.keys(res).length <= 0) return;
  279. this.musicCourseSettings = res.data;
  280. const classs = {};
  281. for (const item of this.courseTypeList) {
  282. const key = item.value;
  283. if (res.data[key]) {
  284. classs[key] = {
  285. courseTotalMinuties: res.data[key],
  286. cycle: [
  287. {
  288. time: this.selectPrices ? this.selectPrices[key] : undefined,
  289. },
  290. ],
  291. };
  292. }
  293. }
  294. this.allClasss = { ...classs };
  295. this.$set(this.form, "classs", classs);
  296. // this.courseTimes = courseTimes
  297. },
  298. changeTag(key) {
  299. const clas = { ...this.form.classs };
  300. if (clas[key]) {
  301. delete clas[key];
  302. } else {
  303. clas[key] = this.allClasss[key];
  304. }
  305. this.$set(this.form, "classs", clas);
  306. },
  307. submit() {
  308. this.$refs.form.validate(async (valid) => {
  309. if (valid) {
  310. const list = [];
  311. for (const key in this.form.classs) {
  312. if (this.form.classs.hasOwnProperty(key)) {
  313. const item = this.form.classs[key];
  314. list.push({
  315. type: this.detail ? undefined : this.activeType,
  316. courseType: key,
  317. classGroupName:
  318. this.studentSubmitedData?.name ||
  319. this.detail?.name ||
  320. this.form.className,
  321. classGroupId: this.detail?.id,
  322. musicGroupId: this.musicGroupId,
  323. startDate: item.courseTime,
  324. classGroupTeacherMapperList: formatClassGroupTeacherMapperList(
  325. this.form.coreTeacher,
  326. this.form.assistant
  327. ),
  328. holiday: item.holiday,
  329. students: this.studentSubmitedData?.seleched,
  330. courseTimes: item.cycle.length,
  331. courseTimeDtoList: item.cycle.map((_) => ({
  332. courseType: key,
  333. dayOfWeek: _.dayOfWeek,
  334. endClassTime: _.endClassTime,
  335. startClassTime: _.startClassTime,
  336. })),
  337. });
  338. }
  339. }
  340. try {
  341. if (this.detail) {
  342. let result = await classGroupUpdate(list);
  343. if (result.code == 206) {
  344. this.$confirm(`当前课程课酬预计为0,是否继续`, "提示", {
  345. confirmButtonText: "确定",
  346. cancelButtonText: "取消",
  347. type: "warning",
  348. })
  349. .then(async () => {
  350. // obj.allowZeroSalary = true;
  351. list.forEach((item) => {
  352. item.allowZeroSalary = true;
  353. });
  354. await classGroupUpdate(list);
  355. this.$listeners.submited();
  356. this.$listeners.close();
  357. })
  358. .catch(() => {
  359. return;
  360. });
  361. return;
  362. }
  363. this.$message.success("排课修改成功");
  364. } else {
  365. if (this.classType == 1) {
  366. // 0新建班级 2 3 4新增班级修改
  367. await revisionClassGroup(list);
  368. this.$message.success("排课成功");
  369. } else if (
  370. this.classType == 2 ||
  371. this.classType == 3 ||
  372. this.classType == 4
  373. ) {
  374. await revisionAddClassGroup(list);
  375. this.$message.success("排课成功");
  376. } else if (this.classType == 5) {
  377. // 这里是合班拆班
  378. let obj = {};
  379. obj.musicGroupPaymentCalenderDtos = this.musicGroupPaymentCalenderDtos;
  380. obj.classGroup4MixDtos = list;
  381. obj.classGroupIds = this.classIdList;
  382. obj.studentIds = this.studentSubmitedData.seleched;
  383. obj.classGroupStudents = this.classGroupStudents;
  384. obj.classCourseMinuteMap = this.selectPrices;
  385. await mergeClassSplitClassAffirm(obj);
  386. let grend = this.$parent.$parent.$parent.$parent.$parent.$parent
  387. .$parent;
  388. grend.closeStudentReset();
  389. grend.getList();
  390. return;
  391. }
  392. }
  393. this.$listeners.submited();
  394. this.$listeners.close();
  395. } catch (error) {
  396. console.log(error);
  397. }
  398. } else {
  399. this.$message.error("请先填写所有表单");
  400. }
  401. });
  402. },
  403. collapseChange(val) {
  404. this.collapses = val;
  405. },
  406. changecoreTeacher(val) {},
  407. },
  408. };
  409. </script>
  410. <style lang="less" scoped>
  411. .dialog-footer {
  412. margin-top: 20px;
  413. display: block;
  414. text-align: right;
  415. }
  416. .title {
  417. font-size: 16px;
  418. padding: 10px;
  419. font-weight: normal;
  420. > span {
  421. color: tomato;
  422. font-size: 14px;
  423. }
  424. }
  425. .tag {
  426. margin-right: 5px;
  427. cursor: pointer;
  428. }
  429. </style>