GatewayProtocol.vue 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. <script setup lang="ts">
  2. import { computed, onMounted, reactive, ref, useTemplateRef } from 'vue';
  3. import { message, Modal } from 'ant-design-vue';
  4. import ModalGuidance from '@/layout/ModalGuidance.vue';
  5. import SvgIcon from '@/components/SvgIcon.vue';
  6. import { useRequest } from '@/hooks/request';
  7. import { useViewVisible } from '@/hooks/view-visible';
  8. import { useUserInfoStore } from '@/stores/user-info';
  9. import { t } from '@/i18n';
  10. import { deleteProtocolBaseInfo, getProtocolList, updateProtocolBaseInfo } from '@/api';
  11. import { getTablePageSorts } from '@/utils';
  12. import { OperatePermission } from '@/utils/permission-type';
  13. import ProtocolContent from '../setup-protocol/ProtocolContent.vue';
  14. import SetupProtocol from '../setup-protocol/SetupProtocol.vue';
  15. import type { ColumnType, TableProps } from 'ant-design-vue/es/table';
  16. import type { PageParams, ProtocolBaseInfo } from '@/types';
  17. const { booleanPermission } = useUserInfoStore();
  18. const protocolInitialInfo: Partial<ProtocolBaseInfo> = {
  19. id: undefined,
  20. protocolName: '',
  21. protocolType: undefined,
  22. deviceType: undefined,
  23. dataBit: 5,
  24. parityBit: 'N',
  25. stopBit: '1',
  26. baudRate: undefined,
  27. dataSendInterval: undefined,
  28. highFreqSendInterval: undefined,
  29. readTimeout: undefined,
  30. nextDataReadDelay: undefined,
  31. nextRoundDataReadDelay: undefined,
  32. readContinuousAddr: '关',
  33. readContinuousAddrCode: 0,
  34. readContinuousAddrLength: undefined,
  35. byteOrder: undefined,
  36. byteOrderCode: undefined,
  37. addrOrder: undefined,
  38. addrOrderCode: undefined,
  39. };
  40. const protocolInfoForm = reactive<Partial<ProtocolBaseInfo>>({
  41. ...protocolInitialInfo,
  42. });
  43. const protocolList = ref<ProtocolBaseInfo[]>([]);
  44. const protocolTotal = ref(0);
  45. const searchContent = ref('');
  46. const pageParams = ref<PageParams>({
  47. pageIndex: 1,
  48. pageSize: 10,
  49. pageSorts: [
  50. {
  51. column: 'id',
  52. asc: true,
  53. },
  54. ],
  55. });
  56. const columns = computed<ColumnType<ProtocolBaseInfo>[]>(() => {
  57. return [
  58. {
  59. title: t('gatewayProtocol.protocolName'),
  60. dataIndex: 'protocolName',
  61. key: 'protocolName',
  62. },
  63. {
  64. title: t('setupProtocol.protocolType'),
  65. dataIndex: 'protocolType',
  66. key: 'protocolType',
  67. },
  68. {
  69. title: t('setupProtocol.deviceType'),
  70. dataIndex: 'deviceType',
  71. key: 'deviceType',
  72. },
  73. {
  74. title: t('common.updateTime'),
  75. dataIndex: 'updateTime',
  76. key: 'updateTime',
  77. sorter: true,
  78. },
  79. {
  80. title: t('common.operation'),
  81. key: 'action',
  82. },
  83. ];
  84. });
  85. onMounted(() => {
  86. getProtocolData();
  87. });
  88. const { isLoading, handleRequest } = useRequest();
  89. const getProtocolData = () => {
  90. handleRequest(async () => {
  91. const { records, total } = await getProtocolList({
  92. ...pageParams.value,
  93. searchContent: searchContent.value,
  94. isDraft: 0,
  95. });
  96. protocolList.value = records;
  97. protocolTotal.value = total;
  98. });
  99. };
  100. const handleSearch = () => {
  101. pageParams.value.pageIndex = 1;
  102. getProtocolData();
  103. };
  104. const handleReset = () => {
  105. searchContent.value = '';
  106. handleSearch();
  107. };
  108. const handleAdd = () => {
  109. modalGuidanceRef.value?.showView();
  110. };
  111. const handleEdit = (record: ProtocolBaseInfo) => {
  112. Object.assign(protocolInfoForm, record);
  113. showView();
  114. };
  115. const handleDelete = (record: ProtocolBaseInfo) => {
  116. Modal.confirm({
  117. title: t('gatewayProtocol.confirmDeleteProtocol', { name: record.protocolName }),
  118. async onOk() {
  119. try {
  120. await deleteProtocolBaseInfo(record.id);
  121. message.success(t('gatewayProtocol.deleteProtocolSuccessful'));
  122. pageParams.value.pageIndex = 1;
  123. getProtocolData();
  124. } catch (err) {
  125. message.error((err as Error).message);
  126. console.error(err);
  127. }
  128. },
  129. });
  130. };
  131. const handleProtocolTableChange: TableProps['onChange'] = (pagination, filters, sorter) => {
  132. pageParams.value.pageIndex = pagination.current || 1;
  133. pageParams.value.pageSize = pagination.pageSize || 10;
  134. pageParams.value.pageSorts = getTablePageSorts(sorter);
  135. getProtocolData();
  136. };
  137. const modalGuidanceRef = useTemplateRef('modalGuidance');
  138. const { isLoading: isConfirmLoading, handleRequest: handleModalConfirmRequest } = useRequest();
  139. const { visible, showView, hideView } = useViewVisible();
  140. const protocolContentRef = useTemplateRef('protocolContent');
  141. const handleClose = () => {
  142. Object.assign(protocolInfoForm, protocolInitialInfo);
  143. };
  144. const handleOk = () => {
  145. handleModalConfirmRequest(async () => {
  146. await protocolContentRef.value?.validateProtocolInfo();
  147. await protocolContentRef.value?.isAtLeastOneParam();
  148. await updateProtocolBaseInfo(protocolInfoForm);
  149. message.success(t('gatewayProtocol.editProtocolSuccessful'));
  150. getProtocolData();
  151. hideView();
  152. });
  153. };
  154. </script>
  155. <template>
  156. <AFlex justify="space-between">
  157. <div class="hvac-layout-main-title">{{ $t('navigation.protocolManage') }}</div>
  158. <AButton
  159. class="icon-button add-button"
  160. type="primary"
  161. @click="handleAdd"
  162. v-if="booleanPermission(OperatePermission.新增协议)"
  163. >
  164. <SvgIcon name="plus" />
  165. {{ $t('common.addNew') }}
  166. </AButton>
  167. </AFlex>
  168. <div class="protocol-list-container">
  169. <div class="protocol-search">
  170. <div>
  171. <span class="protocol-search-label">{{ $t('common.search') }}</span>
  172. <AInput
  173. v-model:value="searchContent"
  174. class="protocol-search-input"
  175. :placeholder="$t('gatewayProtocol.searchTip')"
  176. allow-clear
  177. />
  178. </div>
  179. <div>
  180. <AButton type="primary" @click="handleSearch">{{ $t('common.query') }}</AButton>
  181. <AButton @click="handleReset">{{ $t('common.reset') }}</AButton>
  182. </div>
  183. </div>
  184. <ATable
  185. class="hvac-table protocol-table"
  186. :data-source="protocolList"
  187. :columns="columns"
  188. row-key="id"
  189. :loading="isLoading"
  190. :pagination="{
  191. current: pageParams.pageIndex,
  192. pageSize: pageParams.pageSize,
  193. total: protocolTotal,
  194. showSizeChanger: true,
  195. showQuickJumper: true,
  196. hideOnSinglePage: false,
  197. showTotal: (total) => $t('common.pageTotal', { total }),
  198. }"
  199. @change="handleProtocolTableChange"
  200. >
  201. <template #bodyCell="{ column, record }">
  202. <span v-if="column.key === 'action'">
  203. <SvgIcon
  204. v-if="booleanPermission(OperatePermission.编辑协议)"
  205. class="action-icon"
  206. name="edit-o"
  207. @click="handleEdit(record as ProtocolBaseInfo)"
  208. />
  209. <SvgIcon
  210. v-if="booleanPermission(OperatePermission.删除协议)"
  211. class="action-icon"
  212. name="delete"
  213. @click="handleDelete(record as ProtocolBaseInfo)"
  214. />
  215. </span>
  216. </template>
  217. </ATable>
  218. <ModalGuidance ref="modalGuidance" @finish="getProtocolData">
  219. <SetupProtocol />
  220. </ModalGuidance>
  221. <AModal
  222. v-model:open="visible"
  223. wrap-class-name="gateway-protocol-modal"
  224. :title="$t('common.editor')"
  225. :width="1140"
  226. centered
  227. :mask-closable="false"
  228. :after-close="handleClose"
  229. :confirm-loading="isConfirmLoading"
  230. destroy-on-close
  231. @ok="handleOk"
  232. >
  233. <ProtocolContent ref="protocolContent" :info="protocolInfoForm" :is-recognized="false" disabled-form />
  234. </AModal>
  235. </div>
  236. </template>
  237. <style lang="scss">
  238. .gateway-protocol-modal {
  239. .ant-modal-content {
  240. height: 638px;
  241. }
  242. .ant-modal-body {
  243. height: calc(100% - 84px);
  244. overflow: hidden auto;
  245. }
  246. }
  247. </style>
  248. <style lang="scss" scoped>
  249. .protocol-list-container {
  250. padding: 24px;
  251. margin-top: 16px;
  252. background: var(--antd-color-bg-base);
  253. border-radius: 16px;
  254. }
  255. .protocol-search {
  256. display: flex;
  257. align-items: center;
  258. justify-content: space-between;
  259. button + button {
  260. margin-left: 12px;
  261. }
  262. }
  263. .protocol-search-label {
  264. margin-right: 12px;
  265. font-size: 14px;
  266. line-height: 22px;
  267. color: var(--antd-color-text);
  268. }
  269. .protocol-search-input {
  270. width: 256px;
  271. }
  272. .add-button {
  273. width: 84px;
  274. font-size: 14px;
  275. }
  276. .protocol-table {
  277. margin-top: 16px;
  278. }
  279. .action-icon {
  280. margin-right: 16px;
  281. font-size: 24px;
  282. color: var(--antd-color-primary);
  283. cursor: pointer;
  284. }
  285. </style>