mirror of
https://gitee.com/mirrors/AllinSSL.git
synced 2026-05-01 09:31:27 +08:00
【新增】在翻译文件中添加多吉云AccessKey和SecretKey的相关翻译,更新阿里云ESA的配置接口,优化CA管理功能,增强表单验证逻辑,提升用户体验。
This commit is contained in:
@@ -11217,5 +11217,73 @@
|
||||
"arDZ": "الرجاء إدخال المعلمات بتنسيق JSON، على سبيل المثال:"
|
||||
},
|
||||
"timestamp": "2025-06-18T01:38:26.776Z"
|
||||
},
|
||||
"请输入多吉云AccessKey": {
|
||||
"text": "请输入多吉云AccessKey",
|
||||
"key": "t_0_1750320239265",
|
||||
"translations": {
|
||||
"zhCN": "请输入多吉云AccessKey",
|
||||
"zhTW": "請輸入多吉雲AccessKey",
|
||||
"enUS": "Please enter DogeCloud AccessKey",
|
||||
"jaJP": "DogeCloudのAccessKeyを入力してください",
|
||||
"koKR": "DogeCloud AccessKey를 입력하세요",
|
||||
"ruRU": "Пожалуйста, введите DogeCloud AccessKey",
|
||||
"ptBR": "Por favor, insira o AccessKey do DogeCloud",
|
||||
"frFR": "Veuillez entrer la clé d'accès DogeCloud",
|
||||
"esAR": "Por favor ingrese la AccessKey de DogeCloud",
|
||||
"arDZ": "الرجاء إدخال مفتاح الوصول DogeCloud"
|
||||
},
|
||||
"timestamp": "2025-06-19T08:04:01.428Z"
|
||||
},
|
||||
"请输入多吉云SecretKey": {
|
||||
"text": "请输入多吉云SecretKey",
|
||||
"key": "t_1_1750320241427",
|
||||
"translations": {
|
||||
"zhCN": "请输入多吉云SecretKey",
|
||||
"zhTW": "請輸入多吉雲SecretKey",
|
||||
"enUS": "Please enter DogeCloud SecretKey",
|
||||
"jaJP": "ドージークラウドのSecretKeyを入力してください",
|
||||
"koKR": "도지클라우드 SecretKey를 입력하세요",
|
||||
"ruRU": "Пожалуйста, введите SecretKey DogeCloud",
|
||||
"ptBR": "Por favor, insira a SecretKey do DogeCloud",
|
||||
"frFR": "Veuillez entrer la SecretKey de DogeCloud",
|
||||
"esAR": "Por favor ingrese la SecretKey de DogeCloud",
|
||||
"arDZ": "الرجاء إدخال مفتاح SecretKey الخاص بـ DogeCloud"
|
||||
},
|
||||
"timestamp": "2025-06-19T08:04:01.428Z"
|
||||
},
|
||||
"跳过发送通知": {
|
||||
"text": "跳过发送通知",
|
||||
"key": "t_2_1750320237611",
|
||||
"translations": {
|
||||
"zhCN": "跳过发送通知",
|
||||
"zhTW": "跳過發送通知",
|
||||
"enUS": "Skip sending notification",
|
||||
"jaJP": "通知の送信をスキップ",
|
||||
"koKR": "알림 보내기 건너뛰기",
|
||||
"ruRU": "Пропустить отправку уведомления",
|
||||
"ptBR": "Pular envio de notificação",
|
||||
"frFR": "Ignorer l'envoi de notification",
|
||||
"esAR": "Omitir el envío de notificación",
|
||||
"arDZ": "تخطي إرسال الإشعار"
|
||||
},
|
||||
"timestamp": "2025-06-19T08:04:01.428Z"
|
||||
},
|
||||
"发送": {
|
||||
"text": "发送",
|
||||
"key": "t_3_1750320237991",
|
||||
"translations": {
|
||||
"zhCN": "发送",
|
||||
"zhTW": "發送",
|
||||
"enUS": "Send",
|
||||
"jaJP": "送信",
|
||||
"koKR": "보내기",
|
||||
"ruRU": "Отправить",
|
||||
"ptBR": "Enviar",
|
||||
"frFR": "Envoyer",
|
||||
"esAR": "Enviar",
|
||||
"arDZ": "إرسال"
|
||||
},
|
||||
"timestamp": "2025-06-19T08:04:01.428Z"
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import { Transition, type Component as ComponentType, h } from 'vue'
|
||||
import { RouterView } from 'vue-router'
|
||||
import CustomProvider from '@baota/naive-ui/components/customProvider'
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
name: 'App',
|
||||
setup() {
|
||||
|
||||
@@ -93,7 +93,7 @@ export default defineComponent<DnsProviderSelectProps>({
|
||||
*/
|
||||
const renderSingleSelectTag = ({ option }: { option: DnsProviderOption }): VNode => {
|
||||
return (
|
||||
<div class="flex items-center">
|
||||
<NFlex align="center">
|
||||
{option.label ? (
|
||||
renderLabel(option)
|
||||
) : (
|
||||
@@ -101,7 +101,7 @@ export default defineComponent<DnsProviderSelectProps>({
|
||||
{props.type === 'dns' ? $t('t_0_1747019621052') : $t('t_0_1746858920894')}
|
||||
</NText>
|
||||
)}
|
||||
</div>
|
||||
</NFlex>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -180,6 +180,7 @@ nodeOptions[NOTIFY] = () =>
|
||||
provider_id: '',
|
||||
subject: '',
|
||||
body: '',
|
||||
skip: false,
|
||||
},
|
||||
childNode: null,
|
||||
},
|
||||
|
||||
@@ -246,6 +246,7 @@ export interface DeployConfig<
|
||||
| 'aliyun-cdn'
|
||||
| 'aliyun-oss'
|
||||
| 'aliyun-waf'
|
||||
| 'aliyun-esa'
|
||||
| 'doge-cdn'
|
||||
| 'baidu-cdn'
|
||||
| 'qiniu-cdn'
|
||||
@@ -308,6 +309,11 @@ export interface DeployStorageConfig {
|
||||
bucket: string
|
||||
}
|
||||
|
||||
// 部署阿里云ESA
|
||||
export interface DeployAliyunESAConfig {
|
||||
site_id: string
|
||||
}
|
||||
|
||||
// 部署节点配置(雷池WAF)
|
||||
export interface DeploySafelineConfig {
|
||||
[key: string]: unknown
|
||||
@@ -340,6 +346,7 @@ export type DeployNodeConfig = DeployConfig<
|
||||
| DeployCDNConfig // 部署节点配置(腾讯云CDN/阿里云CDN)
|
||||
| DeployWAFConfig // 部署节点配置(阿里云WAF)
|
||||
| DeployStorageConfig // 部署节点配置(腾讯云COS/阿里云OSS)
|
||||
| DeployAliyunESAConfig // 部署节点配置(阿里云ESA)
|
||||
| DeploySafelineConfig // 部署节点配置(雷池WAF)
|
||||
| DeploySafelineSiteConfig // 部署节点配置(雷池WAF站点)
|
||||
| DeployBTPanelDockerSiteConfig // 部署节点配置(宝塔docker站点)
|
||||
@@ -358,6 +365,7 @@ interface NotifyNodeConfig {
|
||||
provider_id: string
|
||||
subject: string
|
||||
body: string
|
||||
skip: boolean // 当结果来源为跳过状态时,跳过/继续发送通知,true:跳过,false:继续
|
||||
}
|
||||
|
||||
// 定义上传节点配置类型
|
||||
|
||||
@@ -87,6 +87,7 @@ export const ApiProjectConfig: Record<string, ApiProjectType> = {
|
||||
cdn: { name: $t('t_16_1745735766712') },
|
||||
oss: { name: $t('t_2_1746697487164') },
|
||||
waf: { name: $t('t_10_1744958860078') },
|
||||
esa: { name: '阿里云ESA' },
|
||||
},
|
||||
sort: 6,
|
||||
},
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
{
|
||||
"t_11_1747280809178": "تخطي",
|
||||
"t_0_1750320239265": "الرجاء إدخال مفتاح الوصول DogeCloud",
|
||||
"t_1_1750320241427": "الرجاء إدخال مفتاح SecretKey الخاص بـ DogeCloud",
|
||||
"t_2_1750320237611": "تخطي إرسال الإشعار",
|
||||
"t_3_1750320237991": "إرسال",
|
||||
"t_0_1744098811152": "تحذير: لقد دخلتم منطقة غير معروفة، الصفحة التي تحاول زيارتها غير موجودة، يرجى الضغط على الزر للعودة إلى الصفحة الرئيسية.",
|
||||
"t_1_1744098801860": "رجوع إلى الصفحة الرئيسية",
|
||||
"t_2_1744098804908": "نصيحة أمنية: إذا كنت تعتقد أن هذا خطأ، يرجى الاتصال بالمدير على الفور",
|
||||
@@ -529,7 +534,6 @@
|
||||
"t_8_1747280809382": "دلو",
|
||||
"t_9_1747280810169": "نشر متكرر",
|
||||
"t_10_1747280816952": "عندما يكون الشهادة هي نفسها كما في النشر الأخير وكان النشر الأخير ناجحًا",
|
||||
"t_11_1747280809178": "تخطي",
|
||||
"t_12_1747280809893": "لا تتخطى",
|
||||
"t_13_1747280810369": "إعادة النشر",
|
||||
"t_14_1747280811231": "بحث نوع النشر",
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
{
|
||||
"t_11_1747280809178": "Skip",
|
||||
"t_0_1750320239265": "Please enter DogeCloud AccessKey",
|
||||
"t_1_1750320241427": "Please enter DogeCloud SecretKey",
|
||||
"t_2_1750320237611": "Skip sending notification",
|
||||
"t_3_1750320237991": "Send",
|
||||
"t_0_1744098811152": "Warning: You have entered an unknown area, the page you are visiting does not exist, please click the button to return to the homepage.",
|
||||
"t_1_1744098801860": "Return Home",
|
||||
"t_2_1744098804908": "Safety Tip: If you think this is an error, please contact the administrator immediately",
|
||||
@@ -529,7 +534,6 @@
|
||||
"t_8_1747280809382": "Bucket",
|
||||
"t_9_1747280810169": "Repeated deployment",
|
||||
"t_10_1747280816952": "When the certificate is the same as the last deployment and the last deployment was successful",
|
||||
"t_11_1747280809178": "Skip",
|
||||
"t_12_1747280809893": "Do not skip",
|
||||
"t_13_1747280810369": "Re-deployment",
|
||||
"t_14_1747280811231": "Search deployment type",
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
{
|
||||
"t_11_1747280809178": "Saltar",
|
||||
"t_0_1750320239265": "Por favor ingrese la AccessKey de DogeCloud",
|
||||
"t_1_1750320241427": "Por favor ingrese la SecretKey de DogeCloud",
|
||||
"t_2_1750320237611": "Omitir el envío de notificación",
|
||||
"t_3_1750320237991": "Enviar",
|
||||
"t_0_1744098811152": "Advertencia: Ha ingresado a una zona desconocida, la página que intenta visitar no existe, por favor, haga clic en el botón para regresar a la página de inicio.",
|
||||
"t_1_1744098801860": "Volver al inicio",
|
||||
"t_2_1744098804908": "Consejo de seguridad: Si piensa que es un error, póngase en contacto con el administrador inmediatamente",
|
||||
@@ -529,7 +534,6 @@
|
||||
"t_8_1747280809382": "Cubo",
|
||||
"t_9_1747280810169": "Implementación repetida",
|
||||
"t_10_1747280816952": "Cuando el certificado es el mismo que el último despliegue y el último despliegue fue exitoso",
|
||||
"t_11_1747280809178": "Saltar",
|
||||
"t_12_1747280809893": "No omitir",
|
||||
"t_13_1747280810369": "Redespliegue",
|
||||
"t_14_1747280811231": "Buscar tipo de implementación",
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
{
|
||||
"t_11_1747280809178": "Passer",
|
||||
"t_0_1750320239265": "Veuillez entrer la clé d'accès DogeCloud",
|
||||
"t_1_1750320241427": "Veuillez entrer la SecretKey de DogeCloud",
|
||||
"t_2_1750320237611": "Ignorer l'envoi de notification",
|
||||
"t_3_1750320237991": "Envoyer",
|
||||
"t_0_1744098811152": "Avertissement : Vous avez entré dans une zone inconnue, la page que vous visitez n'existe pas, veuillez cliquer sur le bouton pour revenir à la page d'accueil.",
|
||||
"t_1_1744098801860": "Retour à l'accueil",
|
||||
"t_2_1744098804908": "Avis de sécurité : Si vous pensez que c'est une erreur, veuillez contacter l'administrateur immédiatement",
|
||||
@@ -529,7 +534,6 @@
|
||||
"t_8_1747280809382": "Seau",
|
||||
"t_9_1747280810169": "Déploiement répété",
|
||||
"t_10_1747280816952": "Lorsque le certificat est identique au dernier déploiement et que le dernier déploiement a réussi",
|
||||
"t_11_1747280809178": "Passer",
|
||||
"t_12_1747280809893": "Ne pas sauter",
|
||||
"t_13_1747280810369": "Redéploiement",
|
||||
"t_14_1747280811231": "Rechercher le type de déploiement",
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
{
|
||||
"t_11_1747280809178": "スキップ",
|
||||
"t_0_1750320239265": "DogeCloudのAccessKeyを入力してください",
|
||||
"t_1_1750320241427": "ドージークラウドのSecretKeyを入力してください",
|
||||
"t_2_1750320237611": "通知の送信をスキップ",
|
||||
"t_3_1750320237991": "送信",
|
||||
"t_0_1744098811152": "警告:未知のエリアに進入しました。アクセスしようとしたページは存在しません。ボタンをクリックしてホームページに戻ってください。",
|
||||
"t_1_1744098801860": "ホームに戻る",
|
||||
"t_2_1744098804908": "安全注意:これが誤りだと思われる場合は、すぐに管理者に連絡してください",
|
||||
@@ -529,7 +534,6 @@
|
||||
"t_8_1747280809382": "バケット",
|
||||
"t_9_1747280810169": "重複デプロイ",
|
||||
"t_10_1747280816952": "前回の展開と同じ証明書で、前回の展開が成功した場合",
|
||||
"t_11_1747280809178": "スキップ",
|
||||
"t_12_1747280809893": "スキップしない",
|
||||
"t_13_1747280810369": "再展開",
|
||||
"t_14_1747280811231": "展開タイプを検索",
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
{
|
||||
"t_11_1747280809178": "건너뛰기",
|
||||
"t_0_1750320239265": "DogeCloud AccessKey를 입력하세요",
|
||||
"t_1_1750320241427": "도지클라우드 SecretKey를 입력하세요",
|
||||
"t_2_1750320237611": "알림 보내기 건너뛰기",
|
||||
"t_3_1750320237991": "보내기",
|
||||
"t_0_1744098811152": "경고: 알 수 없는 영역에 진입했습니다. 방문하려는 페이지가 존재하지 않습니다. 버튼을 클릭하여 홈페이지로 돌아가세요。",
|
||||
"t_1_1744098801860": "홈으로 돌아가기",
|
||||
"t_2_1744098804908": "안전 유의사항: 이가 오류라면 즉시 관리자에게 연락하십시오",
|
||||
@@ -529,7 +534,6 @@
|
||||
"t_8_1747280809382": "버킷",
|
||||
"t_9_1747280810169": "반복 배포",
|
||||
"t_10_1747280816952": "이전 배포와 동일한 인증서이며 이전 배포가 성공한 경우",
|
||||
"t_11_1747280809178": "건너뛰기",
|
||||
"t_12_1747280809893": "건너뛰지 않음",
|
||||
"t_13_1747280810369": "재배치",
|
||||
"t_14_1747280811231": "배포 유형 검색",
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
{
|
||||
"t_11_1747280809178": "Pular",
|
||||
"t_0_1750320239265": "Por favor, insira o AccessKey do DogeCloud",
|
||||
"t_1_1750320241427": "Por favor, insira a SecretKey do DogeCloud",
|
||||
"t_2_1750320237611": "Pular envio de notificação",
|
||||
"t_3_1750320237991": "Enviar",
|
||||
"t_0_1744098811152": "Aviso: Você entrou em uma área desconhecida, a página que você está visitando não existe, por favor, clique no botão para voltar para a página inicial.",
|
||||
"t_1_1744098801860": "Voltar para a homepage",
|
||||
"t_2_1744098804908": "Dica de Segurança: Se você acha que isso é um erro, entre em contato com o administrador imediatamente",
|
||||
@@ -529,7 +534,6 @@
|
||||
"t_8_1747280809382": "Balde",
|
||||
"t_9_1747280810169": "Implantações repetidas",
|
||||
"t_10_1747280816952": "Quando o certificado é o mesmo da última implantação e a última implantação foi bem-sucedida",
|
||||
"t_11_1747280809178": "Pular",
|
||||
"t_12_1747280809893": "Não pular",
|
||||
"t_13_1747280810369": "Reimplantação",
|
||||
"t_14_1747280811231": "Pesquisar tipo de implantação",
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
{
|
||||
"t_11_1747280809178": "Пропустить",
|
||||
"t_0_1750320239265": "Пожалуйста, введите DogeCloud AccessKey",
|
||||
"t_1_1750320241427": "Пожалуйста, введите SecretKey DogeCloud",
|
||||
"t_2_1750320237611": "Пропустить отправку уведомления",
|
||||
"t_3_1750320237991": "Отправить",
|
||||
"t_0_1744098811152": "Предупреждение: Вы вошли в неизвестную зону, посещаемая страница не существует, пожалуйста, нажмите кнопку, чтобы вернуться на главную страницу.",
|
||||
"t_1_1744098801860": "Вернуться на главную",
|
||||
"t_2_1744098804908": "Совет по безопасности: Если вы считаете, что это ошибка, немедленно свяжитесь с администратором",
|
||||
@@ -529,7 +534,6 @@
|
||||
"t_8_1747280809382": "Ведро",
|
||||
"t_9_1747280810169": "Повторное развертывание",
|
||||
"t_10_1747280816952": "Когда сертификат совпадает с последним развертыванием и последнее развертывание было успешным",
|
||||
"t_11_1747280809178": "Пропустить",
|
||||
"t_12_1747280809893": "Не пропускать",
|
||||
"t_13_1747280810369": "Повторное развертывание",
|
||||
"t_14_1747280811231": "Поиск типа развертывания",
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
{
|
||||
"t_11_1747280809178": "跳过",
|
||||
"t_0_1750320239265": "请输入多吉云AccessKey",
|
||||
"t_1_1750320241427": "请输入多吉云SecretKey",
|
||||
"t_2_1750320237611": "跳过发送通知",
|
||||
"t_3_1750320237991": "发送",
|
||||
"t_0_1744098811152": "警告:您已进入未知区域,所访问的页面不存在,请点击按钮返回首页。",
|
||||
"t_1_1744098801860": "返回首页",
|
||||
"t_2_1744098804908": "安全提示:如果您认为这是个错误,请立即联系管理员",
|
||||
@@ -529,7 +534,6 @@
|
||||
"t_8_1747280809382": "存储桶",
|
||||
"t_9_1747280810169": "重复部署",
|
||||
"t_10_1747280816952": "当与上次部署的证书相同且上次部署成功时",
|
||||
"t_11_1747280809178": "跳过",
|
||||
"t_12_1747280809893": "不跳过",
|
||||
"t_13_1747280810369": "重新部署",
|
||||
"t_14_1747280811231": "搜索部署类型",
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
{
|
||||
"t_11_1747280809178": "跳過",
|
||||
"t_0_1750320239265": "請輸入多吉雲AccessKey",
|
||||
"t_1_1750320241427": "請輸入多吉雲SecretKey",
|
||||
"t_2_1750320237611": "跳過發送通知",
|
||||
"t_3_1750320237991": "發送",
|
||||
"t_0_1744098811152": "警告:您已進入未知區域,所訪問的頁面不存在,請點擊按鈕返回首頁。",
|
||||
"t_1_1744098801860": "返回首頁",
|
||||
"t_2_1744098804908": "安全提示:如果您認為這是個錯誤,請立即聯繫管理員",
|
||||
@@ -528,7 +533,6 @@
|
||||
"t_8_1747280809382": "儲存桶",
|
||||
"t_9_1747280810169": "重複部署",
|
||||
"t_10_1747280816952": "當與上次部署的證書相同且上次部署成功時",
|
||||
"t_11_1747280809178": "跳過",
|
||||
"t_12_1747280809893": "不跳過",
|
||||
"t_13_1747280810369": "重新部署",
|
||||
"t_14_1747280811231": "搜尋部署類型",
|
||||
|
||||
@@ -268,8 +268,8 @@ export interface JdcloudAccessConfig {
|
||||
* 多吉云授权配置
|
||||
*/
|
||||
export interface DogeAccessConfig {
|
||||
access_key_id: string
|
||||
access_key_secret: string
|
||||
access_key: string
|
||||
secret_key: string
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -361,6 +361,8 @@ export interface AcmeAccountDeleteParams {
|
||||
|
||||
// 保持向后兼容的类型别名
|
||||
export interface EabListParams {
|
||||
search?: string
|
||||
ca?: string
|
||||
p: number
|
||||
limit: number
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import BaseComponent from '@components/BaseLayout'
|
||||
export default defineComponent({
|
||||
name: 'AuthApiManage',
|
||||
setup() {
|
||||
const { TableComponent, PageComponent, param, fetch, total, openAddForm } = useController()
|
||||
const { TableComponent, PageComponent, SearchComponent, openAddForm } = useController()
|
||||
const cssVar = useThemeCssVar(['contentPadding', 'borderColor', 'headerHeight', 'iconColorHover'])
|
||||
|
||||
return () => (
|
||||
@@ -28,26 +28,7 @@ export default defineComponent({
|
||||
{$t('t_0_1745289355714')}
|
||||
</NButton>
|
||||
),
|
||||
headerRight: () => (
|
||||
<NInput
|
||||
v-model:value={param.value.search}
|
||||
onKeydown={(e: KeyboardEvent) => {
|
||||
if (e.key === 'Enter') fetch()
|
||||
}}
|
||||
onClear={() => useTimeoutFn(() => fetch(), 100)}
|
||||
placeholder={$t('t_0_1745289808449')}
|
||||
clearable
|
||||
size="large"
|
||||
class="min-w-[300px]"
|
||||
v-slots={{
|
||||
suffix: () => (
|
||||
<div class="flex items-center cursor-pointer" onClick={fetch}>
|
||||
<Search class="text-[var(--text-color-3)] w-[1.6rem] font-bold" />
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
),
|
||||
headerRight: () => <SearchComponent placeholder={$t('t_0_1745289808449')} />,
|
||||
content: () => (
|
||||
<div class="rounded-lg">
|
||||
<TableComponent
|
||||
@@ -60,15 +41,7 @@ export default defineComponent({
|
||||
),
|
||||
footerRight: () => (
|
||||
<div class="mt-4 flex justify-end">
|
||||
<PageComponent
|
||||
v-slots={{
|
||||
prefix: () => (
|
||||
<span>
|
||||
{$t('t_15_1745227839354')} {total.value} {$t('t_16_1745227838930')}
|
||||
</span>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<PageComponent />
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
useModal,
|
||||
useDialog,
|
||||
useTable,
|
||||
useSearch,
|
||||
useModalHooks,
|
||||
useFormHooks,
|
||||
useForm,
|
||||
@@ -64,11 +65,11 @@ import { JSX } from 'vue/jsx-runtime'
|
||||
*/
|
||||
interface AuthApiManageControllerExposes {
|
||||
loading: Ref<boolean>
|
||||
fetch: () => Promise<void>
|
||||
fetch: (resetPage?: boolean) => Promise<void>
|
||||
TableComponent: (props: Record<string, unknown>, context: Record<string, unknown>) => VNode
|
||||
PageComponent: (props: Record<string, unknown>, context: Record<string, unknown>) => VNode
|
||||
SearchComponent: (props: Record<string, unknown>, context: Record<string, unknown>) => VNode
|
||||
param: Ref<AccessListParams>
|
||||
total: Ref<number>
|
||||
openAddForm: () => void
|
||||
}
|
||||
|
||||
@@ -183,7 +184,7 @@ export const useController = (): AuthApiManageControllerExposes => {
|
||||
]
|
||||
|
||||
// 表格实例
|
||||
const { TableComponent, PageComponent, loading, param, total, fetch } = useTable<AccessItem, AccessListParams>({
|
||||
const { TableComponent, PageComponent, loading, param, fetch } = useTable<AccessItem, AccessListParams>({
|
||||
config: createColumns(),
|
||||
request: fetchAccessList,
|
||||
watchValue: ['p', 'limit'],
|
||||
@@ -196,6 +197,14 @@ export const useController = (): AuthApiManageControllerExposes => {
|
||||
},
|
||||
})
|
||||
|
||||
// 搜索实例
|
||||
const { SearchComponent, search } = useSearch({
|
||||
onSearch: (value) => {
|
||||
param.value.search = value
|
||||
fetch()
|
||||
},
|
||||
})
|
||||
|
||||
/**
|
||||
* 打开添加授权API弹窗
|
||||
*/
|
||||
@@ -255,8 +264,8 @@ export const useController = (): AuthApiManageControllerExposes => {
|
||||
fetch,
|
||||
TableComponent,
|
||||
PageComponent,
|
||||
SearchComponent,
|
||||
param,
|
||||
total,
|
||||
openAddForm,
|
||||
}
|
||||
}
|
||||
@@ -403,32 +412,32 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
message: $t('t_0_1747617113090'),
|
||||
trigger: 'input',
|
||||
},
|
||||
access_key_id: {
|
||||
trigger: 'input',
|
||||
validator: (rule: FormItemRule, value: string, callback: (error?: Error) => void) => {
|
||||
if (!value) {
|
||||
const mapTips = {
|
||||
aliyun: $t('t_4_1745317314054'),
|
||||
doge: '请输入多吉云AccessKeyId',
|
||||
}
|
||||
return callback(new Error(mapTips[param.value.type as keyof typeof mapTips] || $t('t_4_1745317314054')))
|
||||
}
|
||||
callback()
|
||||
},
|
||||
},
|
||||
access_key_secret: {
|
||||
trigger: 'input',
|
||||
validator: (rule: FormItemRule, value: string, callback: (error?: Error) => void) => {
|
||||
if (!value) {
|
||||
const mapTips = {
|
||||
aliyun: $t('t_5_1745317315285'),
|
||||
doge: '请输入多吉云AccessKeySecret',
|
||||
}
|
||||
return callback(new Error(mapTips[param.value.type as keyof typeof mapTips] || $t('t_5_1745317315285')))
|
||||
}
|
||||
callback()
|
||||
},
|
||||
},
|
||||
// access_key_id: {
|
||||
// trigger: 'input',
|
||||
// validator: (rule: FormItemRule, value: string, callback: (error?: Error) => void) => {
|
||||
// if (!value) {
|
||||
// const mapTips = {
|
||||
// aliyun: $t('t_4_1745317314054'),
|
||||
// doge: '请输入多吉云AccessKeyId',
|
||||
// }
|
||||
// return callback(new Error(mapTips[param.value.type as keyof typeof mapTips] || $t('t_4_1745317314054')))
|
||||
// }
|
||||
// callback()
|
||||
// },
|
||||
// },
|
||||
// access_key_secret: {
|
||||
// trigger: 'input',
|
||||
// validator: (rule: FormItemRule, value: string, callback: (error?: Error) => void) => {
|
||||
// if (!value) {
|
||||
// const mapTips = {
|
||||
// aliyun: $t('t_5_1745317315285'),
|
||||
// doge: '请输入多吉云AccessKeySecret',
|
||||
// }
|
||||
// return callback(new Error(mapTips[param.value.type as keyof typeof mapTips] || $t('t_5_1745317315285')))
|
||||
// }
|
||||
// callback()
|
||||
// },
|
||||
// },
|
||||
secret_access_key: {
|
||||
required: true,
|
||||
message: '请输入Secret Access Key',
|
||||
@@ -478,6 +487,7 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
baidu: $t('t_3_1747271294475'),
|
||||
volcengine: $t('t_3_1747365600828'),
|
||||
qiniu: $t('t_3_1747984134586'),
|
||||
doge: $t('t_0_1750320239265'),
|
||||
}
|
||||
return callback(new Error(mapTips[param.value.type as keyof typeof mapTips]))
|
||||
}
|
||||
@@ -493,6 +503,7 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
huawei: $t('t_3_1747042967608'),
|
||||
baidu: $t('t_4_1747271294621'),
|
||||
volcengine: $t('t_4_1747365600137'),
|
||||
doge: $t('t_1_1750320241427'),
|
||||
}
|
||||
return callback(new Error(mapTips[param.value.type as keyof typeof mapTips]))
|
||||
}
|
||||
@@ -632,6 +643,7 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
case 'huaweicloud':
|
||||
case 'baidu':
|
||||
case 'volcengine':
|
||||
case 'doge':
|
||||
items.push(
|
||||
useFormInput('AccessKey', 'config.access_key', { allowInput: noSideSpace }),
|
||||
useFormInput('SecretKey', 'config.secret_key', { allowInput: noSideSpace }),
|
||||
@@ -711,12 +723,6 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
useFormInput('Secret Access Key', 'config.secret_access_key', { allowInput: noSideSpace }),
|
||||
)
|
||||
break
|
||||
case 'doge':
|
||||
items.push(
|
||||
useFormInput('AccessKeyId', 'config.access_key_id', { allowInput: noSideSpace }),
|
||||
useFormInput('AccessKeySecret', 'config.access_key_secret', { allowInput: noSideSpace }),
|
||||
)
|
||||
break
|
||||
case 'plugin':
|
||||
items.push(
|
||||
useFormCustom(() => {
|
||||
@@ -743,39 +749,39 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
</NFormItem>
|
||||
)
|
||||
}),
|
||||
useFormCustom(() => {
|
||||
const pluginConfig = param.value.config as PluginAccessConfig
|
||||
const getConfigValue = () => {
|
||||
return typeof pluginConfig.config === 'string'
|
||||
? pluginConfig.config
|
||||
: JSON.stringify(pluginConfig.config, null, 2)
|
||||
}
|
||||
return (
|
||||
<NFormItem
|
||||
path="config.params"
|
||||
v-slots={{
|
||||
label: () => (
|
||||
<div>
|
||||
<NText>自定义参数</NText>
|
||||
<NTooltip
|
||||
v-slots={{
|
||||
trigger: () => (
|
||||
<span class="inline-flex ml-2 -mt-1 cursor-pointer text-base rounded-full w-[14px] h-[14px] justify-center items-center text-orange-600 border border-orange-600">
|
||||
?
|
||||
</span>
|
||||
),
|
||||
}}
|
||||
>
|
||||
{pluginActionTips.value}
|
||||
</NTooltip>
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
>
|
||||
<NInput type="textarea" value={getConfigValue()} placeholder={pluginActionTips.value} rows={4} />
|
||||
</NFormItem>
|
||||
)
|
||||
}),
|
||||
useFormCustom(() => {
|
||||
const pluginConfig = param.value.config as PluginAccessConfig
|
||||
const getConfigValue = () => {
|
||||
return typeof pluginConfig.config === 'string'
|
||||
? pluginConfig.config
|
||||
: JSON.stringify(pluginConfig.config, null, 2)
|
||||
}
|
||||
return (
|
||||
<NFormItem
|
||||
path="config.params"
|
||||
v-slots={{
|
||||
label: () => (
|
||||
<div>
|
||||
<NText>自定义参数</NText>
|
||||
<NTooltip
|
||||
v-slots={{
|
||||
trigger: () => (
|
||||
<span class="inline-flex ml-2 -mt-1 cursor-pointer text-base rounded-full w-[14px] h-[14px] justify-center items-center text-orange-600 border border-orange-600">
|
||||
?
|
||||
</span>
|
||||
),
|
||||
}}
|
||||
>
|
||||
{pluginActionTips.value}
|
||||
</NTooltip>
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
>
|
||||
<NInput type="textarea" value={getConfigValue()} placeholder={pluginActionTips.value} rows={4} />
|
||||
</NFormItem>
|
||||
)
|
||||
}),
|
||||
)
|
||||
break
|
||||
default:
|
||||
@@ -904,8 +910,8 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
break
|
||||
case 'doge':
|
||||
param.value.config = {
|
||||
access_key_id: '',
|
||||
access_key_secret: '',
|
||||
access_key: '',
|
||||
secret_key: '',
|
||||
} as DogeAccessConfig
|
||||
break
|
||||
case 'plugin':
|
||||
|
||||
@@ -189,6 +189,13 @@ export function createNodeFormConfig() {
|
||||
]
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建阿里云ESA相关字段
|
||||
*/
|
||||
aliyunEsaDeploy() {
|
||||
return [this.input('站点ID', 'site_id', { placeholder: '请输入ESA站点ID' })]
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建跳过选项字段
|
||||
* @param valueRef 值引用
|
||||
|
||||
@@ -1,13 +1,29 @@
|
||||
import { NFormItem, NInputNumber, NSwitch } from 'naive-ui'
|
||||
import {
|
||||
NFormItem,
|
||||
NInputNumber,
|
||||
NSwitch,
|
||||
NSelect,
|
||||
NAutoComplete,
|
||||
NInput,
|
||||
NFlex,
|
||||
NText,
|
||||
NButton,
|
||||
NGrid,
|
||||
NFormItemGi,
|
||||
NSpin,
|
||||
NDropdown,
|
||||
} from 'naive-ui'
|
||||
import { useForm, useFormHooks, useModalHooks } from '@baota/naive-ui/hooks'
|
||||
import { useStore } from '@components/FlowChart/useStore'
|
||||
import { $t } from '@locales/index'
|
||||
import rules from './verify'
|
||||
import DnsProviderSelect from '@components/DnsProviderSelect'
|
||||
import CAProviderSelect from '@components/CAProviderSelect'
|
||||
import type { ApplyNodeConfig } from '@components/FlowChart/types'
|
||||
import { deepClone } from '@baota/utils/data'
|
||||
import { noSideSpace } from '@lib/utils'
|
||||
import { getEabList } from '@api/access'
|
||||
import SvgIcon from '@components/SvgIcon'
|
||||
import { CACertificateAuthorization } from '@config/data'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ApplyNodeDrawer',
|
||||
@@ -45,6 +61,150 @@ export default defineComponent({
|
||||
// 表单参数
|
||||
const param = ref(deepClone(props.node.config))
|
||||
|
||||
// CA选项状态
|
||||
const caOptions = ref<Array<{ label: string; value: string; icon: string }>>([])
|
||||
const emailOptions = ref<string[]>([])
|
||||
const isLoadingCA = ref(false)
|
||||
const isLoadingEmails = ref(false)
|
||||
const showEmailDropdown = ref(false)
|
||||
const emailInputRef = ref<any>(null)
|
||||
|
||||
// 加载CA选项
|
||||
const loadCAOptions = async () => {
|
||||
isLoadingCA.value = true
|
||||
try {
|
||||
const { data } = await getEabList({ ca: '', p: 1, limit: 1000 }).fetch()
|
||||
const uniqueCATypes = new Set<string>()
|
||||
const caList: Array<{ label: string; value: string; icon: string }> = []
|
||||
|
||||
// 优先添加重要的CA类型(确保始终显示)
|
||||
const priorityCATypes = ['letsencrypt', 'buypass', 'zerossl']
|
||||
priorityCATypes.forEach((caType) => {
|
||||
if (!uniqueCATypes.has(caType)) {
|
||||
uniqueCATypes.add(caType)
|
||||
const predefinedCA = Object.values(CACertificateAuthorization).find((ca) => ca.type === caType)
|
||||
caList.push({
|
||||
label: predefinedCA ? predefinedCA.name : caType.toUpperCase(),
|
||||
value: caType,
|
||||
icon: `cert-${caType}`,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// 添加API返回的其他CA类型(去重)
|
||||
data?.forEach((item) => {
|
||||
if (item.ca && !uniqueCATypes.has(item.ca)) {
|
||||
uniqueCATypes.add(item.ca)
|
||||
|
||||
// 查找预定义配置中对应的CA信息
|
||||
const predefinedCA = Object.values(CACertificateAuthorization).find((ca) => ca.type === item.ca)
|
||||
caList.push({
|
||||
label: predefinedCA ? predefinedCA.name : item.ca.toUpperCase(),
|
||||
value: item.ca,
|
||||
icon: predefinedCA ? `cert-${item.ca}` : 'cert-custom', // 如果不在预定义配置中,使用custom图标;否则使用对应的cert图标
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
caOptions.value = caList
|
||||
} catch (error) {
|
||||
console.error('加载CA选项失败:', error)
|
||||
} finally {
|
||||
isLoadingCA.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 加载邮件选项
|
||||
const loadEmailOptions = async (ca: string) => {
|
||||
if (!ca) return
|
||||
isLoadingEmails.value = true
|
||||
try {
|
||||
const { data } = await getEabList({ ca, p: 1, limit: 1000 }).fetch()
|
||||
emailOptions.value = data?.map((item) => item.email).filter(Boolean) || []
|
||||
if (!emailOptions.value.length) {
|
||||
param.value.email = ''
|
||||
}
|
||||
// 如果邮箱数组有内容且当前邮箱为空,自动填充第一个邮箱地址
|
||||
if (emailOptions.value.length > 0 && emailOptions.value[0]) {
|
||||
param.value.email = emailOptions.value[0]
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载邮件选项失败:', error)
|
||||
} finally {
|
||||
isLoadingEmails.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 处理CA选择变化
|
||||
const handleCAChange = (value: string) => {
|
||||
param.value.ca = value
|
||||
loadEmailOptions(value)
|
||||
}
|
||||
|
||||
// 跳转到CA管理页面
|
||||
const goToAddCAProvider = () => {
|
||||
window.open('/auto-deploy?type=caManage', '_blank')
|
||||
}
|
||||
|
||||
// 渲染CA选择器标签
|
||||
const renderLabel = (option: { label: string; value: string; icon: string }) => {
|
||||
return (
|
||||
<NFlex align="center">
|
||||
<SvgIcon icon={option.icon} size="2rem" />
|
||||
<NText>{option.label}</NText>
|
||||
</NFlex>
|
||||
)
|
||||
}
|
||||
|
||||
// 渲染CA选择器单选标签
|
||||
const renderSingleSelectTag = ({ option }: { option: any }) => {
|
||||
return (
|
||||
<NFlex align="center">
|
||||
{option.label ? renderLabel(option) : <NText class="text-[#aaa]">{$t('t_0_1747990228780')}</NText>}
|
||||
</NFlex>
|
||||
)
|
||||
}
|
||||
|
||||
// 过滤函数
|
||||
const handleFilter = (pattern: string, option: any): boolean => {
|
||||
return option.label.toLowerCase().includes(pattern.toLowerCase())
|
||||
}
|
||||
|
||||
// 处理邮箱输入框焦点
|
||||
const handleEmailFocus = () => {
|
||||
if (emailOptions.value.length > 0) {
|
||||
showEmailDropdown.value = true
|
||||
}
|
||||
}
|
||||
|
||||
// 处理邮箱输入框失焦
|
||||
const handleEmailBlur = () => {
|
||||
// 延迟关闭下拉,确保点击选项有时间触发
|
||||
setTimeout(() => {
|
||||
showEmailDropdown.value = false
|
||||
}, 200)
|
||||
}
|
||||
|
||||
// 选择邮箱地址
|
||||
const handleSelectEmail = (email: string) => {
|
||||
param.value.email = email
|
||||
showEmailDropdown.value = false
|
||||
emailInputRef.value?.blur()
|
||||
}
|
||||
|
||||
// 创建邮箱下拉选项
|
||||
const emailDropdownOptions = computed(() => {
|
||||
return emailOptions.value.map((email) => ({
|
||||
label: email,
|
||||
key: email,
|
||||
}))
|
||||
})
|
||||
|
||||
// 判断是否需要输入框(letsencrypt、buypass、zerossl)
|
||||
const shouldUseInputForEmail = computed(() => {
|
||||
return ['letsencrypt', 'buypass', 'zerossl'].includes(param.value.ca)
|
||||
})
|
||||
|
||||
// 表单渲染配置
|
||||
const config = computed(() => {
|
||||
// 基本选项
|
||||
@@ -80,27 +240,80 @@ export default defineComponent({
|
||||
type: 'custom' as const,
|
||||
render: () => {
|
||||
return (
|
||||
<CAProviderSelect
|
||||
path="eabId"
|
||||
value={param.value.eabId}
|
||||
email={param.value.email}
|
||||
ca={param.value.ca}
|
||||
{...{
|
||||
'onUpdate:value': (val: { value: string; ca: string; email: string }) => {
|
||||
param.value.eabId = val.value
|
||||
param.value.ca = val.ca
|
||||
// 始终更新邮件,确保 Let's Encrypt 和 Buypass 的邮件能正确显示
|
||||
param.value.email = val.email
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<NSpin show={isLoadingCA.value}>
|
||||
<NGrid cols={24}>
|
||||
<NFormItemGi span={13} label={$t('证书CA')} path="ca" showRequireMark={true}>
|
||||
<NSelect
|
||||
value={param.value.ca}
|
||||
options={caOptions.value}
|
||||
renderLabel={renderLabel}
|
||||
renderTag={renderSingleSelectTag}
|
||||
filterable
|
||||
filter={handleFilter}
|
||||
loading={isLoadingCA.value}
|
||||
placeholder={$t('t_0_1747990228780')}
|
||||
onUpdateValue={handleCAChange}
|
||||
class="flex-1 w-full"
|
||||
v-slots={{
|
||||
empty: () => {
|
||||
return <span class="text-[1.4rem]">{$t('t_2_1747990228008')}</span>
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</NFormItemGi>
|
||||
<NFormItemGi span={11}>
|
||||
<NButton class="mx-[8px]" onClick={goToAddCAProvider}>
|
||||
{$t('添加CA授权')}
|
||||
</NButton>
|
||||
<NButton onClick={loadCAOptions} loading={isLoadingCA.value}>
|
||||
{$t('t_0_1746497662220')}
|
||||
</NButton>
|
||||
</NFormItemGi>
|
||||
</NGrid>
|
||||
</NSpin>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'custom' as const,
|
||||
render: () => {
|
||||
return (
|
||||
<NFormItem label={$t('t_68_1745289354676')} path="email">
|
||||
{shouldUseInputForEmail.value ? (
|
||||
<NDropdown
|
||||
trigger="manual"
|
||||
show={showEmailDropdown.value}
|
||||
options={emailDropdownOptions.value}
|
||||
onSelect={handleSelectEmail}
|
||||
placement="bottom-start"
|
||||
style="width: 100%"
|
||||
>
|
||||
<NInput
|
||||
ref={emailInputRef}
|
||||
v-model:value={param.value.email}
|
||||
placeholder={$t('t_2_1748052862259')}
|
||||
clearable
|
||||
loading={isLoadingEmails.value}
|
||||
onFocus={handleEmailFocus}
|
||||
onBlur={handleEmailBlur}
|
||||
class="w-full"
|
||||
/>
|
||||
</NDropdown>
|
||||
) : (
|
||||
<NSelect
|
||||
v-model:value={param.value.email}
|
||||
options={emailOptions.value.map((email) => ({ label: email, value: email }))}
|
||||
placeholder={$t('t_2_1748052862259')}
|
||||
clearable
|
||||
filterable
|
||||
loading={isLoadingEmails.value}
|
||||
class="w-full"
|
||||
/>
|
||||
)}
|
||||
</NFormItem>
|
||||
)
|
||||
},
|
||||
},
|
||||
useFormInput($t('t_68_1745289354676'), 'email', {
|
||||
placeholder: $t('t_2_1748052862259'),
|
||||
allowInput: noSideSpace,
|
||||
}),
|
||||
|
||||
{
|
||||
type: 'custom' as const,
|
||||
@@ -232,8 +445,37 @@ export default defineComponent({
|
||||
// 创建表单实例
|
||||
const { component: Form, data, example } = useForm<ApplyNodeConfig>({ defaultValue: param, config, rules })
|
||||
|
||||
onMounted(() => {
|
||||
// 监听CA值变化,自动加载邮箱选项
|
||||
watch(
|
||||
() => param.value.ca,
|
||||
async (newCA) => {
|
||||
if (newCA) {
|
||||
await loadEmailOptions(newCA)
|
||||
} else {
|
||||
emailOptions.value = []
|
||||
param.value.email = ''
|
||||
showEmailDropdown.value = false
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// 监听邮箱选项变化,如果当前下拉显示且没有选项了就关闭下拉
|
||||
watch(
|
||||
() => emailOptions.value,
|
||||
(newOptions) => {
|
||||
if (showEmailDropdown.value && newOptions.length === 0) {
|
||||
showEmailDropdown.value = false
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
onMounted(async () => {
|
||||
advancedOptions.value = false
|
||||
await loadCAOptions()
|
||||
// 如果初始化时已有CA值,加载对应的邮箱选项
|
||||
if (param.value.ca) {
|
||||
await loadEmailOptions(param.value.ca)
|
||||
}
|
||||
})
|
||||
|
||||
// 确认事件触发
|
||||
|
||||
@@ -225,6 +225,9 @@ export default defineComponent({
|
||||
case 'aliyun-oss':
|
||||
config.push(...formConfig.storageDeploy())
|
||||
break
|
||||
case 'aliyun-esa':
|
||||
config.push(...formConfig.aliyunEsaDeploy())
|
||||
break
|
||||
case 'plugin':
|
||||
// 插件部署配置
|
||||
config.push(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { FormRules } from 'naive-ui'
|
||||
import { $t } from '@locales/index'
|
||||
import { createNodeValidator } from '@workflowView/lib/NodeValidator'
|
||||
import { isDomain } from '@baota/utils/business'
|
||||
import { isDomain, isWildcardDomain } from '@baota/utils/business'
|
||||
|
||||
// 创建部署节点验证器
|
||||
const validator = createNodeValidator($t('t_11_1747817612051'))
|
||||
@@ -51,7 +51,7 @@ export default {
|
||||
if (!value) {
|
||||
return new Error($t('t_0_1744958839535'))
|
||||
}
|
||||
if (!isDomain(value)) {
|
||||
if (!isWildcardDomain(value)) {
|
||||
return new Error($t('t_0_1744958839535'))
|
||||
}
|
||||
return true
|
||||
|
||||
@@ -11,6 +11,7 @@ import verify from './verify'
|
||||
import { NotifyNodeConfig } from '@components/FlowChart/types'
|
||||
import { deepClone } from '@baota/utils/data'
|
||||
import { noSideSpace } from '@lib/utils'
|
||||
import { NSwitch, NFormItem, NText } from 'naive-ui'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'NotifyNodeDrawer',
|
||||
@@ -25,6 +26,7 @@ export default defineComponent({
|
||||
provider_id: '',
|
||||
subject: '',
|
||||
body: '',
|
||||
skip: false,
|
||||
},
|
||||
}),
|
||||
},
|
||||
@@ -36,6 +38,14 @@ export default defineComponent({
|
||||
const { handleError } = useError()
|
||||
const param = ref(deepClone(props.node.config))
|
||||
|
||||
// 创建一个用于开关的响应式值(发送通知的状态)
|
||||
const shouldSendNotify = computed({
|
||||
get: () => !param.value.skip,
|
||||
set: (value: boolean) => {
|
||||
param.value.skip = !value
|
||||
},
|
||||
})
|
||||
|
||||
// 表单渲染配置
|
||||
const formConfig: FormConfig = [
|
||||
useFormInput($t('t_0_1745920566646'), 'subject', {
|
||||
@@ -58,6 +68,21 @@ export default defineComponent({
|
||||
}}
|
||||
/>
|
||||
)),
|
||||
useFormCustom(() => (
|
||||
<NFormItem label={$t('t_2_1750320237611')} path="skip">
|
||||
<NText>当结果来源为跳过状态时</NText>
|
||||
<NSwitch
|
||||
v-model:value={shouldSendNotify.value}
|
||||
checkedValue={true}
|
||||
uncheckedValue={false}
|
||||
class="mx-[.5rem]"
|
||||
v-slots={{
|
||||
checked: () => $t('t_3_1750320237991'),
|
||||
unchecked: () => $t('t_11_1747280809178'),
|
||||
}}
|
||||
/>
|
||||
</NFormItem>
|
||||
)),
|
||||
]
|
||||
|
||||
// 创建表单实例
|
||||
|
||||
@@ -11,6 +11,7 @@ import type { FormConfig } from '@baota/naive-ui/types/form'
|
||||
import type { VNode } from 'vue'
|
||||
import { useError } from '@baota/hooks/error'
|
||||
import { deepClone } from '@baota/utils/data'
|
||||
import { isUndefined } from '@baota/utils/type'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'StartNodeDrawer',
|
||||
@@ -27,7 +28,7 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const { updateNodeConfig, isRefreshNode } = useStore()
|
||||
const { updateNodeConfig, isRefreshNode, flowData } = useStore()
|
||||
// 弹窗辅助
|
||||
const { confirm } = useModalHooks()
|
||||
// 错误处理
|
||||
@@ -90,7 +91,17 @@ export default defineComponent({
|
||||
return (
|
||||
<NGrid cols={24} xGap={24}>
|
||||
<NFormItemGi label={$t('t_2_1744879616413')} span={8} showRequireMark path="type">
|
||||
<NSelect class="w-full" options={cycleTypeOptions} v-model:value={param.value.type} />
|
||||
<NSelect
|
||||
class="w-full"
|
||||
options={cycleTypeOptions}
|
||||
v-model:value={param.value.type}
|
||||
onUpdateValue={(val: 'day' | 'week' | 'month') => {
|
||||
if (val) {
|
||||
param.value.type = val
|
||||
updateParamValueByType(val)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</NFormItemGi>
|
||||
|
||||
{param.value.type !== 'day' && (
|
||||
@@ -99,9 +110,7 @@ export default defineComponent({
|
||||
<NSelect
|
||||
value={param.value.week}
|
||||
onUpdateValue={(val: number) => {
|
||||
if (typeof val === 'number') {
|
||||
param.value.week = val
|
||||
}
|
||||
param.value.week = val
|
||||
}}
|
||||
options={weekOptions}
|
||||
/>
|
||||
@@ -161,19 +170,24 @@ export default defineComponent({
|
||||
|
||||
// 更新参数的函数
|
||||
const updateParamValue = (updates: StartNodeConfig) => {
|
||||
console.log(updates)
|
||||
let newParams = { ...updates }
|
||||
if (newParams.exec_type === 'manual') {
|
||||
// 小时随机 1-6
|
||||
const randomHour = Math.floor(Math.random() * 6) + 1
|
||||
// 分钟每5分钟随机,0-55
|
||||
const randomMinute = Math.floor(Math.random() * 12) * 5
|
||||
newParams = {
|
||||
...newParams,
|
||||
hour: randomHour,
|
||||
minute: randomMinute,
|
||||
}
|
||||
param.value = newParams
|
||||
// if (newParams.exec_type === 'manual') {
|
||||
// 小时随机 1-6
|
||||
const randomHour = Math.floor(Math.random() * 4) + 1
|
||||
// 分钟每5分钟随机,0-55
|
||||
const randomMinute = Math.floor(Math.random() * 12) * 5
|
||||
newParams = {
|
||||
...newParams,
|
||||
hour: randomHour,
|
||||
minute: randomMinute,
|
||||
}
|
||||
param.value = newParams
|
||||
// }
|
||||
}
|
||||
|
||||
const updateParamValueByType = (type: 'day' | 'week' | 'month') => {
|
||||
updateParamValue(DEFAULT_AUTO_SETTINGS[type] as StartNodeConfig)
|
||||
}
|
||||
|
||||
// 监听执行类型变化
|
||||
@@ -210,6 +224,13 @@ export default defineComponent({
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
if (isUndefined(flowData.value.id)) {
|
||||
updateParamValueByType('day')
|
||||
updateNodeConfig(props.node.id, param.value) // 更新节点配置
|
||||
}
|
||||
})
|
||||
|
||||
return () => (
|
||||
<div class="apply-node-drawer">
|
||||
<Form labelPlacement="top" />
|
||||
|
||||
@@ -18,7 +18,7 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const { TableComponent, PageComponent, handleOpenAddForm, total } = useCAManageController(props)
|
||||
const { TableComponent, PageComponent, handleOpenAddForm } = useCAManageController(props)
|
||||
return () => (
|
||||
<BaseComponent
|
||||
v-slots={{
|
||||
@@ -40,15 +40,7 @@ export default defineComponent({
|
||||
),
|
||||
footerRight: () => (
|
||||
<div class="flex justify-end mt-4">
|
||||
<PageComponent
|
||||
v-slots={{
|
||||
prefix: () => (
|
||||
<span>
|
||||
{$t('t_15_1745227839354')} {total.value} {$t('t_16_1745227838930')}
|
||||
</span>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<PageComponent />
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
|
||||
@@ -18,15 +18,14 @@ export default defineComponent({
|
||||
const {
|
||||
TableComponent,
|
||||
PageComponent,
|
||||
SearchComponent,
|
||||
isDetectionAddWorkflow,
|
||||
isDetectionOpenCAManage,
|
||||
isDetectionOpenAddCAForm,
|
||||
handleAddWorkflow,
|
||||
handleOpenCAManage,
|
||||
hasChildRoutes,
|
||||
param,
|
||||
fetch,
|
||||
data,
|
||||
} = useController()
|
||||
const router = useRouter()
|
||||
// 获取主题变量
|
||||
@@ -65,26 +64,7 @@ export default defineComponent({
|
||||
</NButton>
|
||||
</NSpace>
|
||||
),
|
||||
headerRight: () => (
|
||||
<NInput
|
||||
v-model:value={param.value.search}
|
||||
onKeydown={(e: KeyboardEvent) => {
|
||||
if (e.key === 'Enter') fetch()
|
||||
}}
|
||||
onClear={() => useTimeoutFn(fetch, 100)}
|
||||
placeholder={$t('t_1_1745227838776')}
|
||||
clearable
|
||||
size="large"
|
||||
class="min-w-[300px]"
|
||||
v-slots={{
|
||||
suffix: () => (
|
||||
<div class="flex items-center" onClick={fetch}>
|
||||
<Search class="text-[var(--text-color-3)] w-[1.6rem] cursor-pointer font-bold" />
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
></NInput>
|
||||
),
|
||||
headerRight: () => <SearchComponent placeholder={$t('t_1_1745227838776')} />,
|
||||
content: () => (
|
||||
<div class="rounded-lg ">
|
||||
<TableComponent
|
||||
@@ -99,11 +79,7 @@ export default defineComponent({
|
||||
),
|
||||
footerRight: () => (
|
||||
<div class="mt-4 flex justify-end">
|
||||
<PageComponent
|
||||
v-slots={{
|
||||
prefix: () => <span>{$t('t_0_1746773350551', [data.value.total])}</span>,
|
||||
}}
|
||||
/>
|
||||
<PageComponent />
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
import { NSwitch, NTag, NButton, NSpace, NFlex, NText, NFormItem, NSelect } from 'naive-ui'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useStore } from '@autoDeploy/useStore'
|
||||
import { useDialog, useTable, useModal, useFormHooks, useForm, useModalHooks, useMessage } from '@baota/naive-ui/hooks'
|
||||
import {
|
||||
useDialog,
|
||||
useTable,
|
||||
useModal,
|
||||
useFormHooks,
|
||||
useForm,
|
||||
useModalHooks,
|
||||
useMessage,
|
||||
useSearch,
|
||||
} from '@baota/naive-ui/hooks'
|
||||
import { useStore as useWorkflowViewStore } from '@autoDeploy/children/workflowView/useStore'
|
||||
import { useError } from '@baota/hooks/error'
|
||||
import AddWorkflowModal from './components/WorkflowModal'
|
||||
@@ -152,7 +161,7 @@ export const useController = () => {
|
||||
]
|
||||
|
||||
// 表格实例
|
||||
const { TableComponent, PageComponent, loading, param, data, fetch } = useTable<WorkflowItem, WorkflowListParams>({
|
||||
const { TableComponent, PageComponent, loading, param, fetch } = useTable<WorkflowItem, WorkflowListParams>({
|
||||
config: createColumns(),
|
||||
request: fetchWorkflowList,
|
||||
storage: 'autoDeployPageSize',
|
||||
@@ -161,6 +170,14 @@ export const useController = () => {
|
||||
watchValue: ['p', 'limit'],
|
||||
})
|
||||
|
||||
// 搜索实例
|
||||
const { SearchComponent } = useSearch({
|
||||
onSearch: (value) => {
|
||||
param.value.search = value
|
||||
fetch()
|
||||
},
|
||||
})
|
||||
|
||||
// 节流渲染
|
||||
const throttleFn = useThrottleFn(() => {
|
||||
setTimeout(() => {
|
||||
@@ -229,7 +246,7 @@ export const useController = () => {
|
||||
title: exec_type === 'manual' ? $t('t_2_1745457488661') : $t('t_3_1745457486983'),
|
||||
content: exec_type === 'manual' ? $t('t_4_1745457497303') : $t('t_5_1745457494695'),
|
||||
onPositiveClick: () => setWorkflowExecType({ id, exec_type }),
|
||||
onNegativeClick: fetch,
|
||||
onNegativeClick: () => fetch(),
|
||||
onClose: fetch,
|
||||
})
|
||||
}
|
||||
@@ -243,8 +260,8 @@ export const useController = () => {
|
||||
title: !active ? $t('t_6_1745457487560') : $t('t_7_1745457487185'),
|
||||
content: !active ? $t('t_8_1745457496621') : $t('t_9_1745457500045'),
|
||||
onPositiveClick: () => setWorkflowActive({ id, active }),
|
||||
onNegativeClick: fetch,
|
||||
onClose: fetch,
|
||||
onNegativeClick: () => fetch(),
|
||||
onClose: () => fetch(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -335,6 +352,7 @@ export const useController = () => {
|
||||
return {
|
||||
TableComponent,
|
||||
PageComponent,
|
||||
SearchComponent,
|
||||
isDetectionAddWorkflow, // 检测是否需要添加工作流
|
||||
isDetectionOpenCAManage, // 检测是否需要打开CA授权管理弹窗
|
||||
isDetectionOpenAddCAForm, // 检测是否需要打开添加CA授权弹窗
|
||||
@@ -348,7 +366,6 @@ export const useController = () => {
|
||||
handleOpenCAManage, // 打开CA授权管理弹窗
|
||||
hasChildRoutes,
|
||||
fetch,
|
||||
data,
|
||||
loading,
|
||||
param,
|
||||
}
|
||||
@@ -504,8 +521,14 @@ export const useHistoryController = (id: string) => {
|
||||
* @returns 返回CA授权类型名称
|
||||
*/
|
||||
const handleCertAuth = (type: string) => {
|
||||
const name = type.replaceAll('.', '').replaceAll("'", '').replaceAll(' ', '').toLowerCase() // 处理类型中的特殊字符
|
||||
return CACertificateAuthorization[name as keyof typeof CACertificateAuthorization].type
|
||||
// console.log(type)
|
||||
try {
|
||||
const name = type.replaceAll('.', '').replaceAll("'", '').replaceAll(' ', '').toLowerCase() // 处理类型中的特殊字符
|
||||
const caType = CACertificateAuthorization[name as keyof typeof CACertificateAuthorization].type
|
||||
return { type: caType, icon: type }
|
||||
} catch (error) {
|
||||
return { type, icon: 'custom' }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -528,11 +551,11 @@ export const useCAManageController = (props: { type: string }) => {
|
||||
key: 'ca',
|
||||
width: 200,
|
||||
render: (row: EabItem) => {
|
||||
const name = handleCertAuth(row.ca)
|
||||
const { type, icon } = handleCertAuth(row.ca)
|
||||
return (
|
||||
<NFlex align="center">
|
||||
<SvgIcon icon={`cert-${name}`} size="2rem" />
|
||||
<NText>{name}</NText>
|
||||
<SvgIcon icon={`cert-${icon}`} size="2rem" />
|
||||
<NText>{type}</NText>
|
||||
</NFlex>
|
||||
)
|
||||
},
|
||||
@@ -606,10 +629,14 @@ export const useCAManageController = (props: { type: string }) => {
|
||||
* @param {EabItem} row - CA授权数据
|
||||
*/
|
||||
const handleEdit = (row: EabItem) => {
|
||||
const caTypes = Object.values(CACertificateAuthorization).map((item) => item.type)
|
||||
const isCustomCa = !caTypes.includes(row.ca)
|
||||
|
||||
// 填充表单数据 - 添加编辑模式标识
|
||||
Object.assign(caFormData.value, {
|
||||
email: row.email,
|
||||
ca: row.ca,
|
||||
ca: isCustomCa ? 'custom' : row.ca,
|
||||
caName: isCustomCa ? row.ca : '',
|
||||
Kid: row.Kid || '',
|
||||
HmacEncoded: row.HmacEncoded || '',
|
||||
CADirURL: row.CADirURL || '',
|
||||
@@ -666,7 +693,6 @@ export const useCAManageController = (props: { type: string }) => {
|
||||
*/
|
||||
export const useCAFormController = (props?: { isEdit?: boolean; editId?: string }) => {
|
||||
const { handleError } = useError()
|
||||
const message = useMessage()
|
||||
const { confirm } = useModalHooks()
|
||||
const { useFormInput, useFormCustom } = useFormHooks()
|
||||
|
||||
@@ -710,10 +736,26 @@ export const useCAFormController = (props?: { isEdit?: boolean; editId?: string
|
||||
|
||||
// 自定义类型必填 CADirURL
|
||||
if (currentCa === 'custom') {
|
||||
rules.caName = {
|
||||
required: true,
|
||||
message: '请输入CA名称',
|
||||
trigger: ['blur', 'input'],
|
||||
}
|
||||
rules.CADirURL = {
|
||||
required: true,
|
||||
message: $t('t_4_1750129259795'),
|
||||
trigger: ['blur', 'input'],
|
||||
validator: (rule: any, value: string) => {
|
||||
if (!value) {
|
||||
return new Error('请输入CA目录URL')
|
||||
}
|
||||
// Basic URL validation
|
||||
try {
|
||||
new URL(value)
|
||||
return true
|
||||
} catch (e) {
|
||||
return new Error('请输入有效的URL地址')
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -769,9 +811,6 @@ export const useCAFormController = (props?: { isEdit?: boolean; editId?: string
|
||||
|
||||
// 表单配置
|
||||
const formConfig = computed(() => [
|
||||
useFormInput($t('t_1_1745735764953'), 'email', {
|
||||
placeholder: $t('t_0_1747965909665'),
|
||||
}),
|
||||
useFormCustom(() => {
|
||||
return (
|
||||
<NFormItem label={$t('t_9_1747903669360')} path="ca">
|
||||
@@ -792,11 +831,17 @@ export const useCAFormController = (props?: { isEdit?: boolean; editId?: string
|
||||
</NFormItem>
|
||||
)
|
||||
}),
|
||||
useFormInput($t('t_1_1745735764953'), 'email', {
|
||||
placeholder: $t('t_0_1747965909665'),
|
||||
}),
|
||||
// 条件显示CADirURL字段
|
||||
...(shouldShowCADirURL.value
|
||||
? [
|
||||
useFormInput($t('t_5_1750129253961'), 'CADirURL', {
|
||||
placeholder: $t('t_6_1750129255766'),
|
||||
useFormInput('CA名称', 'caName', {
|
||||
placeholder: '请输入CA提供商名称',
|
||||
}),
|
||||
useFormInput($t('ACME服务URL地址'), 'CADirURL', {
|
||||
placeholder: $t('请输入ACME服务URL地址'),
|
||||
}),
|
||||
]
|
||||
: []),
|
||||
@@ -828,12 +873,17 @@ export const useCAFormController = (props?: { isEdit?: boolean; editId?: string
|
||||
// 提交表单
|
||||
const submitForm = async (formData: any) => {
|
||||
try {
|
||||
const dataToSubmit = { ...formData }
|
||||
if (dataToSubmit.ca === 'custom') {
|
||||
dataToSubmit.ca = dataToSubmit.caName
|
||||
}
|
||||
delete dataToSubmit.caName // 删除临时字段
|
||||
if (props?.isEdit && props?.editId) {
|
||||
// 编辑模式
|
||||
await updateExistingEab({ ...formData, id: props.editId })
|
||||
await updateExistingEab({ ...dataToSubmit, id: props.editId })
|
||||
} else {
|
||||
// 新增模式
|
||||
await addNewEab(formData)
|
||||
await addNewEab(dataToSubmit)
|
||||
}
|
||||
return true
|
||||
} catch (error) {
|
||||
@@ -843,7 +893,7 @@ export const useCAFormController = (props?: { isEdit?: boolean; editId?: string
|
||||
}
|
||||
|
||||
// 表单实例
|
||||
const { component: CAForm } = useForm({
|
||||
const { component: CAForm, fetch } = useForm({
|
||||
config: formConfig,
|
||||
rules: getFormRules(),
|
||||
defaultValue: caFormData,
|
||||
@@ -853,7 +903,7 @@ export const useCAFormController = (props?: { isEdit?: boolean; editId?: string
|
||||
// 确认提交表单
|
||||
confirm(async (close) => {
|
||||
try {
|
||||
await submitForm(caFormData.value)
|
||||
await fetch()
|
||||
close()
|
||||
} catch (error) {
|
||||
handleError(error)
|
||||
|
||||
@@ -13,12 +13,10 @@ import EmptyState from '@components/TableEmptyState'
|
||||
export default defineComponent({
|
||||
name: 'CertManage',
|
||||
setup() {
|
||||
const { TableComponent, PageComponent, fetch, data, param, openUploadModal, getRowClassName } = useController()
|
||||
const { TableComponent, PageComponent, SearchComponent, openUploadModal, getRowClassName } = useController()
|
||||
|
||||
const cssVar = useThemeCssVar(['contentPadding', 'borderColor', 'headerHeight', 'iconColorHover'])
|
||||
// 挂载时请求数据
|
||||
onMounted(() => fetch())
|
||||
const { theme, themeOverrides } = useTheme()
|
||||
console.log(theme.value, themeOverrides.value)
|
||||
|
||||
return () => (
|
||||
<div class="h-full flex flex-col" style={cssVar.value}>
|
||||
<div class="mx-auto max-w-[1600px] w-full p-6">
|
||||
@@ -29,26 +27,7 @@ export default defineComponent({
|
||||
{$t('t_13_1745227838275')}
|
||||
</NButton>
|
||||
),
|
||||
headerRight: () => (
|
||||
<NInput
|
||||
v-model:value={param.value.search}
|
||||
onKeydown={(e: KeyboardEvent) => {
|
||||
if (e.key === 'Enter') fetch()
|
||||
}}
|
||||
onClear={() => useThrottleFn(fetch, 100)}
|
||||
placeholder={$t('t_14_1745227840904')}
|
||||
clearable
|
||||
size="large"
|
||||
class="min-w-[300px]"
|
||||
v-slots={{
|
||||
suffix: () => (
|
||||
<div class="flex items-center" onClick={fetch}>
|
||||
<Search class="text-[var(--text-color-3)] w-[1.6rem] cursor-pointer font-bold" />
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
></NInput>
|
||||
),
|
||||
headerRight: () => <SearchComponent placeholder={$t('t_14_1745227840904')} />,
|
||||
content: () => (
|
||||
<div class="rounded-lg">
|
||||
<TableComponent
|
||||
@@ -62,15 +41,7 @@ export default defineComponent({
|
||||
),
|
||||
footerRight: () => (
|
||||
<div class="mt-4 flex justify-end">
|
||||
<PageComponent
|
||||
v-slots={{
|
||||
prefix: () => (
|
||||
<span>
|
||||
{$t('t_15_1745227839354')} {data.value.total} {$t('t_16_1745227838930')}
|
||||
</span>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<PageComponent />
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
useForm,
|
||||
useLoadingMask,
|
||||
useMessage,
|
||||
useSearch,
|
||||
} from '@baota/naive-ui/hooks'
|
||||
import { useError } from '@baota/hooks/error'
|
||||
import { $t } from '@locales/index'
|
||||
@@ -135,6 +136,14 @@ export const useController = () => {
|
||||
storage: 'certManagePageSize',
|
||||
})
|
||||
|
||||
// 搜索实例
|
||||
const { SearchComponent } = useSearch({
|
||||
onSearch: (value) => {
|
||||
param.value.search = value
|
||||
fetch()
|
||||
},
|
||||
})
|
||||
|
||||
/**
|
||||
* @description 打开上传证书弹窗
|
||||
*/
|
||||
@@ -189,14 +198,14 @@ export const useController = () => {
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => fetch())
|
||||
|
||||
return {
|
||||
loading,
|
||||
fetch,
|
||||
TableComponent,
|
||||
PageComponent,
|
||||
SearchComponent,
|
||||
getRowClassName,
|
||||
param,
|
||||
data,
|
||||
openUploadModal,
|
||||
openViewModal,
|
||||
}
|
||||
|
||||
@@ -18,7 +18,8 @@ export default defineComponent({
|
||||
name: 'MonitorManage',
|
||||
setup() {
|
||||
// 使用控制器获取数据和方法
|
||||
const { TableComponent, PageComponent, param, fetch, data, openAddForm, isDetectionAddMonitor } = useController()
|
||||
const { TableComponent, PageComponent, SearchComponent, fetch, openAddForm, isDetectionAddMonitor } =
|
||||
useController()
|
||||
|
||||
// 获取主题CSS变量
|
||||
const cssVar = useThemeCssVar(['contentPadding', 'borderColor', 'headerHeight', 'iconColorHover'])
|
||||
@@ -44,26 +45,7 @@ export default defineComponent({
|
||||
</NButton>
|
||||
),
|
||||
// 头部右侧区域 - 搜索框
|
||||
headerRight: () => (
|
||||
<NInput
|
||||
v-model:value={param.value.search}
|
||||
onKeydown={(e: KeyboardEvent) => {
|
||||
if (e.key === 'Enter') fetch()
|
||||
}}
|
||||
onClear={() => fetch()}
|
||||
placeholder={$t('t_12_1745289356974')}
|
||||
clearable
|
||||
size="large"
|
||||
class="min-w-[300px]"
|
||||
v-slots={{
|
||||
suffix: () => (
|
||||
<div class="flex items-center" onClick={fetch}>
|
||||
<Search class="text-[var(--text-color-3)] w-[1.6rem] cursor-pointer font-bold" />
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
></NInput>
|
||||
),
|
||||
headerRight: () => <SearchComponent placeholder={$t('t_12_1745289356974')} />,
|
||||
// 内容区域 - 监控表格
|
||||
content: () => (
|
||||
<div class="rounded-lg">
|
||||
@@ -78,15 +60,7 @@ export default defineComponent({
|
||||
// 底部右侧区域 - 分页组件
|
||||
footerRight: () => (
|
||||
<div class="mt-4 flex justify-end">
|
||||
<PageComponent
|
||||
v-slots={{
|
||||
prefix: () => (
|
||||
<span>
|
||||
{$t('t_15_1745227839354')} {data.value.total} {$t('t_16_1745227838930')}
|
||||
</span>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<PageComponent />
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
useForm,
|
||||
useFormHooks,
|
||||
useLoadingMask,
|
||||
useSearch,
|
||||
} from '@baota/naive-ui/hooks'
|
||||
import { useError } from '@baota/hooks/error'
|
||||
import { isDomain, isPort, isIp } from '@baota/utils/business'
|
||||
@@ -38,9 +39,10 @@ interface MonitorControllerExposes {
|
||||
// 表格相关
|
||||
TableComponent: ReturnType<typeof useTable>['TableComponent']
|
||||
PageComponent: ReturnType<typeof useTable>['PageComponent']
|
||||
SearchComponent: ReturnType<typeof useSearch>['SearchComponent']
|
||||
loading: Ref<boolean>
|
||||
param: Ref<SiteMonitorListParams>
|
||||
data: Ref<{ list: SiteMonitorItem[]; total: number }>
|
||||
// param: Ref<SiteMonitorListParams>
|
||||
// data: Ref<{ list: SiteMonitorItem[]; total: number }>
|
||||
fetch: () => Promise<void>
|
||||
|
||||
// 表单和操作相关
|
||||
@@ -144,6 +146,24 @@ export const useController = (): MonitorControllerExposes => {
|
||||
width: 150,
|
||||
render: (row: SiteMonitorItem) => row.end_time + '(' + row.end_day + ')',
|
||||
},
|
||||
{
|
||||
title: $t('上次异常时间'),
|
||||
key: 'except_end_time',
|
||||
width: 150,
|
||||
render: (row: SiteMonitorItem) => row.except_end_time || '-',
|
||||
},
|
||||
{
|
||||
title: $t('上次检查时间'),
|
||||
key: 'last_time',
|
||||
width: 150,
|
||||
render: (row: SiteMonitorItem) => row.last_time || '-',
|
||||
},
|
||||
{
|
||||
title: $t('更新时间'),
|
||||
key: 'update_time',
|
||||
width: 150,
|
||||
render: (row: SiteMonitorItem) => row.update_time || '-',
|
||||
},
|
||||
{
|
||||
title: $t('t_18_1745289354598'),
|
||||
key: 'report_type',
|
||||
@@ -160,12 +180,6 @@ export const useController = (): MonitorControllerExposes => {
|
||||
return <NSwitch value={row.active === 1} onUpdateValue={() => toggleStatus(row)} />
|
||||
},
|
||||
},
|
||||
{
|
||||
title: $t('t_19_1745289354676'),
|
||||
key: 'update_time',
|
||||
width: 150,
|
||||
render: (row: SiteMonitorItem) => row.update_time || '-',
|
||||
},
|
||||
{
|
||||
title: $t('t_7_1745215914189'),
|
||||
key: 'create_time',
|
||||
@@ -196,10 +210,7 @@ export const useController = (): MonitorControllerExposes => {
|
||||
* 表格实例
|
||||
* @description 创建表格实例并管理相关状态
|
||||
*/
|
||||
const { TableComponent, PageComponent, loading, param, data, total, fetch } = useTable<
|
||||
SiteMonitorItem,
|
||||
SiteMonitorListParams
|
||||
>({
|
||||
const { TableComponent, PageComponent, loading, param, fetch } = useTable<SiteMonitorItem, SiteMonitorListParams>({
|
||||
config: createColumns(),
|
||||
request: fetchMonitorList,
|
||||
defaultValue: { p: 1, limit: 10, search: '' },
|
||||
@@ -208,15 +219,13 @@ export const useController = (): MonitorControllerExposes => {
|
||||
storage: 'monitorPageSize',
|
||||
})
|
||||
|
||||
// /**
|
||||
// * 分页实例
|
||||
// * @description 创建表格分页组件
|
||||
// */
|
||||
// const { component: MonitorTablePage } = useTablePage({
|
||||
// param,
|
||||
// total,
|
||||
// ,
|
||||
// })
|
||||
// 搜索实例
|
||||
const { SearchComponent } = useSearch({
|
||||
onSearch: (value) => {
|
||||
param.value.search = value
|
||||
fetch()
|
||||
},
|
||||
})
|
||||
|
||||
/**
|
||||
* 打开添加监控弹窗
|
||||
@@ -297,9 +306,8 @@ export const useController = (): MonitorControllerExposes => {
|
||||
fetch,
|
||||
TableComponent,
|
||||
PageComponent,
|
||||
SearchComponent,
|
||||
isDetectionAddMonitor,
|
||||
param,
|
||||
data,
|
||||
openAddForm,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user