index.vue 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. <template>
  2. <div class="container">
  3. <a-card class="general-card">
  4. <a-row>
  5. <a-col :flex="1">
  6. <a-form
  7. :model="formModel"
  8. :label-col-props="{ span: 4 }"
  9. :wrapper-col-props="{ span: 18 }"
  10. label-align="left"
  11. >
  12. <a-row :gutter="16">
  13. <a-col :span="6">
  14. <a-form-item
  15. field="address"
  16. :label="t('dashboard.form.address')"
  17. label-col-flex="50px"
  18. >
  19. <a-input
  20. v-model="formModel.address"
  21. :placeholder="t('dashboard.form.address')"
  22. allow-clear
  23. />
  24. </a-form-item>
  25. </a-col>
  26. <a-col :span="6">
  27. <a-form-item
  28. field="name"
  29. :label="t('dashboard.form.name')"
  30. label-col-flex="50px"
  31. >
  32. <a-input
  33. v-model="formModel.name"
  34. :placeholder="t('dashboard.form.name')"
  35. allow-clear
  36. />
  37. </a-form-item>
  38. </a-col>
  39. <a-col :span="6">
  40. <a-form-item
  41. field="entityType"
  42. :label="t('dashboard.form.entityType')"
  43. label-col-flex="60px"
  44. >
  45. <a-select
  46. v-model="formModel.entityType"
  47. :placeholder="t('dashboard.form.entityType')"
  48. allow-clear
  49. @clear="formModel.entityType = null"
  50. >
  51. <a-option
  52. v-for="item of deviceTypeList"
  53. :value="item.dictCode"
  54. :label="item.name"
  55. />
  56. </a-select>
  57. </a-form-item>
  58. </a-col>
  59. <a-col :span="6">
  60. <a-form-item
  61. field="status"
  62. :label="t('dashboard.form.status')"
  63. label-col-flex="60px"
  64. >
  65. <a-select
  66. v-model="formModel.status"
  67. :placeholder="t('dashboard.form.status')"
  68. allow-clear
  69. @clear="formModel.status = null"
  70. >
  71. <a-option
  72. v-for="item of deviceStatusList"
  73. :value="item.dictCode"
  74. :label="item.name"
  75. />
  76. </a-select>
  77. </a-form-item>
  78. </a-col>
  79. <a-col :span="6">
  80. <a-form-item
  81. :label="t('dashboard.form.timeRange')"
  82. label-col-flex="60px"
  83. >
  84. <a-range-picker v-model="formModel.time" />
  85. </a-form-item>
  86. </a-col>
  87. </a-row>
  88. </a-form>
  89. </a-col>
  90. <a-divider :style="{ height: '84px' }" direction="vertical" />
  91. <a-col :flex="'86px'">
  92. <a-space :size="10">
  93. <a-button type="primary" @click="search">
  94. <template #icon>
  95. <icon-search />
  96. </template>
  97. {{ t('searchTable.form.search') }}
  98. </a-button>
  99. <a-button @click="reset">
  100. <template #icon>
  101. <icon-refresh />
  102. </template>
  103. {{ t('searchTable.form.reset') }}
  104. </a-button>
  105. </a-space>
  106. <a-space class="right-side">
  107. <a-button type="primary" @click="downloadExcel">
  108. <template #icon>
  109. <icon-download />
  110. </template>
  111. {{ t('searchTable.form.down') }}
  112. </a-button>
  113. </a-space>
  114. </a-col>
  115. </a-row>
  116. <a-table
  117. row-key="name"
  118. :loading="loading"
  119. :pagination="pagination"
  120. :columns="cloneColumns as TableColumnData[]"
  121. :data="renderData"
  122. :bordered="false"
  123. :size="size"
  124. :scrollbar="true"
  125. @page-change="onPageChange"
  126. @row-dblclick="handleClick"
  127. >
  128. <template #index="{ rowIndex }">
  129. {{ rowIndex + 1 + (pagination.current - 1) * pagination.pageSize }}
  130. </template>
  131. <template #entityType="{ record }">
  132. <span>
  133. {{
  134. deviceTypeList.find(item => item.dictCode === record.entityType)
  135. ?.name
  136. }}
  137. </span>
  138. </template>
  139. <template #status="{ record }">
  140. <BTag :status="record.status">
  141. {{
  142. deviceStatusList.find(item => item.dictCode === record.status)
  143. ?.name
  144. }}
  145. </BTag>
  146. </template>
  147. <template #time="{ record }">
  148. <span>{{
  149. record.time && dayjs(record.time).format('YYYY-MM-DD HH:mm:ss')
  150. }}</span>
  151. </template>
  152. </a-table>
  153. </a-card>
  154. <DeviceInfoDialog
  155. v-model="showDeviceInfoDialog"
  156. :id="deviceId"
  157. :deviceInfo="deviceInfo"
  158. :deviceType="deviceType"
  159. >
  160. </DeviceInfoDialog>
  161. </div>
  162. </template>
  163. <script lang="ts" setup name="Dashboard">
  164. import {
  165. ref,
  166. reactive,
  167. shallowRef,
  168. h,
  169. getCurrentInstance,
  170. computed,
  171. } from 'vue';
  172. import { queryDashboardList, exportDashboardList } from '@/api/dashboard';
  173. import type { DashboardParams, DataList } from '@/api/dashboard';
  174. import { SizeProps, Pagination } from '@/types/global';
  175. import BTag from '@/components/business/b-tag/index.vue';
  176. import type { TableColumnData } from '@arco-design/web-vue';
  177. import useLoading from '@/hooks/loading';
  178. import { useI18n } from 'vue-i18n';
  179. import { DeviceInfo } from '@/utils/const';
  180. import type { AdditionalProp } from '@/api/dict';
  181. import dayjs from 'dayjs';
  182. import { downLoadFun } from '@/utils/const';
  183. import { useIntervalFn } from '@vueuse/core';
  184. import DeviceInfoDialog from './device-info/index.vue';
  185. import useDictList from '@/hooks/dict-list';
  186. const { t } = useI18n();
  187. const { loading, setLoading } = useLoading(true);
  188. const cloneColumns = computed(() => [
  189. {
  190. title: t('searchTable.table.number'),
  191. dataIndex: 'index',
  192. slotName: 'index',
  193. ellipsis: true,
  194. tooltip: true,
  195. width: 70,
  196. },
  197. {
  198. title: t('dashboard.table.time'),
  199. dataIndex: 'time',
  200. slotName: 'time',
  201. ellipsis: true,
  202. },
  203. {
  204. title: t('dashboard.form.status'),
  205. dataIndex: 'status',
  206. slotName: 'status',
  207. width: 120,
  208. },
  209. {
  210. title: t('dashboard.form.name'),
  211. dataIndex: 'name',
  212. slotName: 'name',
  213. },
  214. {
  215. title: t('dashboard.form.entityType'),
  216. dataIndex: 'entityType',
  217. slotName: 'entityType',
  218. },
  219. {
  220. title: t('dashboard.form.address'),
  221. dataIndex: 'address',
  222. ellipsis: true,
  223. tooltip: true,
  224. },
  225. ]);
  226. const basePagination: Pagination = {
  227. current: 1,
  228. pageSize: 20,
  229. };
  230. const pagination = reactive({
  231. ...basePagination,
  232. });
  233. const generateFormModel = () => {
  234. return {
  235. pageIndex: 1,
  236. pageSize: 20,
  237. name: null,
  238. address: null,
  239. status: null,
  240. startTime: null,
  241. endTime: null,
  242. time: ['', ''],
  243. entityType: null,
  244. } as DashboardParams;
  245. };
  246. const renderData = ref<DataList[]>([] as DataList[]);
  247. const size = ref<SizeProps>('medium');
  248. const formModel = ref<DashboardParams>(generateFormModel());
  249. const showDeviceInfoDialog = shallowRef<boolean>(false);
  250. const this_ = getCurrentInstance()?.appContext.config.globalProperties;
  251. const deviceInfo = ref<DeviceInfo[]>([] as DeviceInfo[]);
  252. const deviceTypeList = ref<AdditionalProp[]>([] as AdditionalProp[]);
  253. const deviceStatusList = ref<AdditionalProp[]>([] as AdditionalProp[]);
  254. const deviceId = shallowRef<number>(0);
  255. const deviceType = shallowRef<number | null>(1);
  256. useDictList(['DeviceType', 'DeviceStatus']).then(res => {
  257. deviceTypeList.value.push(...res['DeviceType']);
  258. deviceStatusList.value.push(...res['DeviceStatus']);
  259. });
  260. function searchTable() {
  261. // setLoading(true);
  262. const [startTime, endTime] = formModel.value.time
  263. ? formModel.value.time
  264. : ['', ''];
  265. formModel.value.startTime = startTime ? startTime : null;
  266. formModel.value.endTime = endTime ? endTime : null;
  267. queryDashboardList(formModel.value)
  268. .then(res => {
  269. pagination.current = formModel.value.pageIndex;
  270. pagination.pageSize = pagination.pageSize;
  271. pagination.total = res.totalCount;
  272. renderData.value = res.data;
  273. })
  274. .finally(() => {
  275. setLoading(false);
  276. });
  277. }
  278. searchTable();
  279. const { pause, resume, isActive } = useIntervalFn(() => {
  280. /* your function */
  281. formModel.value.pageIndex = 1;
  282. searchTable();
  283. }, 1000);
  284. const search = () => {
  285. searchTable();
  286. };
  287. const reset = () => {
  288. formModel.value = generateFormModel();
  289. };
  290. const downloadExcel = () => {
  291. setLoading(true);
  292. const [startTime, endTime] = formModel.value.time;
  293. formModel.value.startTime = startTime ? startTime : null;
  294. formModel.value.endTime = endTime ? endTime : null;
  295. exportDashboardList(formModel.value)
  296. .then(res => {
  297. if (!res.success) {
  298. return;
  299. }
  300. const url = res.data;
  301. downLoadFun(url);
  302. })
  303. .finally(() => {
  304. setLoading(false);
  305. });
  306. };
  307. const onPageChange = (current: number) => {
  308. formModel.value.pageIndex = current;
  309. if (current === 1) {
  310. resume();
  311. } else {
  312. pause();
  313. }
  314. searchTable();
  315. };
  316. const handleClick = (value: DataList) => {
  317. if (value.data) {
  318. deviceInfo.value.length = 0;
  319. const obj = JSON.parse(value.data);
  320. for (const key in obj) {
  321. deviceInfo.value.push({
  322. label: key,
  323. value: obj[key],
  324. });
  325. }
  326. console.log('dddd', value.entityType);
  327. deviceType.value = value.entityType;
  328. showDeviceInfoDialog.value = true;
  329. } else {
  330. this_ &&
  331. this_.$message.warning('No device information available at the moment');
  332. }
  333. };
  334. </script>
  335. <style lang="less" scoped>
  336. .container {
  337. padding: 10px 10px 20px;
  338. .general-card {
  339. padding-top: 20px;
  340. .right-side {
  341. margin-top: 20px;
  342. }
  343. }
  344. }
  345. </style>