QueryTable.vue 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. <template>
  2. <div class="form">
  3. <div class="table-query-form">
  4. <el-input
  5. v-model="tableQueryTypeContent"
  6. style="max-width: 251px; margin-right: 50px"
  7. :placeholder="'请输入' + tableQueryType"
  8. >
  9. <template #prepend>
  10. <el-select
  11. v-model="tableQueryType"
  12. style="width: 74px"
  13. @change="handleTableQueryTypeChange"
  14. >
  15. <el-option value="姓名" />
  16. <el-option value="工号" />
  17. </el-select>
  18. </template>
  19. </el-input>
  20. <div class="dept-select">
  21. <span>请选择组织:</span>
  22. <el-tree-select
  23. v-model="tableQueryDept"
  24. :data="props.departmentList"
  25. :render-after-expand="false"
  26. :default-expand-all="true"
  27. @change="handleDeptChange"
  28. style="width: 200px"
  29. check-strictly
  30. placeholder="请选择组织"
  31. class="protocal-select"
  32. />
  33. </div>
  34. <div style="min-width: 150px; float: right">
  35. <el-button type="primary" @click="submitTableQuery" style="width: 65px; height: 32px"
  36. >搜 索</el-button
  37. >
  38. <el-button @click="resetTable" style="width: 65px; height: 32px">重 置</el-button>
  39. </div>
  40. </div>
  41. <el-table
  42. ref="queryTableRef"
  43. max-height="calc(100vh - 350px)"
  44. style="width: 100%; margin-top: 18px"
  45. stripe
  46. :data="tableData.list"
  47. highlight-current-row
  48. @sort-change="handleSortChange"
  49. >
  50. <el-table-column label="姓名" prop="nickname" align="center"></el-table-column>
  51. <el-table-column label="工号" prop="username" align="center"></el-table-column>
  52. <el-table-column label="部门" prop="deptName" align="center"></el-table-column>
  53. <el-table-column
  54. v-if="tableLabel === '访问次数'"
  55. :label="'当日' + props.tableLabel"
  56. prop="statisticDay"
  57. sortable="custom"
  58. align="right"
  59. ></el-table-column>
  60. <el-table-column
  61. v-if="tableLabel === '访问次数'"
  62. :label="'本月' + tableLabel"
  63. prop="statisticMonth"
  64. sortable="custom"
  65. align="right"
  66. ></el-table-column>
  67. <el-table-column
  68. :label="'累计' + tableLabel"
  69. prop="statisticAll"
  70. sortable="custom"
  71. :align="tableLabel === '访问次数' ? 'right' : 'center'"
  72. ></el-table-column>
  73. <el-table-column v-if="tableLabel === '访问次数'" label="访问次数统计图" align="center">
  74. <template #default="scope">
  75. <img
  76. style="display: inline-block; margin-right: 20px; cursor: pointer"
  77. src="@/assets/icons/chart-bar.png"
  78. alt=""
  79. @click="showBargraph(scope.row)"
  80. />
  81. <img
  82. style="display: inline-block; cursor: pointer"
  83. src="@/assets/icons/chart-line.png"
  84. alt=""
  85. @click="showLinechart(scope.row)"
  86. />
  87. </template>
  88. </el-table-column>
  89. </el-table>
  90. <el-pagination
  91. v-model:current-page="tableQueryParams.pageNumber"
  92. v-model:currentPageSize="tableQueryParams.pageSize"
  93. :total="tableData.total"
  94. :page-sizes="[10, 20, 50, 100, 200]"
  95. layout="->, total,sizes,prev,pager,next,jumper"
  96. @size-change="handleSizeChange"
  97. @current-change="handleCurrentPageChange"
  98. />
  99. </div>
  100. <el-dialog
  101. v-model="bargraphVisible"
  102. :title="chartTitle"
  103. :close-on-click-modal="true"
  104. :destroy-on-close="true"
  105. width="1000px"
  106. center
  107. >
  108. <DialogNavBar @chart-params-changed="onDialogParamsChanged" />
  109. <BarChart :chart-data="chartData.val" :chart-lable="chartData.label" />
  110. </el-dialog>
  111. <el-dialog
  112. v-model="linechartVisible"
  113. :title="chartTitle"
  114. :close-on-click-modal="true"
  115. :destroy-on-close="true"
  116. width="1000px"
  117. center
  118. >
  119. <DialogNavBar
  120. chart-type="line"
  121. :workshop-list="workshopList"
  122. @chart-params-changed="onDialogParamsChanged"
  123. />
  124. <LineChart :chart-data="chartData.val" :chart-lable="chartData.label" />
  125. </el-dialog>
  126. </template>
  127. <script setup lang="ts">
  128. import { ref } from 'vue';
  129. import { defineProps } from 'vue';
  130. import DialogNavBar from '../common/DialogNavBar.vue';
  131. import BarChart from '../../charts/BarChart.vue';
  132. import LineChart from '../../charts/LineChart.vue';
  133. import {
  134. type ChartQuery,
  135. type UserAccessRecordList,
  136. type UserAccessRecordQueryParams,
  137. getUserVisitTimes,
  138. getUserDailyVisitTimes,
  139. } from '@/api/datamanagement/dataplatform';
  140. import { formatWorkshopChart, formatTimeChart } from '@/utils/platformUtils';
  141. import { PaginationRequest } from '@/types/common/type';
  142. const queryTableRef = ref();
  143. // 获取下拉菜单数据和表格数据
  144. const props = defineProps<{
  145. departmentList: any[];
  146. workshopList: any[];
  147. tableData: UserAccessRecordList;
  148. tableLabel: string;
  149. }>();
  150. // 表格查询参数和修改事件
  151. const tableQueryParams = ref<PaginationRequest & { queryParam: UserAccessRecordQueryParams }>({
  152. pageNumber: 1,
  153. pageSize: 10,
  154. queryParam: {},
  155. // nickname: "",
  156. // username: "",
  157. // sortKey: "",
  158. // sortType: "",
  159. });
  160. const emits = defineEmits<{
  161. (
  162. e: 'tableParamsChanged',
  163. parmas: PaginationRequest & { queryParam: UserAccessRecordQueryParams },
  164. );
  165. }>();
  166. // 页码导航栏修改事件
  167. const handleSizeChange = (v: number) => {
  168. tableQueryParams.value.pageSize = v;
  169. emits('tableParamsChanged', tableQueryParams.value);
  170. };
  171. const handleCurrentPageChange = (v: number) => {
  172. tableQueryParams.value.pageNumber = v;
  173. emits('tableParamsChanged', tableQueryParams.value);
  174. };
  175. // 表格排序事件
  176. const handleSortChange = (data: any) => {
  177. if (data.order !== null) {
  178. tableQueryParams.value.queryParam.sortKey = data.prop;
  179. tableQueryParams.value.queryParam.sortType = data.order.includes('a') ? 'asc' : 'desc';
  180. } else {
  181. delete tableQueryParams.value.queryParam.sortKey;
  182. delete tableQueryParams.value.queryParam.sortType;
  183. }
  184. tableQueryParams.value.pageNumber = 1;
  185. emits('tableParamsChanged', tableQueryParams.value);
  186. };
  187. // 复用输入框类型和变化事件
  188. const tableQueryType = ref<string>('姓名');
  189. const handleTableQueryTypeChange = (v: string) => {
  190. if (v === '姓名') {
  191. delete tableQueryParams.value.queryParam.staffNo;
  192. } else {
  193. delete tableQueryParams.value.queryParam.nickname;
  194. }
  195. tableQueryTypeContent.value = '';
  196. };
  197. // 部门筛选框变化
  198. const handleDeptChange = (v: string) => {
  199. tableQueryParams.value.queryParam.deptId = v;
  200. };
  201. // 复用输入框绑定内容、提交事件、重置事件
  202. const tableQueryTypeContent = ref<string>();
  203. function submitTableQuery() {
  204. if (tableQueryType.value === '姓名') {
  205. tableQueryParams.value.queryParam.nickname = tableQueryTypeContent.value;
  206. } else {
  207. tableQueryParams.value.queryParam.staffNo = tableQueryTypeContent.value;
  208. }
  209. emits('tableParamsChanged', tableQueryParams.value);
  210. }
  211. function resetTable() {
  212. queryTableRef.value.clearSort();
  213. tableQueryTypeContent.value = '';
  214. tableQueryDept.value = undefined;
  215. tableQueryParams.value = {
  216. pageNumber: 1,
  217. pageSize: 10,
  218. queryParam: {},
  219. };
  220. emits('tableParamsChanged', tableQueryParams.value);
  221. }
  222. // 组织列表筛选数据
  223. const tableQueryDept = ref<string>();
  224. // dialog显示和画图
  225. const chartTitle = ref('');
  226. const ChartQueryUserId = ref('');
  227. const bargraphVisible = ref(false);
  228. const showBargraph = (rowData) => {
  229. bargraphVisible.value = true;
  230. chartTitle.value = rowData.nickname + '访问车间统计柱状图';
  231. ChartQueryUserId.value = rowData.userId;
  232. };
  233. const linechartVisible = ref(false);
  234. const showLinechart = (rowData) => {
  235. linechartVisible.value = true;
  236. chartTitle.value = rowData.nickname + '访问车间统计折线图';
  237. ChartQueryUserId.value = rowData.userId;
  238. };
  239. // 请求画图数据
  240. const getChartData = async (cp: ChartQuery) => {
  241. if (chartTitle.value.includes('柱状')) {
  242. const data = await getUserVisitTimes(cp);
  243. chartData.value = formatWorkshopChart(data);
  244. } else {
  245. const data = await getUserDailyVisitTimes(cp);
  246. chartData.value = formatTimeChart(data);
  247. }
  248. };
  249. const chartData = ref<{
  250. label: string[];
  251. val: any[];
  252. }>({
  253. label: [],
  254. val: [],
  255. });
  256. const onDialogParamsChanged = async (v: ChartQuery) => {
  257. v.userId = ChartQueryUserId.value;
  258. await getChartData(v);
  259. };
  260. </script>
  261. <style scoped lang="scss">
  262. .testbox {
  263. width: 930px;
  264. height: 480px;
  265. }
  266. .form {
  267. /* width: 1100px; */
  268. margin-top: 18px;
  269. }
  270. .el-pagination {
  271. margin-top: 30px;
  272. }
  273. .table-query-form {
  274. padding-right: 25px;
  275. width: 100%;
  276. display: flex;
  277. justify-content: flex-start;
  278. align-items: center;
  279. .dept-select {
  280. min-width: 300px;
  281. margin-right: 50px;
  282. }
  283. }
  284. </style>