mirror of
https://gitee.com/mirrors/AllinSSL.git
synced 2026-03-08 15:51:11 +08:00
【调整】api授权新增lecdn和constellix类型
【调整】部署新增LeCdn类型
This commit is contained in:
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 5.7 KiB |
@@ -1 +1 @@
|
||||
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"><text x="50%" y="50%" font-size="48" fill="#a2a9b6" font-family="system-ui, sans-serif" text-anchor="middle" dominant-baseline="middle">LeCDN</text></svg>
|
||||
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 146.61 146.61"><defs><style>.cls-1{fill:url(#未命名的渐变_8);}.cls-2{fill:url(#未命名的渐变_7);}.cls-3{fill:url(#未命名的渐变_7-2);}.cls-4{fill:#7b358f;}</style><linearGradient id="未命名的渐变_8" x1="36.4" y1="42.76" x2="124.15" y2="91.15" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#348bcc"/><stop offset="1" stop-color="#2a6cb6"/></linearGradient><linearGradient id="未命名的渐变_7" x1="104.54" y1="79.61" x2="71.65" y2="80.94" xlink:href="#未命名的渐变_8"/><linearGradient id="未命名的渐变_7-2" x1="61.76" y1="70.81" x2="79.66" y2="33.73" xlink:href="#未命名的渐变_8"/></defs><path class="cls-1" d="M123.41,31.19V65.35A52.62,52.62,0,0,1,108,102.58L83.25,127.33a12,12,0,0,1-16.77.25L39.75,102.4A52.67,52.67,0,0,1,23.2,64.07V31.19A15.43,15.43,0,0,1,38.63,15.76H59.34c1,0,18,.14,13.75,9.6H38.8a6.37,6.37,0,0,0-6.37,6.37V64.78A42.94,42.94,0,0,0,45.93,96l24.3,22.89A6.3,6.3,0,0,0,79,118.8L101.6,96.19a42.94,42.94,0,0,0,12.58-30.37V31.73a6.37,6.37,0,0,0-6.36-6.37H98.13A15.52,15.52,0,0,0,94,15.76h14A15.43,15.43,0,0,1,123.41,31.19Z"/><path class="cls-2" d="M104.36,67.4S101,89.32,80.14,92.82h0c-11.37.37-9.15-11.38-6.75-18.55C74.69,74.53,94.85,78.25,104.36,67.4Z"/><path class="cls-3" d="M91.05,31.08l-1.76,4.28L75.51,68.89a0,0,0,0,1,0,0,.16.16,0,0,0,0,.06c-.17.37-.88,1.93-1.67,4.1h0l-.48,1.18h.07c-2.4,7.17-4.62,18.92,6.75,18.55a36.5,36.5,0,0,1-8.12.41s-30.26.37-18.78-23.48L73.09,25.36c4.23-9.46-12.74-9.6-13.75-9.6h20.4a13.13,13.13,0,0,1,8,2.6C90.88,20.78,93,24.71,91.05,31.08Z"/><path class="cls-4" d="M75.47,69l-1.67,4.1C74.59,70.9,75.3,69.34,75.47,69Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 219 B After Width: | Height: | Size: 1.7 KiB |
@@ -254,6 +254,7 @@ export interface DeployConfig<
|
||||
| 'safeline-site'
|
||||
| 'safeline-panel'
|
||||
| 'btpanel-dockersite'
|
||||
| 'lecdn' // LeCDN 部署类型
|
||||
| 'plugin', // 新增插件类型
|
||||
> {
|
||||
provider: T
|
||||
@@ -331,6 +332,12 @@ export interface DeployBTPanelDockerSiteConfig extends DeployBTPanelSiteConfig {
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
// 部署LeCDN配置
|
||||
export interface DeployLeCDNConfig {
|
||||
site_id: string // 站点ID
|
||||
domain: string // 域名
|
||||
}
|
||||
|
||||
// 部署插件配置
|
||||
export interface DeployPluginConfig {
|
||||
action: string // 插件方法名称
|
||||
@@ -352,6 +359,7 @@ export type DeployNodeConfig = DeployConfig<
|
||||
| DeploySafelineConfig // 部署节点配置(雷池WAF)
|
||||
| DeploySafelineSiteConfig // 部署节点配置(雷池WAF站点)
|
||||
| DeployBTPanelDockerSiteConfig // 部署节点配置(宝塔docker站点)
|
||||
| DeployLeCDNConfig // 部署节点配置(LeCDN)
|
||||
| DeployPluginConfig // 部署节点配置(插件)
|
||||
>
|
||||
|
||||
|
||||
@@ -225,6 +225,19 @@ export const ApiProjectConfig: Record<string, ApiProjectType> = {
|
||||
type: ['dns'],
|
||||
sort: 25,
|
||||
},
|
||||
lecdn: {
|
||||
name: 'LeCDN',
|
||||
icon: 'lecdn',
|
||||
type: ['dns', 'host'],
|
||||
hostRelated: { default: { name: 'LeCDN' } },
|
||||
sort: 26,
|
||||
},
|
||||
constellix: {
|
||||
name: 'Constellix',
|
||||
icon: 'constellix',
|
||||
type: ['dns'],
|
||||
sort: 27,
|
||||
},
|
||||
doge: {
|
||||
name: $t('t_0_1750129254226'),
|
||||
icon: 'doge',
|
||||
@@ -232,14 +245,14 @@ export const ApiProjectConfig: Record<string, ApiProjectType> = {
|
||||
hostRelated: {
|
||||
cdn: { name: $t('t_0_1750129254226') + 'CDN' },
|
||||
},
|
||||
sort: 26,
|
||||
sort: 28,
|
||||
},
|
||||
plugin: {
|
||||
name: '插件',
|
||||
icon: 'plugin',
|
||||
type: ['host'],
|
||||
hostRelated: { default: { name: '插件' } },
|
||||
sort: 27,
|
||||
sort: 29,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"t_0_1750469182154": "صيغة اسم المجال خاطئة",
|
||||
"t_0_1744098811152": "تحذير: لقد دخلتم منطقة غير معروفة، الصفحة التي تحاول زيارتها غير موجودة، يرجى الضغط على الزر للعودة إلى الصفحة الرئيسية.",
|
||||
"t_1_1744098801860": "رجوع إلى الصفحة الرئيسية",
|
||||
"t_2_1744098804908": "نصيحة أمنية: إذا كنت تعتقد أن هذا خطأ، يرجى الاتصال بالمدير على الفور",
|
||||
@@ -667,5 +666,6 @@
|
||||
"t_0_1750399513983": "عنوان URL لخدمة ACME",
|
||||
"t_1_1750399516161": "يرجى إدخال عنوان URL لخدمة ACME",
|
||||
"t_2_1750399515511": "وقت آخر استثناء",
|
||||
"t_3_1750399513606": "شهادة CA"
|
||||
"t_3_1750399513606": "شهادة CA",
|
||||
"t_0_1750469182154": "صيغة اسم المجال خاطئة"
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"t_0_1750469182154": "Domain name format is incorrect",
|
||||
"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",
|
||||
@@ -667,5 +666,6 @@
|
||||
"t_0_1750399513983": "ACME service URL address",
|
||||
"t_1_1750399516161": "Please enter the ACME service URL address",
|
||||
"t_2_1750399515511": "Last exception time",
|
||||
"t_3_1750399513606": "Certificate CA"
|
||||
"t_3_1750399513606": "Certificate CA",
|
||||
"t_0_1750469182154": "Domain name format is incorrect"
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"t_0_1750469182154": "Formato de nombre de dominio incorrecto",
|
||||
"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",
|
||||
@@ -667,5 +666,6 @@
|
||||
"t_0_1750399513983": "Dirección URL del servicio ACME",
|
||||
"t_1_1750399516161": "Por favor, ingrese la URL del servicio ACME",
|
||||
"t_2_1750399515511": "Hora de la última excepción",
|
||||
"t_3_1750399513606": "Certificado CA"
|
||||
"t_3_1750399513606": "Certificado CA",
|
||||
"t_0_1750469182154": "Formato de nombre de dominio incorrecto"
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"t_0_1750469182154": "Format du nom de domaine incorrect",
|
||||
"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",
|
||||
@@ -667,5 +666,6 @@
|
||||
"t_0_1750399513983": "URL du service ACME",
|
||||
"t_1_1750399516161": "Veuillez entrer l'URL du service ACME",
|
||||
"t_2_1750399515511": "Heure de la dernière exception",
|
||||
"t_3_1750399513606": "Certificat CA"
|
||||
"t_3_1750399513606": "Certificat CA",
|
||||
"t_0_1750469182154": "Format du nom de domaine incorrect"
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"t_0_1750469182154": "ドメイン名の形式が間違っています",
|
||||
"t_0_1744098811152": "警告:未知のエリアに進入しました。アクセスしようとしたページは存在しません。ボタンをクリックしてホームページに戻ってください。",
|
||||
"t_1_1744098801860": "ホームに戻る",
|
||||
"t_2_1744098804908": "安全注意:これが誤りだと思われる場合は、すぐに管理者に連絡してください",
|
||||
@@ -667,5 +666,6 @@
|
||||
"t_0_1750399513983": "ACMEサービスURLアドレス",
|
||||
"t_1_1750399516161": "ACMEサービスURLアドレスを入力してください",
|
||||
"t_2_1750399515511": "最終異常時間",
|
||||
"t_3_1750399513606": "証明書CA"
|
||||
"t_3_1750399513606": "証明書CA",
|
||||
"t_0_1750469182154": "ドメイン名の形式が間違っています"
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"t_0_1750469182154": "도메인 이름 형식이 잘못되었습니다",
|
||||
"t_0_1744098811152": "경고: 알 수 없는 영역에 진입했습니다. 방문하려는 페이지가 존재하지 않습니다. 버튼을 클릭하여 홈페이지로 돌아가세요。",
|
||||
"t_1_1744098801860": "홈으로 돌아가기",
|
||||
"t_2_1744098804908": "안전 유의사항: 이가 오류라면 즉시 관리자에게 연락하십시오",
|
||||
@@ -667,5 +666,6 @@
|
||||
"t_0_1750399513983": "ACME 서비스 URL 주소",
|
||||
"t_1_1750399516161": "ACME 서비스 URL 주소를 입력하세요",
|
||||
"t_2_1750399515511": "마지막 예외 시간",
|
||||
"t_3_1750399513606": "인증서 CA"
|
||||
"t_3_1750399513606": "인증서 CA",
|
||||
"t_0_1750469182154": "도메인 이름 형식이 잘못되었습니다"
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"t_0_1750469182154": "Formato do nome de domínio incorreto",
|
||||
"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",
|
||||
@@ -667,5 +666,6 @@
|
||||
"t_0_1750399513983": "Endereço URL do serviço ACME",
|
||||
"t_1_1750399516161": "Por favor, insira o URL do serviço ACME",
|
||||
"t_2_1750399515511": "Hora da última exceção",
|
||||
"t_3_1750399513606": "Certificado CA"
|
||||
"t_3_1750399513606": "Certificado CA",
|
||||
"t_0_1750469182154": "Formato do nome de domínio incorreto"
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"t_0_1750469182154": "Неверный формат доменного имени",
|
||||
"t_0_1744098811152": "Предупреждение: Вы вошли в неизвестную зону, посещаемая страница не существует, пожалуйста, нажмите кнопку, чтобы вернуться на главную страницу.",
|
||||
"t_1_1744098801860": "Вернуться на главную",
|
||||
"t_2_1744098804908": "Совет по безопасности: Если вы считаете, что это ошибка, немедленно свяжитесь с администратором",
|
||||
@@ -667,5 +666,6 @@
|
||||
"t_0_1750399513983": "URL-адрес службы ACME",
|
||||
"t_1_1750399516161": "Введите URL-адрес службы ACME",
|
||||
"t_2_1750399515511": "Время последнего исключения",
|
||||
"t_3_1750399513606": "Сертификат CA"
|
||||
"t_3_1750399513606": "Сертификат CA",
|
||||
"t_0_1750469182154": "Неверный формат доменного имени"
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"t_0_1750469182154": "域名格式错误",
|
||||
"t_0_1744098811152": "警告:您已进入未知区域,所访问的页面不存在,请点击按钮返回首页。",
|
||||
"t_1_1744098801860": "返回首页",
|
||||
"t_2_1744098804908": "安全提示:如果您认为这是个错误,请立即联系管理员",
|
||||
@@ -667,5 +666,6 @@
|
||||
"t_0_1750399513983": "ACME服务URL地址",
|
||||
"t_1_1750399516161": "请输入ACME服务URL地址",
|
||||
"t_2_1750399515511": "上次异常时间",
|
||||
"t_3_1750399513606": "证书CA"
|
||||
"t_3_1750399513606": "证书CA",
|
||||
"t_0_1750469182154": "域名格式错误"
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"t_0_1750469182154": "網域名稱格式錯誤",
|
||||
"t_0_1744098811152": "警告:您已進入未知區域,所訪問的頁面不存在,請點擊按鈕返回首頁。",
|
||||
"t_1_1744098801860": "返回首頁",
|
||||
"t_2_1744098804908": "安全提示:如果您認為這是個錯誤,請立即聯繫管理員",
|
||||
@@ -666,5 +665,6 @@
|
||||
"t_0_1750399513983": "ACME服務URL地址",
|
||||
"t_1_1750399516161": "請輸入ACME服務URL地址",
|
||||
"t_2_1750399515511": "上次異常時間",
|
||||
"t_3_1750399513606": "證書CA"
|
||||
"t_3_1750399513606": "證書CA",
|
||||
"t_0_1750469182154": "網域名稱格式錯誤"
|
||||
}
|
||||
27
frontend/apps/allin-ssl/src/types/access.d.ts
vendored
27
frontend/apps/allin-ssl/src/types/access.d.ts
vendored
@@ -60,7 +60,9 @@ export interface AddAccessParams<
|
||||
| GcoreAccessConfig
|
||||
| JdcloudAccessConfig
|
||||
| DogeAccessConfig
|
||||
| PluginAccessConfig,
|
||||
| PluginAccessConfig
|
||||
| LecdnAccessConfig
|
||||
| ConstellixAccessConfig,
|
||||
> {
|
||||
name: string
|
||||
type: string
|
||||
@@ -93,7 +95,9 @@ export interface UpdateAccessParams<
|
||||
| GcoreAccessConfig
|
||||
| JdcloudAccessConfig
|
||||
| DogeAccessConfig
|
||||
| PluginAccessConfig,
|
||||
| PluginAccessConfig
|
||||
| LecdnAccessConfig
|
||||
| ConstellixAccessConfig,
|
||||
> extends AddAccessParams<T> {
|
||||
id: string
|
||||
}
|
||||
@@ -130,6 +134,7 @@ export interface PanelAccessConfig {
|
||||
url: string
|
||||
api_key: string
|
||||
ignore_ssl: '0' | '1'
|
||||
version?: 'v1' | 'v2' // 1Panel版本选择,可选字段
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -280,6 +285,24 @@ export interface PluginAccessConfig {
|
||||
config: Record<string, any> | string
|
||||
}
|
||||
|
||||
/**
|
||||
* Lecdn 授权配置
|
||||
*/
|
||||
export interface LecdnAccessConfig {
|
||||
url: string
|
||||
username: string
|
||||
password: string
|
||||
ignore_ssl: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Constellix 授权配置
|
||||
*/
|
||||
export interface ConstellixAccessConfig {
|
||||
api_key: string
|
||||
secret_key: string
|
||||
}
|
||||
|
||||
/** 删除授权请求参数 */
|
||||
export interface DeleteAccessParams {
|
||||
id: string
|
||||
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
FormItemRule,
|
||||
FormProps,
|
||||
FormRules,
|
||||
NAlert,
|
||||
NButton,
|
||||
NFlex,
|
||||
NFormItem,
|
||||
@@ -37,6 +38,7 @@ import type {
|
||||
AddAccessParams,
|
||||
SshAccessConfig,
|
||||
UpdateAccessParams,
|
||||
PanelAccessConfig,
|
||||
NamecheapAccessConfig,
|
||||
NS1AccessConfig,
|
||||
CloudnsAccessConfig,
|
||||
@@ -49,6 +51,8 @@ import type {
|
||||
JdcloudAccessConfig,
|
||||
DogeAccessConfig,
|
||||
PluginAccessConfig,
|
||||
LecdnAccessConfig,
|
||||
ConstellixAccessConfig,
|
||||
} from '@/types/access'
|
||||
import type { VNode, Ref } from 'vue'
|
||||
import { testAccess, getPlugins } from '@/api/access'
|
||||
@@ -343,9 +347,18 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
message: $t('t_3_1744164839524'),
|
||||
},
|
||||
username: {
|
||||
required: true,
|
||||
message: $t('t_0_1747365600180'),
|
||||
trigger: 'input',
|
||||
validator: (rule: FormItemRule, value: string, callback: (error?: Error) => void) => {
|
||||
if (!value) {
|
||||
const mapTips = {
|
||||
westcn: $t('t_0_1747365600180'),
|
||||
namedotcom: '请输入用户名',
|
||||
lecdn: '请输入用户名',
|
||||
}
|
||||
return callback(new Error(mapTips[param.value.type as keyof typeof mapTips] || $t('t_0_1747365600180')))
|
||||
}
|
||||
callback()
|
||||
},
|
||||
},
|
||||
password: {
|
||||
trigger: 'input',
|
||||
@@ -354,6 +367,7 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
const mapTips = {
|
||||
westcn: $t('t_1_1747365603108'),
|
||||
ssh: $t('t_0_1747711335067'),
|
||||
lecdn: '请输入密码',
|
||||
}
|
||||
return callback(new Error(mapTips[param.value.type as keyof typeof mapTips]))
|
||||
}
|
||||
@@ -374,6 +388,7 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
btpanel: $t('t_2_1745317314362'),
|
||||
btwaf: $t('t_0_1747271295174'),
|
||||
safeline: $t('t_0_1747300383756'),
|
||||
lecdn: '请输入正确的URL地址',
|
||||
}
|
||||
return callback(new Error(mapTips[param.value.type as keyof typeof mapTips]))
|
||||
}
|
||||
@@ -391,6 +406,7 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
godaddy: $t('t_0_1747984137443'),
|
||||
ns1: '请输入API Key',
|
||||
namecheap: '请输入API Key',
|
||||
constellix: '请输入API Key',
|
||||
}
|
||||
return callback(new Error(mapTips[param.value.type as keyof typeof mapTips]))
|
||||
}
|
||||
@@ -504,6 +520,7 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
baidu: $t('t_4_1747271294621'),
|
||||
volcengine: $t('t_4_1747365600137'),
|
||||
doge: $t('t_1_1750320241427'),
|
||||
constellix: '请输入Secret Key',
|
||||
}
|
||||
return callback(new Error(mapTips[param.value.type as keyof typeof mapTips]))
|
||||
}
|
||||
@@ -513,6 +530,10 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
email: {
|
||||
trigger: 'input',
|
||||
validator: (rule: FormItemRule, value: string, callback: (error?: Error) => void) => {
|
||||
if (param.value.type === 'cloudflare' && (!value || value.trim() === '')) {
|
||||
return callback()
|
||||
}
|
||||
|
||||
if (!isEmail(value)) {
|
||||
return callback(new Error($t('t_5_1747042965911')))
|
||||
}
|
||||
@@ -553,7 +574,7 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
<NSelect
|
||||
class="w-full"
|
||||
options={typeList}
|
||||
renderLabel={renderLabel}
|
||||
renderLabel={renderTypeLabel}
|
||||
renderTag={renderSingleSelectTag}
|
||||
disabled={!!props.data?.id}
|
||||
filterable
|
||||
@@ -606,6 +627,44 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
)
|
||||
break
|
||||
case '1panel':
|
||||
items.push(
|
||||
// 1Panel版本选择下拉框
|
||||
useFormCustom(() => {
|
||||
const config = param.value.config as PanelAccessConfig
|
||||
// 如果version为空或者没有version字段,默认为v1
|
||||
const currentVersion = config.version || 'v1'
|
||||
|
||||
return (
|
||||
<NFormItem label="版本" path="config.version" showRequireMark={false}>
|
||||
<NSelect
|
||||
class="w-full"
|
||||
options={[
|
||||
{ label: 'v1', value: 'v1' },
|
||||
{ label: 'v2', value: 'v2' },
|
||||
]}
|
||||
placeholder="请选择版本"
|
||||
value={currentVersion}
|
||||
onUpdateValue={(value: 'v1' | 'v2') => {
|
||||
;(param.value.config as PanelAccessConfig).version = value
|
||||
}}
|
||||
/>
|
||||
</NFormItem>
|
||||
)
|
||||
}),
|
||||
useFormInput(typeUrlMap.get(param.value.type) || '', 'config.url', {
|
||||
allowInput: noSideSpace,
|
||||
}),
|
||||
useFormInput($t('t_55_1745289355715'), 'config.api_key', {
|
||||
allowInput: noSideSpace,
|
||||
}),
|
||||
useFormSwitch(
|
||||
$t('t_3_1746667592270'),
|
||||
'config.ignore_ssl',
|
||||
{ checkedValue: '1', uncheckedValue: '0' },
|
||||
{ showRequireMark: false },
|
||||
),
|
||||
)
|
||||
break
|
||||
case 'btpanel':
|
||||
case 'btwaf':
|
||||
case 'safeline':
|
||||
@@ -651,8 +710,15 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
break
|
||||
case 'cloudflare':
|
||||
items.push(
|
||||
useFormInput('邮箱', 'config.email', { allowInput: noSideSpace }),
|
||||
useFormInput('邮箱', 'config.email', { allowInput: noSideSpace }, { showRequireMark: false }),
|
||||
useFormInput('APIKey', 'config.api_key', { allowInput: noSideSpace }),
|
||||
useFormCustom(() => {
|
||||
return (
|
||||
<NAlert type="error" class="mt-[1.2rem] whitespace-nowrap" showIcon={false}>
|
||||
<span class="text-[1.3rem]">使用API令牌时不要填写邮箱,否则将作为Global Key请求Cloudflare</span>
|
||||
</NAlert>
|
||||
)
|
||||
}),
|
||||
)
|
||||
break
|
||||
case 'westcn':
|
||||
@@ -723,6 +789,25 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
useFormInput('Secret Access Key', 'config.secret_access_key', { allowInput: noSideSpace }),
|
||||
)
|
||||
break
|
||||
case 'lecdn':
|
||||
items.push(
|
||||
useFormInput('URL', 'config.url', { allowInput: noSideSpace }),
|
||||
useFormInput('Username', 'config.username', { allowInput: noSideSpace }),
|
||||
useFormInput('Password', 'config.password', { allowInput: noSideSpace }),
|
||||
useFormSwitch(
|
||||
$t('t_3_1746667592270'),
|
||||
'config.ignore_ssl',
|
||||
{ checkedValue: '1', uncheckedValue: '0' },
|
||||
{ showRequireMark: false },
|
||||
),
|
||||
)
|
||||
break
|
||||
case 'constellix':
|
||||
items.push(
|
||||
useFormInput('API Key', 'config.api_key', { allowInput: noSideSpace }),
|
||||
useFormInput('Secret Key', 'config.secret_key', { allowInput: noSideSpace }),
|
||||
)
|
||||
break
|
||||
case 'plugin':
|
||||
items.push(
|
||||
useFormCustom(() => {
|
||||
@@ -814,6 +899,13 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
} as SshAccessConfig
|
||||
break
|
||||
case '1panel':
|
||||
param.value.config = {
|
||||
url: '',
|
||||
api_key: '',
|
||||
ignore_ssl: '0',
|
||||
version: 'v1', // 默认选择 v1 版本
|
||||
} as PanelAccessConfig
|
||||
break
|
||||
case 'btpanel':
|
||||
case 'btwaf':
|
||||
param.value.config = {
|
||||
@@ -917,6 +1009,20 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
secret_access_key: '',
|
||||
} as JdcloudAccessConfig
|
||||
break
|
||||
case 'lecdn':
|
||||
param.value.config = {
|
||||
url: '',
|
||||
username: '',
|
||||
password: '',
|
||||
ignore_ssl: '0',
|
||||
} as LecdnAccessConfig
|
||||
break
|
||||
case 'constellix':
|
||||
param.value.config = {
|
||||
api_key: '',
|
||||
secret_key: '',
|
||||
} as ConstellixAccessConfig
|
||||
break
|
||||
case 'doge':
|
||||
param.value.config = {
|
||||
access_key: '',
|
||||
@@ -967,7 +1073,7 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
return (
|
||||
<NFlex class="w-full">
|
||||
{option.label ? (
|
||||
renderLabel(option)
|
||||
renderTypeLabel(option)
|
||||
) : (
|
||||
<span class="text-[1.4rem] text-gray-400">{$t('t_0_1745833934390')}</span>
|
||||
)}
|
||||
@@ -976,18 +1082,39 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染标签
|
||||
* @param {Record<string, any>} option - 选项
|
||||
* 类型选项接口
|
||||
*/
|
||||
interface TypeOption {
|
||||
label: string
|
||||
value: string
|
||||
access: string[]
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染类型选择器标签
|
||||
* @param {TypeOption} option - 类型选项
|
||||
* @returns {VNode} 渲染后的VNode
|
||||
*/
|
||||
const renderLabel = (option: PluginOption): VNode => {
|
||||
const renderTypeLabel = (option: TypeOption): VNode => {
|
||||
const accessTypeMap = {
|
||||
dns: $t('t_3_1745735765112'),
|
||||
host: $t('t_0_1746754500246'),
|
||||
plugin: '插件',
|
||||
}
|
||||
|
||||
return (
|
||||
<NFlex justify="space-between" class="w-[38rem]">
|
||||
<NFlex align="center" size="small">
|
||||
<SvgIcon icon={`resources-${option.value}`} size="1.6rem" />
|
||||
<NText>{option.label}</NText>
|
||||
{option.description && <div class="text-[1.2rem] text-gray-500 mt-[0.2rem]">{option.description}</div>}
|
||||
</NFlex>
|
||||
<NFlex align="center" size="small" class="w-full py-1">
|
||||
<SvgIcon icon={`resources-${option.value}`} size="1.6rem" />
|
||||
<NText class="flex-1">{option.label}</NText>
|
||||
{option.access && option.access.length > 0 && (
|
||||
<NFlex size="small" class="ml-auto">
|
||||
{option.access.map((type: string) => (
|
||||
<NTag key={type} type={type === 'dns' ? 'success' : 'info'} size="small">
|
||||
{accessTypeMap[type as keyof typeof accessTypeMap] || type}
|
||||
</NTag>
|
||||
))}
|
||||
</NFlex>
|
||||
)}
|
||||
</NFlex>
|
||||
)
|
||||
}
|
||||
@@ -999,13 +1126,11 @@ export const useApiFormController = (props: ApiFormControllerProps): ApiFormCont
|
||||
*/
|
||||
const renderPluginLabel = (option: PluginOption): VNode => {
|
||||
return (
|
||||
<NFlex justify="space-between" class="w-full">
|
||||
<NFlex justify="space-between" class="w-[38rem]">
|
||||
<NFlex align="center" size="small">
|
||||
<SvgIcon icon={`resources-${option.value}`} size="1.6rem" />
|
||||
<div>
|
||||
<NText>{option.label}</NText>
|
||||
{option.description && <div class="text-[1.2rem] text-gray-500 mt-[0.2rem]">{option.description}</div>}
|
||||
</div>
|
||||
<NText>{option.label}</NText>
|
||||
{option.description && <div class="text-[1.2rem] text-gray-500 mt-[0.2rem]">{option.description}</div>}
|
||||
</NFlex>
|
||||
</NFlex>
|
||||
)
|
||||
|
||||
@@ -196,6 +196,16 @@ export function createNodeFormConfig() {
|
||||
return [this.input('站点ID', 'site_id', { placeholder: '请输入ESA站点ID' })]
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建LeCDN相关字段
|
||||
*/
|
||||
leCdnDeploy() {
|
||||
return [
|
||||
this.input('站点ID', 'site_id', { placeholder: '请输入LeCDN站点ID' }),
|
||||
this.input($t('t_17_1745227838561'), 'domain', { placeholder: $t('t_0_1744958839535') }),
|
||||
]
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建跳过选项字段
|
||||
* @param valueRef 值引用
|
||||
|
||||
@@ -141,7 +141,9 @@ export default defineComponent({
|
||||
param.value.provider_id !== val.value &&
|
||||
SITE_SELECTOR_PROVIDERS.includes(param.value.provider)
|
||||
) {
|
||||
param.value.siteName = MULTIPLE_SITE_PROVIDERS.includes(param.value.provider) ? [] : ''
|
||||
param.value.provider === '1panel-site'
|
||||
? (param.value.site_id = MULTIPLE_SITE_PROVIDERS.includes(param.value.provider) ? [] : '')
|
||||
: (param.value.siteName = MULTIPLE_SITE_PROVIDERS.includes(param.value.provider) ? [] : '')
|
||||
}
|
||||
param.value.provider_id = val.value
|
||||
param.value.type = val.type
|
||||
@@ -228,6 +230,9 @@ export default defineComponent({
|
||||
case 'aliyun-esa':
|
||||
config.push(...formConfig.aliyunEsaDeploy())
|
||||
break
|
||||
case 'lecdn':
|
||||
config.push(...formConfig.leCdnDeploy())
|
||||
break
|
||||
case 'plugin':
|
||||
// 插件部署配置
|
||||
config.push(
|
||||
|
||||
@@ -105,7 +105,6 @@ export default defineConfig({
|
||||
// targetDir: 'allinssl-gitlab',
|
||||
// discardChanges: true,
|
||||
// },
|
||||
|
||||
{
|
||||
repo: 'https://github.com/allinssl/allinssl.git',
|
||||
branch: '1.0.7',
|
||||
@@ -220,7 +219,7 @@ export default defineConfig({
|
||||
'/api': {
|
||||
// target: `http://${'192.168.168.25'}:${37628}`,
|
||||
// target: `http://${'192.168.168.121'}:${33488}`,
|
||||
target: `http://${'192.168.69.167'}:${40255}`,
|
||||
target: `http://${'192.168.168.64'}:${20773}`,
|
||||
changeOrigin: true, // 是否改变源
|
||||
rewrite: (path: string) => path.replace(/^\/api/, ''), // 重写路径
|
||||
secure: false, // 如果是https接口,需要配置这个参数
|
||||
|
||||
@@ -4,6 +4,7 @@ import simpleGit, { SimpleGit, SimpleGitOptions } from "simple-git";
|
||||
import fs from "fs-extra";
|
||||
import path from "path";
|
||||
import { createError } from "./utils";
|
||||
import { smartCheckoutBranch } from "./gitHandler";
|
||||
|
||||
const DEFAULT_COMMIT_SEPARATOR = "/** 提交分隔符 **/";
|
||||
const DEFAULT_MAX_SCAN_COUNT = 50;
|
||||
@@ -67,7 +68,14 @@ export async function performAutoCommit(
|
||||
const currentBranch = (await git.branchLocal()).current;
|
||||
if (currentBranch !== project.branch) {
|
||||
logger.info(`切换到分支 ${project.branch}...`);
|
||||
await git.checkout(project.branch);
|
||||
// 使用智能分支检出函数
|
||||
await smartCheckoutBranch(
|
||||
git,
|
||||
project.branch,
|
||||
projectName,
|
||||
logger,
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,83 @@ async function hasUncommittedChanges(git: SimpleGit, logger: Logger): Promise<bo
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 智能分支检出函数
|
||||
* 按以下策略检出分支:
|
||||
* 1. 检查本地分支是否存在,存在则直接检出
|
||||
* 2. 检查远程分支是否存在,存在则创建本地分支并检出
|
||||
* 3. 都不存在则抛出清晰的错误信息
|
||||
*
|
||||
* @param git SimpleGit实例
|
||||
* @param branchName 要检出的分支名称
|
||||
* @param projectName 项目名称(用于日志)
|
||||
* @param logger 日志记录器
|
||||
* @param forceCheckout 是否强制检出
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
export async function smartCheckoutBranch(
|
||||
git: SimpleGit,
|
||||
branchName: string,
|
||||
projectName: string,
|
||||
logger: Logger,
|
||||
forceCheckout: boolean = false
|
||||
): Promise<void> {
|
||||
try {
|
||||
// 1. 检查本地分支是否存在
|
||||
const localBranches = await git.branchLocal();
|
||||
const localBranchExists = localBranches.all.includes(branchName);
|
||||
|
||||
if (localBranchExists) {
|
||||
logger.info(`${projectName}: 本地分支 ${branchName} 存在,直接检出...`);
|
||||
if (forceCheckout) {
|
||||
await git.checkout(["-f", branchName]);
|
||||
logger.info(`${projectName}: 成功强制检出本地分支 ${branchName}`);
|
||||
} else {
|
||||
await git.checkout(branchName);
|
||||
logger.info(`${projectName}: 成功检出本地分支 ${branchName}`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 检查远程分支是否存在
|
||||
logger.info(`${projectName}: 本地分支 ${branchName} 不存在,检查远程分支...`);
|
||||
const remoteBranches = await git.branch(['-r']);
|
||||
const remoteBranchName = `origin/${branchName}`;
|
||||
const remoteBranchExists = remoteBranches.all.some(branch =>
|
||||
branch.includes(remoteBranchName) || branch.includes(branchName)
|
||||
);
|
||||
|
||||
if (remoteBranchExists) {
|
||||
logger.info(`${projectName}: 远程分支 ${remoteBranchName} 存在,创建并检出本地分支...`);
|
||||
if (forceCheckout) {
|
||||
await git.checkout(["-b", branchName, remoteBranchName, "-f"]);
|
||||
logger.info(`${projectName}: 成功强制创建并检出分支 ${branchName} (来源: ${remoteBranchName})`);
|
||||
} else {
|
||||
await git.checkout(["-b", branchName, remoteBranchName]);
|
||||
logger.info(`${projectName}: 成功创建并检出分支 ${branchName} (来源: ${remoteBranchName})`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 分支完全不存在
|
||||
const availableBranches = [...localBranches.all, ...remoteBranches.all];
|
||||
throw new Error(
|
||||
`分支 '${branchName}' 在本地和远程都不存在。` +
|
||||
`可用的分支有: ${availableBranches.join(', ')}`
|
||||
);
|
||||
|
||||
} catch (error: any) {
|
||||
// 如果是我们自己抛出的错误,直接重新抛出
|
||||
if (error.message.includes('在本地和远程都不存在')) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
// 处理其他Git操作错误
|
||||
logger.error(`${projectName}: 分支检出过程中出错: ${error.message}`);
|
||||
throw new Error(`无法检出分支 '${branchName}': ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全地丢弃工作区中的所有更改
|
||||
* @param git SimpleGit实例
|
||||
@@ -188,16 +265,26 @@ export async function updateGitProjects(
|
||||
`${projectName}: 需要从分支 ${currentBranch} 切换到分支 ${config.branch}...`,
|
||||
);
|
||||
try {
|
||||
await git.checkout(config.branch);
|
||||
logger.info(`${projectName}: 成功切换到分支 ${config.branch}`);
|
||||
// 使用智能分支检出函数
|
||||
await smartCheckoutBranch(
|
||||
git,
|
||||
config.branch,
|
||||
projectName,
|
||||
logger,
|
||||
false,
|
||||
);
|
||||
} catch (checkoutError: any) {
|
||||
if (config.discardChanges) {
|
||||
logger.warn(
|
||||
`${projectName}: 切换分支失败: ${checkoutError.message},尝试强制切换...`,
|
||||
);
|
||||
await git.checkout(["-f", config.branch]);
|
||||
logger.info(
|
||||
`${projectName}: 成功强制切换到分支 ${config.branch}`,
|
||||
// 使用强制检出
|
||||
await smartCheckoutBranch(
|
||||
git,
|
||||
config.branch,
|
||||
projectName,
|
||||
logger,
|
||||
true,
|
||||
);
|
||||
} else {
|
||||
throw checkoutError;
|
||||
|
||||
Reference in New Issue
Block a user