GroupMonitorTable.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. <template>
  2. <div class="vent-table">
  3. <a-radio-group v-model:value="selectRowIndex" @change="setSelectedRowKeys" style="width: 100%">
  4. <a-table
  5. :columns="columns"
  6. :pagination="false"
  7. :data-source="dataTableSource"
  8. ref="tableRef"
  9. bordered
  10. style="margin-top: 5px"
  11. :scroll="tableScroll"
  12. :selectType="'radio'"
  13. :customRow="rowClick"
  14. >
  15. <template #bodyCell="{ column, record }">
  16. <template v-if="column.dataIndex === 'isCheck'">
  17. <a-radio :value="record.deviceID" />
  18. </template>
  19. <a-tag v-if="column.dataIndex === 'warnFlag'" :color="record.warnFlag == '0' ? 'green' : 'red'">{{
  20. record.warnFlag == '0' ? '正常' : '报警'
  21. }}</a-tag>
  22. <a-tag v-if="column.dataIndex === 'netStatus'" :color="record.netStatus == '0' ? '#f00' : 'green'">{{
  23. record.netStatus == '0' ? '断开' : '连接'
  24. }}</a-tag>
  25. <slot name="bodyCell" v-bind="{ column, record }"></slot>
  26. </template>
  27. <template #operation="{ column, record }">
  28. <slot name="action" v-bind="{ column, record }"></slot>
  29. </template>
  30. </a-table>
  31. </a-radio-group>
  32. </div>
  33. </template>
  34. <script lang="ts" setup>
  35. //ts语法
  36. import { toRaw, watch, ref, onMounted, onUnmounted, nextTick, inject } from 'vue';
  37. import { getTableHeaderColumns } from '/@/hooks/web/useWebColumns';
  38. import { useGlobSetting } from '/@/hooks/setting';
  39. const { sysOrgCode } = useGlobSetting();
  40. const globalConfig = inject('globalConfig');
  41. const props = defineProps({
  42. columnsType: {
  43. type: String,
  44. required: true,
  45. },
  46. dataSource: {
  47. type: Array,
  48. required: true,
  49. },
  50. deviceType: {
  51. type: String,
  52. },
  53. designScope: {
  54. type: String,
  55. },
  56. title: {
  57. type: String,
  58. },
  59. scroll: {
  60. type: Object,
  61. default: () => null,
  62. },
  63. isAction: {
  64. type: Boolean,
  65. default: false,
  66. },
  67. isShowSelect: {
  68. type: Boolean,
  69. default: true,
  70. },
  71. });
  72. const tableRef = ref();
  73. const emits = defineEmits(['selectRow']);
  74. const dataTableSource = ref<any[]>([]);
  75. const loading = ref(true);
  76. const tableScroll = props.scroll.y ? ref({ y: props.scroll.y, x: 'max-content' }) : ref({});
  77. let scrollY = 0;
  78. const columns = ref<any[]>([]);
  79. // 默认初始是第一行
  80. const selectRowIndex = ref(-1);
  81. const headElHeight = ref(0);
  82. const rowClick = (record) => {
  83. return {
  84. onClick: () => {
  85. setSelectedRowKeys(record['deviceID']);
  86. },
  87. };
  88. };
  89. const setSelectedRowKeys = (target) => {
  90. if (Object.prototype.toString.call(target) === '[object String]') {
  91. selectRowIndex.value = target;
  92. emits('selectRow', target);
  93. } else if (Object.prototype.toString.call(target) === '[object Object]') {
  94. const data = target.target.value;
  95. selectRowIndex.value = data;
  96. emits('selectRow', data);
  97. }
  98. };
  99. /** 定义table Columns */
  100. function setColumns(columnsType) {
  101. const isCheckColumn = {
  102. title: '',
  103. dataIndex: 'isCheck',
  104. width: 40,
  105. align: 'center',
  106. customCell: (_, index) => {
  107. if (index % 3 == 0) {
  108. return { rowSpan: 3 };
  109. } else {
  110. return { rowSpan: 0 };
  111. }
  112. },
  113. };
  114. const indexColumn = {
  115. title: '序号',
  116. dataIndex: 'key',
  117. width: 80,
  118. align: 'center',
  119. customCell: (_, index) => {
  120. if (index % 3 == 0) {
  121. return { rowSpan: 3 };
  122. } else {
  123. return { rowSpan: 0 };
  124. }
  125. },
  126. customRender: function ({ index }) {
  127. return index / 3 + 1;
  128. },
  129. };
  130. const runDevice = {
  131. title: '风机',
  132. dataIndex: 'runDevice',
  133. width: 80,
  134. align: 'center',
  135. };
  136. columns.value = getTableHeaderColumns(columnsType);
  137. console.log('风机columns------------------>', columnsType);
  138. if (columns.value && columns.value.length < 1) {
  139. columns.value = getTableHeaderColumns(columnsType.split('_')[0] + '_monitor');
  140. }
  141. const strinstallpos = columns.value.find((item) => {
  142. return item.dataIndex === 'strinstallpos' || item.dataIndex === 'strname';
  143. });
  144. if (strinstallpos) {
  145. strinstallpos.customCell = (_, index) => {
  146. if (index % 3 == 0) {
  147. return { rowSpan: 3 };
  148. } else {
  149. return { rowSpan: 0 };
  150. }
  151. };
  152. }
  153. columns.value.forEach((item) => {
  154. if (item.dataIndex === 'strinstallpos' || item.dataIndex === 'strname' || item.dataIndex.endsWith('_merge')) {
  155. item.customCell = (_, index) => {
  156. if (index % 3 == 0) {
  157. return { rowSpan: 3 };
  158. } else {
  159. return { rowSpan: 0 };
  160. }
  161. };
  162. }
  163. });
  164. columns.value.splice(1, 0, runDevice);
  165. if (props.isShowSelect) {
  166. columns.value = [isCheckColumn, indexColumn, ...columns.value];
  167. } else {
  168. columns.value = [indexColumn, ...columns.value];
  169. }
  170. if (props.isAction) {
  171. columns.value = [
  172. ...columns.value,
  173. {
  174. title: '操作',
  175. dataIndex: 'operation',
  176. width: 120,
  177. align: 'center',
  178. slots: { customRender: 'operation' },
  179. customCell: (_, index) => {
  180. if (index % 3 == 0) {
  181. return { rowSpan: 3 };
  182. } else {
  183. return { rowSpan: 0 };
  184. }
  185. },
  186. },
  187. ];
  188. }
  189. // columns.value = [...columns.value, ...columns.value]
  190. return columns;
  191. }
  192. watch(
  193. () => {
  194. return props.columnsType;
  195. },
  196. (newVal, oldVal) => {
  197. if (!newVal) return;
  198. setColumns(newVal);
  199. nextTick(() => {
  200. const headEl = document.querySelector(`.zxm-table-thead`);
  201. if (headEl) {
  202. headElHeight.value = headEl.clientHeight;
  203. tableScroll.value = { y: (scrollY || props.scroll.y) - (headElHeight.value - 56), x: 'max-content' };
  204. }
  205. });
  206. },
  207. {
  208. immediate: true,
  209. }
  210. );
  211. watch(
  212. () => {
  213. return props.dataSource;
  214. },
  215. (newVal, oldVal) => {
  216. const list: unknown[] = [];
  217. newVal.forEach((item) => {
  218. const data: any = toRaw(item);
  219. const modalTyoe = data.modalTyoe; ///
  220. const resultData1 = {};
  221. const resultData2 = {};
  222. const resultData3 = {};
  223. // 将主风机、备风机的数据进行拆分
  224. columns.value.forEach((column) => {
  225. const columnKey = column.dataIndex;
  226. if (columnKey) {
  227. if (columnKey.startsWith('Fan')) {
  228. const key1 = columnKey.replace('Fan', 'Fan1');
  229. const key2 = columnKey.replace('Fan', 'Fan2');
  230. const key3 = columnKey.replace('Fan', 'Fan3');
  231. if (columnKey.endsWith('_merge')) {
  232. resultData1[columnKey] = data[key1] == 0 || data[key1] == null || data[key1] == undefined ? data[key2] : data[key1] || data[key3];
  233. } else {
  234. if (columnKey.startsWith('FanStartStatus')) {
  235. resultData1[columnKey] = data[key1];
  236. resultData2[columnKey] = data[key2];
  237. resultData3[columnKey] = data[key3];
  238. } else {
  239. resultData1[columnKey] = data['Fan1StartStatus'] == '0' && globalConfig?.simulatedPassword ? '-' : data[key1];
  240. resultData2[columnKey] = data['Fan2StartStatus'] == '0' && globalConfig?.simulatedPassword ? '-' : data[key2];
  241. resultData3[columnKey] = data['Fan3StartStatus'] == '0' && globalConfig?.simulatedPassword ? '-' : data[key3];
  242. }
  243. if (resultData1[columnKey] == undefined && resultData2[columnKey] == undefined) {
  244. resultData1[columnKey] = data[columnKey];
  245. resultData2[columnKey] = data[columnKey];
  246. resultData3[columnKey] = data[columnKey];
  247. }
  248. }
  249. } else if (columnKey.startsWith('fan')) {
  250. const key1 = columnKey.replace('fan', 'fan1');
  251. const key2 = columnKey.replace('fan', 'fan2');
  252. const key3 = columnKey.replace('fan', 'fan3');
  253. if (columnKey.endsWith('_merge')) {
  254. resultData1[columnKey] =
  255. !data[key1] || data[key1] == 0 || data[key1] == null || data[key1] == undefined ? data[key2] : data[key1] || data[key3];
  256. } else {
  257. if (columnKey.startsWith('fanStartStatus')) {
  258. resultData1[columnKey] = data[key1];
  259. resultData2[columnKey] = data[key2];
  260. resultData3[columnKey] = data[key3];
  261. } else {
  262. resultData1[columnKey] = data['fan1StartStatus'] == '0' && globalConfig?.simulatedPassword ? '-' : data[key1];
  263. resultData2[columnKey] = data['fan2StartStatus'] == '0' && globalConfig?.simulatedPassword ? '-' : data[key2];
  264. resultData3[columnKey] = data['fan3StartStatus'] == '0' && globalConfig?.simulatedPassword ? '-' : data[key3];
  265. }
  266. if (resultData1[columnKey] == undefined && resultData2[columnKey] == undefined) {
  267. resultData1[columnKey] = data[columnKey];
  268. resultData2[columnKey] = data[columnKey];
  269. resultData3[columnKey] = data[columnKey];
  270. }
  271. }
  272. } else if (columnKey.endsWith('_merge')) {
  273. resultData1[columnKey] = data[columnKey];
  274. } else {
  275. resultData1[columnKey] = resultData2[columnKey] = resultData3[columnKey] = data[columnKey];
  276. }
  277. }
  278. });
  279. resultData1['deviceID'] = resultData2['deviceID'] = data['deviceID'];
  280. if (props.columnsType.startsWith('fanlocal') && sysOrgCode !== 'zmhjhzmy') {
  281. resultData1['runDevice'] = '主机';
  282. resultData2['runDevice'] = '备机';
  283. } else {
  284. resultData1['runDevice'] = '1#风机';
  285. resultData2['runDevice'] = '2#风机';
  286. resultData3['runDevice'] = '3#风机';
  287. resultData1['modalTyoe'] = modalTyoe;
  288. resultData2['modalTyoe'] = modalTyoe;
  289. resultData3['modalTyoe'] = modalTyoe;
  290. }
  291. if (modalTyoe === 'lijing_3') {
  292. list.push(resultData1, resultData2, resultData3);
  293. } else {
  294. list.push(resultData1, resultData2);
  295. }
  296. });
  297. dataTableSource.value = list;
  298. loading.value = false;
  299. }
  300. );
  301. watch(
  302. () => props.scroll.y,
  303. (newVal) => {
  304. if (newVal) {
  305. scrollY = newVal;
  306. tableScroll.value = { y: newVal - (headElHeight.value - 56), x: 'max-content' };
  307. } else {
  308. tableScroll.value = {};
  309. }
  310. }
  311. );
  312. onMounted(() => {
  313. // 如果是https
  314. // 反之是websocket
  315. });
  316. onUnmounted(() => {});
  317. defineExpose({
  318. setSelectedRowKeys,
  319. });
  320. </script>
  321. <style scoped lang="less">
  322. @ventSpace: zxm;
  323. :deep(.@{ventSpace}-table-body) {
  324. height: auto !important;
  325. &::-webkit-scrollbar {
  326. height: 10px !important;
  327. }
  328. }
  329. :deep(.jeecg-basic-table .@{ventSpace}-table-wrapper .@{ventSpace}-table-title) {
  330. min-height: 0;
  331. }
  332. </style>