Исправления в ветке main

This commit is contained in:
2025-10-28 16:58:54 +06:00
parent 5c672ecc39
commit 89d15bfdc9
7 changed files with 95 additions and 28 deletions

View File

@@ -1 +1 @@
v2.0.10 v2.0.11

View File

@@ -1 +1 @@
v2.0.10 v2.0.11

View File

@@ -5,7 +5,7 @@ metadata:
namespace: lcg namespace: lcg
data: data:
# Основные настройки # Основные настройки
LCG_VERSION: "v2.0.10" LCG_VERSION: "v2.0.11"
LCG_BASE_PATH: "/lcg" LCG_BASE_PATH: "/lcg"
LCG_SERVER_HOST: "0.0.0.0" LCG_SERVER_HOST: "0.0.0.0"
LCG_SERVER_PORT: "8080" LCG_SERVER_PORT: "8080"

View File

@@ -5,7 +5,7 @@ metadata:
namespace: lcg namespace: lcg
labels: labels:
app: lcg app: lcg
version: v2.0.10 version: v2.0.11
spec: spec:
replicas: 1 replicas: 1
selector: selector:
@@ -18,7 +18,7 @@ spec:
spec: spec:
containers: containers:
- name: lcg - name: lcg
image: kuznetcovay/lcg:v2.0.10 image: kuznetcovay/lcg:v2.0.11
imagePullPolicy: Always imagePullPolicy: Always
ports: ports:
- containerPort: 8080 - containerPort: 8080

View File

@@ -15,11 +15,11 @@ resources:
# Common labels # Common labels
# commonLabels: # commonLabels:
# app: lcg # app: lcg
# version: v2.0.10 # version: v2.0.11
# managed-by: kustomize # managed-by: kustomize
# Images # Images
# images: # images:
# - name: lcg # - name: lcg
# newName: kuznetcovay/lcg # newName: kuznetcovay/lcg
# newTag: v2.0.10 # newTag: v2.0.11

View File

@@ -39,11 +39,12 @@ func generateAbbreviation(appName string) string {
// FileInfo содержит информацию о файле // FileInfo содержит информацию о файле
type FileInfo struct { type FileInfo struct {
Name string Name string
Size string DisplayName string
ModTime string Size string
Preview template.HTML ModTime string
Content string // Полное содержимое для поиска Preview template.HTML
Content string // Полное содержимое для поиска
} }
// handleResultsPage обрабатывает главную страницу со списком файлов // handleResultsPage обрабатывает главную страницу со списком файлов
@@ -133,11 +134,12 @@ func getResultFiles() ([]FileInfo, error) {
} }
files = append(files, FileInfo{ files = append(files, FileInfo{
Name: entry.Name(), Name: entry.Name(),
Size: formatFileSize(info.Size()), DisplayName: formatFileDisplayName(entry.Name()),
ModTime: info.ModTime().Format("02.01.2006 15:04"), Size: formatFileSize(info.Size()),
Preview: template.HTML(preview), ModTime: info.ModTime().Format("02.01.2006 15:04"),
Content: fullContent, Preview: template.HTML(preview),
Content: fullContent,
}) })
} }
@@ -167,6 +169,65 @@ func formatFileSize(size int64) string {
return fmt.Sprintf("%.1f %cB", float64(size)/float64(div), "KMGTPE"[exp]) return fmt.Sprintf("%.1f %cB", float64(size)/float64(div), "KMGTPE"[exp])
} }
// formatFileDisplayName преобразует имя файла вида
// gpt_request_GigaChat-2-Max_2025-10-22_13-50-13.md
// в "Gpt Request GigaChat 2 Max — 2025-10-22 13:50:13"
func formatFileDisplayName(filename string) string {
name := strings.TrimSuffix(filename, ".md")
// Разделим на части по '_'
parts := strings.Split(name, "_")
if len(parts) == 0 {
return filename
}
// Первая часть может быть префиксом gpt/request — заменим '_' на пробел и приведем регистр
var words []string
for _, p := range parts {
if p == "" {
continue
}
// Заменяем '-' на пробел в словах модели/текста
p = strings.ReplaceAll(p, "-", " ")
// Разбиваем по пробелам и капитализуем каждое слово
for _, w := range strings.Fields(p) {
if w == "" {
continue
}
r := []rune(w)
r[0] = unicode.ToUpper(r[0])
words = append(words, string(r))
}
}
// Попробуем распознать хвост как дату и время
// Ищем шаблон YYYY-MM-DD_HH-MM-SS в исходном имени
var pretty string
// ожидаем последние две части — дата и время
if len(parts) >= 3 {
datePart := parts[len(parts)-2]
timePart := parts[len(parts)-1]
// заменить '-' в времени на ':'
timePretty := strings.ReplaceAll(timePart, "-", ":")
if len(datePart) == 10 && len(timePart) == 8 { // примитивная проверка
// Собираем текст до датных частей
text := strings.Join(words[:len(words)-2], " ")
pretty = strings.TrimSpace(text)
if pretty != "" {
pretty += " — " + datePart + " " + timePretty
} else {
pretty = datePart + " " + timePretty
}
return pretty
}
}
if len(words) > 0 {
pretty = strings.Join(words, " ")
return pretty
}
return filename
}
// handleFileView обрабатывает просмотр конкретного файла // handleFileView обрабатывает просмотр конкретного файла
func handleFileView(w http.ResponseWriter, r *http.Request) { func handleFileView(w http.ResponseWriter, r *http.Request) {
// Учитываем BasePath при извлечении имени файла // Учитываем BasePath при извлечении имени файла

View File

@@ -73,8 +73,10 @@ const ResultsPageTemplate = `
} }
.files-grid { .files-grid {
display: grid; display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px; gap: 20px;
align-items: stretch;
grid-auto-rows: auto;
} }
.file-card { .file-card {
background: white; background: white;
@@ -100,23 +102,26 @@ const ResultsPageTemplate = `
gap: 8px; gap: 8px;
} }
.delete-btn { .delete-btn {
background: #e74c3c; background: transparent;
color: white; color: #ef9a9a; /* бледно-красный */
border: none; border: none;
padding: 6px 12px; padding: 4px 8px;
border-radius: 4px; border-radius: 4px;
cursor: pointer; cursor: pointer;
font-size: 0.8em; font-size: 18px;
transition: background 0.3s ease; line-height: 1;
transition: color 0.2s ease, transform 0.2s ease;
} }
.delete-btn:hover { .delete-btn:hover {
background: #c0392b; color:rgb(171, 27, 24); /* чуть ярче при ховере */
transform: translateY(-1px);
} }
.file-name { .file-name {
font-weight: 600; font-weight: 600;
color: #333; color: #333;
margin-bottom: 8px; margin-bottom: 8px;
font-size: 1.1em; font-size: 1.1em;
padding-right: 10px;
} }
.file-info { .file-info {
color: #666; color: #666;
@@ -165,7 +170,7 @@ const ResultsPageTemplate = `
body { padding: 10px; } body { padding: 10px; }
.container { margin: 0; border-radius: 8px; box-shadow: 0 10px 20px rgba(0,0,0,0.1); } .container { margin: 0; border-radius: 8px; box-shadow: 0 10px 20px rgba(0,0,0,0.1); }
.header { padding: 20px; } .header { padding: 20px; }
.header h1 { font-size: 2em; } .header h1 { font-size: 1.9em; }
.content { padding: 20px; } .content { padding: 20px; }
.files-grid { grid-template-columns: 1fr; } .files-grid { grid-template-columns: 1fr; }
.stats { grid-template-columns: 1fr 1fr; } .stats { grid-template-columns: 1fr 1fr; }
@@ -174,7 +179,8 @@ const ResultsPageTemplate = `
.search-container input { font-size: 16px; width: 96% !important; } .search-container input { font-size: 16px; width: 96% !important; }
} }
@media (max-width: 480px) { @media (max-width: 480px) {
.header h1 { font-size: 1.8em; } .header h1 { font-size: 1.6em; }
.content { padding: 16px; }
.stats { grid-template-columns: 1fr; } .stats { grid-template-columns: 1fr; }
} }
</style> </style>
@@ -216,10 +222,10 @@ const ResultsPageTemplate = `
{{range .Files}} {{range .Files}}
<div class="file-card" data-content="{{.Content}}"> <div class="file-card" data-content="{{.Content}}">
<div class="file-actions"> <div class="file-actions">
<button class="delete-btn" onclick="deleteFile('{{.Name}}')" title="Удалить файл">🗑️</button> <button class="delete-btn" onclick="deleteFile('{{.Name}}')" title="Удалить файл"></button>
</div> </div>
<div class="file-card-content" onclick="window.location.href='{{$.BasePath}}/file/{{.Name}}'"> <div class="file-card-content" onclick="window.location.href='{{$.BasePath}}/file/{{.Name}}'">
<div class="file-name">{{.Name}}</div> <div class="file-name">{{.DisplayName}}</div>
<div class="file-info"> <div class="file-info">
📅 {{.ModTime}} | 📏 {{.Size}} 📅 {{.ModTime}} | 📏 {{.Size}}
</div> </div>