refactor: 使用 Naive UI 重构后台布局与黑白双主题

This commit is contained in:
GouJ
2026-09-01 16:31:21 +08:00
parent 55516537bf
commit db8c176b55
51 changed files with 3277 additions and 2442 deletions
@@ -1,4 +1,5 @@
<script setup lang="ts">
import { NButton, NCheckbox, NCollapse, NCollapseItem, NInput, NInputNumber, NSelect } from 'naive-ui'
import { computed, reactive, ref } from 'vue'
import { AssetImage } from '../../../components/ui'
import { referenceImageUrl } from '../../../lib/assets'
@@ -43,29 +44,36 @@ function remove(image: VisualStyleImage) {
<fieldset :disabled="disabled" class="flex flex-wrap items-end gap-3">
<label class="min-w-48 flex-1"
><span class="field-label">图片地址</span
><input
v-model="form.imageUrl"
class="input"
><NInput
placeholder="https://… 或 /storage/…"
aria-label="风格图片地址"
/></label>
:input-props="{ 'aria-label': '风格图片地址' }"
v-model:value="form.imageUrl"
></NInput
></label>
<label
><span class="field-label">分类</span
><select v-model="form.category" class="input">
<option v-for="(label, value) in categories" :key="value" :value="value">{{ label }}</option>
</select></label
>
><NSelect
v-model:value="form.category"
:options="[
...Object.entries(categories).map(([value, label]) => ({
label: String(label),
value: value
}))
]"
class="select-control"
></NSelect
></label>
<label class="w-24"
><span class="field-label">排序</span
><input
v-model.number="form.sortOrder"
class="input"
type="number"
step="1"
aria-label="风格图片排序"
/></label>
<label class="flex gap-2 pb-2 text-xs"><input v-model="form.enabled" type="checkbox" />启用</label>
<button class="button button-secondary" type="submit" :disabled="disabled || !valid">登记参考图</button>
><NInputNumber
:input-props="{ 'aria-label': '风格图片排序' }"
:value="typeof form.sortOrder === 'number' ? form.sortOrder : null"
@update:value="form.sortOrder = $event ?? 0"
:step="1"
></NInputNumber
></label>
<NCheckbox v-model:checked="form.enabled" class="flex gap-2 pb-2 text-xs">启用</NCheckbox>
<NButton :disabled="disabled || !valid" attr-type="submit">登记参考图</NButton>
</fieldset>
</form>
<p v-if="form.imageUrl && !valid" class="mt-2 text-xs text-danger" role="alert">
@@ -85,10 +93,12 @@ function remove(image: VisualStyleImage) {
<p v-if="image.provider || image.model" class="mt-2 break-words text-[11px] text-muted">
{{ image.provider }} {{ image.model }}
</p>
<details v-if="image.prompt" class="mt-2 text-xs">
<summary>实际提示词</summary>
<p class="mt-2 whitespace-pre-wrap">{{ image.prompt }}</p>
</details>
<NCollapse v-if="image.prompt" class="mt-2 text-xs"
><NCollapseItem name="details"
><template #header>实际提示词</template>
<p class="mt-2 whitespace-pre-wrap">{{ image.prompt }}</p></NCollapseItem
></NCollapse
>
<div class="mt-3 flex flex-wrap gap-3">
<a
v-if="referenceImageUrl(image.imageUrl)"
@@ -98,19 +108,25 @@ function remove(image: VisualStyleImage) {
rel="noopener noreferrer"
>原图</a
>
<button class="text-button" :disabled="disabled" @click="emit('toggle', image)">
{{ image.enabled ? '停用' : '启用' }}
</button>
<button class="text-button text-danger" :disabled="disabled" @click="confirmingId = image.id">
<NButton :disabled="disabled" @click="emit('toggle', image)" text size="small">{{
image.enabled ? '停用' : '启用'
}}</NButton>
<NButton
:disabled="disabled"
@click="confirmingId = image.id"
text
size="small"
class="text-danger"
>
移除
</button>
</NButton>
</div>
<div v-if="confirmingId === image.id" class="mt-3 text-xs">
<p>仅移除参考图记录不删除远程文件</p>
<div class="mt-2 flex gap-3">
<button class="text-button text-danger" :disabled="disabled" @click="remove(image)">
确认移除</button
><button class="text-button" @click="confirmingId = ''">取消</button>
<NButton :disabled="disabled" @click="remove(image)" text size="small" class="text-danger">
确认移除</NButton
><NButton @click="confirmingId = ''" text size="small">取消</NButton>
</div>
</div>
</article>