GroupMonitorTable.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  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. function setColumns(columnsType) {
  100. const isCheckColumn = {
  101. title: '',
  102. dataIndex: 'isCheck',
  103. width: 40,
  104. align: 'center',
  105. customCell: (_, index) => {
  106. const columnNum = _.modalTyoe ? (_.modalTyoe.endsWith('_3') ? 3 : _.modalTyoe.endsWith('_1') ? 1 : 2) : 2;
  107. if (_.rowIndex % columnNum == 0) {
  108. return { rowSpan: columnNum };
  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. const columnNum = _.modalTyoe ? (_.modalTyoe.endsWith('_3') ? 3 : _.modalTyoe.endsWith('_1') ? 1 : 2) : 2;
  121. if (_.rowIndex % columnNum == 0) {
  122. return { rowSpan: columnNum };
  123. } else {
  124. return { rowSpan: 0 };
  125. }
  126. },
  127. customRender: ({ text, record, index }) => {
  128. return record.index + 1;
  129. },
  130. };
  131. const runDevice = {
  132. title: '风机',
  133. dataIndex: 'runDevice',
  134. width: 80,
  135. align: 'center',
  136. };
  137. columns.value = getTableHeaderColumns(columnsType);
  138. console.log('风机columns------------------>', columnsType);
  139. if (columns.value && columns.value.length < 1) {
  140. columns.value = getTableHeaderColumns(columnsType.split('_')[0] + '_monitor');
  141. }
  142. const strinstallpos = columns.value.find((item) => {
  143. return item.dataIndex === 'strinstallpos' || item.dataIndex === 'strname';
  144. });
  145. if (strinstallpos) {
  146. strinstallpos.customCell = (_, index) => {
  147. const columnNum = _.modalTyoe ? (_.modalTyoe.endsWith('_3') ? 3 : _.modalTyoe.endsWith('_1') ? 1 : 2) : 2;
  148. if (_.rowIndex % columnNum == 0) {
  149. return { rowSpan: columnNum };
  150. } else {
  151. return { rowSpan: 0 };
  152. }
  153. };
  154. }
  155. columns.value.forEach((item) => {
  156. if (item.dataIndex === 'strinstallpos' || item.dataIndex === 'strname' || item.dataIndex.endsWith('_merge')) {
  157. item.customCell = (_, index) => {
  158. const columnNum = _.modalTyoe ? (_.modalTyoe.endsWith('_3') ? 3 : _.modalTyoe.endsWith('_1') ? 1 : 2) : 2;
  159. if (_.rowIndex % columnNum == 0) {
  160. return { rowSpan: columnNum };
  161. } else {
  162. return { rowSpan: 0 };
  163. }
  164. };
  165. }
  166. });
  167. columns.value.splice(1, 0, runDevice);
  168. if (props.isShowSelect) {
  169. columns.value = [isCheckColumn, indexColumn, ...columns.value];
  170. } else {
  171. columns.value = [indexColumn, ...columns.value];
  172. }
  173. if (props.isAction) {
  174. columns.value = [
  175. ...columns.value,
  176. {
  177. title: '操作',
  178. dataIndex: 'operation',
  179. width: 120,
  180. align: 'center',
  181. slots: { customRender: 'operation' },
  182. customCell: (_, index) => {
  183. const columnNum = _.modalTyoe ? (_.modalTyoe.endsWith('_3') ? 3 : _.modalTyoe.endsWith('_1') ? 1 : 2) : 2;
  184. if (_.rowIndex % columnNum == 0) {
  185. return { rowSpan: columnNum };
  186. } else {
  187. return { rowSpan: 0 };
  188. }
  189. },
  190. },
  191. ];
  192. }
  193. // columns.value = [...columns.value, ...columns.value]
  194. return columns;
  195. }
  196. watch(
  197. () => {
  198. return props.columnsType;
  199. },
  200. (newVal, oldVal) => {
  201. if (!newVal) return;
  202. setColumns(newVal);
  203. nextTick(() => {
  204. const headEl = document.querySelector(`.zxm-table-thead`);
  205. if (headEl) {
  206. headElHeight.value = headEl.clientHeight;
  207. tableScroll.value = { y: (scrollY || props.scroll.y) - (headElHeight.value - 56), x: 'max-content' };
  208. }
  209. });
  210. },
  211. {
  212. immediate: true,
  213. }
  214. );
  215. watch(
  216. () => {
  217. return props.dataSource;
  218. },
  219. (newVal, oldVal) => {
  220. const list: unknown[] = [];
  221. newVal.forEach((item, index) => {
  222. const data: any = toRaw(item);
  223. if (data.deviceType.startsWith('fanlocal') && data.install_kind) {
  224. data['modalTyoe'] = data.install_kind;
  225. }
  226. const modalTyoe = data.modalTyoe;
  227. const resultData1 = {};
  228. const resultData2 = {};
  229. const resultData3 = {};
  230. // 将主风机、备风机的数据进行拆分
  231. columns.value.forEach((column) => {
  232. const columnKey = column.dataIndex;
  233. if (columnKey) {
  234. if (columnKey.startsWith('Fan')) {
  235. const key1 = columnKey.replace('Fan', 'Fan1');
  236. const key2 = columnKey.replace('Fan', 'Fan2');
  237. const key3 = columnKey.replace('Fan', 'Fan3');
  238. if (columnKey.endsWith('_merge')) {
  239. resultData1[columnKey] = data[key1] == 0 || data[key1] == null || data[key1] == undefined ? data[key2] : data[key1] || data[key3];
  240. } else {
  241. if (columnKey.startsWith('FanStartStatus')) {
  242. resultData1[columnKey] = data[key1];
  243. resultData2[columnKey] = data[key2];
  244. resultData3[columnKey] = data[key3];
  245. } else {
  246. resultData1[columnKey] = data['Fan1StartStatus'] == '0' && globalConfig?.simulatedPassword ? '-' : data[key1];
  247. resultData2[columnKey] = data['Fan2StartStatus'] == '0' && globalConfig?.simulatedPassword ? '-' : data[key2];
  248. resultData3[columnKey] = data['Fan3StartStatus'] == '0' && globalConfig?.simulatedPassword ? '-' : data[key3];
  249. }
  250. if (resultData1[columnKey] == undefined && resultData2[columnKey] == undefined) {
  251. resultData1[columnKey] = data[columnKey];
  252. resultData2[columnKey] = data[columnKey];
  253. resultData3[columnKey] = data[columnKey];
  254. }
  255. }
  256. } else if (columnKey.startsWith('fan')) {
  257. const key1 = columnKey.replace('fan', 'fan1');
  258. const key2 = columnKey.replace('fan', 'fan2');
  259. const key3 = columnKey.replace('fan', 'fan3');
  260. if (columnKey.endsWith('_merge')) {
  261. resultData1[columnKey] =
  262. !data[key1] || data[key1] == 0 || data[key1] == null || data[key1] == undefined ? data[key2] : data[key1] || data[key3];
  263. } else {
  264. if (columnKey.startsWith('fanStartStatus')) {
  265. resultData1[columnKey] = data[key1];
  266. resultData2[columnKey] = data[key2];
  267. resultData3[columnKey] = data[key3];
  268. } else {
  269. resultData1[columnKey] = data['fan1StartStatus'] == '0' && globalConfig?.simulatedPassword ? '-' : data[key1];
  270. resultData2[columnKey] = data['fan2StartStatus'] == '0' && globalConfig?.simulatedPassword ? '-' : data[key2];
  271. resultData3[columnKey] = data['fan3StartStatus'] == '0' && globalConfig?.simulatedPassword ? '-' : data[key3];
  272. }
  273. if (resultData1[columnKey] == undefined && resultData2[columnKey] == undefined) {
  274. resultData1[columnKey] = data[columnKey];
  275. resultData2[columnKey] = data[columnKey];
  276. resultData3[columnKey] = data[columnKey];
  277. }
  278. }
  279. } else if (columnKey.endsWith('_merge')) {
  280. resultData1[columnKey] = data[columnKey];
  281. } else {
  282. resultData1[columnKey] = resultData2[columnKey] = resultData3[columnKey] = data[columnKey];
  283. }
  284. }
  285. });
  286. resultData1['deviceID'] = resultData2['deviceID'] = data['deviceID'];
  287. if (props.columnsType.startsWith('fanlocal') && sysOrgCode !== 'zmhjhzmy') {
  288. resultData1['runDevice'] = '主机';
  289. resultData2['runDevice'] = '备机';
  290. } else {
  291. resultData1['runDevice'] = '1#风机';
  292. resultData2['runDevice'] = '2#风机';
  293. resultData3['runDevice'] = '3#风机';
  294. }
  295. resultData1['modalTyoe'] = modalTyoe;
  296. resultData2['modalTyoe'] = modalTyoe;
  297. resultData3['modalTyoe'] = modalTyoe;
  298. resultData1['rowIndex'] = 0;
  299. resultData2['rowIndex'] = 1;
  300. resultData3['rowIndex'] = 2;
  301. resultData1['index'] = index;
  302. resultData2['index'] = index;
  303. resultData3['index'] = index;
  304. if (modalTyoe && modalTyoe.endsWith('_3')) {
  305. list.push(resultData1, resultData2, resultData3);
  306. } else if (modalTyoe && modalTyoe.endsWith('_1')) {
  307. list.push(resultData1);
  308. // list.push(resultData1, resultData2);
  309. } else {
  310. list.push(resultData1, resultData2);
  311. }
  312. });
  313. dataTableSource.value = list;
  314. loading.value = false;
  315. }
  316. );
  317. watch(
  318. () => props.scroll.y,
  319. (newVal) => {
  320. if (newVal) {
  321. scrollY = newVal;
  322. tableScroll.value = { y: newVal - (headElHeight.value - 56), x: 'max-content' };
  323. } else {
  324. tableScroll.value = {};
  325. }
  326. }
  327. );
  328. onMounted(() => {
  329. // 如果是https
  330. // 反之是websocket
  331. });
  332. onUnmounted(() => {});
  333. defineExpose({
  334. setSelectedRowKeys,
  335. });
  336. </script>
  337. <style scoped lang="less">
  338. @ventSpace: zxm;
  339. :deep(.@{ventSpace}-table-body) {
  340. height: auto !important;
  341. &::-webkit-scrollbar {
  342. height: 10px !important;
  343. }
  344. }
  345. :deep(.jeecg-basic-table .@{ventSpace}-table-wrapper .@{ventSpace}-table-title) {
  346. min-height: 0;
  347. }
  348. </style>