feat:1,新增游戏配置 2,新增币种 3,新增角色权限管理
parent
c6102d995f
commit
4c54307fc5
|
|
@ -38,8 +38,9 @@ export function uploadImgFile(data) {
|
|||
// 图片上传
|
||||
const baseUrlq = getLocalStorage('uploadUrl');
|
||||
export function uploadImgFileCommon(data, type) {
|
||||
console.log(baseUrlq);
|
||||
return request({
|
||||
url: baseUrlq + `/file/upload/localSysFile/${type}`,
|
||||
url: `/file/upload/localSysFile/${type}`,
|
||||
method: 'post',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
data: data
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 查询游戏配置表
|
||||
export function getGameSecretList(query) {
|
||||
return request({
|
||||
url: '/game/secret/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//配置详情
|
||||
export function getGameSecretInfo(id) {
|
||||
return request({
|
||||
url: `/game/secret/${id}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
// 新增游戏配置
|
||||
export function postGameSecret(data) {
|
||||
return request({
|
||||
url: '/game/secret',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改游戏配置
|
||||
export function updateGameSecret(data) {
|
||||
return request({
|
||||
url: '/game/secret',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
//删除
|
||||
export function deleteGameSecret(id) {
|
||||
return request({
|
||||
url: `/game/secret/${id}`,
|
||||
method: 'delete',
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 查询用户头像管理 列表
|
||||
export function listAvatar(query) {
|
||||
return request({
|
||||
url: '/operation/avatar/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询用户头像管理 详细
|
||||
export function getAvatar(id) {
|
||||
return request({
|
||||
url: '/operation/avatar/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增用户头像管理
|
||||
export function addAvatar(data) {
|
||||
return request({
|
||||
url: '/operation/avatar',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改用户头像管理
|
||||
export function updateAvatar(data) {
|
||||
return request({
|
||||
url: '/operation/avatar',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除用户头像管理
|
||||
export function delAvatar(id) {
|
||||
return request({
|
||||
url: '/operation/avatar/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,656 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 全局子域名搜索
|
||||
export function getSonDomainSearch(query) {
|
||||
return request({
|
||||
url: '/operation/son/get',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
//------------------域名管理---------------------//
|
||||
|
||||
// 域名管理商列表
|
||||
export function getSupplierList(query) {
|
||||
return request({
|
||||
url: '/domain/supplier/select',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
//域名信息查询
|
||||
export function getDomainConfig(query) {
|
||||
return request({
|
||||
url: '/domain/supplier/config',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 开通域名管理商
|
||||
export function tenantSupplier(data) {
|
||||
return request({
|
||||
url: '/operation/tenant',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 开通域名管理商ALB
|
||||
export function tenantSupplierALB(data) {
|
||||
return request({
|
||||
url: '/operation/tenant/alb',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 域名列表
|
||||
export function getDomainList(query) {
|
||||
return request({
|
||||
url: '/domain/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 域名验证
|
||||
export function getDomainVerify(data) {
|
||||
return request({
|
||||
url: '/domain/check',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 刷新域名过期时间
|
||||
export function getDomainExpireTime(data) {
|
||||
return request({
|
||||
url: '/domain/expired',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 强制停用
|
||||
export function setDomainStop(data) {
|
||||
return request({
|
||||
url: '/domain/stop',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 彻底删除管理域名
|
||||
export function delDomain(ids) {
|
||||
return request({
|
||||
url: '/domain/' + ids,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增域名
|
||||
export function addDomain(data) {
|
||||
return request({
|
||||
url: '/domain',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取供应商节点下域名
|
||||
export function getSupplierDomainList(query) {
|
||||
return request({
|
||||
url: '/domain/select',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 获取域名NS
|
||||
export function getDomainNS(id) {
|
||||
return request({
|
||||
url: '/domain/get/ns/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//------------------WEB大厅---------------------//
|
||||
|
||||
// web大厅子域名列表
|
||||
export function getWebDomainList(query) {
|
||||
return request({
|
||||
url: '/operation/son/web/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 刷新解析说明
|
||||
export function refreshWebDomainAnalysis(data) {
|
||||
return request({
|
||||
url: '/operation/son/web/analysis',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// web大厅列表开关
|
||||
export function webDomainSwitch(data) {
|
||||
return request({
|
||||
url: '/operation/son/web/switch',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// web大厅子域名新增
|
||||
export function addWebDomain(data) {
|
||||
return request({
|
||||
url: '/operation/son/web',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// web大厅子域名状态修改
|
||||
export function setWebDomainStatus(data) {
|
||||
return request({
|
||||
url: '/operation/son/web/status',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// web大厅子域名绑定代理
|
||||
export function bindWebDomainAgent(data) {
|
||||
return request({
|
||||
url: '/operation/son/web/bind/agent',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// web大厅子域名清理缓存
|
||||
export function clearWebDomainCache(data) {
|
||||
return request({
|
||||
url: '/operation/son/web/clear/cache',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// web大厅子域名删除
|
||||
export function delWebDomain(ids) {
|
||||
return request({
|
||||
url: '/operation/son/web/' + ids,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// web大厅子域名修改
|
||||
export function updateWebDomain(data) {
|
||||
return request({
|
||||
url: '/operation/son/web',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// web大厅子域名批量更换端口
|
||||
export function changeWebDomainPort(data) {
|
||||
return request({
|
||||
url: '/operation/son/web/port',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// web系统参数
|
||||
export function getWebSystemParam() {
|
||||
return request({
|
||||
url: '/operation/son/web/configKey/batch',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// web系统参数修改
|
||||
export function updateWebSystemParam(data) {
|
||||
return request({
|
||||
url: '/operation/son/web/configKey/batch',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
//------------------后端加速域名---------------------//
|
||||
|
||||
// 后端加速域名列表
|
||||
export function getBackendDomainList(query) {
|
||||
return request({
|
||||
url: '/operation/son/backend/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 后端加速域名刷新解析说明
|
||||
export function refreshBackendDomainAnalysis(data) {
|
||||
return request({
|
||||
url: '/operation/son/backend/analysis',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 后端加速域名状态修改
|
||||
export function setBackendDomainStatus(data) {
|
||||
return request({
|
||||
url: '/operation/son/backend/status',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 后端加速域名清理缓存
|
||||
export function clearBackendDomainCache(data) {
|
||||
return request({
|
||||
url: '/operation/son/backend/clear/cache',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 后端加速域名删除
|
||||
export function delBackendDomain(ids) {
|
||||
return request({
|
||||
url: '/operation/son/backend/' + ids,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 后端加速域名新增
|
||||
export function addBackendDomain(data) {
|
||||
return request({
|
||||
url: '/operation/son/backend',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 后端加速域名修改
|
||||
export function updateBackendDomain(data) {
|
||||
return request({
|
||||
url: '/operation/son/backend',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
//------------------App大厅域名---------------------//
|
||||
|
||||
// App大厅域名列表
|
||||
export function getAppDomainList(query) {
|
||||
return request({
|
||||
url: '/operation/son/app/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// App大厅刷新解析说明
|
||||
export function refreshAppDomainAnalysis(data) {
|
||||
return request({
|
||||
url: '/operation/son/app/analysis',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// App大厅域名状态修改
|
||||
export function setAppDomainStatus(data) {
|
||||
return request({
|
||||
url: '/operation/son/app/status',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// App大厅域名清理缓存
|
||||
export function clearAppDomainCache(data) {
|
||||
return request({
|
||||
url: '/operation/son/app/clear/cache',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// App大厅域名删除
|
||||
export function delAppDomain(ids) {
|
||||
return request({
|
||||
url: '/operation/son/app/' + ids,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// App大厅域名新增
|
||||
export function addAppDomain(data) {
|
||||
return request({
|
||||
url: '/operation/son/app',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// App大厅域名修改
|
||||
export function updateAppDomain(data) {
|
||||
return request({
|
||||
url: '/operation/son/app',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
//------------------OSS加速域名---------------------//
|
||||
|
||||
// OSS加速域名列表
|
||||
export function getOssDomainList(query) {
|
||||
return request({
|
||||
url: '/operation/son/oss/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// OSS加速域名刷新解析说明
|
||||
export function refreshOssDomainAnalysis(data) {
|
||||
return request({
|
||||
url: '/operation/son/oss/analysis',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// OSS加速域名状态修改
|
||||
export function setOssDomainStatus(data) {
|
||||
return request({
|
||||
url: '/operation/son/oss/status',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// OSS加速域名清理缓存
|
||||
export function clearOssDomainCache(data) {
|
||||
return request({
|
||||
url: '/operation/son/oss/clear/cache',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// OSS加速域名删除
|
||||
export function delOssDomain(ids) {
|
||||
return request({
|
||||
url: '/operation/son/oss/' + ids,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// OSS加速域名新增
|
||||
export function addOssDomain(data) {
|
||||
return request({
|
||||
url: '/operation/son/oss',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// OSS加速域名修改
|
||||
export function updateOssDomain(data) {
|
||||
return request({
|
||||
url: '/operation/son/oss',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
//------------------下载站域名---------------------//
|
||||
|
||||
// 下载站域名列表
|
||||
export function getDownloadDomainList(query) {
|
||||
return request({
|
||||
url: '/operation/son/download/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 下载站域名刷新解析说明
|
||||
export function refreshDownloadDomainAnalysis(data) {
|
||||
return request({
|
||||
url: '/operation/son/download/analysis',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 下载站域名状态修改
|
||||
export function setDownloadDomainStatus(data) {
|
||||
return request({
|
||||
url: '/operation/son/download/status',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 下载站域名清理缓存
|
||||
export function clearDownloadDomainCache(data) {
|
||||
return request({
|
||||
url: '/operation/son/download/clear/cache',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 下载站域名删除
|
||||
export function delDownloadDomain(ids) {
|
||||
return request({
|
||||
url: '/operation/son/download/' + ids,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 下载站域名新增
|
||||
export function addDownloadDomain(data) {
|
||||
return request({
|
||||
url: '/operation/son/download',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 下载站域名修改
|
||||
export function updateDownloadDomain(data) {
|
||||
return request({
|
||||
url: '/operation/son/download',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 下载站域名列表开关
|
||||
export function downloadDomainSwitch(data) {
|
||||
return request({
|
||||
url: '/operation/son/download/switch',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 下载站绑定代理
|
||||
export function bindDownloadDomainAgent(data) {
|
||||
return request({
|
||||
url: '/operation/son/download/bind/agent',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
//------------------支付域名---------------------//
|
||||
|
||||
// 支付域名列表
|
||||
export function getPayDomainList(query) {
|
||||
return request({
|
||||
url: '/operation/son/pay/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 支付域名刷新解析说明
|
||||
export function refreshPayDomainAnalysis(data) {
|
||||
return request({
|
||||
url: '/operation/son/pay/analysis',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 支付域名状态修改
|
||||
export function setPayDomainStatus(data) {
|
||||
return request({
|
||||
url: '/operation/son/pay/status',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 支付域名清理缓存
|
||||
export function clearPayDomainCache(data) {
|
||||
return request({
|
||||
url: '/operation/son/pay/clear/cache',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 支付域名删除
|
||||
export function delPayDomain(ids) {
|
||||
return request({
|
||||
url: '/operation/son/pay/' + ids,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 支付域名新增
|
||||
export function addPayDomain(data) {
|
||||
return request({
|
||||
url: '/operation/son/pay',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 支付域名修改
|
||||
export function updatePayDomain(data) {
|
||||
return request({
|
||||
url: '/operation/son/pay',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 支付域名设为主域名
|
||||
export function setPayDomainMain(data) {
|
||||
return request({
|
||||
url: '/operation/son/pay/main/son',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
//------------------外部白名单域名---------------------//
|
||||
|
||||
// 外部白名单域名列表
|
||||
export function getWhiteDomainList(query) {
|
||||
return request({
|
||||
url: '/operation/white/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 外部白名单域名新增
|
||||
export function addWhiteDomain(data) {
|
||||
return request({
|
||||
url: '/operation/white',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 外部白名单域名修改
|
||||
export function updateWhiteDomain(data) {
|
||||
return request({
|
||||
url: '/operation/white',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 外部白名单域名批量修改
|
||||
export function updateWhiteDomainBatch(data) {
|
||||
return request({
|
||||
url: '/operation/white/all',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 外部白名单域名删除
|
||||
export function delWhiteDomain(ids) {
|
||||
return request({
|
||||
url: '/operation/white/' + ids,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
//------------------自定义解析---------------------//
|
||||
|
||||
// 自定义解析列表
|
||||
export function getCustomParsingList(query) {
|
||||
return request({
|
||||
url: '/operation/analysis/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 自定义解析新增
|
||||
export function addCustomParsing(data) {
|
||||
return request({
|
||||
url: '/operation/analysis',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 自定义解析修改
|
||||
export function updateCustomParsing(data) {
|
||||
return request({
|
||||
url: '/operation/analysis',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 自定义解析删除
|
||||
export function delCustomParsing(ids) {
|
||||
return request({
|
||||
url: '/operation/analysis/' + ids,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 域名供应商列表
|
||||
export function getDomainSupplierList(query) {
|
||||
return request({
|
||||
url: '/domain/supplier/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
// 添加域名供应商
|
||||
export function addDomainSupplier(data) {
|
||||
return request({
|
||||
url: '/domain/supplier',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改域名供应商
|
||||
export function putDomainSupplier(data) {
|
||||
return request({
|
||||
url: '/domain/supplier',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
//供应商详情
|
||||
export function getDomainSupplierInfo(id) {
|
||||
return request({
|
||||
url: `/domain/supplier/${id}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
// 域名供应商开关
|
||||
export function switchDomainSupplier(data) {
|
||||
return request({
|
||||
url: '/domain/supplier/switch',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除域名供应商
|
||||
export function delDomainSupplier(ids) {
|
||||
return request({
|
||||
url: '/domain/supplier/' + ids,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 域名供应商配置
|
||||
export function configDomainSupplier(data) {
|
||||
return request({
|
||||
url: '/domain/supplier/config',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
//配置详情
|
||||
export function getDomainSupplierConfig(query) {
|
||||
return request({
|
||||
url: '/domain/supplier/config',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
|
@ -171,3 +171,29 @@ export function postSiteDeleteApiGame(data) {
|
|||
})
|
||||
}
|
||||
|
||||
//站点列表
|
||||
export function getSiteSelectList(query) {
|
||||
return request({
|
||||
url: '/site/select',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
//停用
|
||||
export function postSiteStopApiGameInfo(data) {
|
||||
return request({
|
||||
url: '/site/stop/api/game/info',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
//启用
|
||||
export function postSiteOpenApiGameInfo(data) {
|
||||
return request({
|
||||
url: '/site/open/api/game/info',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 数据源列表
|
||||
export function listDataSource(query) {
|
||||
return request({
|
||||
url: '/site/data/source/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 新增数据源
|
||||
export function addDataSourceSave(data) {
|
||||
return request({
|
||||
url: '/site/data/source/save',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改数据源
|
||||
export function updateDataSource(data) {
|
||||
return request({
|
||||
url: '/site/data/source/update',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 修改开关
|
||||
export function switchDataSource(data) {
|
||||
return request({
|
||||
url: '/site/data/source/switch',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
|
@ -8,6 +8,22 @@ export function listRole(query) {
|
|||
params: query
|
||||
})
|
||||
}
|
||||
// 获取角色选择框列表
|
||||
export function optionselect(query) {
|
||||
return request({
|
||||
url: '/system/role/optionselect',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 获取菜单角色
|
||||
export function getMenu(roleId) {
|
||||
return request({
|
||||
url: '/system/role/getMenu/' + roleId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询角色详细
|
||||
export function getRole(roleId) {
|
||||
|
|
@ -97,7 +113,15 @@ export function authUserCancelAll(data) {
|
|||
return request({
|
||||
url: '/system/role/authUser/cancelAll',
|
||||
method: 'put',
|
||||
params: data
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 批量清除关联账号
|
||||
export function authRolecancelAll(data) {
|
||||
return request({
|
||||
url: '/system/role/authRole/cancelAll',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -106,7 +130,7 @@ export function authUserSelectAll(data) {
|
|||
return request({
|
||||
url: '/system/role/authUser/selectAll',
|
||||
method: 'put',
|
||||
params: data
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,13 +43,36 @@ export function delUser(userId) {
|
|||
method: 'delete'
|
||||
})
|
||||
}
|
||||
//删除账户/批量删除
|
||||
export function deleteUserSystem(data) {
|
||||
return request({
|
||||
url: '/system/user/delete',
|
||||
method: 'delete',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
//冻结账户
|
||||
export function changeStatus(data) {
|
||||
return request({
|
||||
url: '/system/user/changeStatus',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
//清空角色
|
||||
export function resetRole(data) {
|
||||
return request({
|
||||
url: '/system/user/resetRole',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 用户密码重置
|
||||
export function resetUserPwd(userId, password,codeGoogle) {
|
||||
export function resetUserPwd(userId,inputGoogleCode) {
|
||||
const data = {
|
||||
userId,
|
||||
password,
|
||||
codeGoogle
|
||||
inputGoogleCode
|
||||
}
|
||||
return request({
|
||||
url: '/system/user/resetPwd',
|
||||
|
|
@ -58,6 +81,20 @@ export function resetUserPwd(userId, password,codeGoogle) {
|
|||
})
|
||||
}
|
||||
|
||||
// 用户重置谷歌验证码
|
||||
export function resetGoogle(userId,inputGoogleCode) {
|
||||
const data = {
|
||||
userId,
|
||||
inputGoogleCode
|
||||
}
|
||||
return request({
|
||||
url: '/system/user/resetGoogle',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 用户状态修改
|
||||
export function changeUserStatus(userId, status) {
|
||||
const data = {
|
||||
|
|
@ -89,10 +126,11 @@ export function updateUserProfile(data) {
|
|||
}
|
||||
|
||||
// 用户密码重置
|
||||
export function updateUserPwd(oldPassword, newPassword) {
|
||||
export function updateUserPwd(oldPassword, newPassword,codeGoogle) {
|
||||
const data = {
|
||||
oldPassword,
|
||||
newPassword
|
||||
newPassword,
|
||||
codeGoogle
|
||||
}
|
||||
return request({
|
||||
url: '/system/user/profile/updatePwd',
|
||||
|
|
@ -101,6 +139,18 @@ export function updateUserPwd(oldPassword, newPassword) {
|
|||
})
|
||||
}
|
||||
|
||||
// 修改密码
|
||||
export function updateUserPassword(newPassword) {
|
||||
const data = {
|
||||
newPassword
|
||||
}
|
||||
return request({
|
||||
url: '/system/user/profile/change/password',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 用户头像上传
|
||||
export function uploadAvatar(data) {
|
||||
return request({
|
||||
|
|
@ -136,11 +186,10 @@ export function deptTreeSelect() {
|
|||
})
|
||||
}
|
||||
|
||||
// 修改密码
|
||||
export function updateUserPassword(data) {
|
||||
// 用户名称检查
|
||||
export function getSystemUserCheck(userName) {
|
||||
return request({
|
||||
url: '/resetPwd',
|
||||
method: 'post',
|
||||
data: data
|
||||
url: '/system/user/check/' + userName,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,9 @@ a:hover {
|
|||
div:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style-type: none;
|
||||
}
|
||||
.fr {
|
||||
float: right;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -249,11 +249,14 @@ file_picker_callback: (cb, value, meta) => {
|
|||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style>
|
||||
.tinymce-wrapper {
|
||||
position: relative; /* ✅ 关键 */
|
||||
width: 100%;
|
||||
min-height: 500px;
|
||||
z-index: 0;
|
||||
}
|
||||
.tox-tinymce-aux {
|
||||
z-index: 2600 !important;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
<template>
|
||||
<el-dialog :title="t('上传头像')" v-model="open" width="800px" align-center append-to-body @opened="modalOpened" @close="closeDialog">
|
||||
<el-row>
|
||||
<el-col :xs="24" :md="12" :style="{ height: '350px' }">
|
||||
<vue-cropper ref="cropper" :img="options.img" :info="true" :autoCrop="options.autoCrop"
|
||||
:autoCropWidth="options.autoCropWidth" :autoCropHeight="options.autoCropHeight"
|
||||
:fixedBox="options.fixedBox" :outputType="options.outputType" @realTime="realTime" v-if="visible" />
|
||||
</el-col>
|
||||
<el-col :xs="24" :md="12" :style="{ height: '350px' }">
|
||||
<div class="avatar-upload-preview">
|
||||
<img :src="options.previews.url" :style="options.previews.img" />
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<br />
|
||||
<el-row>
|
||||
<el-col :lg="2" :md="2">
|
||||
<el-upload action="#" :http-request="requestUpload" :show-file-list="false" :before-upload="beforeUpload">
|
||||
<el-button>
|
||||
{{ t('选择') }}
|
||||
<el-icon class="el-icon--right">
|
||||
<Upload />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-upload>
|
||||
</el-col>
|
||||
<el-col :lg="{ span: 1, offset: 2 }" :md="2">
|
||||
<el-button icon="Plus" @click="changeScale(1)"></el-button>
|
||||
</el-col>
|
||||
<el-col :lg="{ span: 1, offset: 1 }" :md="2">
|
||||
<el-button icon="Minus" @click="changeScale(-1)"></el-button>
|
||||
</el-col>
|
||||
<el-col :lg="{ span: 1, offset: 1 }" :md="2">
|
||||
<el-button icon="RefreshLeft" @click="rotateLeft()"></el-button>
|
||||
</el-col>
|
||||
<el-col :lg="{ span: 1, offset: 1 }" :md="2">
|
||||
<el-button icon="RefreshRight" @click="rotateRight()"></el-button>
|
||||
</el-col>
|
||||
<el-col :lg="{ span: 2, offset: 6 }" :md="2">
|
||||
<el-button type="primary" @click="saveUploadImg()">{{ t('提 交') }}</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import "vue-cropper/dist/index.css";
|
||||
import { VueCropper } from "vue-cropper";
|
||||
import { uploadImgFile,uploadImgFileCommon } from "@/api/common";
|
||||
|
||||
const props = defineProps({
|
||||
imgInfo: {
|
||||
type: Object,
|
||||
default: {
|
||||
img: '',
|
||||
filename: ''
|
||||
}
|
||||
},
|
||||
autoCropWidth: {
|
||||
type: [Number, String],
|
||||
default: 200
|
||||
},
|
||||
autoCropHeight: {
|
||||
type: [Number, String],
|
||||
default: 200
|
||||
},
|
||||
typeUpImg: {
|
||||
type: [Number, String],
|
||||
default: 3
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['saveUpload', 'close']);
|
||||
const { proxy } = getCurrentInstance();
|
||||
const open = ref(true);
|
||||
const visible = ref(false);
|
||||
|
||||
//图片裁剪数据
|
||||
const options = reactive({
|
||||
img: props.imgInfo.img, // 裁剪图片的地址
|
||||
autoCrop: true, // 是否默认生成截图框
|
||||
autoCropWidth: props.autoCropWidth, // 默认生成截图框宽度
|
||||
autoCropHeight: props.autoCropHeight, // 默认生成截图框高度
|
||||
fixedBox: true, // 固定截图框大小 不允许改变
|
||||
outputType: "png", // 默认生成截图为PNG格式
|
||||
filename: props.imgInfo.filename, // 文件名称
|
||||
previews: {} //预览数据
|
||||
});
|
||||
|
||||
/** 打开弹出层结束时的回调 */
|
||||
function modalOpened() {
|
||||
visible.value = true;
|
||||
}
|
||||
|
||||
/** 覆盖默认上传行为 */
|
||||
function requestUpload() { }
|
||||
|
||||
/** 向左旋转 */
|
||||
function rotateLeft() {
|
||||
proxy.$refs.cropper.rotateLeft();
|
||||
}
|
||||
|
||||
/** 向右旋转 */
|
||||
function rotateRight() {
|
||||
proxy.$refs.cropper.rotateRight();
|
||||
}
|
||||
|
||||
/** 图片缩放 */
|
||||
function changeScale(num) {
|
||||
num = num || 1;
|
||||
proxy.$refs.cropper.changeScale(num);
|
||||
}
|
||||
|
||||
/** 上传预处理 */
|
||||
function beforeUpload(file) {
|
||||
if (file.type.indexOf("image/") == -1) {
|
||||
proxy.$modal.msgError(proxy.t('文件格式错误,请上传图片类型,如:JPG,PNG后缀的文件'));
|
||||
} else {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = () => {
|
||||
options.img = reader.result;
|
||||
options.filename = file.name;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/** 上传图片 */
|
||||
function saveUploadImg() {
|
||||
proxy.$refs.cropper.getCropBlob(data => {
|
||||
let formData = new FormData();
|
||||
formData.append("file", data, options.filename);
|
||||
|
||||
uploadImgFileCommon(formData,props.typeUpImg||3).then(res => {
|
||||
open.value = false;
|
||||
visible.value = false;
|
||||
emit('saveUpload', res);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** 实时预览 */
|
||||
function realTime(data) {
|
||||
options.previews = data;
|
||||
}
|
||||
|
||||
/** 关闭窗口 */
|
||||
function closeDialog() {
|
||||
open.value = false;
|
||||
visible.value = false;
|
||||
emit('close');
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped></style>
|
||||
|
|
@ -1,75 +1,77 @@
|
|||
<template>
|
||||
<div class="component-upload-image">
|
||||
<el-upload
|
||||
multiple
|
||||
:action="uploadImgUrl"
|
||||
list-type="picture-card"
|
||||
:on-success="handleUploadSuccess"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:limit="limit"
|
||||
:on-error="handleUploadError"
|
||||
:on-exceed="handleExceed"
|
||||
ref="imageUpload"
|
||||
:before-remove="handleDelete"
|
||||
:show-file-list="true"
|
||||
:headers="headers"
|
||||
:file-list="fileList"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:class="{ hide: fileList.length >= limit }"
|
||||
>
|
||||
<el-icon class="avatar-uploader-icon"><plus /></el-icon>
|
||||
</el-upload>
|
||||
<!-- 上传提示 -->
|
||||
<div class="el-upload__tip" v-if="showTip">
|
||||
请上传
|
||||
<template v-if="fileSize">
|
||||
大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
|
||||
</template>
|
||||
<template v-if="fileType">
|
||||
格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b>
|
||||
</template>
|
||||
的文件
|
||||
</div>
|
||||
<el-upload multiple :action="uploadImgUrl" :disabled="disabled" list-type="picture-card" :on-success="handleUploadSuccess"
|
||||
:before-upload="handleBeforeUpload" :limit="limit" :on-error="handleUploadError" :on-exceed="handleExceed"
|
||||
ref="imageUpload" :before-remove="handleDelete" :show-file-list="true" :headers="headers" :file-list="fileList"
|
||||
:on-preview="handlePictureCardPreview" :class="{ hide: fileList.length >= limit }">
|
||||
<el-icon class="avatar-uploader-icon">
|
||||
<plus />
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
<!-- 上传提示 -->
|
||||
<div class="el-upload__tip" v-if="showTip">
|
||||
{{ t('请上传') }}
|
||||
<template v-if="fileSize">
|
||||
{{ t('大小不超过') }} <b style="color: #f56c6c">{{ fileSize }}MB</b>
|
||||
</template>
|
||||
<template v-if="fileType">
|
||||
{{ t('格式为') }} <b style="color: #f56c6c">{{ fileType.join("/") }}</b>
|
||||
</template>
|
||||
{{ t('的文件') }}
|
||||
</div>
|
||||
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
title="预览"
|
||||
width="800px"
|
||||
append-to-body
|
||||
>
|
||||
<img
|
||||
:src="dialogImageUrl"
|
||||
style="display: block; max-width: 100%; margin: 0 auto"
|
||||
/>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="dialogVisible" :title="t('预览')" width="800px" append-to-body>
|
||||
<img :src="dialogImageUrl" style="display: block; max-width: 100%; margin: 0 auto" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getToken } from "@/utils/auth";
|
||||
import { getToken, getLocalStorage } from "@/utils/auth";
|
||||
|
||||
const props = defineProps({
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
modelValue: [String, Object, Array],
|
||||
// 图片数量限制
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 5,
|
||||
type: Number,
|
||||
default: 5,
|
||||
},
|
||||
// 图片宽高
|
||||
imgSize: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
width: 0,
|
||||
height: 0
|
||||
})
|
||||
},
|
||||
//字符和数字
|
||||
typeUpImg:{
|
||||
type: [Number, String],
|
||||
default: "1"
|
||||
},
|
||||
// 大小限制(MB)
|
||||
fileSize: {
|
||||
type: Number,
|
||||
default: 5,
|
||||
type: Number,
|
||||
default: 5,
|
||||
},
|
||||
// 文件类型, 例如['png', 'jpg', 'jpeg']
|
||||
fileType: {
|
||||
type: Array,
|
||||
default: () => ["png", "jpg", "jpeg"],
|
||||
type: Array,
|
||||
default: () => ["png", "jpg", "jpeg", "gif", "webp",'ico','mp4','mp3'],
|
||||
},
|
||||
// 是否显示提示
|
||||
isShowTip: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
|
@ -78,66 +80,92 @@ const number = ref(0);
|
|||
const uploadList = ref([]);
|
||||
const dialogImageUrl = ref("");
|
||||
const dialogVisible = ref(false);
|
||||
const baseUrl = import.meta.env.VITE_APP_BASE_API;
|
||||
const uploadImgUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传的图片服务器地址
|
||||
const baseUrl = getLocalStorage('fileUrl');
|
||||
const uploadUrl = getLocalStorage('uploadUrl');
|
||||
const uploadImgUrl = ref(uploadUrl + `/file/upload/localSysFile/${props.typeUpImg}`); // 上传的图片服务器地址
|
||||
const headers = ref({ Authorization: "Bearer " + getToken() });
|
||||
const fileList = ref([]);
|
||||
const showTip = computed(
|
||||
() => props.isShowTip && (props.fileType || props.fileSize)
|
||||
);
|
||||
|
||||
watch(() => props.modelValue, val => {
|
||||
if (val) {
|
||||
// 首先将值转为数组
|
||||
const list = Array.isArray(val) ? val : props.modelValue.split(",");
|
||||
// 然后将数组转为对象数组
|
||||
fileList.value = list.map(item => {
|
||||
if (typeof item === "string") {
|
||||
if (item.indexOf(baseUrl) === -1) {
|
||||
item = { name: baseUrl + item, url: baseUrl + item };
|
||||
} else {
|
||||
item = { name: item, url: item };
|
||||
// 首先将值转为数组
|
||||
const list = Array.isArray(val) ? val : props.modelValue.split(",");
|
||||
// 然后将数组转为对象数组
|
||||
fileList.value = list.map(item => {
|
||||
if (typeof item === "string") {
|
||||
if (item.indexOf(baseUrl) === -1) {
|
||||
item = { name: baseUrl + item, url: baseUrl + item };
|
||||
} else {
|
||||
item = { name: item, url: item };
|
||||
}
|
||||
}
|
||||
}
|
||||
return item;
|
||||
});
|
||||
return item;
|
||||
});
|
||||
} else {
|
||||
fileList.value = [];
|
||||
return [];
|
||||
fileList.value = [];
|
||||
return [];
|
||||
}
|
||||
},{ deep: true, immediate: true });
|
||||
}, { deep: true, immediate: true });
|
||||
|
||||
// 上传前loading加载
|
||||
function handleBeforeUpload(file) {
|
||||
let isImg = false;
|
||||
|
||||
// 检查图片类型
|
||||
if (props.fileType.length) {
|
||||
let fileExtension = "";
|
||||
if (file.name.lastIndexOf(".") > -1) {
|
||||
fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
|
||||
}
|
||||
isImg = props.fileType.some(type => {
|
||||
if (file.type.indexOf(type) > -1) return true;
|
||||
if (fileExtension && fileExtension.indexOf(type) > -1) return true;
|
||||
return false;
|
||||
});
|
||||
let fileExtension = "";
|
||||
if (file.name.lastIndexOf(".") > -1) {
|
||||
fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
|
||||
}
|
||||
isImg = props.fileType.some(type => {
|
||||
if (file.type.indexOf(type) > -1) return true;
|
||||
if (fileExtension && fileExtension.indexOf(type) > -1) return true;
|
||||
return false;
|
||||
});
|
||||
} else {
|
||||
isImg = file.type.indexOf("image") > -1;
|
||||
isImg = file.type.indexOf("image") > -1;
|
||||
}
|
||||
|
||||
if (!isImg) {
|
||||
proxy.$modal.msgError(
|
||||
`文件格式不正确, 请上传${props.fileType.join("/")}图片格式文件!`
|
||||
);
|
||||
return false;
|
||||
proxy.$modal.msgError(
|
||||
`文件格式不正确, 请上传${props.fileType.join("/")}图片格式文件!`
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查图片大小
|
||||
if (props.fileSize) {
|
||||
const isLt = file.size / 1024 / 1024 < props.fileSize;
|
||||
if (!isLt) {
|
||||
proxy.$modal.msgError(`上传头像图片大小不能超过 ${props.fileSize} MB!`);
|
||||
return false;
|
||||
}
|
||||
const isLt = file.size / 1024 / 1024 < props.fileSize;
|
||||
if (!isLt) {
|
||||
proxy.$modal.msgError(`上传头像图片大小不能超过 ${props.fileSize} MB!`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
proxy.$modal.loading("正在上传图片,请稍候...");
|
||||
number.value++;
|
||||
|
||||
// 检查图片宽高
|
||||
const checkSize = new Promise(function (resolve, reject) {
|
||||
// 希望的宽
|
||||
let width = props.imgSize.width;
|
||||
// 希望的高
|
||||
let height = props.imgSize.height;
|
||||
let _URL = window.URL || window.webkitURL;
|
||||
let img = new Image();
|
||||
img.onload = function () {
|
||||
let valid = img.width == width && img.height == height;
|
||||
// 符合要求 或者 没有限制宽高
|
||||
valid || (width === 0 && height === 0) ? resolve() : reject();
|
||||
}
|
||||
img.src = _URL.createObjectURL(file);
|
||||
}).then(() => {
|
||||
proxy.$modal.loading("正在上传图片,请稍候...");
|
||||
number.value++;
|
||||
}, () => {
|
||||
proxy.$modal.msgError(`上传图片尺寸必须为${props.imgSize.width}x${props.imgSize.height}px!`);
|
||||
return Promise.reject();
|
||||
});
|
||||
return checkSize;
|
||||
}
|
||||
|
||||
// 文件个数超出
|
||||
|
|
@ -148,14 +176,14 @@ function handleExceed() {
|
|||
// 上传成功回调
|
||||
function handleUploadSuccess(res, file) {
|
||||
if (res.code === 200) {
|
||||
uploadList.value.push({ name: res.fileName, url: res.fileName });
|
||||
uploadedSuccessfully();
|
||||
uploadList.value.push({ name: res.fileName, url: res.url });
|
||||
uploadedSuccessfully();
|
||||
} else {
|
||||
number.value--;
|
||||
proxy.$modal.closeLoading();
|
||||
proxy.$modal.msgError(res.msg);
|
||||
proxy.$refs.imageUpload.handleRemove(file);
|
||||
uploadedSuccessfully();
|
||||
number.value--;
|
||||
proxy.$modal.closeLoading();
|
||||
proxy.$modal.msgError(res.msg);
|
||||
proxy.$refs.imageUpload.handleRemove(file);
|
||||
uploadedSuccessfully();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -163,20 +191,20 @@ function handleUploadSuccess(res, file) {
|
|||
function handleDelete(file) {
|
||||
const findex = fileList.value.map(f => f.name).indexOf(file.name);
|
||||
if (findex > -1 && uploadList.value.length === number.value) {
|
||||
fileList.value.splice(findex, 1);
|
||||
emit("update:modelValue", listToString(fileList.value));
|
||||
return false;
|
||||
fileList.value.splice(findex, 1);
|
||||
emit("update:modelValue", listToString(fileList.value));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 上传结束处理
|
||||
function uploadedSuccessfully() {
|
||||
if (number.value > 0 && uploadList.value.length === number.value) {
|
||||
fileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value);
|
||||
uploadList.value = [];
|
||||
number.value = 0;
|
||||
emit("update:modelValue", listToString(fileList.value));
|
||||
proxy.$modal.closeLoading();
|
||||
fileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value);
|
||||
uploadList.value = [];
|
||||
number.value = 0;
|
||||
emit("update:modelValue", listToString(fileList.value));
|
||||
proxy.$modal.closeLoading();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -197,9 +225,9 @@ function listToString(list, separator) {
|
|||
let strs = "";
|
||||
separator = separator || ",";
|
||||
for (let i in list) {
|
||||
if (undefined !== list[i].url && list[i].url.indexOf("blob:") !== 0) {
|
||||
strs += list[i].url.replace(baseUrl, "") + separator;
|
||||
}
|
||||
if (undefined !== list[i].url && list[i].url.indexOf("blob:") !== 0) {
|
||||
strs += list[i].url.replace(baseUrl, "") + separator;
|
||||
}
|
||||
}
|
||||
return strs != "" ? strs.substr(0, strs.length - 1) : "";
|
||||
}
|
||||
|
|
@ -208,6 +236,6 @@ function listToString(list, separator) {
|
|||
<style scoped lang="scss">
|
||||
// .el-upload--picture-card 控制加号部分
|
||||
:deep(.hide .el-upload--picture-card) {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -13,8 +13,9 @@
|
|||
@clear="handleQuery" :maxlength="inputConfig.maxlength" :isCalculable="false" :show-word-limit="inputConfig.showWordLimit">
|
||||
</NumberInput>
|
||||
<!-- 下拉选择框字典放到inputConfig.dictKey -->
|
||||
<custom-select v-else-if="inputType === 'select'" :placeholder="t(inputPlaceholder || `请选择${currentLabel}`)" v-model="queryParams[queryParams[keyName]]" @change="handleQuery" clearable
|
||||
<custom-select v-else-if="inputType === 'select' && loadingShow" filterable :placeholder="t(inputPlaceholder || `请选择${currentLabel}`)" v-model="queryParams[queryParams[keyName]]" @change="handleQuery" clearable
|
||||
@clear="handleQuery" :options="inputConfig.options"></custom-select>
|
||||
|
||||
<!-- 普通输入框 -->
|
||||
<el-input v-else v-model="queryParams[queryParams[keyName]]"
|
||||
:placeholder="t(inputPlaceholder || `请输入${currentLabel}`)" @keyup.enter="handleQuery" clearable
|
||||
|
|
@ -55,6 +56,7 @@ const currentLabel = ref(''), inputPlaceholder = ref(''); // 输入框提示
|
|||
const inputType = ref(''); // 输入框类型
|
||||
const inputConfig = ref({}); // input框配置
|
||||
|
||||
const loadingShow = ref(true);
|
||||
// 参数切换
|
||||
const keyChange = (type) => {
|
||||
props.queryParamsList.forEach(item => {
|
||||
|
|
@ -69,6 +71,10 @@ const keyChange = (type) => {
|
|||
// value和输入框配置
|
||||
inputType.value = item.inputType || '';
|
||||
inputConfig.value = item.inputConfig || {}
|
||||
loadingShow.value = false;
|
||||
nextTick(() => {
|
||||
loadingShow.value = true;
|
||||
})
|
||||
} else {
|
||||
// 把其他的值清空
|
||||
queryParams.value[item.value] = null
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { isHttp } from '@/utils/validate'
|
|||
import { isRelogin } from '@/utils/request'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useSettingsStore from '@/store/modules/settings'
|
||||
import { getLangSelect,getTimeZone,getCurrencySelect,getMaterialGroupSelect } from '@/api/siteManagement'
|
||||
import { getLangSelect,getTimeZone,getCurrencySelect,getMaterialGroupSelect,getSiteSelectList } from '@/api/siteManagement'
|
||||
import usePermissionStore from '@/store/modules/permission'
|
||||
|
||||
|
||||
|
|
@ -41,6 +41,16 @@ router.beforeEach((to, from, next) => {
|
|||
getCurrencySelect().then((resCurrency) => {
|
||||
setLocalStorage('currencySelect', resCurrency.data);
|
||||
})
|
||||
getSiteSelectList().then((resSite) => {
|
||||
let siteSelect = resSite.data.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
value: item.id,
|
||||
label: item.siteName,
|
||||
};
|
||||
});
|
||||
setLocalStorage('siteSelect', siteSelect);
|
||||
})
|
||||
useUserStore().getDict().then(res => {
|
||||
setLocalStorage('dict', res.data);
|
||||
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@
|
|||
<el-dialog v-model="goodDialogVisible" align-center :title="t('温馨提示')" width="418" :before-close="handleClose">
|
||||
<div style="width: 90%;margin-bottom: 20px;">{{ t('请用手机打开客服端Google身份验证器,输入验证码') }}</div>
|
||||
<div class="">
|
||||
<number-input v-model="gooleCode" style="width: 90%" :placeholder="t('验证码只能为数字')" ></number-input>
|
||||
<number-input v-model="gooleCode" style="width: 90%" :maxlength="6" :placeholder="t('验证码只能为数字')" ></number-input>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
|
|
@ -90,7 +90,7 @@
|
|||
</div>
|
||||
<el-form ref="authenticatorRef" :model="authenticatorForm" :rules="authenticatorRules">
|
||||
<el-form-item label="谷歌验证码" prop="authenticatorCode">
|
||||
<number-input v-model="authenticatorForm.authenticatorCode" style="width: 100%;height: 36px;" :placeholder="t('验证码只能为数字')" ></number-input>
|
||||
<number-input v-model="authenticatorForm.authenticatorCode" :maxlength="6" style="width: 100%;height: 36px;" :placeholder="t('验证码只能为数字')" ></number-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="" style="margin-top: 20px;margin-bottom: 20px;">
|
||||
|
|
|
|||
|
|
@ -120,12 +120,26 @@ const currencySelectArr = getLocalStorage('currencySelect')?.map(item => {
|
|||
});
|
||||
const openView = ref(false);
|
||||
|
||||
const siteList = ref(getLocalStorage('siteSelect'));
|
||||
const queryParamsList = ref([{
|
||||
label: proxy.t('站点名称'),
|
||||
value: 'siteName',
|
||||
inputType: 'select',
|
||||
inputConfig:{
|
||||
options: siteList.value.map(item => {
|
||||
return {
|
||||
label: item.label,
|
||||
value: item.label,
|
||||
}
|
||||
}),
|
||||
}
|
||||
},{
|
||||
label: proxy.t('站点ID'),
|
||||
value: 'siteId',
|
||||
inputType: 'select',
|
||||
inputConfig:{
|
||||
options: siteList.value,
|
||||
}
|
||||
}]);
|
||||
const data = reactive({
|
||||
form: {},
|
||||
|
|
|
|||
|
|
@ -1,24 +1,47 @@
|
|||
<template>
|
||||
<!-- 厅主公告详情 -->
|
||||
<el-dialog :title="t('厅主公告详情')" :close-on-click-modal="false" align-center v-model="showDialog" width="900px" append-to-body>
|
||||
<!-- 详情 -->
|
||||
<el-dialog :title="t('详情')" :close-on-click-modal="false" align-center v-model="showDialog" width="900px" append-to-body>
|
||||
<el-scrollbar max-height="700px" >
|
||||
<div style="font-size: 20px; font-weight: bold; margin-bottom: 20px;width: 100%;text-align: center;">{{ modifyDate.title }}</div>
|
||||
|
||||
<el-descriptions :column="1">
|
||||
<el-descriptions-item label="公告类型">
|
||||
<span v-if="modifyDate.noticeType == 1">{{ t('日常公告') }}</span>
|
||||
<span v-if="modifyDate.noticeType == 2">{{ t('不停机维护') }}</span>
|
||||
<el-descriptions :column="1" border label-width="150px">
|
||||
<el-descriptions-item label-class-name="label-class-name" label="会员ID">
|
||||
|
||||
{{ modifyDate.id }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="发送时间">
|
||||
{{ parseTime(modifyDate.noticeStartTime) }}
|
||||
<el-descriptions-item label-class-name="label-class-name" label="会员账号">
|
||||
{{ modifyDate.memberAccount }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="公告状态">
|
||||
<dict-tag :options="noticeStatusArr" :value="modifyDate.noticeStatus" />
|
||||
<el-descriptions-item label-class-name="label-class-name" label="币种">
|
||||
{{ modifyDate.currencyType }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="内容">
|
||||
<div style="width: 100%;overflow: hidden;">
|
||||
<div v-html="modifyDate.content"></div>
|
||||
</div>
|
||||
<el-descriptions-item label-class-name="label-class-name" label="LineCode">
|
||||
--
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label-class-name="label-class-name" label="所属站点(ID)">
|
||||
{{ modifyDate.siteName }}({{ modifyDate.siteId }})
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label-class-name="label-class-name" label="总余额">
|
||||
{{ modifyDate.balance==null?'--':modifyDate.balance }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label-class-name="label-class-name" label="总输赢">
|
||||
{{ modifyDate.failAndWin== null ? '--' : modifyDate.failAndWin }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label-class-name="label-class-name" label="总打码">
|
||||
{{ modifyDate.betAmount == null ?'--': modifyDate.betAmount }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label-class-name="label-class-name" label="在线状态">
|
||||
<span v-if="modifyDate.presenceStatus== 0">离线</span>
|
||||
<span v-if="modifyDate.presenceStatus== 1">在线</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label-class-name="label-class-name" label="最后登录">
|
||||
{{ formatTime(modifyDate.loginDate) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label-class-name="label-class-name" label="注册时间">
|
||||
{{ formatTime(modifyDate.registeTime) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label-class-name="label-class-name" label="备注">
|
||||
{{ modifyDate.remark == null ? '--' : modifyDate.remark }}
|
||||
</el-descriptions-item>
|
||||
|
||||
</el-descriptions>
|
||||
|
|
@ -159,6 +182,10 @@ const closeDialog = () => {
|
|||
|
||||
}
|
||||
}
|
||||
.label-class-name{
|
||||
width: 180px;
|
||||
text-align: right !important;
|
||||
}
|
||||
</style>
|
||||
<style >
|
||||
.el-form-ge .el-form-item__content{
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
</el-table-column>
|
||||
<el-table-column :label="t('所属站点(ID)')" min-width="100" align="center" >
|
||||
<template #default="{row}">
|
||||
{{ row.siteName }}
|
||||
{{ row.siteName }}({{ row.siteId }})
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('币种')" min-width="100" align="center" prop="currencyType" >
|
||||
|
|
@ -309,7 +309,7 @@ const getSiteSelects = () => {
|
|||
|
||||
const handleView = (row) => {
|
||||
openView.value = true;
|
||||
// modifyDate.value = row;
|
||||
modifyDate.value = row;
|
||||
}
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,267 @@
|
|||
<template>
|
||||
<div class="tp-content-box">
|
||||
<el-tabs v-model="activeName" @tab-change="handleChange">
|
||||
<el-tab-pane name="1" :label="t('男头像')"></el-tab-pane>
|
||||
<el-tab-pane name="2" :label="t('女头像')"></el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<!-- 列表组件 -->
|
||||
<div class="cpt-main">
|
||||
<div class="avatar-list">
|
||||
<li v-for="item in dataList" :key="item.id">
|
||||
<img :class="item.stopStatus !== 1 ? 'img-disable' : ''" :src="fileHost + item.imgUrl">
|
||||
<span class="img-tag" v-if="item.systemType"></span>
|
||||
<div class="mask-box mb-disable" v-if="item.stopStatus !== 1">
|
||||
<p class="disable-text">{{ t('已停用') }}</p>
|
||||
</div>
|
||||
<div class="mask-box mb-btn">
|
||||
<el-button @click="changeStatus(item, 0)" v-if="item.stopStatus === 1 && item.systemType"
|
||||
type="danger">{{
|
||||
t('停用') }}</el-button>
|
||||
<el-button @click="changeStatus(item, 1)" v-if="item.stopStatus === 0 && item.systemType"
|
||||
type="success">{{
|
||||
t('启用') }}</el-button>
|
||||
<el-button v-if="!item.systemType" type="info" @click="deleteAvatar(item)">{{ t('删除') }}</el-button>
|
||||
</div>
|
||||
</li>
|
||||
<li style="border: #dddddd dashed 1px;">
|
||||
<div class="upload-box">
|
||||
<el-upload action="#" :http-request="requestUpload" :show-file-list="false"
|
||||
:before-upload="beforeUpload">
|
||||
<el-icon color="#666666" size="26">
|
||||
<Plus />
|
||||
</el-icon>
|
||||
<div class="upload-tips">
|
||||
<div>{{ t('图标大小200*200') }}</div>
|
||||
<div>{{ t('PNG或JPG格式') }}</div>
|
||||
</div>
|
||||
</el-upload>
|
||||
</div>
|
||||
</li>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 头像上传裁剪 -->
|
||||
<image-crop v-if="isShowCrop" :imgInfo="uploadInfo" @saveUpload="saveUpload" @close="isShowCrop = false"></image-crop>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 头像管理 -->
|
||||
<script setup name="Avatar">
|
||||
import ImageCrop from "@/components/ImageCrop/index.vue";
|
||||
import { getLocalStorage } from "@/utils/auth";
|
||||
import { listAvatar, addAvatar, delAvatar, updateAvatar } from "@/api/operation/avatar";
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const activeName = ref('1'); // 当前tab页
|
||||
|
||||
// 获取头像列表
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 200,
|
||||
sex: '1'
|
||||
});
|
||||
const dataList = ref([]), loading = ref(false);
|
||||
|
||||
// 男女头像切换
|
||||
const handleChange = () => {
|
||||
queryParams.sex = activeName.value;
|
||||
getAvatarList();
|
||||
}
|
||||
|
||||
// 请求头像列表
|
||||
const getAvatarList = () => {
|
||||
loading.value = true;
|
||||
listAvatar(queryParams).then(res => {
|
||||
dataList.value = res.rows;
|
||||
loading.value = false;
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
getAvatarList();
|
||||
|
||||
// 图片上传
|
||||
const fileHost = getLocalStorage('fileUrl') || ''; // 文件host
|
||||
const isShowCrop = ref(false);
|
||||
const uploadInfo = ref({
|
||||
img: '',
|
||||
filename: ''
|
||||
});
|
||||
|
||||
// 覆盖默认上传行为
|
||||
function requestUpload() { }
|
||||
|
||||
// 上传预处理
|
||||
function beforeUpload(file) {
|
||||
if (file.type.indexOf("image/") == -1) {
|
||||
proxy.$modal.msgError(proxy.t('文件格式错误,请上传图片类型,如:JPG,PNG后缀的文件'));
|
||||
} else {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = () => {
|
||||
uploadInfo.value.img = reader.result;
|
||||
uploadInfo.value.filename = file.name;
|
||||
isShowCrop.value = true; // 去裁剪
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 新增头像
|
||||
const saveUpload = (data) => {
|
||||
const params = {
|
||||
imgUrl: data.url,
|
||||
sex: activeName.value
|
||||
}
|
||||
addAvatar(params).then(res => {
|
||||
isShowCrop.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('头像新增成功'));
|
||||
getAvatarList();
|
||||
});
|
||||
}
|
||||
|
||||
// 头像启用停用
|
||||
const changeStatus = (row, status) => {
|
||||
proxy.$modal.confirm(proxy.t('确认{}该头像吗?', status === 0 ? '停用' : '启用')).then(() => {
|
||||
const params = {
|
||||
imgUrl: row.imgUrl,
|
||||
sex: row.sex,
|
||||
id: row.id,
|
||||
stopStatus: status
|
||||
}
|
||||
|
||||
updateAvatar(params).then(res => {
|
||||
proxy.$modal.msgSuccess(proxy.t('{}头像成功!', status === 0 ? '停用' : '启用'));
|
||||
getAvatarList();
|
||||
})
|
||||
}).catch(() => { });
|
||||
}
|
||||
|
||||
// 删除头像
|
||||
const deleteAvatar = (row) => {
|
||||
proxy.$modal.confirm(proxy.t('确认删除该头像吗?')).then(() => {
|
||||
delAvatar(row.id).then(res => {
|
||||
proxy.$modal.msgSuccess(proxy.t('删除头像成功!'));
|
||||
getAvatarList();
|
||||
})
|
||||
}).catch(() => { });
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.tp-content-box {
|
||||
padding: 15px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.cpt-main {
|
||||
height: calc(100% - 55px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
|
||||
.avatar-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
|
||||
li {
|
||||
min-width: 140px;
|
||||
min-height: 140px;
|
||||
width: calc(10% - 10px);
|
||||
margin: 5px;
|
||||
position: relative;
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.img-disable {
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.mask-box {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.mb-disable {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.img-tag {
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 30%;
|
||||
height: 30%;
|
||||
background: url(../../../assets/images/avatar-tag.png) no-repeat right top;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.mask-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background-color: rgba(0, 0, 0, .6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all .2s ease-in-out;
|
||||
|
||||
.disable-text {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
color: #b90505;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
padding: 8px 0;
|
||||
background-color: #ffffff;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
|
||||
.mb-disable{
|
||||
background-color: rgba(0, 0, 0, .3);
|
||||
}
|
||||
|
||||
.mb-btn {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.upload-box {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
|
||||
>div {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
:deep(.el-upload) {
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.upload-tips {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
padding-top: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,382 @@
|
|||
<template>
|
||||
<!-- 新增子域名 -->
|
||||
<el-dialog :title="t('新增域名')" v-model="isShowDialog" width="800px" append-to-body @close="closeDialog">
|
||||
<el-scrollbar max-height="600px" v-loading="loading">
|
||||
<el-form ref="formRef" :rules="rules" :model="formData" label-width="120" class="mr0">
|
||||
<el-form-item label-width="0" prop="domainSupplierId" class="clt-item">
|
||||
<span slot="label" class="label-box">
|
||||
<i style="color: #f56c6c; margin-right: 4px;">*</i>{{ t('选择节点') }}
|
||||
<icon-tips>
|
||||
<div class="node-tips">
|
||||
<p>{{ t('(1)中国市场(含港澳台):推荐使用alb域名(aws防封)、三方公共域名(aws与azure防封)、Wangsu (CDN+IP)、A8、Yundun(云盾)、Funnull(方能)、superEdge、大陆阿里云。')}}</p>
|
||||
<p>{{ t('(2)全球市场(即非中国):推荐使用使用alb域名(aws与aliyun防封)、三方公共域名(aws与azure防封)、AWS、CF、腾讯云、 阿里云、Google、Azure、华为云 、Wangsu(CDN+IP)、Yundun (云盾)。')}}</p>
|
||||
<p>{{ t('(3)Wangsu独立IP:提供独立IP地址,适用于会封禁域名,但不会封禁IP的国家(例如:印尼、中国、巴西、越南等),国际和中国大陆市场均可使用(即全球通用200USDT/IP/月),若超过7天未启用系统自动回收。') }}
|
||||
</p>
|
||||
<p>{{ t('(4)开放回源(仅限web大厅):提供开放独立源服务,可使用外部三方CDN,需申请开通(300U/月),需要专业人士配置websocket、HTTP2、缓存等,详见域名管理教程。') }}
|
||||
</p>
|
||||
</div>
|
||||
</icon-tips>:
|
||||
</span>
|
||||
<div class="item-right">
|
||||
<supplier-select v-model="formData.domainSupplierId" @change="supplierChange"
|
||||
:supplierList="supplierList" type="addSonDomain"></supplier-select>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('选择域名:')" prop="domainId" class="mr0">
|
||||
<!-- 非防封 -->
|
||||
<checkbox-select v-if="!nodeProhibitStatus" class="w100" :disabled="!supplierDomainList.length"
|
||||
:options="supplierDomainList" v-model="formData.domainId" :placeholder="t('节点下域名')"
|
||||
@change="selectDomain" @allSelect="selectDomain"></checkbox-select>
|
||||
|
||||
<!-- 防封 -->
|
||||
<el-checkbox-group v-else v-model="formData.domainId" style="width: 100%" @change="selectDomain">
|
||||
<template v-for="item in supplierDomainList" :key="item.value">
|
||||
<el-checkbox :value="item.value" :label="item.label">
|
||||
{{ item.label }}
|
||||
<icon-tips trigger="hover" v-if="item.value == -1 || item.value == -2">
|
||||
{{ item.value == -1 ? t('由系统固定分配独立ALB域名与端口,启用成功开始计费') : t('由系统随机分配云平台原生域名,启用成功开始计费') }}
|
||||
</icon-tips>
|
||||
</el-checkbox>
|
||||
</template>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('域名用途:')" class="mr0">
|
||||
{{ domainTypeName }}
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('生效域名:')" prop="domainNames" class="mr0">
|
||||
<span v-if="!formData.domainNames.length">
|
||||
{{ t('您当前未添加域名,请先到') }}
|
||||
<el-button link type="primary" @click="goDomainManage">{{ t('域名管理') }}</el-button>
|
||||
{{ t('添加主域名和验证后再来设置') }}
|
||||
</span>
|
||||
|
||||
<!-- 生效域名增删 -->
|
||||
<template v-else>
|
||||
<el-row v-for="(item, index) in formData.domainNames" :key="index" class="domain-list">
|
||||
<el-col :span="18" class="et-col">
|
||||
<el-form-item :prop="`domainNames[${index}].sonTitle`" :rules="rules.sonTitle" class="w100 mr0"
|
||||
label-width="0">
|
||||
<el-input v-model="item.sonTitle" :placeholder="t('例如:* 或 @ 或 www')" clearable>
|
||||
<template #append><b>.</b>{{ item.sonDomain }}</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6" style="text-align: right;">
|
||||
<el-button type="primary" icon="Plus" style="margin-right: 10px;"
|
||||
@click="setDomainName(index, 'add')" />
|
||||
<el-button icon="Close" style="margin-left: 0;" @click="setDomainName(index, 'delete')" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="closeDialog">{{ t('关 闭') }}</el-button>
|
||||
<el-button type="primary" @click="submitForm" :loading="loading">{{ t('确 认') }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup name="AddSonDomain">
|
||||
import SupplierSelect from '../components/SupplierSelect.vue';
|
||||
import IconTips from "@/components/IconTips"; // 小图标提示
|
||||
import CheckboxSelect from "@/components/CheckboxSelect"; // 下拉多选框
|
||||
import {
|
||||
getSupplierDomainList, // 供应商节点下域名
|
||||
addWebDomain, // 添加web大厅域名
|
||||
addBackendDomain, // 添加后端加速域名
|
||||
addAppDomain, // 添加app大厅域名
|
||||
addOssDomain, // 添加oss域名
|
||||
addDownloadDomain, // 添加下载站域名
|
||||
addPayDomain, // 添加支付域名
|
||||
}
|
||||
from "@/api/operation/domain";
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const loading = ref(false);
|
||||
const isShowDialog = ref(true); // 弹窗是否显示
|
||||
const formRef = ref();
|
||||
|
||||
// 接收参数
|
||||
const props = defineProps({
|
||||
supplierList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
});
|
||||
|
||||
// 域名用途
|
||||
const domainTypeName = computed(() => {
|
||||
if (props.type == 'webHall') {
|
||||
return proxy.t('Web大厅域名');
|
||||
} else if (props.type == 'backend') {
|
||||
return proxy.t('后端加速域名');
|
||||
} else if (props.type == 'appHall') {
|
||||
return proxy.t('App大厅域名');
|
||||
} else if (props.type == 'oss') {
|
||||
return proxy.t('OSS加速域名');
|
||||
} else if (props.type == 'downloadSite') {
|
||||
return proxy.t('下载站域名');
|
||||
} else if (props.type == 'payment') {
|
||||
return proxy.t('支付域名');
|
||||
}
|
||||
});
|
||||
|
||||
// 表单参数
|
||||
const formData = reactive({
|
||||
domainSupplierId: '',
|
||||
domainId: [],
|
||||
domainNames: []
|
||||
});
|
||||
|
||||
// 表单校验
|
||||
const rules = reactive({
|
||||
domainSupplierId: [
|
||||
{ required: true, message: proxy.t('请选择节点'), trigger: 'change' },
|
||||
],
|
||||
domainId: [
|
||||
{ required: true, message: proxy.t('请选择域名'), trigger: 'change' }
|
||||
],
|
||||
sonTitle: [
|
||||
{ required: true, message: proxy.t('请输入子域名'), trigger: ['change', 'blur'] },
|
||||
{
|
||||
pattern: /^[\w\*@]+$/,
|
||||
message: proxy.t('只能包含字母、数字、下划线、星号和@'),
|
||||
trigger: ['change', 'blur']
|
||||
},
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
const _index = +rule.field.toString().match(/\d+/)[0], _domainNames = formData.domainNames;
|
||||
let isHas = false;
|
||||
|
||||
_domainNames.forEach((item, index) => {
|
||||
if (index != _index && item.sonTitle != '' && item.sonTitle + '.' + item.sonDomain == _domainNames[_index].sonTitle + '.' + _domainNames[_index].sonDomain) {
|
||||
isHas = true;
|
||||
}
|
||||
});
|
||||
if (isHas) {
|
||||
callback(new Error(proxy.t('子域名不能重复')));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// 选择供应商节点
|
||||
const supplierDomainList = ref([]),
|
||||
nodeProhibitStatus = ref(false); // 当前节点是否防封
|
||||
const supplierChange = (val) => {
|
||||
// 清空表单
|
||||
formData.domainId = [];
|
||||
formData.domainNames = [];
|
||||
|
||||
// 查找当前节点是否防封
|
||||
nodeProhibitStatus.value = props.supplierList.find(v => v.id == val).prohibit;
|
||||
|
||||
getSupplierDomainList({ domainSupplierId: val }).then(res => {
|
||||
supplierDomainList.value = res.data.map(v => {
|
||||
return {
|
||||
label: v.name,
|
||||
value: v.id
|
||||
}
|
||||
});
|
||||
|
||||
// 如果是防封节点,则增加选项
|
||||
if (nodeProhibitStatus.value) {
|
||||
const _domainList = [{
|
||||
label: proxy.t('三方公共域名(防封)'),
|
||||
value: '-2'
|
||||
}];
|
||||
|
||||
// 如果是web大厅则增加选项
|
||||
if (props.type == 'webHall') {
|
||||
_domainList.unshift({
|
||||
label: proxy.t('ALB防封域名'),
|
||||
value: '-1'
|
||||
});
|
||||
}
|
||||
|
||||
supplierDomainList.value = [..._domainList, ...supplierDomainList.value];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 选择域名
|
||||
const selectDomain = (val) => {
|
||||
const _domainNames = [];
|
||||
|
||||
// 查找当前选中的域名信息
|
||||
val.forEach(thisId => {
|
||||
if (thisId != -1 && thisId != -2) { // 防封状态没有子域名
|
||||
const domainInfo = supplierDomainList.value.find(v => v.value == thisId);
|
||||
let isHas = false;
|
||||
|
||||
// 查找当前选中的域名是否已存在
|
||||
formData.domainNames.forEach(item => {
|
||||
if (item.domainId == domainInfo.value) {
|
||||
isHas = true;
|
||||
_domainNames.push({...item});
|
||||
}
|
||||
});
|
||||
|
||||
// 不存在则新增
|
||||
if (!isHas) {
|
||||
_domainNames.push({
|
||||
domainId: thisId,
|
||||
sonTitle: '',
|
||||
sonDomain: domainInfo.label
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
formData.domainNames = _domainNames;
|
||||
}
|
||||
|
||||
// 子域名增删
|
||||
const setDomainName = (index, type) => {
|
||||
if (type === 'add') {
|
||||
// 当前位置后面复制一份
|
||||
const copyItem = JSON.parse(JSON.stringify(formData.domainNames[index]));
|
||||
|
||||
copyItem.sonTitle = '';
|
||||
formData.domainNames.splice(index + 1, 0, copyItem);
|
||||
} else {
|
||||
// 如果当前domainNames记录删完了,则删除对应formData.domainId
|
||||
const _domainNameId = formData.domainNames[index].domainId;
|
||||
|
||||
formData.domainNames.splice(index, 1);
|
||||
formData.domainNames.findIndex(v => v.domainId == _domainNameId) == -1 && formData.domainId.splice(formData.domainId.findIndex(v => v == _domainNameId), 1);
|
||||
}
|
||||
}
|
||||
|
||||
// 提交
|
||||
const submitForm = () => {
|
||||
formRef.value.validate(valid => {
|
||||
if (valid) {
|
||||
// 组装参数
|
||||
const operationDomainSons = [];
|
||||
|
||||
// 防封状态
|
||||
formData.domainId.forEach(item => {
|
||||
if (item == -1 || item == -2) {
|
||||
operationDomainSons.push({
|
||||
domainSupplierId: formData.domainSupplierId,
|
||||
domainId: item
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 非防封状态
|
||||
formData.domainNames.forEach(item => {
|
||||
operationDomainSons.push({
|
||||
domainSupplierId: formData.domainSupplierId,
|
||||
domainId: item.domainId,
|
||||
name: item.sonTitle + '.' + item.sonDomain,
|
||||
});
|
||||
});
|
||||
|
||||
// 提交
|
||||
loading.value = true;
|
||||
switch (props.type) {
|
||||
case 'webHall':
|
||||
submitSuccess(addWebDomain({ operationDomainSons: operationDomainSons }));
|
||||
break;
|
||||
case 'backend':
|
||||
submitSuccess(addBackendDomain({ operationDomainSons: operationDomainSons }));
|
||||
break;
|
||||
case 'appHall':
|
||||
submitSuccess(addAppDomain({ operationDomainSons: operationDomainSons }));
|
||||
break;
|
||||
case 'oss':
|
||||
submitSuccess(addOssDomain({ operationDomainSons: operationDomainSons }));
|
||||
break;
|
||||
case 'downloadSite':
|
||||
submitSuccess(addDownloadDomain({ operationDomainSons: operationDomainSons }));
|
||||
break;
|
||||
case 'payment':
|
||||
submitSuccess(addPayDomain({ operationDomainSons: operationDomainSons }));
|
||||
break;
|
||||
}
|
||||
|
||||
// 提交后回调
|
||||
function submitSuccess(apiFn) {
|
||||
apiFn.then(() => {
|
||||
loading.value = false;
|
||||
proxy.$message.success(proxy.t('添加成功'));
|
||||
closeDialog('submit');
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const emit = defineEmits(['closeDialog', 'goDomainManage']);
|
||||
const closeDialog = (type) => {
|
||||
emit('closeDialog', type);
|
||||
}
|
||||
|
||||
// 前往域名管理
|
||||
const goDomainManage = () => {
|
||||
emit('goDomainManage');
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
// 自定义表单label
|
||||
.clt-item {
|
||||
.label-box {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.item-right {
|
||||
width: calc(100% - 120px);
|
||||
}
|
||||
|
||||
// 校验提示位置
|
||||
:deep(.el-form-item__error) {
|
||||
padding-left: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
.node-tips {
|
||||
width: 550px;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
padding: 5px 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 生效域名列表
|
||||
.domain-list {
|
||||
width: 100%;
|
||||
margin-bottom: 18px;
|
||||
|
||||
.et-col {
|
||||
line-height: 32px;
|
||||
padding-right: 5px;
|
||||
|
||||
&:last-child {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,265 @@
|
|||
<template>
|
||||
<!-- 批量操作弹窗 -->
|
||||
<el-dialog :title="dialogTitle" v-model="isShowDialog" width="800px" append-to-body @close="closeDialog">
|
||||
<el-scrollbar max-height="600px" v-loading="loading">
|
||||
<el-table row-key="id" stripe border :data="tableList">
|
||||
<el-table-column :label="t('主域名')" align="center" min-width="150"
|
||||
v-if="batchOpType == 'port' || batchOpType == 'clearCache' || batchOpType == 'delete' || batchOpType == 'stop' || batchOpType == 'enable'">
|
||||
<template #default="{ row }">
|
||||
{{ row.mainName || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('CDN节点')" prop="cdnNodeName" align="center" min-width="150"></el-table-column>
|
||||
<el-table-column :label="t('子域名')" prop="name" align="center" min-width="150"></el-table-column>
|
||||
<el-table-column :label="t('其他担保域名列表')" align="center" min-width="150"
|
||||
v-if="batchOpType == 'showSecurity' || batchOpType == 'hideSecurity'">
|
||||
<template #default="{ row }">
|
||||
{{ row.backupDomain ? t('展示') : t('隐藏') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('作为推广域名')" align="center" min-width="150"
|
||||
v-if="batchOpType == 'showPromotion' || batchOpType == 'hidePromotion'">
|
||||
<template #default="{ row }">
|
||||
{{ row.marketingDomain ? t('开启') : t('关闭') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('启用入口')" align="center" min-width="150" v-if="batchOpType == 'edit'">
|
||||
<template #default="{ row }">
|
||||
<dict-select class="w100" v-model="row.startEntrance" dictKey="ff_operation_start_entrance"
|
||||
:disabled="row.usageStatus != 4"></dict-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('屏蔽设备')" align="center" min-width="150" v-if="batchOpType == 'edit'">
|
||||
<template #default="{ row }">
|
||||
<dict-select class="w100" v-model="row.blockDevice" dictKey="ff_operation_block_device"
|
||||
:disabled="row.usageStatus != 4 || row.startEntrance == 2"></dict-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('强制绑定代理账号(选填)')" align="center" min-width="150"
|
||||
v-if="batchOpType == 'bindAgent'">
|
||||
<template #default="{ row }">
|
||||
<el-input v-model="row.agentAccount" :placeholder="t('请输入代理账号')" clearable></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-scrollbar>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="closeDialog">{{ t('关 闭') }}</el-button>
|
||||
<el-button type="primary" @click="submitForm" :loading="loading">{{ t('确 认') }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup name="BatchOperation">
|
||||
import {
|
||||
changeWebDomainPort, // 批量更换端口
|
||||
clearWebDomainCache, // 批量清理缓存
|
||||
delWebDomain, // 批量删除
|
||||
setWebDomainStatus, // 批量修改状态
|
||||
webDomainSwitch, // 批量开关
|
||||
bindWebDomainAgent, // 批量绑定代理
|
||||
} from "@/api/operation/domain";
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const loading = ref(false);
|
||||
const isShowDialog = ref(true);
|
||||
|
||||
// 接收参数
|
||||
const props = defineProps({
|
||||
selectionData: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
batchOpType: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
});
|
||||
|
||||
// 监听参数
|
||||
const tableList = ref([]);
|
||||
watch(() => props.selectionData, newVal => {
|
||||
const _tableList = JSON.parse(JSON.stringify(newVal)); // 以免影响原表格数据
|
||||
|
||||
switch (props.batchOpType) {
|
||||
case 'port':
|
||||
// 防封域名不能更换端口
|
||||
tableList.value = _tableList.filter(v => v.sonType != -1 && v.sonType != -2);
|
||||
break
|
||||
case 'stop':
|
||||
// 过滤已停用的域名
|
||||
tableList.value = _tableList.filter(v => v.usageStatus != 5);
|
||||
break
|
||||
case 'enable':
|
||||
// 过滤已启用的域名
|
||||
tableList.value = _tableList.filter(v => v.usageStatus != 4);
|
||||
break
|
||||
case 'showSecurity':
|
||||
// 关闭状态并且启用成功的域名
|
||||
tableList.value = _tableList.filter(v => !v.backupDomain && v.usageStatus == 4);
|
||||
break
|
||||
case 'hideSecurity':
|
||||
// 开启状态并且启用成功的域名
|
||||
tableList.value = _tableList.filter(v => v.backupDomain && v.usageStatus == 4);
|
||||
break
|
||||
case 'showPromotion':
|
||||
// 关闭状态/启用成功/启用入口不是仅极速APP的域名
|
||||
tableList.value = _tableList.filter(v => !v.marketingDomain && v.usageStatus == 4 && v.startEntrance != 2);
|
||||
break
|
||||
case 'hidePromotion':
|
||||
// 开启状态/启用成功/启用入口不是仅极速APP的域名
|
||||
tableList.value = _tableList.filter(v => v.marketingDomain && v.usageStatus == 4 && v.startEntrance != 2);
|
||||
break
|
||||
case 'bindAgent':
|
||||
// 启用状态才能绑定代理
|
||||
tableList.value = _tableList.filter(v => v.usageStatus == 4);
|
||||
break
|
||||
default:
|
||||
tableList.value = _tableList;
|
||||
break
|
||||
}
|
||||
}, { immediate: true });
|
||||
|
||||
// 弹窗标题
|
||||
const dialogTitle = computed(() => {
|
||||
if (props.batchOpType === 'port') {
|
||||
return proxy.t('批量更换端口');
|
||||
} else if (props.batchOpType === 'clearCache') {
|
||||
return proxy.t('批量清理缓存');
|
||||
} else if (props.batchOpType === 'delete') {
|
||||
return proxy.t('批量删除');
|
||||
} else if (props.batchOpType === 'stop') {
|
||||
return proxy.t('批量停用');
|
||||
} else if (props.batchOpType === 'enable') {
|
||||
return proxy.t('批量启用');
|
||||
} else if (props.batchOpType === 'issued') {
|
||||
return proxy.t('批量锁定下发');
|
||||
} else if (props.batchOpType === 'showSecurity') {
|
||||
return proxy.t('批量展示其他担保列表');
|
||||
} else if (props.batchOpType === 'hideSecurity') {
|
||||
return proxy.t('批量隐藏其他担保列表');
|
||||
} else if (props.batchOpType === 'showPromotion') {
|
||||
return proxy.t('批量开启推广域名');
|
||||
} else if (props.batchOpType === 'hidePromotion') {
|
||||
return proxy.t('批量关闭推广域名');
|
||||
} else if (props.batchOpType === 'edit') {
|
||||
return proxy.t('批量修改');
|
||||
} else if (props.batchOpType === 'bindAgent') {
|
||||
return proxy.t('批量绑定代理');
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
});
|
||||
|
||||
// 提交
|
||||
const submitForm = () => {
|
||||
loading.value = true;
|
||||
const params = {
|
||||
ids: tableList.value.map(item => item.id)
|
||||
};
|
||||
|
||||
switch (props.batchOpType) {
|
||||
case 'port':
|
||||
submitSuccess(changeWebDomainPort(params), proxy.t('批量端口更换成功'));
|
||||
break;
|
||||
case 'clearCache':
|
||||
submitSuccess(clearWebDomainCache(params), proxy.t('批量清理缓存成功'));
|
||||
break;
|
||||
case 'delete':
|
||||
submitSuccess(delWebDomain(params.ids.join(',')), proxy.t('批量删除成功'));
|
||||
break;
|
||||
case 'stop':
|
||||
params.usageStatus = 5;
|
||||
submitSuccess(setWebDomainStatus(params), proxy.t('批量停用成功'));
|
||||
break;
|
||||
case 'enable':
|
||||
params.usageStatus = 4;
|
||||
submitSuccess(setWebDomainStatus(params), proxy.t('批量启用成功'));
|
||||
break;
|
||||
case 'showSecurity':
|
||||
const _showParams = [];
|
||||
params.ids.forEach(id => {
|
||||
_showParams.push({
|
||||
id: id,
|
||||
backupDomain: true
|
||||
})
|
||||
});
|
||||
|
||||
submitSuccess(webDomainSwitch({ operationDomainSons: _showParams }), proxy.t('批量展示其他担保列表成功'));
|
||||
break;
|
||||
case 'hideSecurity':
|
||||
const _hideParams = [];
|
||||
params.ids.forEach(id => {
|
||||
_hideParams.push({
|
||||
id: id,
|
||||
backupDomain: false
|
||||
})
|
||||
});
|
||||
submitSuccess(webDomainSwitch({ operationDomainSons: _hideParams }), proxy.t('批量隐藏其他担保列表成功'));
|
||||
break;
|
||||
case 'showPromotion':
|
||||
const _showPromotionParams = [];
|
||||
params.ids.forEach(id => {
|
||||
_showPromotionParams.push({
|
||||
id: id,
|
||||
marketingDomain: true
|
||||
})
|
||||
});
|
||||
submitSuccess(webDomainSwitch({ operationDomainSons: _showPromotionParams }), proxy.t('批量开启推广域名成功'));
|
||||
break;
|
||||
case 'hidePromotion':
|
||||
const _hidePromotionParams = [];
|
||||
params.ids.forEach(id => {
|
||||
_hidePromotionParams.push({
|
||||
id: id,
|
||||
marketingDomain: false
|
||||
})
|
||||
});
|
||||
submitSuccess(webDomainSwitch({ operationDomainSons: _hidePromotionParams }), proxy.t('批量关闭推广域名成功'));
|
||||
case 'edit':
|
||||
const _editParams = [];
|
||||
params.ids.forEach(id => {
|
||||
const item = tableList.value.find(v => v.id == id);
|
||||
_editParams.push({
|
||||
id: id,
|
||||
startEntrance: item.startEntrance,
|
||||
blockDevice: item.blockDevice
|
||||
})
|
||||
});
|
||||
submitSuccess(webDomainSwitch({ operationDomainSons: _editParams }), proxy.t('批量修改成功'));
|
||||
break;
|
||||
case 'bindAgent':
|
||||
const _agentParams = [];
|
||||
params.ids.forEach(id => {
|
||||
const item = tableList.value.find(v => v.id == id);
|
||||
_agentParams.push({
|
||||
id: id,
|
||||
agentAccount: item.agentAccount
|
||||
})
|
||||
});
|
||||
submitSuccess(bindWebDomainAgent({ operationDomainSons: _agentParams }), proxy.t('批量绑定代理成功'));
|
||||
break;
|
||||
}
|
||||
|
||||
// 提交后回调
|
||||
function submitSuccess(apiFn, msg) {
|
||||
apiFn.then(() => {
|
||||
loading.value = false;
|
||||
proxy.$message.success(msg);
|
||||
closeDialog('batchSubmit');
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const emit = defineEmits(['closeDialog']);
|
||||
const closeDialog = (type) => {
|
||||
emit('closeDialog', type);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
<template>
|
||||
<!-- 绑定代理 -->
|
||||
<el-dialog :title="t('绑定代理')" v-model="isShowDialog" width="700px" append-to-body @close="closeDialog">
|
||||
<el-scrollbar max-height="600px" v-loading="loading">
|
||||
<el-form ref="formRef" :model="formData" label-width="120">
|
||||
<el-form-item :label="t('当前节点:')">
|
||||
{{ currentDomainInfo.cdnNodeName }}
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('生效域名:')">
|
||||
{{ currentDomainInfo.name }}
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('域名用途:')">
|
||||
{{ domainTypeName }}
|
||||
</el-form-item>
|
||||
<el-form-item label-width="0" class="clt-item">
|
||||
<span slot="label" class="label-box">
|
||||
{{ t('强制绑定代理账号(选填):') }}
|
||||
</span>
|
||||
<div class="item-right">
|
||||
<el-input v-model="formData.agentAccount" :placeholder="t('请输入代理账号')" clearable />
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('功能说明:')">
|
||||
{{ t('线下代理专属域名,上级归属的优先级:推广链接的上级 > 渠道ID的强制绑定上级 > 域名管理的强制绑定上级(无上级时,域名管理的才生效)') }}
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="closeDialog">{{ t('关 闭') }}</el-button>
|
||||
<el-button type="primary" @click="submitForm" :loading="loading">{{ t('确 认') }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup name="BindAgent">
|
||||
import { bindWebDomainAgent, bindDownloadDomainAgent } from "@/api/operation/domain";
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const loading = ref(false);
|
||||
const isShowDialog = ref(true); // 弹窗是否显示
|
||||
const formRef = ref();
|
||||
|
||||
// 接收参数
|
||||
const props = defineProps({
|
||||
currentDomainInfo: {
|
||||
type: Object,
|
||||
default: () => { }
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
});
|
||||
|
||||
// 域名用途
|
||||
const domainTypeName = computed(() => {
|
||||
if (props.type == 'webHall') {
|
||||
return proxy.t('Web大厅域名');
|
||||
} else if (props.type == 'downloadSite') {
|
||||
return proxy.t('下载站域名');
|
||||
}
|
||||
});
|
||||
|
||||
// 表单参数
|
||||
const formData = reactive({
|
||||
agentAccount: props.currentDomainInfo.agentAccount
|
||||
});
|
||||
|
||||
// 提交
|
||||
const submitForm = () => {
|
||||
const params = {
|
||||
operationDomainSons: [{
|
||||
id: props.currentDomainInfo.id,
|
||||
agentAccount: formData.agentAccount
|
||||
}]
|
||||
}
|
||||
|
||||
// 提交
|
||||
loading.value = true;
|
||||
switch (props.type) {
|
||||
case 'webHall':
|
||||
submitSuccess(bindWebDomainAgent(params));
|
||||
break;
|
||||
case 'downloadSite':
|
||||
submitSuccess(bindDownloadDomainAgent(params));
|
||||
break;
|
||||
}
|
||||
|
||||
// 提交后回调
|
||||
function submitSuccess(apiFn) {
|
||||
apiFn.then(() => {
|
||||
loading.value = false;
|
||||
proxy.$message.success(proxy.t('代理绑定成功'));
|
||||
closeDialog('submit');
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const emit = defineEmits(['closeDialog']);
|
||||
const closeDialog = (type) => {
|
||||
emit('closeDialog', type);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
// 自定义表单label
|
||||
.clt-item {
|
||||
.label-box {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.item-right {
|
||||
width: calc(100% - 120px);
|
||||
}
|
||||
|
||||
// 校验提示位置
|
||||
:deep(.el-form-item__error) {
|
||||
padding-left: 120px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,174 @@
|
|||
<template>
|
||||
<!-- 修改域名 -->
|
||||
<el-dialog :title="t('修改域名')" v-model="isShowDialog" width="600px" append-to-body @close="closeDialog">
|
||||
<el-scrollbar max-height="600px" v-loading="loading">
|
||||
<el-form ref="formRef" :rules="rules" :model="formData" label-width="100">
|
||||
<el-form-item :label="t('当前节点:')">
|
||||
{{ currentDomainInfo.cdnNodeName }}
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('主域名:')">
|
||||
{{ domainStr[1] }}
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('域名用途:')">
|
||||
{{ domainTypeName }}
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('生效域名:')" prop="name" class="mr0">
|
||||
<el-input class="w100" v-model="formData.name" :placeholder="t('例如:* 或 @ 或 www')" clearable>
|
||||
<template #append><b>.</b>{{ domainStr[1] }}</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="closeDialog">{{ t('关 闭') }}</el-button>
|
||||
<el-button type="primary" @click="submitForm" :loading="loading">{{ t('确 认') }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup name="EditSonDomain">
|
||||
import {
|
||||
updateWebDomain, // 修改web大厅域名
|
||||
updateBackendDomain, // 修改后端加速域名
|
||||
updateAppDomain, // 修改app大厅域名
|
||||
updateOssDomain, // 修改oss加速域名
|
||||
updateDownloadDomain, // 修改下载站域名
|
||||
updatePayDomain, // 修改支付域名
|
||||
} from "@/api/operation/domain";
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const loading = ref(false);
|
||||
const isShowDialog = ref(true); // 弹窗是否显示
|
||||
const formRef = ref();
|
||||
|
||||
// 接收参数
|
||||
const props = defineProps({
|
||||
currentDomainInfo: {
|
||||
type: Object,
|
||||
default: () => { }
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
});
|
||||
|
||||
// 域名用途
|
||||
const domainTypeName = computed(() => {
|
||||
if (props.type == 'webHall') {
|
||||
return proxy.t('Web大厅域名');
|
||||
} else if (props.type == 'backend') {
|
||||
return proxy.t('后端加速域名');
|
||||
} else if (props.type == 'appHall') {
|
||||
return proxy.t('App大厅域名');
|
||||
} else if (props.type == 'oss') {
|
||||
return proxy.t('OSS加速域名');
|
||||
} else if (props.type == 'downloadSite') {
|
||||
return proxy.t('下载站域名');
|
||||
} else if (props.type == 'payment') {
|
||||
return proxy.t('支付域名');
|
||||
}
|
||||
});
|
||||
|
||||
// 拆分成域名主体和前缀
|
||||
const domainStr = computed(() => {
|
||||
const _domainName = props.currentDomainInfo.name;
|
||||
|
||||
if (_domainName) {
|
||||
const index = _domainName.indexOf('.');
|
||||
if (index !== -1) {
|
||||
return [_domainName.substring(0, index), _domainName.substring(index + 1)]
|
||||
}
|
||||
}
|
||||
return [];
|
||||
});
|
||||
|
||||
// 表单参数
|
||||
const formData = reactive({
|
||||
name: domainStr.value[0]
|
||||
});
|
||||
|
||||
// 表单校验
|
||||
const rules = reactive({
|
||||
name: [
|
||||
{ required: true, message: proxy.t('请输入子域名'), trigger: ['change', 'blur'] },
|
||||
{
|
||||
pattern: /^[\w\*@]+$/,
|
||||
message: proxy.t('只能包含字母、数字、下划线、星号和@'),
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// 提交
|
||||
const submitForm = () => {
|
||||
formRef.value.validate(valid => {
|
||||
if (valid) {
|
||||
const params = {
|
||||
id: props.currentDomainInfo.id,
|
||||
name: formData.name + '.' + domainStr.value[1]
|
||||
}
|
||||
|
||||
// 提交
|
||||
loading.value = true;
|
||||
switch (props.type) {
|
||||
case 'webHall':
|
||||
submitSuccess(updateWebDomain(params));
|
||||
break;
|
||||
case 'backend':
|
||||
submitSuccess(updateBackendDomain(params));
|
||||
break;
|
||||
case 'appHall':
|
||||
submitSuccess(updateAppDomain(params));
|
||||
break;
|
||||
case 'oss':
|
||||
submitSuccess(updateOssDomain(params));
|
||||
break;
|
||||
case 'downloadSite':
|
||||
submitSuccess(updateDownloadDomain(params));
|
||||
break;
|
||||
case 'payment':
|
||||
submitSuccess(updatePayDomain(params));
|
||||
break;
|
||||
}
|
||||
|
||||
// 提交后回调
|
||||
function submitSuccess(apiFn) {
|
||||
apiFn.then(() => {
|
||||
loading.value = false;
|
||||
proxy.$message.success(proxy.t('修改成功'));
|
||||
closeDialog('submit');
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const emit = defineEmits(['closeDialog']);
|
||||
const closeDialog = (type) => {
|
||||
emit('closeDialog', type);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
// 自定义表单label
|
||||
.clt-item {
|
||||
.label-box {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.item-right {
|
||||
width: calc(100% - 100px);
|
||||
}
|
||||
|
||||
// 校验提示位置
|
||||
:deep(.el-form-item__error) {
|
||||
padding-left: 100px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
<template>
|
||||
<!-- 列表左侧域名供应商选择按钮 -->
|
||||
<el-radio-group v-model="domainSupplierId" size="large" class="supplier-button" @change="changeVal">
|
||||
<el-radio-button value="" :label="t('全部')" />
|
||||
<template v-for="item in supplierList" :key="item.id">
|
||||
<el-radio-button :value="item.id">
|
||||
<template #default>
|
||||
<span>{{ item.supplierName }}</span>
|
||||
<span class="rb-tag"
|
||||
:style="'background-color:' + (item.supplierType == 1 ? '#F56C6C' : item.supplierType == 2 ? '#409EFF' : '#67C23A')">
|
||||
{{ item.supplierTypeName }}
|
||||
</span>
|
||||
</template>
|
||||
</el-radio-button>
|
||||
</template>
|
||||
</el-radio-group>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getSupplierList } from "@/api/operation/domain";
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const domainSupplierId = defineModel(); // 选中域名供应商ID
|
||||
|
||||
// 初始化列表
|
||||
onMounted(() => {
|
||||
getSupplierInfo();
|
||||
});
|
||||
|
||||
// 域名供应商列表
|
||||
const supplierList = ref([]);
|
||||
const supplierTips = reactive({
|
||||
'Az': proxy.t('此节点属于微软官方CDN,国际和中国大陆市场均可使用(即全球通用)。微软防封:此节点提供了第三方公共域名,该域名随机生成,可防封防屏蔽(即无需使用自己域名),国际和中国大陆市场均可使用(即全球通用)。'),
|
||||
'ALY-CN': proxy.t('此节点是大陆专用的阿里云,只适合中国大陆市场,存活期间不会出现被封,速度最快最稳定,但需要自行购买备案域名和大陆阿里云账号来配置(即购买阿里云小号,一般存活一个多月后被封,所以可能需要频繁换备案域名或换号)。'),
|
||||
'WS': proxy.t('此节点覆盖中国大陆和国际市场,国际和中国大陆市场均可使用(即全球通用)。'),
|
||||
'AliYun': proxy.t('此节点只适合海外市场,且禁止中国地区访问和使用(含港澳台)。'),
|
||||
'WSIP': proxy.t('此节点提供独立IP地址,适用于会封禁域名,但不会封禁IP的国家(例如:印尼、中国、巴西、越南等),国际和中国大陆市场均可使用(即全球通用)。'),
|
||||
'A8': proxy.t('此节点属于大陆到香港CN2专线,只推荐中国大陆市场使用,海外市场不推荐。'),
|
||||
'AWS': proxy.t('此节点属于亚马逊官方CDN,国际和中国大陆市场均可使用(即全球通用)。'),
|
||||
'SE': proxy.t('此节点具备独家移动清洗线路功能,即可以防止中国大陆运营商屏蔽,仅限于中国大陆市场使用。'),
|
||||
'CF': proxy.t('全球最大CDN供应商,主要可以抗攻击,国际和中国大陆市场均可使用(即全球通用)。'),
|
||||
'YD': proxy.t('节点主要分布在推荐东南亚与印度、中国大陆市场,推荐东南亚和大陆使用。'),
|
||||
'FN': proxy.t('此节点属于大陆到香港CN2专线,只推荐中国大陆市场使用,海外市场不推荐。'),
|
||||
'HWCloud': proxy.t('此节点只适合海外市场,且禁止中国地区访问和使用(含港澳台)。'),
|
||||
'TCCloud': proxy.t('此节点只适合海外市场,且禁止中国地区访问和使用(含港澳台)。'),
|
||||
'GC': proxy.t('仅限于国际市场使用,不能用在中国市场。'),
|
||||
'OSR': proxy.t('我方提供独立源服务IP信息,您可使用外部三方CDN绑定到我方源站,所以仅限web大厅使用(不支持原生APP),需要有专业知识才能配置websocket、HTTP2、缓存等信息,详见域名管理教程。')
|
||||
});
|
||||
|
||||
// 获取域名供应商列表
|
||||
const getSupplierInfo = () => {
|
||||
getSupplierList().then(res => {
|
||||
const _data = res.data;
|
||||
|
||||
if (_data.length) {
|
||||
const supplierType = [
|
||||
{ value: 1, label: '全球' },
|
||||
{ value: 2, label: '大陆' },
|
||||
{ value: 3, label: '国际' }
|
||||
]; // 供应商类型
|
||||
|
||||
// 供应商类型名称和描述
|
||||
_data.forEach(item => {
|
||||
item.tips = supplierTips[item.supplierCode];
|
||||
item.supplierTypeName = supplierType.find(i => i.value == item.supplierType).label;
|
||||
});
|
||||
|
||||
supplierList.value = _data;
|
||||
console.log(supplierList.value);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 当前供应商节点
|
||||
const curSupplierNode = computed(() => {
|
||||
return supplierList.value.find(item => item.id == domainSupplierId.value);
|
||||
});
|
||||
|
||||
const emit = defineEmits(['getCurSupplierNode']);
|
||||
const changeVal = () => {
|
||||
emit('getCurSupplierNode', curSupplierNode.value);
|
||||
}
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
getSupplierInfo,
|
||||
supplierList
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.supplier-button {
|
||||
width: calc(100% - 15px);
|
||||
|
||||
:deep(.el-radio-button) {
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.el-radio-button__inner {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #dcdfe6 !important;
|
||||
}
|
||||
|
||||
&.is-active .el-radio-button__inner {
|
||||
box-shadow: none;
|
||||
border: 1px solid #409EFF !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rb-tag {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
right: -5px;
|
||||
top: -5px;
|
||||
color: #ffffff;
|
||||
font-size: 10px;
|
||||
padding: 0 5px;
|
||||
line-height: 1.5;
|
||||
border-radius: 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
<template>
|
||||
<el-radio-group v-model="supplierId" class="supplier-box">
|
||||
<el-radio v-for="item in supplierList" :value="item.id" size="large" border
|
||||
:disabled="!item.isOpen || item.stopStatus" @change="changeSupplier(item)" :class="type == 'addSonDomain' ? 'son-radio' : ''">
|
||||
<template #default>
|
||||
{{ item.supplierName }}
|
||||
<icon-tips trigger="hover">
|
||||
<p class="c-clear" style="width: 400px;">{{ item.tips }}</p>
|
||||
</icon-tips>
|
||||
<span class="rb-tag"
|
||||
:style="'background-color:' + (item.supplierType == 1 ? '#F56C6C' : item.supplierType == 2 ? '#409EFF' : '#67C23A')">
|
||||
{{ item.supplierTypeName }}
|
||||
</span>
|
||||
<span v-if="item.prohibit" class="prohibit">{{ t('防封') }}</span>
|
||||
<!-- 非维护状态,且不是增加子域名弹窗 -->
|
||||
<p class="sl-bottom" v-if="!item.stopStatus && type != 'addSonDomain'">
|
||||
<span>{{ item.domainCount > 0 ? item.domainCount + t('条') : t('无域名') }} </span>
|
||||
<el-button v-hasPermi="['operation:tenant:edit']" style="margin-left: 5px;" link type="primary" v-if="item.domainCount == 0" @click="supplierSet(item)">{{ item.isOpen &&
|
||||
item.domainCount == 0 ?
|
||||
t('关闭') : t('开通') }}</el-button>
|
||||
<el-button v-hasPermi="['operation:tenant:alb']" style="margin-left: 5px;" link type="primary" @click="albSet(item)"
|
||||
v-if="item.domainCount > 0 && item.isOpen && item.supportAlb">{{ item.albStatus ?
|
||||
t('ALB关闭') : t('ALB开通') }}</el-button>
|
||||
</p>
|
||||
<div class="stop-box" v-if="item.stopStatus">
|
||||
<el-icon size="18">
|
||||
<WarnTriangleFilled />
|
||||
</el-icon>
|
||||
<p class="c-clear" style="line-height: 1;">{{ t('维护中...') }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { tenantSupplierALB, tenantSupplier } from "@/api/operation/domain";
|
||||
import IconTips from "@/components/IconTips"; // 小图标提示
|
||||
|
||||
// 接收参数
|
||||
const props = defineProps({
|
||||
supplierList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const loading = ref(false);
|
||||
const supplierId = defineModel();
|
||||
const emits = defineEmits(['changeSupplier']);
|
||||
const changeSupplier = (item) => {
|
||||
emits('changeSupplier', item);
|
||||
};
|
||||
// alb开通/关闭
|
||||
const albSet = (item) => {
|
||||
proxy.$modal.confirm(proxy.t('确认') + (item.albStatus ? proxy.t('关闭') : proxy.t('开通')) + '节点ALB?' ).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
tenantSupplierALB({ supplierId: item.id, albStatus: !item.albStatus }).then(res => {
|
||||
loading.value = false;
|
||||
item.albStatus = !item.albStatus;
|
||||
proxy.$modal.msgSuccess(proxy.t('操作成功!'));
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
};
|
||||
|
||||
// 供应商开通/关闭
|
||||
const supplierSet = (item) => {
|
||||
const content = item.isOpen ? proxy.t('默认提供')+item.freeNode+proxy.t('个免费节点,该节点无域名解析数据可进行关闭。') : proxy.t('免费提供') + item.freeNode +proxy.t('个免费节点,超出部分额外收取')+ item.exceedCost + proxy.t('USDT/节点/月,每个节点都是独立云,都能扛攻击,建议平均分配。');
|
||||
const title = (item.isOpen? proxy.t('确认关闭') : proxy.t('确认开通')) + item.supplierName + proxy.t('节点') + '?';
|
||||
|
||||
proxy.$modal.confirm(content, title).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
tenantSupplier({ supplierId: item.id, isOpen:!item.isOpen }).then(res => {
|
||||
loading.value = false;
|
||||
item.isOpen =!item.isOpen;
|
||||
proxy.$modal.msgSuccess(proxy.t('操作成功!'));
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.supplier-box {
|
||||
:deep(.el-radio) {
|
||||
display: inline-block;
|
||||
height: 60px;
|
||||
margin: 10px 10px 0 0;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.son-radio) {
|
||||
height: 40px !important;
|
||||
}
|
||||
|
||||
.prohibit,
|
||||
.rb-tag {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
color: #ffffff;
|
||||
font-size: 10px;
|
||||
padding: 0 5px;
|
||||
line-height: 1.5;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.rb-tag {
|
||||
right: -5px;
|
||||
top: -8px;
|
||||
}
|
||||
|
||||
.prohibit {
|
||||
left: -5px;
|
||||
top: -8px;
|
||||
background-color: #42b983;
|
||||
}
|
||||
|
||||
.sl-bottom {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.stop-box {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
border-radius: 4px;
|
||||
|
||||
:deep(.el-icon) {
|
||||
transform: translateY(5px);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,329 @@
|
|||
<template>
|
||||
<!-- 新增/修改自定义解析 -->
|
||||
<el-dialog :title="dialogTitle" v-model="isShowDialog" width="700px" append-to-body @close="closeDialog">
|
||||
<el-scrollbar max-height="600px" v-loading="loading">
|
||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="120">
|
||||
<el-form-item :label="t('选择节点:')" prop="domainSupplierId" class="mr0">
|
||||
<el-radio-group v-model="formData.domainSupplierId" @change="changeCdnNode">
|
||||
<template v-for="item in supplierList" :key="item.value">
|
||||
<el-radio :value="item.value">{{ t(item.label) }}</el-radio>
|
||||
</template>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('选择域名:')" prop="domainId" class="mr0">
|
||||
<el-select class="w100" v-model="formData.domainId" :placeholder="t('请选择域名')" @change="changeDomain"
|
||||
:disabled="!supplierDomainList.length">
|
||||
<el-option v-for="item in supplierDomainList" :key="item.value" :label="item.label"
|
||||
:value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('主机记录:')" prop="hostRecord" class="mr0">
|
||||
<el-input v-model="formData.hostRecord" clearable :placeholder="t('请输入主机记录')"
|
||||
:disabled="!formData.domainId">
|
||||
<template #append v-if="formData.domainId"><b>.</b>{{ formData.domainName }}</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('解析类型:')" prop="analysisType" class="mr0">
|
||||
<dict-select class="w100" v-model="formData.analysisType" :placeholder="t('请选择解析类型')"
|
||||
dictKey="ff_operation_domain_analysis_type" @change="analysisTypeChange"></dict-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('解析记录值:')" prop="recordValue" class="mr0" v-if="formData.analysisType != 6">
|
||||
<el-input v-model="formData.recordValue" clearable :placeholder="rvPlaceholder" />
|
||||
</el-form-item>
|
||||
<!-- SRV解析类型 -->
|
||||
<template v-if="formData.analysisType == 6">
|
||||
<el-form-item :label="t('协议:')" prop="protocolType" class="mr0" v-if="nodeAnalysisType == 2">
|
||||
<dict-select class="w100" v-model="formData.protocolType" :placeholder="t('请选择协议类型')"
|
||||
dictKey="ff_operation_domain_analysis_protocol_type"></dict-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('优先级:')" prop="priority" :rules="rules.srvNumber" class="mr0">
|
||||
<number-input v-model="formData.priority" maxlength="5" clearable :placeholder="t('请输入0-65535')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('权重:')" prop="weight" :rules="rules.srvNumber" class="mr0">
|
||||
<number-input v-model="formData.weight" maxlength="5" clearable :placeholder="t('请输入0-65535')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('端口:')" prop="port" :rules="rules.srvNumber" class="mr0">
|
||||
<number-input v-model="formData.port" maxlength="5" clearable :placeholder="t('请输入0-65535')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('服务:')" prop="service" class="mr0" v-if="nodeAnalysisType == 2">
|
||||
<el-input v-model="formData.service" clearable :placeholder="t('请输入例如:_serviceName')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('目标:')" prop="target" class="mr0">
|
||||
<el-input v-model="formData.target" clearable :placeholder="t('请输入目标')" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
<el-form-item :label="t('TTL:')" prop="ttl" class="mr0">
|
||||
<number-input v-model="formData.ttl" maxlength="10" clearable :placeholder="t('请输入大于等于600的整数')" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="closeDialog">{{ t('关 闭') }}</el-button>
|
||||
<el-button type="primary" @click="submitForm" :loading="loading">{{ t('确 认') }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup name="AddEditParsing">
|
||||
import {
|
||||
getSupplierDomainList, // 供应商节点下域名
|
||||
addCustomParsing,
|
||||
updateCustomParsing
|
||||
} from "@/api/operation/domain";
|
||||
import NumberInput from "@/components/NumberInput/index.vue"; // 数字输入框
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const loading = ref(false);
|
||||
const isShowDialog = ref(true); // 弹窗是否显示
|
||||
const formRef = ref();
|
||||
const oldForm = shallowRef({ });
|
||||
// 接收参数
|
||||
const props = defineProps({
|
||||
supplierList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
currentParsingInfo: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
});
|
||||
|
||||
// 弹窗标题
|
||||
const dialogTitle = computed(() => {
|
||||
if (props.currentParsingInfo.id) {
|
||||
return proxy.t('修改域名解析');
|
||||
} else {
|
||||
return proxy.t('新增域名解析');
|
||||
}
|
||||
});
|
||||
|
||||
// 表单参数
|
||||
const formData = reactive({
|
||||
domainSupplierId: '', // 节点id
|
||||
domainId: '', // 域名id
|
||||
domainName: '', // 域名名称
|
||||
hostRecord: '', // 主机记录
|
||||
analysisType: '', // 解析类型
|
||||
recordValue: '', // 解析记录值
|
||||
protocolType: '', // 协议类型
|
||||
priority: '', // 优先级
|
||||
weight: '', // 权重
|
||||
port: '', // 端口
|
||||
service: '', // 服务
|
||||
target: '', // 目标
|
||||
ttl: '', // ttl
|
||||
});
|
||||
|
||||
// 初始化修改状态
|
||||
let initEditStatus = ref(false);
|
||||
|
||||
// 表单校验
|
||||
const rules = reactive({
|
||||
domainSupplierId: [
|
||||
{ required: true, message: proxy.t('请选择节点'), trigger: 'change' }
|
||||
],
|
||||
domainId: [
|
||||
{ required: true, message: proxy.t('请选择域名'), trigger: 'change' }
|
||||
],
|
||||
hostRecord: [
|
||||
{ required: true, message: proxy.t('请输入主机记录'), trigger: ['change', 'blur'] },
|
||||
// 符合规范的主机记录
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
const reg = /^[a-zA-Z0-9\-\_]+$/;
|
||||
if (value != '' && !reg.test(value)) {
|
||||
callback(new Error(proxy.t('主机记录只能包含字母、数字、下划线、横线')));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}, trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
analysisType: [
|
||||
{ required: true, message: proxy.t('请选择解析类型'), trigger: 'change' }
|
||||
],
|
||||
recordValue: [
|
||||
{ required: true, message: proxy.t('请输入解析记录值'), trigger: ['change', 'blur'] }
|
||||
],
|
||||
protocolType: [
|
||||
{ required: true, message: proxy.t('请选择协议类型'), trigger: 'change' }
|
||||
],
|
||||
srvNumber: [
|
||||
{
|
||||
required: true,
|
||||
validator: (rule, value, callback) => {
|
||||
if (value == '' || (value < 0 || value > 65535)) {
|
||||
callback(new Error(proxy.t('请输入0-65535的整数')));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}, trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
service: [
|
||||
{ required: true, message: proxy.t('请输入服务'), trigger: ['change', 'blur'] }
|
||||
],
|
||||
target: [
|
||||
{ required: true, message: proxy.t('请输入目标'), trigger: ['change', 'blur'] }
|
||||
],
|
||||
ttl: [
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (value !== '' && value < 600) {
|
||||
callback(new Error(proxy.t('请输入大于等于600的整数')));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}, trigger: ['change', 'blur']
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// 切换节点,获取域名
|
||||
const supplierDomainList = ref([]),
|
||||
nodeAnalysisType = ref(1); // 当前节点下域名解析类型
|
||||
|
||||
const changeCdnNode = (val) => {
|
||||
// 清空已选中的域名和主机记录
|
||||
formData.domainId = '';
|
||||
formData.domainName = '';
|
||||
formData.hostRecord = '';
|
||||
|
||||
// 当前节点下域名解析类型,SRV类型输入框增加
|
||||
nodeAnalysisType.value = props.supplierList.find(v => v.value == val).analysisType;
|
||||
|
||||
// 当前节点下域名列表
|
||||
getSupplierDomainList({ domainSupplierId: val }).then(res => {
|
||||
supplierDomainList.value = res.data.map(v => {
|
||||
return {
|
||||
label: v.name,
|
||||
value: v.id
|
||||
}
|
||||
});
|
||||
|
||||
// 初始化修改状态数据
|
||||
if (initEditStatus.value) {
|
||||
const _currentParsingInfo = props.currentParsingInfo;
|
||||
|
||||
formData.domainId = _currentParsingInfo.domainId;
|
||||
formData.domainName = _currentParsingInfo.domainName;
|
||||
formData.hostRecord = _currentParsingInfo.hostRecord;
|
||||
formData.analysisType = _currentParsingInfo.analysisType + '';
|
||||
formData.recordValue = _currentParsingInfo.recordValue;
|
||||
formData.protocolType = _currentParsingInfo.protocolType ? _currentParsingInfo.protocolType + '' : '';
|
||||
formData.priority = _currentParsingInfo.priority;
|
||||
formData.weight = _currentParsingInfo.weight;
|
||||
formData.port = _currentParsingInfo.port;
|
||||
formData.service = _currentParsingInfo.service;
|
||||
formData.target = _currentParsingInfo.target;
|
||||
formData.ttl = _currentParsingInfo.ttl || '';
|
||||
initEditStatus.value = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 切换域名
|
||||
const changeDomain = (val) => {
|
||||
const findDomain = supplierDomainList.value.find(v => v.value == val);
|
||||
|
||||
formData.domainId = findDomain.value;
|
||||
formData.domainName = findDomain.label;
|
||||
}
|
||||
|
||||
// 解析类型切换时,更改解析记录值placeholder
|
||||
const rvPlaceholder = ref(proxy.t('请输入IPv4地址'));
|
||||
const analysisTypeChange = (val) => {
|
||||
const _label = proxy.useDict('ff_operation_domain_analysis_type').ff_operation_domain_analysis_type.find(v => v.value == val).label;
|
||||
|
||||
if (_label == 'AAAA') {
|
||||
rvPlaceholder.value = proxy.t('请输入IPv6地址');
|
||||
} else if (_label == 'CNAME') {
|
||||
rvPlaceholder.value = proxy.t('请输入域名地址');
|
||||
} else if (_label == 'NS') {
|
||||
rvPlaceholder.value = proxy.t('请输入域名服务器地址');
|
||||
} else {
|
||||
rvPlaceholder.value = proxy.t('请输入IPv4地址');
|
||||
}
|
||||
};
|
||||
|
||||
// 提交
|
||||
const submitForm = () => {
|
||||
formRef.value.validate((valid) => {
|
||||
if (!valid) return;
|
||||
|
||||
const params = {
|
||||
domainId: formData.domainId,
|
||||
hostRecord: formData.hostRecord,
|
||||
analysisType: formData.analysisType,
|
||||
ttl: formData.ttl,
|
||||
};
|
||||
|
||||
// 解析类型为SRV类型时,参数增加
|
||||
if (formData.analysisType == 6) {
|
||||
params.priority = formData.priority;
|
||||
params.weight = formData.weight;
|
||||
params.port = formData.port;
|
||||
params.target = formData.target;
|
||||
|
||||
// 节点下域名解析类型为2时,参数增加
|
||||
if (nodeAnalysisType.value == 2) {
|
||||
params.protocolType = formData.protocolType;
|
||||
params.service = formData.service;
|
||||
}
|
||||
} else {
|
||||
params.recordValue = formData.recordValue;
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
if (props.currentParsingInfo.id) {
|
||||
// 修改
|
||||
params.id = props.currentParsingInfo.id;
|
||||
if (JSON.stringify(formData) != oldForm.value) {
|
||||
submitSuccess(updateCustomParsing(params), proxy.t('修改成功'));
|
||||
}else{
|
||||
loading.value = false;
|
||||
closeDialog('cancel');
|
||||
}
|
||||
} else {
|
||||
// 新增
|
||||
submitSuccess(addCustomParsing(params), proxy.t('添加成功'));
|
||||
}
|
||||
|
||||
// 提交后回调
|
||||
function submitSuccess(apiFn, msg) {
|
||||
apiFn.then(() => {
|
||||
loading.value = false;
|
||||
proxy.$message.success(msg);
|
||||
closeDialog('submit');
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const emit = defineEmits(['closeDialog']);
|
||||
const closeDialog = (type) => {
|
||||
emit('closeDialog', type);
|
||||
}
|
||||
|
||||
// 监听修改状态数据
|
||||
watch(() => props.currentParsingInfo, (val) => {
|
||||
if (val.id) {
|
||||
// 触发节点下域名请求,去返回函数内回填其他数据
|
||||
formData.domainSupplierId = val.domainSupplierId;
|
||||
changeCdnNode(val.domainSupplierId);
|
||||
initEditStatus.value = true;
|
||||
setTimeout(() => {
|
||||
let objForm = { ...formData }
|
||||
oldForm.value = JSON.stringify(objForm);
|
||||
}, 500);
|
||||
}
|
||||
}, { immediate: true });
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
@ -0,0 +1,259 @@
|
|||
<template>
|
||||
<!-- 自定义解析列表 -->
|
||||
<table-search-card :model="queryParams" @getList="getList" :leftSpan="16" :rightSpan="8" @handleQuery="handleQuery()"
|
||||
@resetQuery="resetQuery">
|
||||
<template #left>
|
||||
<table-search-date ref="searchDateRef" dateType="datetimerange" v-model:dateRange="dateRange"
|
||||
v-model:operateTimeType="operateTimeType" @dateChange="handleQuery"></table-search-date>
|
||||
<select-input-form :queryParamsList="queryParamsList" v-model:queryParams="queryParams" :width="[130, 260]"
|
||||
@handleQuery="handleQuery"></select-input-form>
|
||||
<el-form-item prop="analysisType" style="width: 120px;">
|
||||
<dict-select clearable v-model="queryParams.analysisType" :placeholder="t('解析类型')"
|
||||
dictKey="ff_operation_domain_analysis_type" @change="handleQuery"></dict-select>
|
||||
</el-form-item>
|
||||
<el-form-item prop="domainSupplierId" style="width: 150px;">
|
||||
<el-select v-model="queryParams.domainSupplierId" :placeholder="t('CDN节点')" @change="handleQuery">
|
||||
<el-option v-for="item in supplierList" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template #right>
|
||||
<el-button type="success" plain icon="Plus" @click="isShowAddEdit = true"
|
||||
v-hasPermi="['operation:analysis:add']">{{
|
||||
t('新增') }}</el-button>
|
||||
</template>
|
||||
</table-search-card>
|
||||
|
||||
<!-- 查询表格 -->
|
||||
<el-table ref="tableRef" class="c-table-main" v-loading="loading" row-key="id" stripe border :data="dataList"
|
||||
@select="tableSelect" @select-all="tableSelect">
|
||||
<el-table-column align="center" type="selection" width="55" />
|
||||
<el-table-column :label="t('CDN节点名称')" prop="cdnNodeName" align="center" min-width="160"></el-table-column>
|
||||
<el-table-column :label="t('主域名')" prop="domainName" align="center" min-width="160"></el-table-column>
|
||||
<el-table-column :label="t('主机记录')" prop="hostRecord" align="center" min-width="180">
|
||||
<template #default="{row}">
|
||||
<div style="width: 100%;">{{ row.hostRecord }}</div>
|
||||
<div style="width: 100%;font-weight: 600;" v-for="(item, index) in row.operationDomainAnalysisDns" :key="index">
|
||||
<p> {{ item.typeValue }}:{{ item.value }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('解析类型')" align="center" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<dict-text dictKey="ff_operation_domain_analysis_type" :value="row.analysisType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('解析记录值')" prop="recordValue" align="center" min-width="160"></el-table-column>
|
||||
<el-table-column :label="t('TTL')" align="center" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{row.ttl || '-'}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<table-operation></table-operation>
|
||||
<el-table-column :label="t('操作')" align="center" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="opInfo(row, 'edit')" v-hasPermi="['operation:analysis:edit']">
|
||||
{{ t('修改') }}
|
||||
</el-button>
|
||||
<el-button link type="primary" @click="opInfo(row, 'delete')" v-hasPermi="['operation:analysis:remove']">
|
||||
{{ t('删除') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 批量操作 -->
|
||||
<table-batch-operate v-if="total > 0" v-model:batchOpType="batchOpType" v-model:isAllSelection="isAllSelection"
|
||||
@allSelectionChange="allSelectionChange" @opTypeChange="opTypeChange" :selectionData="selectionData"
|
||||
:opTypeOptions="opTypeOptions"></table-batch-operate>
|
||||
<!-- 列表分页 -->
|
||||
<pagination v-if="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList" />
|
||||
|
||||
<!-- 添加解析 -->
|
||||
<add-edit-parsing v-if="isShowAddEdit" :supplierList="supplierList" :currentParsingInfo="currentParsingInfo"
|
||||
@closeDialog="closeDialog"></add-edit-parsing>
|
||||
</template>
|
||||
|
||||
<script setup name="CustomParsingList">
|
||||
import {
|
||||
getSupplierList, // 供应商列表
|
||||
getCustomParsingList, // 域名列表
|
||||
delCustomParsing, // 删除域名
|
||||
} from "@/api/operation/domain";
|
||||
import TableSearchDate from "@/components/TableSearchDate"; // 日期选择
|
||||
import TableBatchOperate from '@/components/TableBatchOperate'; // 批量操作
|
||||
import AddEditParsing from "./AddEditParsing.vue"; // 添加解析
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const loading = ref(true); // loading状态
|
||||
const isShowAddEdit = ref(false); // 各弹窗状态
|
||||
|
||||
// 获取供应商列表
|
||||
const supplierList = ref([]);
|
||||
getSupplierList().then(res => {
|
||||
supplierList.value = res.data.filter(i => i.isOpen).map(v => {
|
||||
return {
|
||||
label: v.supplierName,
|
||||
value: v.id,
|
||||
analysisType: v.analysisType
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 日期选择
|
||||
const searchDateRef = ref(), dateRange = ref([]), operateTimeType = ref('');
|
||||
|
||||
// 根据下拉框条件输入搜索
|
||||
const queryParamsList = ref([
|
||||
{
|
||||
label: proxy.t('主域名'),
|
||||
value: 'domainName'
|
||||
}, {
|
||||
label: proxy.t('主机记录'),
|
||||
value: 'hostRecord'
|
||||
}, {
|
||||
label: proxy.t('解析记录值'),
|
||||
value: 'recordValue'
|
||||
}, {
|
||||
label: proxy.t('操作人'),
|
||||
value: 'updateBy'
|
||||
}
|
||||
]);
|
||||
|
||||
// 搜索配置
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
searchType: 'domainName',
|
||||
domainName: '',
|
||||
hostRecord: '',
|
||||
recordValue: '',
|
||||
updateBy: '',
|
||||
domainSupplierId: '', // CDN节点
|
||||
analysisType: '', // 解析类型
|
||||
orderByColumn: 'createTime',
|
||||
isAsc: 'desc'
|
||||
});
|
||||
|
||||
// 请求列表
|
||||
const dataList = ref([]), total = ref(0);
|
||||
const getList = () => {
|
||||
const params = proxy.addDateRange(queryParams, dateRange.value); // 日期参数
|
||||
loading.value = true;
|
||||
|
||||
getCustomParsingList(params).then(res => {
|
||||
loading.value = false;
|
||||
dataList.value = res.rows;
|
||||
total.value = +res.total;
|
||||
clearBatchOp(); // 清空批量操作痕迹
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
dataList.value = [];
|
||||
total.value = 0;
|
||||
clearBatchOp(); // 清空批量操作痕迹
|
||||
});
|
||||
}
|
||||
getList();
|
||||
|
||||
// 操作信息
|
||||
const currentParsingInfo = ref({}); // 当前操作的域名信息
|
||||
const opInfo = (row, type) => {
|
||||
switch (type) {
|
||||
case 'edit':
|
||||
// 修改域名
|
||||
currentParsingInfo.value = row;
|
||||
isShowAddEdit.value = true;
|
||||
break;
|
||||
case 'delete':
|
||||
// 删除域名
|
||||
let msg = proxy.t('确定要删除该域名吗!')
|
||||
if (row.batchOpType) {
|
||||
msg = proxy.t('确定要批量删除选中的域名吗!')
|
||||
}
|
||||
|
||||
proxy.$modal.confirm(msg).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
delCustomParsing(row.id).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('删除成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
batchOpType.value = '';
|
||||
});
|
||||
}).catch(() => {
|
||||
batchOpType.value = '';
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 批量操作
|
||||
const tableRef = ref(),
|
||||
isAllSelection = ref(false), // 是否全选
|
||||
selectionData = ref([]), // 选中的表格数据
|
||||
batchOpType = ref(''); // 选中的批量操作类型
|
||||
|
||||
// 批量操作选项
|
||||
const opTypeOptions = ref([
|
||||
{ label: proxy.t('批量删除'), value: 'delete' }
|
||||
]);
|
||||
|
||||
// 勾选表格
|
||||
const tableSelect = (val) => {
|
||||
selectionData.value = val;
|
||||
|
||||
if (val.length === dataList.value.length) {
|
||||
isAllSelection.value = true;
|
||||
} else {
|
||||
isAllSelection.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 全选表格
|
||||
const allSelectionChange = () => {
|
||||
tableRef.value.toggleAllSelection();
|
||||
}
|
||||
|
||||
// 选择批量数据操作类型
|
||||
const opTypeChange = () => {
|
||||
opInfo({id: selectionData.value.map(item => item.id).join(','), batchOpType: true}, batchOpType.value);
|
||||
}
|
||||
|
||||
// 清空批量操作痕迹
|
||||
const clearBatchOp = () => {
|
||||
isAllSelection.value = false;
|
||||
selectionData.value = [];
|
||||
batchOpType.value = '';
|
||||
}
|
||||
|
||||
// 搜索按钮操作
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
|
||||
// 重置按钮操作
|
||||
const resetQuery = () => {
|
||||
searchDateRef.value.dateResetQuery(); // 日期选择重置
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = (type) => {
|
||||
isShowAddEdit.value = false; // 新增域名弹窗
|
||||
currentParsingInfo.value = {}; // 当前操作的域名信息
|
||||
batchOpType.value = ''; // 批量操作类型
|
||||
|
||||
// 批量操作清空
|
||||
if (type === 'batchSubmit') clearBatchOp();
|
||||
// 提交后刷新列表
|
||||
if (type === 'submit' || type === 'batchSubmit') {
|
||||
getList();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'></style>
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
<template>
|
||||
<!-- 新增域名 -->
|
||||
<el-dialog :title="t('新增域名')" v-model="isShowDialog" width="800px" align-center append-to-body @close="closeDialog">
|
||||
<el-scrollbar max-height="600px" v-loading="loading">
|
||||
<el-form ref="formRef" :rules="rules" :model="formData" label-width="100">
|
||||
<el-form-item label-width="0" prop="domainSupplierId" class="clt-item mr0">
|
||||
<span slot="label" class="label-box">
|
||||
<span class="label-name"><i style="color: #f56c6c; margin-right: 4px;">*</i>{{ t('选择节点') }}</span>
|
||||
<span class="label-open">({{ t('已开通') }}<b class="c-orange">{{ openCount }}</b>{{ t('个') }})</span>
|
||||
<span class="label-ds c-blue">{{ t('节点说明') }}</span>
|
||||
</span>
|
||||
<div class="item-right">
|
||||
<supplier-select v-model="formData.domainSupplierId" @changeSupplier="changeSupplier" :supplierList="supplierList"></supplier-select>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('主域名')" prop="domainNames" class="mr0">
|
||||
<el-input type="textarea" :rows="5" v-model="formData.domainNames"
|
||||
:placeholder="t('支持批量添加,最多20个,多个域名请换行,例如:\n123.com\n123.com.hk\n123.in')" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="add-tips">
|
||||
<h3>{{ t('收费和用法教程:') }}</h3>
|
||||
<p><b>{{t('1、限顶级域名:')}}</b>{{ t('此处只能添加独立的顶级域名,请勿添加子域名,例如: 只能添加123.com,不是www.123.com,详见域名管理教程') }}</p>
|
||||
<p><b>{{t('2、节点说明')}}</b></p>
|
||||
<p><b>{{t('(1)中国市场(含港澳台):')}}</b>{{ t('推荐使用alb域名(aws防封)、三方公共域名(aws与azure防封)、Wangsu (CDN+IP)、A8、Yundun (云盾)、Funnull(方能)、superEdge、大陆阿里云。')}}</p>
|
||||
<p><b>{{t('(2)全球市场(即非中国):')}}</b>{{ t('推荐使用使用alb域名(aws与aliyun防封)、三方公共域名(aws与azure防封)、AWS、CF、腾讯云、 阿里云、 Google、Azure、华为云、Wangsu(CDN + IP)、Yundun (云盾)。')}}</p>
|
||||
<p><b>{{t('(3)Wangsu独立IP:')}}</b>{{ t('提供独立IP地址,适用于会封禁域名,但不会封禁IP的国家(例如:印尼、中国、巴西、越南等),国际和中国大陆市场均可使用(即全球通用200USDT/IP/月),若超过7天未启用系统自动回收。') }}
|
||||
</p>
|
||||
<p><b>{{t('(4)开放回源(仅限web大厅):')}}</b>{{ t('提供开放独立源服务,可使用外部三方CDN,需申请开通(300U/月),需要专业人士配置websocket、HTTP2、缓存等,详见域名管理教程。') }}</p>
|
||||
<p><b>{{t('3、域名解析限额:')}}</b>{{ t('前')+domainNameCnt+t('个域名免费(含子域名),超出部分额外收取')+exceedDomainCost+t('USDT/条解析/月;') }}</p>
|
||||
<p><b>{{t('4、流量限额:')}}</b>{{ t('每月前') +trafficG+ t('G免费,超出部分额外收取') + exceedTrafficCost +t('USDT/G/月;') }}</p>
|
||||
<p><b>{{t('5、节点限制:')}}</b>{{ t('免费提供') + freeNode + t('个节点,超出部分额外收取') + exceedCost + t('USDT/节点/月,每个节点都是独立云,都能扛攻击,建议均匀分配。') }}</p>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="closeDialog('close')">{{ t('关 闭') }}</el-button>
|
||||
<el-button type="primary" @click="submitForm" :loading="loading">{{ t('确 认') }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup name="AddDomain">
|
||||
import SupplierSelect from '../components/SupplierSelect.vue';
|
||||
import { addDomain } from "@/api/operation/domain";
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
// 接收参数
|
||||
const props = defineProps({
|
||||
supplierList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
supplierConfig: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
});
|
||||
const domainNameCnt = ref(0),exceedDomainCost = ref(0),trafficG = ref(0),exceedTrafficCost = ref(0),freeNode = ref(0),exceedCost = ref(0);
|
||||
|
||||
const loading = ref(false);
|
||||
const isShowDialog = ref(true); // 弹窗是否显示
|
||||
const formRef = ref();
|
||||
|
||||
// 表单参数
|
||||
const formData = reactive({
|
||||
domainSupplierId: '',
|
||||
domainNames: []
|
||||
});
|
||||
|
||||
// 开通状态的节点数量
|
||||
const openCount = computed(() => {
|
||||
return props.supplierList.filter(item => item.isOpen).length;
|
||||
});
|
||||
nextTick(()=>{
|
||||
console.log(props.supplierConfig)
|
||||
domainNameCnt.value = props.supplierConfig.domainNameCnt;
|
||||
exceedDomainCost.value = props.supplierConfig.exceedDomainCost;
|
||||
trafficG.value = props.supplierConfig.trafficG;
|
||||
exceedTrafficCost.value = props.supplierConfig.exceedTrafficCost;
|
||||
})
|
||||
|
||||
const changeSupplier = (item) => {
|
||||
freeNode.value = item.freeNode;
|
||||
exceedCost.value = item.exceedCost;
|
||||
};
|
||||
// 表单校验
|
||||
const rules = reactive({
|
||||
domainSupplierId: [
|
||||
{ required: true, message: proxy.t('请选择节点'), trigger: 'change' }
|
||||
],
|
||||
domainNames: [
|
||||
{ required: true, message: proxy.t('域名不能为空'), trigger: ['blur', 'change'] },
|
||||
// 域名校验
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
const reg = /^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$/;
|
||||
if (value) {
|
||||
if (value.split('\n').length > 20) {
|
||||
callback(new Error(proxy.t('最多支持20个域名')));
|
||||
} else {
|
||||
const arr = value.split('\n');
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (!reg.test(arr[i])) {
|
||||
callback(new Error(proxy.t('请输入正确的域名')));
|
||||
}
|
||||
}
|
||||
callback();
|
||||
}
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// 提交
|
||||
const submitForm = () => {
|
||||
formRef.value.validate(valid => {
|
||||
if (valid) {
|
||||
const params = {
|
||||
domainSupplierId: formData.domainSupplierId,
|
||||
domainNames: formData.domainNames.split('\n')
|
||||
}
|
||||
|
||||
// 如果domainNames出现重复的,提示用户
|
||||
if (params.domainNames.length !== new Set(params.domainNames).size) {
|
||||
proxy.$message.error(proxy.t('域名不能重复'));
|
||||
} else {
|
||||
loading.value = true;
|
||||
addDomain(params).then(() => {
|
||||
loading.value = false;
|
||||
proxy.$message.success(proxy.t('添加成功'));
|
||||
closeDialog('submit');
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const emit = defineEmits(['closeDialog']);
|
||||
const closeDialog = (type) => {
|
||||
emit('closeDialog', type);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
// 自定义表单label
|
||||
.clt-item {
|
||||
.label-box {
|
||||
width: 100px;
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.label-open {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.label-ds {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-right {
|
||||
width: calc(100% - 100px);
|
||||
}
|
||||
|
||||
// 校验提示位置
|
||||
:deep(.el-form-item__error) {
|
||||
padding-left: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
.add-tips{
|
||||
background-color: #ededee;
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
h3{
|
||||
margin: 0;
|
||||
padding-bottom: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 26px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
<template>
|
||||
<!-- 限额说明 -->
|
||||
<el-dialog :title="t('限额说明')" v-model="isShowDialog" width="900px" append-to-body @close="closeDialog">
|
||||
<el-scrollbar max-height="600px" v-loading="loading">
|
||||
<div class="limit-box">
|
||||
<h3>{{ t('1.域名不是越多越好:') }}</h3>
|
||||
<div class="lb-text">
|
||||
<p>
|
||||
{{ t('因为每个节点的域名都要检测网络质量,然后再根据网络质量排序,若节点域名数量过多,每次巡检都要浪费1-2秒来测速,进而会导致网络卡顿的情况,建议每个功能用途控制在2-10个/节点。') }}
|
||||
</p>
|
||||
</div>
|
||||
<h3>{{ t('2.历史旧域名过多如何处理?:') }}</h3>
|
||||
<div class="lb-text">
|
||||
<p>
|
||||
{{ t('历史使用过或旧的域名,建议用url转发跳转,不仅能保留权重,也能无限量跳转。') }}
|
||||
</p>
|
||||
<p><span>{{ t('(1)站点后台操作方法:批量选择域名》批量停用(等待5-10分钟生效) 》再批量删除域名即可。') }}</span></p>
|
||||
<p><span>{{ t('(2)域名商后台操作方法:将dns改为域名商默认(如godaddy尊享版DNS)》勾选域名+批量设置转发。') }}</span></p>
|
||||
</div>
|
||||
<h3>{{ t('3.备用域名建议:') }}</h3>
|
||||
<div class="lb-text">
|
||||
<p>
|
||||
{{ t('即暂不启用的域名,建议先只添加到主域名,暂不进行解析,以免还没启用就被拦截、劫持、封锁或被墙;等需要使用的时候再添加到各功能模块使用即可。') }}
|
||||
</p>
|
||||
</div>
|
||||
<h3>{{ t('4.收费说明:') }}</h3>
|
||||
<div class="lb-text">
|
||||
<p>
|
||||
<b>{{ t('1、限顶级域名:') }}</b>
|
||||
</p>
|
||||
<p>{{ t('此处只能添加独立的顶级域名,请勿添加子域名,例如: 只能添加123.com,不是www.123.com,详见域名管理教程') }}</p>
|
||||
<p>
|
||||
<b>{{ t('2、节点说明:') }}</b>
|
||||
</p>
|
||||
<p>
|
||||
<b>{{ t(' (1)中国市场(含港澳台):') }}</b>
|
||||
{{ t('推荐使用alb域名(aws防封)、三方公共域名(aws与azure防封)、Wangsu (CDN+IP)、A8、Yundun(云盾)、Funnull(方能)、superEdge、大陆阿里云。') }}
|
||||
</p>
|
||||
<p>
|
||||
<b>{{ t(' (2)全球市场(即非中国):') }}</b>
|
||||
{{ t('推荐使用使用alb域名(aws与aliyun防封)、三方公共域名(aws与azure防封)、AWS、CF、腾讯云、 阿里云、 Google、Azure、华为云、Wangsu(CDN + IP)、Yundun (云盾)。') }}
|
||||
</p>
|
||||
<p>
|
||||
<b>{{ t(' (3)Wangsu独立IP:') }}</b>
|
||||
{{
|
||||
t('提供独立IP地址,适用于会封禁域名,但不会封禁IP的国家(例如:印尼、中国、巴西、越南等),国际和中国大陆市场均可使用(即全球通用200USDT/IP/月),若超过7天未启用系统自动回收。')
|
||||
}}
|
||||
</p>
|
||||
<p>
|
||||
<b>{{ t(' (4)开放回源(仅限web大厅):') }}</b>
|
||||
{{ t('提供开放独立源服务,可使用外部三方CDN,需申请开通(300U/月),需要专业人士配置websocket、HTTP2、缓存等,详见域名管理教程。') }}
|
||||
</p>
|
||||
</div>
|
||||
<h3>{{ t('3、域名解析限额:') }}</h3>
|
||||
<div class="lb-text">
|
||||
<p>{{ t('前30个域名免费(含子域名),超出部分额外收取5USDT/条解析/月;') }}</p>
|
||||
</div>
|
||||
<h3>{{ t('4、流量限额:') }}</h3>
|
||||
<div class="lb-text"><p>{{ t('每月前500G免费,超出部分额外收取0.3USDT/G/月;') }}</p></div>
|
||||
<h3>{{ t('5、节点限制:') }}</h3>
|
||||
<div class="lb-text"><p>{{ t('免费提供3个节点,超出部分额外收取300USDT/节点/月,每个节点都是独立云,都能扛攻击,建议均匀分配。') }}</p></div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="closeDialog">{{ t('关 闭') }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup name="ShowInfoDialog">
|
||||
const loading = ref(false);
|
||||
const isShowDialog = ref(true); // 弹窗是否显示
|
||||
|
||||
// 关闭弹窗
|
||||
const emit = defineEmits(['closeDialog']);
|
||||
const closeDialog = (type) => {
|
||||
emit('closeDialog', type);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.limit-box {
|
||||
h3{
|
||||
margin: 0;
|
||||
padding-bottom: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.lb-text{
|
||||
background-color: #ededee;
|
||||
padding: 5px 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
|
||||
p {
|
||||
line-height: 26px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,469 @@
|
|||
<template>
|
||||
<!-- 域名管理列表 -->
|
||||
<table-search-card :model="queryParams" @getList="getList" :leftSpan="16" :rightSpan="8" @handleQuery="handleQuery()"
|
||||
@resetQuery="resetQuery">
|
||||
<template #left>
|
||||
<select-input-form :queryParamsList="queryParamsList" v-model:queryParams="queryParams" :width="[130, 260]"
|
||||
@handleQuery="handleQuery"></select-input-form>
|
||||
<el-form-item prop="domainStatus" style="width: 150px;">
|
||||
<CustomSelect clearable v-model="queryParams.domainStatus" :placeholder="t('主域名状态')"
|
||||
:options="domainStatusOptions" @change="handleQuery"></CustomSelect>
|
||||
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template #right>
|
||||
<auto-refresh-time apiName="domainList" @refreshFn="getList" style="margin-right: 10px;"></auto-refresh-time>
|
||||
<el-button type="success" plain icon="Plus" @click="openAddDomain" v-hasPermi="['operation:domain:add']">{{
|
||||
t('新增') }}</el-button>
|
||||
</template>
|
||||
</table-search-card>
|
||||
|
||||
<!-- 查询表格 -->
|
||||
<div class="domain-main">
|
||||
<!-- 左侧供应商 -->
|
||||
<div class="dm-left">
|
||||
<el-scrollbar max-height="600px">
|
||||
<!-- 供应商选择 -->
|
||||
<supplier-button ref="supplierRef" v-model="queryParams.domainSupplierId" @change="handleQuery"
|
||||
@getCurSupplierNode="getCurSupplierNode"></supplier-button>
|
||||
|
||||
<el-button size="large" style="width: calc(100% - 15px);" @click="isShowInfo = true">
|
||||
<el-icon color="#E6A23C" style="margin-right: 5px;">
|
||||
<InfoFilled />
|
||||
</el-icon>{{ t(' 限额说明') }}
|
||||
</el-button>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
<!-- 右侧表格 -->
|
||||
<div class="dm-right">
|
||||
<el-table ref="tableRef" class="c-table-main" v-loading="loading" row-key="id" stripe border :data="dataList"
|
||||
@select="tableSelect" @select-all="tableSelect">
|
||||
<el-table-column align="center" type="selection" width="55" />
|
||||
<el-table-column align="center" min-width="160">
|
||||
<template #header>
|
||||
<span>{{ t('CDN节点名称') }}</span>
|
||||
<icon-tips v-if="currentNodeTips">
|
||||
<p class="c-clear" style="width: 400px;">{{ currentNodeTips }}</p>
|
||||
</icon-tips>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
{{ row.cdnNodeName }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" min-width="280">
|
||||
<template #header>
|
||||
<span>{{ t('主域名') }}</span>
|
||||
<span style="color: #409EFF;"> ({{ t('子域名数') }})</span>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
{{ row.name }}
|
||||
<!-- 子域名展示 -->
|
||||
<el-popover placement="right" :width="524" trigger="click">
|
||||
<template #reference>
|
||||
<span class="c-blue"> ({{ row.operationDomainSons?.length }})</span>
|
||||
</template>
|
||||
<el-table :data="row.operationDomainSons">
|
||||
<el-table-column width="200" align="center" property="name" :label="t('子域名')" />
|
||||
<el-table-column width="150" align="center" property="date" :label="t('域名用途')">
|
||||
<template #default="{ row }">
|
||||
<dict-text dictKey="operation_domain_son_type" :value="row.domainSonTypeType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="150" align="center" property="date" :label="t('使用状态')">
|
||||
<template #default="{ row }">
|
||||
<dict-text :colorValues="['c-grey', 'c-orange', 'c-orange', 'c-green', 'c-red']"
|
||||
dictKey="operation_domain_son_usage_status" :value="row.usageStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-popover>
|
||||
<!-- 复制 -->
|
||||
<copy-icon :text="row.name" class="copy-ml"></copy-icon>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('验证方式')" align="center" min-width="320">
|
||||
<template #default="{ row }">
|
||||
<!-- 正常 -->
|
||||
<p class="c-clear" v-if="row.domainStatus == 2">
|
||||
<!-- ,当前DNS为: -->
|
||||
<span class="c-green">{{ t('验证已生效') }}</span>
|
||||
<el-button link type="primary" @click="row.isShowDns = !row.isShowDns">{{ row.isShowDns ? t('收起') :
|
||||
t('展开')
|
||||
}}</el-button>
|
||||
</p>
|
||||
<!-- 待验证 -->
|
||||
<p class="c-clear" v-if="row.domainStatus == 1">
|
||||
<template v-if="row.dnsList.length">
|
||||
<span>{{ t('请将DNS修改为以下服务器后:') }}</span>
|
||||
<el-button v-if="!row.checkLoading" link type="primary" @click="opInfo(row, 'check')"
|
||||
v-hasPermi="['operation:domain:check']">
|
||||
{{ t('验证') }}
|
||||
</el-button>
|
||||
<el-icon v-else class="c-rotate" style="position: relative; top: 4px;" size="16"
|
||||
color="#409EFF">
|
||||
<Loading />
|
||||
</el-icon>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button v-if="!row.getNSLoading" link type="primary" @click="opInfo(row, 'getNS')"
|
||||
v-hasPermi="['operation:domain:get:ns']">
|
||||
{{ t('获取NS') }}
|
||||
</el-button>
|
||||
<el-icon v-else class="c-rotate" style="position: relative; top: 4px;" size="16"
|
||||
color="#409EFF">
|
||||
<Loading />
|
||||
</el-icon>
|
||||
</template>
|
||||
</p>
|
||||
<!-- 已过期、待找回 -->
|
||||
<p class="c-clear c-grey" v-if="row.domainStatus == 3 || row.domainStatus == 4">{{ t('域名暂不可用') }}</p>
|
||||
<!-- DNS -->
|
||||
<template v-if="row.isShowDns || row.domainStatus == 1">
|
||||
<p class="c-clear c-grey" v-for="(dns, index) in row.dnsList" :key="index">
|
||||
{{ dns.valueType + ':' + dns.value }}
|
||||
<copy-icon :text="dns.value" class="copy-ml"></copy-icon>
|
||||
</p>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('主域名状态')" align="center" min-width="150">
|
||||
<template #default="{ row }">
|
||||
<dict-text :colorValues="['c-orange', 'c-green', 'c-grey', 'c-red']"
|
||||
dictKey="ff_operation_domain_status" :value="row.domainStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('域名过期日期')" align="center" min-width="160">
|
||||
<template #default="{ row }">
|
||||
{{ formatTime(row.overdueDate, 'YYYY-MM-DD') }}
|
||||
<el-icon @click="opInfo(row, 'refresh')" :class="row.refreshLoading ? 'c-rotate' : ''"
|
||||
style="position: relative; top: 4px; margin-left: 8px;" size="16" class="c-blue">
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('证书过期日期')" align="center" min-width="140">
|
||||
<template #default="{ row }">
|
||||
{{ formatTime(row.certificateOverdueDate, 'YYYY-MM-DD') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('操作')" align="center" min-width="180">
|
||||
<template #default="{ row }">
|
||||
<el-button v-if="!row.checkLoading && row.domainStatus == 1" link type="primary"
|
||||
@click="opInfo(row, 'check')" v-hasPermi="['operation:domain:check']">
|
||||
{{ t('验证') }}
|
||||
</el-button>
|
||||
<el-icon v-if="row.checkLoading" class="c-rotate" style="position: relative; top: 4px;" size="16"
|
||||
color="#409EFF">
|
||||
<Loading />
|
||||
</el-icon>
|
||||
<el-button v-if="row.domainStatus != 2" link type="primary" @click="opInfo(row, 'delete')"
|
||||
v-hasPermi="['operation:domain:remove']">
|
||||
{{ t('彻底删除') }}
|
||||
</el-button>
|
||||
<el-button v-if="row.domainStatus == 2" link type="primary" @click="opInfo(row, 'stop')"
|
||||
v-hasPermi="['operation:domain:stop']">
|
||||
{{ t('强制停用') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<table-operation></table-operation>
|
||||
</el-table>
|
||||
<!-- 批量操作 -->
|
||||
<table-batch-operate v-if="total > 0" v-model:batchOpType="batchOpType" v-model:isAllSelection="isAllSelection"
|
||||
@allSelectionChange="allSelectionChange" @opTypeChange="opTypeChange" :selectionData="selectionData"
|
||||
:opTypeOptions="opTypeOptions"></table-batch-operate>
|
||||
<!-- 列表分页 -->
|
||||
<pagination v-if="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 限额说明弹窗 -->
|
||||
<show-content v-if="isShowInfo" @closeDialog="closeDialog"></show-content>
|
||||
<!-- 新增域名弹窗 -->
|
||||
<add-domain v-if="isShowAdd" :supplierConfig="supplierConfig" :supplierList="supplierList" @closeDialog="closeDialog"></add-domain>
|
||||
</template>
|
||||
|
||||
<script setup name="DomainManageList">
|
||||
import {
|
||||
getDomainList, // 域名列表
|
||||
getDomainVerify, // 域名验证
|
||||
getDomainExpireTime, // 刷新域名过期日期
|
||||
setDomainStop, // 强制停用
|
||||
getDomainNS, // 获取NS
|
||||
delDomain, // 删除域名
|
||||
getDomainConfig,
|
||||
} from "@/api/operation/domain";
|
||||
import AutoRefreshTime from "@/components/AutoRefreshTime"; // 定时刷新
|
||||
import CopyIcon from "@/components/CopyIcon"; // 小图标复制
|
||||
import IconTips from "@/components/IconTips"; // 小图标提示
|
||||
import TableBatchOperate from '@/components/TableBatchOperate'; // 批量操作
|
||||
import ShowContent from "./ShowContent.vue"; // 限额说明说明弹窗
|
||||
import AddDomain from "./AddDomain.vue"; // 新增域名
|
||||
import SupplierButton from "../components/SupplierButton.vue"; // 供应商选择按钮
|
||||
import DictSelect from '@/components/DictSelect';
|
||||
import DictText from '@/components/DictText';
|
||||
import CustomSelect from '@/components/CustomSelect';
|
||||
import { ref } from "vue";
|
||||
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const loading = ref(true); // loading状态
|
||||
|
||||
// 供应商
|
||||
const supplierRef = ref(null), currentNodeTips = ref(''), supplierList = ref([]);
|
||||
const supplierConfig = ref({ });
|
||||
// 获取供应商节点信息
|
||||
const getCurSupplierNode = (data) => {
|
||||
currentNodeTips.value = data?.tips;
|
||||
}
|
||||
|
||||
// 根据下拉框条件输入搜索
|
||||
const queryParamsList = ref([{
|
||||
label: proxy.t('操作人'),
|
||||
value: 'updateBy'
|
||||
}, {
|
||||
label: proxy.t('主域名'),
|
||||
value: 'name'
|
||||
}]);
|
||||
const domainStatusOptions = ref([
|
||||
{
|
||||
label: proxy.t('待验证'),
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: proxy.t('正常'),
|
||||
value: 2
|
||||
},
|
||||
{
|
||||
label: proxy.t('已过期'),
|
||||
value: 3
|
||||
},
|
||||
{
|
||||
label: proxy.t('待找回'),
|
||||
value: 4
|
||||
}
|
||||
|
||||
]);
|
||||
// 搜索配置
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
searchType: 'updateBy',
|
||||
name: '',
|
||||
updateBy: '',
|
||||
domainStatus: '',
|
||||
orderByColumn: 'createTime',
|
||||
isAsc: 'desc',
|
||||
domainSupplierId: '' // 供应商
|
||||
});
|
||||
|
||||
// 请求列表
|
||||
const dataList = ref([]), total = ref(0);
|
||||
const getList = () => {
|
||||
loading.value = true;
|
||||
|
||||
getDomainList(queryParams).then(res => {
|
||||
loading.value = false;
|
||||
dataList.value = res.rows;
|
||||
total.value = +res.total;
|
||||
clearBatchOp(); // 清空批量操作痕迹
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
dataList.value = [];
|
||||
total.value = 0;
|
||||
clearBatchOp(); // 清空批量操作痕迹
|
||||
});
|
||||
}
|
||||
getList();
|
||||
|
||||
// 新增域名
|
||||
const openAddDomain = () => {
|
||||
getDomainConfig({}).then(res => {
|
||||
supplierConfig.value = res.data
|
||||
supplierList.value = supplierRef.value?.supplierList; // 供应商列表
|
||||
isShowAdd.value = true;
|
||||
});
|
||||
}
|
||||
|
||||
// 操作信息
|
||||
const opInfo = (row, type) => {
|
||||
const _ids = row.id ? [row.id] : row; // 操作的id,有表格内点击和批量操作两种
|
||||
|
||||
switch (type) {
|
||||
case 'check':
|
||||
// 验证域名
|
||||
if (row.id) {
|
||||
row.checkLoading = true;
|
||||
} else {
|
||||
loading.value = true;
|
||||
};
|
||||
|
||||
getDomainVerify({ ids: _ids }).then(res => {
|
||||
proxy.$modal.msgSuccess(proxy.t('验证成功!'));
|
||||
row.checkLoading = false;
|
||||
getList();
|
||||
}).catch(() => {
|
||||
row.checkLoading = false;
|
||||
loading.value = false;
|
||||
batchOpType.value = '';
|
||||
});
|
||||
break
|
||||
case 'getNS':
|
||||
// 获取NS
|
||||
row.getNSLoading = true;
|
||||
|
||||
getDomainNS(row.id).then(res => {
|
||||
proxy.$modal.msgSuccess(proxy.t('获取NS成功!'));
|
||||
row.getNSLoading = false;
|
||||
getList();
|
||||
}).catch(() => {
|
||||
row.getNSLoading = false;
|
||||
loading.value = false;
|
||||
});
|
||||
break
|
||||
case 'refresh':
|
||||
// 刷新域名过期日期
|
||||
if (row.id) {
|
||||
row.refreshLoading = true;
|
||||
} else {
|
||||
loading.value = true;
|
||||
};
|
||||
|
||||
getDomainExpireTime({ ids: _ids }).then(res => {
|
||||
proxy.$modal.msgSuccess(proxy.t('刷新成功!'));
|
||||
row.refreshLoading = false;
|
||||
getList();
|
||||
}).catch(() => {
|
||||
row.refreshLoading = false;
|
||||
loading.value = false;
|
||||
batchOpType.value = '';
|
||||
});
|
||||
break
|
||||
case 'stop':
|
||||
// 强制停用
|
||||
proxy.$modal.confirm(proxy.t('停用将停止解析域名,请谨慎操作!')).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
setDomainStop({ ids: _ids }).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('域名停用成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
batchOpType.value = '';
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'delete':
|
||||
// 删除域名
|
||||
proxy.$modal.confirm(proxy.t('删除主域名,子域名解析将被删除,请谨慎操作!')).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
delDomain(_ids.join(',')).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('删除成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
batchOpType.value = '';
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 批量操作
|
||||
const tableRef = ref(),
|
||||
isAllSelection = ref(false), // 是否全选
|
||||
selectionData = ref([]), // 选中的表格数据
|
||||
batchOpType = ref(''); // 选中的批量操作类型
|
||||
|
||||
// 批量操作选项
|
||||
const opTypeOptions = ref([
|
||||
{ label: proxy.t('检查过期日期'), value: 'refresh' },
|
||||
{ label: proxy.t('域名验证'), value: 'check' },
|
||||
{ label: proxy.t('彻底删除'), value: 'delete' },
|
||||
{ label: proxy.t('强制停用'), value: 'stop' }
|
||||
]);
|
||||
|
||||
// 勾选表格
|
||||
const tableSelect = (val) => {
|
||||
selectionData.value = val;
|
||||
|
||||
if (val.length === dataList.value.length) {
|
||||
isAllSelection.value = true;
|
||||
} else {
|
||||
isAllSelection.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 全选表格
|
||||
const allSelectionChange = () => {
|
||||
tableRef.value.toggleAllSelection();
|
||||
}
|
||||
|
||||
// 选择批量数据操作类型
|
||||
const opTypeChange = () => {
|
||||
const ids = selectionData.value.map(v => v.id);
|
||||
opInfo(ids, batchOpType.value);
|
||||
}
|
||||
|
||||
// 清空批量操作痕迹
|
||||
const clearBatchOp = () => {
|
||||
isAllSelection.value = false;
|
||||
selectionData.value = [];
|
||||
batchOpType.value = '';
|
||||
}
|
||||
|
||||
// 搜索按钮操作
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
|
||||
// 重置按钮操作
|
||||
const resetQuery = () => {
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const isShowInfo = ref(false), isShowAdd = ref(false);
|
||||
const closeDialog = (type) => {
|
||||
isShowAdd.value = false;
|
||||
isShowInfo.value = false;
|
||||
// getList();
|
||||
if (type == 'submit') {
|
||||
getList();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.domain-main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
|
||||
// 左侧
|
||||
.dm-left {
|
||||
width: 145px;
|
||||
height: 100%;
|
||||
border-right: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
// 右侧
|
||||
.dm-right {
|
||||
width: calc(100% - 160px);
|
||||
margin-left: 15px;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.copy-ml {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,370 @@
|
|||
<template>
|
||||
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery()"
|
||||
@resetQuery="resetQuery">
|
||||
<template #left>
|
||||
<el-form-item prop="supplierCode">
|
||||
<el-input v-model="queryParams.supplierCode" placeholder="请输入服务商code" clearable />
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template #right>
|
||||
<el-button type="primary" plain icon="Plus" @click="openAddDomainNameProvider" v-hasPermi="['operation:supplier:add']">{{
|
||||
t('新增') }}</el-button>
|
||||
<el-button type="primary" @click="openConfigSupplier" v-hasPermi="['operation:supplier:config:query']">{{
|
||||
t('配置信息') }}</el-button>
|
||||
</template>
|
||||
</table-search-card>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
class="c-table-main"
|
||||
:data="deptList"
|
||||
row-key="id"
|
||||
border
|
||||
stripe
|
||||
>
|
||||
|
||||
<el-table-column prop="supplierCode" label="服务商code" min-width="160"></el-table-column>
|
||||
|
||||
<el-table-column prop="supplierName" label="供应商名称" min-width="160"></el-table-column>
|
||||
<el-table-column prop="currencyCode" label="币种代码" min-width="110"></el-table-column>
|
||||
<el-table-column prop="freeNode" label="免费节点数量" min-width="150">
|
||||
<template #default="{ row }">
|
||||
{{ row.freeNode }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('停用状态')" align="center" prop="stopStatus" v-hasPermi="['operation:supplier:switch']" label-class-name="text-warning">
|
||||
<template #default="{ row }">
|
||||
<base-switch v-model="row.stopStatus" :active-value="true" :inactive-value="false"
|
||||
:before-change="() => beforeSwitchChange(row, 'stopStatus')" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="超出自由节点" min-width="150">
|
||||
<template #default="{ row }">
|
||||
{{ row.exceedFreeNode }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="exceedCost" label="超出费用/节点/月" width="200">
|
||||
<template #default="{ row }">
|
||||
{{ row.exceedCost }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="200">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime)||'--' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" min-width="150" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="handleUpdate(scope.row)" v-hasPermi="['operation:supplier:edit']">修改</el-button>
|
||||
<el-button v-if="scope.row.parentId != 0" link type="primary" @click="handleDelete(scope.row)" v-hasPermi="['operation:supplier:remove']">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<!-- 添加或修改部门对话框 -->
|
||||
<el-dialog :title="title" align-center v-model="open" width="800px" append-to-body>
|
||||
<el-form ref="deptRef" :model="form" :rules="rules" label-width="170px">
|
||||
<el-form-item label="供应商名称" prop="supplierName">
|
||||
<el-input v-model="form.supplierName" placeholder="请输入供应商名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="服务商code" prop="supplierCode">
|
||||
<el-input v-model="form.supplierCode" placeholder="请输入服务商code" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="币种" prop="deptName">
|
||||
<custom-select v-model="form.currencyType" :options="currencySelectArr" style="width: 220px;"></custom-select>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="供应商类型" prop="supplierType">
|
||||
<custom-select v-model="form.supplierType" :options="supplierTypeSelectArr" style=""></custom-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="自定义解析类型" prop="analysisType">
|
||||
<custom-select v-model="form.analysisType" :options="analysisTypeSelectArr" style=""></custom-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="免费节点数量" prop="freeNode">
|
||||
<el-input v-model="form.freeNode" placeholder="请输入免费节点数量" />
|
||||
</el-form-item>
|
||||
<el-form-item label="允许超出免费节点数量" prop="exceedFreeNode">
|
||||
<el-input v-model="form.exceedFreeNode" placeholder="请输入允许超出免费节点数量" />
|
||||
</el-form-item>
|
||||
<el-form-item label="超出费用/节点/月" prop="exceedCost">
|
||||
<el-input v-model="form.exceedCost" placeholder="请输入超出费用/节点/月" />
|
||||
</el-form-item>
|
||||
<el-form-item label="防封" prop="prohibit">
|
||||
<el-switch v-model="form.prohibit" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否支持alb负载均衡" prop="supportAlb">
|
||||
<el-switch v-model="form.supportAlb" />
|
||||
</el-form-item>
|
||||
<el-form-item label="停用状态" prop="stopStatus">
|
||||
<el-switch v-model="form.stopStatus" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog :title="t('配置信息')" align-center v-model="showConfigSupplier" width="700px" append-to-body>
|
||||
<el-form ref="configRef" :model="formConfig" :rules="rulesConfig" label-width="170px">
|
||||
<el-form-item label="域名解析数量" prop="domainNameCnt">
|
||||
<el-input v-model="formConfig.domainNameCnt" placeholder="请输入域名解析数量" />
|
||||
</el-form-item>
|
||||
<el-form-item label="超出域名数量收费" prop="exceedDomainCost">
|
||||
<el-input v-model="formConfig.exceedDomainCost" placeholder="请输入超出域名数量收费" />
|
||||
</el-form-item>
|
||||
<el-form-item label="流量G" prop="trafficG">
|
||||
<el-input v-model="formConfig.trafficG" placeholder="请输入流量G" />
|
||||
</el-form-item>
|
||||
<el-form-item label="超出流量部分收费" prop="exceedTrafficCost">
|
||||
<el-input v-model="formConfig.exceedTrafficCost" placeholder="请输入超出流量部分收费" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitConfig">确 定</el-button>
|
||||
<el-button @click="cancelConfig">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup name="Dept">
|
||||
import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild } from "@/api/system/dept";
|
||||
import { getDomainSupplierList,switchDomainSupplier,addDomainSupplier,putDomainSupplier,delDomainSupplier,getDomainSupplierInfo,getDomainSupplierConfig,configDomainSupplier } from "@/api/operation/domainNameProvider";
|
||||
import baseSwitch from "@/components/BaseSwitch";
|
||||
import CustomSelect from '@/components/CustomSelect';
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
|
||||
|
||||
const deptList = ref([]);
|
||||
const total = ref(0);
|
||||
const open = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const title = ref("");
|
||||
const deptOptions = ref([]);
|
||||
const isExpandAll = ref(true);
|
||||
const refreshTable = ref(true);
|
||||
const oldForm = shallowRef({ });
|
||||
const showConfigSupplier = ref(false);
|
||||
const formConfig = ref({
|
||||
});
|
||||
const rulesConfig = reactive({
|
||||
domainNameCnt: [
|
||||
{ required: true, message: "请输入域名数量", trigger: "change" },
|
||||
],
|
||||
exceedDomainCost: [
|
||||
{ required: true, message: "请输入超出域名单价", trigger: "change" },
|
||||
],
|
||||
trafficG: [
|
||||
{ required: true, message: "请输入流量单价", trigger: "change" },
|
||||
],
|
||||
exceedTrafficCost: [
|
||||
{ required: true, message: "请输入超出流量单价", trigger: "change" },
|
||||
],
|
||||
});
|
||||
const data = reactive({
|
||||
form: {},
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
orderByColumn:'createTime',
|
||||
isAsc:'desc'
|
||||
},
|
||||
rules: {
|
||||
supplierName: [
|
||||
{ required: true, message: "请输入供应商名称", trigger: "change" },
|
||||
{ min: 2, max: 20, message: "长度在 2 到 20 个字符", trigger: "change" },
|
||||
],
|
||||
supplierCode: [
|
||||
{ required: true, message: "请输入供应商编号", trigger: "change" },
|
||||
],
|
||||
supplierType: [
|
||||
{ required: true, message: "请选择供应商类型", trigger: "change" },
|
||||
],
|
||||
analysisType: [
|
||||
{ required: true, message: "请选择供应商类型", trigger: "change" },
|
||||
],
|
||||
freeNode: [
|
||||
{ required: true, message: "请选择供应商类型", trigger: "change" },
|
||||
],
|
||||
exceedFreeNode: [
|
||||
{ required: true, message: "请选择供应商类型", trigger: "change" },
|
||||
],
|
||||
exceedCost: [
|
||||
{ required: true, message: "请选择供应商类型", trigger: "change" },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
const supplierTypeSelectArr = ref([
|
||||
{ label: "全球", value: "1" },
|
||||
{ label: "大陆", value: "2" },
|
||||
{ label: "国际", value: "3" },
|
||||
])
|
||||
const analysisTypeSelectArr = ref([
|
||||
{ label: "正常解析", value: "1" },
|
||||
{ label: "支持更换请求协议", value: "2" },
|
||||
])
|
||||
// const currencySelectArr = getLocalStorage('currencySelect')?.map(item => {
|
||||
// return {
|
||||
// label: `${item.currencyName}(${item.currencyCode})`,
|
||||
// value: item.currencyCode
|
||||
// };
|
||||
// });
|
||||
/** 查询部门列表 */
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
getDomainSupplierList(queryParams.value).then(response => {
|
||||
deptList.value = response.rows;
|
||||
total.value = response.total;
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
/** 取消按钮 */
|
||||
function cancel() {
|
||||
open.value = false;
|
||||
reset();
|
||||
}
|
||||
|
||||
/** 表单重置 */
|
||||
function reset() {
|
||||
form.value = {
|
||||
deptId: undefined,
|
||||
parentId: undefined,
|
||||
deptName: undefined,
|
||||
orderNum: 0,
|
||||
leader: undefined,
|
||||
phone: undefined,
|
||||
email: undefined,
|
||||
status: "0"
|
||||
};
|
||||
proxy.resetForm("deptRef");
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
getList();
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
function resetQuery() {
|
||||
proxy.resetForm("queryRef");
|
||||
handleQuery();
|
||||
}
|
||||
const switchBeforeChange = () => {
|
||||
return false
|
||||
}
|
||||
|
||||
const beforeSwitchChange = async (row, undateKeys) => {
|
||||
const _status = row[undateKeys] == true ? false : true
|
||||
const _data = {
|
||||
id: row.id
|
||||
}
|
||||
_data[undateKeys] = _status
|
||||
try {
|
||||
await switchDomainSupplier(_data).then(() => {
|
||||
proxy.$modal.msgSuccess(_status === 1 ? proxy.t('开启成功') : proxy.t('关闭成功'))
|
||||
getList()
|
||||
})
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(proxy.t('接口调用失败'), error);
|
||||
return false; // 阻止开关状态改变
|
||||
}
|
||||
}
|
||||
/** 新增按钮操作 */
|
||||
function openAddDomainNameProvider(row) {
|
||||
reset();
|
||||
open.value = true;
|
||||
title.value = "新增域名供应商";
|
||||
}
|
||||
//配置
|
||||
const openConfigSupplier = async (row) => {
|
||||
getDomainSupplierConfig({ }).then(res => {
|
||||
formConfig.value = res.data;
|
||||
showConfigSupplier.value = true;
|
||||
oldForm.value = JSON.stringify(formConfig.value);
|
||||
})
|
||||
}
|
||||
const cancelConfig = () => {
|
||||
reset();
|
||||
showConfigSupplier.value = false;
|
||||
}
|
||||
const submitConfig = async () => {
|
||||
proxy.$refs["configRef"].validate(valid => {
|
||||
if (valid) {
|
||||
if (JSON.stringify(formConfig.value) != oldForm.value) {
|
||||
configDomainSupplier(formConfig.value).then(res => {
|
||||
proxy.$message.success(proxy.t('修改成功'));
|
||||
cancelConfig();
|
||||
getList();
|
||||
})
|
||||
}else{
|
||||
cancelConfig();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
/** 修改按钮操作 */
|
||||
function handleUpdate(row) {
|
||||
reset();
|
||||
getDomainSupplierInfo(row.id).then(response => {
|
||||
form.value = response.data;
|
||||
open.value = true;
|
||||
title.value = "修改域名供应商";
|
||||
setTimeout(() => {
|
||||
let objForm = form.value
|
||||
oldForm.value = JSON.stringify(objForm);
|
||||
}, 500);
|
||||
});
|
||||
}
|
||||
|
||||
/** 提交按钮 */
|
||||
function submitForm() {
|
||||
proxy.$refs["deptRef"].validate(valid => {
|
||||
if (valid) {
|
||||
if (form.value.id != undefined) {
|
||||
if (JSON.stringify(form.value) != oldForm.value) {
|
||||
putDomainSupplier(form.value).then(response => {
|
||||
proxy.$modal.msgSuccess("修改成功");
|
||||
open.value = false;
|
||||
getList();
|
||||
});
|
||||
}else{
|
||||
open.value = false;
|
||||
}
|
||||
} else {
|
||||
addDomainSupplier(form.value).then(response => {
|
||||
proxy.$modal.msgSuccess("新增成功");
|
||||
open.value = false;
|
||||
getList();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
function handleDelete(row) {
|
||||
proxy.$modal.confirm('是否确认删除名称为"' + row.supplierName + '"的数据项?').then(function() {
|
||||
return delDomainSupplier(row.id);
|
||||
}).then(() => {
|
||||
getList();
|
||||
proxy.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
getList();
|
||||
</script>
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 全局搜索 -->
|
||||
<el-input v-model="domainName" class="domain-search-input" :placeholder="t('全局搜索域名')">
|
||||
<template #suffix>
|
||||
<el-icon @click="searchDomain" :class="'el-input__icon ' + (searchLoading ? 'c-rotate' : '')"
|
||||
style="cursor: pointer;">
|
||||
<Search v-if="!searchLoading" />
|
||||
<Loading v-else />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
|
||||
<!-- 标签页 -->
|
||||
<el-tabs v-model="activeName" @tab-click="tabClick">
|
||||
<el-tab-pane name="domainManage" :label="t('域名管理')" v-hasPermi="['operation:domain:list']"></el-tab-pane>
|
||||
<el-tab-pane name="DomainNameProvider" :label="t('域名供应商管理')" v-hasPermi="['operation:son:web:list']"></el-tab-pane>
|
||||
<!-- <el-tab-pane name="webHall" :label="t('Web大厅')" v-hasPermi="['operation:son:web:list']"></el-tab-pane> -->
|
||||
<!-- <el-tab-pane name="backend" :label="t('后端加速域名')" v-hasPermi="['operation:son:backend:list']"></el-tab-pane>
|
||||
<el-tab-pane name="appHall" :label="t('App大厅')" v-hasPermi="['operation:son:app:list']"></el-tab-pane>
|
||||
<el-tab-pane name="oss" :label="t('OSS加速域名')" v-hasPermi="['operation:son:oss:list']"></el-tab-pane>
|
||||
<el-tab-pane name="downloadSite" :label="t('下载站域名')" v-hasPermi="['operation:son:download:list']"></el-tab-pane>
|
||||
<el-tab-pane name="payment" :label="t('支付域名')" v-hasPermi="['operation:son:pay:list']"></el-tab-pane>
|
||||
<el-tab-pane name="whiteList" :label="t('外部白名单域名(含担保)')" v-hasPermi="['operation:whitelist:list']"></el-tab-pane>
|
||||
<el-tab-pane name="customParsing" :label="t('自定义解析')" v-hasPermi="['operation:analysis:list']"></el-tab-pane> -->
|
||||
</el-tabs>
|
||||
|
||||
<!-- 列表组件 -->
|
||||
<div class="tabs-main-box">
|
||||
<domain-manage-list v-if="activeName === 'domainManage'"></domain-manage-list>
|
||||
<domainName-provider v-if="activeName === 'DomainNameProvider'"></domainName-provider>
|
||||
<!-- <web-hall-list v-if="activeName === 'webHall'" @goDomainManage="goDomainManage" :searchResult="searchResult"></web-hall-list>
|
||||
<backend-list v-if="activeName === 'backend'" @goDomainManage="goDomainManage" :searchResult="searchResult"></backend-list>
|
||||
<app-hall-list v-if="activeName === 'appHall'" @goDomainManage="goDomainManage" :searchResult="searchResult"></app-hall-list>
|
||||
<oss-list v-if="activeName === 'oss'" @goDomainManage="goDomainManage" :searchResult="searchResult"></oss-list>
|
||||
<download-site-list v-if="activeName === 'downloadSite'" @goDomainManage="goDomainManage" :searchResult="searchResult"></download-site-list>
|
||||
<payment-list v-if="activeName === 'payment'" @goDomainManage="goDomainManage" :searchResult="searchResult"></payment-list>
|
||||
<white-list v-if="activeName === 'whiteList'"></white-list>
|
||||
<custom-parsing v-if="activeName === 'customParsing'"></custom-parsing> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 域名管理 -->
|
||||
<script setup name="Domain">
|
||||
import { getSonDomainSearch } from "@/api/operation/domain"; // 子域名搜索
|
||||
import DomainManageList from './domainManage/index.vue'; // 域名管理列表
|
||||
import DomainNameProvider from './domainNameProvider/index.vue'; // 域名提供方
|
||||
import WebHallList from './sonDomainList/WebHallList.vue'; // web大厅列表
|
||||
import BackendList from './sonDomainList/BackendList.vue'; // 后端加速列表
|
||||
import AppHallList from './sonDomainList/AppHallList.vue'; // app大厅列表
|
||||
import OssList from './sonDomainList/OssList.vue'; // oss加速列表
|
||||
import DownloadSiteList from './sonDomainList/DownloadSiteList.vue'; // 下载站列表
|
||||
import PaymentList from './sonDomainList/PaymentList.vue' // 支付域名列表
|
||||
import WhiteList from './whiteList/index.vue'; // 外部白名单
|
||||
import CustomParsing from './customParsing/index.vue'; // 自定义解析
|
||||
|
||||
// 默认tab页
|
||||
const activeName = ref('domainManage');
|
||||
|
||||
// 子组件跳转过来,展示域名管理tab页
|
||||
const goDomainManage = () => {
|
||||
activeName.value = 'domainManage';
|
||||
}
|
||||
|
||||
// 全局搜索域名
|
||||
const tabNames = ['webHall', 'backend', 'appHall', 'oss', 'downloadSite', 'payment'], // 根据返回域名类型,来定位,顺序不能更改 字典 operation_domain_son_type
|
||||
searchLoading = ref(false), // 搜索loading状态
|
||||
domainName = ref(''), // 搜索域名
|
||||
searchResult = ref({}); // 搜索结果
|
||||
|
||||
const searchDomain = () => {
|
||||
if (!domainName.value) return;
|
||||
searchLoading.value = true;
|
||||
|
||||
getSonDomainSearch({ name: domainName.value }).then(res => {
|
||||
searchLoading.value = false;
|
||||
|
||||
// 搜索结果定位
|
||||
activeName.value = tabNames[res.data.domainSonTypeType - 1];
|
||||
searchResult.value = {
|
||||
type: 'domainName',
|
||||
domainName: domainName.value,
|
||||
domainSupplierId: res.data.domainSupplierId
|
||||
};
|
||||
}).catch(() => {
|
||||
searchLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
// tab切换
|
||||
const tabClick = () => {
|
||||
searchResult.value = {};
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.app-container {
|
||||
position: relative;
|
||||
|
||||
.domain-search-input {
|
||||
width: 240px;
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 15px;
|
||||
z-index: 1000;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,404 @@
|
|||
<template>
|
||||
<!-- APP大厅域名列表 -->
|
||||
<table-search-card :model="queryParams" @getList="getList" :leftSpan="16" :rightSpan="8" @handleQuery="handleQuery()"
|
||||
@resetQuery="resetQuery">
|
||||
<template #left>
|
||||
<select-input-form :queryParamsList="queryParamsList" v-model:queryParams="queryParams" :width="[130, 260]"
|
||||
@handleQuery="handleQuery"></select-input-form>
|
||||
<el-form-item prop="usageStatus" style="width: 150px;">
|
||||
<dict-select clearable v-model="queryParams.usageStatus" :placeholder="t('使用状态')"
|
||||
dictKey="operation_domain_son_usage_status" @change="handleQuery"></dict-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template #right>
|
||||
<auto-refresh-time apiName="appDomainList" @refreshFn="getList"
|
||||
style="margin-right: 10px;"></auto-refresh-time>
|
||||
<el-button type="success" plain icon="Plus" @click="openAddDomain" v-hasPermi="['operation:son:app:add']">{{
|
||||
t('新增') }}</el-button>
|
||||
</template>
|
||||
</table-search-card>
|
||||
|
||||
<!-- 查询表格 -->
|
||||
<div class="domain-main">
|
||||
<!-- 左侧供应商 -->
|
||||
<div class="dm-left">
|
||||
<el-scrollbar max-height="600px">
|
||||
<!-- 供应商选择 -->
|
||||
<supplier-button ref="supplierRef" v-model="queryParams.domainSupplierId" @change="handleQuery"
|
||||
@getCurSupplierNode="getCurSupplierNode"></supplier-button>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
<!-- 右侧表格 -->
|
||||
<div class="dm-right">
|
||||
<el-alert v-if="currentNodeTips" style="margin-bottom: 15px;" :title="currentNodeTips" :closable="false"
|
||||
type="warning" show-icon />
|
||||
|
||||
<el-table ref="tableRef" class="c-table-main" v-loading="loading" row-key="id" stripe border :data="dataList"
|
||||
@select="tableSelect" @select-all="tableSelect">
|
||||
<el-table-column align="center" type="selection" width="55" />
|
||||
<el-table-column :label="t('CDN节点名称')" align="center" min-width="160">
|
||||
<template #default="{ row }">
|
||||
{{ row.cdnNodeName }}
|
||||
<dict-text class="c-green" dictKey="ff_operation_son_type" :value="row.sonType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" min-width="280">
|
||||
<template #header>
|
||||
<span>{{ t('生效域名') }}</span>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
{{ row.name }}<copy-icon :text="row.name" class="copy-ml"></copy-icon>
|
||||
<p :class="'c-clear ' + (row.analyzeStatus ? 'c-green' : 'c-red')">{{ row.analyzeStatus ? t('已解析') :
|
||||
t('待解析') }}</p>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" min-width="220">
|
||||
<template #header>
|
||||
<span>{{ t('解析说明(生效状态和网速)') }}</span>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<span :class="'c-clear ' + (row.analyzeInvalid ? 'c-green' : 'c-red')">{{ row.analyzeInvalid ?
|
||||
t('已生效') : t('未生效') }}</span>
|
||||
<el-icon @click="opInfo(row, 'refresh')" :class="row.refreshLoading ? 'c-rotate' : ''"
|
||||
style="position: relative; top: 4px; margin-left: 8px;" size="16" class="c-blue">
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('使用状态')" align="center" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<dict-text :colorValues="['c-grey', 'c-orange', 'c-orange', 'c-green', 'c-red']"
|
||||
dictKey="operation_domain_son_usage_status" :value="row.usageStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<table-operation></table-operation>
|
||||
<el-table-column :label="t('操作')" align="center" min-width="220" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button v-if="row.usageStatus == 4" link type="primary" @click="opInfo(row, 'clearCache')"
|
||||
v-hasPermi="['operation:son:app:clear']">
|
||||
{{ t('清理缓存') }}
|
||||
</el-button>
|
||||
<el-tooltip v-if="row.usageStatus == 1 || row.usageStatus == 5" effect="dark"
|
||||
:content="t('提示:启用后请等待1分钟再操作')" placement="top">
|
||||
<el-button link type="primary" @click="opInfo(row, 'status')"
|
||||
v-hasPermi="['operation:son:app:status']">
|
||||
{{ t('启用') }}
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="row.usageStatus == 2 || row.usageStatus == 3 || row.usageStatus == 4" effect="dark"
|
||||
:content="t('提示:停用后请等待1分钟再操作')" placement="top">
|
||||
<el-button link type="primary" @click="opInfo(row, 'status')"
|
||||
v-hasPermi="['operation:son:app:status']">
|
||||
{{ t('停用') }}
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-button v-if="row.usageStatus == 1 && row.sonType != -1 && row.sonType != -2" link type="primary"
|
||||
@click="opInfo(row, 'edit')" v-hasPermi="['operation:son:app:edit']">
|
||||
{{ t('修改') }}
|
||||
</el-button>
|
||||
<el-button v-if="row.usageStatus == 1 || row.usageStatus == 5" link type="primary"
|
||||
@click="opInfo(row, 'delete')" v-hasPermi="['operation:son:app:remove']">
|
||||
{{ t('删除') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 批量操作 -->
|
||||
<table-batch-operate v-if="total > 0" v-model:batchOpType="batchOpType" v-model:isAllSelection="isAllSelection"
|
||||
@allSelectionChange="allSelectionChange" @opTypeChange="opTypeChange" :selectionData="selectionData"
|
||||
:opTypeOptions="opTypeOptions"></table-batch-operate>
|
||||
<!-- 列表分页 -->
|
||||
<pagination v-if="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 新增域名弹窗 -->
|
||||
<add-son-domain v-if="isShowAdd" type="appHall" :supplierList="supplierList" @goDomainManage="goDomainManage"
|
||||
@closeDialog="closeDialog"></add-son-domain>
|
||||
|
||||
<!-- 修改域名弹窗 -->
|
||||
<edit-son-domain v-if="isShowEdit" type="appHall" :currentDomainInfo="currentDomainInfo"
|
||||
@closeDialog="closeDialog"></edit-son-domain>
|
||||
|
||||
<!-- 批量操作弹窗 -->
|
||||
<batch-operation v-if="isShowBatchOp" type="appHall" :batchOpType="batchOpType" :selectionData="selectionData"
|
||||
@closeDialog="closeDialog"></batch-operation>
|
||||
</template>
|
||||
|
||||
<script setup name="AppHallList">
|
||||
import {
|
||||
getAppDomainList, // 域名列表
|
||||
refreshAppDomainAnalysis, // 刷新解析说明
|
||||
setAppDomainStatus, // 域名状态切换
|
||||
clearAppDomainCache, // 清理缓存
|
||||
delAppDomain // 删除域名
|
||||
} from "@/api/operation/domain";
|
||||
import AutoRefreshTime from "@/components/AutoRefreshTime"; // 定时刷新
|
||||
import CopyIcon from "@/components/CopyIcon"; // 小图标复制
|
||||
import TableBatchOperate from '@/components/TableBatchOperate'; // 批量操作
|
||||
import SupplierButton from "../components/SupplierButton.vue"; // 供应商选择按钮
|
||||
import AddSonDomain from "../components/AddSonDomain.vue"; // 新增子域名弹窗
|
||||
import EditSonDomain from "../components/EditSonDomain.vue"; // 修改子域名弹窗
|
||||
import BatchOperation from "../components/BatchOperation.vue"; // 批量操作弹窗
|
||||
|
||||
const props = defineProps({
|
||||
// 全局搜索结果
|
||||
searchResult: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const loading = ref(true); // loading状态
|
||||
const isShowAdd = ref(false), isShowEdit = ref(false), isShowBatchOp = ref(false); // 各弹窗状态
|
||||
|
||||
// 获取供应商节点信息
|
||||
const supplierRef = ref(null), currentNodeTips = ref(''), supplierList = ref([]);
|
||||
const getCurSupplierNode = (data) => {
|
||||
currentNodeTips.value = data?.tips;
|
||||
}
|
||||
|
||||
// 根据下拉框条件输入搜索
|
||||
const queryParamsList = ref([{
|
||||
label: proxy.t('操作人'),
|
||||
value: 'updateBy'
|
||||
}, {
|
||||
label: proxy.t('子域名'),
|
||||
value: 'name'
|
||||
}]);
|
||||
|
||||
// 搜索配置
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
searchType: 'updateBy',
|
||||
name: '', // 子域名
|
||||
updateBy: '', // 操作人
|
||||
usageStatus: '', // 使用状态
|
||||
orderByColumn: 'createTime',
|
||||
isAsc: 'desc',
|
||||
domainSupplierId: '' // 供应商
|
||||
});
|
||||
|
||||
// 请求列表
|
||||
const dataList = ref([]), total = ref(0);
|
||||
const getList = () => {
|
||||
loading.value = true;
|
||||
|
||||
getAppDomainList(queryParams).then(res => {
|
||||
loading.value = false;
|
||||
dataList.value = res.rows;
|
||||
total.value = +res.total;
|
||||
clearBatchOp(); // 清空批量操作痕迹
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
dataList.value = [];
|
||||
total.value = 0;
|
||||
clearBatchOp(); // 清空批量操作痕迹
|
||||
});
|
||||
}
|
||||
getList();
|
||||
|
||||
// 新增域名
|
||||
const openAddDomain = () => {
|
||||
supplierList.value = supplierRef.value?.supplierList.filter(v => v.isOpen && !v.stopStatus); // 已开通且不是维护状态的供应商
|
||||
isShowAdd.value = true;
|
||||
}
|
||||
|
||||
// 操作信息
|
||||
const currentDomainInfo = ref({}); // 当前操作的域名信息
|
||||
const opInfo = (row, type) => {
|
||||
const _ids = row.id ? [row.id] : row; // 操作的id,有表格内点击和批量操作两种
|
||||
|
||||
switch (type) {
|
||||
case 'status':
|
||||
// 启用/停用
|
||||
let typeName = '', content = '', _usageStatus = '';
|
||||
|
||||
if (row.usageStatus == 1 || row.usageStatus == 5) {
|
||||
typeName = proxy.t('启用');
|
||||
content = proxy.t('确认启用该域名吗!');
|
||||
_usageStatus = 4;
|
||||
} else {
|
||||
typeName = proxy.t('停用');
|
||||
content = proxy.t('确认停用该域名吗!');
|
||||
_usageStatus = 5;
|
||||
}
|
||||
|
||||
proxy.$modal.confirm(content).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
setAppDomainStatus({ ids: _ids, usageStatus: _usageStatus }).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('域名') + typeName + proxy.t('成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'refresh':
|
||||
// 刷新域名解析说明
|
||||
row.refreshLoading = true;
|
||||
refreshAppDomainAnalysis({ id: row.id }).then(res => {
|
||||
proxy.$modal.msgSuccess(proxy.t('刷新成功!'));
|
||||
row.refreshLoading = false;
|
||||
getList();
|
||||
}).catch(() => {
|
||||
row.refreshLoading = false;
|
||||
});
|
||||
break
|
||||
case 'clearCache':
|
||||
// 清理缓存
|
||||
proxy.$modal.confirm(proxy.t('确定要清理该记录的缓存吗?')).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
clearAppDomainCache({ ids: _ids }).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('缓存清理成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'delete':
|
||||
// 删除域名
|
||||
proxy.$modal.confirm(proxy.t('确定要删除该域名吗!')).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
delAppDomain(_ids.join(',')).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('删除成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'edit':
|
||||
// 修改域名
|
||||
currentDomainInfo.value = row;
|
||||
isShowEdit.value = true;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 批量操作
|
||||
const tableRef = ref(),
|
||||
isAllSelection = ref(false), // 是否全选
|
||||
selectionData = ref([]), // 选中的表格数据
|
||||
batchOpType = ref(''); // 选中的批量操作类型
|
||||
|
||||
// 批量操作选项
|
||||
const opTypeOptions = ref([
|
||||
{ label: proxy.t('批量清理缓存'), value: 'clearCache' },
|
||||
{ label: proxy.t('批量删除'), value: 'delete' },
|
||||
{ label: proxy.t('批量停用'), value: 'stop' },
|
||||
{ label: proxy.t('批量启用'), value: 'enable' }
|
||||
]);
|
||||
|
||||
// 勾选表格
|
||||
const tableSelect = (val) => {
|
||||
selectionData.value = val;
|
||||
|
||||
if (val.length === dataList.value.length) {
|
||||
isAllSelection.value = true;
|
||||
} else {
|
||||
isAllSelection.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 全选表格
|
||||
const allSelectionChange = () => {
|
||||
tableRef.value.toggleAllSelection();
|
||||
}
|
||||
|
||||
// 选择批量数据操作类型
|
||||
const opTypeChange = () => {
|
||||
isShowBatchOp.value = true;
|
||||
}
|
||||
|
||||
// 清空批量操作痕迹
|
||||
const clearBatchOp = () => {
|
||||
isAllSelection.value = false;
|
||||
selectionData.value = [];
|
||||
batchOpType.value = '';
|
||||
}
|
||||
|
||||
// 搜索按钮操作
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
|
||||
// 重置按钮操作
|
||||
const resetQuery = () => {
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = (type) => {
|
||||
isShowAdd.value = false; // 新增域名弹窗
|
||||
isShowEdit.value = false; // 修改域名弹窗
|
||||
isShowBatchOp.value = false; // 批量操作弹窗
|
||||
batchOpType.value = ''; // 批量操作类型
|
||||
|
||||
// 批量操作清空
|
||||
if (type === 'batchSubmit') clearBatchOp();
|
||||
// 提交后刷新列表
|
||||
if (type === 'submit' || type === 'batchSubmit') {
|
||||
getList();
|
||||
}
|
||||
}
|
||||
|
||||
// 跳转域名管理
|
||||
const emit = defineEmits(['goDomainManage']);
|
||||
const goDomainManage = () => {
|
||||
emit('goDomainManage');
|
||||
}
|
||||
|
||||
// 全局搜索展示
|
||||
watch(() => props.searchResult, (val) => {
|
||||
if (val.type == 'domainName') {
|
||||
queryParams.searchType = 'name'
|
||||
queryParams.name = val.domainName;
|
||||
|
||||
nextTick(() => {
|
||||
queryParams.domainSupplierId = val.domainSupplierId;
|
||||
handleQuery();
|
||||
});
|
||||
}
|
||||
}, { deep: true, immediate: true });
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.domain-main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
|
||||
// 左侧
|
||||
.dm-left {
|
||||
width: 145px;
|
||||
height: 100%;
|
||||
border-right: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
// 右侧
|
||||
.dm-right {
|
||||
width: calc(100% - 160px);
|
||||
margin-left: 15px;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.copy-ml {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,403 @@
|
|||
<template>
|
||||
<!-- 后端加速域名列表 -->
|
||||
<table-search-card :model="queryParams" @getList="getList" :leftSpan="16" :rightSpan="8" @handleQuery="handleQuery()"
|
||||
@resetQuery="resetQuery">
|
||||
<template #left>
|
||||
<select-input-form :queryParamsList="queryParamsList" v-model:queryParams="queryParams" :width="[130, 260]"
|
||||
@handleQuery="handleQuery"></select-input-form>
|
||||
<el-form-item prop="usageStatus" style="width: 150px;">
|
||||
<dict-select clearable v-model="queryParams.usageStatus" :placeholder="t('使用状态')"
|
||||
dictKey="operation_domain_son_usage_status" @change="handleQuery"></dict-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template #right>
|
||||
<auto-refresh-time apiName="backendDomainList" @refreshFn="getList" style="margin-right: 10px;"></auto-refresh-time>
|
||||
<el-button type="success" plain icon="Plus" @click="openAddDomain" v-hasPermi="['operation:son:backend:add']">{{
|
||||
t('新增') }}</el-button>
|
||||
</template>
|
||||
</table-search-card>
|
||||
|
||||
<!-- 查询表格 -->
|
||||
<div class="domain-main">
|
||||
<!-- 左侧供应商 -->
|
||||
<div class="dm-left">
|
||||
<el-scrollbar max-height="600px">
|
||||
<!-- 供应商选择 -->
|
||||
<supplier-button ref="supplierRef" v-model="queryParams.domainSupplierId" @change="handleQuery"
|
||||
@getCurSupplierNode="getCurSupplierNode"></supplier-button>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
<!-- 右侧表格 -->
|
||||
<div class="dm-right">
|
||||
<el-alert v-if="currentNodeTips" style="margin-bottom: 15px;" :title="currentNodeTips" :closable="false"
|
||||
type="warning" show-icon />
|
||||
|
||||
<el-table ref="tableRef" class="c-table-main" v-loading="loading" row-key="id" stripe border :data="dataList"
|
||||
@select="tableSelect" @select-all="tableSelect">
|
||||
<el-table-column align="center" type="selection" width="55" />
|
||||
<el-table-column :label="t('CDN节点名称')" align="center" min-width="160">
|
||||
<template #default="{ row }">
|
||||
{{ row.cdnNodeName }}
|
||||
<dict-text class="c-green" dictKey="ff_operation_son_type" :value="row.sonType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" min-width="280">
|
||||
<template #header>
|
||||
<span>{{ t('生效域名') }}</span>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
{{ row.name }}<copy-icon :text="row.name" class="copy-ml"></copy-icon>
|
||||
<p :class="'c-clear ' + (row.analyzeStatus ? 'c-green' : 'c-red')">{{ row.analyzeStatus ? t('已解析') :
|
||||
t('待解析') }}</p>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" min-width="220">
|
||||
<template #header>
|
||||
<span>{{ t('解析说明(生效状态和网速)') }}</span>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<span :class="'c-clear ' + (row.analyzeInvalid ? 'c-green' : 'c-red')">{{ row.analyzeInvalid ?
|
||||
t('已生效') : t('未生效') }}</span>
|
||||
<el-icon @click="opInfo(row, 'refresh')" :class="row.refreshLoading ? 'c-rotate' : ''"
|
||||
style="position: relative; top: 4px; margin-left: 8px;" size="16" class="c-blue">
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('使用状态')" align="center" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<dict-text :colorValues="['c-grey', 'c-orange', 'c-orange', 'c-green', 'c-red']"
|
||||
dictKey="operation_domain_son_usage_status" :value="row.usageStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<table-operation></table-operation>
|
||||
<el-table-column :label="t('操作')" align="center" min-width="220" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button v-if="row.usageStatus == 4" link type="primary" @click="opInfo(row, 'clearCache')"
|
||||
v-hasPermi="['operation:son:backend:clear']">
|
||||
{{ t('清理缓存') }}
|
||||
</el-button>
|
||||
<el-tooltip v-if="row.usageStatus == 1 || row.usageStatus == 5" effect="dark"
|
||||
:content="t('提示:启用后请等待1分钟再操作')" placement="top">
|
||||
<el-button link type="primary" @click="opInfo(row, 'status')"
|
||||
v-hasPermi="['operation:son:backend:status']">
|
||||
{{ t('启用') }}
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="row.usageStatus == 2 || row.usageStatus == 3 || row.usageStatus == 4" effect="dark"
|
||||
:content="t('提示:停用后请等待1分钟再操作')" placement="top">
|
||||
<el-button link type="primary" @click="opInfo(row, 'status')"
|
||||
v-hasPermi="['operation:son:backend:status']">
|
||||
{{ t('停用') }}
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-button v-if="row.usageStatus == 1 && row.sonType != -1 && row.sonType != -2" link type="primary"
|
||||
@click="opInfo(row, 'edit')" v-hasPermi="['operation:son:backend:edit']">
|
||||
{{ t('修改') }}
|
||||
</el-button>
|
||||
<el-button v-if="row.usageStatus == 1 || row.usageStatus == 5" link type="primary"
|
||||
@click="opInfo(row, 'delete')" v-hasPermi="['operation:son:backend:remove']">
|
||||
{{ t('删除') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 批量操作 -->
|
||||
<table-batch-operate v-if="total > 0" v-model:batchOpType="batchOpType" v-model:isAllSelection="isAllSelection"
|
||||
@allSelectionChange="allSelectionChange" @opTypeChange="opTypeChange" :selectionData="selectionData"
|
||||
:opTypeOptions="opTypeOptions"></table-batch-operate>
|
||||
<!-- 列表分页 -->
|
||||
<pagination v-if="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 新增域名弹窗 -->
|
||||
<add-son-domain v-if="isShowAdd" type="backend" :supplierList="supplierList" @goDomainManage="goDomainManage"
|
||||
@closeDialog="closeDialog"></add-son-domain>
|
||||
|
||||
<!-- 修改域名弹窗 -->
|
||||
<edit-son-domain v-if="isShowEdit" type="backend" :currentDomainInfo="currentDomainInfo"
|
||||
@closeDialog="closeDialog"></edit-son-domain>
|
||||
|
||||
<!-- 批量操作弹窗 -->
|
||||
<batch-operation v-if="isShowBatchOp" type="backend" :batchOpType="batchOpType" :selectionData="selectionData"
|
||||
@closeDialog="closeDialog"></batch-operation>
|
||||
</template>
|
||||
|
||||
<script setup name="BackendList">
|
||||
import {
|
||||
getBackendDomainList, // 域名列表
|
||||
refreshBackendDomainAnalysis, // 刷新解析说明
|
||||
setBackendDomainStatus, // 域名状态切换
|
||||
clearBackendDomainCache, // 清理缓存
|
||||
delBackendDomain // 删除域名
|
||||
} from "@/api/operation/domain";
|
||||
import AutoRefreshTime from "@/components/AutoRefreshTime"; // 定时刷新
|
||||
import CopyIcon from "@/components/CopyIcon"; // 小图标复制
|
||||
import TableBatchOperate from '@/components/TableBatchOperate'; // 批量操作
|
||||
import SupplierButton from "../components/SupplierButton.vue"; // 供应商选择按钮
|
||||
import AddSonDomain from "../components/AddSonDomain.vue"; // 新增子域名弹窗
|
||||
import EditSonDomain from "../components/EditSonDomain.vue"; // 修改子域名弹窗
|
||||
import BatchOperation from "../components/BatchOperation.vue"; // 批量操作弹窗
|
||||
|
||||
const props = defineProps({
|
||||
// 全局搜索结果
|
||||
searchResult: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const loading = ref(true); // loading状态
|
||||
const isShowAdd = ref(false), isShowEdit = ref(false), isShowBatchOp = ref(false); // 各弹窗状态
|
||||
|
||||
// 获取供应商节点信息
|
||||
const supplierRef = ref(null), currentNodeTips = ref(''), supplierList = ref([]);
|
||||
const getCurSupplierNode = (data) => {
|
||||
currentNodeTips.value = data?.tips;
|
||||
}
|
||||
|
||||
// 根据下拉框条件输入搜索
|
||||
const queryParamsList = ref([{
|
||||
label: proxy.t('操作人'),
|
||||
value: 'updateBy'
|
||||
}, {
|
||||
label: proxy.t('子域名'),
|
||||
value: 'name'
|
||||
}]);
|
||||
|
||||
// 搜索配置
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
searchType: 'updateBy',
|
||||
name: '', // 子域名
|
||||
updateBy: '', // 操作人
|
||||
usageStatus: '', // 使用状态
|
||||
orderByColumn: 'createTime',
|
||||
isAsc: 'desc',
|
||||
domainSupplierId: '' // 供应商
|
||||
});
|
||||
|
||||
// 请求列表
|
||||
const dataList = ref([]), total = ref(0);
|
||||
const getList = () => {
|
||||
loading.value = true;
|
||||
|
||||
getBackendDomainList(queryParams).then(res => {
|
||||
loading.value = false;
|
||||
dataList.value = res.rows;
|
||||
total.value = +res.total;
|
||||
clearBatchOp(); // 清空批量操作痕迹
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
dataList.value = [];
|
||||
total.value = 0;
|
||||
clearBatchOp(); // 清空批量操作痕迹
|
||||
});
|
||||
}
|
||||
getList();
|
||||
|
||||
// 新增域名
|
||||
const openAddDomain = () => {
|
||||
supplierList.value = supplierRef.value?.supplierList.filter(v => v.isOpen && !v.stopStatus); // 已开通且不是维护状态的供应商
|
||||
isShowAdd.value = true;
|
||||
}
|
||||
|
||||
// 操作信息
|
||||
const currentDomainInfo = ref({}); // 当前操作的域名信息
|
||||
const opInfo = (row, type) => {
|
||||
const _ids = row.id ? [row.id] : row; // 操作的id,有表格内点击和批量操作两种
|
||||
|
||||
switch (type) {
|
||||
case 'status':
|
||||
// 启用/停用
|
||||
let typeName = '', content = '', _usageStatus = '';
|
||||
|
||||
if (row.usageStatus == 1 || row.usageStatus == 5) {
|
||||
typeName = proxy.t('启用');
|
||||
content = proxy.t('确认启用该域名吗!');
|
||||
_usageStatus = 4;
|
||||
} else {
|
||||
typeName = proxy.t('停用');
|
||||
content = proxy.t('确认停用该域名吗!');
|
||||
_usageStatus = 5;
|
||||
}
|
||||
|
||||
proxy.$modal.confirm(content).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
setBackendDomainStatus({ ids: _ids, usageStatus: _usageStatus }).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('域名') + typeName + proxy.t('成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'refresh':
|
||||
// 刷新域名解析说明
|
||||
row.refreshLoading = true;
|
||||
refreshBackendDomainAnalysis({ id: row.id }).then(res => {
|
||||
proxy.$modal.msgSuccess(proxy.t('刷新成功!'));
|
||||
row.refreshLoading = false;
|
||||
getList();
|
||||
}).catch(() => {
|
||||
row.refreshLoading = false;
|
||||
});
|
||||
break
|
||||
case 'clearCache':
|
||||
// 清理缓存
|
||||
proxy.$modal.confirm(proxy.t('确定要清理该记录的缓存吗?')).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
clearBackendDomainCache({ ids: _ids }).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('缓存清理成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'delete':
|
||||
// 删除域名
|
||||
proxy.$modal.confirm(proxy.t('确定要删除该域名吗!')).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
delBackendDomain(_ids.join(',')).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('删除成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'edit':
|
||||
// 修改域名
|
||||
currentDomainInfo.value = row;
|
||||
isShowEdit.value = true;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 批量操作
|
||||
const tableRef = ref(),
|
||||
isAllSelection = ref(false), // 是否全选
|
||||
selectionData = ref([]), // 选中的表格数据
|
||||
batchOpType = ref(''); // 选中的批量操作类型
|
||||
|
||||
// 批量操作选项
|
||||
const opTypeOptions = ref([
|
||||
{ label: proxy.t('批量清理缓存'), value: 'clearCache' },
|
||||
{ label: proxy.t('批量删除'), value: 'delete' },
|
||||
{ label: proxy.t('批量停用'), value: 'stop' },
|
||||
{ label: proxy.t('批量启用'), value: 'enable' }
|
||||
]);
|
||||
|
||||
// 勾选表格
|
||||
const tableSelect = (val) => {
|
||||
selectionData.value = val;
|
||||
|
||||
if (val.length === dataList.value.length) {
|
||||
isAllSelection.value = true;
|
||||
} else {
|
||||
isAllSelection.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 全选表格
|
||||
const allSelectionChange = () => {
|
||||
tableRef.value.toggleAllSelection();
|
||||
}
|
||||
|
||||
// 选择批量数据操作类型
|
||||
const opTypeChange = () => {
|
||||
isShowBatchOp.value = true;
|
||||
}
|
||||
|
||||
// 清空批量操作痕迹
|
||||
const clearBatchOp = () => {
|
||||
isAllSelection.value = false;
|
||||
selectionData.value = [];
|
||||
batchOpType.value = '';
|
||||
}
|
||||
|
||||
// 搜索按钮操作
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
|
||||
// 重置按钮操作
|
||||
const resetQuery = () => {
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = (type) => {
|
||||
isShowAdd.value = false; // 新增域名弹窗
|
||||
isShowEdit.value = false; // 修改域名弹窗
|
||||
isShowBatchOp.value = false; // 批量操作弹窗
|
||||
batchOpType.value = ''; // 批量操作类型
|
||||
|
||||
// 批量操作清空
|
||||
if (type === 'batchSubmit') clearBatchOp();
|
||||
// 提交后刷新列表
|
||||
if (type === 'submit' || type === 'batchSubmit') {
|
||||
getList();
|
||||
}
|
||||
}
|
||||
|
||||
// 跳转域名管理
|
||||
const emit = defineEmits(['goDomainManage']);
|
||||
const goDomainManage = () => {
|
||||
emit('goDomainManage');
|
||||
}
|
||||
|
||||
// 全局搜索展示
|
||||
watch(() => props.searchResult, (val) => {
|
||||
if (val.type == 'domainName') {
|
||||
queryParams.searchType = 'name'
|
||||
queryParams.name = val.domainName;
|
||||
|
||||
nextTick(() => {
|
||||
queryParams.domainSupplierId = val.domainSupplierId;
|
||||
handleQuery();
|
||||
});
|
||||
}
|
||||
}, { deep: true, immediate: true });
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.domain-main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
|
||||
// 左侧
|
||||
.dm-left {
|
||||
width: 145px;
|
||||
height: 100%;
|
||||
border-right: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
// 右侧
|
||||
.dm-right {
|
||||
width: calc(100% - 160px);
|
||||
margin-left: 15px;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.copy-ml {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,503 @@
|
|||
<template>
|
||||
<!-- 下载站域名列表 -->
|
||||
<table-search-card :model="queryParams" @getList="getList" :leftSpan="16" :rightSpan="8" @handleQuery="handleQuery()"
|
||||
@resetQuery="resetQuery">
|
||||
<template #left>
|
||||
<select-input-form :queryParamsList="queryParamsList" v-model:queryParams="queryParams" :width="[130, 260]"
|
||||
@handleQuery="handleQuery"></select-input-form>
|
||||
<el-form-item prop="usageStatus" style="width: 150px;">
|
||||
<dict-select clearable v-model="queryParams.usageStatus" :placeholder="t('使用状态')"
|
||||
dictKey="operation_domain_son_usage_status" @change="handleQuery"></dict-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template #right>
|
||||
<auto-refresh-time apiName="downloadSiteDomainList" @refreshFn="getList"
|
||||
style="margin-right: 10px;"></auto-refresh-time>
|
||||
<el-button type="success" plain icon="Plus" @click="openAddDomain" v-hasPermi="['operation:son:download:add']">{{
|
||||
t('新增') }}</el-button>
|
||||
</template>
|
||||
</table-search-card>
|
||||
|
||||
<!-- 查询表格 -->
|
||||
<div class="domain-main">
|
||||
<!-- 左侧供应商 -->
|
||||
<div class="dm-left">
|
||||
<el-scrollbar max-height="600px">
|
||||
<!-- 供应商选择 -->
|
||||
<supplier-button ref="supplierRef" v-model="queryParams.domainSupplierId" @change="handleQuery"
|
||||
@getCurSupplierNode="getCurSupplierNode"></supplier-button>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
<!-- 右侧表格 -->
|
||||
<div class="dm-right">
|
||||
<el-alert v-if="currentNodeTips" style="margin-bottom: 15px;" :title="currentNodeTips" :closable="false"
|
||||
type="warning" show-icon />
|
||||
|
||||
<el-table ref="tableRef" class="c-table-main" v-loading="loading" row-key="id" stripe border :data="dataList"
|
||||
@select="tableSelect" @select-all="tableSelect">
|
||||
<el-table-column align="center" type="selection" width="55" />
|
||||
<el-table-column :label="t('CDN节点名称')" align="center" min-width="160">
|
||||
<template #default="{ row }">
|
||||
{{ row.cdnNodeName }}
|
||||
<dict-text class="c-green" dictKey="ff_operation_son_type" :value="row.sonType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" min-width="280">
|
||||
<template #header>
|
||||
<span>{{ t('生效域名') }}</span>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
{{ row.name }}<copy-icon :text="row.name" class="copy-ml"></copy-icon>
|
||||
<p :class="'c-clear ' + (row.analyzeStatus ? 'c-green' : 'c-red')">{{ row.analyzeStatus ? t('已解析') :
|
||||
t('待解析') }}</p>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('端口类型')" align="center" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<dict-text dictKey="ff_operation_domain_son_port_type" :value="row.portType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('端口号')" prop="portValue" align="center" min-width="120"></el-table-column>
|
||||
<el-table-column align="center" min-width="220">
|
||||
<template #header>
|
||||
<span>{{ t('解析说明(生效状态和网速)') }}</span>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<span :class="'c-clear ' + (row.analyzeInvalid ? 'c-green' : 'c-red')">{{ row.analyzeInvalid ?
|
||||
t('已生效') : t('未生效') }}</span>
|
||||
<el-icon @click="opInfo(row, 'refresh')" :class="row.refreshLoading ? 'c-rotate' : ''"
|
||||
style="position: relative; top: 4px; margin-left: 8px;" size="16" class="c-blue">
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" min-width="160">
|
||||
<template #header>
|
||||
<span>{{ t('其他担保域名列表') }}</span>
|
||||
<icon-tips>
|
||||
<p class="c-clear" style="width: 400px;">
|
||||
{{ t('1.展示:即会员验证担保域名后,会展示一些站点的其他域名列表,方便会员保存记录、找到回家路或信任其他域名(推荐无封锁的国家)。') }}<br />
|
||||
{{ t('2.隐藏:即会员验证担保域名后,只能看到当前域名的验证结果,看不到其他域名列表,防止域名全部暴露,有被拦截和举报的风险。') }}
|
||||
</p>
|
||||
</icon-tips>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<base-switch :active-value="true" :inactive-value="false" v-model="row.backupDomain"
|
||||
:tipText="row.status ? t('确认隐藏吗?') : t('确认展示吗?')" :disabled="row.usageStatus != 4"
|
||||
:before-change="() => beforeSwitchChange(row, 'backupDomain')"></base-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" min-width="150">
|
||||
<template #header>
|
||||
<span>{{ t('强制绑定代理') }}</span>
|
||||
<icon-tips>
|
||||
<p class="c-clear" style="width: 400px;">
|
||||
{{ t('代理上级归属优先级:推广链接的上级 > 渠道ID的强制绑定上级 > 域名管理的强制绑定上级(无上级时,域名管理的才生效)') }}
|
||||
</p>
|
||||
</icon-tips>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.agentAccount" class="c-blue" @click="goRoute(row, 'agentAccount')">{{
|
||||
row.agentAccount }}</span>
|
||||
<span v-else>{{ t('无') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('使用状态')" align="center" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<dict-text :colorValues="['c-grey', 'c-orange', 'c-orange', 'c-green', 'c-red']"
|
||||
dictKey="operation_domain_son_usage_status" :value="row.usageStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<table-operation></table-operation>
|
||||
<el-table-column :label="t('操作')" align="center" min-width="220" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button v-if="row.usageStatus == 4" link type="primary" @click="opInfo(row, 'agent')"
|
||||
v-hasPermi="['operation:son:download:agent']">
|
||||
{{ t('绑定代理') }}
|
||||
</el-button>
|
||||
<el-button v-if="row.usageStatus == 4" link type="primary" @click="opInfo(row, 'clearCache')"
|
||||
v-hasPermi="['operation:son:download:clear']">
|
||||
{{ t('清理缓存') }}
|
||||
</el-button>
|
||||
<el-tooltip v-if="row.usageStatus == 1 || row.usageStatus == 5" effect="dark"
|
||||
:content="t('提示:启用后请等待1分钟再操作')" placement="top">
|
||||
<el-button link type="primary" @click="opInfo(row, 'status')"
|
||||
v-hasPermi="['operation:son:download:status']">
|
||||
{{ t('启用') }}
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="row.usageStatus == 2 || row.usageStatus == 3 || row.usageStatus == 4" effect="dark"
|
||||
:content="t('提示:停用后请等待1分钟再操作')" placement="top">
|
||||
<el-button link type="primary" @click="opInfo(row, 'status')"
|
||||
v-hasPermi="['operation:son:download:status']">
|
||||
{{ t('停用') }}
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-button v-if="row.usageStatus == 1 && row.sonType != -1 && row.sonType != -2" link type="primary"
|
||||
@click="opInfo(row, 'edit')" v-hasPermi="['operation:son:download:edit']">
|
||||
{{ t('修改') }}
|
||||
</el-button>
|
||||
<el-button v-if="row.usageStatus == 1 || row.usageStatus == 5" link type="primary"
|
||||
@click="opInfo(row, 'delete')" v-hasPermi="['operation:son:download:remove']">
|
||||
{{ t('删除') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 批量操作 -->
|
||||
<table-batch-operate v-if="total > 0" v-model:batchOpType="batchOpType" v-model:isAllSelection="isAllSelection"
|
||||
@allSelectionChange="allSelectionChange" @opTypeChange="opTypeChange" :selectionData="selectionData"
|
||||
:opTypeOptions="opTypeOptions"></table-batch-operate>
|
||||
<!-- 列表分页 -->
|
||||
<pagination v-if="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 新增域名弹窗 -->
|
||||
<add-son-domain v-if="isShowAdd" type="downloadSite" :supplierList="supplierList" @goDomainManage="goDomainManage"
|
||||
@closeDialog="closeDialog"></add-son-domain>
|
||||
|
||||
<!-- 修改域名弹窗 -->
|
||||
<edit-son-domain v-if="isShowEdit" type="downloadSite" :currentDomainInfo="currentDomainInfo"
|
||||
@closeDialog="closeDialog"></edit-son-domain>
|
||||
|
||||
<!-- 绑定代理弹窗 -->
|
||||
<bind-agent v-if="isShowAgent" type="downloadSite" :currentDomainInfo="currentDomainInfo"
|
||||
@closeDialog="closeDialog"></bind-agent>
|
||||
|
||||
<!-- 批量操作弹窗 -->
|
||||
<batch-operation v-if="isShowBatchOp" type="downloadSite" :batchOpType="batchOpType" :selectionData="selectionData"
|
||||
@closeDialog="closeDialog"></batch-operation>
|
||||
</template>
|
||||
|
||||
<script setup name="DownloadSiteList">
|
||||
import {
|
||||
getDownloadDomainList, // 域名列表
|
||||
refreshDownloadDomainAnalysis, // 刷新解析说明
|
||||
downloadDomainSwitch, // 开关切换
|
||||
setDownloadDomainStatus, // 域名状态切换
|
||||
clearDownloadDomainCache, // 清理缓存
|
||||
delDownloadDomain, // 删除域名
|
||||
} from "@/api/operation/domain";
|
||||
import AutoRefreshTime from "@/components/AutoRefreshTime"; // 定时刷新
|
||||
import CopyIcon from "@/components/CopyIcon"; // 小图标复制
|
||||
import IconTips from "@/components/IconTips"; // 小图标提示
|
||||
import TableBatchOperate from '@/components/TableBatchOperate'; // 批量操作
|
||||
import SupplierButton from "../components/SupplierButton.vue"; // 供应商选择按钮
|
||||
import BaseSwitch from "@/components/BaseSwitch"; // 开关
|
||||
import AddSonDomain from "../components/AddSonDomain.vue"; // 新增子域名弹窗
|
||||
import EditSonDomain from "../components/EditSonDomain.vue"; // 修改子域名弹窗
|
||||
import BindAgent from "../components/BindAgent.vue"; // 绑定代理
|
||||
import BatchOperation from "../components/BatchOperation.vue"; // 批量操作弹窗
|
||||
|
||||
const props = defineProps({
|
||||
// 全局搜索结果
|
||||
searchResult: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const loading = ref(true); // loading状态
|
||||
const isShowAdd = ref(false), isShowAgent = ref(false), isShowEdit = ref(false), isShowBatchOp = ref(false); // 各弹窗状态
|
||||
|
||||
// 获取供应商节点信息
|
||||
const supplierRef = ref(null), currentNodeTips = ref(''), supplierList = ref([]);
|
||||
const getCurSupplierNode = (data) => {
|
||||
currentNodeTips.value = data?.tips;
|
||||
}
|
||||
|
||||
// 根据下拉框条件输入搜索
|
||||
const queryParamsList = ref([{
|
||||
label: proxy.t('操作人'),
|
||||
value: 'updateBy'
|
||||
}, {
|
||||
label: proxy.t('子域名'),
|
||||
value: 'name'
|
||||
}]);
|
||||
|
||||
// 搜索配置
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
searchType: 'updateBy',
|
||||
name: '', // 子域名
|
||||
updateBy: '', // 操作人
|
||||
usageStatus: '', // 使用状态
|
||||
orderByColumn: 'createTime',
|
||||
isAsc: 'desc',
|
||||
domainSupplierId: '' // 供应商
|
||||
});
|
||||
|
||||
// 请求列表
|
||||
const dataList = ref([]), total = ref(0);
|
||||
const getList = () => {
|
||||
loading.value = true;
|
||||
|
||||
getDownloadDomainList(queryParams).then(res => {
|
||||
loading.value = false;
|
||||
|
||||
// 更改特定字段类型
|
||||
res.rows.forEach(item => {
|
||||
item.startEntrance = item.startEntrance.toString();
|
||||
item.blockDevice = item.blockDevice.toString();
|
||||
});
|
||||
|
||||
dataList.value = res.rows;
|
||||
total.value = +res.total;
|
||||
clearBatchOp(); // 清空批量操作痕迹
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
dataList.value = [];
|
||||
total.value = 0;
|
||||
clearBatchOp(); // 清空批量操作痕迹
|
||||
});
|
||||
}
|
||||
getList();
|
||||
|
||||
// 跳转页面
|
||||
const goRoute = (row, type) => {
|
||||
proxy.$router.push({
|
||||
path: '/agent/agent-info',
|
||||
query: {
|
||||
[type]: row.agentAccount,
|
||||
searchType: type
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 新增域名
|
||||
const openAddDomain = () => {
|
||||
supplierList.value = supplierRef.value?.supplierList.filter(v => v.isOpen && !v.stopStatus); // 已开通且不是维护状态的供应商
|
||||
isShowAdd.value = true;
|
||||
}
|
||||
|
||||
// 开启状态切换
|
||||
const beforeSwitchChange = (row, type) => {
|
||||
const params = {
|
||||
id: row.id,
|
||||
[type]: !row[type]
|
||||
}
|
||||
|
||||
downloadDomainSwitch({ operationDomainSons: [params] }).then(res => {
|
||||
proxy.$modal.msgSuccess(proxy.t('操作成功!'));
|
||||
getList();
|
||||
return true;
|
||||
}).catch(() => {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
// 操作信息
|
||||
const currentDomainInfo = ref({}); // 当前操作的域名信息
|
||||
const opInfo = (row, type) => {
|
||||
const _ids = row.id ? [row.id] : row; // 操作的id,有表格内点击和批量操作两种
|
||||
|
||||
switch (type) {
|
||||
case 'status':
|
||||
// 启用/停用
|
||||
let typeName = '', content = '', _usageStatus = '';
|
||||
|
||||
if (row.usageStatus == 1 || row.usageStatus == 5) {
|
||||
typeName = proxy.t('启用');
|
||||
content = proxy.t('确认启用该域名吗!');
|
||||
_usageStatus = 4;
|
||||
} else {
|
||||
typeName = proxy.t('停用');
|
||||
content = proxy.t('确认停用该域名吗!');
|
||||
_usageStatus = 5;
|
||||
}
|
||||
|
||||
proxy.$modal.confirm(content).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
setDownloadDomainStatus({ ids: _ids, usageStatus: _usageStatus }).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('域名') + typeName + proxy.t('成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'refresh':
|
||||
// 刷新域名解析说明
|
||||
row.refreshLoading = true;
|
||||
refreshDownloadDomainAnalysis({ id: row.id }).then(res => {
|
||||
proxy.$modal.msgSuccess(proxy.t('刷新成功!'));
|
||||
row.refreshLoading = false;
|
||||
getList();
|
||||
}).catch(() => {
|
||||
row.refreshLoading = false;
|
||||
});
|
||||
break
|
||||
case 'agent':
|
||||
// 绑定代理
|
||||
currentDomainInfo.value = row;
|
||||
isShowAgent.value = true;
|
||||
break
|
||||
case 'clearCache':
|
||||
// 清理缓存
|
||||
proxy.$modal.confirm(proxy.t('确定要清理该记录的缓存吗?')).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
clearDownloadDomainCache({ ids: _ids }).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('缓存清理成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'delete':
|
||||
// 删除域名
|
||||
proxy.$modal.confirm(proxy.t('确定要删除该域名吗!')).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
delDownloadDomain(_ids.join(',')).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('删除成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'edit':
|
||||
// 修改域名
|
||||
currentDomainInfo.value = row;
|
||||
isShowEdit.value = true;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 批量操作
|
||||
const tableRef = ref(),
|
||||
isAllSelection = ref(false), // 是否全选
|
||||
selectionData = ref([]), // 选中的表格数据
|
||||
batchOpType = ref(''); // 选中的批量操作类型
|
||||
|
||||
// 批量操作选项
|
||||
const opTypeOptions = ref([
|
||||
{ label: proxy.t('批量清理缓存'), value: 'clearCache' },
|
||||
{ label: proxy.t('批量删除'), value: 'delete' },
|
||||
{ label: proxy.t('批量停用'), value: 'stop' },
|
||||
{ label: proxy.t('批量启用'), value: 'enable' },
|
||||
{ label: proxy.t('批量展示其他担保列表'), value: 'showSecurity' },
|
||||
{ label: proxy.t('批量隐藏其他担保列表'), value: 'hideSecurity' },
|
||||
{ label: proxy.t('批量绑定代理'), value: 'bindAgent' }
|
||||
]);
|
||||
|
||||
// 勾选表格
|
||||
const tableSelect = (val) => {
|
||||
selectionData.value = val;
|
||||
|
||||
if (val.length === dataList.value.length) {
|
||||
isAllSelection.value = true;
|
||||
} else {
|
||||
isAllSelection.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 全选表格
|
||||
const allSelectionChange = () => {
|
||||
tableRef.value.toggleAllSelection();
|
||||
}
|
||||
|
||||
// 选择批量数据操作类型
|
||||
const opTypeChange = () => {
|
||||
isShowBatchOp.value = true;
|
||||
}
|
||||
|
||||
// 清空批量操作痕迹
|
||||
const clearBatchOp = () => {
|
||||
isAllSelection.value = false;
|
||||
selectionData.value = [];
|
||||
batchOpType.value = '';
|
||||
}
|
||||
|
||||
// 搜索按钮操作
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
|
||||
// 重置按钮操作
|
||||
const resetQuery = () => {
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = (type) => {
|
||||
isShowAdd.value = false; // 新增域名弹窗
|
||||
isShowAgent.value = false; // 绑定代理弹窗
|
||||
isShowEdit.value = false; // 修改域名弹窗
|
||||
isShowBatchOp.value = false; // 批量操作弹窗
|
||||
batchOpType.value = ''; // 批量操作类型
|
||||
|
||||
// 批量操作清空
|
||||
if (type === 'batchSubmit') clearBatchOp();
|
||||
// 提交后刷新列表
|
||||
if (type === 'submit' || type === 'batchSubmit') {
|
||||
getList();
|
||||
}
|
||||
}
|
||||
|
||||
// 跳转域名管理
|
||||
const emit = defineEmits(['goDomainManage']);
|
||||
const goDomainManage = () => {
|
||||
emit('goDomainManage');
|
||||
}
|
||||
|
||||
// 全局搜索展示
|
||||
watch(() => props.searchResult, (val) => {
|
||||
if (val.type == 'domainName') {
|
||||
queryParams.searchType = 'name'
|
||||
queryParams.name = val.domainName;
|
||||
|
||||
nextTick(() => {
|
||||
queryParams.domainSupplierId = val.domainSupplierId;
|
||||
handleQuery();
|
||||
});
|
||||
}
|
||||
}, { deep: true, immediate: true });
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.right-switch {
|
||||
display: inline-block;
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.domain-main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
|
||||
// 左侧
|
||||
.dm-left {
|
||||
width: 145px;
|
||||
height: 100%;
|
||||
border-right: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
// 右侧
|
||||
.dm-right {
|
||||
width: calc(100% - 160px);
|
||||
margin-left: 15px;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.copy-ml {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,403 @@
|
|||
<template>
|
||||
<!-- OSS加速域名列表 -->
|
||||
<table-search-card :model="queryParams" @getList="getList" :leftSpan="16" :rightSpan="8" @handleQuery="handleQuery()"
|
||||
@resetQuery="resetQuery">
|
||||
<template #left>
|
||||
<select-input-form :queryParamsList="queryParamsList" v-model:queryParams="queryParams" :width="[130, 260]"
|
||||
@handleQuery="handleQuery"></select-input-form>
|
||||
<el-form-item prop="usageStatus" style="width: 150px;">
|
||||
<dict-select clearable v-model="queryParams.usageStatus" :placeholder="t('使用状态')"
|
||||
dictKey="operation_domain_son_usage_status" @change="handleQuery"></dict-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template #right>
|
||||
<auto-refresh-time apiName="ossDomainList" @refreshFn="getList" style="margin-right: 10px;"></auto-refresh-time>
|
||||
<el-button type="success" plain icon="Plus" @click="openAddDomain" v-hasPermi="['operation:son:oss:add']">{{
|
||||
t('新增') }}</el-button>
|
||||
</template>
|
||||
</table-search-card>
|
||||
|
||||
<!-- 查询表格 -->
|
||||
<div class="domain-main">
|
||||
<!-- 左侧供应商 -->
|
||||
<div class="dm-left">
|
||||
<el-scrollbar max-height="600px">
|
||||
<!-- 供应商选择 -->
|
||||
<supplier-button ref="supplierRef" v-model="queryParams.domainSupplierId" @change="handleQuery"
|
||||
@getCurSupplierNode="getCurSupplierNode"></supplier-button>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
<!-- 右侧表格 -->
|
||||
<div class="dm-right">
|
||||
<el-alert v-if="currentNodeTips" style="margin-bottom: 15px;" :title="currentNodeTips" :closable="false"
|
||||
type="warning" show-icon />
|
||||
|
||||
<el-table ref="tableRef" class="c-table-main" v-loading="loading" row-key="id" stripe border :data="dataList"
|
||||
@select="tableSelect" @select-all="tableSelect">
|
||||
<el-table-column align="center" type="selection" width="55" />
|
||||
<el-table-column :label="t('CDN节点名称')" align="center" min-width="160">
|
||||
<template #default="{ row }">
|
||||
{{ row.cdnNodeName }}
|
||||
<dict-text class="c-green" dictKey="ff_operation_son_type" :value="row.sonType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" min-width="280">
|
||||
<template #header>
|
||||
<span>{{ t('生效域名') }}</span>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
{{ row.name }}<copy-icon :text="row.name" class="copy-ml"></copy-icon>
|
||||
<p :class="'c-clear ' + (row.analyzeStatus ? 'c-green' : 'c-red')">{{ row.analyzeStatus ? t('已解析') :
|
||||
t('待解析') }}</p>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" min-width="220">
|
||||
<template #header>
|
||||
<span>{{ t('解析说明(生效状态和网速)') }}</span>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<span :class="'c-clear ' + (row.analyzeInvalid ? 'c-green' : 'c-red')">{{ row.analyzeInvalid ?
|
||||
t('已生效') : t('未生效') }}</span>
|
||||
<el-icon @click="opInfo(row, 'refresh')" :class="row.refreshLoading ? 'c-rotate' : ''"
|
||||
style="position: relative; top: 4px; margin-left: 8px;" size="16" class="c-blue">
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('使用状态')" align="center" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<dict-text :colorValues="['c-grey', 'c-orange', 'c-orange', 'c-green', 'c-red']"
|
||||
dictKey="operation_domain_son_usage_status" :value="row.usageStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<table-operation></table-operation>
|
||||
<el-table-column :label="t('操作')" align="center" min-width="220" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button v-if="row.usageStatus == 4" link type="primary" @click="opInfo(row, 'clearCache')"
|
||||
v-hasPermi="['operation:son:oss:clear']">
|
||||
{{ t('清理缓存') }}
|
||||
</el-button>
|
||||
<el-tooltip v-if="row.usageStatus == 1 || row.usageStatus == 5" effect="dark"
|
||||
:content="t('提示:启用后请等待1分钟再操作')" placement="top">
|
||||
<el-button link type="primary" @click="opInfo(row, 'status')"
|
||||
v-hasPermi="['operation:son:oss:status']">
|
||||
{{ t('启用') }}
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="row.usageStatus == 2 || row.usageStatus == 3 || row.usageStatus == 4" effect="dark"
|
||||
:content="t('提示:停用后请等待1分钟再操作')" placement="top">
|
||||
<el-button link type="primary" @click="opInfo(row, 'status')"
|
||||
v-hasPermi="['operation:son:oss:status']">
|
||||
{{ t('停用') }}
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-button v-if="row.usageStatus == 1 && row.sonType != -1 && row.sonType != -2" link type="primary"
|
||||
@click="opInfo(row, 'edit')" v-hasPermi="['operation:son:oss:edit']">
|
||||
{{ t('修改') }}
|
||||
</el-button>
|
||||
<el-button v-if="row.usageStatus == 1 || row.usageStatus == 5" link type="primary"
|
||||
@click="opInfo(row, 'delete')" v-hasPermi="['operation:son:oss:remove']">
|
||||
{{ t('删除') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 批量操作 -->
|
||||
<table-batch-operate v-if="total > 0" v-model:batchOpType="batchOpType" v-model:isAllSelection="isAllSelection"
|
||||
@allSelectionChange="allSelectionChange" @opTypeChange="opTypeChange" :selectionData="selectionData"
|
||||
:opTypeOptions="opTypeOptions"></table-batch-operate>
|
||||
<!-- 列表分页 -->
|
||||
<pagination v-if="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 新增域名弹窗 -->
|
||||
<add-son-domain v-if="isShowAdd" type="oss" :supplierList="supplierList" @goDomainManage="goDomainManage"
|
||||
@closeDialog="closeDialog"></add-son-domain>
|
||||
|
||||
<!-- 修改域名弹窗 -->
|
||||
<edit-son-domain v-if="isShowEdit" type="oss" :currentDomainInfo="currentDomainInfo"
|
||||
@closeDialog="closeDialog"></edit-son-domain>
|
||||
|
||||
<!-- 批量操作弹窗 -->
|
||||
<batch-operation v-if="isShowBatchOp" type="oss" :batchOpType="batchOpType" :selectionData="selectionData"
|
||||
@closeDialog="closeDialog"></batch-operation>
|
||||
</template>
|
||||
|
||||
<script setup name="OssList">
|
||||
import {
|
||||
getOssDomainList, // 域名列表
|
||||
refreshOssDomainAnalysis, // 刷新解析说明
|
||||
setOssDomainStatus, // 域名状态切换
|
||||
clearOssDomainCache, // 清理缓存
|
||||
delOssDomain // 删除域名
|
||||
} from "@/api/operation/domain";
|
||||
import AutoRefreshTime from "@/components/AutoRefreshTime"; // 定时刷新
|
||||
import CopyIcon from "@/components/CopyIcon"; // 小图标复制
|
||||
import TableBatchOperate from '@/components/TableBatchOperate'; // 批量操作
|
||||
import SupplierButton from "../components/SupplierButton.vue"; // 供应商选择按钮
|
||||
import AddSonDomain from "../components/AddSonDomain.vue"; // 新增子域名弹窗
|
||||
import EditSonDomain from "../components/EditSonDomain.vue"; // 修改子域名弹窗
|
||||
import BatchOperation from "../components/BatchOperation.vue"; // 批量操作弹窗
|
||||
|
||||
const props = defineProps({
|
||||
// 全局搜索结果
|
||||
searchResult: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const loading = ref(true); // loading状态
|
||||
const isShowAdd = ref(false), isShowEdit = ref(false), isShowBatchOp = ref(false); // 各弹窗状态
|
||||
|
||||
// 获取供应商节点信息
|
||||
const supplierRef = ref(null), currentNodeTips = ref(''), supplierList = ref([]);
|
||||
const getCurSupplierNode = (data) => {
|
||||
currentNodeTips.value = data?.tips;
|
||||
}
|
||||
|
||||
// 根据下拉框条件输入搜索
|
||||
const queryParamsList = ref([{
|
||||
label: proxy.t('操作人'),
|
||||
value: 'updateBy'
|
||||
}, {
|
||||
label: proxy.t('子域名'),
|
||||
value: 'name'
|
||||
}]);
|
||||
|
||||
// 搜索配置
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
searchType: 'updateBy',
|
||||
name: '', // 子域名
|
||||
updateBy: '', // 操作人
|
||||
usageStatus: '', // 使用状态
|
||||
orderByColumn: 'createTime',
|
||||
isAsc: 'desc',
|
||||
domainSupplierId: '' // 供应商
|
||||
});
|
||||
|
||||
// 请求列表
|
||||
const dataList = ref([]), total = ref(0);
|
||||
const getList = () => {
|
||||
loading.value = true;
|
||||
|
||||
getOssDomainList(queryParams).then(res => {
|
||||
loading.value = false;
|
||||
dataList.value = res.rows;
|
||||
total.value = +res.total;
|
||||
clearBatchOp(); // 清空批量操作痕迹
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
dataList.value = [];
|
||||
total.value = 0;
|
||||
clearBatchOp(); // 清空批量操作痕迹
|
||||
});
|
||||
}
|
||||
getList();
|
||||
|
||||
// 新增域名
|
||||
const openAddDomain = () => {
|
||||
supplierList.value = supplierRef.value?.supplierList.filter(v => v.isOpen && !v.stopStatus); // 已开通且不是维护状态的供应商
|
||||
isShowAdd.value = true;
|
||||
}
|
||||
|
||||
// 操作信息
|
||||
const currentDomainInfo = ref({}); // 当前操作的域名信息
|
||||
const opInfo = (row, type) => {
|
||||
const _ids = row.id ? [row.id] : row; // 操作的id,有表格内点击和批量操作两种
|
||||
|
||||
switch (type) {
|
||||
case 'status':
|
||||
// 启用/停用
|
||||
let typeName = '', content = '', _usageStatus = '';
|
||||
|
||||
if (row.usageStatus == 1 || row.usageStatus == 5) {
|
||||
typeName = proxy.t('启用');
|
||||
content = proxy.t('确认启用该域名吗!');
|
||||
_usageStatus = 4;
|
||||
} else {
|
||||
typeName = proxy.t('停用');
|
||||
content = proxy.t('确认停用该域名吗!');
|
||||
_usageStatus = 5;
|
||||
}
|
||||
|
||||
proxy.$modal.confirm(content).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
setOssDomainStatus({ ids: _ids, usageStatus: _usageStatus }).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('域名') + typeName + proxy.t('成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'refresh':
|
||||
// 刷新域名解析说明
|
||||
row.refreshLoading = true;
|
||||
refreshOssDomainAnalysis({ id: row.id }).then(res => {
|
||||
proxy.$modal.msgSuccess(proxy.t('刷新成功!'));
|
||||
row.refreshLoading = false;
|
||||
getList();
|
||||
}).catch(() => {
|
||||
row.refreshLoading = false;
|
||||
});
|
||||
break
|
||||
case 'clearCache':
|
||||
// 清理缓存
|
||||
proxy.$modal.confirm(proxy.t('确定要清理该记录的缓存吗?')).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
clearOssDomainCache({ ids: _ids }).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('缓存清理成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'delete':
|
||||
// 删除域名
|
||||
proxy.$modal.confirm(proxy.t('确定要删除该域名吗!')).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
delOssDomain(_ids.join(',')).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('删除成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'edit':
|
||||
// 修改域名
|
||||
currentDomainInfo.value = row;
|
||||
isShowEdit.value = true;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 批量操作
|
||||
const tableRef = ref(),
|
||||
isAllSelection = ref(false), // 是否全选
|
||||
selectionData = ref([]), // 选中的表格数据
|
||||
batchOpType = ref(''); // 选中的批量操作类型
|
||||
|
||||
// 批量操作选项
|
||||
const opTypeOptions = ref([
|
||||
{ label: proxy.t('批量清理缓存'), value: 'clearCache' },
|
||||
{ label: proxy.t('批量删除'), value: 'delete' },
|
||||
{ label: proxy.t('批量停用'), value: 'stop' },
|
||||
{ label: proxy.t('批量启用'), value: 'enable' }
|
||||
]);
|
||||
|
||||
// 勾选表格
|
||||
const tableSelect = (val) => {
|
||||
selectionData.value = val;
|
||||
|
||||
if (val.length === dataList.value.length) {
|
||||
isAllSelection.value = true;
|
||||
} else {
|
||||
isAllSelection.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 全选表格
|
||||
const allSelectionChange = () => {
|
||||
tableRef.value.toggleAllSelection();
|
||||
}
|
||||
|
||||
// 选择批量数据操作类型
|
||||
const opTypeChange = () => {
|
||||
isShowBatchOp.value = true;
|
||||
}
|
||||
|
||||
// 清空批量操作痕迹
|
||||
const clearBatchOp = () => {
|
||||
isAllSelection.value = false;
|
||||
selectionData.value = [];
|
||||
batchOpType.value = '';
|
||||
}
|
||||
|
||||
// 搜索按钮操作
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
|
||||
// 重置按钮操作
|
||||
const resetQuery = () => {
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = (type) => {
|
||||
isShowAdd.value = false; // 新增域名弹窗
|
||||
isShowEdit.value = false; // 修改域名弹窗
|
||||
isShowBatchOp.value = false; // 批量操作弹窗
|
||||
batchOpType.value = ''; // 批量操作类型
|
||||
|
||||
// 批量操作清空
|
||||
if (type === 'batchSubmit') clearBatchOp();
|
||||
// 提交后刷新列表
|
||||
if (type === 'submit' || type === 'batchSubmit') {
|
||||
getList();
|
||||
}
|
||||
}
|
||||
|
||||
// 跳转域名管理
|
||||
const emit = defineEmits(['goDomainManage']);
|
||||
const goDomainManage = () => {
|
||||
emit('goDomainManage');
|
||||
}
|
||||
|
||||
// 全局搜索展示
|
||||
watch(() => props.searchResult, (val) => {
|
||||
if (val.type == 'domainName') {
|
||||
queryParams.searchType = 'name'
|
||||
queryParams.name = val.domainName;
|
||||
|
||||
nextTick(() => {
|
||||
queryParams.domainSupplierId = val.domainSupplierId;
|
||||
handleQuery();
|
||||
});
|
||||
}
|
||||
}, { deep: true, immediate: true });
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.domain-main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
|
||||
// 左侧
|
||||
.dm-left {
|
||||
width: 145px;
|
||||
height: 100%;
|
||||
border-right: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
// 右侧
|
||||
.dm-right {
|
||||
width: calc(100% - 160px);
|
||||
margin-left: 15px;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.copy-ml {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,422 @@
|
|||
<template>
|
||||
<!-- 支付域名列表 -->
|
||||
<table-search-card :model="queryParams" @getList="getList" :leftSpan="16" :rightSpan="8" @handleQuery="handleQuery()"
|
||||
@resetQuery="resetQuery">
|
||||
<template #left>
|
||||
<select-input-form :queryParamsList="queryParamsList" v-model:queryParams="queryParams" :width="[130, 260]"
|
||||
@handleQuery="handleQuery"></select-input-form>
|
||||
<el-form-item prop="usageStatus" style="width: 150px;">
|
||||
<dict-select clearable v-model="queryParams.usageStatus" :placeholder="t('使用状态')"
|
||||
dictKey="operation_domain_son_usage_status" @change="handleQuery"></dict-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template #right>
|
||||
<auto-refresh-time apiName="paymentDomainList" @refreshFn="getList" style="margin-right: 10px;"></auto-refresh-time>
|
||||
<el-button type="success" plain icon="Plus" @click="openAddDomain" v-hasPermi="['operation:son:pay:add']">{{
|
||||
t('新增') }}</el-button>
|
||||
</template>
|
||||
</table-search-card>
|
||||
|
||||
<!-- 查询表格 -->
|
||||
<div class="domain-main">
|
||||
<!-- 左侧供应商 -->
|
||||
<div class="dm-left">
|
||||
<el-scrollbar max-height="600px">
|
||||
<!-- 供应商选择 -->
|
||||
<supplier-button ref="supplierRef" v-model="queryParams.domainSupplierId" @change="handleQuery"
|
||||
@getCurSupplierNode="getCurSupplierNode"></supplier-button>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
<!-- 右侧表格 -->
|
||||
<div class="dm-right">
|
||||
<el-alert v-if="currentNodeTips" style="margin-bottom: 15px;" :title="currentNodeTips" :closable="false"
|
||||
type="warning" show-icon />
|
||||
|
||||
<el-table ref="tableRef" class="c-table-main" v-loading="loading" row-key="id" stripe border :data="dataList"
|
||||
@select="tableSelect" @select-all="tableSelect">
|
||||
<el-table-column align="center" type="selection" width="55" />
|
||||
<el-table-column :label="t('CDN节点名称')" align="center" min-width="160">
|
||||
<template #default="{ row }">
|
||||
{{ row.cdnNodeName }}
|
||||
<dict-text class="c-green" dictKey="ff_operation_son_type" :value="row.sonType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" min-width="280">
|
||||
<template #header>
|
||||
<span>{{ t('生效域名') }}</span>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
{{ row.name }}<copy-icon :text="row.name" class="copy-ml"></copy-icon>
|
||||
<p :class="'c-clear ' + (row.analyzeStatus ? 'c-green' : 'c-red')">{{ row.analyzeStatus ? t('已解析') :
|
||||
t('待解析') }}</p>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" min-width="220">
|
||||
<template #header>
|
||||
<span>{{ t('解析说明(生效状态和网速)') }}</span>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<span :class="'c-clear ' + (row.analyzeInvalid ? 'c-green' : 'c-red')">{{ row.analyzeInvalid ?
|
||||
t('已生效') : t('未生效') }}</span>
|
||||
<el-icon @click="opInfo(row, 'refresh')" :class="row.refreshLoading ? 'c-rotate' : ''"
|
||||
style="position: relative; top: 4px; margin-left: 8px;" size="16" class="c-blue">
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('使用状态')" align="center" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<dict-text :colorValues="['c-grey', 'c-orange', 'c-orange', 'c-green', 'c-red']"
|
||||
dictKey="operation_domain_son_usage_status" :value="row.usageStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<table-operation></table-operation>
|
||||
<el-table-column :label="t('操作')" align="center" min-width="220" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button v-if="row.usageStatus == 4 && !row.mainSon" link type="primary" @click="opInfo(row, 'main')"
|
||||
v-hasPermi="['operation:son:pay:main']">
|
||||
{{ t('设为主域名') }}
|
||||
</el-button>
|
||||
<el-button v-if="row.usageStatus == 4" link type="primary" @click="opInfo(row, 'clearCache')"
|
||||
v-hasPermi="['operation:son:pay:clear']">
|
||||
{{ t('清理缓存') }}
|
||||
</el-button>
|
||||
<el-tooltip v-if="row.usageStatus == 1 || row.usageStatus == 5" effect="dark"
|
||||
:content="t('提示:启用后请等待1分钟再操作')" placement="top">
|
||||
<el-button link type="primary" @click="opInfo(row, 'status')"
|
||||
v-hasPermi="['operation:son:pay:status']">
|
||||
{{ t('启用') }}
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="row.usageStatus == 2 || row.usageStatus == 3 || row.usageStatus == 4" effect="dark"
|
||||
:content="t('提示:停用后请等待1分钟再操作')" placement="top">
|
||||
<el-button link type="primary" @click="opInfo(row, 'status')"
|
||||
v-hasPermi="['operation:son:pay:status']">
|
||||
{{ t('停用') }}
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-button v-if="row.usageStatus == 1 && row.sonType != -1 && row.sonType != -2" link type="primary"
|
||||
@click="opInfo(row, 'edit')" v-hasPermi="['operation:son:pay:edit']">
|
||||
{{ t('修改') }}
|
||||
</el-button>
|
||||
<el-button v-if="row.usageStatus == 1 || row.usageStatus == 5" link type="primary"
|
||||
@click="opInfo(row, 'delete')" v-hasPermi="['operation:son:pay:remove']">
|
||||
{{ t('删除') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 批量操作 -->
|
||||
<table-batch-operate v-if="total > 0" v-model:batchOpType="batchOpType" v-model:isAllSelection="isAllSelection"
|
||||
@allSelectionChange="allSelectionChange" @opTypeChange="opTypeChange" :selectionData="selectionData"
|
||||
:opTypeOptions="opTypeOptions"></table-batch-operate>
|
||||
<!-- 列表分页 -->
|
||||
<pagination v-if="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 新增域名弹窗 -->
|
||||
<add-son-domain v-if="isShowAdd" type="payment" :supplierList="supplierList" @goDomainManage="goDomainManage"
|
||||
@closeDialog="closeDialog"></add-son-domain>
|
||||
|
||||
<!-- 修改域名弹窗 -->
|
||||
<edit-son-domain v-if="isShowEdit" type="payment" :currentDomainInfo="currentDomainInfo"
|
||||
@closeDialog="closeDialog"></edit-son-domain>
|
||||
|
||||
<!-- 批量操作弹窗 -->
|
||||
<batch-operation v-if="isShowBatchOp" type="payment" :batchOpType="batchOpType" :selectionData="selectionData"
|
||||
@closeDialog="closeDialog"></batch-operation>
|
||||
</template>
|
||||
|
||||
<script setup name="PaymentList">
|
||||
import {
|
||||
getPayDomainList, // 域名列表
|
||||
setPayDomainMain, // 主域名设置
|
||||
refreshPayDomainAnalysis, // 刷新解析说明
|
||||
setPayDomainStatus, // 域名状态切换
|
||||
clearPayDomainCache, // 清理缓存
|
||||
delPayDomain // 删除域名
|
||||
} from "@/api/operation/domain";
|
||||
import AutoRefreshTime from "@/components/AutoRefreshTime"; // 定时刷新
|
||||
import CopyIcon from "@/components/CopyIcon"; // 小图标复制
|
||||
import TableBatchOperate from '@/components/TableBatchOperate'; // 批量操作
|
||||
import SupplierButton from "../components/SupplierButton.vue"; // 供应商选择按钮
|
||||
import AddSonDomain from "../components/AddSonDomain.vue"; // 新增子域名弹窗
|
||||
import EditSonDomain from "../components/EditSonDomain.vue"; // 修改子域名弹窗
|
||||
import BatchOperation from "../components/BatchOperation.vue"; // 批量操作弹窗
|
||||
|
||||
const props = defineProps({
|
||||
// 全局搜索结果
|
||||
searchResult: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const loading = ref(true); // loading状态
|
||||
const isShowAdd = ref(false), isShowEdit = ref(false), isShowBatchOp = ref(false); // 各弹窗状态
|
||||
|
||||
// 获取供应商节点信息
|
||||
const supplierRef = ref(null), currentNodeTips = ref(''), supplierList = ref([]);
|
||||
const getCurSupplierNode = (data) => {
|
||||
currentNodeTips.value = data?.tips;
|
||||
}
|
||||
|
||||
// 根据下拉框条件输入搜索
|
||||
const queryParamsList = ref([{
|
||||
label: proxy.t('操作人'),
|
||||
value: 'updateBy'
|
||||
}, {
|
||||
label: proxy.t('子域名'),
|
||||
value: 'name'
|
||||
}]);
|
||||
|
||||
// 搜索配置
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
searchType: 'updateBy',
|
||||
name: '', // 子域名
|
||||
updateBy: '', // 操作人
|
||||
usageStatus: '', // 使用状态
|
||||
orderByColumn: 'createTime',
|
||||
isAsc: 'desc',
|
||||
domainSupplierId: '' // 供应商
|
||||
});
|
||||
|
||||
// 请求列表
|
||||
const dataList = ref([]), total = ref(0);
|
||||
const getList = () => {
|
||||
loading.value = true;
|
||||
|
||||
getPayDomainList(queryParams).then(res => {
|
||||
loading.value = false;
|
||||
dataList.value = res.rows;
|
||||
total.value = +res.total;
|
||||
clearBatchOp(); // 清空批量操作痕迹
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
dataList.value = [];
|
||||
total.value = 0;
|
||||
clearBatchOp(); // 清空批量操作痕迹
|
||||
});
|
||||
}
|
||||
getList();
|
||||
|
||||
// 新增域名
|
||||
const openAddDomain = () => {
|
||||
supplierList.value = supplierRef.value?.supplierList.filter(v => v.isOpen && !v.stopStatus); // 已开通且不是维护状态的供应商
|
||||
isShowAdd.value = true;
|
||||
}
|
||||
|
||||
// 操作信息
|
||||
const currentDomainInfo = ref({}); // 当前操作的域名信息
|
||||
const opInfo = (row, type) => {
|
||||
const _ids = row.id ? [row.id] : row; // 操作的id,有表格内点击和批量操作两种
|
||||
|
||||
switch (type) {
|
||||
case'main':
|
||||
// 设为主域名
|
||||
proxy.$modal.confirm(proxy.t('确定要设置为主域名吗?')).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
setPayDomainMain({ id: row.id }).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('设置成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'status':
|
||||
// 启用/停用
|
||||
let typeName = '', content = '', _usageStatus = '';
|
||||
|
||||
if (row.usageStatus == 1 || row.usageStatus == 5) {
|
||||
typeName = proxy.t('启用');
|
||||
content = proxy.t('确认启用该域名吗!');
|
||||
_usageStatus = 4;
|
||||
} else {
|
||||
typeName = proxy.t('停用');
|
||||
content = proxy.t('确认停用该域名吗!');
|
||||
_usageStatus = 5;
|
||||
}
|
||||
|
||||
proxy.$modal.confirm(content).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
setPayDomainStatus({ ids: _ids, usageStatus: _usageStatus }).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('域名') + typeName + proxy.t('成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'refresh':
|
||||
// 刷新域名解析说明
|
||||
row.refreshLoading = true;
|
||||
refreshPayDomainAnalysis({ id: row.id }).then(res => {
|
||||
proxy.$modal.msgSuccess(proxy.t('刷新成功!'));
|
||||
row.refreshLoading = false;
|
||||
getList();
|
||||
}).catch(() => {
|
||||
row.refreshLoading = false;
|
||||
});
|
||||
break
|
||||
case 'clearCache':
|
||||
// 清理缓存
|
||||
proxy.$modal.confirm(proxy.t('确定要清理该记录的缓存吗?')).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
clearPayDomainCache({ ids: _ids }).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('缓存清理成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'delete':
|
||||
// 删除域名
|
||||
proxy.$modal.confirm(proxy.t('确定要删除该域名吗!')).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
delPayDomain(_ids.join(',')).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('删除成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'edit':
|
||||
// 修改域名
|
||||
currentDomainInfo.value = row;
|
||||
isShowEdit.value = true;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 批量操作
|
||||
const tableRef = ref(),
|
||||
isAllSelection = ref(false), // 是否全选
|
||||
selectionData = ref([]), // 选中的表格数据
|
||||
batchOpType = ref(''); // 选中的批量操作类型
|
||||
|
||||
// 批量操作选项
|
||||
const opTypeOptions = ref([
|
||||
{ label: proxy.t('批量清理缓存'), value: 'clearCache' },
|
||||
{ label: proxy.t('批量删除'), value: 'delete' },
|
||||
{ label: proxy.t('批量停用'), value: 'stop' },
|
||||
{ label: proxy.t('批量启用'), value: 'enable' }
|
||||
]);
|
||||
|
||||
// 勾选表格
|
||||
const tableSelect = (val) => {
|
||||
selectionData.value = val;
|
||||
|
||||
if (val.length === dataList.value.length) {
|
||||
isAllSelection.value = true;
|
||||
} else {
|
||||
isAllSelection.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 全选表格
|
||||
const allSelectionChange = () => {
|
||||
tableRef.value.toggleAllSelection();
|
||||
}
|
||||
|
||||
// 选择批量数据操作类型
|
||||
const opTypeChange = () => {
|
||||
isShowBatchOp.value = true;
|
||||
}
|
||||
|
||||
// 清空批量操作痕迹
|
||||
const clearBatchOp = () => {
|
||||
isAllSelection.value = false;
|
||||
selectionData.value = [];
|
||||
batchOpType.value = '';
|
||||
}
|
||||
|
||||
// 搜索按钮操作
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
|
||||
// 重置按钮操作
|
||||
const resetQuery = () => {
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = (type) => {
|
||||
isShowAdd.value = false; // 新增域名弹窗
|
||||
isShowEdit.value = false; // 修改域名弹窗
|
||||
isShowBatchOp.value = false; // 批量操作弹窗
|
||||
batchOpType.value = ''; // 批量操作类型
|
||||
|
||||
// 批量操作清空
|
||||
if (type === 'batchSubmit') clearBatchOp();
|
||||
// 提交后刷新列表
|
||||
if (type === 'submit' || type === 'batchSubmit') {
|
||||
getList();
|
||||
}
|
||||
}
|
||||
|
||||
// 跳转域名管理
|
||||
const emit = defineEmits(['goDomainManage']);
|
||||
const goDomainManage = () => {
|
||||
emit('goDomainManage');
|
||||
}
|
||||
|
||||
// 全局搜索展示
|
||||
watch(() => props.searchResult, (val) => {
|
||||
if (val.type == 'domainName') {
|
||||
queryParams.searchType = 'name'
|
||||
queryParams.name = val.domainName;
|
||||
|
||||
nextTick(() => {
|
||||
queryParams.domainSupplierId = val.domainSupplierId;
|
||||
handleQuery();
|
||||
});
|
||||
}
|
||||
}, { deep: true, immediate: true });
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.domain-main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
|
||||
// 左侧
|
||||
.dm-left {
|
||||
width: 145px;
|
||||
height: 100%;
|
||||
border-right: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
// 右侧
|
||||
.dm-right {
|
||||
width: calc(100% - 160px);
|
||||
margin-left: 15px;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.copy-ml {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,645 @@
|
|||
<template>
|
||||
<!-- web大厅域名列表 -->
|
||||
<table-search-card :model="queryParams" @getList="getList" :leftSpan="16" :rightSpan="8" @handleQuery="handleQuery()"
|
||||
@resetQuery="resetQuery">
|
||||
<template #left>
|
||||
<select-input-form :queryParamsList="queryParamsList" v-model:queryParams="queryParams" :width="[130, 260]"
|
||||
@handleQuery="handleQuery"></select-input-form>
|
||||
<el-form-item prop="usageStatus" style="width: 150px;">
|
||||
<dict-select clearable v-model="queryParams.usageStatus" :placeholder="t('使用状态')"
|
||||
dictKey="operation_domain_son_usage_status" @change="handleQuery"></dict-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template #right>
|
||||
<span class="right-switch" v-if="h5InterceptOpen > 0">
|
||||
{{ t('H5防拦截开关') }}
|
||||
<icon-tips>
|
||||
<p class="c-clear" style="width: 400px;">
|
||||
{{ t('说明:(大陆推荐开启) 同品牌与SEO管理--防拦截模式开关功能同步,因该功能将隐藏敏感信息,所以开启后普通SEO和专业SEO将失效,且无法使用') }}
|
||||
</p>
|
||||
</icon-tips>
|
||||
<base-switch style="margin: 0 12px 0 5px;" :active-value="1" :inactive-value="2" v-model="h5InterceptOpen"
|
||||
:tipText="t('确认') + (h5InterceptOpen == 2 ? t('开启') : t('关闭')) + t('H5防拦截吗?')"
|
||||
:before-change="() => configSwitchChange('h5InterceptOpen')"
|
||||
v-hasPermi="['operation:son:web:system:edit']"></base-switch>
|
||||
</span>
|
||||
<auto-refresh-time apiName="webDomainList" @refreshFn="getList"
|
||||
style="margin-right: 10px;"></auto-refresh-time>
|
||||
<el-button type="success" plain icon="Plus" @click="openAddDomain" v-hasPermi="['operation:son:web:add']">{{
|
||||
t('新增') }}</el-button>
|
||||
</template>
|
||||
</table-search-card>
|
||||
|
||||
<!-- 查询表格 -->
|
||||
<div class="domain-main">
|
||||
<!-- 左侧供应商 -->
|
||||
<div class="dm-left">
|
||||
<el-scrollbar max-height="600px">
|
||||
<!-- 供应商选择 -->
|
||||
<supplier-button ref="supplierRef" v-model="queryParams.domainSupplierId" @change="handleQuery"
|
||||
@getCurSupplierNode="getCurSupplierNode"></supplier-button>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
<!-- 右侧表格 -->
|
||||
<div class="dm-right">
|
||||
<el-alert v-if="currentNodeTips" style="margin-bottom: 15px;" :title="currentNodeTips" :closable="false"
|
||||
type="warning" show-icon />
|
||||
|
||||
<el-table ref="tableRef" class="c-table-main" v-loading="loading" row-key="id" stripe border :data="dataList"
|
||||
@select="tableSelect" @select-all="tableSelect">
|
||||
<el-table-column align="center" type="selection" width="55" />
|
||||
<el-table-column :label="t('CDN节点名称')" align="center" min-width="160">
|
||||
<template #default="{ row }">
|
||||
{{ row.cdnNodeName }}
|
||||
<dict-text class="c-green" dictKey="ff_operation_son_type" :value="row.sonType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" min-width="280">
|
||||
<template #header>
|
||||
<span>{{ t('生效域名') }}</span>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
{{ row.name }}<copy-icon :text="row.name" class="copy-ml"></copy-icon>
|
||||
<p :class="'c-clear ' + (row.analyzeStatus ? 'c-green' : 'c-red')">{{ row.analyzeStatus ? t('已解析') :
|
||||
t('待解析') }}</p>
|
||||
<p v-if="row.operationDomainSonDns.length !=0">
|
||||
<div v-for="(item,index) in row.operationDomainSonDns">
|
||||
{{ t('DNS修改为以下服务器后刷新解析:') }} {{ item.typeValue }}:{{ item.value }}
|
||||
</div>
|
||||
</p>
|
||||
<p v-if="row.analyzeStatu && row.operationDomainSonDns.length !=0">
|
||||
<div v-for="(item,index) in row.operationDomainSonDns">
|
||||
{{ t('已解析完成:') }} {{ item.typeValue }}:{{ item.value }}
|
||||
</div>
|
||||
</p>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('端口类型')" align="center" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<dict-text dictKey="ff_operation_domain_son_port_type" :value="row.portType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('端口号')" prop="portValue" align="center" min-width="120"></el-table-column>
|
||||
<el-table-column align="center" min-width="220">
|
||||
<template #header>
|
||||
<span>{{ t('解析说明(生效状态和网速)') }}</span>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<span :class="'c-clear ' + (row.analyzeInvalid ? 'c-green' : 'c-red')">{{ row.analyzeInvalid ?
|
||||
t('已生效') : t('未生效') }}</span>
|
||||
<el-icon @click="opInfo(row, 'refresh')" :class="row.refreshLoading ? 'c-rotate' : ''"
|
||||
style="position: relative; top: 4px; margin-left: 8px;" size="16" class="c-blue">
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" min-width="160">
|
||||
<template #header>
|
||||
<span>{{ t('其他担保域名列表') }}</span>
|
||||
<icon-tips>
|
||||
<p class="c-clear" style="width: 400px;">
|
||||
{{ t('1.展示:即会员验证担保域名后,会展示一些站点的其他域名列表,方便会员保存记录、找到回家路或信任其他域名(推荐无封锁的国家)。') }}<br />
|
||||
{{ t('2.隐藏:即会员验证担保域名后,只能看到当前域名的验证结果,看不到其他域名列表,防止域名全部暴露,有被拦截和举报的风险。') }}
|
||||
</p>
|
||||
</icon-tips>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<base-switch :active-value="true" :inactive-value="false" v-model="row.backupDomain"
|
||||
:tipText="row.status ? t('确认隐藏吗?') : t('确认展示吗?')" :disabled="row.usageStatus != 4"
|
||||
:before-change="() => beforeSwitchChange(row, 'backupDomain')"></base-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" min-width="160">
|
||||
<template #header>
|
||||
<span>{{ t('作为推广域名') }}</span>
|
||||
<icon-tips>
|
||||
{{ t('开启作为前台代理推广域名显示,且建议保持一条域名开启') }}
|
||||
</icon-tips>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<base-switch :active-value="true" :inactive-value="false" v-model="row.marketingDomain"
|
||||
:tipText="row.status ? t('确认关闭吗?') : t('确认开启吗?')"
|
||||
:disabled="row.startEntrance == 2 || row.usageStatus != 4"
|
||||
:before-change="() => beforeSwitchChange(row, 'marketingDomain')"></base-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" min-width="150">
|
||||
<template #header>
|
||||
<span>{{ t('强制绑定代理') }}</span>
|
||||
<icon-tips>
|
||||
<p class="c-clear" style="width: 400px;">
|
||||
{{ t('代理上级归属优先级:推广链接的上级 > 渠道ID的强制绑定上级 > 域名管理的强制绑定上级(无上级时,域名管理的才生效)') }}
|
||||
</p>
|
||||
</icon-tips>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.agentAccount" class="c-blue" @click="goRoute(row, 'agentAccount')">{{
|
||||
row.agentAccount }}</span>
|
||||
<span v-else>{{ t('无') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" min-width="150">
|
||||
<template #header>
|
||||
<span>{{ t('启用入口') }}</span>
|
||||
<icon-tips>
|
||||
<p class="c-clear" style="width: 400px;">
|
||||
{{ t('1.全部(默认,不限制)') }} <br />
|
||||
{{ t('2.仅极速APP(无法直接访问网址)') }} <br />
|
||||
{{ t('3.H5和PWA(H5和PWA可以访问网址,但不会出现在轮巡列表)') }} <br />
|
||||
{{ t('4.支持CDN节点:阿里云,Funnull,Cloudflare,YunDun,WangSu,腾讯云,CloudFront') }}
|
||||
</p>
|
||||
</icon-tips>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<dict-select class="w100" v-model="row.startEntrance" dictKey="ff_operation_start_entrance"
|
||||
@change="changeRowStatus(row, 'startEntrance')" :disabled="row.usageStatus != 4"></dict-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" min-width="150">
|
||||
<template #header>
|
||||
<span>{{ t('屏蔽设备') }}</span>
|
||||
<icon-tips>
|
||||
<p class="c-clear" style="width: 400px;">
|
||||
{{ t('1.都不屏蔽(默认)') }} <br />
|
||||
{{ t('2.屏蔽PC端(移动端-安卓/ios可访问,PC电脑端不可访问)') }} <br />
|
||||
{{ t('3.屏蔽手机端(PC电脑端可访问,移动端-安卓/ios不可访问)') }} <br />
|
||||
{{ t('4.支持CDN节点:阿里云,Funnull,Cloudflare,YunDun,WangSu,腾讯云,CloudFront') }}
|
||||
</p>
|
||||
</icon-tips>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<dict-select class="w100" v-model="row.blockDevice" dictKey="ff_operation_block_device"
|
||||
@change="changeRowStatus(row, 'blockDevice')"
|
||||
:disabled="row.usageStatus != 4 || row.startEntrance == 2"></dict-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('使用状态')" align="center" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<dict-text :colorValues="['c-grey', 'c-orange', 'c-orange', 'c-green', 'c-red']"
|
||||
dictKey="operation_domain_son_usage_status" :value="row.usageStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<table-operation></table-operation>
|
||||
<el-table-column :label="t('操作')" align="center" min-width="220" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button v-if="row.usageStatus == 4" link type="primary" @click="opInfo(row, 'agent')"
|
||||
v-hasPermi="['operation:son:web:agent']">
|
||||
{{ t('绑定代理') }}
|
||||
</el-button>
|
||||
<el-button v-if="row.usageStatus == 4" link type="primary" @click="opInfo(row, 'clearCache')"
|
||||
v-hasPermi="['operation:son:web:clear']">
|
||||
{{ t('清理缓存') }}
|
||||
</el-button>
|
||||
<el-tooltip v-if="row.usageStatus == 1 || row.usageStatus == 5" effect="dark"
|
||||
:content="t('提示:启用后请等待1分钟再操作')" placement="top">
|
||||
<el-button link type="primary" @click="opInfo(row, 'status')"
|
||||
v-hasPermi="['operation:son:web:status']">
|
||||
{{ t('启用') }}
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-if="row.usageStatus == 2 || row.usageStatus == 3 || row.usageStatus == 4" effect="dark"
|
||||
:content="t('提示:停用后请等待1分钟再操作')" placement="top">
|
||||
<el-button link type="primary" @click="opInfo(row, 'status')"
|
||||
v-hasPermi="['operation:son:web:status']">
|
||||
{{ t('停用') }}
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-button v-if="row.usageStatus == 1 && row.sonType != -1 && row.sonType != -2" link type="primary"
|
||||
@click="opInfo(row, 'edit')" v-hasPermi="['operation:son:web:edit']">
|
||||
{{ t('修改') }}
|
||||
</el-button>
|
||||
<el-button v-if="row.usageStatus == 1 || row.usageStatus == 5" link type="primary"
|
||||
@click="opInfo(row, 'delete')" v-hasPermi="['operation:son:web:remove']">
|
||||
{{ t('删除') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 批量操作 -->
|
||||
<table-batch-operate v-if="total > 0" v-model:batchOpType="batchOpType" v-model:isAllSelection="isAllSelection"
|
||||
@allSelectionChange="allSelectionChange" @opTypeChange="opTypeChange" :selectionData="selectionData"
|
||||
:opTypeOptions="opTypeOptions"></table-batch-operate>
|
||||
<!-- 列表分页 -->
|
||||
<pagination v-if="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 新增域名弹窗 -->
|
||||
<add-son-domain v-if="isShowAdd" type="webHall" :supplierList="supplierList" @goDomainManage="goDomainManage"
|
||||
@closeDialog="closeDialog"></add-son-domain>
|
||||
|
||||
<!-- 修改域名弹窗 -->
|
||||
<edit-son-domain v-if="isShowEdit" type="webHall" :currentDomainInfo="currentDomainInfo"
|
||||
@closeDialog="closeDialog"></edit-son-domain>
|
||||
|
||||
<!-- 绑定代理弹窗 -->
|
||||
<bind-agent v-if="isShowAgent" type="webHall" :currentDomainInfo="currentDomainInfo"
|
||||
@closeDialog="closeDialog"></bind-agent>
|
||||
|
||||
<!-- 批量操作弹窗 -->
|
||||
<batch-operation v-if="isShowBatchOp" type="webHall" :batchOpType="batchOpType" :selectionData="selectionData"
|
||||
@closeDialog="closeDialog"></batch-operation>
|
||||
</template>
|
||||
|
||||
<script setup name="WebHallList">
|
||||
import {
|
||||
getWebDomainList, // 域名列表
|
||||
refreshWebDomainAnalysis, // 刷新解析说明
|
||||
webDomainSwitch, // 开关切换
|
||||
setWebDomainStatus, // 域名状态切换
|
||||
clearWebDomainCache, // 清理缓存
|
||||
delWebDomain, // 删除域名
|
||||
getWebSystemParam, // 获取系统参数
|
||||
updateWebSystemParam // 更新系统参数
|
||||
} from "@/api/operation/domain";
|
||||
import AutoRefreshTime from "@/components/AutoRefreshTime"; // 定时刷新
|
||||
import CopyIcon from "@/components/CopyIcon"; // 小图标复制
|
||||
import IconTips from "@/components/IconTips"; // 小图标提示
|
||||
import TableBatchOperate from '@/components/TableBatchOperate'; // 批量操作
|
||||
import SupplierButton from "../components/SupplierButton.vue"; // 供应商选择按钮
|
||||
import BaseSwitch from "@/components/BaseSwitch"; // 开关
|
||||
import AddSonDomain from "../components/AddSonDomain.vue"; // 新增子域名弹窗
|
||||
import EditSonDomain from "../components/EditSonDomain.vue"; // 修改子域名弹窗
|
||||
import BindAgent from "../components/BindAgent.vue"; // 绑定代理
|
||||
import BatchOperation from "../components/BatchOperation.vue"; // 批量操作弹窗
|
||||
|
||||
const props = defineProps({
|
||||
// 全局搜索结果
|
||||
searchResult: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const loading = ref(true); // loading状态
|
||||
const isShowAdd = ref(false), isShowAgent = ref(false), isShowEdit = ref(false), isShowBatchOp = ref(false); // 各弹窗状态
|
||||
|
||||
// H5防拦截开关
|
||||
const h5InterceptOpen = ref(0);
|
||||
getWebSystemParam().then(res => {
|
||||
h5InterceptOpen.value = +res.data.h5InterceptOpen;
|
||||
});
|
||||
|
||||
// 切换H5防拦截开关状态
|
||||
const configSwitchChange = (type) => {
|
||||
if (type == 'h5InterceptOpen') {
|
||||
const params = {
|
||||
h5InterceptOpen: h5InterceptOpen.value == 1 ? 2 : 1
|
||||
}
|
||||
updateWebSystemParam(params).then(() => {
|
||||
proxy.$modal.msgSuccess(proxy.t('操作成功!'));
|
||||
h5InterceptOpen.value = params.h5InterceptOpen;
|
||||
}).catch(() => {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 获取供应商节点信息
|
||||
const supplierRef = ref(null), currentNodeTips = ref(''), supplierList = ref([]);
|
||||
const getCurSupplierNode = (data) => {
|
||||
currentNodeTips.value = data?.tips;
|
||||
}
|
||||
|
||||
// 根据下拉框条件输入搜索
|
||||
const queryParamsList = ref([{
|
||||
label: proxy.t('操作人'),
|
||||
value: 'updateBy'
|
||||
}, {
|
||||
label: proxy.t('子域名'),
|
||||
value: 'name'
|
||||
}]);
|
||||
|
||||
// 搜索配置
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
searchType: 'updateBy',
|
||||
name: '', // 子域名
|
||||
updateBy: '', // 操作人
|
||||
usageStatus: '', // 使用状态
|
||||
orderByColumn: 'createTime',
|
||||
isAsc: 'desc',
|
||||
domainSupplierId: '' // 供应商
|
||||
});
|
||||
|
||||
// 请求列表
|
||||
const dataList = ref([]), total = ref(0);
|
||||
const getList = () => {
|
||||
loading.value = true;
|
||||
|
||||
getWebDomainList(queryParams).then(res => {
|
||||
loading.value = false;
|
||||
|
||||
// 更改特定字段类型
|
||||
res.rows.forEach(item => {
|
||||
item.startEntrance = item.startEntrance.toString();
|
||||
item.blockDevice = item.blockDevice.toString();
|
||||
});
|
||||
|
||||
dataList.value = res.rows;
|
||||
total.value = +res.total;
|
||||
clearBatchOp(); // 清空批量操作痕迹
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
dataList.value = [];
|
||||
total.value = 0;
|
||||
clearBatchOp(); // 清空批量操作痕迹
|
||||
});
|
||||
}
|
||||
getList();
|
||||
|
||||
// 跳转页面
|
||||
const goRoute = (row, type) => {
|
||||
proxy.$router.push({
|
||||
path: '/agent/agent-info',
|
||||
query: {
|
||||
[type]: row.agentAccount,
|
||||
searchType: type
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 新增域名
|
||||
const openAddDomain = () => {
|
||||
supplierList.value = supplierRef.value?.supplierList.filter(v => v.isOpen && !v.stopStatus); // 已开通且不是维护状态的供应商
|
||||
isShowAdd.value = true;
|
||||
}
|
||||
|
||||
// 开启状态切换
|
||||
const beforeSwitchChange = (row, type) => {
|
||||
const params = {
|
||||
id: row.id,
|
||||
[type]: !row[type]
|
||||
}
|
||||
|
||||
webDomainSwitch({ operationDomainSons: [params] }).then(res => {
|
||||
proxy.$modal.msgSuccess(proxy.t('操作成功!'));
|
||||
getList();
|
||||
return true;
|
||||
}).catch(() => {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
// 启用入口、屏蔽设备切换
|
||||
const changeRowStatus = (row, type) => {
|
||||
const params = {
|
||||
id: row.id,
|
||||
[type]: row[type]
|
||||
}
|
||||
|
||||
if (type === 'startEntrance') {
|
||||
// 启用入口
|
||||
const _label = proxy.useDict('ff_operation_start_entrance').ff_operation_start_entrance.find(v => v.value == row.startEntrance).label;
|
||||
|
||||
if (row.startEntrance == 2) params.marketingDomain = false; // 开启入口为仅极速APP时,强制关闭作为推广域名
|
||||
|
||||
proxy.$modal.confirm(proxy.t('是否确认修改此域名启用入口为:') + _label).then(() => {
|
||||
loading.value = true;
|
||||
changeSuccess(webDomainSwitch({ operationDomainSons: [params] }));
|
||||
}).catch(() => {
|
||||
getList();
|
||||
});
|
||||
} else if (type === 'blockDevice') {
|
||||
// 屏蔽设备
|
||||
const _label = proxy.useDict('ff_operation_block_device').ff_operation_block_device.find(v => v.value == row.blockDevice).label;
|
||||
|
||||
proxy.$modal.confirm(proxy.t('是否确认修改此域名屏蔽设备为:') + _label).then(() => {
|
||||
loading.value = true;
|
||||
changeSuccess(webDomainSwitch({ operationDomainSons: [params] }));
|
||||
}).catch(() => {
|
||||
getList();
|
||||
});
|
||||
}
|
||||
|
||||
// 切换成功
|
||||
function changeSuccess(apiFn) {
|
||||
apiFn.then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('操作成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 操作信息
|
||||
const currentDomainInfo = ref({}); // 当前操作的域名信息
|
||||
const opInfo = (row, type) => {
|
||||
const _ids = row.id ? [row.id] : row; // 操作的id,有表格内点击和批量操作两种
|
||||
|
||||
switch (type) {
|
||||
case 'status':
|
||||
// 启用/停用
|
||||
let typeName = '', content = '', _usageStatus = '';
|
||||
|
||||
if (row.usageStatus == 1 || row.usageStatus == 5) {
|
||||
typeName = proxy.t('启用');
|
||||
content = proxy.t('确认启用该域名吗!');
|
||||
_usageStatus = 4;
|
||||
} else {
|
||||
typeName = proxy.t('停用');
|
||||
content = proxy.t('确认停用该域名吗!');
|
||||
_usageStatus = 5;
|
||||
}
|
||||
|
||||
proxy.$modal.confirm(content).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
setWebDomainStatus({ ids: _ids, usageStatus: _usageStatus }).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('域名') + typeName + proxy.t('成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'refresh':
|
||||
// 刷新域名解析说明
|
||||
row.refreshLoading = true;
|
||||
refreshWebDomainAnalysis({ id: row.id }).then(res => {
|
||||
proxy.$modal.msgSuccess(proxy.t('刷新成功!'));
|
||||
row.refreshLoading = false;
|
||||
getList();
|
||||
}).catch(() => {
|
||||
row.refreshLoading = false;
|
||||
});
|
||||
break
|
||||
case 'agent':
|
||||
// 绑定代理
|
||||
currentDomainInfo.value = row;
|
||||
isShowAgent.value = true;
|
||||
break
|
||||
case 'clearCache':
|
||||
// 清理缓存
|
||||
proxy.$modal.confirm(proxy.t('确定要清理该记录的缓存吗?')).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
clearWebDomainCache({ ids: _ids }).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('缓存清理成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'delete':
|
||||
// 删除域名
|
||||
proxy.$modal.confirm(proxy.t('确定要删除该域名吗!')).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
delWebDomain(_ids.join(',')).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('删除成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break
|
||||
case 'edit':
|
||||
// 修改域名
|
||||
currentDomainInfo.value = row;
|
||||
isShowEdit.value = true;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 批量操作
|
||||
const tableRef = ref(),
|
||||
isAllSelection = ref(false), // 是否全选
|
||||
selectionData = ref([]), // 选中的表格数据
|
||||
batchOpType = ref(''); // 选中的批量操作类型
|
||||
|
||||
// 批量操作选项
|
||||
const opTypeOptions = ref([
|
||||
{ label: proxy.t('批量更换端口'), value: 'port' },
|
||||
{ label: proxy.t('批量清理缓存'), value: 'clearCache' },
|
||||
{ label: proxy.t('批量删除'), value: 'delete' },
|
||||
{ label: proxy.t('批量停用'), value: 'stop' },
|
||||
{ label: proxy.t('批量启用'), value: 'enable' },
|
||||
// { label: proxy.t('批量锁定下发'), value: 'issued' },
|
||||
{ label: proxy.t('批量展示其他担保列表'), value: 'showSecurity' },
|
||||
{ label: proxy.t('批量隐藏其他担保列表'), value: 'hideSecurity' },
|
||||
{ label: proxy.t('批量开启推广域名'), value: 'showPromotion' },
|
||||
{ label: proxy.t('批量关闭推广域名'), value: 'hidePromotion' },
|
||||
{ label: proxy.t('批量修改'), value: 'edit' },
|
||||
{ label: proxy.t('批量绑定代理'), value: 'bindAgent' }
|
||||
]);
|
||||
|
||||
// 勾选表格
|
||||
const tableSelect = (val) => {
|
||||
selectionData.value = val;
|
||||
|
||||
if (val.length === dataList.value.length) {
|
||||
isAllSelection.value = true;
|
||||
} else {
|
||||
isAllSelection.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 全选表格
|
||||
const allSelectionChange = () => {
|
||||
tableRef.value.toggleAllSelection();
|
||||
}
|
||||
|
||||
// 选择批量数据操作类型
|
||||
const opTypeChange = () => {
|
||||
isShowBatchOp.value = true;
|
||||
}
|
||||
|
||||
// 清空批量操作痕迹
|
||||
const clearBatchOp = () => {
|
||||
isAllSelection.value = false;
|
||||
selectionData.value = [];
|
||||
batchOpType.value = '';
|
||||
}
|
||||
|
||||
// 搜索按钮操作
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
|
||||
// 重置按钮操作
|
||||
const resetQuery = () => {
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = (type) => {
|
||||
isShowAdd.value = false; // 新增域名弹窗
|
||||
isShowAgent.value = false; // 绑定代理弹窗
|
||||
isShowEdit.value = false; // 修改域名弹窗
|
||||
isShowBatchOp.value = false; // 批量操作弹窗
|
||||
batchOpType.value = ''; // 批量操作类型
|
||||
|
||||
// 批量操作清空
|
||||
if (type === 'batchSubmit') clearBatchOp();
|
||||
// 提交后刷新列表
|
||||
if (type === 'submit' || type === 'batchSubmit') {
|
||||
getList();
|
||||
}
|
||||
}
|
||||
|
||||
// 跳转域名管理
|
||||
const emit = defineEmits(['goDomainManage']);
|
||||
const goDomainManage = () => {
|
||||
emit('goDomainManage');
|
||||
}
|
||||
|
||||
// 全局搜索展示
|
||||
watch(() => props.searchResult, (val) => {
|
||||
if (val.type == 'domainName') {
|
||||
queryParams.searchType = 'name'
|
||||
queryParams.name = val.domainName;
|
||||
|
||||
nextTick(() => {
|
||||
queryParams.domainSupplierId = val.domainSupplierId;
|
||||
handleQuery();
|
||||
});
|
||||
}
|
||||
}, { deep: true, immediate: true });
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.right-switch {
|
||||
display: inline-block;
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.domain-main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
|
||||
// 左侧
|
||||
.dm-left {
|
||||
width: 145px;
|
||||
height: 100%;
|
||||
border-right: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
// 右侧
|
||||
.dm-right {
|
||||
width: calc(100% - 160px);
|
||||
margin-left: 15px;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.copy-ml {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
<template>
|
||||
<!-- 新增/修改域名白名单 -->
|
||||
<el-dialog :title="dialogTitle" v-model="isShowDialog" width="600px" append-to-body @close="closeDialog">
|
||||
<el-scrollbar max-height="600px" v-loading="loading">
|
||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="100">
|
||||
<el-form-item :label="t('具体域名:')" prop="name" class="mr0" v-if="currentDomainInfo.id">
|
||||
<el-input v-model="formData.name" :placeholder="t('支持添加主域(test.com)或子域(a.test.com)')" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('具体域名:')" prop="names" class="mr0" v-else>
|
||||
<el-input type="textarea" :rows="5" v-model="formData.names"
|
||||
:placeholder="t('支持批量添加,最多20个,多个域名请换行,例如:\n123.com\n123.com.hk\n123.in')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('域名类型:')" prop="domainType" class="mr0" v-if="currentDomainInfo.id">
|
||||
<dict-select class="w100" v-model="formData.domainType" :placeholder="t('请选择域名类型')"
|
||||
dictKey="operation_domain_white_type"></dict-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('用途备注:')" prop="remark" class="mr0">
|
||||
<el-input type="textarea" :rows="5" show-word-limit maxlength="500" v-model="formData.remark"
|
||||
:placeholder="t('请输入备注信息')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('用途说明:')">
|
||||
<span style="display: inline-block; line-height: 22px;" class="c-orange">
|
||||
{{ t('因站点服务器前面设有CDN和防火墙,为了防止外部域名调用访问时被拦截,所以可将外部域名添加到白名单,以免被拦截。') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="closeDialog">{{ t('关 闭') }}</el-button>
|
||||
<el-button type="primary" @click="submitForm" :loading="loading">{{ t('确 认') }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup name="AddEditWhiteList">
|
||||
import { addWhiteDomain, updateWhiteDomain } from "@/api/operation/domain";
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const loading = ref(false);
|
||||
const isShowDialog = ref(true); // 弹窗是否显示
|
||||
const formRef = ref();
|
||||
|
||||
// 接收参数
|
||||
const props = defineProps({
|
||||
currentDomainInfo: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
});
|
||||
|
||||
// 弹窗标题
|
||||
const dialogTitle = computed(() => {
|
||||
if (props.currentDomainInfo.id) {
|
||||
return proxy.t('修改白名单域名');
|
||||
} else {
|
||||
return proxy.t('新增域名白名单');
|
||||
}
|
||||
});
|
||||
|
||||
// 表单参数
|
||||
const formData = reactive({
|
||||
name: '', // 修改时域名
|
||||
names: '', // 新增时域名
|
||||
domainType: '', // 域名类型
|
||||
remark: ''
|
||||
});
|
||||
|
||||
// 初始化表单参数
|
||||
watch(() => props.currentDomainInfo, (val) => {
|
||||
if (val.id) {
|
||||
formData.name = val.name;
|
||||
formData.domainType = val.domainType.toString();
|
||||
formData.remark = val.remark;
|
||||
}
|
||||
}, { immediate: true });
|
||||
|
||||
// 表单校验
|
||||
const reg = /^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$/;
|
||||
const rules = reactive({
|
||||
name: [
|
||||
{ required: true, message: proxy.t('域名不能为空'), trigger: ['blur', 'change'] },
|
||||
// 域名校验
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (value) {
|
||||
if (!reg.test(value)) {
|
||||
callback(new Error(proxy.t('请输入正确的域名')));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
],
|
||||
names: [
|
||||
{ required: true, message: proxy.t('域名不能为空'), trigger: ['blur', 'change'] },
|
||||
// 域名校验
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (value) {
|
||||
if (value.split('\n').length > 20) {
|
||||
callback(new Error(proxy.t('最多支持20个域名')));
|
||||
} else {
|
||||
const arr = value.split('\n');
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (!reg.test(arr[i])) {
|
||||
callback(new Error(proxy.t('请输入正确的域名')));
|
||||
}
|
||||
}
|
||||
callback();
|
||||
}
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
],
|
||||
domainType: [
|
||||
{ required: true, message: proxy.t('请选择域名类型'), trigger: 'change' }
|
||||
]
|
||||
});
|
||||
|
||||
// 提交
|
||||
const submitForm = () => {
|
||||
formRef.value.validate((valid) => {
|
||||
if (!valid) return;
|
||||
|
||||
loading.value = true;
|
||||
const params = {
|
||||
remark: formData.remark
|
||||
};
|
||||
|
||||
if (props.currentDomainInfo.id) {
|
||||
// 修改
|
||||
params.id = props.currentDomainInfo.id;
|
||||
params.domainType = formData.domainType;
|
||||
params.name = formData.name;
|
||||
|
||||
updateWhiteDomain(params).then(() => {
|
||||
loading.value = false;
|
||||
proxy.$message.success(proxy.t('修改成功'));
|
||||
closeDialog('submit');
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
} else {
|
||||
// 新增
|
||||
params.names = formData.names.split('\n');
|
||||
addWhiteDomain(params).then(() => {
|
||||
loading.value = false;
|
||||
proxy.$message.success(proxy.t('添加成功'));
|
||||
closeDialog('submit');
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const emit = defineEmits(['closeDialog']);
|
||||
const closeDialog = (type) => {
|
||||
emit('closeDialog', type);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
<template>
|
||||
<!-- 批量操作弹窗 -->
|
||||
<el-dialog :title="dialogTitle" v-model="isShowDialog" width="800px" append-to-body @close="closeDialog">
|
||||
<el-scrollbar max-height="600px" v-loading="loading">
|
||||
<el-table row-key="id" stripe border :data="tableList">
|
||||
<el-table-column :label="t('域名')" prop="name" align="center" min-width="150"></el-table-column>
|
||||
<el-table-column :label="t('域名类型')" align="center" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<dict-select class="w100" v-model="row.domainType" dictKey="operation_domain_white_type"></dict-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('用途备注')" align="center" min-width="200">
|
||||
<template #default="{ row }">
|
||||
<el-input v-model="row.remark" :placeholder="t('请输入备注')" clearable></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-scrollbar>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="closeDialog">{{ t('关 闭') }}</el-button>
|
||||
<el-button type="primary" @click="submitForm" :loading="loading">{{ t('确 认') }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup name="BatchOperation">
|
||||
import {
|
||||
updateWhiteDomainBatch // 批量修改白名单
|
||||
} from "@/api/operation/domain";
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const loading = ref(false);
|
||||
const isShowDialog = ref(true);
|
||||
|
||||
// 接收参数
|
||||
const props = defineProps({
|
||||
selectionData: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
batchOpType: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
});
|
||||
|
||||
// 表格数据
|
||||
const tableList = ref([]), _tableList = [];
|
||||
|
||||
JSON.parse(JSON.stringify(props.selectionData)).forEach(item => {
|
||||
item.domainType = item.domainType + '';
|
||||
_tableList.push(item);
|
||||
});
|
||||
tableList.value = _tableList;
|
||||
|
||||
// 弹窗标题
|
||||
const dialogTitle = computed(() => {
|
||||
if (props.batchOpType === 'edit') {
|
||||
return proxy.t('批量修改');
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
});
|
||||
|
||||
// 提交
|
||||
const submitForm = () => {
|
||||
loading.value = true;
|
||||
const params = {
|
||||
ids: tableList.value.map(item => item.id)
|
||||
};
|
||||
|
||||
switch (props.batchOpType) {
|
||||
case 'edit':
|
||||
const _editParams = [];
|
||||
params.ids.forEach(id => {
|
||||
const item = tableList.value.find(v => v.id == id);
|
||||
_editParams.push({
|
||||
id: id,
|
||||
domainType: item.domainType,
|
||||
remark: item.remark
|
||||
})
|
||||
});
|
||||
submitSuccess(updateWhiteDomainBatch({ operationDomainWhites: _editParams }), proxy.t('批量修改成功'));
|
||||
break;
|
||||
}
|
||||
|
||||
// 提交后回调
|
||||
function submitSuccess(apiFn, msg) {
|
||||
apiFn.then(() => {
|
||||
loading.value = false;
|
||||
proxy.$message.success(msg);
|
||||
closeDialog('batchSubmit');
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const emit = defineEmits(['closeDialog']);
|
||||
const closeDialog = (type) => {
|
||||
emit('closeDialog', type);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
<template>
|
||||
<!-- 外部白名单域名列表 -->
|
||||
<table-search-card :model="queryParams" @getList="getList" :leftSpan="16" :rightSpan="8" @handleQuery="handleQuery()"
|
||||
@resetQuery="resetQuery">
|
||||
<template #left>
|
||||
<table-search-date ref="searchDateRef" dateType="datetimerange" v-model:dateRange="dateRange"
|
||||
v-model:operateTimeType="operateTimeType" @dateChange="handleQuery"></table-search-date>
|
||||
<el-form-item prop="name" style="width: 200px;">
|
||||
<el-input v-model="queryParams.name" :placeholder="t('请输入域名')" clearable @change="handleQuery"></el-input>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template #right>
|
||||
<el-button type="success" plain icon="Plus" @click="isShowAddEdit = true"
|
||||
v-hasPermi="['operation:white:add']">{{
|
||||
t('新增') }}</el-button>
|
||||
</template>
|
||||
</table-search-card>
|
||||
|
||||
<!-- 查询表格 -->
|
||||
<el-table ref="tableRef" class="c-table-main" v-loading="loading" row-key="id" stripe border :data="dataList"
|
||||
@select="tableSelect" @select-all="tableSelect">
|
||||
<el-table-column align="center" type="selection" width="55" />
|
||||
<el-table-column :label="t('域名')" prop="name" align="center" min-width="160"></el-table-column>
|
||||
<el-table-column :label="t('域名类型')" align="center" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<dict-text dictKey="operation_domain_white_type" :value="row.domainType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('用途备注')" show-overflow-tooltip prop="remark" align="center"
|
||||
min-width="260"></el-table-column>
|
||||
<table-operation></table-operation>
|
||||
<el-table-column :label="t('操作')" align="center" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="opInfo(row, 'edit')" v-hasPermi="['operation:white:all:edit']">
|
||||
{{ t('修改') }}
|
||||
</el-button>
|
||||
<el-button link type="primary" @click="opInfo(row, 'delete')" v-hasPermi="['operation:white:remove']">
|
||||
{{ t('删除') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 批量操作 -->
|
||||
<table-batch-operate v-if="total > 0" v-model:batchOpType="batchOpType" v-model:isAllSelection="isAllSelection"
|
||||
@allSelectionChange="allSelectionChange" @opTypeChange="opTypeChange" :selectionData="selectionData"
|
||||
:opTypeOptions="opTypeOptions"></table-batch-operate>
|
||||
<!-- 列表分页 -->
|
||||
<pagination v-if="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList" />
|
||||
|
||||
<!-- 新增/修改白名单 -->
|
||||
<add-edit-white-list v-if="isShowAddEdit" :currentDomainInfo="currentDomainInfo" @closeDialog="closeDialog"></add-edit-white-list>
|
||||
|
||||
<!-- 批量操作弹窗 -->
|
||||
<batch-operation v-if="isShowBatchOp" :batchOpType="batchOpType" :selectionData="selectionData"
|
||||
@closeDialog="closeDialog"></batch-operation>
|
||||
</template>
|
||||
|
||||
<script setup name="WhiteList">
|
||||
import {
|
||||
getWhiteDomainList, // 域名列表
|
||||
delWhiteDomain, // 删除域名
|
||||
} from "@/api/operation/domain";
|
||||
import TableSearchDate from "@/components/TableSearchDate"; // 日期选择
|
||||
import TableBatchOperate from '@/components/TableBatchOperate'; // 批量操作
|
||||
import AddEditWhiteList from "./AddEditWhiteList.vue"; // 新增/修改白名单
|
||||
import BatchOperation from "./BatchOperation.vue"; // 批量操作
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const loading = ref(true); // loading状态
|
||||
const isShowAddEdit = ref(false), isShowBatchOp = ref(false); // 各弹窗状态
|
||||
|
||||
// 日期选择
|
||||
const searchDateRef = ref(), dateRange = ref([]), operateTimeType = ref('');
|
||||
|
||||
// 搜索配置
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
name: '', // 域名
|
||||
orderByColumn: 'createTime',
|
||||
isAsc: 'desc'
|
||||
});
|
||||
|
||||
// 请求列表
|
||||
const dataList = ref([]), total = ref(0);
|
||||
const getList = () => {
|
||||
const params = proxy.addDateRange(queryParams, dateRange.value); // 日期参数
|
||||
loading.value = true;
|
||||
|
||||
getWhiteDomainList(params).then(res => {
|
||||
loading.value = false;
|
||||
dataList.value = res.rows;
|
||||
total.value = +res.total;
|
||||
clearBatchOp(); // 清空批量操作痕迹
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
dataList.value = [];
|
||||
total.value = 0;
|
||||
clearBatchOp(); // 清空批量操作痕迹
|
||||
});
|
||||
}
|
||||
getList();
|
||||
|
||||
// 操作信息
|
||||
const currentDomainInfo = ref({}); // 当前操作的域名信息
|
||||
const opInfo = (row, type) => {
|
||||
switch (type) {
|
||||
case 'edit':
|
||||
// 修改域名
|
||||
currentDomainInfo.value = row;
|
||||
isShowAddEdit.value = true;
|
||||
break;
|
||||
case 'delete':
|
||||
// 删除域名
|
||||
proxy.$modal.confirm(proxy.t('确定要删除该域名吗!')).then(() => {
|
||||
loading.value = true;
|
||||
|
||||
delWhiteDomain(row.id).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('删除成功!'));
|
||||
getList();
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}).catch(() => { });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 批量操作
|
||||
const tableRef = ref(),
|
||||
isAllSelection = ref(false), // 是否全选
|
||||
selectionData = ref([]), // 选中的表格数据
|
||||
batchOpType = ref(''); // 选中的批量操作类型
|
||||
|
||||
// 批量操作选项
|
||||
const opTypeOptions = ref([
|
||||
{ label: proxy.t('批量修改'), value: 'edit' },
|
||||
{ label: proxy.t('批量删除'), value: 'delete' }
|
||||
]);
|
||||
|
||||
// 勾选表格
|
||||
const tableSelect = (val) => {
|
||||
selectionData.value = val;
|
||||
|
||||
if (val.length === dataList.value.length) {
|
||||
isAllSelection.value = true;
|
||||
} else {
|
||||
isAllSelection.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 全选表格
|
||||
const allSelectionChange = () => {
|
||||
tableRef.value.toggleAllSelection();
|
||||
}
|
||||
|
||||
// 选择批量数据操作类型
|
||||
const opTypeChange = () => {
|
||||
if (batchOpType.value === 'edit') {
|
||||
isShowBatchOp.value = true;
|
||||
} else if (batchOpType.value === 'delete') {
|
||||
proxy.$modal.confirm(proxy.t('确定要删除选中的域名吗!')).then(() => {
|
||||
loading.value = true;
|
||||
delWhiteDomain(selectionData.value.map(item => item.id).join(',')).then(res => {
|
||||
loading.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('删除成功!'));
|
||||
getList();
|
||||
clearBatchOp(); // 清空批量操作痕迹
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
batchOpType.value = '';
|
||||
});
|
||||
}).catch(() => {
|
||||
batchOpType.value = '';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 清空批量操作痕迹
|
||||
const clearBatchOp = () => {
|
||||
isAllSelection.value = false;
|
||||
selectionData.value = [];
|
||||
batchOpType.value = '';
|
||||
}
|
||||
|
||||
// 搜索按钮操作
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
|
||||
// 重置按钮操作
|
||||
const resetQuery = () => {
|
||||
searchDateRef.value.dateResetQuery(); // 日期选择重置
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = (type) => {
|
||||
isShowAddEdit.value = false; // 新增域名弹窗
|
||||
isShowBatchOp.value = false; // 批量操作弹窗
|
||||
currentDomainInfo.value = {}; // 当前操作的域名信息
|
||||
batchOpType.value = ''; // 批量操作类型
|
||||
|
||||
// 批量操作清空
|
||||
if (type === 'batchSubmit') clearBatchOp();
|
||||
// 提交后刷新列表
|
||||
if (type === 'submit' || type === 'batchSubmit') {
|
||||
getList();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'></style>
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
<template>
|
||||
<!-- 新增 -->
|
||||
<el-dialog :title="addEditStatus=='add' ? t('新增') : t('修改')" align-center :close-on-click-modal="false" v-model="showDialog"
|
||||
width="800px" append-to-body>
|
||||
<el-scrollbar max-height="900px">
|
||||
<el-form ref="formRef" :model="formAll" :rules="rules" label-width="130px" class="add-form">
|
||||
<el-form-item :label="t('api平台代码')" prop="apiPlatformCode">
|
||||
<el-input v-model="formAll.apiPlatformCode" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('平台代码')" prop="platformCode">
|
||||
<el-input v-model="formAll.platformCode" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('平台展示代码')" prop="platformShowCode">
|
||||
<el-input v-model="formAll.platformShowCode" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('语言信息')" prop="langInfo">
|
||||
<el-input v-model="formAll.langInfo" type="textarea" :rows="5" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('货币信息')" prop="currencyInfo">
|
||||
<el-input v-model="formAll.currencyInfo" type="textarea" :rows="5" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm" :loading="loadingButton">{{ t('确 定') }}</el-button>
|
||||
<el-button @click="closeDialog">{{ t('取 消') }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import { formatTime,finalTimestamp } from '@/utils/ruoyi'; // 时间格式化
|
||||
import ImageUpload from "@/components/ImageUpload";
|
||||
import { updateGame } from "@/api/game/game";
|
||||
import { nextTick, onMounted, ref } from "vue"; // 获取当前实例
|
||||
import { getLocalStorage } from "@/utils/auth";
|
||||
|
||||
const langList = getLocalStorage('langList')?.filter(v => v.langType == 1 && v.langStatus).map(item => {
|
||||
return {
|
||||
label: item.name,
|
||||
value: item.id
|
||||
};
|
||||
}); // 语种选项
|
||||
const loadingButton = ref(false);
|
||||
const oldForm = shallowRef({ });
|
||||
const { proxy } = getCurrentInstance() // 获取当前实例
|
||||
const emits = defineEmits(['submit', 'update:show']) // 自定义事件
|
||||
const props = defineProps({ // 父组件向子组件传值
|
||||
data: {
|
||||
type: Object, // 父组件传值
|
||||
default: {}
|
||||
},
|
||||
show: {
|
||||
type: Boolean, // 显示
|
||||
default: false
|
||||
},
|
||||
addEditStatus:{ // 添加/修改
|
||||
type: String,
|
||||
default: 'add'
|
||||
},
|
||||
modifyDate: { //修改数据
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
})
|
||||
|
||||
const showDialog = computed({ //弹窗显示控制
|
||||
get() {
|
||||
return props.show
|
||||
},
|
||||
set(value) {
|
||||
emits('update:show', value)
|
||||
}
|
||||
})
|
||||
|
||||
const activeNameLang = ref(0);//语言切换选中
|
||||
|
||||
const langOptionAll = ref([]); // 语言tabs切换的数据
|
||||
const formAll = reactive({
|
||||
syncStatus:false,
|
||||
})
|
||||
|
||||
// 修改时数据更新相关内容
|
||||
nextTick(() => {
|
||||
if (props.addEditStatus != 'edit') return;
|
||||
Object.assign(formAll, props.modifyDate)
|
||||
setTimeout(() => {
|
||||
let objForm = { ...formAll }
|
||||
oldForm.value = JSON.stringify(objForm);
|
||||
}, 500);
|
||||
});
|
||||
|
||||
//表单验证规则
|
||||
const rules = reactive({
|
||||
apiPlatformCode: [
|
||||
{ required: true, message: '请输入平台编码', trigger: 'change' },
|
||||
],
|
||||
platformCode: [
|
||||
{ required: true, message: '请输入游戏编码', trigger: 'change' },
|
||||
],
|
||||
platformShowCode: [
|
||||
{ required: true, message: '请输入游戏显示编码', trigger: 'change' },
|
||||
],
|
||||
langInfo: [
|
||||
{ required: true, message: '请输入语言信息', trigger: 'change' },
|
||||
],
|
||||
})
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
showDialog.value = false
|
||||
}
|
||||
|
||||
// 提交
|
||||
const formRef = ref(null)
|
||||
|
||||
// 提交修改和新增数据表单
|
||||
const submitForm = () => {
|
||||
// 验证表单
|
||||
formRef.value.validate(valid => {
|
||||
if (valid) {
|
||||
loadingButton.value = true;
|
||||
// 初始化表单数据
|
||||
let formData = {
|
||||
...formAll
|
||||
};
|
||||
if (JSON.stringify(formAll) != oldForm.value) {
|
||||
updateGame(formData).then(res => {
|
||||
loadingButton.value = false;
|
||||
proxy.$modal.msgSuccess(proxy.t('修改成功!'));
|
||||
emits('submit');
|
||||
closeDialog();
|
||||
}).catch(() => {
|
||||
loadingButton.value = false;
|
||||
});
|
||||
}else{
|
||||
loadingButton.value = false;
|
||||
closeDialog();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
</script>
|
||||
<style scope lang="scss">
|
||||
.w100 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.upload-box-vioce{
|
||||
height: 90px !important;
|
||||
overflow: hidden;
|
||||
.upload-tips {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
padding-left: 10px;
|
||||
}
|
||||
.component-upload-image .el-upload--picture-card {
|
||||
width: 180px !important;
|
||||
height: 90px !important;
|
||||
}
|
||||
.el-upload-list--picture-card .el-upload-list__item {
|
||||
width: 180px!important;
|
||||
height: 90px!important;
|
||||
}
|
||||
:deep(.el-upload-list) {
|
||||
width:180px!important;
|
||||
height: 90px!important;
|
||||
.el-upload,
|
||||
.el-upload-list--picture-card .el-upload-list__item {
|
||||
width: 180px!important;
|
||||
height: 90px!important;
|
||||
}
|
||||
|
||||
.el-upload-list__item {
|
||||
margin: 0;
|
||||
border: none;
|
||||
width: 180px!important;
|
||||
height: 90px!important;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.upload-box-vioce11{
|
||||
height: 400px !important;
|
||||
overflow: hidden;
|
||||
.upload-tips {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
padding-left: 10px;
|
||||
}
|
||||
.component-upload-image .el-upload--picture-card {
|
||||
width: 300px !important;
|
||||
height: 400px !important;
|
||||
}
|
||||
.el-upload-list--picture-card .el-upload-list__item {
|
||||
width: 300px!important;
|
||||
height: 400px!important;
|
||||
}
|
||||
:deep(.el-upload-list) {
|
||||
width:300px!important;
|
||||
height: 400px!important;
|
||||
.el-upload,
|
||||
.el-upload-list--picture-card .el-upload-list__item {
|
||||
width: 300px!important;
|
||||
height: 400px!important;
|
||||
}
|
||||
|
||||
.el-upload-list__item {
|
||||
margin: 0;
|
||||
border: none;
|
||||
width: 300px!important;
|
||||
height: 400px!important;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
<template>
|
||||
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
|
||||
<template #left>
|
||||
<el-form-item prop="platformShowCode">
|
||||
<el-input v-model="queryParams.platformShowCode" :placeholder="t('请输入平台')" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template #right>
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" >{{ t('新增配置') }}</el-button>
|
||||
</template>
|
||||
</table-search-card>
|
||||
|
||||
<el-table v-loading="loading" :data="gameList" class="c-table-main" stripe
|
||||
ref="dragTable" row-key="id" border>
|
||||
<el-table-column :label="t('平台名称')" align="center" prop="platformCode" />
|
||||
<el-table-column :label="t('api平台代码')" align="center" prop="apiPlatformCode" />
|
||||
<el-table-column :label="t('货币信息')" align="center" prop="currencyInfo" />
|
||||
<el-table-column :label="t('语言信息')" align="center" prop="langInfo" />
|
||||
<table-operation></table-operation>
|
||||
<el-table-column :label="t('操作')" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['game:game:edit']">{{ t('修改') }}</el-button>
|
||||
<el-button link type="primary" @click="handleSynchronous(scope.row)"
|
||||
v-hasPermi="['game:game:sync']">{{ t('删除') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList" />
|
||||
<add-dialog v-if="isShowDialog"
|
||||
:addEditStatus="addEditStatus" :modifyDate="modifyDate" @submit="getList"
|
||||
v-model:show="isShowDialog"></add-dialog>
|
||||
</template>
|
||||
|
||||
<script setup name="Game">
|
||||
import AddDialog from "./AddDialog"//新增/修改弹窗
|
||||
import * as game from "@/api/game/game";
|
||||
import { platformSelect,getGamePlatformApiSync,getGamePlatformTenantSync } from "@/api/game/platform";
|
||||
import {getGameSecretList,getGameSecretInfo} from "@/api/game/configuration";
|
||||
import useInitDataStore from "@/store/modules/initData";
|
||||
|
||||
const emits = defineEmits(["reset"])
|
||||
|
||||
const useInitData = useInitDataStore();
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const gameList = ref([]);
|
||||
const open = ref(false);
|
||||
const loading = ref(true);
|
||||
const ids = ref([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const title = ref("");
|
||||
const gameTypeOptions = ref([
|
||||
{ label: '电子', value: '1' },
|
||||
{ label: '棋牌', value: '2' },
|
||||
{ label: '真人', value: '3' },
|
||||
{ label: '捕鱼', value: '4' },
|
||||
{ label: '体育', value: '6' },
|
||||
{ label: '斗鸡', value: '7' },
|
||||
{ label: '电竞', value: '8' },
|
||||
{ label: '彩票', value: '9' },
|
||||
{ label: '区块链', value: '10' },
|
||||
]);
|
||||
const data = reactive({
|
||||
form: {},
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
rules: {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
/** 查询平台管理列表 */
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
getGameSecretList(queryParams.value).then(response => {
|
||||
gameList.value = response.rows;
|
||||
total.value = response.total;
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
// 表单重置
|
||||
function reset() {
|
||||
form.value = {
|
||||
id: null
|
||||
};
|
||||
proxy.resetForm("gameRef");
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
useInitData.setStateData('currencyCode', String(queryParams.value.currencyCode));
|
||||
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
function resetQuery() {
|
||||
queryParams.value.gameType = useInitData.dictInitData.platformType
|
||||
queryParams.value.platformId = useInitData.dictInitData.platformId
|
||||
queryParams.value.pageNum = 1;
|
||||
platformListInit(true)
|
||||
}
|
||||
|
||||
const addEditStatus = ref('add'), isShowDialog = ref(false), editDataId = ref(''),modifyDate = ref({});
|
||||
/** 修改按钮操作 */
|
||||
function handleUpdate(row) {
|
||||
reset();
|
||||
const _id = row.id || ids.value
|
||||
game.getGame(_id).then(response => {
|
||||
modifyDate.value = response.data;
|
||||
isShowDialog.value = true;
|
||||
addEditStatus.value = 'edit'
|
||||
title.value = proxy.t('修改平台管理');
|
||||
});
|
||||
// proxy.$modal.msgError("该功能暂未开发")
|
||||
}
|
||||
|
||||
const handleAdd = () => {
|
||||
isShowDialog.value = true;
|
||||
addEditStatus.value = 'add'
|
||||
title.value = proxy.t('新增配置');
|
||||
}
|
||||
const handleSynchronous = (row) => {
|
||||
proxy.$modal.confirm(proxy.t('当前设置宣传图同步到所有币种下生效')).then(() => {
|
||||
game.gameGameSync({id:row.id}).then(() => {
|
||||
proxy.$modal.msgSuccess(proxy.t('同步成功'));
|
||||
getList();
|
||||
})
|
||||
}).catch(() => {})
|
||||
}
|
||||
// 游戏api同步
|
||||
const handleApiGame = () => {
|
||||
proxy.$modal.confirm(proxy.t('是否确认同步?')).then(() => {
|
||||
getGamePlatformApiSync({}).then(() => {
|
||||
proxy.$modal.msgSuccess(proxy.t('同步成功'));
|
||||
getList();
|
||||
})
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
// 获取游戏平台下拉
|
||||
const platformList = ref([])
|
||||
const platformListInit = async (isFirst = false) => {
|
||||
let { platformId, gameType } = queryParams.value
|
||||
await platformSelect({ platformType: gameType,currencyCode:queryParams.value.currencyCode }).then(res => {
|
||||
platformList.value = res.data
|
||||
queryParams.value.platformId = isFirst && platformId ? platformId : res?.data?.length ? res.data[0].id : null
|
||||
getList();
|
||||
})
|
||||
}
|
||||
//初始化
|
||||
onMounted(() => {
|
||||
getList();
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<!-- 新增 -->
|
||||
<el-dialog :title="addEditStatus=='add' ? t('新增') : t('修改')" :close-on-click-modal="false" v-model="showDialog"
|
||||
<el-dialog :title="addEditStatus=='add' ? t('新增') : t('修改')" align-center :close-on-click-modal="false" v-model="showDialog"
|
||||
width="700px" append-to-body>
|
||||
<el-scrollbar max-height="900px">
|
||||
<el-form ref="formRef" :model="formAll" :rules="rules" label-width="130px" class="add-form">
|
||||
|
|
@ -22,6 +22,8 @@
|
|||
<el-form-item :label="t('icon图样式')" prop="iconStyle">
|
||||
<el-radio-group v-model="formAll.iconStyle">
|
||||
<el-radio :value="1">{{ t('默认') }}</el-radio>
|
||||
<el-radio :value="2">{{ t('自定义') }}</el-radio>
|
||||
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<div v-if="formAll.iconStyle == 1">
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
<platform v-if="activeName === 'platform'" @toGameManage="toGameManage"></platform>
|
||||
<game v-if="activeName === 'game'">
|
||||
</game>
|
||||
<configuration v-if="activeName === 'configuration'"></configuration>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -26,12 +27,14 @@
|
|||
import platform from "./platform"
|
||||
const { proxy } = getCurrentInstance();
|
||||
import game from "./game"
|
||||
import Configuration from "./configuration"
|
||||
|
||||
const platItem = ref({})
|
||||
const activeName = ref('platform')
|
||||
const tabs = ref([
|
||||
{ label: proxy.t('平台管理'), name: 'platform' },
|
||||
{ label: proxy.t('子游戏管理'), name: 'game' },
|
||||
{ label: proxy.t('配置管理'), name: 'configuration' },
|
||||
])
|
||||
|
||||
// 跳转子游戏管理
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@
|
|||
@resetQuery="resetQuery">
|
||||
<template #left>
|
||||
<!-- 待处理列表没有时间查询 -->
|
||||
<span v-show="listType != 'pending'">
|
||||
<!-- <span v-show="listType != 'pending'">
|
||||
</span> -->
|
||||
<el-form-item prop="timeType">
|
||||
<el-select v-model="queryParams.timeType" :placeholder="t('时间类型')" style="width: 150px;"
|
||||
@change="handleQuery">
|
||||
|
|
@ -14,7 +15,7 @@
|
|||
</el-form-item>
|
||||
<table-search-date ref="searchDateRef" v-model:dateRange="dateRange"
|
||||
v-model:operateTimeType="operateTimeType" @dateChange="handleQuery"></table-search-date>
|
||||
</span>
|
||||
|
||||
<el-form-item >
|
||||
<custom-select style="width: 130px;" v-if="siteSelect.length > 0" collapse-tags collapse-tags-tooltip v-model="queryParams.tenantId" :options="siteSelect" :placeholder="t('请选择')"></custom-select>
|
||||
</el-form-item>
|
||||
|
|
@ -157,6 +158,8 @@ import DictSelect from "@/components/DictSelect";
|
|||
import { getLocalStorage } from "@/utils/auth";
|
||||
import { moneyFormat } from "@/utils"; // 金额格式化
|
||||
import DetailDialog from "./DetailDialog.vue"; // 详情弹窗
|
||||
import { finalTimestamp } from "@/utils/ruoyi";
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
listType: {
|
||||
|
|
@ -184,14 +187,14 @@ const currencySelectArr = getLocalStorage('currencySelect')?.map(item => {
|
|||
};
|
||||
}); //
|
||||
// 日期选择
|
||||
const searchDateRef = ref(null), dateRange = ref([]), operateTimeType = ref('');
|
||||
const searchDateRef = ref(null), dateRange = ref([]), operateTimeType = ref('day');
|
||||
|
||||
// 搜索配置
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
tenantId: '',
|
||||
timeType: '',
|
||||
timeType: '1',
|
||||
searchType: 'memberAccount', // 搜索类型
|
||||
memberAccount: '',
|
||||
feedbackStatus: '', // 反馈状态:1待处理 2-已采纳 3-已忽略
|
||||
|
|
@ -205,12 +208,15 @@ const queryParams = reactive({
|
|||
const dataList = ref([]);
|
||||
const total = ref(0); // 总数
|
||||
const getList = () => {
|
||||
let params = {}
|
||||
|
||||
if (props.listType !== 'pending') { // 非待处理状态才有时间查询
|
||||
params = proxy.addDateRange(queryParams, dateRange.value);
|
||||
} else {
|
||||
params = queryParams;
|
||||
// if (props.listType !== 'pending') { // 非待处理状态才有时间查询
|
||||
// params = proxy.addDateRange(queryParams, dateRange.value);
|
||||
// } else {
|
||||
// params = queryParams;
|
||||
// }
|
||||
let params = {
|
||||
...queryParams,
|
||||
beginTime: finalTimestamp(dateRange.value[0]),
|
||||
endTime: finalTimestamp(dateRange.value[1])
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
|
|
@ -375,14 +381,9 @@ const handleQuery = () => {
|
|||
|
||||
// 重置按钮操作
|
||||
const resetQuery = () => {
|
||||
if (props.listType !== 'pending') {
|
||||
// searchDateRef.value = ; // 日期选择重置
|
||||
searchDateRef.value = null;
|
||||
dateRange.value = [];
|
||||
operateTimeType.value = '';
|
||||
}
|
||||
|
||||
handleQuery();
|
||||
dateRange.value = [];
|
||||
operateTimeType.value = "day";
|
||||
searchDateRef.value.timeTypeChange(operateTimeType.value)
|
||||
}
|
||||
|
||||
const initByListType = (val) => {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,10 @@
|
|||
<el-input style="width: 550px;" v-model="formAll.title" placeholder="请输入标题"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('内容')" prop="content">
|
||||
<editor v-model="formAll.content" :min-height="260"/>
|
||||
<div style="width: 600px;">
|
||||
<editor v-model="formAll.content" :min-height="260"/>
|
||||
</div>
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('公告时间')" prop="ShowStartTime">
|
||||
<div >
|
||||
|
|
|
|||
|
|
@ -154,9 +154,8 @@
|
|||
<!-- <div style="width: 100%;"> <el-input style="width: 550px;" v-model="formAll.name" disabled placeholder="请输入确认安全码"></el-input></div> -->
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('自动额度最小值')" prop="creditQuota">
|
||||
<div style="width: 100%;"> <el-input style="width: 550px;" v-model="formAll.creditQuota" disabled placeholder="请输入"></el-input></div>
|
||||
<div style="width: 100%;"> <el-input style="width: 550px;" v-model="formAll.creditQuota" placeholder="请输入"></el-input></div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('备注')">
|
||||
<el-input
|
||||
v-model="formAll.remark"
|
||||
|
|
@ -194,6 +193,7 @@ const fileHost = getLocalStorage('fileUrl') || ''; // 文件host
|
|||
|
||||
const langList = getLocalStorage('langSelect')?.map(item => {
|
||||
return {
|
||||
...item,
|
||||
label: item.name,
|
||||
value: item.id
|
||||
};
|
||||
|
|
@ -235,7 +235,7 @@ const formAll = reactive({
|
|||
currencyPattern:[],
|
||||
backendDomain:'',
|
||||
creditQuotaType: 1,
|
||||
creditQuota:10000,
|
||||
creditQuota:0,
|
||||
siteType:0,
|
||||
})
|
||||
const loadingButton = ref(false)
|
||||
|
|
@ -359,7 +359,7 @@ const changeLangPattern = () => {
|
|||
let arr = [];
|
||||
formAll.langPattern.map(item => {
|
||||
let langListname = langList.find(item1 => item1.value == item);
|
||||
arr.push({ value: item, label: langListname.label });
|
||||
arr.push({ value: item, label: `${langListname.label}(${langListname.langDisplay})` });
|
||||
|
||||
})
|
||||
langListarr.value =arr;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,12 @@
|
|||
{{ row.currencyCode}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('状态')" align="center" min-width="120" prop="quota">
|
||||
<template #default="{ row }">
|
||||
<el-button v-if="row.status == 1" @click="handleEnable(row)" type="primary">{{t('启用')}}</el-button>
|
||||
<el-button v-if="row.status == 0" @click="handleDisable(row)" type="primary">{{t('停用')}}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('操作时间')" align="center" min-width="120" prop="currencyCode">
|
||||
<template #default="{ row }">
|
||||
{{ row.updateTime ? formatTime(row.updateTime): formatTime(row.createTime) }}
|
||||
|
|
@ -32,7 +38,7 @@
|
|||
<el-table-column :label="t('操作')" align="center" min-width="120" prop="quota">
|
||||
<template #default="{ row }">
|
||||
<el-button @click="handleEdit(row)" type="primary">{{t('修改')}}</el-button>
|
||||
<el-button @click="handleDelect(row)" type="primary">{{t('删除')}}</el-button>
|
||||
<!-- <el-button @click="handleDelect(row)" type="primary">{{t('删除')}}</el-button> -->
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
|
@ -73,7 +79,7 @@ import { formatTime,finalTimestamp } from '@/utils/ruoyi'; // 时间格式化
|
|||
import CustomSelect from "@/components/CustomSelect"; // 素材列表
|
||||
import { nextTick, onMounted, ref } from "vue"; // 获取当前实例
|
||||
import { getLocalStorage } from "@/utils/auth";
|
||||
import { postSiteBindApiGame,getSiteBindApiGameInfo,postSiteUpdateApiGame,postSiteDeleteApiGame } from "@/api/siteManagement";
|
||||
import { postSiteBindApiGame,getSiteBindApiGameInfo,postSiteUpdateApiGame,postSiteDeleteApiGame,postSiteOpenApiGameInfo,postSiteStopApiGameInfo } from "@/api/siteManagement";
|
||||
import { id } from 'element-plus/es/locales.mjs';
|
||||
|
||||
const currencySelectArr = getLocalStorage('currencySelect')?.map(item => {
|
||||
|
|
@ -168,6 +174,24 @@ const handleDelect = (row) => {
|
|||
})
|
||||
}).catch(() => {})
|
||||
}
|
||||
//
|
||||
const handleDisable = (row) => {
|
||||
proxy.$modal.confirm(proxy.t('确认是否停用?')).then(() => {
|
||||
postSiteStopApiGameInfo({siteId:formAll.siteId,id:row.id}).then(() => {
|
||||
proxy.$modal.msgSuccess(proxy.t('停用成功'));
|
||||
getSiteBindApiGameInfos();
|
||||
})
|
||||
}).catch(() => {})
|
||||
}
|
||||
//
|
||||
const handleEnable = (row) => {
|
||||
proxy.$modal.confirm(proxy.t('确认是否启用?')).then(() => {
|
||||
postSiteOpenApiGameInfo({siteId:formAll.siteId,id:row.id}).then(() => {
|
||||
proxy.$modal.msgSuccess(proxy.t('启用成功'));
|
||||
getSiteBindApiGameInfos();
|
||||
})
|
||||
}).catch(() => {})
|
||||
}
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
showDialog.value = false
|
||||
|
|
|
|||
|
|
@ -147,13 +147,26 @@ const currencySelectArr = getLocalStorage('currencySelect')?.map(item => {
|
|||
};
|
||||
});
|
||||
const openView = ref(false);
|
||||
|
||||
const siteList = ref(getLocalStorage('siteSelect'));
|
||||
const queryParamsList = ref([{
|
||||
label: proxy.t('站点名称'),
|
||||
value: 'siteName',
|
||||
inputType: 'select',
|
||||
inputConfig:{
|
||||
options: siteList.value.map(item => {
|
||||
return {
|
||||
label: item.label,
|
||||
value: item.label,
|
||||
}
|
||||
}),
|
||||
}
|
||||
},{
|
||||
label: proxy.t('站点ID'),
|
||||
value: 'siteId',
|
||||
inputType: 'select',
|
||||
inputConfig:{
|
||||
options: siteList.value,
|
||||
}
|
||||
}]);
|
||||
const data = reactive({
|
||||
form: {},
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@
|
|||
v-model:show="openView"></modify-dialog>
|
||||
</template>
|
||||
|
||||
<script setup name="Agent">
|
||||
<script setup name="BillingRecords">
|
||||
import {getSiteFlowUserList} from "@/api/report";
|
||||
import CustomSelect from '@/components/CustomSelect';
|
||||
import CheckboxSelect from "@/components/CheckboxSelect"; // 多选框
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
|
||||
<template #left>
|
||||
<table-search-date v-model:dateRange="dateRange" v-model:operateTimeType="operateTimeType"></table-search-date>
|
||||
<select-input-form ref="selectInputFormRef" :queryParamsList="queryParamsList" :queryParams="queryParams"
|
||||
<select-input-form ref="selectInputFormRef" v-if="loadingShow" :queryParamsList="queryParamsList" :queryParams="queryParams"
|
||||
@handleQuery="handleQuery">
|
||||
</select-input-form>
|
||||
<el-form-item prop="changeType">
|
||||
|
|
@ -95,7 +95,7 @@
|
|||
v-model:show="openView"></modify-dialog>
|
||||
</template>
|
||||
|
||||
<script setup name="Agent">
|
||||
<script setup name="BillingRecords">
|
||||
import {getSiteFlowQuotasList} from "@/api/report";
|
||||
import CustomSelect from '@/components/CustomSelect';
|
||||
import CheckboxSelect from "@/components/CheckboxSelect"; // 多选框
|
||||
|
|
@ -103,9 +103,8 @@ import TableSearchDate from '@/components/TableSearchDate'
|
|||
import AddSiteDialog from "./components/AddSiteDialog"; // 新增站点弹窗
|
||||
import ModifyDialog from "./components/ModifyDialog";
|
||||
import { getLocalStorage } from "@/utils/auth";
|
||||
import Crontab from '@/components/Crontab'
|
||||
import { parseTime,finalTimestamp } from '@/utils/ruoyi'; // 时间格式化
|
||||
import { onMounted } from "vue";
|
||||
|
||||
const router = useRouter();
|
||||
const { proxy } = getCurrentInstance();
|
||||
const agentList = ref([]);
|
||||
|
|
@ -113,14 +112,26 @@ const loading = ref(true);
|
|||
const total = ref(0);
|
||||
|
||||
const openView = ref(false);
|
||||
|
||||
const siteList = ref(getLocalStorage('siteSelect'));
|
||||
const queryParamsList = ref([{
|
||||
label: proxy.t('站点ID'),
|
||||
value: 'siteId',
|
||||
inputType: 'number',
|
||||
inputType: 'select',
|
||||
inputConfig:{
|
||||
options: siteList.value,
|
||||
}
|
||||
},{
|
||||
label: proxy.t('所属站点'),
|
||||
value: 'siteName',
|
||||
inputType: 'select',
|
||||
inputConfig:{
|
||||
options: siteList.value.map(item => {
|
||||
return {
|
||||
label: item.label,
|
||||
value: item.label,
|
||||
}
|
||||
}),
|
||||
}
|
||||
},
|
||||
{
|
||||
label: proxy.t('编号'),
|
||||
|
|
@ -191,7 +202,7 @@ total.value = response.total;
|
|||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
const loadingShow = ref(true);
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
queryParams.value.pageNum = 1;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
</el-select>
|
||||
</el-form-item>
|
||||
<table-search-date v-model:dateRange="dateRange" v-model:operateTimeType="operateTimeType"></table-search-date>
|
||||
<select-input-form ref="selectInputFormRef" :queryParamsList="queryParamsList" :queryParams="queryParams"
|
||||
<select-input-form ref="selectInputFormRef" v-if="loadingShow" :queryParamsList="queryParamsList" :queryParams="queryParams"
|
||||
@handleQuery="handleQuery">
|
||||
</select-input-form>
|
||||
<select-input-form ref="selectInputFormRef" :queryParamsList="queryParamsList2" keyName="searchType2" :queryParams="queryParams"
|
||||
|
|
@ -106,7 +106,7 @@
|
|||
v-model:show="openView"></modify-dialog>
|
||||
</template>
|
||||
|
||||
<script setup name="Agent">
|
||||
<script setup name="BillingRecords">
|
||||
import {getSiteFlowGameCurrencyList} from "@/api/report";
|
||||
import CustomSelect from '@/components/CustomSelect';
|
||||
import CheckboxSelect from "@/components/CheckboxSelect"; // 多选框
|
||||
|
|
@ -123,13 +123,26 @@ const agentList = ref([]);
|
|||
const loading = ref(true);
|
||||
const total = ref(0);
|
||||
const openView = ref(false);
|
||||
const siteList = ref(getLocalStorage('siteSelect'));
|
||||
const queryParamsList = ref([{
|
||||
label: proxy.t('站点ID'),
|
||||
value: 'siteId',
|
||||
inputType: 'number',
|
||||
inputType: 'select',
|
||||
inputConfig:{
|
||||
options: siteList.value,
|
||||
}
|
||||
},{
|
||||
label: proxy.t('站点名称'),
|
||||
value: 'siteName',
|
||||
inputType: 'select',
|
||||
inputConfig:{
|
||||
options: siteList.value.map(item => {
|
||||
return {
|
||||
label: item.label,
|
||||
value: item.label,
|
||||
}
|
||||
}),
|
||||
}
|
||||
}]);
|
||||
const queryParamsList2 = ref([{
|
||||
label: proxy.t('订单号'),
|
||||
|
|
@ -198,7 +211,7 @@ function resetQuery() {
|
|||
proxy.resetForm("queryRef");
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
const loadingShow = ref(true);
|
||||
//初始化
|
||||
onMounted(() => {
|
||||
getList();
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
</el-tabs>
|
||||
<!-- 列表组件 -->
|
||||
<div class="tabs-main-box">
|
||||
<billing-records v-if="activeName == 'BillingRecords'" v-hasPermi="['report:quotas:flow:list']"></billing-records>
|
||||
<billing-records v-if="activeName == 'BillingRecords'" ></billing-records>
|
||||
<account-changes v-if="activeName == 'AccountChanges'"></account-changes>
|
||||
<deposit-order v-if="activeName == 'DepositOrder'"></deposit-order>
|
||||
</div>
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
</template>
|
||||
|
||||
<!-- 稽核管理 -->
|
||||
<script setup name="User">
|
||||
<script setup name="BillingRecords">
|
||||
import BillingRecords from "./billingRecords/list.vue";
|
||||
import AccountChanges from "./accountChanges/list.vue";
|
||||
import DepositOrder from "./depositOrder/list.vue";
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@
|
|||
loading.value = true;
|
||||
await passwordForm.value.validate();
|
||||
let objForm = {
|
||||
password:form.value.newPassword
|
||||
newPassword:form.value.newPassword
|
||||
}
|
||||
// 这里添加实际的API调用
|
||||
updateUserPassword(objForm).then(response => {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,249 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
|
||||
<template #left>
|
||||
<el-form-item label="数据名称" prop="dataName">
|
||||
<el-input
|
||||
v-model="queryParams.dataName"
|
||||
placeholder="请输入数据名称"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template #right>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="Plus"
|
||||
@click="handleAdd"
|
||||
v-hasPermi="['site:data:source:save']"
|
||||
>新增</el-button>
|
||||
</template>
|
||||
</table-search-card>
|
||||
<el-table v-loading="loading" :data="postList" border>
|
||||
<el-table-column label="数据名称" align="center" prop="dataName" />
|
||||
<el-table-column label="驱动类名" align="center" prop="driverClassName" />
|
||||
<el-table-column label="地址" align="center" prop="address" />
|
||||
<el-table-column label="数据库用户名" align="center" prop="dbUsername" />
|
||||
<el-table-column label="最大使用量" align="center" prop="maxUse" />
|
||||
<el-table-column label="状态" align="center" prop="status">
|
||||
<template #default="scope">
|
||||
<base-switch v-model="scope.row.status" :active-value="1" :inactive-value="0"
|
||||
:before-change="() => beforeSwitchChange(scope.row, 'status')" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="180" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="handleUpdate(scope.row)" v-hasPermi="['site:data:source:update']">修改</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<!-- 添加或修改岗位对话框 -->
|
||||
<el-dialog :title="title" align-center v-if="open" v-model="open" width="800px" append-to-body>
|
||||
<el-form ref="postRef" :model="form" :rules="rules" label-width="150px">
|
||||
<el-form-item label="数据名称" prop="dataName">
|
||||
<el-input v-model="form.dataName" placeholder="请输入数据名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="驱动类名" prop="driverClassName">
|
||||
<el-input v-model="form.driverClassName" placeholder="请输入驱动类名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="地址" prop="address">
|
||||
<el-input v-model="form.address" placeholder="请输入地址" />
|
||||
</el-form-item>
|
||||
<el-form-item label="数据库端口" prop="dbPort">
|
||||
<el-input v-model="form.dbPort" placeholder="请输入数据库端口" />
|
||||
</el-form-item>
|
||||
<el-form-item label="数据库用户名" prop="dbUsername">
|
||||
<el-input v-model="form.dbUsername" placeholder="请输入数据库用户名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="数据库密码" prop="dbPassword">
|
||||
<el-input v-model="form.dbPassword" type="password" placeholder="请输入数据库密码"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="最大使用量" prop="maxUse">
|
||||
<el-input v-model="form.maxUse" placeholder="请输入最大使用量" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Post">
|
||||
import { listDataSource, addDataSourceSave, updateDataSource,switchDataSource } from "@/api/system/dataSourceManagement";
|
||||
import baseSwitch from "@/components/BaseSwitch";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
|
||||
|
||||
const postList = ref([]);
|
||||
const open = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const title = ref("");
|
||||
const oldForm = shallowRef({ });
|
||||
const data = reactive({
|
||||
form: {
|
||||
maxUse:2,
|
||||
},
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
dataName: "",
|
||||
},
|
||||
rules: {
|
||||
dataName: [{ required: true, message: "数据名称不能为空", trigger: "change" }],
|
||||
driverClassName: [{ required: true, message: "驱动类名不能为空", trigger: "change" }],
|
||||
address: [{ required: true, message: "地址不能为空", trigger: "change" }],
|
||||
dbPort: [{ required: true, message: "数据库端口不能为空", trigger: "change" }],
|
||||
dbUsername: [{ required: true, message: "数据库用户名不能为空", trigger: "change" }],
|
||||
dbPassword: [{ required: true, message: "数据库密码不能为空", trigger: "change" }],
|
||||
maxUse: [{ required: true, message: "最大使用量不能为空", trigger: "change" }],
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询岗位列表 */
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
listDataSource(queryParams.value).then(response => {
|
||||
postList.value = response.rows;
|
||||
total.value = response.total;
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
/** 取消按钮 */
|
||||
function cancel() {
|
||||
open.value = false;
|
||||
reset();
|
||||
}
|
||||
|
||||
/** 表单重置 */
|
||||
function reset() {
|
||||
form.value = {
|
||||
id: undefined,
|
||||
dataName: undefined,
|
||||
driverClassName:undefined,
|
||||
address: undefined,
|
||||
dbPort: undefined,
|
||||
dbUsername: undefined,
|
||||
dbPassword: undefined,
|
||||
maxUse: 2,
|
||||
};
|
||||
proxy.resetForm("postRef");
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
function resetQuery() {
|
||||
proxy.resetForm("queryRef");
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
/** 多选框选中数据 */
|
||||
function handleSelectionChange(selection) {
|
||||
ids.value = selection.map(item => item.postId);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
|
||||
/** 新增按钮操作 */
|
||||
function handleAdd() {
|
||||
reset();
|
||||
open.value = true;
|
||||
title.value = "新增数据源";
|
||||
}
|
||||
|
||||
/** 修改按钮操作 */
|
||||
function handleUpdate(row) {
|
||||
reset();
|
||||
const id = row.id || ids.value;
|
||||
form.value = row;
|
||||
open.value = true;
|
||||
oldForm.value = JSON.stringify(form.value);
|
||||
title.value = "修改数据源";
|
||||
}
|
||||
// 列表开关事件
|
||||
const beforeSwitchChange = async (row, undateKeys) => {
|
||||
const _status = row[undateKeys] === 1 ? 2 : 1
|
||||
const _data = {
|
||||
id: row.id
|
||||
}
|
||||
_data[undateKeys] = _status
|
||||
try {
|
||||
await switchDataSource(_data).then(() => {
|
||||
proxy.$modal.msgSuccess(_status === 1 ? proxy.t('开启成功') : proxy.t('关闭成功'))
|
||||
getList()
|
||||
})
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(proxy.t('接口调用失败'), error);
|
||||
return false; // 阻止开关状态改变
|
||||
}
|
||||
}
|
||||
/** 提交按钮 */
|
||||
function submitForm() {
|
||||
proxy.$refs["postRef"].validate(valid => {
|
||||
if (valid) {
|
||||
if (form.value.id != undefined) {
|
||||
if (JSON.stringify(form.value) != oldForm.value) {
|
||||
updateDataSource(form.value).then(response => {
|
||||
proxy.$modal.msgSuccess("修改成功");
|
||||
open.value = false;
|
||||
getList();
|
||||
});
|
||||
}else{
|
||||
open.value = false;
|
||||
}
|
||||
} else {
|
||||
addDataSourceSave(form.value).then(response => {
|
||||
proxy.$modal.msgSuccess("新增成功");
|
||||
open.value = false;
|
||||
getList();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
function handleExport() {
|
||||
proxy.download("system/post/export", {
|
||||
...queryParams.value
|
||||
}, `post_${new Date().getTime()}.xlsx`);
|
||||
}
|
||||
|
||||
getList();
|
||||
</script>
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
<el-table-column label="权限字符" align="center" prop="roleKey" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
<span>{{ formatTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ onActivated(() => {
|
|||
|
||||
// 路由跳转过来
|
||||
if (Object.keys(routeParams).length) {
|
||||
activeName.value = routeParams.activeName || 'auditManage';
|
||||
activeName.value = routeParams.activeName || 'userList';
|
||||
memberAccount.value = routeParams.memberAccount || '';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
</li>
|
||||
<li class="list-group-item">
|
||||
<svg-icon icon-class="date" />创建日期
|
||||
<div class="pull-right">{{ state.user.createTime }}</div>
|
||||
<div class="pull-right">{{ formatTime(state.user.createTime) }}</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="user-info-head" @click="editCropper()">
|
||||
<img :src="options.img" title="点击上传头像" class="img-circle img-lg" />
|
||||
<el-dialog :title="title" align-center v-model="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog">
|
||||
<el-dialog :title="title" v-model="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog">
|
||||
<el-row>
|
||||
<el-col :xs="24" :md="12" :style="{ height: '350px' }">
|
||||
<vue-cropper
|
||||
|
|
@ -63,17 +63,19 @@ import "vue-cropper/dist/index.css";
|
|||
import { VueCropper } from "vue-cropper";
|
||||
import { uploadAvatar } from "@/api/system/user";
|
||||
import useUserStore from "@/store/modules/user";
|
||||
import { getLocalStorage } from "@/utils/auth";
|
||||
|
||||
const userStore = useUserStore();
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const fileHost = getLocalStorage('fileUrl') || ''; // 文件host
|
||||
const open = ref(false);
|
||||
const visible = ref(false);
|
||||
const title = ref("修改头像");
|
||||
|
||||
//图片裁剪数据
|
||||
const options = reactive({
|
||||
img: userStore.avatar, // 裁剪图片的地址
|
||||
img: fileHost + userStore.avatar, // 裁剪图片的地址
|
||||
autoCrop: true, // 是否默认生成截图框
|
||||
autoCropWidth: 200, // 默认生成截图框宽度
|
||||
autoCropHeight: 200, // 默认生成截图框高度
|
||||
|
|
@ -133,7 +135,7 @@ function uploadImg() {
|
|||
formData.append("avatarfile", data, options.filename);
|
||||
uploadAvatar(formData).then(response => {
|
||||
open.value = false;
|
||||
options.img = import.meta.env.VITE_APP_BASE_API + response.imgUrl;
|
||||
options.img = response.imgUrl;
|
||||
userStore.avatar = options.img;
|
||||
proxy.$modal.msgSuccess("修改成功");
|
||||
visible.value = false;
|
||||
|
|
@ -148,7 +150,7 @@ function realTime(data) {
|
|||
|
||||
/** 关闭窗口 */
|
||||
function closeDialog() {
|
||||
options.img = userStore.avatar;
|
||||
options.img = fileHost + userStore.avatar;
|
||||
options.visible = false;
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,221 +0,0 @@
|
|||
# 权限树状表格组件使用说明
|
||||
|
||||
## 概述
|
||||
|
||||
这个权限树状表格组件实现了类似表格的树形权限管理界面,左侧显示树形菜单结构,右侧显示对应的权限复选框,完全符合您截图中的设计需求。
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
src/views/system/user/role/
|
||||
├── render.vue # 核心权限树状表格组件
|
||||
├── permission-dialog.vue # 权限选择对话框组件
|
||||
├── permission-example.vue # 完整使用示例
|
||||
└── README.md # 使用说明
|
||||
```
|
||||
|
||||
## 核心功能
|
||||
|
||||
### 1. 树状表格展示
|
||||
- 表格样式的树形结构展示
|
||||
- 支持多级树形结构
|
||||
- 可展开/收起节点
|
||||
- 支持节点复选框选择(含半选状态)
|
||||
|
||||
### 2. 权限复选框管理
|
||||
- 每个节点可以配置独立的权限项
|
||||
- 权限项以复选框形式展示在右侧
|
||||
- 支持权限项的选中状态管理
|
||||
- 支持热门权限标记
|
||||
|
||||
### 3. 表格式布局
|
||||
- 左侧:菜单名称列(支持树形缩进)
|
||||
- 右侧:权限操作列(权限复选框)
|
||||
- 表格头部标题
|
||||
- 行分隔线和悬停效果
|
||||
|
||||
## 数据结构
|
||||
|
||||
```javascript
|
||||
const treeData = [
|
||||
{
|
||||
id: 1, // 节点唯一标识
|
||||
label: '开站管理', // 节点显示名称
|
||||
children: [ // 子节点(可选)
|
||||
{
|
||||
id: 11,
|
||||
label: '待审核',
|
||||
perms: [] // 权限列表(可选)
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
label: '待付款',
|
||||
perms: [ // 权限项配置
|
||||
{
|
||||
key: 'pay',
|
||||
label: '付款',
|
||||
checked: false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 15,
|
||||
label: '已上线',
|
||||
perms: [
|
||||
{
|
||||
key: 'add_brand',
|
||||
label: '新增子品牌',
|
||||
checked: false,
|
||||
isHot: true // 热门权限标记
|
||||
},
|
||||
{
|
||||
key: 'edit',
|
||||
label: '修改',
|
||||
checked: false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 1. 基础使用
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<PermissionTreeTable ref="treeTableRef" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import PermissionTreeTable from './render.vue'
|
||||
|
||||
const treeTableRef = ref()
|
||||
|
||||
// 获取选中的数据
|
||||
const getSelectedData = () => {
|
||||
if (treeTableRef.value) {
|
||||
return treeTableRef.value.getCheckedData()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
### 2. 对话框形式使用
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<PermissionDialog
|
||||
v-model="dialogVisible"
|
||||
:role-id="currentRoleId"
|
||||
@confirm="handlePermissionConfirm"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import PermissionDialog from './permission-dialog.vue'
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const currentRoleId = ref(1)
|
||||
|
||||
const handlePermissionConfirm = (data) => {
|
||||
console.log('选中的权限:', data)
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## 样式说明
|
||||
|
||||
### 1. 表格式布局
|
||||
- 使用 CSS Grid 布局实现表格效果
|
||||
- 左列:菜单名称(固定宽度 300px)
|
||||
- 右列:权限操作(自适应宽度)
|
||||
- 表格头部和内容分离
|
||||
|
||||
### 2. 主要样式类名
|
||||
- `.permission-tree-table`: 组件容器
|
||||
- `.table-header`: 表格头部
|
||||
- `.table-content`: 表格内容区域
|
||||
- `.table-row`: 每行的容器
|
||||
- `.row-left`: 左侧菜单名称区域
|
||||
- `.row-right`: 右侧权限操作区域
|
||||
- `.expand-icon`: 展开/收起图标
|
||||
- `.hot-tag`: 热门权限标记
|
||||
|
||||
### 3. 核心样式
|
||||
```css
|
||||
.permission-tree-table {
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
display: grid;
|
||||
grid-template-columns: 300px 1fr;
|
||||
background: #f5f7fa;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
display: grid;
|
||||
grid-template-columns: 300px 1fr;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.table-row:hover {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
```
|
||||
|
||||
## API 说明
|
||||
|
||||
### Props
|
||||
- `modelValue`: 对话框显示状态(仅对话框组件)
|
||||
- `roleId`: 角色ID(可选)
|
||||
|
||||
### Events
|
||||
- `confirm`: 确认选择权限时触发,返回选中的权限数据
|
||||
|
||||
### Methods
|
||||
- `getCheckedData()`: 获取当前选中的数据
|
||||
- 返回格式:
|
||||
```javascript
|
||||
{
|
||||
checkedNodes: [ // 选中的节点
|
||||
{ id: 1, label: '开站管理' }
|
||||
],
|
||||
checkedPermissions: { // 选中的权限
|
||||
"12": [
|
||||
{ key: 'pay', label: '付款' }
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 扩展功能
|
||||
|
||||
### 1. 权限标记
|
||||
可以为特定权限添加标记(如"热门"标记):
|
||||
|
||||
```javascript
|
||||
const isHot = perm === '新增子品牌'
|
||||
// 在渲染时添加标记
|
||||
h('span', { class: 'hot-tag' }, '热')
|
||||
```
|
||||
|
||||
### 2. 权限分组
|
||||
可以通过树形结构对权限进行分组管理。
|
||||
|
||||
### 3. 权限搜索
|
||||
可以添加搜索功能来快速定位特定权限。
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 确保每个节点的 `id` 唯一
|
||||
2. `perms` 数组为空时不会显示权限复选框
|
||||
3. 权限状态通过 `permissionState` 响应式对象管理
|
||||
4. 使用 `:deep()` 选择器来修改 Element Plus 组件的默认样式
|
||||
|
|
@ -70,7 +70,7 @@
|
|||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
<span>{{ formatTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
|
|
@ -91,7 +91,7 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="User">
|
||||
<script setup name="AuthUser">
|
||||
import selectUser from "./selectUser";
|
||||
import { allocatedUserList, authUserCancel, authUserCancelAll } from "@/api/system/role";
|
||||
|
||||
|
|
@ -108,7 +108,7 @@ const userIds = ref([]);
|
|||
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
pageSize: 20,
|
||||
roleId: route.params.roleId,
|
||||
userName: undefined,
|
||||
phonenumber: undefined,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,78 +0,0 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
align-center
|
||||
title="新增权限"
|
||||
width="800px"
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<div class="permission-dialog">
|
||||
<PermissionTreeTable ref="treeTableRef" />
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirm">确认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import PermissionTreeTable from './render.vue'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
roleId: {
|
||||
type: [String, Number],
|
||||
default: null
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'confirm'])
|
||||
|
||||
const treeTableRef = ref()
|
||||
|
||||
const dialogVisible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (val) => emit('update:modelValue', val)
|
||||
})
|
||||
|
||||
// 获取选中的权限数据
|
||||
const getSelectedPermissions = () => {
|
||||
if (treeTableRef.value) {
|
||||
return treeTableRef.value.getCheckedData()
|
||||
}
|
||||
return { checkedNodes: [], checkedPermissions: {} }
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
dialogVisible.value = false
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
dialogVisible.value = false
|
||||
}
|
||||
|
||||
const handleConfirm = () => {
|
||||
const selectedData = getSelectedPermissions()
|
||||
emit('confirm', selectedData)
|
||||
dialogVisible.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.permission-dialog {
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,195 +0,0 @@
|
|||
<template>
|
||||
<div class="permission-example">
|
||||
<div class="header">
|
||||
<h2>权限树使用示例</h2>
|
||||
<el-button type="primary" @click="showPermissionDialog">
|
||||
新增权限
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 权限对话框 -->
|
||||
<PermissionDialog
|
||||
v-model="dialogVisible"
|
||||
:role-id="currentRoleId"
|
||||
@confirm="handlePermissionConfirm"
|
||||
/>
|
||||
|
||||
<!-- 直接展示权限树状表格 -->
|
||||
<div class="tree-container">
|
||||
<h3>权限树状表格展示:</h3>
|
||||
<PermissionTreeTable ref="treeTableRef" />
|
||||
|
||||
<div class="action-buttons">
|
||||
<el-button @click="getSelectedData">获取选中数据</el-button>
|
||||
<el-button type="primary" @click="savePermissions">保存权限</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 已选权限展示 -->
|
||||
<div v-if="selectedData" class="selected-permissions">
|
||||
<h3>已选择的权限:</h3>
|
||||
|
||||
<div class="permission-summary">
|
||||
<div class="section">
|
||||
<h4>选中的节点:</h4>
|
||||
<div class="node-list">
|
||||
<el-tag
|
||||
v-for="node in selectedData.checkedNodes"
|
||||
:key="node.id"
|
||||
size="small"
|
||||
class="node-tag"
|
||||
>
|
||||
{{ node.label }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h4>选中的权限:</h4>
|
||||
<div v-for="(perms, nodeId) in selectedData.checkedPermissions" :key="nodeId" class="node-permissions">
|
||||
<strong>节点 {{ nodeId }}:</strong>
|
||||
<el-tag
|
||||
v-for="perm in perms"
|
||||
:key="perm.key"
|
||||
size="small"
|
||||
type="success"
|
||||
class="perm-tag"
|
||||
>
|
||||
{{ perm.label }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import PermissionDialog from './permission-dialog.vue'
|
||||
import PermissionTreeTable from './render.vue'
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const currentRoleId = ref(1)
|
||||
const selectedData = ref(null)
|
||||
const treeTableRef = ref()
|
||||
|
||||
const showPermissionDialog = () => {
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const handlePermissionConfirm = (data) => {
|
||||
console.log('确认选择的权限:', data)
|
||||
selectedData.value = data
|
||||
|
||||
// 这里可以调用API保存权限
|
||||
// await saveRolePermissions(currentRoleId.value, data)
|
||||
}
|
||||
|
||||
const getSelectedData = () => {
|
||||
if (treeTableRef.value) {
|
||||
const data = treeTableRef.value.getCheckedData()
|
||||
selectedData.value = data
|
||||
console.log('当前选中的数据:', data)
|
||||
}
|
||||
}
|
||||
|
||||
const savePermissions = async () => {
|
||||
const data = getSelectedData()
|
||||
if (data) {
|
||||
try {
|
||||
// 这里调用保存权限的API
|
||||
// await saveRolePermissions(currentRoleId.value, data)
|
||||
console.log('保存权限成功:', data)
|
||||
// 显示成功消息
|
||||
// ElMessage.success('权限保存成功')
|
||||
} catch (error) {
|
||||
console.error('保存权限失败:', error)
|
||||
// ElMessage.error('权限保存失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.permission-example {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.tree-container {
|
||||
margin-bottom: 30px;
|
||||
padding: 20px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
margin-top: 20px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.action-buttons .el-button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.selected-permissions {
|
||||
margin-top: 20px;
|
||||
padding: 20px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.permission-summary {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.section h4 {
|
||||
margin: 0 0 10px 0;
|
||||
color: #303133;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.node-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.node-permissions {
|
||||
margin-bottom: 15px;
|
||||
padding: 10px;
|
||||
background: white;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.node-permissions strong {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
color: #303133;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.node-tag,
|
||||
.perm-tag {
|
||||
margin-right: 8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.node-tag {
|
||||
background-color: #409eff;
|
||||
border-color: #409eff;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,588 +0,0 @@
|
|||
<template>
|
||||
<div class="table">
|
||||
<!-- default-expand-all 默认展开全部数据 -->
|
||||
<!-- expand-on-click-node 只有点击箭头才会收缩节点 -->
|
||||
<!-- check-on-click-node 点击文本选中 -->
|
||||
<!-- show-checkbox 复选框 -->
|
||||
<div class="menu-list">
|
||||
<el-tree ref="tree" :data="list" default-expand-all :expand-on-click-node='false' check-on-click-node show-checkbox node-key="menuId" :props="defaultProps"></el-tree>
|
||||
</div>
|
||||
<el-button @click="getCheckedKeys">通过 key 获取</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
list: [
|
||||
{
|
||||
"menuId": 1,
|
||||
"menuName": "首页(首页)",
|
||||
"menuCode": "首页",
|
||||
"parentId": 0,
|
||||
"orderNum": 0,
|
||||
"path": "/page",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 0,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "iconfont icon-shouye",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 1,
|
||||
"children": [
|
||||
{
|
||||
"menuId": 2,
|
||||
"menuName": "首页(首页)",
|
||||
"menuCode": "首页",
|
||||
"parentId": 1,
|
||||
"orderNum": 1,
|
||||
"path": "/welcome",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"menuId": 3,
|
||||
"menuName": "随访数据查询(随访数据查询)",
|
||||
"menuCode": "随访数据查询",
|
||||
"parentId": 0,
|
||||
"orderNum": 1,
|
||||
"path": "/followUpDataQuery",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 0,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "iconfont icon-shengwuxuejiance",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 1,
|
||||
"children": [
|
||||
{
|
||||
"menuId": 4,
|
||||
"menuName": "随访数据查询(随访数据查询)",
|
||||
"menuCode": "随访数据查询",
|
||||
"parentId": 3,
|
||||
"orderNum": 1,
|
||||
"path": "index",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
},
|
||||
{
|
||||
"menuId": 5,
|
||||
"menuName": "随访详情(随访详情)",
|
||||
"menuCode": "随访详情",
|
||||
"parentId": 3,
|
||||
"orderNum": 2,
|
||||
"path": "detail",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"menuId": 21,
|
||||
"menuName": "此单名称(11)",
|
||||
"menuCode": "11",
|
||||
"parentId": 0,
|
||||
"orderNum": 1,
|
||||
"path": "请问请问饿```",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 0,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "321",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 1,
|
||||
// "children": null
|
||||
},
|
||||
{
|
||||
"menuId": 6,
|
||||
"menuName": "调查数据查询(调查数据查询)",
|
||||
"menuCode": "调查数据查询",
|
||||
"parentId": 0,
|
||||
"orderNum": 2,
|
||||
"path": "/surveyDataQuery",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 0,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "iconfont icon-shaichaxinxichaxun",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 1,
|
||||
"children": [
|
||||
{
|
||||
"menuId": 7,
|
||||
"menuName": "调查数据查询(调查数据查询)",
|
||||
"menuCode": "调查数据查询",
|
||||
"parentId": 6,
|
||||
"orderNum": 1,
|
||||
"path": "index",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
},
|
||||
{
|
||||
"menuId": 8,
|
||||
"menuName": "新建问卷(新建问卷)",
|
||||
"menuCode": "新建问卷",
|
||||
"parentId": 6,
|
||||
"orderNum": 2,
|
||||
"path": "evaluationreport",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
},
|
||||
{
|
||||
"menuId": 9,
|
||||
"menuName": "随访详情(随访详情)",
|
||||
"menuCode": "随访详情",
|
||||
"parentId": 6,
|
||||
"orderNum": 3,
|
||||
"path": "evaluationlook",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"menuId": 10,
|
||||
"menuName": "任务配置(任务配置)",
|
||||
"menuCode": "任务配置",
|
||||
"parentId": 0,
|
||||
"orderNum": 3,
|
||||
"path": "/taskSet",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 0,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "iconfont icon-renwuguanli",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 1,
|
||||
"children": [
|
||||
{
|
||||
"menuId": 11,
|
||||
"menuName": "任务配置(任务配置)",
|
||||
"menuCode": "任务配置",
|
||||
"parentId": 10,
|
||||
"orderNum": 1,
|
||||
"path": "index",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"menuId": 12,
|
||||
"menuName": "数据统计(数据统计)",
|
||||
"menuCode": "数据统计",
|
||||
"parentId": 0,
|
||||
"orderNum": 4,
|
||||
"path": "/dataStatistics",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 0,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "iconfont icon-shujutongji",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 1,
|
||||
"children": [
|
||||
{
|
||||
"menuId": 13,
|
||||
"menuName": "数据统计(数据统计)",
|
||||
"menuCode": "数据统计",
|
||||
"parentId": 12,
|
||||
"orderNum": 1,
|
||||
"path": "index",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"menuId": 14,
|
||||
"menuName": "数据导出(数据导出)",
|
||||
"menuCode": "数据导出",
|
||||
"parentId": 0,
|
||||
"orderNum": 5,
|
||||
"path": "/dataExport",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 0,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "iconfont icon-suifangrenwuguanli",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 1,
|
||||
"children": [
|
||||
{
|
||||
"menuId": 15,
|
||||
"menuName": "数据导出(数据导出)",
|
||||
"menuCode": "数据导出",
|
||||
"parentId": 14,
|
||||
"orderNum": 1,
|
||||
"path": "index",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"menuId": 16,
|
||||
"menuName": "系统管理(系统管理)",
|
||||
"menuCode": "系统管理",
|
||||
"parentId": 0,
|
||||
"orderNum": 6,
|
||||
"path": "/systemManage",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 0,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "iconfont icon-xitongguanli",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 1,
|
||||
"children": [
|
||||
{
|
||||
"menuId": 17,
|
||||
"menuName": "用户管理(用户管理)",
|
||||
"menuCode": "用户管理",
|
||||
"parentId": 16,
|
||||
"orderNum": 1,
|
||||
"path": "usersManage",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
},
|
||||
{
|
||||
"menuId": 18,
|
||||
"menuName": "角色管理(角色管理)",
|
||||
"menuCode": "角色管理",
|
||||
"parentId": 16,
|
||||
"orderNum": 2,
|
||||
"path": "roleManage",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
},
|
||||
{
|
||||
"menuId": 19,
|
||||
"menuName": "权限配置(权限配置)",
|
||||
"menuCode": "权限配置",
|
||||
"parentId": 16,
|
||||
"orderNum": 3,
|
||||
"path": "permissionSetting",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
},
|
||||
{
|
||||
"menuId": 20,
|
||||
"menuName": "菜单管理(菜单管理)",
|
||||
"menuCode": "菜单管理",
|
||||
"parentId": 16,
|
||||
"orderNum": 4,
|
||||
"path": "menuManage",
|
||||
"component": null,
|
||||
"query": null,
|
||||
"isFrame": 0,
|
||||
"isCache": 0,
|
||||
"menuType": 1,
|
||||
"visible": 1,
|
||||
"perms": null,
|
||||
"icon": "",
|
||||
"status": 1,
|
||||
"remark": null,
|
||||
"roleId": null,
|
||||
"selected": true,
|
||||
"level": 2,
|
||||
"children": null
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
defaultProps: {
|
||||
children: 'children', // 子级
|
||||
label: 'menuName' // 名称
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
// 回显菜单
|
||||
this.setCheckedKeys()
|
||||
},
|
||||
methods: {
|
||||
// 提交数据
|
||||
getCheckedKeys () {
|
||||
// 获取子级的key
|
||||
const childMenu = this.$refs.tree.getCheckedKeys()
|
||||
// 获取父级的key
|
||||
const partMenu = this.$refs.tree.getHalfCheckedKeys()
|
||||
// 合并数据
|
||||
const menu = partMenu.concat(childMenu)
|
||||
console.log(menu)
|
||||
},
|
||||
|
||||
// 回显菜单
|
||||
setCheckedKeys () {
|
||||
// 一般是调接口,拿到菜单数据和回显的菜单数组
|
||||
|
||||
// 如果default-expand-all没有展开列表时,可以使用下面代码,设置展开所有行,
|
||||
// const nodesMap = this.$refs.tree.store.nodesMap
|
||||
// const keys = Object.keys(nodesMap)
|
||||
// keys.forEach(key => {
|
||||
// nodesMap[key].expanded = true
|
||||
// })
|
||||
|
||||
// 设置回显的菜单
|
||||
this.$nextTick(() => {
|
||||
this.$refs.tree.setCheckedKeys([3])
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.table {
|
||||
padding: 20px;
|
||||
min-height: 88vh;
|
||||
background: #fff;
|
||||
margin: 20px;
|
||||
}
|
||||
.menu-list {
|
||||
::v-deep .el-tree {
|
||||
border-top: 1px solid #ebeef5;
|
||||
border-left: 1px solid #ebeef5;
|
||||
border-right: 1px solid #ebeef5;
|
||||
.el-tree-node__expand-icon {
|
||||
display: none !important;
|
||||
}
|
||||
.el-tree-node {
|
||||
&.is-expanded,
|
||||
&.is-current,
|
||||
&.is-focusable {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
.el-tree-node__content {
|
||||
background-color: transparent !important;
|
||||
&:hover {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
> .el-tree-node {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
position: relative;
|
||||
> .el-tree-node__content {
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
padding-left: 20px !important;
|
||||
}
|
||||
.el-tree-node__children {
|
||||
position: relative;
|
||||
&::after {
|
||||
content: ' ';
|
||||
display: block;
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
border-left: 1px solid #ebeef5;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
}
|
||||
.el-tree-node {
|
||||
width: 350px;
|
||||
padding: 10px 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<!-- 授权用户 -->
|
||||
<el-dialog title="选择用户" align-center v-model="visible" width="800px" top="5vh" append-to-body>
|
||||
<el-dialog title="选择用户" v-model="visible" width="800px" top="5vh" append-to-body>
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true">
|
||||
<el-form-item label="用户名称" prop="userName">
|
||||
<el-input
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
<span>{{ formatTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
|
@ -60,7 +60,7 @@
|
|||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup name="User">
|
||||
<script setup name="SelectUser">
|
||||
import { authUserSelectAll, unallocatedUserList } from "@/api/system/role";
|
||||
|
||||
const props = defineProps({
|
||||
|
|
@ -79,7 +79,7 @@ const userIds = ref([]);
|
|||
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
pageSize: 20,
|
||||
roleId: undefined,
|
||||
userName: undefined,
|
||||
phonenumber: undefined
|
||||
|
|
|
|||
|
|
@ -1,132 +0,0 @@
|
|||
<template>
|
||||
<div class="test-page">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>权限树状表格测试页面</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 权限树状表格 -->
|
||||
<PermissionTreeTable ref="treeTableRef" />
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="actions">
|
||||
<el-button @click="getSelectedData">获取选中数据</el-button>
|
||||
<el-button type="primary" @click="showDialog">打开对话框</el-button>
|
||||
<el-button type="success" @click="setDefaultData">设置默认选中</el-button>
|
||||
<el-button type="warning" @click="clearAll">清空所有</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 结果展示 -->
|
||||
<div v-if="selectedData" class="result">
|
||||
<h3>选中结果:</h3>
|
||||
<el-alert
|
||||
title="数据获取成功"
|
||||
type="success"
|
||||
:closable="false"
|
||||
show-icon
|
||||
/>
|
||||
<pre>{{ JSON.stringify(selectedData, null, 2) }}</pre>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 对话框测试 -->
|
||||
<PermissionDialog
|
||||
v-model="dialogVisible"
|
||||
@confirm="handleDialogConfirm"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import PermissionTreeTable from './render.vue'
|
||||
import PermissionDialog from './permission-dialog.vue'
|
||||
|
||||
const treeTableRef = ref()
|
||||
const dialogVisible = ref(false)
|
||||
const selectedData = ref(null)
|
||||
|
||||
// 获取选中数据
|
||||
const getSelectedData = () => {
|
||||
if (treeTableRef.value) {
|
||||
const data = treeTableRef.value.getCheckedData()
|
||||
selectedData.value = data
|
||||
console.log('选中的数据:', data)
|
||||
}
|
||||
}
|
||||
|
||||
// 显示对话框
|
||||
const showDialog = () => {
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
// 处理对话框确认
|
||||
const handleDialogConfirm = (data) => {
|
||||
selectedData.value = data
|
||||
console.log('对话框确认的数据:', data)
|
||||
}
|
||||
|
||||
// 设置默认选中数据(示例)
|
||||
const setDefaultData = () => {
|
||||
// 这里可以实现设置默认选中状态的逻辑
|
||||
console.log('设置默认选中数据')
|
||||
// 由于当前实现是内部状态管理,这里只是示例
|
||||
// 实际使用时可能需要通过props传入初始状态
|
||||
}
|
||||
|
||||
// 清空所有选中
|
||||
const clearAll = () => {
|
||||
// 这里可以实现清空所有选中状态的逻辑
|
||||
console.log('清空所有选中')
|
||||
selectedData.value = null
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.test-page {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.actions {
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.actions .el-button {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.result {
|
||||
margin-top: 20px;
|
||||
padding: 20px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.result h3 {
|
||||
margin-top: 0;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.result pre {
|
||||
background: #fff;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #e4e7ed;
|
||||
overflow-x: auto;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.el-alert {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
<template>
|
||||
<!-- 账户详情 -->
|
||||
<el-dialog :title="t('账户详情')" align-center v-model="showDialog" width="700px" append-to-body
|
||||
class="el-dialog">
|
||||
<el-scrollbar max-height="700px">
|
||||
<el-descriptions :column="1" border class="c-descriptions">
|
||||
<el-descriptions-item :label="t('所属部门')" label-width="150">
|
||||
{{ modifyDate.dept?.deptName||'--' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="t('后台账号')" label-width="150" >
|
||||
{{ modifyDate.userName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="t('后台昵称')" label-width="150">
|
||||
{{ modifyDate.nickName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="t('权限名称')" label-width="150">
|
||||
{{ modifyDate.roleName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="t('创建人')" label-width="150">
|
||||
{{ modifyDate.updateBy||modifyDate.createBy }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="t('创建时间')" label-width="150">
|
||||
{{ formatTime(modifyDate.createTime) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="t('最后登录方式')" label-width="150">
|
||||
{{ t('密码登录') }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="t('最后登录时间')" label-width="150">
|
||||
{{ formatTime(modifyDate.loginDate) || '--' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="t('最后登出时间')" label-width="150">
|
||||
{{ formatTime(modifyDate.exitDate) || '--' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="t('最后登入IP')" label-width="150">
|
||||
{{ modifyDate.loginIp || '--' }}
|
||||
</el-descriptions-item>
|
||||
|
||||
|
||||
</el-descriptions>
|
||||
</el-scrollbar>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="closeDialog">{{ t('取 消') }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import { nextTick, ref } from "vue";
|
||||
const { proxy } = getCurrentInstance()
|
||||
const emits = defineEmits(['submit', 'update:show']) // 自定义事件
|
||||
const props = defineProps({ // 父组件向子组件传值
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
modifyDate: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
})
|
||||
const showDialog = computed({// 对话框显示隐藏
|
||||
get() {
|
||||
return props.show
|
||||
},
|
||||
set(value) {
|
||||
emits('update:show', value)
|
||||
}
|
||||
})
|
||||
|
||||
const formAll = reactive({ // 表单验证数据
|
||||
id: '',
|
||||
rewardAmount:'',
|
||||
auditRate:'',
|
||||
remark:'',
|
||||
password:''
|
||||
})
|
||||
|
||||
//数据更新区域
|
||||
nextTick(() => {
|
||||
formAll.id = props.modifyDate.id;
|
||||
})
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
});
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
showDialog.value = false
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scope lang="scss">
|
||||
.icon-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
}
|
||||
.disable-click {
|
||||
pointer-events: none;
|
||||
}
|
||||
.clt-item {
|
||||
.label-box {
|
||||
vertical-align: middle;
|
||||
width: 150px;
|
||||
text-align: right;
|
||||
padding-right: 12px;
|
||||
word-break: break-all;
|
||||
line-height: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:deep(.el-form-item__error) {
|
||||
padding-left: 150px;
|
||||
}
|
||||
|
||||
.item-right {
|
||||
width: calc(100% - 150px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
<template>
|
||||
<!-- Google验证码 -->
|
||||
<el-dialog v-model="showDialog" align-center width="500px" append-to-body
|
||||
class="el-dialog">
|
||||
<template #title>
|
||||
<div class="title" style="width: 100%;text-align: center;">Google验证码</div>
|
||||
</template>
|
||||
<el-form :model="formGoogle" :rules="rulesGoogle" ref="googleRef" label-width="130px">
|
||||
<el-form-item label="Google验证码" prop="googleCode">
|
||||
<el-input v-model="formGoogle.googleCode" placeholder="请输入您的Google验证码" maxlength="6" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer" style="display: flex;justify-content: center;">
|
||||
<el-button @click="showDialog = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitGoogle">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import { nextTick, ref } from "vue";
|
||||
const { proxy } = getCurrentInstance()
|
||||
const emits = defineEmits(['submit', 'update:show']) // 自定义事件
|
||||
const props = defineProps({ // 父组件向子组件传值
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
modifyDate: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
})
|
||||
const showDialog = computed({// 对话框显示隐藏
|
||||
get() {
|
||||
return props.show
|
||||
},
|
||||
set(value) {
|
||||
emits('update:show', value)
|
||||
}
|
||||
})
|
||||
|
||||
const rulesGoogle = reactive({
|
||||
googleCode: [{ required: true, message: "请输入谷歌验证码", trigger: "change" }]
|
||||
});
|
||||
const formGoogle = reactive({
|
||||
googleCode: ''
|
||||
});
|
||||
|
||||
//数据更新区域
|
||||
nextTick(() => {
|
||||
|
||||
})
|
||||
const submitGoogle = () => {
|
||||
proxy.$refs["googleRef"].validate(valid => {
|
||||
if (valid) {
|
||||
emits('submit', formGoogle.googleCode)
|
||||
}
|
||||
})
|
||||
}
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
});
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
showDialog.value = false
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scope lang="scss">
|
||||
.icon-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
}
|
||||
.disable-click {
|
||||
pointer-events: none;
|
||||
}
|
||||
.clt-item {
|
||||
.label-box {
|
||||
vertical-align: middle;
|
||||
width: 150px;
|
||||
text-align: right;
|
||||
padding-right: 12px;
|
||||
word-break: break-all;
|
||||
line-height: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:deep(.el-form-item__error) {
|
||||
padding-left: 150px;
|
||||
}
|
||||
|
||||
.item-right {
|
||||
width: calc(100% - 150px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<template>
|
||||
<div>
|
||||
<div style="margin-bottom: 10px;">
|
||||
<span>批量数量:</span>
|
||||
<b>{{ batchCount }}</b>
|
||||
</div>
|
||||
|
||||
<el-form :model="form">
|
||||
<el-form-item label="操作类型">
|
||||
<el-select v-model="form.actionType" placeholder="请选择操作类型" style="width: 300px">
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive } from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
batchCount: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
options: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
});
|
||||
|
||||
const form = reactive({
|
||||
actionType: ""
|
||||
});
|
||||
|
||||
// 这里可以暴露给外部取值
|
||||
defineExpose({ form });
|
||||
</script>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -27,9 +27,9 @@ export default defineConfig(({ mode, command }) => {
|
|||
proxy: {
|
||||
'/dev-api': {
|
||||
// target: 'http://192.168.50.139:9080',
|
||||
// target: 'http://192.168.50.233:8081',
|
||||
target: 'http://192.168.50.233:8081',
|
||||
// target: 'http://192.168.50.178:8080',
|
||||
target: 'http://192.168.50.11:8081',
|
||||
// target: 'http://192.168.50.11:8081',
|
||||
changeOrigin: true,
|
||||
rewrite: (p) => p.replace(/^\/dev-api/, '')
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue