test-report-mixin.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import config from '@/common/mx-config'
  2. import philosophyMixin from './test-report-philosophy'
  3. import occupationMixin from './test-report-occupation'
  4. import knowledgeMixin from './test-report-knowledge'
  5. export default {
  6. mixins: [philosophyMixin, occupationMixin, knowledgeMixin],
  7. props: {
  8. category: {
  9. type: Number | String,
  10. default: ''
  11. },
  12. source: {
  13. type: Object,
  14. default: null
  15. }
  16. },
  17. data() {
  18. return {
  19. // local data
  20. defaultActives: [],
  21. // api data
  22. dataList: [],
  23. // config
  24. reportConfig: {
  25. categoryDescription: '',
  26. matchedKeys: [],
  27. selectMajorLimit: 7,
  28. chartBarRotate: false, // false:柱状 / true:条状
  29. chartSubtext: '红色为系统推荐类型',
  30. resolveKeys: [],
  31. tableDefines: {},
  32. resolveConfig: {}
  33. }
  34. }
  35. },
  36. computed: {
  37. dynamicTableData() {
  38. const result = []
  39. const keys = Object.keys(this.reportConfig.tableDefines)
  40. keys.forEach(key => {
  41. const row = []
  42. row.push(this.reportConfig.tableDefines[key].label)
  43. this.dataList.forEach(i => row.push(i[key]))
  44. result.push(row)
  45. })
  46. return {
  47. columns: result[0],
  48. rows: result.slice(1, result.length)
  49. }
  50. },
  51. chartHeight() {
  52. const height = (this.dynamicTableData.rows.length + 1) * 44 + 'px'
  53. return height
  54. },
  55. mergedData() {
  56. const result = {}
  57. this.reportConfig.resolveKeys.forEach(key => {
  58. result[key] = this.dataList.sum(item => item[key] || 0)
  59. })
  60. return result
  61. },
  62. sortedMergedData() {
  63. const result = this.reportConfig.resolveKeys.map(key => ({ key: key, value: this.mergedData[key] }))
  64. result.sort((left, right) => {
  65. const lWeight = this.reportConfig.matchedKeys.includes(left.key) ? 100 : 1
  66. const rWeight = this.reportConfig.matchedKeys.includes(right.key) ? 100 : 1
  67. return right.value * rWeight - left.value * lWeight
  68. })
  69. return result
  70. },
  71. topOfMergedData() {
  72. const topThree = this.sortedMergedData.filter(i => this.reportConfig.matchedKeys.includes(i.key))
  73. this.defaultActives = this.readonly ? this.sortedMergedData.map(i => i.key) : topThree.map(i => i.key)
  74. return topThree
  75. },
  76. chartOptions() {
  77. const filterProps = this.reportConfig.resolveKeys
  78. const propNames = filterProps.map(key => this.reportConfig.tableDefines[key].label)
  79. const myTop = this.topOfMergedData
  80. const propSumColored = Object.keys(this.mergedData).map(key => myTop.some(i => i.key == key) ? {
  81. value: this.mergedData[key],
  82. itemStyle: { color: config.color.error }
  83. } : this.mergedData[key])
  84. const rotateConfig = this.reportConfig.chartBarRotate ? {
  85. yAxis: { type: 'category', data: propNames },
  86. xAxis: { type: 'value' }
  87. } : {
  88. xAxis: { type: 'category', data: propNames },
  89. yAxis: { type: 'value' }
  90. }
  91. return {
  92. title: {
  93. text: '测验汇总',
  94. subtext: this.reportConfig.chartSubtext,
  95. left: 'center'
  96. },
  97. ...rotateConfig,
  98. tooltip: {
  99. trigger: 'item'
  100. },
  101. series: [{
  102. data: propSumColored,
  103. type: 'bar',
  104. emphasis: {
  105. itemStyle: {
  106. shadowBlur: 10,
  107. shadowOffsetX: 0,
  108. shadowColor: 'rgba(0, 0, 0, 0.5)'
  109. }
  110. }
  111. }]
  112. }
  113. }
  114. },
  115. watch: {
  116. source: {
  117. immediate: true,
  118. handler: function(val) {
  119. if (!val?.datas?.length) return
  120. this.$nextTick(() => {
  121. const resolver = this[this.category + 'Resolver']
  122. if (typeof resolver === 'function') resolver()
  123. })
  124. }
  125. }
  126. },
  127. methods: {}
  128. }