index.tsx 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. import { defineComponent, reactive, onMounted, ref, nextTick } from 'vue';
  2. import styles from './index.module.less';
  3. import {
  4. NButton,
  5. NDataTable,
  6. NForm,
  7. NFormItem,
  8. NImage,
  9. NModal,
  10. NSelect,
  11. NSpace,
  12. useDialog,
  13. useMessage
  14. } from 'naive-ui';
  15. import SearchInput from '@/components/searchInput';
  16. import CSelect from '@/components/CSelect';
  17. import Pagination from '@/components/pagination';
  18. import { classGroupList, deleteClass, getSubject,addGroup } from './api';
  19. import CreateClass from './modals/createClass';
  20. import RestStudentBox from './modals/restStudentBox';
  21. import TrainDetail from './modals/Gotoclass';
  22. import { getgradeNumList, classArray } from './contants';
  23. import add from '@/views/studentList/images/add.png';
  24. import ClassGuide from '@/custom-plugins/guide-page/class-guide';
  25. import { useRouter } from 'vue-router';
  26. import { rowDark } from 'naive-ui/es/legacy-grid/styles';
  27. import TheEmpty from '/src/components/TheEmpty';
  28. import TheTooltip from '/src/components/TheTooltip';
  29. import PreviewWindow from '../preview-window';
  30. import { state as globalState } from '/src/state';
  31. import { courseSchedulePage } from '../home/api';
  32. import ResetSubject from './modals/resetSubject';
  33. import { fscreen } from '/src/utils';
  34. import UpdateSubject from './modals/updateSubject';
  35. export default defineComponent({
  36. name: 'class-classList',
  37. setup(props, { emit }) {
  38. const state = reactive({
  39. searchForm: {
  40. keyword: null as any,
  41. currentClass: null,
  42. currentGradeNum: null,
  43. subjectId: null
  44. },
  45. orchestraType: null,
  46. courseTypeCode: null,
  47. loading: false,
  48. pagination: {
  49. page: 1,
  50. rows: 10,
  51. pageTotal: 6
  52. },
  53. gradeNumList: [] as any,
  54. tableList: [] as any,
  55. studentVisible: false,
  56. activeRow: null as any,
  57. showaddClass: false,
  58. goCourseVisiable: false,
  59. removeVisiable: false,
  60. removeRow: {} as any,
  61. previewModal: false,
  62. previewParams: {} as any,
  63. lastCourse: null as any,
  64. subjectList: [] as any,
  65. showResetClass: false,
  66. showSubjectClass: false,
  67. groupVisiable:false
  68. });
  69. const formRef = ref();
  70. const dialog = useDialog();
  71. const message = useMessage();
  72. const router = useRouter();
  73. const search = () => {
  74. state.pagination.page = 1;
  75. getList();
  76. console.log('search', state);
  77. };
  78. const showGuide = ref(false);
  79. state.gradeNumList = getgradeNumList();
  80. const onReset = () => {
  81. state.searchForm = {
  82. keyword: null as any,
  83. currentClass: null,
  84. currentGradeNum: null,
  85. subjectId: null
  86. };
  87. getList();
  88. };
  89. const removeClass = async () => {
  90. try {
  91. await deleteClass({ ids: state.removeRow.id });
  92. getList();
  93. message.success(`删除成功`);
  94. state.removeVisiable = false;
  95. } catch (e) {
  96. console.log(e);
  97. }
  98. };
  99. const getList = async () => {
  100. // classGroupList
  101. state.loading = true;
  102. try {
  103. const res = await classGroupList({
  104. ...state.searchForm,
  105. ...state.pagination
  106. });
  107. state.tableList = res.data.rows;
  108. state.pagination.pageTotal = res.data.total;
  109. state.loading = false;
  110. setTimeout(() => {
  111. if (state.tableList.length > 0) {
  112. showGuide.value = true;
  113. }
  114. }, 500);
  115. } catch (e) {
  116. state.loading = false;
  117. console.log(e);
  118. }
  119. console.log('getList');
  120. };
  121. const getSubjectList = async () => {
  122. const res = await getSubject({ page: 1, rows: 9999 });
  123. state.subjectList = res.data.rows.map((item: any) => {
  124. return {
  125. value: item.id,
  126. label: item.name
  127. };
  128. });
  129. state.subjectList.unshift({ value: null, label: '选择声部' });
  130. };
  131. const columns = () => {
  132. return [
  133. {
  134. title: '班级名称',
  135. key: 'name',
  136. },
  137. {
  138. title: '班级声部',
  139. key: 'subjectName',
  140. },
  141. {
  142. title: '学生人数',
  143. key: 'preStudentNum',
  144. },
  145. {
  146. title: '上次学习',
  147. key: 'lastStudy',
  148. width: '20%',
  149. render(row: any) {
  150. return row.lastStudy ? (
  151. <TheTooltip
  152. maxWidth={300}
  153. showContentWidth={300}
  154. content={row.lastStudy}
  155. />
  156. ) : (
  157. '--'
  158. );
  159. }
  160. },
  161. {
  162. title: '操作',
  163. key: 'id',
  164. render(row: any, index: number) {
  165. return (
  166. <div>
  167. <NSpace>
  168. {index == 0 ? (
  169. <div id="class-0">
  170. <NButton
  171. type="primary"
  172. text
  173. onClick={() => {
  174. router.push({
  175. path: '/classDetail',
  176. query: { name: row.name, id: row.id }
  177. });
  178. }}>
  179. 详情
  180. </NButton>
  181. </div>
  182. ) : (
  183. <NButton
  184. type="primary"
  185. text
  186. onClick={() => {
  187. router.push({
  188. path: '/classDetail',
  189. query: { name: row.name, id: row.id }
  190. });
  191. }}>
  192. 详情
  193. </NButton>
  194. )}
  195. <NButton
  196. type="primary"
  197. text
  198. onClick={() => resetClassSubject(row)}>
  199. 修改声部
  200. </NButton>
  201. {index == 0 ? (
  202. <NButton
  203. type="primary"
  204. {...{ id: 'class-1' }}
  205. text
  206. onClick={() => {
  207. startResetStudent(row);
  208. }}>
  209. 学生调整
  210. </NButton>
  211. ) : (
  212. <NButton
  213. type="primary"
  214. text
  215. onClick={() => {
  216. startResetStudent(row);
  217. }}>
  218. 学生调整
  219. </NButton>
  220. )}
  221. {index == 0 ? (
  222. <NButton
  223. {...{ id: 'class-2' }}
  224. disabled={!(row.preStudentNum > 0)}
  225. type="primary"
  226. text
  227. onClick={() => classesBegin(row)}>
  228. 开始上课
  229. </NButton>
  230. ) : (
  231. <NButton
  232. disabled={!(row.preStudentNum > 0)}
  233. type="primary"
  234. text
  235. onClick={() => classesBegin(row)}>
  236. 开始上课
  237. </NButton>
  238. )}
  239. {!(row.preStudentNum > 0) ? (
  240. <p
  241. style={{ color: '#EA4132', cursor: 'pointer' }}
  242. onClick={() => {
  243. state.removeVisiable = true;
  244. state.removeRow = row;
  245. }}>
  246. 删除
  247. </p>
  248. ) : null}
  249. {row.imGroupId?null: <NButton
  250. type="primary"
  251. text
  252. onClick={() => {
  253. createImgroup(row);
  254. }}>
  255. 创建群聊
  256. </NButton>}
  257. </NSpace>
  258. </div>
  259. );
  260. }
  261. }
  262. ];
  263. };
  264. const startResetStudent = (row: any) => {
  265. state.activeRow = row;
  266. state.studentVisible = true;
  267. };
  268. const classesBegin = async (row: any) => {
  269. try {
  270. console.log(row, 'row');
  271. // 判断是否有声部
  272. if (row.subjectId) {
  273. //
  274. router.push({
  275. path: '/prepare-lessons',
  276. query: {
  277. lastUseCoursewareId: row.lessonCoursewareId,
  278. unit: row.lessonCoursewareKnowledgeDetailId,
  279. subjectId: row.subjectId,
  280. name: row.name, // 班级名称
  281. classGroupId: row.id // 班级编号
  282. }
  283. });
  284. } else {
  285. state.showSubjectClass = true;
  286. state.activeRow = row;
  287. }
  288. } catch (e) {
  289. console.log(e);
  290. }
  291. };
  292. const resetClassSubject = (row: any) => {
  293. state.activeRow = row;
  294. state.showResetClass = true;
  295. };
  296. const createImgroup = async(row:any)=>{
  297. state.activeRow = row
  298. state.groupVisiable = true;
  299. }
  300. const submitGroup = async ()=>{
  301. console.log( state.activeRow,'row')
  302. try{
  303. const res = await addGroup({classGroupId:state.activeRow.id})
  304. message.success('创建成功')
  305. state.groupVisiable = false
  306. getList()
  307. }catch(e){
  308. console.log(e)
  309. }
  310. }
  311. onMounted(() => {
  312. getList();
  313. getSubjectList();
  314. });
  315. return () => (
  316. <div class={styles.listWrap}>
  317. <div class={styles.searchList}>
  318. <NForm label-placement="left" inline ref={formRef}>
  319. <NFormItem>
  320. <SearchInput
  321. {...{ placeholder: '请输入班级名称' }}
  322. class={styles.searchInput}
  323. searchWord={state.searchForm.keyword}
  324. onChangeValue={(val: string) =>
  325. (state.searchForm.keyword = val)
  326. }></SearchInput>
  327. </NFormItem>
  328. <NFormItem>
  329. <CSelect
  330. {...({
  331. options: state.gradeNumList,
  332. placeholder: '选择年级',
  333. clearable: true,
  334. inline: true
  335. } as any)}
  336. v-model:value={state.searchForm.currentGradeNum}></CSelect>
  337. </NFormItem>
  338. <NFormItem>
  339. <CSelect
  340. {...({
  341. options: classArray,
  342. placeholder: '选择班级',
  343. clearable: true,
  344. inline: true
  345. } as any)}
  346. v-model:value={state.searchForm.currentClass}></CSelect>
  347. </NFormItem>
  348. <NFormItem>
  349. <CSelect
  350. {...({
  351. options: state.subjectList,
  352. placeholder: '选择声部',
  353. clearable: true,
  354. inline: true
  355. } as any)}
  356. v-model:value={state.searchForm.subjectId}></CSelect>
  357. </NFormItem>
  358. <NFormItem>
  359. <NSpace justify="end">
  360. <NButton type="primary" class="searchBtn" onClick={search}>
  361. 搜索
  362. </NButton>
  363. <NButton
  364. type="primary"
  365. ghost
  366. class="resetBtn"
  367. onClick={onReset}>
  368. 重置
  369. </NButton>
  370. </NSpace>
  371. </NFormItem>
  372. </NForm>
  373. </div>
  374. <NButton
  375. class={styles.addBtn}
  376. type="primary"
  377. onClick={() => (state.showaddClass = true)}
  378. v-slots={{
  379. icon: () => (
  380. <>
  381. <NImage
  382. class={styles.addBtnIcon}
  383. previewDisabled
  384. src={add}></NImage>
  385. </>
  386. )
  387. }}>
  388. 创建班级
  389. </NButton>
  390. <div class={styles.tableWrap}>
  391. <NDataTable
  392. v-slots={{
  393. empty: () => <TheEmpty></TheEmpty>
  394. }}
  395. class={styles.classTable}
  396. loading={state.loading}
  397. columns={columns()}
  398. data={state.tableList}></NDataTable>
  399. <Pagination
  400. v-model:page={state.pagination.page}
  401. v-model:pageSize={state.pagination.rows}
  402. v-model:pageTotal={state.pagination.pageTotal}
  403. onList={getList}
  404. sync
  405. />
  406. </div>
  407. <NModal
  408. v-model:show={state.studentVisible}
  409. preset="card"
  410. class={['modalTitle background', styles.studentVisible]}
  411. title={'学员调整'}>
  412. <RestStudentBox
  413. activeRow={state.activeRow}
  414. onClose={() => (state.studentVisible = false)}
  415. onGetList={() => getList()}></RestStudentBox>
  416. </NModal>
  417. <NModal
  418. v-model:show={state.showaddClass}
  419. style={{ width: '500px' }}
  420. display-directive='if'
  421. preset="card"
  422. class={['modalTitle background']}
  423. title={'创建班级'}>
  424. <CreateClass
  425. gradeNumList={state.gradeNumList}
  426. classArray={classArray}
  427. subjectList={state.subjectList}
  428. onGetList={() => getList()}
  429. onClose={() => (state.showaddClass = false)}
  430. />
  431. </NModal>
  432. <NModal
  433. v-model:show={state.showResetClass}
  434. style={{ width: '500px' }}
  435. display-directive='if'
  436. preset="card"
  437. class={['modalTitle background']}
  438. title={'修改声部'}>
  439. <ResetSubject
  440. activeRow={state.activeRow}
  441. subjectList={state.subjectList}
  442. onGetList={() => getList()}
  443. onClose={() => (state.showResetClass = false)}
  444. />
  445. </NModal>
  446. <NModal
  447. v-model:show={state.showSubjectClass}
  448. style={{ width: '500px' }}
  449. preset="card"
  450. class={['modalTitle background']}
  451. title={'修改声部'}>
  452. {state.showSubjectClass ? (
  453. <UpdateSubject
  454. activeRow={state.activeRow}
  455. onGetList={() => getList()}
  456. onConfirm={(item: any) => {
  457. //
  458. router.push({
  459. path: '/prepare-lessons',
  460. query: {
  461. ...item
  462. }
  463. });
  464. }}
  465. onClose={() => (state.showSubjectClass = false)}
  466. />
  467. ) : null}
  468. </NModal>
  469. {/* 上课弹窗 */}
  470. <PreviewWindow
  471. v-model:show={state.previewModal}
  472. type="attend"
  473. params={state.previewParams}
  474. />
  475. <NModal
  476. v-model:show={state.removeVisiable}
  477. preset="card"
  478. class={['modalTitle', styles.removeVisiable]}
  479. title={'删除班级'}>
  480. <div class={styles.studentRemove}>
  481. <p>
  482. 确定要删除班级么?
  483. <span>删除班级信息将会清空</span>。
  484. </p>
  485. <NSpace class={styles.btnGroup} justify="center">
  486. <NButton round type="primary" onClick={removeClass}>
  487. 确定
  488. </NButton>
  489. <NButton round onClick={() => (state.removeVisiable = false)}>
  490. 取消
  491. </NButton>
  492. </NSpace>
  493. </div>
  494. </NModal>
  495. <NModal
  496. v-model:show={state.groupVisiable}
  497. preset="card"
  498. class={['modalTitle', styles.removeVisiable]}
  499. title={'创建群聊'}>
  500. <div class={styles.studentRemove}>
  501. <p>
  502. 是否创建班级群聊
  503. </p>
  504. <NSpace class={styles.btnGroup} justify="center">
  505. <NButton round type="primary" onClick={submitGroup}>
  506. 确定
  507. </NButton>
  508. <NButton round onClick={() => (state.groupVisiable = false)}>
  509. 取消
  510. </NButton>
  511. </NSpace>
  512. </div>
  513. </NModal>
  514. {showGuide.value ? <ClassGuide></ClassGuide> : null}
  515. </div>
  516. );
  517. }
  518. });