manage.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. <template>
  2. <div class="main-wrap flex flex-col gap-y-2 p-4">
  3. <NCard>
  4. <div class="mb-2 flex gap-x-4">
  5. <NForm ref="formRef" :model="form" inline label-placement="left">
  6. <NFormItem label="SN" path="sn">
  7. <NInput v-model:value="form.sn" style="width: 250px" clearable />
  8. </NFormItem>
  9. <NFormItem label="UUID" path="uuid">
  10. <NInput v-model:value="form.uuid" style="width: 250px" clearable />
  11. </NFormItem>
  12. </NForm>
  13. <div class="flex gap-2">
  14. <NButton disabled type="success" @click="createXlogConnect()">
  15. <template #icon>
  16. <span class="i-ph:plus-circle" />
  17. </template>
  18. 新增xlog
  19. </NButton>
  20. <NButton type="info" @click="handleQueryClick" :loading="isRequestLoading" :disabled="isRequestLoading">
  21. <template #icon>
  22. <span class="i-ph:magnifying-glass" />
  23. </template>
  24. 查询
  25. </NButton>
  26. <NButton type="warning" @click="resetForm">
  27. <template #icon>
  28. <span class="i-ph:arrow-clockwise" />
  29. </template>
  30. 重置
  31. </NButton>
  32. </div>
  33. </div>
  34. <div>
  35. <NDataTable ref="dataTableRef" v-model:checked-row-keys="checkedRowKeys" :remote="true" :min-height="166.6"
  36. :max-height="maxHeight" size="small" :columns="tableColumns" :data="tableData" :row-key="tableRowKey"
  37. :loading="isRequestLoading" striped :single-line="false" :row-props="rowProps" />
  38. <div class="mt-3 flex items-end justify-between">
  39. <div class="flex items-center gap-x-3">
  40. <span>已选择&nbsp;{{ checkedRowKeys.length }}&nbsp; 条</span>
  41. </div>
  42. <NPagination v-bind="tablePagination" :prefix="paginationPrefix" />
  43. </div>
  44. </div>
  45. </NCard>
  46. <NDropdown placement="bottom-start" trigger="manual" v-bind="dropdownOptions" :show="showDropdown" />
  47. </div>
  48. </template>
  49. <script setup lang="tsx">
  50. import { h } from 'vue'
  51. import { useRouter } from 'vue-router'
  52. import { NButton, NDataTable, NForm, NNumberAnimation } from 'naive-ui'
  53. import type { DataTableColumns, PaginationProps, DropdownProps } from 'naive-ui'
  54. import type { XlogSiteItemInfo } from '@/service/xlog/interface'
  55. import { getManageList } from '@/service/xlog'
  56. import { useDataTable } from '@/composable/comp/useDataTable'
  57. import { useResettableReactive } from '@/composable/useResettable'
  58. const router = useRouter()
  59. const formRef = useTemplateRef<InstanceType<typeof NForm>>('formRef')
  60. const dataTableRef = useTemplateRef<InstanceType<typeof NDataTable>>('dataTableRef')
  61. const { maxHeight } = useDataTable(dataTableRef)
  62. const isRequestLoading = ref(false)
  63. const showDropdown = ref(false)
  64. const checkedRowKeys = ref<Array<number | string>>([])
  65. const contextmenuUUID = ref<string | undefined>(undefined)
  66. interface XlogSiteFilterForm extends Partial<XlogSiteItemInfo> { }
  67. const [form, , resetForm] = useResettableReactive<XlogSiteFilterForm>({
  68. sn: '',
  69. uuid: '',
  70. })
  71. const handleQueryClick = () => {
  72. // 请求查询数据
  73. handleListQuery()
  74. }
  75. const prevUserListTotal = ref(0)
  76. const paginationPrefix: PaginationProps['prefix'] = (info) => {
  77. const { itemCount } = info
  78. return (
  79. itemCount && (
  80. <div>
  81. <span>总&nbsp; </span>
  82. < NNumberAnimation
  83. from={prevUserListTotal.value}
  84. to={itemCount}
  85. onFinish={() => {
  86. prevUserListTotal.value = itemCount
  87. }}
  88. />
  89. <span>&nbsp;条 </span>
  90. </div>
  91. )
  92. )
  93. }
  94. const dropdownOptions = reactive<DropdownProps>({
  95. x: 0,
  96. y: 0,
  97. options: [
  98. {
  99. label: () => <span class='text-green-500'> 查看 </span>,
  100. key: 'view',
  101. },
  102. ],
  103. onClickoutside: () => {
  104. showDropdown.value = false
  105. },
  106. onSelect: (key: string) => {
  107. showDropdown.value = false
  108. if (contextmenuUUID.value === undefined) return
  109. if (key === 'view') {
  110. itemView(contextmenuUUID.value, "")
  111. }
  112. },
  113. })
  114. const createXlogConnect = () => {
  115. // TODO 创建xlog连接
  116. }
  117. const tableRowKey = (rowData: XlogSiteItemInfo) => {
  118. return rowData.sn
  119. }
  120. function createColumns(): DataTableColumns<XlogSiteItemInfo> {
  121. return [
  122. {
  123. type: 'selection',
  124. fixed: 'left'
  125. },
  126. {
  127. title: 'SN',
  128. key: 'sn',
  129. width: 200,
  130. },
  131. {
  132. title: 'UUID',
  133. key: 'uuid',
  134. },
  135. {
  136. title: '操作',
  137. key: 'operate',
  138. width: 80,
  139. fixed: 'right',
  140. render(row) {
  141. return h('div', { class: 'flex justify-center gap-4 p-x-4' }, [
  142. h(NButton, {
  143. type: "success",
  144. strong: true,
  145. size: 'small',
  146. onClick: () => itemView(row.uuid, "")
  147. }, {
  148. default: () => '查看'
  149. })
  150. ])
  151. }
  152. }
  153. ]
  154. }
  155. // 表格右键菜单
  156. function rowProps(row: XlogSiteItemInfo) {
  157. return {
  158. onContextmenu: (e: MouseEvent) => {
  159. e.preventDefault()
  160. showDropdown.value = false
  161. nextTick().then(() => {
  162. contextmenuUUID.value = row.uuid
  163. showDropdown.value = true
  164. dropdownOptions.x = e.clientX
  165. dropdownOptions.y = e.clientY
  166. })
  167. },
  168. }
  169. }
  170. const tableData = ref<XlogSiteItemInfo[]>([])
  171. const tableColumns = createColumns()
  172. const tablePagination = reactive<PaginationProps>({
  173. page: 1,
  174. pageSize: 10,
  175. showSizePicker: true,
  176. pageSizes: [10, 20, 50, 100],
  177. itemCount: 0,
  178. showQuickJumper: true,
  179. showQuickJumpDropdown: true,
  180. onUpdatePage: (page: number) => {
  181. tablePagination.page = page
  182. handleListQuery()
  183. },
  184. onUpdatePageSize: (pageSize: number) => {
  185. tablePagination.pageSize = pageSize
  186. tablePagination.page = 1
  187. handleListQuery()
  188. },
  189. })
  190. const itemView = (uuid: string, sn: string) => {
  191. router.push({
  192. path: `/xlog-terminal/${uuid}`,
  193. query: { sn },
  194. })
  195. }
  196. interface XlogSiteListFilter {
  197. sn?: string
  198. uuid?: string
  199. }
  200. const queryXlogSiteList = async (pageSize: number, pageNum: number, filter?: XlogSiteListFilter) => {
  201. const siteList = await getManageList(pageSize, pageNum, filter)
  202. tableData.value = siteList.data
  203. tablePagination.itemCount = siteList.total
  204. }
  205. const handleListQuery = () => {
  206. const pageSize = tablePagination.pageSize ?? 10
  207. const page = tablePagination.page ?? 1
  208. // 处理过滤条件
  209. const filter = {
  210. sn: form.sn,
  211. uuid: form.uuid
  212. }
  213. queryXlogSiteList(pageSize, page, filter)
  214. }
  215. onMounted(() => {
  216. handleListQuery()
  217. })
  218. </script>