fix:portal门户界面
This commit is contained in:
@@ -791,6 +791,58 @@ const local: any = {
|
|||||||
editSsid:'Edit ssid',
|
editSsid:'Edit ssid',
|
||||||
updateSuccess:'Update success',
|
updateSuccess:'Update success',
|
||||||
},
|
},
|
||||||
|
portal: {
|
||||||
|
title: 'Portal management',
|
||||||
|
name: 'Name',
|
||||||
|
selectSite:'no site',
|
||||||
|
authType: 'Authentication Type',
|
||||||
|
auth: {
|
||||||
|
none: 'No Authentication',
|
||||||
|
simplePassword: 'Simple password',
|
||||||
|
externalRadius: 'RADIUS server',
|
||||||
|
externalPortal: 'External Portal server',
|
||||||
|
hotspot: 'Hotspot',
|
||||||
|
ldap: 'LDAP'
|
||||||
|
},
|
||||||
|
addPortal: 'Add Portal',
|
||||||
|
enable: 'Enable',
|
||||||
|
ssid: 'SSID',
|
||||||
|
selectSsid: 'Please select SSID',
|
||||||
|
authTimeout: 'Authentication Timeout',
|
||||||
|
dailyLimit: 'Daily Limit',
|
||||||
|
enableDailyLimit: 'Enable',
|
||||||
|
httpsRedirect: 'HTTPS Redirection',
|
||||||
|
enableHttpsRedirect: 'Enable',
|
||||||
|
landingPage: 'Landing Page',
|
||||||
|
landingUrl: 'URL',
|
||||||
|
enterUrl: 'Please enter URL',
|
||||||
|
nameRequired: 'Please enter portal name',
|
||||||
|
ssidRequired: 'Please select SSID',
|
||||||
|
urlRequired: 'Please enter URL',
|
||||||
|
addSuccess: 'Add Success',
|
||||||
|
addError: 'Add Error',
|
||||||
|
total:'Total',
|
||||||
|
updateSuccess:'Update success',
|
||||||
|
editPortal:'Edit Portal',
|
||||||
|
timeUnit: {
|
||||||
|
min: 'Min',
|
||||||
|
hour: 'Hour',
|
||||||
|
day: 'Day'
|
||||||
|
},
|
||||||
|
landing: {
|
||||||
|
originalUrl: 'The Original URL',
|
||||||
|
promotionUrl: 'The Promotional URL',
|
||||||
|
logoutPage: 'The Success Page'
|
||||||
|
},
|
||||||
|
externalPortal: 'External Portal server',
|
||||||
|
ipAddress: 'IP Address',
|
||||||
|
url: 'URL',
|
||||||
|
ipRequired: 'Please enter IP',
|
||||||
|
invalidUrl: 'The URL is not formatted correctly',
|
||||||
|
confirmDelete: 'Confirm Delete',
|
||||||
|
deleteConfirmContent: 'Sure to delete portal {name} ?',
|
||||||
|
deleteSuccess: 'Delete success'
|
||||||
|
},
|
||||||
terminal:{
|
terminal:{
|
||||||
title:'Terminal',
|
title:'Terminal',
|
||||||
total:'Total',
|
total:'Total',
|
||||||
|
|||||||
@@ -736,7 +736,7 @@ const local:any = {
|
|||||||
forgetConfirm:'确认要移除设备吗?',
|
forgetConfirm:'确认要移除设备吗?',
|
||||||
restartConfirm:'确认要重启设备吗?',
|
restartConfirm:'确认要重启设备吗?',
|
||||||
led:'LED',
|
led:'LED',
|
||||||
useSiteSettings:'站点设置',
|
useSiteSettings:'使用站点设置',
|
||||||
on:'打开',
|
on:'打开',
|
||||||
off:'关闭',
|
off:'关闭',
|
||||||
longitude:'经度(可选)',
|
longitude:'经度(可选)',
|
||||||
@@ -758,6 +758,92 @@ const local:any = {
|
|||||||
configError:'配置失败',
|
configError:'配置失败',
|
||||||
|
|
||||||
},
|
},
|
||||||
|
wlan:{
|
||||||
|
title:'无线网络',
|
||||||
|
selectSite:'无站点',
|
||||||
|
selectGroup:'无网络组',
|
||||||
|
total:'共',
|
||||||
|
name:'SSid名称',
|
||||||
|
security:'安全性',
|
||||||
|
none:'无',
|
||||||
|
wpaEnterprise:'WPA-Enterprise',
|
||||||
|
wpaPersonal:'WPA-Personal',
|
||||||
|
ppskWithoutRadius:'PPSK without RADIUS',
|
||||||
|
ppskWithRadius:'PPSK with RADIUS',
|
||||||
|
band:'频段',
|
||||||
|
guestNetwork:'访客网络',
|
||||||
|
enable:'开启',
|
||||||
|
disable:'关闭',
|
||||||
|
deviceType:'设备类型',
|
||||||
|
broadcast:'广播',
|
||||||
|
vlan:'VLAN',
|
||||||
|
addSsid:'Ssid配置',
|
||||||
|
open:'开启',
|
||||||
|
vlanId:'VLAN ID',
|
||||||
|
default:'默认',
|
||||||
|
custom:'定制',
|
||||||
|
nameRequired:'名称不能为空',
|
||||||
|
nameLength:'名称长度1~32字符',
|
||||||
|
vlanIdRequired:'VLAN ID不能为空',
|
||||||
|
addSuccess:'添加成功',
|
||||||
|
confirmDelete:'删除设备',
|
||||||
|
deleteConfirmContent:'确认要删除设备吗',
|
||||||
|
deleteSuccess:'删除成功',
|
||||||
|
editSsid:'修改配置',
|
||||||
|
updateSuccess:'修改成功',
|
||||||
|
},
|
||||||
|
portal: {
|
||||||
|
title: '门户管理',
|
||||||
|
name: '名称',
|
||||||
|
selectSite:'无站点',
|
||||||
|
authType: '身份验证类型',
|
||||||
|
auth: {
|
||||||
|
none: '无认证',
|
||||||
|
simplePassword: '简单密码',
|
||||||
|
externalRadius: '外部 Radius 服务器',
|
||||||
|
externalPortal: '外部 Portal 服务器',
|
||||||
|
hotspot: '热点',
|
||||||
|
ldap: 'LDAP 格式'
|
||||||
|
},
|
||||||
|
addPortal: '添加门户',
|
||||||
|
enable: '启用',
|
||||||
|
ssid: 'SSID',
|
||||||
|
selectSsid: '请选择SSID',
|
||||||
|
authTimeout: '身份验证时间',
|
||||||
|
dailyLimit: '每日限额',
|
||||||
|
enableDailyLimit: '启用每日限额',
|
||||||
|
httpsRedirect: 'HTTPS 重定向',
|
||||||
|
enableHttpsRedirect: '启用 HTTPS 重定向',
|
||||||
|
landingPage: '登录页面',
|
||||||
|
landingUrl: '促销 URL',
|
||||||
|
enterUrl: '请输入 URL',
|
||||||
|
nameRequired: '请输入门户名称',
|
||||||
|
ssidRequired: '请选择 SSID',
|
||||||
|
urlRequired: '请输入 URL',
|
||||||
|
addSuccess: '添加成功',
|
||||||
|
addError: '添加失败',
|
||||||
|
total:'共',
|
||||||
|
updateSuccess:'更新成功',
|
||||||
|
editPortal:'修改配置',
|
||||||
|
timeUnit: {
|
||||||
|
min: '分钟',
|
||||||
|
hour: '小时',
|
||||||
|
day: '天'
|
||||||
|
},
|
||||||
|
landing: {
|
||||||
|
originalUrl: '重定向到原始 URL',
|
||||||
|
promotionUrl: '重定向到促销 URL',
|
||||||
|
logoutPage: '重定向到注销页面'
|
||||||
|
},
|
||||||
|
externalPortal: '自定义 Portal 服务器',
|
||||||
|
ipAddress: 'IP地址',
|
||||||
|
url: 'URL',
|
||||||
|
ipRequired: '请输入IP地址',
|
||||||
|
invalidUrl: 'URL 格式不正确',
|
||||||
|
confirmDelete: '确认删除',
|
||||||
|
deleteConfirmContent: '确定要删除门户 {name} 吗?',
|
||||||
|
deleteSuccess: '删除成功'
|
||||||
|
},
|
||||||
terminal:{
|
terminal:{
|
||||||
title:'终端设备',
|
title:'终端设备',
|
||||||
total:'共',
|
total:'共',
|
||||||
|
|||||||
@@ -348,6 +348,59 @@ export function updateWlanSsid(siteId: string, wlanId: string, ssidId: string, p
|
|||||||
data: params
|
data: params
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
/** 获取门户列表 */
|
||||||
|
export function fetchPortalList(siteId: string, params: { pageNum: number; pageSize: number }) {
|
||||||
|
return request<Api.Portal.PortalResponse>({
|
||||||
|
url: `/system/portal/${siteId}`,
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
pageNum: params.pageNum,
|
||||||
|
pageSize: params.pageSize
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/** 获取 SSID 列表 */
|
||||||
|
export function fetchSsidList(siteId: string) {
|
||||||
|
return request<Api.Portal.SsidListResponse>({
|
||||||
|
url: `/system/wlan/ssids/${siteId}`,
|
||||||
|
method: 'get'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加门户 */
|
||||||
|
export function addPortal(siteId: string, params: Api.Portal.AddPortalParams) {
|
||||||
|
return request<any>({
|
||||||
|
url: `/system/portal/${siteId}`,
|
||||||
|
method: 'post',
|
||||||
|
data: params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/** 获取门户配置 */
|
||||||
|
export function getPortalConfig(siteId: string, portalId: string) {
|
||||||
|
return request<Api.Portal.AddPortalParams>({
|
||||||
|
url: `/system/portal/${siteId}/${portalId}`,
|
||||||
|
method: 'get'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 更新门户配置 */
|
||||||
|
export function updatePortalConfig(siteId: string, portalId: string, params: Api.Portal.AddPortalParams) {
|
||||||
|
return request<any>({
|
||||||
|
url: `/system/portal/${siteId}/${portalId}`,
|
||||||
|
method: 'put',
|
||||||
|
data: params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/** 删除门户 */
|
||||||
|
export function deletePortal(siteId: string, portalId: string) {
|
||||||
|
return request<any>({
|
||||||
|
url: `/system/portal/${siteId}/${portalId}`,
|
||||||
|
method: 'delete'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
89
src/typings/api.d.ts
vendored
89
src/typings/api.d.ts
vendored
@@ -807,8 +807,8 @@ declare namespace Api {
|
|||||||
namespace Wlan {
|
namespace Wlan {
|
||||||
interface WlanGroup {
|
interface WlanGroup {
|
||||||
wlanId: string;
|
wlanId: string;
|
||||||
name: string;
|
wlanName: string;
|
||||||
primary: boolean;
|
ssidList: SsidInfo[];
|
||||||
}
|
}
|
||||||
|
|
||||||
type WlanGroupResponse = App.Service.ApiResponse<WlanGroup[]>;
|
type WlanGroupResponse = App.Service.ApiResponse<WlanGroup[]>;
|
||||||
@@ -876,6 +876,91 @@ declare namespace Api {
|
|||||||
vlanId?: number;
|
vlanId?: number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
namespace Portal {
|
||||||
|
interface Portal {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
enable: boolean;
|
||||||
|
ssidNames: string[];
|
||||||
|
ssidList: string[];
|
||||||
|
networkList: string[];
|
||||||
|
authType: number;
|
||||||
|
hotspotTypes: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface PortalResponse extends App.Service.ApiResponse<{
|
||||||
|
rows: Portal[];
|
||||||
|
total: number;
|
||||||
|
}> {}
|
||||||
|
}
|
||||||
|
namespace Portal {
|
||||||
|
// 先定义基础类型
|
||||||
|
interface SsidInfo {
|
||||||
|
ssidId: string;
|
||||||
|
ssidName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WlanGroup {
|
||||||
|
wlanId: string;
|
||||||
|
wlanName: string;
|
||||||
|
ssidList: SsidInfo[];
|
||||||
|
}
|
||||||
|
interface Portal {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
enable: boolean;
|
||||||
|
ssidNames: string[];
|
||||||
|
ssidList: string[];
|
||||||
|
networkList: string[];
|
||||||
|
authType: number;
|
||||||
|
hotspotTypes: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface PortalResponse extends App.Service.ApiResponse<{
|
||||||
|
rows: Portal[];
|
||||||
|
total: number;
|
||||||
|
}> {}
|
||||||
|
|
||||||
|
|
||||||
|
interface SsidListResponse extends App.Service.ApiResponse<WlanGroup[]> {}
|
||||||
|
|
||||||
|
interface AuthTimeout {
|
||||||
|
customTimeout: number;
|
||||||
|
customTimeoutUnit: 1 | 2 | 3; // 1:分钟 2:小时 3:天
|
||||||
|
}
|
||||||
|
|
||||||
|
interface NoAuth {
|
||||||
|
dailyLimitEnable: boolean;
|
||||||
|
}
|
||||||
|
interface ExternalPortal {
|
||||||
|
hostType: 1 | 2; // 1: IP地址 2: URL
|
||||||
|
serverUrl: string; // IP地址或URL值
|
||||||
|
serverUrlScheme?: string; // URL时的协议类型
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ImportedPortalPage {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AddPortalParams {
|
||||||
|
name: string;
|
||||||
|
enable: boolean;
|
||||||
|
ssidList: string[];
|
||||||
|
authType: number;
|
||||||
|
authTimeout: AuthTimeout;
|
||||||
|
noAuth: NoAuth;
|
||||||
|
httpsRedirectEnable: boolean;
|
||||||
|
landingPage: 1 | 2 | 3;
|
||||||
|
landingUrlScheme?: string;
|
||||||
|
landingUrl?: string;
|
||||||
|
externalPortal?: ExternalPortal; // 添加外部Portal配置
|
||||||
|
pageType: number;
|
||||||
|
importedPortalPage: ImportedPortalPage;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declare namespace App {
|
declare namespace App {
|
||||||
|
|||||||
6
src/typings/auto-imports.d.ts
vendored
6
src/typings/auto-imports.d.ts
vendored
@@ -14,6 +14,7 @@ declare global {
|
|||||||
const addData: typeof import('../service/api/dictData')['addData']
|
const addData: typeof import('../service/api/dictData')['addData']
|
||||||
const addJob: typeof import('../service/api/job')['addJob']
|
const addJob: typeof import('../service/api/job')['addJob']
|
||||||
const addPackage: typeof import('../service/api/auth')['addPackage']
|
const addPackage: typeof import('../service/api/auth')['addPackage']
|
||||||
|
const addPortal: typeof import('../service/api/auth')['addPortal']
|
||||||
const addRateLimit: typeof import('../service/api/auth')['addRateLimit']
|
const addRateLimit: typeof import('../service/api/auth')['addRateLimit']
|
||||||
const addThemeVarsToHtml: typeof import('../store/modules/theme/shared')['addThemeVarsToHtml']
|
const addThemeVarsToHtml: typeof import('../store/modules/theme/shared')['addThemeVarsToHtml']
|
||||||
const addWlanSsid: typeof import('../service/api/auth')['addWlanSsid']
|
const addWlanSsid: typeof import('../service/api/auth')['addWlanSsid']
|
||||||
@@ -66,6 +67,7 @@ declare global {
|
|||||||
const delJobLog: typeof import('../service/api/job')['delJobLog']
|
const delJobLog: typeof import('../service/api/job')['delJobLog']
|
||||||
const deleteApDevices: typeof import('../service/api/auth')['deleteApDevices']
|
const deleteApDevices: typeof import('../service/api/auth')['deleteApDevices']
|
||||||
const deletePackage: typeof import('../service/api/auth')['deletePackage']
|
const deletePackage: typeof import('../service/api/auth')['deletePackage']
|
||||||
|
const deletePortal: typeof import('../service/api/auth')['deletePortal']
|
||||||
const deleteWlanSsid: typeof import('../service/api/auth')['deleteWlanSsid']
|
const deleteWlanSsid: typeof import('../service/api/auth')['deleteWlanSsid']
|
||||||
const describe: typeof import('vitest')['describe']
|
const describe: typeof import('vitest')['describe']
|
||||||
const dict: typeof import('../store/modules/dict/index')['default']
|
const dict: typeof import('../store/modules/dict/index')['default']
|
||||||
@@ -142,10 +144,12 @@ declare global {
|
|||||||
const fetchKycList: typeof import('../service/api/auth')['fetchKycList']
|
const fetchKycList: typeof import('../service/api/auth')['fetchKycList']
|
||||||
const fetchLogin: typeof import('../service/api/auth')['fetchLogin']
|
const fetchLogin: typeof import('../service/api/auth')['fetchLogin']
|
||||||
const fetchPackageList: typeof import('../service/api/auth')['fetchPackageList']
|
const fetchPackageList: typeof import('../service/api/auth')['fetchPackageList']
|
||||||
|
const fetchPortalList: typeof import('../service/api/auth')['fetchPortalList']
|
||||||
const fetchRateLimitList: typeof import('../service/api/auth')['fetchRateLimitList']
|
const fetchRateLimitList: typeof import('../service/api/auth')['fetchRateLimitList']
|
||||||
const fetchRefreshToken: typeof import('../service/api/auth')['fetchRefreshToken']
|
const fetchRefreshToken: typeof import('../service/api/auth')['fetchRefreshToken']
|
||||||
const fetchRegister: typeof import('../service/api/auth')['fetchRegister']
|
const fetchRegister: typeof import('../service/api/auth')['fetchRegister']
|
||||||
const fetchSiteList: typeof import('../service/api/auth')['fetchSiteList']
|
const fetchSiteList: typeof import('../service/api/auth')['fetchSiteList']
|
||||||
|
const fetchSsidList: typeof import('../service/api/auth')['fetchSsidList']
|
||||||
const fetchTerminalList: typeof import('../service/api/auth')['fetchTerminalList']
|
const fetchTerminalList: typeof import('../service/api/auth')['fetchTerminalList']
|
||||||
const fetchWlanGroups: typeof import('../service/api/auth')['fetchWlanGroups']
|
const fetchWlanGroups: typeof import('../service/api/auth')['fetchWlanGroups']
|
||||||
const fetchWlanSsidList: typeof import('../service/api/auth')['fetchWlanSsidList']
|
const fetchWlanSsidList: typeof import('../service/api/auth')['fetchWlanSsidList']
|
||||||
@@ -175,6 +179,7 @@ declare global {
|
|||||||
const getFixedTabs: typeof import('../store/modules/tab/shared')['getFixedTabs']
|
const getFixedTabs: typeof import('../store/modules/tab/shared')['getFixedTabs']
|
||||||
const getGlobalMenusByAuthRoutes: typeof import('../store/modules/route/shared')['getGlobalMenusByAuthRoutes']
|
const getGlobalMenusByAuthRoutes: typeof import('../store/modules/route/shared')['getGlobalMenusByAuthRoutes']
|
||||||
const getLocalizedTimeUnit: typeof import('../utils/units')['getLocalizedTimeUnit']
|
const getLocalizedTimeUnit: typeof import('../utils/units')['getLocalizedTimeUnit']
|
||||||
|
const getPortalConfig: typeof import('../service/api/auth')['getPortalConfig']
|
||||||
const getRouteIcons: typeof import('../store/modules/tab/shared')['getRouteIcons']
|
const getRouteIcons: typeof import('../store/modules/tab/shared')['getRouteIcons']
|
||||||
const getSelectedMenuKeyPathByKey: typeof import('../store/modules/route/shared')['getSelectedMenuKeyPathByKey']
|
const getSelectedMenuKeyPathByKey: typeof import('../store/modules/route/shared')['getSelectedMenuKeyPathByKey']
|
||||||
const getServiceBaseURL: typeof import('../utils/service')['getServiceBaseURL']
|
const getServiceBaseURL: typeof import('../utils/service')['getServiceBaseURL']
|
||||||
@@ -299,6 +304,7 @@ declare global {
|
|||||||
const updateJob: typeof import('../service/api/job')['updateJob']
|
const updateJob: typeof import('../service/api/job')['updateJob']
|
||||||
const updateLocaleOfGlobalMenus: typeof import('../store/modules/route/shared')['updateLocaleOfGlobalMenus']
|
const updateLocaleOfGlobalMenus: typeof import('../store/modules/route/shared')['updateLocaleOfGlobalMenus']
|
||||||
const updatePackage: typeof import('../service/api/auth')['updatePackage']
|
const updatePackage: typeof import('../service/api/auth')['updatePackage']
|
||||||
|
const updatePortalConfig: typeof import('../service/api/auth')['updatePortalConfig']
|
||||||
const updateTabByI18nKey: typeof import('../store/modules/tab/shared')['updateTabByI18nKey']
|
const updateTabByI18nKey: typeof import('../store/modules/tab/shared')['updateTabByI18nKey']
|
||||||
const updateTabsByI18nKey: typeof import('../store/modules/tab/shared')['updateTabsByI18nKey']
|
const updateTabsByI18nKey: typeof import('../store/modules/tab/shared')['updateTabsByI18nKey']
|
||||||
const updateWlanSsid: typeof import('../service/api/auth')['updateWlanSsid']
|
const updateWlanSsid: typeof import('../service/api/auth')['updateWlanSsid']
|
||||||
|
|||||||
@@ -1,6 +1,669 @@
|
|||||||
<script>
|
|
||||||
|
|
||||||
</script>
|
|
||||||
<template>
|
<template>
|
||||||
|
<SimpleScrollbar>
|
||||||
|
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||||
|
<ACard
|
||||||
|
:title="t('page.portal.title')"
|
||||||
|
:bordered="false"
|
||||||
|
:body-style="{ flex: 1, overflow: 'hidden' }"
|
||||||
|
class="flex-col-stretch sm:flex-1-hidden card-wrapper"
|
||||||
|
>
|
||||||
|
<template #extra>
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<!-- 站点选择 -->
|
||||||
|
<a-select
|
||||||
|
v-model:value="selectedSiteId"
|
||||||
|
:loading="siteLoading"
|
||||||
|
:placeholder="t('page.portal.selectSite')"
|
||||||
|
style="width: 200px"
|
||||||
|
@change="handleSiteChange"
|
||||||
|
>
|
||||||
|
<a-select-option
|
||||||
|
v-for="site in siteList"
|
||||||
|
:key="site.siteId"
|
||||||
|
:value="site.siteId"
|
||||||
|
>
|
||||||
|
{{ site.name }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
|
||||||
|
<!-- 表格操作组件 -->
|
||||||
|
<TableHeaderOperation
|
||||||
|
v-model:columns="columnChecks"
|
||||||
|
:loading="tableLoading"
|
||||||
|
:show-delete="false"
|
||||||
|
@add="handleAdd"
|
||||||
|
@refresh="getData"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 表格 -->
|
||||||
|
<ATable
|
||||||
|
:columns="columns"
|
||||||
|
:data-source="tableData"
|
||||||
|
:loading="tableLoading"
|
||||||
|
:pagination="{
|
||||||
|
...mobilePagination,
|
||||||
|
total: mobilePagination.total,
|
||||||
|
current: searchParams.pageNum,
|
||||||
|
pageSize: searchParams.pageSize,
|
||||||
|
showTotal: (total: number) => `${t('page.portal.total')} ${total} `
|
||||||
|
}"
|
||||||
|
@change="(pagination) => {
|
||||||
|
searchParams.pageNum = pagination.current;
|
||||||
|
searchParams.pageSize = pagination.pageSize;
|
||||||
|
getData();
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'operate'">
|
||||||
|
<div class="flex items-center justify-center gap-2">
|
||||||
|
<a-tooltip :title="t('common.edit')">
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
@click="() => handleEdit(record)"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<EditOutlined />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
|
||||||
|
<a-tooltip :title="t('common.delete')">
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
class="text-red-500"
|
||||||
|
@click="() => handleDelete(record)"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<DeleteOutlined />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</ATable>
|
||||||
|
</ACard>
|
||||||
|
|
||||||
|
<!-- 添加门户对话框 -->
|
||||||
|
<a-modal
|
||||||
|
v-model:visible="addVisible"
|
||||||
|
:title="t('page.portal.addPortal')"
|
||||||
|
@ok="handleAddConfirm"
|
||||||
|
width="600px"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
:model="addForm"
|
||||||
|
:rules="addRules"
|
||||||
|
:label-col="{ span: 6 }"
|
||||||
|
:wrapper-col="{ span: 16 }"
|
||||||
|
layout="horizontal"
|
||||||
|
ref="formRef"
|
||||||
|
>
|
||||||
|
<a-form-item name="name" :label="t('page.portal.name')">
|
||||||
|
<a-input v-model:value="addForm.name" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item name="enable" :label="t('page.portal.enable')">
|
||||||
|
<a-switch v-model:checked="addForm.enable" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item name="ssidList" :label="t('page.portal.ssid')">
|
||||||
|
<a-tree-select
|
||||||
|
v-model:value="addForm.ssidList"
|
||||||
|
:tree-data="treeData"
|
||||||
|
:loading="ssidLoading"
|
||||||
|
:placeholder="t('page.portal.selectSsid')"
|
||||||
|
multiple
|
||||||
|
tree-checkable
|
||||||
|
:tree-default-expand-all="true"
|
||||||
|
:show-checked-strategy="TreeSelect.SHOW_CHILD"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<!-- 外部Portal服务器配置 -->
|
||||||
|
<a-form-item name="externalPortal" :label="t('page.portal.externalPortal')">
|
||||||
|
<div class="flex-col gap-2">
|
||||||
|
<!-- URL输入框 -->
|
||||||
|
<a-form-item
|
||||||
|
:name="['externalPortal', 'serverUrl']"
|
||||||
|
:label="t('page.portal.url')"
|
||||||
|
>
|
||||||
|
<a-input-group compact>
|
||||||
|
<a-select
|
||||||
|
v-model:value="addForm.externalPortal.serverUrlScheme"
|
||||||
|
style="width: 30%"
|
||||||
|
>
|
||||||
|
<a-select-option value="http">http://</a-select-option>
|
||||||
|
<a-select-option value="https">https://</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
<a-input
|
||||||
|
v-model:value="addForm.externalPortal.serverUrl"
|
||||||
|
style="width: 70%"
|
||||||
|
:placeholder="t('page.portal.enterUrl')"
|
||||||
|
/>
|
||||||
|
</a-input-group>
|
||||||
|
</a-form-item>
|
||||||
|
</div>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<!-- 身份验证时间配置项,仅在非外部Portal认证时显示 -->
|
||||||
|
<a-form-item
|
||||||
|
v-if="addForm.authType !== 4"
|
||||||
|
name="authTimeout"
|
||||||
|
:label="t('page.portal.authTimeout')"
|
||||||
|
>
|
||||||
|
<a-input-group compact>
|
||||||
|
<a-input-number
|
||||||
|
v-model:value="addForm.authTimeout.customTimeout"
|
||||||
|
style="width: 60%"
|
||||||
|
:min="1"
|
||||||
|
:max="getMaxTimeout(addForm.authTimeout.customTimeoutUnit)"
|
||||||
|
/>
|
||||||
|
<a-select
|
||||||
|
v-model:value="addForm.authTimeout.customTimeoutUnit"
|
||||||
|
style="width: 40%"
|
||||||
|
>
|
||||||
|
<a-select-option :value="1">{{ t('page.portal.timeUnit.min') }}</a-select-option>
|
||||||
|
<a-select-option :value="2">{{ t('page.portal.timeUnit.hour') }}</a-select-option>
|
||||||
|
<a-select-option :value="3">{{ t('page.portal.timeUnit.day') }}</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-input-group>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item name="noAuth" :label="t('page.portal.dailyLimit')">
|
||||||
|
<a-checkbox v-model:checked="addForm.noAuth.dailyLimitEnable">
|
||||||
|
{{ t('page.portal.enableDailyLimit') }}
|
||||||
|
</a-checkbox>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item name="httpsRedirectEnable" :label="t('page.portal.httpsRedirect')">
|
||||||
|
<a-checkbox v-model:checked="addForm.httpsRedirectEnable">
|
||||||
|
{{ t('page.portal.enableHttpsRedirect') }}
|
||||||
|
</a-checkbox>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
|
||||||
|
<!-- 添加编辑门户对话框 -->
|
||||||
|
<a-modal
|
||||||
|
v-model:visible="editVisible"
|
||||||
|
:title="t('page.portal.editPortal')"
|
||||||
|
@ok="handleEditConfirm"
|
||||||
|
width="600px"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
:model="editForm"
|
||||||
|
:rules="addRules"
|
||||||
|
:label-col="{ span: 6 }"
|
||||||
|
:wrapper-col="{ span: 16 }"
|
||||||
|
layout="horizontal"
|
||||||
|
ref="editFormRef"
|
||||||
|
>
|
||||||
|
<a-form-item name="name" :label="t('page.portal.name')">
|
||||||
|
<a-input v-model:value="editForm.name" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item name="enable" :label="t('page.portal.enable')">
|
||||||
|
<a-switch v-model:checked="editForm.enable" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item name="ssidList" :label="t('page.portal.ssid')">
|
||||||
|
<a-tree-select
|
||||||
|
v-model:value="editForm.ssidList"
|
||||||
|
:tree-data="treeData"
|
||||||
|
:loading="ssidLoading"
|
||||||
|
:placeholder="t('page.portal.selectSsid')"
|
||||||
|
multiple
|
||||||
|
tree-checkable
|
||||||
|
:tree-default-expand-all="true"
|
||||||
|
:show-checked-strategy="TreeSelect.SHOW_CHILD"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<!-- 外部Portal服务器配置 -->
|
||||||
|
<a-form-item name="externalPortal" :label="t('page.portal.externalPortal')">
|
||||||
|
<div class="flex-col gap-2">
|
||||||
|
<!-- URL输入框 -->
|
||||||
|
<a-form-item
|
||||||
|
:name="['externalPortal', 'serverUrl']"
|
||||||
|
:label="t('page.portal.url')"
|
||||||
|
>
|
||||||
|
<a-input-group compact>
|
||||||
|
<a-select
|
||||||
|
v-model:value="editForm.externalPortal.serverUrlScheme"
|
||||||
|
style="width: 30%"
|
||||||
|
>
|
||||||
|
<a-select-option value="http">http://</a-select-option>
|
||||||
|
<a-select-option value="https">https://</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
<a-input
|
||||||
|
v-model:value="editForm.externalPortal.serverUrl"
|
||||||
|
style="width: 70%"
|
||||||
|
:placeholder="t('page.portal.enterUrl')"
|
||||||
|
/>
|
||||||
|
</a-input-group>
|
||||||
|
</a-form-item>
|
||||||
|
</div>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<!-- 身份验证时间配置项,仅在非外部Portal认证时显示 -->
|
||||||
|
<a-form-item
|
||||||
|
v-if="editForm.authType !== 4"
|
||||||
|
name="authTimeout"
|
||||||
|
:label="t('page.portal.authTimeout')"
|
||||||
|
>
|
||||||
|
<a-input-group compact>
|
||||||
|
<a-input-number
|
||||||
|
v-model:value="editForm.authTimeout.customTimeout"
|
||||||
|
style="width: 60%"
|
||||||
|
:min="1"
|
||||||
|
:max="getMaxTimeout(editForm.authTimeout.customTimeoutUnit)"
|
||||||
|
/>
|
||||||
|
<a-select
|
||||||
|
v-model:value="editForm.authTimeout.customTimeoutUnit"
|
||||||
|
style="width: 40%"
|
||||||
|
>
|
||||||
|
<a-select-option :value="1">{{ t('page.portal.timeUnit.min') }}</a-select-option>
|
||||||
|
<a-select-option :value="2">{{ t('page.portal.timeUnit.hour') }}</a-select-option>
|
||||||
|
<a-select-option :value="3">{{ t('page.portal.timeUnit.day') }}</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-input-group>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item name="httpsRedirectEnable" :label="t('page.portal.httpsRedirect')">
|
||||||
|
<a-checkbox v-model:checked="editForm.httpsRedirectEnable">
|
||||||
|
{{ t('page.portal.enableHttpsRedirect') }}
|
||||||
|
</a-checkbox>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
</div>
|
||||||
|
</SimpleScrollbar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { SimpleScrollbar } from '~/packages/materials/src';
|
||||||
|
import { ref, onMounted, watch } from 'vue';
|
||||||
|
import { Card as ACard, Table as ATable, message, TreeSelect, Modal } from 'ant-design-vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import {
|
||||||
|
fetchSiteList,
|
||||||
|
fetchPortalList,
|
||||||
|
fetchSsidList,
|
||||||
|
addPortal,
|
||||||
|
getPortalConfig,
|
||||||
|
updatePortalConfig,
|
||||||
|
deletePortal
|
||||||
|
} from '@/service/api/auth';
|
||||||
|
import { DeleteOutlined, EditOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { useTable } from '@/hooks/common/table';
|
||||||
|
import type { TreeSelectProps } from 'ant-design-vue';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
// 站点相关
|
||||||
|
const siteList = ref<Api.Site.SiteInfo[]>([]);
|
||||||
|
const selectedSiteId = ref<string>('');
|
||||||
|
const siteLoading = ref(false);
|
||||||
|
|
||||||
|
// 使用 useTable hook
|
||||||
|
const {
|
||||||
|
columns,
|
||||||
|
columnChecks,
|
||||||
|
data: tableData,
|
||||||
|
loading: tableLoading,
|
||||||
|
getData,
|
||||||
|
mobilePagination,
|
||||||
|
searchParams,
|
||||||
|
} = useTable<Api.Portal.Portal>({
|
||||||
|
apiFn: async (params) => {
|
||||||
|
if (!selectedSiteId.value) {
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
rows: [],
|
||||||
|
total: 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return fetchPortalList(selectedSiteId.value, {
|
||||||
|
pageNum: params.pageNum || 1,
|
||||||
|
pageSize: params.pageSize || 10
|
||||||
|
});
|
||||||
|
},
|
||||||
|
rowKey: 'id',
|
||||||
|
columns: () => [
|
||||||
|
{
|
||||||
|
title: t('page.portal.name'),
|
||||||
|
dataIndex: 'name',
|
||||||
|
key: 'name',
|
||||||
|
width: 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'SSID',
|
||||||
|
dataIndex: 'ssidNames',
|
||||||
|
key: 'ssidNames',
|
||||||
|
width: 200,
|
||||||
|
customRender: ({ text }: { text: string[] }) => {
|
||||||
|
return text ? text.join(', ') : '-';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('page.portal.authType'),
|
||||||
|
dataIndex: 'authType',
|
||||||
|
key: 'authType',
|
||||||
|
width: 150,
|
||||||
|
customRender: ({ text }: { text: number }) => {
|
||||||
|
const authTypeMap: Record<number, string> = {
|
||||||
|
0: t('page.portal.auth.none'),
|
||||||
|
1: t('page.portal.auth.simplePassword'),
|
||||||
|
2: t('page.portal.auth.externalRadius'),
|
||||||
|
4: t('page.portal.auth.externalPortal'),
|
||||||
|
11: t('page.portal.auth.hotspot'),
|
||||||
|
15: t('page.portal.auth.ldap')
|
||||||
|
};
|
||||||
|
return authTypeMap[text] || text;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('common.operate'),
|
||||||
|
key: 'operate',
|
||||||
|
width: 120,
|
||||||
|
fixed: 'right',
|
||||||
|
align: 'center'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取站点列表
|
||||||
|
const getSiteList = async () => {
|
||||||
|
siteLoading.value = true;
|
||||||
|
const { data, error } = await fetchSiteList({
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 100
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!error) {
|
||||||
|
siteList.value = data.rows || [];
|
||||||
|
// 如果有站点数据,默认选择第一个
|
||||||
|
if (siteList.value.length > 0) {
|
||||||
|
selectedSiteId.value = siteList.value[0].siteId;
|
||||||
|
// 获取第一个站点的数据
|
||||||
|
await getData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
siteLoading.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理站点变更
|
||||||
|
const handleSiteChange = async (value: string) => {
|
||||||
|
selectedSiteId.value = value;
|
||||||
|
await getData();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 组件挂载时获取站点列表
|
||||||
|
onMounted(() => {
|
||||||
|
getSiteList();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加表单相关
|
||||||
|
const addVisible = ref(false);
|
||||||
|
const formRef = ref();
|
||||||
|
const ssidList = ref<Api.Portal.SsidInfo[]>([]);
|
||||||
|
const ssidLoading = ref(false);
|
||||||
|
const treeData = ref<TreeSelectProps['treeData']>([]);
|
||||||
|
|
||||||
|
// URL 格式校验正则
|
||||||
|
const URL_PATTERN = new RegExp(
|
||||||
|
'^(([-a-zA-Z0-9@:%._+~#=]{2,256}\\.[a-z]{2,63})|(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.)){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)))' +
|
||||||
|
'((:([1-9]|[1-9]\\d|[1-9]\\d{2}|[1-9]\\d{3}|[1-5]\\d{4}|6[0-4]\\d{3}|65[0-4]\\d{2}|655[0-2]\\d|6553[0-5]))?)' +
|
||||||
|
'(/[-a-zA-Z0-9@:%_+.~#?&//=]*)?$'
|
||||||
|
);
|
||||||
|
|
||||||
|
const addForm = ref({
|
||||||
|
name: '',
|
||||||
|
enable: true,
|
||||||
|
ssidList: [],
|
||||||
|
authType: 4, // 固定为外部 Portal 认证
|
||||||
|
authTimeout: {
|
||||||
|
customTimeout: 8,
|
||||||
|
customTimeoutUnit: 2
|
||||||
|
},
|
||||||
|
noAuth: {
|
||||||
|
dailyLimitEnable: false
|
||||||
|
},
|
||||||
|
httpsRedirectEnable: false,
|
||||||
|
landingPage: 1,
|
||||||
|
pageType: 2,
|
||||||
|
importedPortalPage: {
|
||||||
|
id: 'test'
|
||||||
|
},
|
||||||
|
externalPortal: {
|
||||||
|
hostType: 2,
|
||||||
|
serverUrl: '',
|
||||||
|
serverUrlScheme: 'http'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const addRules = {
|
||||||
|
name: [
|
||||||
|
{ required: true, message: t('page.portal.nameRequired'), trigger: 'blur' }
|
||||||
|
],
|
||||||
|
ssidList: [
|
||||||
|
{
|
||||||
|
validator: (_rule: any, value: Record<string, string>) => {
|
||||||
|
if (Object.keys(value).length === 0) {
|
||||||
|
return Promise.reject(t('page.portal.ssidRequired'));
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
},
|
||||||
|
trigger: 'change'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
externalPortal: [
|
||||||
|
{
|
||||||
|
validator: (_rule: any, value: Api.Portal.ExternalPortal) => {
|
||||||
|
if (addForm.value.authType === 4) {
|
||||||
|
if (!value.serverUrl) {
|
||||||
|
return Promise.reject(t('page.portal.urlRequired'));
|
||||||
|
}
|
||||||
|
// URL 格式校验
|
||||||
|
if (!URL_PATTERN.test(value.serverUrl)) {
|
||||||
|
return Promise.reject(t('page.portal.invalidUrl'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取 SSID 列表
|
||||||
|
const getSsidList = async () => {
|
||||||
|
if (!selectedSiteId.value) return;
|
||||||
|
|
||||||
|
ssidLoading.value = true;
|
||||||
|
const { data, error } = await fetchSsidList(selectedSiteId.value);
|
||||||
|
|
||||||
|
if (!error) {
|
||||||
|
// 转换数据为树形结构
|
||||||
|
treeData.value = data.map((group: Api.Portal.WlanGroup) => ({
|
||||||
|
title: group.wlanName,
|
||||||
|
value: group.wlanId, // 这个值不会被选中,只是为了符合树结构
|
||||||
|
key: group.wlanId,
|
||||||
|
selectable: false, // 禁止选择父节点
|
||||||
|
children: group.ssidList.map((ssid: Api.Portal.SsidInfo) => ({
|
||||||
|
title: ssid.ssidName,
|
||||||
|
value: ssid.ssidId,
|
||||||
|
key: ssid.ssidId,
|
||||||
|
isLeaf: true
|
||||||
|
}))
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
message.error(t('common.error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
ssidLoading.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 根据时间单位获取最大超时时间
|
||||||
|
const getMaxTimeout = (unit: number) => {
|
||||||
|
switch (unit) {
|
||||||
|
case 1: return 1000000; // 分钟
|
||||||
|
case 2: return 10000; // 小时
|
||||||
|
case 3: return 1000; // 天
|
||||||
|
default: return 1000000;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理添加
|
||||||
|
const handleAdd = async () => {
|
||||||
|
addVisible.value = true;
|
||||||
|
await getSsidList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 修改添加确认处理函数
|
||||||
|
const handleAddConfirm = async () => {
|
||||||
|
await formRef.value?.validate();
|
||||||
|
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
|
||||||
|
// 创建一个新对象来存储要提交的数据
|
||||||
|
const submitData = { ...addForm.value };
|
||||||
|
|
||||||
|
// 设置默认参数
|
||||||
|
submitData.authTimeout = {
|
||||||
|
customTimeout: 8,
|
||||||
|
customTimeoutUnit: 2
|
||||||
|
};
|
||||||
|
submitData.externalPortal = {
|
||||||
|
hostType: 2,
|
||||||
|
serverUrl: submitData.externalPortal.serverUrl,
|
||||||
|
serverUrlScheme: submitData.externalPortal.serverUrlScheme
|
||||||
|
};
|
||||||
|
|
||||||
|
const { error } = await addPortal(selectedSiteId.value, submitData);
|
||||||
|
|
||||||
|
hide();
|
||||||
|
if (!error) {
|
||||||
|
message.success(t('page.portal.addSuccess'));
|
||||||
|
addVisible.value = false;
|
||||||
|
getData(); // 刷新列表
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加响应式变量
|
||||||
|
const currentPortalId = ref<string>('');
|
||||||
|
const editVisible = ref(false);
|
||||||
|
const editFormRef = ref();
|
||||||
|
const editForm = ref({
|
||||||
|
name: '',
|
||||||
|
enable: true,
|
||||||
|
ssidList: [],
|
||||||
|
authType: 4, // 固定为外部 Portal 认证
|
||||||
|
authTimeout: {
|
||||||
|
customTimeout: 8,
|
||||||
|
customTimeoutUnit: 2
|
||||||
|
},
|
||||||
|
httpsRedirectEnable: false,
|
||||||
|
landingPage: 1,
|
||||||
|
pageType: 2,
|
||||||
|
importedPortalPage: {
|
||||||
|
id: 'test'
|
||||||
|
},
|
||||||
|
externalPortal: {
|
||||||
|
hostType: 2,
|
||||||
|
serverUrl: '',
|
||||||
|
serverUrlScheme: 'http'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 处理编辑按钮点击
|
||||||
|
const handleEdit = async (record: Api.Portal.Portal) => {
|
||||||
|
currentPortalId.value = record.id;
|
||||||
|
editVisible.value = true;
|
||||||
|
|
||||||
|
// 获取 SSID 列表
|
||||||
|
await getSsidList();
|
||||||
|
|
||||||
|
// 获取当前门户的配置
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
const { data, error } = await getPortalConfig(selectedSiteId.value, currentPortalId.value);
|
||||||
|
hide();
|
||||||
|
|
||||||
|
if (!error && data) {
|
||||||
|
// 移除 noAuth 字段后再赋值
|
||||||
|
const { noAuth, ...configWithoutNoAuth } = data;
|
||||||
|
editForm.value = configWithoutNoAuth;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 修改编辑确认处理函数
|
||||||
|
const handleEditConfirm = async () => {
|
||||||
|
await editFormRef.value?.validate();
|
||||||
|
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
|
||||||
|
const submitData = {
|
||||||
|
name: editForm.value.name,
|
||||||
|
enable: editForm.value.enable,
|
||||||
|
ssidList: editForm.value.ssidList,
|
||||||
|
authType: 4, // 固定为外部 Portal 认证
|
||||||
|
httpsRedirectEnable: editForm.value.httpsRedirectEnable,
|
||||||
|
landingPage: 1,
|
||||||
|
pageType: 2,
|
||||||
|
importedPortalPage: {
|
||||||
|
id: 'test'
|
||||||
|
},
|
||||||
|
authTimeout: {
|
||||||
|
customTimeout: 8,
|
||||||
|
customTimeoutUnit: 2
|
||||||
|
},
|
||||||
|
externalPortal: {
|
||||||
|
hostType: 2,
|
||||||
|
serverUrl: editForm.value.externalPortal.serverUrl,
|
||||||
|
serverUrlScheme: editForm.value.externalPortal.serverUrlScheme
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const { error } = await updatePortalConfig(selectedSiteId.value, currentPortalId.value, submitData);
|
||||||
|
|
||||||
|
hide();
|
||||||
|
if (!error) {
|
||||||
|
message.success(t('page.portal.updateSuccess'));
|
||||||
|
editVisible.value = false;
|
||||||
|
getData(); // 刷新列表
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加删除门户的 API 函数
|
||||||
|
const handleDelete = (record: Api.Portal.Portal) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('page.portal.confirmDelete'),
|
||||||
|
content: t('page.portal.deleteConfirmContent', { name: record.name }),
|
||||||
|
okText: t('common.confirm'),
|
||||||
|
cancelText: t('common.cancel'),
|
||||||
|
onOk: async () => {
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
const { error } = await deletePortal(selectedSiteId.value, record.id);
|
||||||
|
hide();
|
||||||
|
|
||||||
|
if (!error) {
|
||||||
|
message.success(t('page.portal.deleteSuccess'));
|
||||||
|
getData(); // 刷新列表
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.card-wrapper {
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user