resultAnalysis.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <template>
  2. <div class="snapshot-statistics-hotspot-container layout-pd">
  3. <el-card shadow="never">
  4. <el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent inline :disabled="gridOptions.loading">
  5. <el-form-item prop="crTime">
  6. <statistical-time v-model="state.queryParams.crTime" @change="handleQuery" ref="statisticalTimeRef" :disabled="state.loading" />
  7. </el-form-item>
  8. <el-form-item label="培训标题" prop="keyword">
  9. <el-input
  10. v-model="state.queryParams.keyword"
  11. placeholder="培训标题"
  12. clearable
  13. @change="handleQuery"
  14. :disabled="state.loading"
  15. class="keyword-input"
  16. />
  17. </el-form-item>
  18. <el-form-item>
  19. <el-button type="primary" @click="handleQuery" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
  20. <el-button @click="resetQuery(ruleFormRef)" class="default-button" :loading="state.loading">
  21. <SvgIcon name="ele-Refresh" class="mr5" />重置
  22. </el-button>
  23. </el-form-item>
  24. </el-form>
  25. <el-row :gutter="20">
  26. <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
  27. <div style="height: 70vh">
  28. <vxe-grid v-bind="gridOptions" ref="gridRef" v-on="gridEvents">
  29. <template #pager>
  30. <pagination
  31. @pagination="queryList"
  32. :total="state.total"
  33. v-model:current-page="state.queryParams.PageIndex"
  34. v-model:page-size="state.queryParams.PageSize"
  35. :disabled="state.loading"
  36. />
  37. </template>
  38. </vxe-grid>
  39. </div>
  40. </el-col>
  41. <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
  42. <v-chart class="chart" :option="option" :loading="state.loading" autoresize />
  43. </el-col>
  44. </el-row>
  45. </el-card>
  46. </div>
  47. </template>
  48. <script setup lang="tsx" name="examTrainTrainStatisticsResultAnalysis">
  49. import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
  50. import { FormInstance } from 'element-plus';
  51. import { defaultDate } from '@/utils/constants';
  52. import Other from '@/utils/other';
  53. import { getTrainResultAnalysisData, getTrainResultAnalysisExport, getTrainCalcuteAnalysisData } from '@/api/examTrain/statistics';
  54. const StatisticalTime = defineAsyncComponent(() => import('@/components/StatisticalTime/index.vue')); // 日期类型选择组件
  55. const pagination = defineAsyncComponent(() => import('@/components/ProTable/components/Pagination.vue')); // 分页
  56. // 定义变量内容
  57. const ruleFormRef = ref<RefType>(); // 表单ref
  58. const state = reactive<any>({
  59. queryParams: {
  60. // 查询条件
  61. PageIndex: 1,
  62. PageSize: 20,
  63. crTime: defaultDate,
  64. startTime: null,
  65. endTime: null,
  66. anlysisType: 3,
  67. keyword: '',
  68. sortField: null,
  69. sortRule: null,
  70. },
  71. tableData: [], //表单
  72. loading: false, // 加载
  73. total: 0, // 总数
  74. });
  75. /** 搜索按钮操作 */
  76. const handleQuery = () => {
  77. queryList();
  78. };
  79. const requestParams = ref<EmptyObjectType>({});
  80. const gridOptions = reactive<any>({
  81. loading: false,
  82. border: true,
  83. showOverflow: true,
  84. columnConfig: {
  85. resizable: true,
  86. },
  87. scrollY: {
  88. enabled: true,
  89. gt: 100,
  90. },
  91. toolbarConfig: {
  92. custom: true,
  93. refresh: {
  94. queryMethod: () => {
  95. handleQuery();
  96. },
  97. },
  98. tools: [{ toolRender: { name: 'exportCurrent' } }, { toolRender: { name: 'exportAll' } }],
  99. },
  100. params: {
  101. exportMethod: getTrainResultAnalysisExport,
  102. exportParams: requestParams,
  103. },
  104. customConfig: {
  105. storage: true,
  106. },
  107. id: 'examTrainTrainStatisticsResultAnalysis',
  108. rowConfig: { isHover: true, height: 30, isCurrent: true, useKey: true },
  109. height: 'auto',
  110. align: 'center',
  111. columns: [
  112. { field: 'userName', title: '培训人员', width: 120 },
  113. { field: 'trainName', title: '培训标题', minWidth: 200 },
  114. { field: 'isCompleteDes', title: '学习是否完成', width: 120 },
  115. ],
  116. data: [],
  117. });
  118. /** 获取列表 */
  119. const dataTable = ref([] as any[]);
  120. const queryList = () => {
  121. state.loading = true;
  122. gridOptions.loading = true;
  123. requestParams.value = Other.deepClone(state.queryParams);
  124. requestParams.value.startTime = state.queryParams.crTime === null ? null : state.queryParams.crTime[0];
  125. requestParams.value.endTime = state.queryParams.crTime === null ? null : state.queryParams.crTime[1];
  126. Reflect.deleteProperty(requestParams.value, 'crTime');
  127. getTrainResultAnalysisData(requestParams.value).then((res) => {
  128. gridOptions.data = res.result.items ?? [];
  129. state.total = res?.result.pagination.totalCount ?? 0;
  130. gridOptions.loading = false;
  131. }).catch(() => {
  132. gridOptions.loading = false;
  133. });
  134. getTrainCalcuteAnalysisData(requestParams.value).then((res) => {
  135. state.tableData = res.result ?? null;
  136. const legendData = ['进行中', '是', '否'];
  137. dataTable.value = [
  138. { name: '进行中', value: state.tableData.trainning },
  139. { name: '是', value: state.tableData.complete },
  140. { name: '否', value: state.tableData.unComplete },
  141. ];
  142. setOption(legendData, dataTable.value);
  143. state.loading = false;
  144. }).catch(() => {
  145. state.loading = false;
  146. });
  147. };
  148. const gridEvents = {
  149. sortChange(val: any) {
  150. state.queryParams.sortField = val.order ? val.field : null;
  151. // 0 升序 1 降序
  152. state.queryParams.sortRule = val.order ? (val.order == 'desc' ? 1 : 0) : null;
  153. handleQuery();
  154. },
  155. };
  156. /** 重置按钮操作 */
  157. const statisticalTimeRef = ref<RefType>();
  158. const resetQuery = (formEl: FormInstance | undefined) => {
  159. if (!formEl) return;
  160. formEl.resetFields();
  161. statisticalTimeRef.value.reset();
  162. queryList();
  163. };
  164. const option = ref<EmptyObjectType>({});
  165. // 热点类型统计表
  166. const setOption = (legendData: string[], data: any) => {
  167. option.value = {
  168. title: {
  169. text: '学习完成度占比',
  170. left: 'center',
  171. },
  172. tooltip: {
  173. formatter: '{b0}: {c0} ({d}%)',
  174. },
  175. legend: [
  176. {
  177. left: 'left',
  178. top: '40',
  179. orient: 'vertical',
  180. data: legendData,
  181. },
  182. ],
  183. series: [
  184. {
  185. type: 'pie',
  186. radius: ['0%', '60%'],
  187. top: '10%',
  188. itemStyle: {
  189. borderRadius: 10,
  190. borderColor: '#fff',
  191. borderWidth: 2,
  192. },
  193. label: {
  194. show: true,
  195. overflow: 'none',
  196. formatter: (params: any) => {
  197. if (params.name !== '') {
  198. return `${params.name}:${params.data.value}`;
  199. // (${params.percent}%)
  200. }
  201. },
  202. },
  203. data: data,
  204. },
  205. ],
  206. };
  207. };
  208. onMounted(() => {
  209. queryList();
  210. });
  211. </script>
  212. <style lang="scss" scoped>
  213. .chart {
  214. height: 70vh;
  215. margin-top: 10px;
  216. }
  217. </style>