diff --git a/agent/app/api/v2/compose_template.go b/agent/app/api/v2/compose_template.go index fb747dfe61ec..c19ff805a09a 100644 --- a/agent/app/api/v2/compose_template.go +++ b/agent/app/api/v2/compose_template.go @@ -28,6 +28,28 @@ func (b *BaseApi) CreateComposeTemplate(c *gin.Context) { helper.Success(c) } +// @Tags Container Compose-template +// @Summary Bacth compose template +// @Accept json +// @Param request body dto.ComposeTemplateBatch true "request" +// @Success 200 +// @Security ApiKeyAuth +// @Security Timestamp +// @Router /containers/template/batch [post] +// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"批量导入编排模版","formatEN":"batch import compose templates"} +func (b *BaseApi) BatchComposeTemplate(c *gin.Context) { + var req dto.ComposeTemplateBatch + if err := helper.CheckBindAndValidate(&req, c); err != nil { + return + } + + if err := composeTemplateService.Batch(req); err != nil { + helper.InternalServer(c, err) + return + } + helper.Success(c) +} + // @Tags Container Compose-template // @Summary Page compose templates // @Accept json diff --git a/agent/app/dto/compose_template.go b/agent/app/dto/compose_template.go index de3832ab0449..f936e13f338d 100644 --- a/agent/app/dto/compose_template.go +++ b/agent/app/dto/compose_template.go @@ -8,6 +8,10 @@ type ComposeTemplateCreate struct { Content string `json:"content"` } +type ComposeTemplateBatch struct { + Templates []ComposeTemplateCreate `json:"templates" validate:"required"` +} + type ComposeTemplateUpdate struct { ID uint `json:"id"` Description string `json:"description"` diff --git a/agent/app/service/compose_template.go b/agent/app/service/compose_template.go index 8aaea8bc741f..a5d6b6b1f7c9 100644 --- a/agent/app/service/compose_template.go +++ b/agent/app/service/compose_template.go @@ -2,6 +2,7 @@ package service import ( "github.com/1Panel-dev/1Panel/agent/app/dto" + "github.com/1Panel-dev/1Panel/agent/app/model" "github.com/1Panel-dev/1Panel/agent/app/repo" "github.com/1Panel-dev/1Panel/agent/buserr" "github.com/jinzhu/copier" @@ -12,8 +13,9 @@ type ComposeTemplateService struct{} type IComposeTemplateService interface { List() ([]dto.ComposeTemplateInfo, error) SearchWithPage(search dto.SearchWithPage) (int64, interface{}, error) - Create(composeDto dto.ComposeTemplateCreate) error + Create(req dto.ComposeTemplateCreate) error Update(id uint, upMap map[string]interface{}) error + Batch(req dto.ComposeTemplateBatch) error Delete(ids []uint) error } @@ -64,6 +66,22 @@ func (u *ComposeTemplateService) Create(composeDto dto.ComposeTemplateCreate) er return nil } +func (u *ComposeTemplateService) Batch(req dto.ComposeTemplateBatch) error { + for _, item := range req.Templates { + template, _ := composeRepo.Get(repo.WithByName(item.Name)) + if template.ID == 0 { + if err := composeRepo.Create(&model.ComposeTemplate{Name: item.Name, Content: item.Content, Description: item.Description}); err != nil { + return err + } + } else { + if err := composeRepo.Update(template.ID, map[string]interface{}{"content": item.Content, "description": item.Description}); err != nil { + return err + } + } + } + return nil +} + func (u *ComposeTemplateService) Delete(ids []uint) error { if len(ids) == 1 { compose, _ := composeRepo.Get(repo.WithByID(ids[0])) diff --git a/agent/router/ro_container.go b/agent/router/ro_container.go index 724fec76df13..4a89bafc58f9 100644 --- a/agent/router/ro_container.go +++ b/agent/router/ro_container.go @@ -52,6 +52,7 @@ func (s *ContainerRouter) InitRouter(Router *gin.RouterGroup) { baRouter.GET("/template", baseApi.ListComposeTemplate) baRouter.POST("/template/search", baseApi.SearchComposeTemplate) baRouter.POST("/template/update", baseApi.UpdateComposeTemplate) + baRouter.POST("/template/batch", baseApi.BatchComposeTemplate) baRouter.POST("/template", baseApi.CreateComposeTemplate) baRouter.POST("/template/del", baseApi.DeleteComposeTemplate) diff --git a/frontend/src/api/interface/container.ts b/frontend/src/api/interface/container.ts index fd82dc0ae81a..64fa49ce2ac0 100644 --- a/frontend/src/api/interface/container.ts +++ b/frontend/src/api/interface/container.ts @@ -318,25 +318,19 @@ export namespace Container { export interface TemplateCreate { name: string; - from: string; description: string; - path: string; content: string; } export interface TemplateUpdate { id: number; - from: string; description: string; - path: string; content: string; } export interface TemplateInfo { id: number; createdAt: Date; name: string; - from: string; description: string; - path: string; content: string; } diff --git a/frontend/src/api/modules/container.ts b/frontend/src/api/modules/container.ts index 1ebf9f67a344..f5ba0b7fb60c 100644 --- a/frontend/src/api/modules/container.ts +++ b/frontend/src/api/modules/container.ts @@ -162,6 +162,9 @@ export const deleteComposeTemplate = (params: { ids: number[] }) => { export const createComposeTemplate = (params: Container.TemplateCreate) => { return http.post(`/containers/template`, params); }; +export const batchComposeTemplate = (templates: Array) => { + return http.post(`/containers/template/batch`, { templates: templates }); +}; export const updateComposeTemplate = (params: Container.TemplateUpdate) => { return http.post(`/containers/template/update`, params); }; diff --git a/frontend/src/components/status/index.vue b/frontend/src/components/status/index.vue index 7118ebf008cb..a9816171c696 100644 --- a/frontend/src/components/status/index.vue +++ b/frontend/src/components/status/index.vue @@ -63,6 +63,7 @@ const getType = (status: string) => { case 'healthy': case 'unused': case 'executing': + case 'new': return 'success'; case 'stopped': case 'exceptional': @@ -76,7 +77,10 @@ const getType = (status: string) => { case 'dead': case 'removing': case 'deleted': + case 'conflict': return 'warning'; + case 'duplicate': + return 'info'; default: return 'primary'; } diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 7e2c90a768f8..959c63bad2da 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -185,6 +185,10 @@ const message = { installSuccess: 'Install successful', uninstallSuccess: 'Uninstall successful', offlineTips: 'Offline version does not support this operation', + errImportFormat: 'Import data or format is abnormal, please check and try again!', + importHelper: + 'When importing conflicting or duplicate data, the imported content will be used as the standard to update the original database data.', + errImport: 'File content is abnormal:', }, login: { username: 'Username', @@ -335,6 +339,9 @@ const message = { systemrestart: 'Interrupted', starterr: 'Startup failed', uperr: 'Startup failed', + new: 'New', + conflict: 'Conflict', + duplicate: 'Duplicate', }, units: { second: ' second | second | seconds', @@ -1037,8 +1044,6 @@ const message = { cronjob: { create: 'Create cron job', edit: 'Edit cron job', - errImport: 'File content exception:', - errImportFormat: 'The scheduled task data or format is abnormal. Please check and try again!', importHelper: 'Duplicate scheduled tasks will be automatically skipped during import. Tasks will be set to [Disabled] status by default, and set to [Pending Edit] status when data association is abnormal.', changeStatus: 'Change status', @@ -2886,15 +2891,7 @@ const message = { forwardHelper2: 'Leave the destination IP blank to forward to the local port.', forwardHelper3: 'Only support IPv4 port forwarding.', forwardInboundInterface: 'Forward Inbound Network Interface', - importHelper: - 'When importing conflicting or duplicate firewall rules, the imported content will be used as the standard to update the original firewall rules.', exportHelper: 'About to export {0} firewall rules. Continue?', - new: 'New', - conflict: 'Conflict', - duplicate: 'Duplicate', - errImportFormat: 'Import file format error, please check the JSON file format', - errImport: 'Import failed: ', - selectImportRules: 'Please select rules to import', importSuccess: 'Successfully imported {0} rules', importPartialSuccess: 'Import completed: {0} succeeded, {1} failed', }, diff --git a/frontend/src/lang/modules/es-es.ts b/frontend/src/lang/modules/es-es.ts index f5ea2eb9f2fb..0cc4fc3b57d3 100644 --- a/frontend/src/lang/modules/es-es.ts +++ b/frontend/src/lang/modules/es-es.ts @@ -184,6 +184,10 @@ const message = { installSuccess: 'Instalación completada correctamente', uninstallSuccess: 'Desinstalación completada correctamente', offlineTips: 'La versión offline no admite esta operación', + errImportFormat: 'Los datos de importación o el formato son anormales, ¡compruebe e inténtelo de nuevo!', + importHelper: + 'Al importar datos conflictivos o duplicados, el contenido importado se utilizará como estándar para actualizar los datos originales de la base de datos.', + errImport: 'El contenido del archivo es anormal:', }, login: { username: 'Usuario', @@ -342,6 +346,9 @@ const message = { systemrestart: 'Interrumpido', starterr: 'Error al iniciar', uperr: 'Error al iniciar', + new: 'Nuevo', + conflict: 'Conflicto', + duplicate: 'Duplicado', }, units: { second: ' segundo | segundo | segundos', @@ -1036,9 +1043,6 @@ const message = { cronjob: { create: 'Crear tarea programada', edit: 'Editar tarea programada', - errImport: 'Excepción en el contenido del archivo:', - errImportFormat: - 'Los datos o el formato de la tarea programada son anormales. ¡Por favor verifique e inténtelo de nuevo!', importHelper: 'Las tareas programadas duplicadas se omitirán automáticamente durante la importación. Las tareas se establecerán en estado [Deshabilitado] por defecto, y en estado [Pendiente de edición] cuando la asociación de datos sea anormal.', changeStatus: 'Cambiar estado', @@ -2859,15 +2863,7 @@ const message = { forwardHelper2: 'Deja en blanco la IP de destino para reenviar al puerto local.', forwardHelper3: 'Solo se admite redirección de puertos IPv4.', forwardInboundInterface: 'Interfaz de Red de Entrada para Reenvío', - importHelper: - 'Al importar reglas de firewall conflictivas o duplicadas, el contenido importado se utilizará como estándar para actualizar las reglas de firewall originales.', exportHelper: 'A punto de exportar {0} reglas de firewall. ¿Continuar?', - new: 'Nueva', - conflict: 'Conflicto', - duplicate: 'Duplicada', - errImportFormat: 'Error en el formato del archivo importado, comprueba el formato del archivo JSON', - errImport: 'Error al importar: ', - selectImportRules: 'Selecciona las reglas que deseas importar', importSuccess: 'Se importaron correctamente {0} reglas', importPartialSuccess: 'Importación completada: {0} correctas, {1} fallidas', }, diff --git a/frontend/src/lang/modules/ja.ts b/frontend/src/lang/modules/ja.ts index a2cf382a97d3..49c989e3229a 100644 --- a/frontend/src/lang/modules/ja.ts +++ b/frontend/src/lang/modules/ja.ts @@ -175,6 +175,10 @@ const message = { resetSuccess: 'リセット成功', creatingInfo: '作成、この操作は必要ありません', offlineTips: 'オフライン版はこの操作をサポートしていません', + errImportFormat: 'インポートデータまたはフォーマットが異常です。確認して再試行してください!', + importHelper: + '競合または重複するデータをインポートする場合、インポートされた内容を基準として元のデータベースデータを更新します。', + errImport: 'ファイル内容が異常です:', }, login: { username: 'ユーザー名', @@ -324,6 +328,9 @@ const message = { systemrestart: '中断', starterr: '起動に失敗しました', uperr: '起動に失敗しました', + new: '新規', + conflict: '競合', + duplicate: '重複', }, units: { second: '2番目|2番目|秒', @@ -1008,8 +1015,6 @@ const message = { cronjob: { create: 'Cronジョブを作成します', edit: 'Cronジョブを編集します', - errImport: 'ファイル内容異常:', - errImportFormat: 'インポートしたスケジュールタスクのデータまたは形式が異常です。確認して再試行してください!', importHelper: 'インポート時に同名のスケジュールタスクは自動的にスキップされます。タスクはデフォルトで【無効】状態に設定され、データ関連付け異常時には【編集待ち】状態に設定されます。', changeStatus: 'ステータスを変更します', @@ -2801,15 +2806,7 @@ const message = { forwardHelper2: '宛先IPを空白のままにして、ローカルポートに転送します。', forwardHelper3: 'IPv4ポート転送のみをサポートします。', forwardInboundInterface: '転送入站ネットワークインターフェース', - importHelper: - '競合または重複するファイアウォールルールをインポートする場合、インポートされた内容を基準として元のファイアウォールルールを更新します。', exportHelper: '{0} 件のファイアウォールルールをエクスポートします。続行しますか?', - new: '新規', - conflict: '競合', - duplicate: '重複', - errImportFormat: 'インポートファイルの形式エラーです。JSON ファイルの形式を確認してください', - errImport: 'インポートに失敗しました: ', - selectImportRules: 'インポートするルールを選択してください', importSuccess: '{0} 件のルールを正常にインポートしました', importPartialSuccess: 'インポート完了: {0} 件成功、{1} 件失敗', }, diff --git a/frontend/src/lang/modules/ko.ts b/frontend/src/lang/modules/ko.ts index 4c69f6766c4f..67a3badf80c3 100644 --- a/frontend/src/lang/modules/ko.ts +++ b/frontend/src/lang/modules/ko.ts @@ -174,6 +174,10 @@ const message = { resetSuccess: '초기화 완료', creatingInfo: '생성 중입니다. 이 작업이 필요하지 않습니다', offlineTips: '오프라인 버전은 이 작업을 지원하지 않습니다', + errImportFormat: '가져오기 데이터 또는 형식이 비정상입니다. 확인 후 다시 시도하세요!', + importHelper: + '충돌하거나 중복되는 데이터를 가져올 때 가져온 내용을 기준으로 원래 데이터베이스 데이터를 업데이트합니다.', + errImport: '파일 내용이 비정상입니다:', }, login: { username: '사용자 이름', @@ -326,6 +330,9 @@ const message = { systemrestart: '중단됨', starterr: '시작 실패', uperr: '실행 실패', + new: '신규', + conflict: '충돌', + duplicate: '중복', }, units: { second: '초 | 초 | 초', @@ -998,8 +1005,6 @@ const message = { cronjob: { create: '크론 작업 생성', edit: '크론 작업 수정', - errImport: '파일 내용 이상:', - errImportFormat: '가져온 예약 작업 데이터 또는 형식이 이상합니다. 확인 후 다시 시도하십시오!', importHelper: '가져오기 시 동일한 이름의 예약 작업은 자동으로 건너뜁니다. 작업은 기본적으로 【비활성화】 상태로 설정되며, 데이터 연동 이상 시 【편집 대기】 상태로 설정됩니다.', changeStatus: '상태 변경', @@ -2752,15 +2757,7 @@ const message = { forwardHelper2: '대상 IP 를 비워두면 로컬 포트로 전달됩니다.', forwardHelper3: 'IPv4 포트 전달만 지원됩니다.', forwardInboundInterface: '포워딩 인바운드 네트워크 인터페이스', - importHelper: - '충돌하거나 중복되는 방화벽 규칙을 가져올 때 가져온 내용을 기준으로 원래 방화벽 규칙을 업데이트합니다.', exportHelper: '{0}개의 방화벽 규칙을 내보내려고 합니다. 계속하시겠습니까?', - new: '신규', - conflict: '충돌', - duplicate: '중복', - errImportFormat: '가져오기 파일 형식 오류입니다. JSON 파일 형식을 확인하세요', - errImport: '가져오기에 실패했습니다: ', - selectImportRules: '가져올 규칙을 선택하세요', importSuccess: '{0}개의 규칙을 성공적으로 가져왔습니다', importPartialSuccess: '가져오기 완료: 성공 {0}건, 실패 {1}건', }, diff --git a/frontend/src/lang/modules/ms.ts b/frontend/src/lang/modules/ms.ts index e858b152d1a3..ae4697371a42 100644 --- a/frontend/src/lang/modules/ms.ts +++ b/frontend/src/lang/modules/ms.ts @@ -177,6 +177,10 @@ const message = { resetSuccess: 'Berjaya ditetapkan semula', creatingInfo: 'Sedang mencipta, operasi ini tidak diperlukan', offlineTips: 'Versi luar talian tidak menyokong operasi ini', + errImportFormat: 'Data import atau format adalah tidak normal, sila periksa dan cuba lagi!', + importHelper: + 'Apabila mengimport data yang bercanggah atau pendua, kandungan yang diimport akan digunakan sebagai piawai untuk mengemas kini data pangkalan data asal.', + errImport: 'Kandungan fail adalah tidak normal:', }, login: { username: 'Nama Pengguna', @@ -332,6 +336,9 @@ const message = { systemrestart: 'Dihentikan', starterr: 'Permulaan gagal', uperr: 'Permulaan gagal', + new: 'Baru', + conflict: 'Konflik', + duplicate: 'Pendua', }, units: { second: 'saat | saat | saat', @@ -1032,8 +1039,6 @@ const message = { cronjob: { create: 'Cipta tugas cron', edit: 'Edit tugas cron', - errImport: 'Kandungan fail tidak normal:', - errImportFormat: 'Data atau format tugas terjadual yang diimport tidak normal. Sila semak dan cuba lagi!', importHelper: 'Tugas terjadual dengan nama sama akan dilangkau secara automatik semasa import. Tugas akan ditetapkan ke status 【Lumpuh】 secara lalai, dan ditetapkan ke status 【Menunggu Edit】 apabila perkaitan data tidak normal.', changeStatus: 'Tukar status', @@ -2867,15 +2872,7 @@ const message = { forwardHelper2: 'Biarkan IP sasaran kosong untuk memajukan ke port tempatan.', forwardHelper3: 'Hanya menyokong pemajuan port IPv4.', forwardInboundInterface: 'Antara Muka Rangkaian Masukan Penerusan', - importHelper: - 'Apabila mengimport peraturan firewall yang bercanggah atau pendua, kandungan yang diimport akan digunakan sebagai piawai untuk mengemas kini peraturan firewall asal.', exportHelper: 'Akan mengeksport {0} peraturan firewall. Teruskan?', - new: 'Baharu', - conflict: 'Konflik', - duplicate: 'Duplikat', - errImportFormat: 'Ralat format fail import, sila semak format fail JSON', - errImport: 'Import gagal: ', - selectImportRules: 'Sila pilih peraturan untuk diimport', importSuccess: '{0} peraturan berjaya diimport', importPartialSuccess: 'Import selesai: {0} berjaya, {1} gagal', }, diff --git a/frontend/src/lang/modules/pt-br.ts b/frontend/src/lang/modules/pt-br.ts index 7ee2f1150c9e..d5d217e315aa 100644 --- a/frontend/src/lang/modules/pt-br.ts +++ b/frontend/src/lang/modules/pt-br.ts @@ -175,6 +175,10 @@ const message = { resetSuccess: 'Redefinido com sucesso', creatingInfo: 'Criando, não é necessário realizar esta operação', offlineTips: 'A versão offline não suporta esta operação', + errImportFormat: 'Dados de importação ou formato estão anormais, verifique e tente novamente!', + importHelper: + 'Ao importar dados conflitantes ou duplicados, o conteúdo importado será usado como padrão para atualizar os dados originais do banco de dados.', + errImport: 'O conteúdo do arquivo está anormal:', }, login: { username: 'Usuário', @@ -330,6 +334,9 @@ const message = { systemrestart: 'Interrompido', starterr: 'Falha na inicialização', uperr: 'Falha na inicialização', + new: 'Novo', + conflict: 'Conflito', + duplicate: 'Duplicado', }, units: { second: 'segundo | segundos | segundos', @@ -1029,9 +1036,6 @@ const message = { cronjob: { create: 'Criar tarefa cron', edit: 'Editar tarefa cron', - errImport: 'Conteúdo do arquivo anormal:', - errImportFormat: - 'Os dados ou formato da tarefa agendada estão anormais. Por favor, verifique e tente novamente!', importHelper: 'Tarefas agendadas duplicadas serão automaticamente ignoradas durante a importação. As tarefas serão definidas como status 【Desativado】 por padrão, e como status 【Aguardando Edição】 quando a associação de dados for anormal.', changeStatus: 'Alterar status', @@ -2872,15 +2876,7 @@ const message = { forwardHelper2: 'Deixe o IP de destino em branco para redirecionar para a porta local.', forwardHelper3: 'Somente suporta redirecionamento de porta IPv4.', forwardInboundInterface: 'Interface de Rede de Entrada para Encaminhamento', - importHelper: - 'Ao importar regras de firewall conflitantes ou duplicadas, o conteúdo importado será usado como padrão para atualizar as regras de firewall originais.', exportHelper: 'Prestes a exportar {0} regras de firewall. Continuar?', - new: 'Nova', - conflict: 'Conflito', - duplicate: 'Duplicada', - errImportFormat: 'Erro no formato do arquivo de importação, verifique o formato do arquivo JSON', - errImport: 'Falha na importação: ', - selectImportRules: 'Selecione as regras que deseja importar', importSuccess: '{0} regras importadas com sucesso', importPartialSuccess: 'Importação concluída: {0} sucesso, {1} falha', }, diff --git a/frontend/src/lang/modules/ru.ts b/frontend/src/lang/modules/ru.ts index 1d1831629584..a9e8732e2e57 100644 --- a/frontend/src/lang/modules/ru.ts +++ b/frontend/src/lang/modules/ru.ts @@ -175,6 +175,10 @@ const message = { resetSuccess: 'Сброс успешен', creatingInfo: 'Создание, эта операция не нужна', offlineTips: 'Офлайн версия не поддерживает эту операцию', + errImportFormat: 'Данные импорта или формат ненормальны, проверьте и повторите попытку!', + importHelper: + 'При импорте конфликтующих или дублирующихся данных импортированное содержимое будет использоваться в качестве стандарта для обновления исходных данных базы данных.', + errImport: 'Содержимое файла ненормально:', }, login: { username: 'Имя пользователя', @@ -327,6 +331,9 @@ const message = { systemrestart: 'Прервано', starterr: 'Ошибка запуска', uperr: 'Ошибка запуска', + new: 'Новый', + conflict: 'Конфликт', + duplicate: 'Дубликат', }, units: { second: ' секунда | секунда | секунд', @@ -1027,9 +1034,6 @@ const message = { cronjob: { create: 'Создать задачу cron', edit: 'Редактировать задачу cron', - errImport: 'Аномальное содержимое файла:', - errImportFormat: - 'Данные или формат запланированной задачи ненормальны. Пожалуйста, проверьте и повторите попытку!', importHelper: 'Повторяющиеся запланированные задачи будут автоматически пропущены при импорте. По умолчанию задачи устанавливаются в статус 【Отключено】, а при аномальной ассоциации данных - в статус 【Ожидает редактирования】.', changeStatus: 'Изменить статус', @@ -2868,15 +2872,7 @@ const message = { forwardHelper2: 'Оставьте целевой IP пустым для перенаправления на локальный порт.', forwardHelper3: 'Поддерживается только переадресация портов IPv4.', forwardInboundInterface: '转发入站Сетевой интерфейс для пересылки входящего трафика网卡', - importHelper: - 'При импорте конфликтующих или дублирующихся правил брандмауэра импортированное содержимое будет использоваться в качестве стандарта для обновления исходных правил брандмауэра.', exportHelper: 'Собираюсь экспортировать {0} правил брандмауэра. Продолжить?', - new: 'Новое', - conflict: 'Конфликт', - duplicate: 'Дубликат', - errImportFormat: 'Ошибка формата импортируемого файла, проверьте формат JSON', - errImport: 'Не удалось импортировать: ', - selectImportRules: 'Выберите правила для импорта', importSuccess: 'Успешно импортировано {0} правил', importPartialSuccess: 'Импорт завершён: {0} успешно, {1} с ошибкой', }, diff --git a/frontend/src/lang/modules/tr.ts b/frontend/src/lang/modules/tr.ts index d363ce7bf431..675855f15740 100644 --- a/frontend/src/lang/modules/tr.ts +++ b/frontend/src/lang/modules/tr.ts @@ -186,6 +186,10 @@ const message = { installSuccess: 'Yükleme başarılı', uninstallSuccess: 'Kaldırma başarılı', offlineTips: 'A versão offline não suporta esta operação', + errImportFormat: 'İçe aktarma verisi veya biçimi anormal, lütfen kontrol edip tekrar deneyin!', + importHelper: + 'Çakışan veya yinelenen verileri içe aktarırken, içe aktarılan içerik orijinal veritabanı verilerini güncellemek için standart olarak kullanılacaktır.', + errImport: 'Dosya içeriği anormal:', }, login: { username: 'Kullanıcı adı', @@ -339,6 +343,9 @@ const message = { systemrestart: 'Kesintiye Uğradı', starterr: 'Başlatma başarısız', uperr: 'Başlatma başarısız', + new: 'Yeni', + conflict: 'Çakışma', + duplicate: 'Yinelenen', }, units: { second: ' saniye | saniye | saniye', @@ -1049,8 +1056,6 @@ const message = { cronjob: { create: 'Cron görevi oluştur', edit: 'Cron görevini düzenle', - errImport: 'Dosya içeriği anormal:', - errImportFormat: 'Zamanlanmış görev verileri veya biçimi anormal. Lütfen kontrol edip tekrar deneyin!', importHelper: 'İçe aktarım sırasında aynı isimli zamanlanmış görevler otomatik olarak atlanacaktır. Görevler varsayılan olarak 【Devre Dışı】 durumuna ayarlanır ve veri ilişkilendirme anormalse 【Düzenleme Bekliyor】 durumuna ayarlanır.', changeStatus: 'Durumu değiştir', @@ -2926,15 +2931,7 @@ const message = { forwardHelper2: 'Yerel porta yönlendirmek için hedef IP’yi boş bırakın.', forwardHelper3: 'Yalnızca IPv4 port yönlendirmesini destekler.', forwardInboundInterface: 'İletme Gelen Ağ Arayüzü', - importHelper: - 'Çakışan veya yinelenen güvenlik duvarı kurallarını içe aktarırken, içe aktarılan içerik orijinal güvenlik duvarı kurallarını güncellemek için standart olarak kullanılacaktır.', exportHelper: '{0} güvenlik duvarı kuralını dışa aktarmak üzere. Devam etmek istiyor musunuz?', - new: 'Yeni', - conflict: 'Çakışma', - duplicate: 'Yinelenen', - errImportFormat: 'İçe aktarma dosya biçimi hatalı, lütfen JSON dosya biçimini kontrol edin', - errImport: 'İçe aktarma başarısız: ', - selectImportRules: 'Lütfen içe aktarılacak kuralları seçin', importSuccess: '{0} kural başarıyla içe aktarıldı', importPartialSuccess: 'İçe aktarma tamamlandı: {0} başarılı, {1} başarısız', }, diff --git a/frontend/src/lang/modules/zh-Hant.ts b/frontend/src/lang/modules/zh-Hant.ts index a40898685835..0633e6d01f56 100644 --- a/frontend/src/lang/modules/zh-Hant.ts +++ b/frontend/src/lang/modules/zh-Hant.ts @@ -183,6 +183,9 @@ const message = { installSuccess: '安裝成功', uninstallSuccess: '移除成功', offlineTips: '離線版本不支援此操作', + errImportFormat: '導入數據或格式異常,請檢查後重試!', + importHelper: '導入衝突或重複數據時,將以導入內容為標準,更新原數據庫數據。', + errImport: '文件內容異常:', }, login: { username: '使用者名稱', @@ -324,6 +327,9 @@ const message = { systemrestart: '中斷', starterr: '啟動失敗', uperr: '啟動失敗', + new: '新', + conflict: '衝突', + duplicate: '重複', }, units: { second: '秒', @@ -985,8 +991,6 @@ const message = { cronjob: { create: '建立計劃任務', edit: '編輯計劃任務', - errImport: '文件內容異常:', - errImportFormat: '匯入的計劃任務資料或格式異常,請檢查後重試!', importHelper: '匯入時將自動跳過重名計劃任務。任務預設設定為【停用】狀態,資料關聯異常時,設定為【待編輯】狀態。', changeStatus: '狀態修改', @@ -2681,14 +2685,7 @@ const message = { forwardHelper2: '如果目標 IP 不填寫,預設為本機埠轉發', forwardHelper3: '目前僅支援 IPv4 的埠轉發', forwardInboundInterface: '轉發入站網路介面', - importHelper: '導入衝突或重複防火牆規則時,將以導入內容為標準,更新原防火牆規則。', exportHelper: '即將導出 {0} 條防火牆規則,是否繼續?', - new: '新增', - conflict: '衝突', - duplicate: '重複', - errImportFormat: '匯入檔案格式錯誤,請檢查 JSON 檔案格式', - errImport: '匯入失敗:', - selectImportRules: '請選擇要匯入的規則', importSuccess: '成功匯入 {0} 條規則', importPartialSuccess: '匯入完成:成功 {0} 條,失敗 {1} 條', }, diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index f2d2dd04fd52..f4f4a077d910 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -183,6 +183,9 @@ const message = { installSuccess: '安装成功', uninstallSuccess: '卸载成功', offlineTips: '离线版不支持此操作', + errImportFormat: '导入数据或格式异常,请检查后重试!', + importHelper: '导入冲突或重复数据时,将以导入内容为标准,更新原数据库数据。', + errImport: '文件内容异常:', }, login: { username: '用户名', @@ -324,6 +327,9 @@ const message = { systemrestart: '中断', starterr: '启动失败', uperr: '启动失败', + new: '新', + conflict: '冲突', + duplicate: '重复', }, units: { second: '秒', @@ -922,6 +928,7 @@ const message = { template: '模版', composeTemplate: '编排模版', createComposeTemplate: '创建编排模版', + exportHelper: '即将导出 {0} 条编排模版,是否继续?', content: '内容', contentEmpty: '编排内容不能为空,请输入后重试!', containerNumber: '容器数量', @@ -985,8 +992,6 @@ const message = { cronjob: { create: '创建计划任务', edit: '编辑计划任务', - errImport: '文件内容异常:', - errImportFormat: '导入的计划任务数据或格式异常,请检查后重试!', importHelper: '导入时将自动跳过重名计划任务。任务默认设置为【停用】状态,数据关联异常时,设置为【待编辑】状态。', changeStatus: '状态修改', @@ -2674,14 +2679,7 @@ const message = { forwardHelper2: '如果目标IP不填写,则默认为本机端口转发', forwardHelper3: '当前仅支持 IPv4 的端口转发', forwardInboundInterface: '转发入站网卡', - importHelper: '导入冲突或重复防火墙规则时,将以导入内容为标准,更新原防火墙规则。', exportHelper: '即将导出 {0} 条防火墙规则,是否继续?', - new: '新规则', - conflict: '冲突', - duplicate: '重复', - errImportFormat: '导入文件格式错误,请检查 JSON 文件格式', - errImport: '导入失败:', - selectImportRules: '请选择要导入的规则', importSuccess: '成功导入 {0} 条规则', importPartialSuccess: '导入完成:成功 {0} 条,失败 {1} 条', }, diff --git a/frontend/src/views/container/template/import/index.vue b/frontend/src/views/container/template/import/index.vue new file mode 100644 index 000000000000..06d0e3049190 --- /dev/null +++ b/frontend/src/views/container/template/import/index.vue @@ -0,0 +1,208 @@ + + + diff --git a/frontend/src/views/container/template/index.vue b/frontend/src/views/container/template/index.vue index 64ee3dedc696..87e16da6d54c 100644 --- a/frontend/src/views/container/template/index.vue +++ b/frontend/src/views/container/template/index.vue @@ -15,6 +15,15 @@ {{ $t('commons.button.delete') }} + + + + {{ $t('commons.button.import') }} + + + {{ $t('commons.button.export') }} + +