DetailData.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import {
  2. PropType,
  3. computed,
  4. defineComponent,
  5. onMounted,
  6. toRefs,
  7. watch
  8. } from 'vue';
  9. import styles from '../index.module.less';
  10. import icons from '../icons.json';
  11. import { Badge, Image } from 'vant';
  12. import { ISubjectGradeDistribution } from '../type';
  13. const colors = [
  14. '#21B3D7',
  15. '#DF8010',
  16. '#17BDA6',
  17. '#21B3D7',
  18. '#DF8010',
  19. '#17BDA6',
  20. '#21B3D7',
  21. '#DF8010',
  22. '#17BDA6',
  23. '#21B3D7',
  24. '#DF8010',
  25. '#17BDA6',
  26. '#21B3D7',
  27. '#DF8010',
  28. '#17BDA6',
  29. ];
  30. export default defineComponent({
  31. name: 'DetailData',
  32. props: {
  33. data: {
  34. type: Array as PropType<ISubjectGradeDistribution[]>,
  35. default: () => []
  36. }
  37. },
  38. setup(props) {
  39. const { data } = toRefs(props);
  40. /** 声部列表 */
  41. const subjects = computed(() => {
  42. let list = data.value.reduce((list: any[], item) => {
  43. const _itemIndex = list.findIndex(
  44. _item => _item.subjectName === item.subjectName
  45. );
  46. if (_itemIndex > -1) {
  47. const listItem = list[_itemIndex];
  48. listItem[item.grade] = item.studentNum;
  49. } else {
  50. list.push({
  51. subjectName: item.subjectName,
  52. [item.grade]: item.studentNum
  53. });
  54. }
  55. return list;
  56. }, []);
  57. if (!list.length) {
  58. list = ['长笛', '单簧管', '萨克斯', '小号', '圆号', '长号', '上低音号'].map((n, i) => {
  59. return {
  60. subjectName: n,
  61. '总人数': 0,
  62. '一年级': 0,
  63. '二年级': 0,
  64. '三年级': 0,
  65. '四年级': 0,
  66. '五年级': 0,
  67. '六年级': 0,
  68. };
  69. })
  70. }
  71. return list;
  72. });
  73. /** 年级列表 */
  74. const gradeList = computed(() => {
  75. let index = -1;
  76. let _list = Array.from(new Set(data.value.map(item => item.grade)))
  77. .filter(item => item !== '总人数')
  78. .map(item => {
  79. if (index >= colors.length - 1) index = 0;
  80. else ++index;
  81. return {
  82. name: item,
  83. color: colors[index]
  84. };
  85. });
  86. if (!_list.length) {
  87. _list = ['一', '二', '三', '四', '五', '六'].map((n, i) => {
  88. if (index >= colors.length - 1) index = 0;
  89. else ++index;
  90. return {
  91. name: n + '年级',
  92. color: colors[index]
  93. };
  94. });
  95. }
  96. return _list;
  97. });
  98. return () => (
  99. <div class={styles.item}>
  100. <div class={[styles.itemTop, styles.detailDataContainerTop]}>
  101. <Image class={styles.icon} src={icons[4]} />
  102. <div class={styles.title}>详细数据</div>
  103. <div class={styles.des}>(单位:人)</div>
  104. </div>
  105. <div class={styles.detailDataContainer}>
  106. <div class={styles.detailLeft}>
  107. <div>
  108. <div style={{background: '#F8F8F8'}} class={[styles.tableTitle, styles.totalTableTitle]}>声部</div>
  109. {subjects.value.map(item => (
  110. <div class={styles.tableTr}>{item.subjectName}</div>
  111. ))}
  112. </div>
  113. <div class={styles.center}>
  114. <div style={{background: '#F2F2F2'}} class={[styles.tableTitle]}>总人数</div>
  115. {subjects.value.map(item => (
  116. <div class={styles.tableTr}>{item['总人数']}</div>
  117. ))}
  118. </div>
  119. </div>
  120. <div
  121. class={[styles.detailRight, styles.center]}
  122. onTouchmove={(e: Event) => e.stopPropagation()}
  123. onMousemove={(e: Event) => e.stopPropagation()}>
  124. {gradeList.value.map(item => (
  125. <div style={{ color: item.color }}>
  126. <div class={styles.tableTitle}>
  127. <div style={{ background: item.color }}></div>
  128. <div>{item.name}</div>
  129. </div>
  130. {subjects.value.map((_n, _index) => (
  131. <div class={styles.tableTr}>{_n[item.name] || 0}</div>
  132. ))}
  133. </div>
  134. ))}
  135. </div>
  136. </div>
  137. </div>
  138. );
  139. }
  140. });