restStudentBox.tsx 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. import {
  2. NButton,
  3. NSpace,
  4. useMessage,
  5. NCheckboxGroup,
  6. NCheckbox,
  7. NRow,
  8. NImage,
  9. NInput,
  10. NScrollbar,
  11. NDropdown
  12. } from 'naive-ui';
  13. import { computed, defineComponent, onMounted, reactive, ref } from 'vue';
  14. import styles from '../index.module.less';
  15. import SearchInput from '@/components/searchInput';
  16. import smallArrow from '../images/smallArrow.png';
  17. import transArrrow from '../images/transArrrow.png';
  18. import transArrowActive from '../images/transArrowActive.png';
  19. import { getCLassStudent, classGroupList, adjustStudent } from '../api';
  20. export default defineComponent({
  21. props: {
  22. activeRow: {
  23. type: Object,
  24. default: () => ({ id: '' })
  25. }
  26. },
  27. name: 'RestStudentBox',
  28. emits: ['close', 'getList'],
  29. setup(props, { emit }) {
  30. const message = useMessage();
  31. const data = reactive({
  32. uploading: false
  33. });
  34. const options = ref([] as any);
  35. const chioseOptions = ref([] as any);
  36. const formRef = ref();
  37. const handleSubmit = async () => {
  38. data.uploading = true;
  39. };
  40. const classList = ref([] as any);
  41. console.log(props.activeRow, 'activeRow');
  42. const targetClass = reactive({
  43. name: '',
  44. id: ''
  45. });
  46. const currentchioseStudent = ref([] as any);
  47. const currentStudentList = ref([] as any);
  48. const currentSearch = ref(null as any);
  49. const targetchioseStudent = ref([] as any);
  50. const targetStudentList = ref([] as any);
  51. const targetSearch = ref(null as any);
  52. //
  53. const submitList = ref([] as any);
  54. /**
  55. * 这里干3件事 1.获取当前班的学生
  56. * 2.查询所有的班级列表 并且排查当前班级
  57. * 3.默认选择第一个班级 并且查出此班的学生
  58. */
  59. const chioseStudnet = (val: any) => {
  60. console.log(val);
  61. };
  62. const getAllClassList = async () => {
  63. try {
  64. const res = await classGroupList({
  65. page: 1,
  66. rows: 9999,
  67. upgradeFlag: true
  68. });
  69. classList.value = res.data.rows.map((item: any) => {
  70. return {
  71. label: item.name,
  72. key: item.id,
  73. disabled: item.id == props.activeRow.id
  74. };
  75. });
  76. if (classList.value[0].disabled) {
  77. targetClass.name = classList.value[1].label;
  78. targetClass.id = classList.value[1].key;
  79. } else {
  80. targetClass.name = classList.value[0].label;
  81. targetClass.id = classList.value[0].key;
  82. }
  83. const tarRes = await getCLassStudentList(targetClass.id);
  84. targetStudentList.value = tarRes.data.rows.map((item: any) => {
  85. return {
  86. label: item.nickname + '(' + item.id + ')',
  87. value: item.id
  88. };
  89. });
  90. } catch (e) {
  91. console.log(e);
  92. }
  93. };
  94. const getCLassStudentList = async (id: string | number) => {
  95. return await getCLassStudent({
  96. page: 1,
  97. rows: 999,
  98. classGroupId: id
  99. });
  100. };
  101. const chioseClass = async (val: any) => {
  102. classList.value.forEach((item: any) => {
  103. if (item.key == val) {
  104. targetClass.name = item.label;
  105. targetClass.id = item.key;
  106. }
  107. });
  108. const res = await getCLassStudentList(val);
  109. targetStudentList.value = res.data.rows.map((item: any) => {
  110. return {
  111. label: item.nickname + '(' + item.id + ')',
  112. value: item.id
  113. };
  114. });
  115. console.log(submitList.value, 'submitList.value');
  116. // 判断一下 targetStudentList.value 和 submitList 对比
  117. targetStudentList.value = targetStudentList.value.filter(
  118. (item: any) =>
  119. !submitList.value.some((ele: any) => ele.value === item.value)
  120. );
  121. // 如果 如果submitList 学生的toClassId 和targetClassId相同 则添加
  122. submitList.value.forEach((ele: any) => {
  123. if (ele.toClassId == targetClass.id) {
  124. console.log(ele.toClassId, ele);
  125. targetStudentList.value.push({
  126. label: ele.label,
  127. value: ele.value
  128. });
  129. }
  130. });
  131. // 有2下 如果submitList 学生 和 targetStudentList 学生id相同 则删除
  132. };
  133. const currentFitterList = computed(() => {
  134. const oraginArr = currentStudentList.value || [];
  135. const list = oraginArr.filter((item: any) => {
  136. return item.label.indexOf(currentSearch.value || '') != -1;
  137. });
  138. return list;
  139. });
  140. const targetFitterList = computed(() => {
  141. const oraginArr = targetStudentList.value || [];
  142. const list = oraginArr.filter((item: any) => {
  143. return item.label.indexOf(targetSearch.value || '') != -1;
  144. });
  145. return list;
  146. });
  147. const chioseAllCurrentStudent = () => {
  148. if (
  149. currentFitterList.value.length === currentchioseStudent.value.length
  150. ) {
  151. // 说明要取消全选
  152. currentchioseStudent.value = [];
  153. } else {
  154. currentchioseStudent.value = currentFitterList.value.map(
  155. (item: any) => {
  156. return item.value;
  157. }
  158. );
  159. // 全选
  160. }
  161. };
  162. const chioseAllTargetStudent = () => {
  163. if (targetFitterList.value.length === targetchioseStudent.value.length) {
  164. // 说明要取消全选
  165. targetchioseStudent.value = [];
  166. } else {
  167. targetchioseStudent.value = targetFitterList.value.map((item: any) => {
  168. return item.value;
  169. });
  170. // 全选
  171. }
  172. };
  173. const toTargetList = () => {
  174. const subStudetn = currentStudentList.value.filter((item: any) => {
  175. return currentchioseStudent.value.indexOf(item.value) != -1;
  176. });
  177. if (subStudetn.length > 0) {
  178. const arr = subStudetn.map((item: any) => {
  179. return {
  180. ...item,
  181. studentId: item.value,
  182. toClassId: targetClass.id
  183. };
  184. });
  185. submitList.value = submitList.value.filter(
  186. (item: any) => !arr.some((ele: any) => ele.value === item.value)
  187. );
  188. submitList.value = submitList.value.concat(arr);
  189. }
  190. // 接下来 删除 currentStudentList里的这三个学生
  191. currentStudentList.value = currentStudentList.value.filter(
  192. (item: any) => !subStudetn.some((ele: any) => ele.value === item.value)
  193. );
  194. subStudetn.forEach((item: any) => {
  195. targetStudentList.value.push(item);
  196. });
  197. currentchioseStudent.value = [];
  198. };
  199. const toCurrentList = () => {
  200. const subStudetn = targetStudentList.value.filter((item: any) => {
  201. return targetchioseStudent.value.indexOf(item.value) != -1;
  202. });
  203. if (subStudetn.length > 0) {
  204. const arr = subStudetn.map((item: any) => {
  205. return {
  206. ...item,
  207. studentId: item.value,
  208. toClassId: props.activeRow.id
  209. };
  210. });
  211. submitList.value = submitList.value.filter(
  212. (item: any) => !arr.some((ele: any) => ele.value === item.value)
  213. );
  214. submitList.value = submitList.value.concat(arr);
  215. }
  216. targetStudentList.value = targetStudentList.value.filter(
  217. (item: any) => !subStudetn.some((ele: any) => ele.value === item.value)
  218. );
  219. subStudetn.forEach((item: any) => {
  220. currentStudentList.value.push(item);
  221. });
  222. targetchioseStudent.value = [];
  223. // 过去 所以
  224. console.log(submitList.value, ' submitList.value===>');
  225. };
  226. const submitStudent = async () => {
  227. if (classList.value.length < 2) {
  228. message.error('当前只有一个班级,无法调整');
  229. return;
  230. }
  231. if (submitList.value < 1) {
  232. emit('close');
  233. return;
  234. }
  235. try {
  236. const res = await adjustStudent(submitList.value);
  237. emit('close');
  238. emit('getList');
  239. } catch (e) {
  240. console.log(e);
  241. }
  242. };
  243. onMounted(async () => {
  244. getAllClassList();
  245. const res = await getCLassStudentList(props.activeRow.id as string);
  246. currentStudentList.value = res.data.rows.map((item: any) => {
  247. return {
  248. label: item.nickname + '(' + item.id + ')',
  249. value: item.id
  250. };
  251. });
  252. });
  253. return () => (
  254. <div class={[styles.container, styles.resetStudentWrap]}>
  255. <div class={styles.studentTransfer}>
  256. <div class={styles.studentTransferList}>
  257. <div class={styles.studentLeft}>
  258. <div class={styles.listTop}>
  259. <p>{props.activeRow.name}</p>
  260. <span>(当前班级)</span>
  261. </div>
  262. <div class={styles.listCore}>
  263. <NRow class={styles.chioseCheckAllBox}>
  264. <NCheckbox
  265. onUpdateChecked={val => {
  266. chioseAllCurrentStudent();
  267. }}
  268. checked={
  269. currentFitterList.value.length ===
  270. currentchioseStudent.value.length
  271. }
  272. indeterminate={
  273. currentchioseStudent.value.length > 0 &&
  274. currentFitterList.value.length !==
  275. currentchioseStudent.value.length
  276. }
  277. label="全选"></NCheckbox>
  278. </NRow>
  279. <NRow>
  280. <SearchInput
  281. {...{ placeholder: '请输入学生姓名' }}
  282. class={styles.searchInput}
  283. searchWord={currentSearch.value}
  284. onChangeValue={(val: string) =>
  285. (currentSearch.value = val)
  286. }></SearchInput>
  287. </NRow>
  288. <NScrollbar style="max-height: 204px;min-height: 204px;margin-top:14px;">
  289. <NCheckboxGroup v-model:value={currentchioseStudent.value}>
  290. {currentFitterList.value.map((item: any) => (
  291. <NRow class={styles.chioseCheckBox}>
  292. <NCheckbox
  293. value={item.value}
  294. label={item.label}></NCheckbox>
  295. </NRow>
  296. ))}
  297. </NCheckboxGroup>
  298. </NScrollbar>
  299. </div>
  300. <div class={[styles.bottomLeft, styles.bottom]}>
  301. <div class={styles.bottomWrap}>
  302. 共{currentStudentList.value.length}名学生
  303. </div>
  304. </div>
  305. </div>
  306. <div class={styles.chioseBox}>
  307. <div
  308. class={[styles.chioseBtn, styles.chioseBtnRight]}
  309. onClick={() => toTargetList()}></div>
  310. <div
  311. class={styles.chioseBtn}
  312. onClick={() => toCurrentList()}></div>
  313. </div>
  314. <div class={styles.studentRight}>
  315. <div class={styles.listTop}>
  316. {targetClass.id ? (
  317. <NDropdown
  318. key="111"
  319. v-model:value={targetClass.id}
  320. options={classList.value}
  321. onSelect={(value: any) => {
  322. chioseClass(value);
  323. }}
  324. scrollable>
  325. <div>
  326. {targetClass.name}
  327. <NImage
  328. class={styles.smallArrow}
  329. src={smallArrow}
  330. previewDisabled></NImage>
  331. </div>
  332. </NDropdown>
  333. ) : null}
  334. </div>
  335. <div class={styles.listCore}>
  336. <NRow class={styles.chioseCheckAllBox}>
  337. <NCheckbox
  338. onUpdateChecked={val => {
  339. chioseAllTargetStudent();
  340. }}
  341. checked={
  342. targetFitterList.value.length ===
  343. targetchioseStudent.value.length
  344. }
  345. indeterminate={
  346. targetchioseStudent.value.length > 0 &&
  347. targetFitterList.value.length !==
  348. targetchioseStudent.value.length
  349. }
  350. label="全选"></NCheckbox>
  351. </NRow>
  352. <NRow>
  353. <SearchInput
  354. {...{ placeholder: '请输入学生姓名' }}
  355. class={styles.searchInput}
  356. searchWord={targetSearch.value}
  357. onChangeValue={(val: string) =>
  358. (targetSearch.value = val)
  359. }></SearchInput>
  360. </NRow>
  361. <NScrollbar style="max-height: 204px;min-height: 204px;margin-top:14px;">
  362. <NCheckboxGroup v-model:value={targetchioseStudent.value}>
  363. {targetFitterList.value.map((item: any) => (
  364. <NRow class={styles.chioseCheckBox}>
  365. <NCheckbox
  366. value={item.value}
  367. label={item.label}></NCheckbox>
  368. </NRow>
  369. ))}
  370. </NCheckboxGroup>
  371. </NScrollbar>
  372. </div>
  373. <div class={[styles.bottomRight, styles.bottom]}>
  374. <div class={styles.bottomWrap}>
  375. 共{targetStudentList.value.length}名学生
  376. </div>
  377. </div>
  378. </div>
  379. </div>
  380. </div>
  381. <NSpace class={styles.btnGroup} justify="center">
  382. <NButton round onClick={() => emit('close')}>
  383. 取消
  384. </NButton>
  385. <NButton
  386. round
  387. loading={data.uploading}
  388. type="primary"
  389. onClick={() => {
  390. submitStudent();
  391. }}>
  392. 保存
  393. </NButton>
  394. </NSpace>
  395. </div>
  396. );
  397. }
  398. });