teamCourseList.vue 36 KB

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