From 788c97d9d5d1234bb9c4919075ae7d09b1049f6a Mon Sep 17 00:00:00 2001 From: chiyi Date: Fri, 10 Jul 2026 00:23:14 +0800 Subject: [PATCH] =?UTF-8?q?ai=E5=8E=BB=E7=89=B9=E5=BE=81=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/internal/http/handler/admin_read.go | 1 + backend/internal/http/handler/user_generation.go | 1 + backend/internal/model/models.go | 1 + backend/internal/service/admin_read.go | 2 ++ backend/internal/service/user_generation.go | 1 + backend/internal/service/v1.go | 9 +++++---- frontend/src/views/ImagesView.vue | 3 ++- frontend/src/views/LogsView.vue | 4 ++++ frontend/src/views/PlaygroundView.vue | 4 ++-- frontend/src/views/UserLogsTableView.vue | 1 + frontend/src/views/UserLogsView.vue | 3 ++- 11 files changed, 22 insertions(+), 8 deletions(-) diff --git a/backend/internal/http/handler/admin_read.go b/backend/internal/http/handler/admin_read.go index 830ef81..09716da 100644 --- a/backend/internal/http/handler/admin_read.go +++ b/backend/internal/http/handler/admin_read.go @@ -130,6 +130,7 @@ func (h *AdminReadHandler) Logs(c *gin.Context) { "resolution": item.Resolution, "duration": item.Duration, "refs": item.Refs, + "deai": item.DeAI, "source": item.Source, "user_id": emptyStringNil(item.UserID), "user_name": userName, diff --git a/backend/internal/http/handler/user_generation.go b/backend/internal/http/handler/user_generation.go index 45d4a4f..4d6bc42 100644 --- a/backend/internal/http/handler/user_generation.go +++ b/backend/internal/http/handler/user_generation.go @@ -310,6 +310,7 @@ func (h *UserGenerationHandler) Logs(c *gin.Context) { "resolution": item.Resolution, "duration": item.Duration, "refs": item.Refs, + "deai": item.DeAI, "source": emptyStringNil(item.Source), "user_id": emptyStringNil(item.UserID), "user_name": userName, diff --git a/backend/internal/model/models.go b/backend/internal/model/models.go index 1acbccf..8b4e3be 100644 --- a/backend/internal/model/models.go +++ b/backend/internal/model/models.go @@ -93,6 +93,7 @@ type EventLog struct { Resolution string `gorm:"size:32"` Duration string `gorm:"size:32"` Refs int `gorm:"not null;default:0"` + DeAI bool `gorm:"not null;default:false"` // 去AI特征 was applied (image only) RefFiles datatypes.JSON `gorm:"type:jsonb"` // relative paths of saved reference images, for回显 on reload Source string `gorm:"size:32;index"` // AccountID is the provider token/account chosen to fulfil this generation, diff --git a/backend/internal/service/admin_read.go b/backend/internal/service/admin_read.go index 1528c7e..8d60db9 100644 --- a/backend/internal/service/admin_read.go +++ b/backend/internal/service/admin_read.go @@ -546,6 +546,7 @@ func (s *AdminReadService) Images(ctx context.Context, limit, offset int, kind s "resolution": "", "ratio": "", "duration": "", + "deai": false, } if event, ok := index[item.Name]; ok { row["prompt"] = event.Prompt @@ -557,6 +558,7 @@ func (s *AdminReadService) Images(ctx context.Context, limit, offset int, kind s row["resolution"] = event.Resolution row["ratio"] = event.Ratio row["duration"] = event.Duration + row["deai"] = event.DeAI } out = append(out, row) } diff --git a/backend/internal/service/user_generation.go b/backend/internal/service/user_generation.go index 7d2a745..86934cb 100644 --- a/backend/internal/service/user_generation.go +++ b/backend/internal/service/user_generation.go @@ -171,6 +171,7 @@ func shapeJobEvent(item *model.EventLog, modelNames map[string]string) map[strin "ratio": item.Ratio, "resolution": item.Resolution, "duration": item.Duration, + "deai": item.DeAI, "status": status, "file": emptyOrNil(item.File), "url": emptyOrNil(url), diff --git a/backend/internal/service/v1.go b/backend/internal/service/v1.go index 1e8f065..a307af1 100644 --- a/backend/internal/service/v1.go +++ b/backend/internal/service/v1.go @@ -453,7 +453,7 @@ func (s *V1Service) prepareImageExecution(ctx context.Context, principal *APIPri if !noStore { fileURL, relativePath = s.allocateOutput(principal, "png", in.BaseURL) } - eventID, err := s.logPendingEvent(ctx, "image", modelItem, principal, in.Prompt, aspectRatio, resolution, "", refCount, price, relativePath, source, refFiles) + eventID, err := s.logPendingEvent(ctx, "image", modelItem, principal, in.Prompt, aspectRatio, resolution, "", refCount, price, relativePath, source, refFiles, in.DeAI) if err != nil { s.cleanupReferenceImages(ctx, "", refFiles) return nil, err @@ -703,7 +703,7 @@ func (s *V1Service) prepareVideoExecution(ctx context.Context, principal *APIPri if !noStore { fileURL, relativePath = s.allocateOutput(principal, "mp4", in.BaseURL) } - eventID, err := s.logPendingEvent(ctx, "video", modelItem, principal, in.Prompt, aspectRatio, resolution, duration, refCount, price, relativePath, source, refFiles) + eventID, err := s.logPendingEvent(ctx, "video", modelItem, principal, in.Prompt, aspectRatio, resolution, duration, refCount, price, relativePath, source, refFiles, false) if err != nil { s.cleanupReferenceImages(ctx, "", refFiles) return nil, err @@ -825,7 +825,7 @@ func (s *V1Service) StartVideoJob(ctx context.Context, principal *APIPrincipal, refFiles := s.saveReferenceImages(ctx, principal, in.ReferenceImages) // Source "v1": no output file is allocated — the result is the upstream URL, // stored on the event when the render completes. - eventID, err := s.logPendingEvent(ctx, "video", modelItem, principal, in.Prompt, aspectRatio, resolution, duration, len(in.ReferenceImages), price, "", "v1", refFiles) + eventID, err := s.logPendingEvent(ctx, "video", modelItem, principal, in.Prompt, aspectRatio, resolution, duration, len(in.ReferenceImages), price, "", "v1", refFiles, false) if err != nil { s.cleanupReferenceImages(ctx, "", refFiles) return nil, err @@ -1343,7 +1343,7 @@ func (s *V1Service) allocateOutput(principal *APIPrincipal, ext, baseURL string) return "/images/" + relativePath, relativePath } -func (s *V1Service) logPendingEvent(ctx context.Context, kind string, modelItem *model.ModelConfig, principal *APIPrincipal, prompt, ratio, resolution, duration string, refs int, cost float64, file, source string, refFiles []string) (string, error) { +func (s *V1Service) logPendingEvent(ctx context.Context, kind string, modelItem *model.ModelConfig, principal *APIPrincipal, prompt, ratio, resolution, duration string, refs int, cost float64, file, source string, refFiles []string, deai bool) (string, error) { event := &model.EventLog{ ID: "evt-" + randomUpper(12), TS: time.Now(), @@ -1356,6 +1356,7 @@ func (s *V1Service) logPendingEvent(ctx context.Context, kind string, modelItem Resolution: resolution, Duration: duration, Refs: refs, + DeAI: deai, Source: source, Cost: cost, File: file, diff --git a/frontend/src/views/ImagesView.vue b/frontend/src/views/ImagesView.vue index 2232afd..e4b227c 100644 --- a/frontend/src/views/ImagesView.vue +++ b/frontend/src/views/ImagesView.vue @@ -328,6 +328,7 @@ onUnmounted(() => window.removeEventListener('keydown', onKey)) {{ f.resolution }} {{ f.ratio }} {{ f.duration }} + 去AI
{{ fmtSize(f.size) }} · {{ fmtTs(f.mtime) }}
@@ -356,7 +357,7 @@ onUnmounted(() => window.removeEventListener('keydown', onKey)) :kind="selected.kind" :prompt="selected.prompt" :meta="[selected.model, selected.name].filter(Boolean).join(' · ')" - :meta-sub="[selected.resolution, selected.ratio, (selected.kind === 'video' ? selected.duration : ''), fmtSize(selected.size), fmtTs(selected.mtime)].filter(Boolean).join(' · ')" + :meta-sub="[selected.resolution, selected.ratio, (selected.kind === 'video' ? selected.duration : ''), (selected.deai ? '去AI特征' : ''), fmtSize(selected.size), fmtTs(selected.mtime)].filter(Boolean).join(' · ')" :download-name="selected.name.split('/').pop()" @close="selected = null" /> diff --git a/frontend/src/views/LogsView.vue b/frontend/src/views/LogsView.vue index 3bc3d8a..b44eab4 100644 --- a/frontend/src/views/LogsView.vue +++ b/frontend/src/views/LogsView.vue @@ -325,6 +325,10 @@ const sourcePill = (s) => ({ · 参考 {{ e.refs }} + {{ e.cost }} diff --git a/frontend/src/views/PlaygroundView.vue b/frontend/src/views/PlaygroundView.vue index 59b9397..17dcc32 100644 --- a/frontend/src/views/PlaygroundView.vue +++ b/frontend/src/views/PlaygroundView.vue @@ -471,7 +471,7 @@ async function loadHistory() { .map((e) => ({ id: 'srv-' + e.id, prompt: e.prompt, model: e.model, kind: e.kind, - ratio: e.ratio, resolution: e.resolution, duration: e.duration, + ratio: e.ratio, resolution: e.resolution, duration: e.duration, deai: !!e.deai, status: e.status === 'success' ? 'done' : 'running', url: e.file ? generatedUrl(e.file) : '', error: '', @@ -834,7 +834,7 @@ onUnmounted(() => {
{{ item.prompt }}
-
{{ item.model }} · {{ (item.elapsed_ms / 1000).toFixed(1) }}s
+
{{ item.model }} · 去AI · {{ (item.elapsed_ms / 1000).toFixed(1) }}s
diff --git a/frontend/src/views/UserLogsTableView.vue b/frontend/src/views/UserLogsTableView.vue index 7b18d83..7f29052 100644 --- a/frontend/src/views/UserLogsTableView.vue +++ b/frontend/src/views/UserLogsTableView.vue @@ -120,6 +120,7 @@ const params = (e) => { const parts = [e.ratio || '—', e.resolution || '—'] if (e.duration) parts.push(e.duration) if (e.refs > 0) parts.push(`参考 ${e.refs}`) + if (e.deai) parts.push('去AI特征') return parts.join(' · ') } diff --git a/frontend/src/views/UserLogsView.vue b/frontend/src/views/UserLogsView.vue index c32c965..1659c68 100644 --- a/frontend/src/views/UserLogsView.vue +++ b/frontend/src/views/UserLogsView.vue @@ -360,6 +360,7 @@ onUnmounted(() => { {{ e.resolution }} {{ e.ratio }} {{ e.duration }} + 去AI
{{ fmtTs(e.ts) }} · {{ fmtMs(e.elapsed_ms) }}
@@ -387,7 +388,7 @@ onUnmounted(() => { :src="generatedUrl(lightbox.file)" :kind="lightbox.kind" :prompt="lightbox.prompt" - :meta="[lightbox.model, lightbox.ratio, lightbox.resolution, lightbox.duration, fmtMs(lightbox.elapsed_ms)].filter(Boolean).join(' · ')" + :meta="[lightbox.model, lightbox.ratio, lightbox.resolution, lightbox.duration, (lightbox.deai ? '去AI特征' : ''), fmtMs(lightbox.elapsed_ms)].filter(Boolean).join(' · ')" :download-name="lightbox.file" @close="lightbox = null" />