From 0b20cec9bd6879aa3a2268ee7935b3f082e400ce Mon Sep 17 00:00:00 2001 From: zhongzm Date: Thu, 16 Jan 2025 20:45:33 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=E7=BB=88=E7=AB=AF=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E7=95=8C=E9=9D=A2=E4=BF=A1=E6=81=AF=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/service/api/auth.ts | 31 ++++++++ src/typings/api.d.ts | 39 +++++++++- src/typings/auto-imports.d.ts | 4 + src/views/device/terminal/index.vue | 116 +++++++++++++++++++++++++--- 4 files changed, 177 insertions(+), 13 deletions(-) diff --git a/src/service/api/auth.ts b/src/service/api/auth.ts index cb674bd..8988322 100644 --- a/src/service/api/auth.ts +++ b/src/service/api/auth.ts @@ -217,6 +217,37 @@ export function getDashboardSiteList(params: { pageNum: number; pageSize: number params }); } +/** 获取KYC审核列表 */ +export function fetchKycList(params: Api.Kyc.KycParams) { + return request({ + url: '/system/kyc/page', + method: 'get', + params + }); +} +/** KYC审核通过 */ +export function approveKyc(id: string, userId: number) { + return request({ + url: `/system/kyc/approve`, + method: 'put', + data: { id, userId } + }); +} + +/** KYC审核拒绝 */ +export function rejectKyc(id: string, userId: number, reason: string) { + return request({ + url: `/system/kyc/reject`, + method: 'put', + data: { + id, + userId, + description: reason + } + }); +} + + diff --git a/src/typings/api.d.ts b/src/typings/api.d.ts index 434079b..bcee2fa 100644 --- a/src/typings/api.d.ts +++ b/src/typings/api.d.ts @@ -565,9 +565,15 @@ declare namespace Api { interface TerminalDevice { id: number; - clientName: string; - clientDeviceType: string; - clientMac: string; + name: string; + ip: string; + authStatus: number; + ssid: string; + apName: string; + activity: number; + trafficDown: number; + trafficUp: number; + uptime: number; createBy: string | null; createTime: string; updateBy: string | null; @@ -663,4 +669,31 @@ declare namespace Api { rows: DashboardSite[]; total: number; } + namespace Kyc { + interface KycInfo { + id: string; + userId: number; + userName: string; + fullName: string; + idType: string; + idFile: string; + identifyPicture: string; + status: string; + reason?: string; + createTime: string; + updateTime: string; + } + + interface KycParams { + pageNum: number; + pageSize: number; + userName?: string; + status?: number; + } + + interface KycResponse { + rows: KycInfo[]; + total: number; + } + } } diff --git a/src/typings/auto-imports.d.ts b/src/typings/auto-imports.d.ts index e5a4198..60e2acc 100644 --- a/src/typings/auto-imports.d.ts +++ b/src/typings/auto-imports.d.ts @@ -17,6 +17,7 @@ declare global { const addThemeVarsToHtml: typeof import('../store/modules/theme/shared')['addThemeVarsToHtml'] const afterAll: typeof import('vitest')['afterAll'] const afterEach: typeof import('vitest')['afterEach'] + const approveKyc: typeof import('../service/api/auth')['approveKyc'] const assert: typeof import('vitest')['assert'] const assign: typeof import('lodash-es')['assign'] const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] @@ -132,6 +133,8 @@ declare global { const fetchGetConstantRoutes: typeof import('../service/api/route')['fetchGetConstantRoutes'] const fetchGetMenuTree: typeof import('../service/api/menu')['fetchGetMenuTree'] const fetchIsRouteExist: typeof import('../service/api/route')['fetchIsRouteExist'] + const fetchKycImg: typeof import('../service/api/auth')['fetchKycImg'] + const fetchKycList: typeof import('../service/api/auth')['fetchKycList'] const fetchLogin: typeof import('../service/api/auth')['fetchLogin'] const fetchPackageList: typeof import('../service/api/auth')['fetchPackageList'] const fetchRateLimitList: typeof import('../service/api/auth')['fetchRateLimitList'] @@ -230,6 +233,7 @@ declare global { const refDefault: typeof import('@vueuse/core')['refDefault'] const refThrottled: typeof import('@vueuse/core')['refThrottled'] const refWithControl: typeof import('@vueuse/core')['refWithControl'] + const rejectKyc: typeof import('../service/api/auth')['rejectKyc'] const removeEmptyChildren: typeof import('../utils/menu')['removeEmptyChildren'] const removeRateLimit: typeof import('../service/api/auth')['removeRateLimit'] const resolveComponent: typeof import('vue')['resolveComponent'] diff --git a/src/views/device/terminal/index.vue b/src/views/device/terminal/index.vue index e83211f..dc0404b 100644 --- a/src/views/device/terminal/index.vue +++ b/src/views/device/terminal/index.vue @@ -56,8 +56,9 @@ import { SimpleScrollbar } from '~/packages/materials/src'; import { computed, shallowRef, watch } from 'vue'; import { useElementSize } from '@vueuse/core'; import { fetchTerminalList } from '@/service/api/auth'; -import { Card as ACard, Table as ATable } from 'ant-design-vue'; +import { Card as ACard, Table as ATable, Tag as ATag } from 'ant-design-vue'; import TerminalSearch from './modules/terminal-search.vue'; +import { formatStorage, formatTime } from '@/utils/units'; const wrapperEl = shallowRef(null); @@ -68,6 +69,43 @@ const scrollConfig = computed(() => ({ x: 800 })); +const getAuthStatusText = (status: number) => { + switch (status) { + case 1: + return 'pending'; + case 2: + return 'authorized'; + default: + return '未知'; + } +}; + +const getAuthStatusColor = (status: number) => { + switch (status) { + case 1: + return 'warning'; + case 2: + return 'success'; + default: + return 'default'; + } +}; + +const formatDetailedTime = (seconds: number): string => { + const days = Math.floor(seconds / 86400); + const hours = Math.floor((seconds % 86400) / 3600); + const minutes = Math.floor((seconds % 3600) / 60); + const remainingSeconds = seconds % 60; + + const parts = []; + if (days > 0) parts.push(`${days}天`); + if (hours > 0) parts.push(`${hours}小时`); + if (minutes > 0) parts.push(`${minutes}分钟`); + if (remainingSeconds > 0 || parts.length === 0) parts.push(`${remainingSeconds}秒`); + + return parts.join(''); +}; + const { columns, columnChecks, @@ -114,25 +152,83 @@ const { pagination: true, columns: (): AntDesign.TableColumn[] => [ { - key: 'clientName', - dataIndex: 'clientName', + key: 'name', + dataIndex: 'name', title: '设备名称', align: 'center', width: 150 }, { - key: 'clientDeviceType', - dataIndex: 'clientDeviceType', - title: '设备类型', + key: 'ip', + dataIndex: 'ip', + title: 'IP地址', align: 'center', width: 150 }, { - key: 'clientMac', - dataIndex: 'clientMac', - title: 'MAC地址', + key: 'authStatus', + dataIndex: 'authStatus', + title: '状态', align: 'center', - width: 180 + width: 120, + customRender: ({ text }) => h(ATag, { + color: getAuthStatusColor(text) + }, () => getAuthStatusText(text)) + }, + { + key: 'ssid', + dataIndex: 'ssid', + title: '网络', + align: 'center', + width: 150 + }, + { + key: 'apName', + dataIndex: 'apName', + title: '所属AP设备', + align: 'center', + width: 150 + }, + { + key: 'activity', + dataIndex: 'activity', + title: '下载速率', + align: 'center', + width: 120, + customRender: ({ text }) => { + const { value, unit } = formatStorage(text); + return `${value.toFixed(2)} ${unit}/s`; + } + }, + { + key: 'trafficDown', + dataIndex: 'trafficDown', + title: '下载量', + align: 'center', + width: 120, + customRender: ({ text }) => { + const { value, unit } = formatStorage(text); + return `${value.toFixed(2)} ${unit}`; + } + }, + { + key: 'trafficUp', + dataIndex: 'trafficUp', + title: '上传量', + align: 'center', + width: 120, + customRender: ({ text }) => { + const { value, unit } = formatStorage(text); + return `${value.toFixed(2)} ${unit}`; + } + }, + { + key: 'uptime', + dataIndex: 'uptime', + title: '在线时长', + align: 'center', + width: 150, + customRender: ({ text }) => formatDetailedTime(text) } ] });