index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. <template>
  2. <HomeContainer>
  3. <!-- 时间范围显示 -->
  4. <!-- <view v-if="startDate && endDate" class="time-range-display">
  5. <text class="time-range-text">时间范围:{{ startDate }} 至 {{ endDate }}</text>
  6. </view> -->
  7. <!-- 统计表格区域 -->
  8. <view class="statistic-tables-section">
  9. <!-- 查获数量统计表格 -->
  10. <StatisticTable title="查获数量" :columns="seizureColumns" :data="seizureTableData" :blankData="'0'"
  11. class="statistic-table" />
  12. <!-- 在岗时长统计表格 -->
  13. <StatisticTable title="在岗时长" :columns="workingColumns" :data="workingTableData" :blankData="'0'"
  14. class="statistic-table" />
  15. <!-- 巡检合格率统计表格 -->
  16. <StatisticTable title="巡检合格率" :columns="inspectionColumns" :data="inspectionTableData" :blankData="'0'"
  17. class="statistic-table" />
  18. <!-- 抽问抽答正确率统计表格 -->
  19. <StatisticTable title="抽问抽答正确率" :columns="questionColumns" :data="questionTableData" :blankData="'0'"
  20. class="statistic-table" />
  21. <!-- 培训答题分数统计表格 -->
  22. <StatisticTable title="培训答题分数" :columns="learningColumns" :data="learningTableData" :blankData="'0'"
  23. class="statistic-table" />
  24. </view>
  25. </HomeContainer>
  26. </template>
  27. <script>
  28. import HomeContainer from '@/components/HomeContainer.vue'
  29. import HeadTitle from '@/components/HeadTitle.vue'
  30. import StatisticTable from '@/components/statistic-table/statistic-table.vue'
  31. import { getHomeReportWhole } from '@/api/home-new/home-new.js'
  32. export default {
  33. name: 'StatisticalReport',
  34. components: {
  35. HomeContainer,
  36. HeadTitle,
  37. StatisticTable
  38. },
  39. data() {
  40. return {
  41. // 时间参数
  42. startDate: '',
  43. endDate: '',
  44. // 表格列配置
  45. seizureColumns: [
  46. { props: 'name', title: '查获数量' },
  47. { props: 'totalNumber', title: '总数' },
  48. { props: 'averageNumber', title: '平均数' },
  49. { props: 'medianNumber', title: '中位数' },
  50. { props: 'maxNumber', title: '最大值' },
  51. { props: 'minNumber', title: '最小值' }
  52. ],
  53. workingColumns: [
  54. { props: 'name', title: '在岗时长' },
  55. { props: 'totalNumber', title: '总数' },
  56. { props: 'averageNumber', title: '平均数' },
  57. { props: 'medianNumber', title: '中位数' },
  58. { props: 'maxNumber', title: '最大值' },
  59. { props: 'minNumber', title: '最小值' }
  60. ],
  61. inspectionColumns: [
  62. { props: 'name', title: '巡检合格率(%)' },
  63. // { props: 'totalNumber', title: '总数' },
  64. { props: 'averageNumber', title: '平均数' },
  65. { props: 'medianNumber', title: '中位数' },
  66. { props: 'maxNumber', title: '最大值' },
  67. { props: 'minNumber', title: '最小值' }
  68. ],
  69. questionColumns: [
  70. { props: 'name', title: '抽问抽答正确率(%)' },
  71. // { props: 'totalNumber', title: '总数' },
  72. { props: 'averageNumber', title: '平均数' },
  73. { props: 'medianNumber', title: '中位数' },
  74. { props: 'maxNumber', title: '最大值' },
  75. { props: 'minNumber', title: '最小值' }
  76. ],
  77. learningColumns: [
  78. { props: 'name', title: '培训答题分数' },
  79. // { props: 'totalNumber', title: '总数' },
  80. { props: 'averageNumber', title: '平均数' },
  81. { props: 'medianNumber', title: '中位数' },
  82. { props: 'maxNumber', title: '最大值' },
  83. { props: 'minNumber', title: '最小值' }
  84. ],
  85. // 统计表格数据
  86. seizureTableData: [], // 查获数量 - seizureList
  87. workingTableData: [], // 在岗时长 - workingList
  88. inspectionTableData: [], // 巡检合格率 - checkList
  89. questionTableData: [], // 抽问抽答正确率 - answerList
  90. learningTableData: [] // 培训答题分数 - learningList
  91. }
  92. },
  93. async onLoad(options) {
  94. // 接收页面参数
  95. this.startDate = options.startDate || ''
  96. this.endDate = options.endDate || ''
  97. console.log('接收到的时间参数:', {
  98. startDate: this.startDate,
  99. endDate: this.endDate
  100. })
  101. // 页面加载时获取数据
  102. await this.loadData()
  103. },
  104. methods: {
  105. // 加载数据方法
  106. async loadData() {
  107. try {
  108. // 根据时间参数构建查询条件
  109. const queryParams = {}
  110. if (this.startDate && this.endDate) {
  111. queryParams.startDate = this.startDate
  112. queryParams.endDate = this.endDate
  113. }
  114. console.log('加载数据的查询参数:', queryParams)
  115. // 调用getHomeReportWhole接口获取真实数据
  116. const response = await getHomeReportWhole(queryParams)
  117. if (response.code === 200 && response.data) {
  118. // 处理接口返回的真实数据
  119. const { checkList, learningList, seizureList, workingList, answerList } = response.data;
  120. // 分配数据到对应的表格
  121. this.seizureTableData = seizureList || this.generateMockDepartmentData('查获数量')
  122. this.workingTableData = workingList || this.generateMockDepartmentData('在岗时长')
  123. this.inspectionTableData = checkList.map((item) => {
  124. return {
  125. ...item,
  126. medianNumber: `${(item.medianNumber * 100).toFixed(2)}`,
  127. maxNumber: `${(item.maxNumber * 100).toFixed(2)}`,
  128. minNumber: `${(item.minNumber * 100).toFixed(2)}`,
  129. averageNumber: `${(item.averageNumber * 100).toFixed(2)}`
  130. }
  131. }) || this.generateMockDepartmentData('巡检合格率')
  132. this.questionTableData = answerList.map((item) => {
  133. return {
  134. ...item,
  135. medianNumber: `${(item.medianNumber).toFixed(2)}`,
  136. maxNumber: `${(item.maxNumber).toFixed(2)}`,
  137. minNumber: `${(item.minNumber).toFixed(2)}`,
  138. averageNumber: `${(item.averageNumber).toFixed(2)}`
  139. }
  140. }) || this.generateMockDepartmentData('抽问抽答正确率')
  141. this.learningTableData = learningList || this.generateMockDepartmentData('培训答题分数')
  142. // 如果有时间参数,显示时间范围提示
  143. // if (this.startDate && this.endDate) {
  144. // uni.showToast({
  145. // title: `已加载 ${this.startDate} 至 ${this.endDate} 的数据`,
  146. // icon: 'none',
  147. // duration: 2000
  148. // })
  149. // }
  150. } else {
  151. // 如果接口返回失败,使用模拟数据
  152. console.warn('接口返回数据异常,使用模拟数据')
  153. this.seizureTableData = this.generateMockDepartmentData('查获数量')
  154. this.workingTableData = this.generateMockDepartmentData('在岗时长')
  155. this.inspectionTableData = this.generateMockDepartmentData('巡检合格率')
  156. this.questionTableData = this.generateMockDepartmentData('抽问抽答正确率')
  157. this.learningTableData = this.generateMockDepartmentData('培训答题分数')
  158. }
  159. } catch (error) {
  160. console.error('加载数据失败:', error)
  161. // 如果接口调用失败,使用模拟数据
  162. this.seizureTableData = this.generateMockDepartmentData('查获数量')
  163. this.workingTableData = this.generateMockDepartmentData('在岗时长')
  164. this.inspectionTableData = this.generateMockDepartmentData('巡检合格率')
  165. this.questionTableData = this.generateMockDepartmentData('抽问抽答正确率')
  166. this.learningTableData = this.generateMockDepartmentData('培训答题分数')
  167. uni.showToast({
  168. title: '数据加载失败,使用模拟数据',
  169. icon: 'none'
  170. })
  171. }
  172. },
  173. // 生成模拟科室数据(根据类型生成不同科室的统计数据)
  174. generateMockDepartmentData(type) {
  175. // 模拟科室列表
  176. const departments = ['安检一科', '安检二科', '安检三科', '安检四科', '安检五科']
  177. // 根据类型设置基础数值范围
  178. const baseConfig = {
  179. '查获数量': { baseTotal: 800, baseAvg: 20, baseMedian: 18, baseMax: 40, baseMin: 5 },
  180. '在岗时长': { baseTotal: 1200, baseAvg: 30, baseMedian: 28, baseMax: 60, baseMin: 15 },
  181. '巡检合格率': { baseTotal: 1000, baseAvg: 25, baseMedian: 23, baseMax: 50, baseMin: 10 },
  182. '抽问抽答正确率': { baseTotal: 600, baseAvg: 15, baseMedian: 14, baseMax: 30, baseMin: 3 },
  183. '培训答题分数': { baseTotal: 900, baseAvg: 22, baseMedian: 21, baseMax: 45, baseMin: 8 }
  184. }
  185. const config = baseConfig[type] || baseConfig['查获数量']
  186. return departments.map((dept, index) => {
  187. // 为每个科室生成略有差异的数据
  188. const variation = (index + 1) * 0.1 // 每个科室数据略有不同
  189. return {
  190. name: dept,
  191. totalNumber: Math.round(config.baseTotal * (1 + variation * 0.2)),
  192. averageNumber: (config.baseAvg * (1 + variation * 0.1)).toFixed(1),
  193. medianNumber: (config.baseMedian * (1 + variation * 0.1)).toFixed(1),
  194. maxNumber: Math.round(config.baseMax * (1 + variation * 0.3)),
  195. minNumber: Math.round(config.baseMin * (1 + variation * 0.1))
  196. }
  197. })
  198. },
  199. // 生成模拟表格数据(根据时间参数调整数据)
  200. generateMockTableData(type, queryParams = {}) {
  201. // 根据时间范围调整数据值
  202. let baseValue = 1000
  203. let completionRate = 98.5
  204. let passRate = 96.2
  205. let avgTime = 15
  206. // 如果有时间参数,根据时间范围调整数据
  207. if (queryParams.startDate && queryParams.endDate) {
  208. // 计算时间跨度(天数)
  209. const start = new Date(queryParams.startDate)
  210. const end = new Date(queryParams.endDate)
  211. const diffTime = Math.abs(end - start)
  212. const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24))
  213. // 根据时间跨度调整数据
  214. baseValue = Math.round(1000 * (diffDays / 30)) // 假设30天为基准
  215. completionRate = 98.5 - (30 - Math.min(diffDays, 30)) * 0.1
  216. passRate = 96.2 - (30 - Math.min(diffDays, 30)) * 0.05
  217. avgTime = 15 + (30 - Math.min(diffDays, 30)) * 0.2
  218. }
  219. return [
  220. { label: `${type}总数`, value: baseValue.toLocaleString() },
  221. { label: `${type}完成率`, value: `${completionRate.toFixed(1)}%` },
  222. { label: `${type}合格率`, value: `${passRate.toFixed(1)}%` },
  223. { label: `${type}平均用时`, value: `${avgTime.toFixed(0)}分钟` }
  224. ]
  225. }
  226. }
  227. }
  228. </script>
  229. <style lang="scss" scoped>
  230. .statistical-report {
  231. min-height: 100vh;
  232. background-color: #f5f7fa;
  233. }
  234. // 时间范围显示样式
  235. .time-range-display {
  236. background-color: #ffffff;
  237. padding: 24rpx 32rpx;
  238. margin-bottom: 24rpx;
  239. border-radius: 12rpx;
  240. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
  241. .time-range-text {
  242. font-size: 28rpx;
  243. color: #666;
  244. font-weight: 500;
  245. }
  246. }
  247. .page-header {
  248. margin-bottom: 32rpx;
  249. }
  250. .statistic-tables-section {
  251. .statistic-table {
  252. margin-bottom: 32rpx;
  253. }
  254. }
  255. // 响应式适配
  256. @media (max-width: 750px) {
  257. .time-range-display {
  258. padding: 20rpx 24rpx;
  259. margin-bottom: 20rpx;
  260. .time-range-text {
  261. font-size: 26rpx;
  262. }
  263. }
  264. .statistic-tables-section {
  265. .statistic-table {
  266. margin-bottom: 24rpx;
  267. }
  268. }
  269. }
  270. </style>