teamCourseList.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. <template>
  2. <div class="m-container">
  3. <h2>
  4. <div class="squrt"></div>课表列表
  5. </h2>
  6. <div class="m-core">
  7. <!-- 搜索类型 -->
  8. <el-form :inline="true"
  9. class="searchForm"
  10. v-model.trim="searchForm">
  11. <el-form-item>
  12. <el-input style="width: 240px"
  13. v-model.trim="searchForm.search"
  14. @keyup.enter.native="search"
  15. placeholder="课程组编号/课程编号/课程名称" />
  16. </el-form-item>
  17. <el-form-item>
  18. <el-select v-model.trim="searchForm.schoolId"
  19. clearable
  20. filterable
  21. placeholder="请选择教学点">
  22. <el-option v-for="(item, index) in schoolList"
  23. :key="index"
  24. :value="item.id"
  25. :label="item.name"></el-option>
  26. </el-select>
  27. </el-form-item>
  28. <el-form-item>
  29. <el-select v-model.trim="searchForm.teacherIdList"
  30. clearable
  31. filterable
  32. placeholder="请选择老师">
  33. <el-option v-for="(item, index) in teacherList"
  34. :key="index"
  35. :value="item.id"
  36. :label="item.realName"></el-option>
  37. </el-select>
  38. </el-form-item>
  39. <el-form-item>
  40. <el-select class="multiple"
  41. v-model.trim="searchForm.organIdList"
  42. filterable
  43. clearable
  44. placeholder="请选择分部">
  45. <el-option v-for="(item,index) in organList"
  46. :key="index"
  47. :label="item.name"
  48. :value="item.id"></el-option>
  49. </el-select>
  50. </el-form-item>
  51. <el-form-item>
  52. <el-select v-model.trim="searchForm.courseType"
  53. clearable
  54. filterable
  55. placeholder="课程类型">
  56. <el-option v-for="(item, index) in courseType"
  57. :key="index"
  58. :value="item.value"
  59. :label="item.label"></el-option>
  60. </el-select>
  61. </el-form-item>
  62. <el-form-item>
  63. <el-select v-model.trim="searchForm.courseStatus"
  64. clearable
  65. filterable
  66. placeholder="课程状态">
  67. <el-option label="未开始"
  68. value="NOT_START"></el-option>
  69. <el-option label="进行中"
  70. value="UNDERWAY"></el-option>
  71. <el-option label="已结束"
  72. value="OVER"></el-option>
  73. </el-select>
  74. </el-form-item>
  75. <el-form-item>
  76. <el-date-picker v-model.trim="searchForm.timer"
  77. style="width:420px;"
  78. type="daterange"
  79. value-format="yyyy-MM-dd"
  80. range-separator="至"
  81. start-placeholder="开始日期"
  82. end-placeholder="结束日期"></el-date-picker>
  83. </el-form-item>
  84. <el-form-item>
  85. <div class="searchBtn"
  86. @click="search">搜索</div>
  87. </el-form-item>
  88. <el-form-item>
  89. <div class="searchBtn exportBtn"
  90. v-permission="'export/superFindCourseSchedules'"
  91. @click="onCourseExport">导出课表</div>
  92. </el-form-item>
  93. </el-form>
  94. <div class="btnWraps"></div>
  95. <!-- 列表 -->
  96. <div class="tableWrap">
  97. <el-table :data="tableList"
  98. :header-cell-style="{background:'#EDEEF0',color:'#444'}">
  99. <el-table-column align="center"
  100. prop="organName"
  101. label="分部名称"></el-table-column>
  102. <el-table-column align="center"
  103. width="130px"
  104. prop="musicGroupId"
  105. label="乐团/课程组编号"></el-table-column>
  106. <el-table-column align="center"
  107. prop="id"
  108. label="课程编号"></el-table-column>
  109. <el-table-column align="center"
  110. width="200px"
  111. label="时间">
  112. <template slot-scope="scope">{{ scope.row.startClassTime ? scope.row.startClassTime.substr(0, 16) : '' }}-{{ scope.row.endClassTime ? scope.row.endClassTime.substr(11,5) : ''}}</template>
  113. </el-table-column>
  114. <!-- <el-table-column align="center" prop="groupName" label="乐团/VIP名"></el-table-column> -->
  115. <!-- <el-table-column align="center" prop="classGroupName" label="班级名称"></el-table-column> -->
  116. <el-table-column align="center"
  117. prop="studentId"
  118. label="学生ID">
  119. <template slot-scope="scope">
  120. <div v-if="scope.row.groupType != 'MUSIC'">{{scope.row.studentId}}</div>
  121. </template>
  122. </el-table-column>
  123. <el-table-column align="center"
  124. prop="subjectName"
  125. label="声部"></el-table-column>
  126. <el-table-column align="center"
  127. prop="name"
  128. label="课程名称"></el-table-column>
  129. <el-table-column align="center"
  130. label="课程类型">
  131. <template slot-scope="scope">
  132. <div>{{ scope.row.type | coursesType}}</div>
  133. </template>
  134. </el-table-column>
  135. <el-table-column align="center"
  136. label="教学模式">
  137. <template slot-scope="scope">
  138. <div>{{ scope.row.teachMode | teachMode}}</div>
  139. </template>
  140. </el-table-column>
  141. <el-table-column align="center"
  142. prop="schoolName"
  143. label="教学点">
  144. <template slot-scope="scope">
  145. <div>{{scope.row.schoolName?scope.row.schoolName:'网络教室'}}</div>
  146. </template>
  147. </el-table-column>
  148. <el-table-column align="center"
  149. prop="courseScheduleStatus"
  150. label="课程状态">
  151. <template slot-scope="scope">
  152. <div>{{ scope.row.status | coursesStatus }}</div>
  153. </template>
  154. </el-table-column>
  155. <!-- <el-table-column align="center"
  156. label="是否签到">
  157. <template slot-scope="scope">
  158. <div>{{ scope.row.isSignIn | attendanceType}}</div>
  159. </template>
  160. </el-table-column> -->
  161. <!-- <el-table-column align="center"
  162. label="是否签退"
  163. fixed="right">
  164. <template slot-scope="scope">
  165. <div>{{ scope.row.isSignOut | attendanceOutType}}</div>
  166. </template>
  167. </el-table-column> -->
  168. <!-- <el-table-column align="center"
  169. prop="isCallNames"
  170. label="是否点名"
  171. fixed="right">
  172. <template slot-scope="scope">{{ scope.row.isCallNames ? '是' : '否' }}</template>
  173. </el-table-column> -->
  174. <el-table-column align="center"
  175. prop="teacherName"
  176. label="指导老师"
  177. fixed="right"></el-table-column>
  178. <el-table-column align="center"
  179. label="详情"
  180. fixed="right"
  181. width="120px">
  182. <template slot-scope="scope">
  183. <div>
  184. <el-button type="text"
  185. v-if="permission('teamCourseList/details')"
  186. @click="lookDetail(scope.row)">详情</el-button>
  187. </div>
  188. </template>
  189. </el-table-column>
  190. </el-table>
  191. <pagination :total="rules.total"
  192. :page.sync="rules.page"
  193. :limit.sync="rules.limit"
  194. :page-sizes="rules.page_size"
  195. @pagination="getList" />
  196. </div>
  197. </div>
  198. <el-dialog title="课表详情"
  199. :visible.sync="classVisible"
  200. :before-close="closeClassVisible"
  201. width="1000px">
  202. <el-form :model="maskForm"
  203. :inline="true">
  204. <el-form-item label="老师姓名">
  205. <!-- <el-input v-model.trim="maskForm.teacherName"
  206. disabled></el-input>-->
  207. <div class="inputStyle">{{maskForm.teacherName}}</div>
  208. </el-form-item>
  209. <el-form-item label="课程模式">
  210. <!-- <el-input :value="maskForm.teachMode | teachMode"
  211. disabled></el-input>-->
  212. <div class="inputStyle">{{maskForm.teachMode| teachMode}}</div>
  213. <!-- <span>{{maskForm.teachMode }}</span> -->
  214. </el-form-item>
  215. <el-form-item label="课程类型">
  216. <!-- <el-input :value="maskForm.type |classType"
  217. disabled></el-input>-->
  218. <div class="inputStyle">{{maskForm.type|coursesType}}</div>
  219. </el-form-item>
  220. <!-- courseScheduleStatus -->
  221. <el-form-item label="课程状态">
  222. <!-- <el-input :value="maskForm.type |classType"
  223. disabled></el-input>-->
  224. <div class="inputStyle">{{maskForm.status | coursesStatus}}</div>
  225. </el-form-item>
  226. <el-form-item label="签到时间">
  227. <!-- <el-input v-model.trim=" maskForm.signInTime"
  228. disabled></el-input>-->
  229. <div class="inputStyle">{{maskForm.signInTime | dateForMinFormat}}</div>
  230. </el-form-item>
  231. <el-form-item label="签退时间">
  232. <!-- <el-input v-model.trim="maskForm.signOutTime"
  233. disabled></el-input>-->
  234. <div class="inputStyle">{{maskForm.signOutTime | dateForMinFormat}}</div>
  235. </el-form-item>
  236. <el-form-item label="是否点名">
  237. <!-- <el-input :value="maskForm.isCallNames | isCall"
  238. disabled></el-input>-->
  239. <div class="inputStyle">{{maskForm.isCallNames | isCall}}</div>
  240. </el-form-item>
  241. <el-form-item label="签到状态">
  242. <!-- <el-input :value=" maskForm.isSignIn | attendanceType"
  243. disabled></el-input>-->
  244. <div class="inputStyle"
  245. :class="maskForm.isSignIn==1?'':'red'">{{ maskForm.isSignIn | attendanceType}}</div>
  246. </el-form-item>
  247. <el-form-item label="签退状态">
  248. <!-- <el-input :value=" maskForm.isSignOut | attendanceOutType"
  249. disabled></el-input>-->
  250. <div class="inputStyle"
  251. :class="maskForm.isSignIn==1?'':'red'">{{ maskForm.isSignOut | attendanceOutType}}</div>
  252. </el-form-item>
  253. <el-form-item label="备注">
  254. <!-- <el-input :value=" maskForm.isSignOut | attendanceOutType"
  255. disabled></el-input>-->
  256. <div class="inputStyle">{{ maskForm.remark}}</div>
  257. </el-form-item>
  258. </el-form>
  259. <el-tabs v-model.trim="activeName"
  260. v-if="maskForm.status != 'NOT_START'"
  261. type="card"
  262. @tab-click="handleClick">
  263. <el-tab-pane label="点名"
  264. name="first">
  265. <div v-if="activeName == 'first'">
  266. <!-- studentRollCall -->
  267. <studentRollCall :courseScheduleId="maskForm.id"></studentRollCall>
  268. </div>
  269. </el-tab-pane>
  270. <el-tab-pane label="GPS定位"
  271. v-if="maskForm.teachMode == 'OFFLINE'"
  272. name="second">
  273. <div v-if="activeName == 'second'">
  274. <gpsLoction :courseScheduleId="maskForm.id"></gpsLoction>
  275. </div>
  276. </el-tab-pane>
  277. <el-tab-pane label="作业"
  278. v-if="maskForm.type != 'VIP'"
  279. name="third">
  280. <div v-if="activeName == 'third'">
  281. <studentWork :courseScheduleId="maskForm.id"></studentWork>
  282. </div>
  283. </el-tab-pane>
  284. <el-tab-pane label="评论"
  285. v-if="maskForm.type == 'VIP' || maskForm.type == 'PRACTICE'"
  286. name="four">
  287. <div v-if="activeName == 'four'">
  288. <courseEvaluate :courseScheduleId="maskForm.id"></courseEvaluate>
  289. </div>
  290. </el-tab-pane>
  291. </el-tabs>
  292. </el-dialog>
  293. </div>
  294. </template>
  295. <script>
  296. import pagination from "@/components/Pagination/index";
  297. import {
  298. getTeacher,
  299. getMusicGroupAllClass,
  300. superFindCourseSchedules,
  301. getEmployeeOrgan
  302. } from "@/api/buildTeam";
  303. import { getTeacherPersonalAttendanceDetail } from "@/api/teacherManager";
  304. import { getSchool } from "@/api/systemManage";
  305. import { courseType } from "@/utils/searchArray";
  306. import studentRollCall from "./componentCourse/studentRollCall";
  307. import gpsLoction from "./componentCourse/gpsLocation";
  308. import studentWork from "./componentCourse/studentWork";
  309. import courseEvaluate from "./componentCourse/courseEvaluate";
  310. import { permission } from "@/utils/directivePage";
  311. import axios from "axios";
  312. import { getToken } from "@/utils/auth";
  313. import load from "@/utils/loading";
  314. let nowTime = new Date();
  315. nowTime =
  316. nowTime.getFullYear() +
  317. "-" +
  318. (nowTime.getMonth() + 1) +
  319. "-" +
  320. nowTime.getDate();
  321. export default {
  322. data () {
  323. return {
  324. classVisible: false,
  325. timerVisible: false,
  326. courseVisible: false,
  327. courseType: courseType,
  328. searchForm: {
  329. organIdList: null,
  330. courseStatus: null,
  331. courseType: null,
  332. timer: [nowTime, nowTime], // 时间
  333. class: null,
  334. search: null, // 乐团名称 编号 vip课名称
  335. teacherIdList: null, // 老师编号
  336. schoolId: null // 教学点编号
  337. },
  338. tableList: [],
  339. searchLsit: [],
  340. organList: [],
  341. rules: {
  342. // 分页规则
  343. limit: 10, // 限制显示条数
  344. page: 1, // 当前页
  345. total: 0, // 总条数
  346. page_size: [10, 20, 40, 50] // 选择限制显示条数
  347. },
  348. teacherList: [],
  349. schoolList: [],
  350. maskForm: {},
  351. activeName: "first"
  352. // classList: []
  353. };
  354. },
  355. components: {
  356. pagination,
  357. studentRollCall,
  358. gpsLoction,
  359. studentWork,
  360. courseEvaluate
  361. },
  362. activated () {
  363. this.init();
  364. },
  365. mounted () {
  366. this.init();
  367. },
  368. methods: {
  369. init () {
  370. this.getList();
  371. // 获取所有老师
  372. getTeacher().then(res => {
  373. if (res.code == 200) {
  374. this.teacherList = res.data;
  375. }
  376. });
  377. // 获取教学点
  378. getSchool().then(res => {
  379. if (res.code == 200) {
  380. this.schoolList = res.data;
  381. }
  382. });
  383. getEmployeeOrgan().then(res => {
  384. if (res.code == 200) {
  385. this.organList = res.data;
  386. }
  387. });
  388. },
  389. permission (str, parent) {
  390. return permission(str, parent);
  391. },
  392. search () {
  393. this.rules.page = 1;
  394. this.getList();
  395. },
  396. onCourseExport () {
  397. // 课表导出
  398. let searchForm = this.searchForm;
  399. if (!searchForm.timer || searchForm.timer.length <= 0) {
  400. searchForm.timer = [];
  401. this.$message.error("请选择时间段");
  402. return;
  403. }
  404. let obj = {
  405. courseStatus: searchForm.courseStatus || null,
  406. courseType: searchForm.courseType || null,
  407. startTime: searchForm.timer[0] || null,
  408. endTime: searchForm.timer[1] || null,
  409. classGroupId: searchForm.class || null,
  410. organIdList: searchForm.organIdList || null,
  411. search: searchForm.search || null,
  412. teacherIdList: searchForm.teacherIdList || null,
  413. schoolId: searchForm.schoolId || null
  414. };
  415. let url = "/api-web/export/superFindCourseSchedules";
  416. const options = {
  417. method: "get",
  418. headers: {
  419. Authorization: getToken()
  420. },
  421. params: obj,
  422. url,
  423. responseType: "blob"
  424. };
  425. this.$confirm("您确定导出报表", "提示", {
  426. confirmButtonText: "确定",
  427. cancelButtonText: "取消",
  428. type: "warning"
  429. })
  430. .then(() => {
  431. load.startLoading();
  432. axios(options)
  433. .then(res => {
  434. let blob = new Blob([res.data], {
  435. // type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
  436. type: "application/vnd.ms-excel;charset=utf-8"
  437. //word文档为application/msword,pdf文档为application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8
  438. });
  439. let text = new Response(blob).text();
  440. text.then(res => {
  441. // 判断是否报错
  442. if (res.indexOf("code") != -1) {
  443. let json = JSON.parse(res);
  444. this.$message.error(json.msg);
  445. } else {
  446. let objectUrl = URL.createObjectURL(blob);
  447. let link = document.createElement("a");
  448. let fname = "课表列表" + new Date().getTime(); //下载文件的名字
  449. link.href = objectUrl;
  450. link.setAttribute("download", fname);
  451. document.body.appendChild(link);
  452. link.click();
  453. }
  454. });
  455. load.endLoading();
  456. })
  457. .catch(error => {
  458. this.$message.error("导出数据失败,请联系管理员");
  459. load.endLoading();
  460. });
  461. })
  462. .catch(() => { });
  463. },
  464. getList () {
  465. let searchForm = this.searchForm;
  466. if (!searchForm.timer || searchForm.timer.length <= 0) {
  467. searchForm.timer = [];
  468. this.$message.error("请选择时间段");
  469. return;
  470. }
  471. let obj = {
  472. courseStatus: searchForm.courseStatus || null,
  473. courseType: searchForm.courseType || null,
  474. startTime: searchForm.timer[0] || null,
  475. endTime: searchForm.timer[1] || null,
  476. page: this.rules.page,
  477. rows: this.rules.limit,
  478. classGroupId: searchForm.class || null,
  479. organIdList: searchForm.organIdList || null,
  480. search: searchForm.search || null,
  481. teacherIdList: searchForm.teacherIdList || null,
  482. schoolId: searchForm.schoolId || null
  483. };
  484. superFindCourseSchedules(obj).then(res => {
  485. if (res.code == 200) {
  486. this.tableList = res.data.rows;
  487. this.rules.total = res.data.total;
  488. }
  489. });
  490. },
  491. lookDetail (row) {
  492. // this.maskForm = row;
  493. this.activeName = "first";
  494. // 发请求 获取详情 row.id
  495. getTeacherPersonalAttendanceDetail({ courseScheduleId: row.id }).then(res => {
  496. if (res.code == 200) {
  497. this.activeName = "first";
  498. this.maskForm = res.data;
  499. this.maskForm.id = row.id;
  500. this.classVisible = true;
  501. }
  502. })
  503. },
  504. handleClick (tab, event) {
  505. // console.log(tab, event);
  506. },
  507. closeClassVisible () {
  508. this.activeName = null;
  509. this.classVisible = false;
  510. }
  511. },
  512. filters: {
  513. isCall (val) {
  514. if (val == 0) {
  515. return "未点名";
  516. } else if (val == 1) {
  517. return "已点名";
  518. }
  519. }
  520. }
  521. };
  522. </script>
  523. <style lang="scss" scoped>
  524. .visible {
  525. visibility: hidden;
  526. }
  527. .cl-container {
  528. .topFrom {
  529. margin: 20px 30px 0;
  530. .classlist {
  531. display: flex;
  532. flex-direction: row;
  533. justify-content: flex-start;
  534. align-items: center;
  535. ul {
  536. li {
  537. list-style: none;
  538. }
  539. }
  540. }
  541. }
  542. .searchForm {
  543. margin: 0 30px;
  544. }
  545. }
  546. .btnWraps {
  547. display: flex;
  548. flex-direction: row;
  549. justify-content: flex-start;
  550. div {
  551. margin-right: 20px;
  552. }
  553. }
  554. .inputStyle {
  555. width: 180px;
  556. }
  557. .red {
  558. color: red;
  559. }
  560. .exportBtn {
  561. background: #13817a;
  562. }
  563. </style>