teamCourseList.vue 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209
  1. <template>
  2. <div class="m-container">
  3. <h2>
  4. <div class="squrt"></div>
  5. 课表列表
  6. <filter-search
  7. ref="filterSearch"
  8. @reload="reloadSearch"
  9. :keys="['searchType']"
  10. :moreKeys="['start', 'end', 'organId']"
  11. />
  12. </h2>
  13. <div class="m-core">
  14. <!-- 搜索类型 -->
  15. <save-form
  16. :inline="true"
  17. class="searchForm"
  18. @submit="search"
  19. @reset="reset"
  20. ref="searchForm"
  21. :model.sync="searchForm"
  22. >
  23. <el-form-item>
  24. <el-input
  25. type="number"
  26. v-model.trim="searchForm.courseIdSearch"
  27. clearable
  28. placeholder="课程编号"
  29. />
  30. </el-form-item>
  31. <el-form-item>
  32. <el-input
  33. v-model.trim="searchForm.search"
  34. clearable
  35. placeholder="课程组编号/课程名称"
  36. />
  37. </el-form-item>
  38. <el-form-item>
  39. <el-select
  40. v-model.trim="searchForm.schoolId"
  41. clearable
  42. filterable
  43. placeholder="请选择教学点"
  44. >
  45. <el-option
  46. v-for="(item, index) in selects.schools"
  47. :key="index"
  48. :value="item.id"
  49. :label="item.name"
  50. ></el-option>
  51. </el-select>
  52. </el-form-item>
  53. <el-form-item>
  54. <remote-search
  55. :commit="'setTeachers'"
  56. v-model="searchForm.teacherIdList"
  57. />
  58. <!-- <el-select
  59. v-model.trim="searchForm.teacherIdList"
  60. clearable
  61. filterable
  62. placeholder="请选择老师"
  63. >
  64. <el-option
  65. v-for="(item, index) in selects.teachers"
  66. :key="index"
  67. :value="item.id"
  68. :label="item.realName"
  69. ></el-option>
  70. </el-select> -->
  71. </el-form-item>
  72. <el-form-item>
  73. <el-select
  74. class="multiple"
  75. v-model.trim="searchForm.organIdList"
  76. filterable
  77. clearable
  78. placeholder="请选择分部"
  79. >
  80. <el-option
  81. v-for="(item, index) in selects.branchs"
  82. :key="index"
  83. :label="item.name"
  84. :value="item.id"
  85. ></el-option>
  86. </el-select>
  87. </el-form-item>
  88. <el-form-item>
  89. <el-select
  90. v-model.trim="searchForm.groupType"
  91. clearable
  92. filterable
  93. placeholder="课程组类型"
  94. >
  95. <el-option
  96. v-for="item in courseListType"
  97. :key="item.value"
  98. :value="item.value"
  99. :label="item.label"
  100. ></el-option>
  101. </el-select>
  102. </el-form-item>
  103. <el-form-item>
  104. <el-select
  105. v-model.trim="searchForm.courseType"
  106. clearable
  107. filterable
  108. placeholder="课程类型"
  109. >
  110. <el-option
  111. v-for="(item, index) in courseType"
  112. :key="index"
  113. :value="item.value"
  114. :label="item.label"
  115. ></el-option>
  116. </el-select>
  117. </el-form-item>
  118. <el-form-item>
  119. <el-select
  120. v-model.trim="searchForm.teachMode"
  121. clearable
  122. filterable
  123. placeholder="教学模式"
  124. >
  125. <el-option label="线上课" value="ONLINE"></el-option>
  126. <el-option label="线下课" value="OFFLINE"></el-option>
  127. </el-select>
  128. </el-form-item>
  129. <el-form-item>
  130. <el-select
  131. v-model.trim="searchForm.courseStatus"
  132. clearable
  133. filterable
  134. placeholder="课程状态"
  135. >
  136. <el-option label="未开始" value="NOT_START"></el-option>
  137. <el-option label="进行中" value="UNDERWAY"></el-option>
  138. <el-option label="已结束" value="OVER"></el-option>
  139. </el-select>
  140. </el-form-item>
  141. <el-form-item>
  142. <el-select
  143. v-model.trim="searchForm.mergeCourseType"
  144. clearable
  145. filterable
  146. placeholder="合并课程类型"
  147. >
  148. <el-option
  149. v-for="(item, index) in mergeCourseTypeOptions"
  150. :key="index"
  151. :value="item.value"
  152. :label="item.label"
  153. ></el-option>
  154. </el-select>
  155. </el-form-item>
  156. <el-form-item>
  157. <el-select
  158. v-model.trim="searchForm.teachType"
  159. clearable
  160. filterable
  161. placeholder="老师类型"
  162. >
  163. <el-option
  164. v-for="item in workTypeOptions"
  165. :key="item.label"
  166. :label="item.label"
  167. :value="item.value"
  168. ></el-option>
  169. </el-select>
  170. </el-form-item>
  171. <el-form-item>
  172. <el-select
  173. v-model.trim="searchForm.isCallNames"
  174. clearable
  175. filterable
  176. placeholder="是否点名"
  177. >
  178. <el-option label="是" value="1"></el-option>
  179. <el-option label="否" value="0"></el-option>
  180. </el-select>
  181. </el-form-item>
  182. <el-form-item>
  183. <el-date-picker
  184. v-model.trim="searchForm.timer"
  185. type="daterange"
  186. value-format="yyyy-MM-dd"
  187. range-separator="至"
  188. start-placeholder="上课开始日期"
  189. end-placeholder="上课结束日期"
  190. :picker-options="{
  191. firstDayOfWeek: 1,
  192. }"
  193. ></el-date-picker>
  194. </el-form-item>
  195. <el-form-item>
  196. <el-date-picker
  197. v-model.trim="searchForm.creatTimer"
  198. type="daterange"
  199. value-format="yyyy-MM-dd"
  200. range-separator="至"
  201. start-placeholder="创建开始日期"
  202. end-placeholder="创建结束日期"
  203. :picker-options="{
  204. firstDayOfWeek: 1,
  205. }"
  206. ></el-date-picker>
  207. </el-form-item>
  208. <el-row type="flex" justify="space-around">
  209. <el-col>
  210. <el-button native-type="submit" type="primary">搜索</el-button>
  211. <el-button native-type="reset" type="danger">重置</el-button>
  212. <el-button
  213. v-permission="'export/superFindCourseSchedules'"
  214. @click="onCourseExport"
  215. type="primary"
  216. >导出课表</el-button
  217. >
  218. </el-col>
  219. </el-row>
  220. </save-form>
  221. <!-- 列表 -->
  222. <div class="tableWrap" style="margin-top: 20px">
  223. <el-table
  224. :data="tableList"
  225. ref="tableList"
  226. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  227. @selection-change="handleSelectionChange"
  228. @select='onTableSelect'
  229. row-key="id"
  230. >
  231. >
  232. <el-table-column
  233. v-permission="'courseSchedule/batchDelete?page=teamCourseList'"
  234. type="selection"
  235. width="55"
  236. ></el-table-column>
  237. <el-table-column
  238. align="center"
  239. prop="organName"
  240. label="分部名称"
  241. ></el-table-column>
  242. <el-table-column
  243. align="center"
  244. width="150px"
  245. prop="musicGroupId"
  246. label="乐团/课程组编号"
  247. >
  248. <template slot-scope="scope">
  249. <el-button type="text" @click="gotoCourse(scope.row)">
  250. <copy-text>{{ scope.row.musicGroupId }}</copy-text>
  251. </el-button>
  252. </template>
  253. </el-table-column>
  254. <el-table-column
  255. align="center"
  256. prop="id"
  257. width="100px"
  258. label="课程编号"
  259. >
  260. <template slot-scope="scope">
  261. <copy-text>{{ scope.row.id }}</copy-text>
  262. </template>
  263. </el-table-column>
  264. <el-table-column align="center" width="200px" label="上课时间">
  265. <template slot-scope="scope"
  266. >{{
  267. scope.row.startClassTime
  268. ? scope.row.startClassTime.substr(0, 16)
  269. : ""
  270. }}-{{
  271. scope.row.endClassTime
  272. ? scope.row.endClassTime.substr(11, 5)
  273. : ""
  274. }}</template
  275. >
  276. </el-table-column>
  277. <el-table-column
  278. align="center"
  279. prop="subjectName"
  280. label="声部"
  281. ></el-table-column>
  282. <el-table-column prop="name" width="150px" label="课程名称">
  283. <template slot-scope="scope">
  284. <copy-text>{{ scope.row.name }}</copy-text>
  285. </template>
  286. </el-table-column>
  287. <el-table-column align="center" width="150px" label="课程类型">
  288. <template slot-scope="scope">
  289. <div>{{ scope.row.type | coursesType }}</div>
  290. </template>
  291. </el-table-column>
  292. <el-table-column align="center" label="教学模式">
  293. <template slot-scope="scope">
  294. <div>{{ scope.row.teachMode | teachMode }}</div>
  295. </template>
  296. </el-table-column>
  297. <el-table-column
  298. align="center"
  299. prop="teacherName"
  300. width="110"
  301. label="主教老师"
  302. ></el-table-column>
  303. <el-table-column align="center" prop="schoolName" label="教学点">
  304. <template slot-scope="scope">
  305. <div>
  306. {{ scope.row.schoolName ? scope.row.schoolName : "网络教室" }}
  307. </div>
  308. </template>
  309. </el-table-column>
  310. <el-table-column
  311. align="center"
  312. prop="courseScheduleStatus"
  313. label="课程状态"
  314. >
  315. <template slot-scope="scope">
  316. <div>{{ scope.row.status | coursesStatus }}</div>
  317. </template>
  318. </el-table-column>
  319. <el-table-column align="center" label="考勤申诉">
  320. <template slot-scope="scope">
  321. <div>{{ scope.row.isComplaints == 1 ? "是" : "否" }}</div>
  322. </template>
  323. </el-table-column>
  324. <el-table-column align="center" prop="isLock" label="是否冻结">
  325. <template slot-scope="scope">{{
  326. scope.row.isLock ? "是" : "否"
  327. }}</template>
  328. </el-table-column>
  329. <el-table-column
  330. align="center"
  331. prop="newCourseId"
  332. label="合并类型"
  333. width="130px"
  334. >
  335. <template slot-scope="scope">
  336. <div>
  337. <span
  338. v-if="
  339. scope.row.newCourseId > 0 &&
  340. scope.row.newCourseId == scope.row.id
  341. "
  342. >合并课
  343. </span>
  344. <el-button
  345. type="text"
  346. @click="common(scope.row)"
  347. v-if="
  348. scope.row.newCourseId > 0 &&
  349. scope.row.newCourseId != scope.row.id
  350. "
  351. >
  352. 被合并课
  353. </el-button>
  354. </div>
  355. </template>
  356. </el-table-column>
  357. <el-table-column
  358. align="center"
  359. prop="isCallNames"
  360. label="是否点名"
  361. fixed="right"
  362. >
  363. <template slot-scope="scope">{{
  364. scope.row.isCallNames ? "是" : "否"
  365. }}</template>
  366. </el-table-column>
  367. <el-table-column
  368. align="center"
  369. label="详情"
  370. fixed="right"
  371. width="220px"
  372. >
  373. <template slot-scope="scope">
  374. <div>
  375. <!-- <el-button
  376. type="text"
  377. @click="removeCourse(scope.row)"
  378. v-permission="
  379. 'courseSchedule/batchDelete?page=teamCourseList'
  380. "
  381. >删除</el-button
  382. > -->
  383. <auth auths="/teamCourseListDetail">
  384. <!-- v-if="permission('teamCourseList/details')" -->
  385. <el-button type="text" @click="lookDetail(scope.row)"
  386. >详情</el-button
  387. >
  388. </auth>
  389. <el-button
  390. type="text"
  391. v-if="
  392. permission('courseSchedule/classStartDateAdjust?hight') &&
  393. (!scope.row.isLock || scope.row.newCourseId > 0)
  394. "
  395. @click="resetClass(scope.row)"
  396. >调整</el-button
  397. >
  398. <!-- <el-button
  399. type="text"
  400. @click="addCompound(scope.row)"
  401. v-if="
  402. scope.row.groupType == 'MUSIC' &&
  403. scope.row.type != 'MUSIC_NETWORK' &&
  404. scope.row.type != 'HIGH_ONLINE' &&
  405. scope.row.status == 'NOT_START' &&
  406. !isAddCom(scope.row) &&
  407. permission('courseSchedule/courseMerge') &&
  408. scope.row.newCourseId <= 0 &&
  409. !scope.row.beMerged &&
  410. !scope.row.isLock // 李焕辜临轩要求冻结课程不能合并
  411. "
  412. >添加合课</el-button
  413. >
  414. <el-button
  415. type="text"
  416. v-if="
  417. isAddCom(scope.row) &&
  418. permission('courseSchedule/courseMerge')
  419. "
  420. @click="cancleCompound(scope.row)"
  421. >取消合课</el-button
  422. > -->
  423. <el-button
  424. type="text"
  425. v-if="
  426. scope.row.newCourseId == scope.row.id &&
  427. permission('courseSchedule/mergeCourseSplit') &&
  428. scope.row.status != 'OVER'
  429. "
  430. @click="resetCompound(scope.row)"
  431. >取消合并</el-button
  432. >
  433. <el-button
  434. type="text"
  435. v-if="
  436. scope.row.status == 'OVER' &&
  437. !scope.row.isSettlement &&
  438. permission('courseSchedule/cleanAttendance')
  439. "
  440. @click="clearAttend(scope.row)"
  441. >清除考勤</el-button
  442. >
  443. </div>
  444. </template>
  445. </el-table-column>
  446. </el-table>
  447. <pagination
  448. :total.sync="rules.total"
  449. :page.sync="rules.page"
  450. :limit.sync="rules.limit"
  451. :page-sizes="rules.page_size"
  452. @pagination="getList"
  453. sync
  454. />
  455. </div>
  456. </div>
  457. <el-dialog title="课表详情" :visible.sync="classVisible" width="1000px">
  458. <el-form :model="maskForm" :inline="true">
  459. <el-form-item label="老师姓名">
  460. <!-- <el-input v-model.trim="maskForm.teacherName"
  461. disabled></el-input>-->
  462. <div class="inputStyle">{{ maskForm.teacherName }}</div>
  463. </el-form-item>
  464. <el-form-item label="课程模式">
  465. <!-- <el-input :value="maskForm.teachMode | teachMode"
  466. disabled></el-input>-->
  467. <div class="inputStyle">{{ maskForm.teachMode | teachMode }}</div>
  468. <!-- <span>{{maskForm.teachMode }}</span> -->
  469. </el-form-item>
  470. <el-form-item label="课程类型">
  471. <!-- <el-input :value="maskForm.type |classType"
  472. disabled></el-input>-->
  473. <div class="inputStyle">{{ maskForm.type | coursesType }}</div>
  474. </el-form-item>
  475. <!-- courseScheduleStatus -->
  476. <el-form-item label="课程状态">
  477. <!-- <el-input :value="maskForm.type |classType"
  478. disabled></el-input>-->
  479. <div class="inputStyle">{{ maskForm.status | coursesStatus }}</div>
  480. </el-form-item>
  481. <!-- <el-form-item label="签到时间">
  482. <div class="inputStyle">{{maskForm.signInTime | dateForMinFormat}}</div>
  483. </el-form-item>
  484. <el-form-item label="签退时间">
  485. <div class="inputStyle">{{maskForm.signOutTime | dateForMinFormat}}</div>
  486. </el-form-item> -->
  487. <el-form-item label="是否点名">
  488. <!-- <el-input :value="maskForm.isCallNames | isCall"
  489. disabled></el-input>-->
  490. <div class="inputStyle">{{ maskForm.isCallNames | isCall }}</div>
  491. </el-form-item>
  492. <!-- <el-form-item label="签到状态">
  493. <div class="inputStyle"
  494. :class="maskForm.isSignIn==1?'':'red'">{{ maskForm.isSignIn | attendanceType}}</div>
  495. </el-form-item>
  496. <el-form-item label="签退状态">
  497. <div class="inputStyle"
  498. :class="maskForm.isSignIn==1?'':'red'">{{ maskForm.isSignOut | attendanceOutType}}</div>
  499. </el-form-item> -->
  500. <el-form-item label="上课时间">
  501. {{
  502. maskForm.startClassTime
  503. ? maskForm.startClassTime.substr(0, 16)
  504. : ""
  505. }}-{{
  506. maskForm.endClassTime ? maskForm.endClassTime.substr(11, 5) : ""
  507. }}
  508. </el-form-item>
  509. <el-form-item label="上课时长">
  510. <div
  511. class="inputStyle"
  512. :class="maskForm.attendClassTime <= 120 ? '' : 'red'"
  513. >
  514. {{
  515. maskForm.attendClassTime >= 0 ? maskForm.attendClassTime : 0
  516. }}分钟
  517. <el-tooltip placement="top" popper-class="mTooltip">
  518. <div slot="content">学员和老师同时在教室里的时长。</div>
  519. <!-- <img :src="imageIcon" class="micon el-tooltip" style="width:8px height:8px" alt /> -->
  520. <i
  521. class="el-icon-question micon el-tooltip"
  522. style="font-size: 18px; color: #f56c6c"
  523. v-permission="'export/teacherSalary'"
  524. ></i>
  525. </el-tooltip>
  526. </div>
  527. </el-form-item>
  528. <el-form-item label="学员考勤" v-if="maskForm.status != 'NOT_START'">
  529. <div
  530. class="inputStyle"
  531. :class="maskForm.errorAttendanceNum != 0 ? 'red' : null"
  532. >
  533. {{ maskForm.errorAttendanceNum != 0 ? "异常" : "正常" }}
  534. </div>
  535. </el-form-item>
  536. <el-form-item label="老师考勤" v-if="maskForm.status != 'NOT_START'">
  537. <div
  538. class="inputStyle"
  539. :class="
  540. maskForm.signInStatusEnum == 1 && maskForm.signOutStatusEnum == 1
  541. ? null
  542. : 'red'
  543. "
  544. >
  545. {{
  546. maskForm.signInStatusEnum == 1 && maskForm.signOutStatusEnum == 1
  547. ? "正常"
  548. : "异常"
  549. }}
  550. </div>
  551. </el-form-item>
  552. <el-form-item v-if="maskForm.school" label="教学点">
  553. {{ maskForm.school.name }}
  554. <el-tooltip content="查看教学点" :open-delay="0.5">
  555. <i
  556. @click="openLocation(maskForm.school)"
  557. class="el-icon-map-location"
  558. style="cursor: pointer"
  559. ></i>
  560. </el-tooltip>
  561. </el-form-item>
  562. </el-form>
  563. <!-- v-if="maskForm.status != 'NOT_START'" -->
  564. <el-tabs v-model.trim="activeName" type="card" @tab-click="handleClick">
  565. <el-tab-pane
  566. label="学员列表"
  567. name="first"
  568. v-if="permission('/teamCourseListDetailStudnetList')"
  569. >
  570. <div v-if="activeName == 'first'">
  571. <!-- studentRollCall -->
  572. <studentRollCall
  573. :courseScheduleId="maskForm.id"
  574. :isMainGo="isMainGo"
  575. ></studentRollCall>
  576. </div>
  577. </el-tab-pane>
  578. <!-- <el-tab-pane label="GPS定位"
  579. v-if="maskForm.teachMode == 'OFFLINE'"
  580. name="second">
  581. <div v-if="activeName == 'second'">
  582. <gpsLoction :courseScheduleId="maskForm.id"></gpsLoction>
  583. </div>
  584. </el-tab-pane> -->
  585. <el-tab-pane
  586. label="老师列表"
  587. name="second"
  588. v-if="permission('/teamCourseListDetailTeacherList')"
  589. >
  590. <div v-if="activeName == 'second'">
  591. <teacherList
  592. :courseScheduleId="maskForm.id"
  593. :teachMode="maskForm.teachMode"
  594. :courseStatus="maskForm.status"
  595. ></teacherList>
  596. </div>
  597. </el-tab-pane>
  598. <!-- v-if="maskForm.teachMode != 'OFFLINE'" -->
  599. <el-tab-pane
  600. label="作业"
  601. name="third"
  602. v-if="permission('/teamCourseListDetailWorkList')"
  603. >
  604. <div v-if="activeName == 'third'">
  605. <studentWork :courseScheduleId="maskForm.id"></studentWork>
  606. </div>
  607. </el-tab-pane>
  608. <!-- v-if="maskForm.type == 'VIP' || maskForm.type == 'PRACTICE'" -->
  609. <el-tab-pane
  610. label="评论"
  611. name="four"
  612. v-if="permission('/teamCourseListDetailCommentList')"
  613. >
  614. <div v-if="activeName == 'four'">
  615. <courseEvaluate :courseScheduleId="maskForm.id"></courseEvaluate>
  616. </div>
  617. </el-tab-pane>
  618. <el-tab-pane
  619. label="调整记录"
  620. v-if="permission('/teamCourseListDetailAdjust')"
  621. name="five"
  622. >
  623. <div v-if="activeName == 'five'">
  624. <infoMsg :courseScheduleId="maskForm.id"></infoMsg>
  625. </div>
  626. </el-tab-pane>
  627. <!-- infoMsg -->
  628. </el-tabs>
  629. </el-dialog>
  630. <el-dialog :visible.sync="show" width="400px" title="课程调整">
  631. <resetClass
  632. :show="show"
  633. v-if="show"
  634. @closeReset="closeReset"
  635. @getList="getList"
  636. :id="id"
  637. />
  638. </el-dialog>
  639. <el-dialog title="查看教学点" :visible.sync="locationVisible">
  640. <school-location
  641. v-if="maskForm.school"
  642. :longitudeLatitude="maskForm.school.longitudeLatitude"
  643. :address="maskForm.school.address"
  644. />
  645. </el-dialog>
  646. <addCompound
  647. ref='addCompound'
  648. :compoundList="deleteList"
  649. v-if="permission('courseSchedule/courseMerge')"
  650. v-show="deleteList.length>0"
  651. @clearCom="clearCom"
  652. @getList="getList"
  653. @removeCourse="removeCourse"
  654. @cancleCompound="cancleCompound"
  655. />
  656. </div>
  657. </template>
  658. <script>
  659. import pagination from "@/components/Pagination/index";
  660. import {
  661. superFindCourseSchedules,
  662. cleanAttendance,
  663. cancelCourseMerge,
  664. } from "@/api/buildTeam";
  665. import { bathDelete } from "@/api/vipSeting";
  666. import { workType, mergeCourseType } from "@/constant";
  667. import { objectToOptions, getTimes } from "@/utils";
  668. import { getTeacherPersonalAttendanceDetail } from "@/api/teacherManager";
  669. import { getSchool } from "@/api/systemManage";
  670. import { courseType, courseListType } from "@/utils/searchArray";
  671. import studentRollCall from "./componentCourse/studentRollCall";
  672. import gpsLoction from "./componentCourse/gpsLocation";
  673. import studentWork from "./componentCourse/studentWork";
  674. import courseEvaluate from "./componentCourse/courseEvaluate";
  675. import { permission } from "@/utils/directivePage";
  676. import axios from "axios";
  677. import { getToken } from "@/utils/auth";
  678. import load from "@/utils/loading";
  679. import SchoolLocation from "./components/modals/school-location";
  680. import resetClass from "./componentCourse/resetClass";
  681. import teacherList from "./componentCourse/teacherList";
  682. import addCompound from "./componentCourse/addCompound";
  683. import infoMsg from "./componentCourse/infoMsg";
  684. let nowTime = new Date();
  685. nowTime =
  686. nowTime.getFullYear() +
  687. "-" +
  688. (nowTime.getMonth() + 1) +
  689. "-" +
  690. nowTime.getDate();
  691. const initSearch = {
  692. teachMode: null, // 教学模式
  693. organIdList: null,
  694. courseStatus: null,
  695. courseType: null,
  696. timer: [nowTime, nowTime], // 时间
  697. class: null,
  698. teachType: null,
  699. mergeCourseType: null,
  700. isCallNames: null, // 是否点名
  701. search: null, // 乐团名称 编号 vip课名称
  702. teacherIdList: null, // 老师编号
  703. schoolId: null, // 教学点编号
  704. creatTimer: [],
  705. courseIdSearch: null,
  706. };
  707. export default {
  708. data() {
  709. return {
  710. classVisible: false,
  711. timerVisible: false,
  712. courseVisible: false,
  713. locationVisible: false,
  714. courseType: courseType,
  715. mergeCourseType,
  716. courseListType: courseListType,
  717. searchForm: { ...initSearch },
  718. tableList: [],
  719. searchLsit: [],
  720. organList: [],
  721. rules: {
  722. // 分页规则
  723. limit: 10, // 限制显示条数
  724. page: 1, // 当前页
  725. total: 0, // 总条数
  726. page_size: [10, 20, 40, 50], // 选择限制显示条数
  727. },
  728. teacherList: [],
  729. schoolList: [],
  730. maskForm: {},
  731. activeName: "first",
  732. id: null,
  733. show: false,
  734. compoundList: [],
  735. deleteList: [],
  736. isMainGo: false,
  737. isDetele: false,
  738. };
  739. },
  740. components: {
  741. pagination,
  742. studentRollCall,
  743. gpsLoction,
  744. studentWork,
  745. courseEvaluate,
  746. resetClass,
  747. teacherList,
  748. addCompound,
  749. infoMsg,
  750. SchoolLocation,
  751. },
  752. created() {
  753. this.searchForm.timer = [nowTime, nowTime];
  754. },
  755. computed: {
  756. workTypeOptions() {
  757. return objectToOptions(workType);
  758. },
  759. mergeCourseTypeOptions() {
  760. return objectToOptions(mergeCourseType);
  761. },
  762. },
  763. mounted() {
  764. const { query } = this.$route;
  765. if (query.start || query.end) {
  766. this.searchForm.timer = [query.start, query.end];
  767. } else {
  768. let flag = false;
  769. for (let item in this.searchForm) {
  770. if (typeof this.searchForm[item] == "object") {
  771. // 对象或者数组
  772. if (this.searchForm[item]?.length > 0) {
  773. flag = true;
  774. }
  775. } else {
  776. if (this.searchForm[item]) {
  777. flag = true;
  778. }
  779. }
  780. }
  781. if (!flag) {
  782. this.searchForm.timer = [nowTime, nowTime];
  783. }
  784. }
  785. // 课程时间段异常,不需要时间搜索
  786. if (query.searchType == "COURSE_TIME_ERROR") {
  787. this.searchForm.timer = [];
  788. }
  789. if (query.organId) {
  790. this.searchForm.organIdList = Number(query.organId);
  791. }
  792. this.$store.dispatch("setBranchs");
  793. this.$store.dispatch("setTeachers");
  794. this.$store.dispatch("setSchools");
  795. this.init();
  796. },
  797. methods: {
  798. init() {
  799. this.getList();
  800. },
  801. permission(str, parent) {
  802. return permission(str, parent);
  803. },
  804. reloadSearch() {
  805. this.searchForm.timer = [nowTime, nowTime];
  806. this.getList();
  807. },
  808. async removeCourse(row) {
  809. if (this.deleteList.length < 1 && !row) {
  810. this.$message.error("请自少选择一节课");
  811. return;
  812. }
  813. let flag = false;
  814. let arr = this.deleteList.map((course) => {
  815. if (course.isSettlement || course.status == "UNDERWAY") {
  816. flag = true;
  817. }
  818. return course.id;
  819. });
  820. if (flag) {
  821. this.$message.error("已结算或进行中的课程无法删除");
  822. return;
  823. }
  824. let courseScheduleIds = arr.join(",") || row.id;
  825. this.$confirm("是否确认删除此数据?", "提示", {
  826. type: "warning",
  827. }).then(() => {
  828. bathDelete({ courseScheduleIds: courseScheduleIds }).then((res) => {
  829. if (res.code == 200) {
  830. this.$message.success("删除成功");
  831. this.getList();
  832. this.clearCom()
  833. }
  834. }).catch((e)=>{
  835. this.$refs.addCompound.isLook = true
  836. });
  837. }).catch((e) => {
  838. this.$refs.addCompound.isLook = true
  839. });;
  840. },
  841. reset() {
  842. this.searchForm = { ...initSearch };
  843. this.search();
  844. },
  845. search() {
  846. this.rules.page = 1;
  847. this.$refs.searchForm.save(this.searchForm);
  848. this.getList();
  849. },
  850. common(row) {
  851. this.searchForm = {
  852. ...initSearch,
  853. timer: [],
  854. courseIdSearch: row.newCourseId,
  855. };
  856. this.search();
  857. },
  858. getSearchForm() {
  859. let searchForm = this.searchForm;
  860. if (!searchForm.timer || searchForm.timer.length <= 0) {
  861. searchForm.timer = [];
  862. // this.$message.error("请选择时间段");
  863. // return;
  864. }
  865. if (!searchForm.creatTimer || searchForm.creatTimer.length <= 0) {
  866. searchForm.creatTimer = [];
  867. }
  868. let count = 0;
  869. for (let item in searchForm) {
  870. if (searchForm[item] && !Array.isArray(searchForm[item])) {
  871. count++;
  872. } else if (
  873. Array.isArray(searchForm[item]) &&
  874. searchForm[item].length > 0
  875. ) {
  876. count++;
  877. }
  878. }
  879. // 课程时间段异常,不需要时间搜索,则课表列表搜索可以不要条件搜索
  880. // if (count <= 0) {
  881. // this.$message.error("请至少选择一个搜索条件");
  882. // return false;
  883. // }
  884. const { creatTimer, timer, ...rest } = searchForm;
  885. return {
  886. ...rest,
  887. page: this.rules.page,
  888. rows: this.rules.limit,
  889. searchType: this.$route.query.searchType,
  890. ...getTimes(creatTimer, ["createStartDate", "createEndDate"]),
  891. ...getTimes(timer, ["startTime", "endTime"]),
  892. };
  893. },
  894. openLocation(school) {
  895. this.locationVisible = true;
  896. },
  897. onCourseExport() {
  898. // 课表导出
  899. if (!this.getSearchForm()) {
  900. return;
  901. }
  902. let url = "/api-web/export/superFindCourseSchedules";
  903. const options = {
  904. method: "get",
  905. headers: {
  906. Authorization: getToken(),
  907. },
  908. params: this.getSearchForm(),
  909. url,
  910. responseType: "blob",
  911. };
  912. this.$confirm("您确定导出报表", "提示", {
  913. confirmButtonText: "确定",
  914. cancelButtonText: "取消",
  915. type: "warning",
  916. })
  917. .then(() => {
  918. load.startLoading();
  919. axios(options)
  920. .then((res) => {
  921. let blob = new Blob([res.data], {
  922. // type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
  923. type: "application/vnd.ms-excel;charset=utf-8",
  924. //word文档为application/msword,pdf文档为application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8
  925. });
  926. let text = new Response(blob).text();
  927. text.then((res) => {
  928. // 判断是否报错
  929. if (res.indexOf("code") != -1) {
  930. let json = JSON.parse(res);
  931. this.$message.error(json.msg);
  932. } else {
  933. let objectUrl = URL.createObjectURL(blob);
  934. let link = document.createElement("a");
  935. let fname = "课表列表" + new Date().getTime() + ".xls"; //下载文件的名字
  936. link.href = objectUrl;
  937. link.setAttribute("download", fname);
  938. document.body.appendChild(link);
  939. link.click();
  940. }
  941. });
  942. load.endLoading();
  943. })
  944. .catch((error) => {
  945. this.$message.error("导出数据失败,请联系管理员");
  946. load.endLoading();
  947. });
  948. })
  949. .catch(() => {});
  950. },
  951. getList() {
  952. if (!this.getSearchForm()) {
  953. return;
  954. }
  955. superFindCourseSchedules(this.getSearchForm()).then((res) => {
  956. if (res.code == 200) {
  957. this.tableList = res.data.rows;
  958. this.rules.total = res.data.total;
  959. let idList = this.deleteList.map((course) => {
  960. return course.id;
  961. });
  962. this.isDetele = true;
  963. this.$nextTick(() => {
  964. this.tableList.forEach((course) => {
  965. if (idList.indexOf(course.id) != -1) {
  966. this.$refs.tableList.toggleRowSelection(course, true);
  967. }
  968. });
  969. this.isDetele = false;
  970. });
  971. // let arr = this.$helpers.lodash.differenceWith( this.tableList, this.deleteList,'id')
  972. }
  973. });
  974. },
  975. lookDetail(row) {
  976. // this.maskForm = row;
  977. // 发请求 获取详情 row.id
  978. this.maskForm = row;
  979. this.activeName = "first";
  980. this.classVisible = true;
  981. getTeacherPersonalAttendanceDetail({ courseScheduleId: row.id }).then(
  982. (res) => {
  983. if (res.code == 200) {
  984. this.maskForm = { ...this.maskForm, ...res.data };
  985. this.maskForm.id = row.id;
  986. this.activeName = "first";
  987. this.classVisible = true;
  988. this.isMainGo = this.$refs.filterSearch?.show;
  989. console.log(this.isMainGo);
  990. }
  991. }
  992. );
  993. },
  994. handleClick(tab, event) {
  995. // console.log(tab, event);
  996. },
  997. resetClass(row) {
  998. console.log(row);
  999. this.id = row.id;
  1000. this.show = true;
  1001. },
  1002. closeReset() {
  1003. this.show = false;
  1004. },
  1005. clearAttend(row) {
  1006. this.$confirm("是否清除考勤记录?", "提示", {
  1007. confirmButtonText: "确定",
  1008. cancelButtonText: "取消",
  1009. type: "warning",
  1010. })
  1011. .then(() => {
  1012. cleanAttendance({ courseScheduleIds: row.id }).then((res) => {
  1013. if (res.code == 200) {
  1014. this.$message.success("清除成功");
  1015. this.getList();
  1016. } else {
  1017. this.$message.error(res.msg);
  1018. }
  1019. });
  1020. })
  1021. .catch(() => {});
  1022. },
  1023. // addCompound(row) {
  1024. // this.compoundList.push(row);
  1025. // this.compoundList = [...new Set(this.compoundList)];
  1026. // },
  1027. // isAddCom(row) {
  1028. // let flag = false;
  1029. // this.compoundList.forEach((com) => {
  1030. // if (com.id == row.id) {
  1031. // flag = true;
  1032. // }
  1033. // });
  1034. // return flag;
  1035. // },
  1036. cancleCompound(row) {
  1037. let indexNum = null;
  1038. this.deleteList.forEach((com, index) => {
  1039. if (com.id == row.id) {
  1040. indexNum = index;
  1041. }
  1042. });
  1043. if (indexNum + "") {
  1044. this.deleteList.splice(indexNum, 1);
  1045. }
  1046. this.tableList.forEach((course,index)=>{
  1047. if(course.id == row.id){
  1048. this.$refs.tableList.toggleRowSelection(course,false);
  1049. }
  1050. })
  1051. if(this.deleteList.length <=0){
  1052. this.clearCom()
  1053. }
  1054. },
  1055. clearCom() {
  1056. // this.deleteList = [];
  1057. this.$set(this,'deleteList',[])
  1058. this.$refs.tableList.clearSelection();
  1059. this.$refs.addCompound.isLook = false
  1060. },
  1061. resetCompound(row) {
  1062. this.$confirm("您确定取消合并该课程?", "提示", {
  1063. confirmButtonText: "确定",
  1064. cancelButtonText: "取消",
  1065. type: "warning",
  1066. })
  1067. .then(() => {
  1068. cancelCourseMerge({ mainCourseId: row.id }).then((res) => {
  1069. if (res.code == 200) {
  1070. this.$message.success("提交成功");
  1071. this.getList();
  1072. }
  1073. });
  1074. })
  1075. .catch(() => {});
  1076. },
  1077. handleSelectionChange(arr) {
  1078. // this.deleteList = arr;
  1079. if (arr.length > 0) {
  1080. // 有可能加 有可能减
  1081. this.deleteList = this.deleteList.concat(arr);
  1082. // 去重
  1083. this.deleteList = this.$helpers.lodash.uniqBy(this.deleteList, "id");
  1084. }
  1085. // else if(){}
  1086. else {
  1087. if (this.isDetele) return;
  1088. // 有2种 1是新页
  1089. // 2是点击反选
  1090. let idList = this.deleteList.map((course) => {
  1091. return course.id;
  1092. });
  1093. this.$nextTick(() => {
  1094. let tableIdList = [];
  1095. this.tableList.forEach((course) => {
  1096. tableIdList.push(course.id);
  1097. if (idList.indexOf(course.id) != -1) {
  1098. this.$refs.tableList.toggleRowSelection(course, false);
  1099. // 删除这个元素
  1100. }
  1101. });
  1102. this.deleteList = this.$helpers.lodash.remove(
  1103. this.deleteList,
  1104. function (item) {
  1105. return tableIdList.indexOf(item.id) == -1;
  1106. }
  1107. );
  1108. });
  1109. }
  1110. },
  1111. gotoCourse(row) {
  1112. if (row.groupType == "MUSIC") {
  1113. this.$router.push({
  1114. path: "/teamList",
  1115. query: { search: row.musicGroupId },
  1116. });
  1117. } else if (row.groupType == "VIP") {
  1118. this.$router.push({
  1119. path: "/vipManager/vipList",
  1120. query: { search: row.musicGroupId },
  1121. });
  1122. } else if (row.groupType == "PRACTICE") {
  1123. this.$router.push({
  1124. path: "/accompanyManager/accompany",
  1125. query: { search: row.musicGroupId },
  1126. });
  1127. }
  1128. },
  1129. onTableSelect(rows,row){
  1130. let idList = this.deleteList.map((course) => {
  1131. return course.id;
  1132. });
  1133. if(idList.indexOf(row.id)!= -1){
  1134. this.deleteList.splice(idList.indexOf(row.id),1)
  1135. }
  1136. }
  1137. },
  1138. filters: {
  1139. isCall(val) {
  1140. if (val == 0) {
  1141. return "未点名";
  1142. } else if (val == 1) {
  1143. return "已点名";
  1144. }
  1145. },
  1146. },
  1147. watch: {
  1148. classVisible(val) {
  1149. if (!val) {
  1150. this.activeName = null;
  1151. }
  1152. },
  1153. },
  1154. };
  1155. </script>
  1156. <style lang="scss" scoped>
  1157. .visible {
  1158. visibility: hidden;
  1159. }
  1160. .cl-container {
  1161. .topFrom {
  1162. margin: 20px 30px 0;
  1163. .classlist {
  1164. display: flex;
  1165. flex-direction: row;
  1166. justify-content: flex-start;
  1167. align-items: center;
  1168. ul {
  1169. li {
  1170. list-style: none;
  1171. }
  1172. }
  1173. }
  1174. }
  1175. .searchForm {
  1176. margin: 0 30px;
  1177. }
  1178. }
  1179. .btnWraps {
  1180. display: flex;
  1181. flex-direction: row;
  1182. justify-content: flex-start;
  1183. div {
  1184. margin-right: 20px;
  1185. }
  1186. }
  1187. .inputStyle {
  1188. width: 180px;
  1189. }
  1190. .red {
  1191. color: red;
  1192. }
  1193. .exportBtn {
  1194. background: #13817a;
  1195. }
  1196. .newBand {
  1197. margin-top: 30px;
  1198. }
  1199. </style>