1. 迎宾海报

This commit is contained in:
李琦
2026-08-04 08:45:09 +08:00
parent 91b2658ef0
commit 773c4953b2
6 changed files with 574 additions and 312 deletions

View File

@@ -170,9 +170,15 @@
<a-button size="small" danger type="text" class="!px-1" @click.stop="removeText(t.id)">删除</a-button>
</div>
<a-input v-model:value="t.content" placeholder="文字内容" class="mb-2" :maxlength="80" />
<a-form-item label="字体" class="!mb-2">
<a-select v-model:value="t.fontFamily" class="w-full" :options="fontSelectOptions" />
<div class="hw-font-sample mt-1" :style="{ fontFamily: resolveFontCss(t.fontFamily) }">
{{ fontSample(t.fontFamily) }}
</div>
</a-form-item>
<div class="grid grid-cols-2 gap-2">
<a-form-item label="字号" class="!mb-2">
<a-input-number v-model:value="t.fontSize" :min="10" :max="120" class="w-full" />
<a-input-number v-model:value="t.fontSize" :min="10" :max="160" class="w-full" />
</a-form-item>
<a-form-item label="字距" class="!mb-2">
<a-input-number v-model:value="t.letterSpacing" :min="-2" :max="40" class="w-full" />
@@ -194,9 +200,10 @@
/>
</a-form-item>
</div>
<div class="flex gap-4 mb-1">
<div class="flex gap-4 mb-1 flex-wrap">
<a-checkbox v-model:checked="t.vertical">竖排</a-checkbox>
<a-checkbox v-model:checked="t.shadow">阴影</a-checkbox>
<a-checkbox v-model:checked="t.stroke">描边</a-checkbox>
</div>
<div class="text-[10px] text-[#8A8680]">位置 X {{ Math.round(t.x) }}% · Y {{ Math.round(t.y) }}%</div>
</div>
@@ -278,12 +285,15 @@
v-for="(z, i) in tpl.zones"
:key="i"
class="hw-tpl-zone"
:class="{ vertical: z.vertical }"
:class="{ vertical: z.vertical, art: z.art }"
:style="zoneStyle(z)"
>{{ z.label }}</span>
<span v-if="!tpl.zones?.length" class="hw-tpl-preview-empty">自定义空白</span>
</div>
<div class="hw-tpl-card-label">{{ tpl.label }}</div>
<div class="hw-tpl-card-label">
{{ tpl.label }}
<span v-if="tpl.artistic" class="hw-tpl-art-tag">艺术字</span>
</div>
<div class="hw-tpl-card-desc">{{ tpl.desc }}</div>
</button>
</div>
@@ -312,10 +322,12 @@ import {
import ImageField from '@/components/ImageField.vue'
import MediaPickerModal from '@/components/MediaPickerModal.vue'
import {
TEXT_FONTS,
clampPct,
createTextLayer,
defaultTextsForTemplate,
normalizeHotelWelcomeConfig,
resolveFontCss,
resolveTemplate,
serializeHotelWelcomeConfig,
templateGroups,
@@ -363,6 +375,11 @@ const columns = [
const currentTemplateMeta = computed(() => templateMeta(detail.value?.template))
const createTemplateMeta = computed(() => templateMeta(createForm.template))
const currentTemplateDesc = computed(() => currentTemplateMeta.value?.desc || '')
const fontSelectOptions = TEXT_FONTS.map((f) => ({ value: f.value, label: f.label }))
function fontSample(key) {
return TEXT_FONTS.find((f) => f.value === key)?.sample || 'Aa'
}
function zoneStyle(z) {
return {
@@ -559,20 +576,23 @@ function textStyle(t) {
: align === 'right'
? 'translate(-100%, -50%)'
: 'translate(-50%, -50%)'
return {
const style = {
left: `${clampPct(t.x)}%`,
top: `${clampPct(t.y)}%`,
transform,
fontSize: `${t.fontSize || 24}px`,
color: t.color || '#fff',
fontFamily: t.fontFamily === 'serif'
? '"Ma Shan Zheng", "Songti SC", serif'
: t.fontFamily || 'serif',
fontFamily: resolveFontCss(t.fontFamily),
fontWeight: t.fontWeight || '600',
letterSpacing: `${t.letterSpacing || 0}px`,
textAlign: align,
writingMode: t.vertical ? 'vertical-rl' : 'horizontal-tb',
}
if (t.stroke) {
style.webkitTextStroke = `1px ${t.strokeColor || 'rgba(255,255,255,0.35)'}`
style.paintOrder = 'stroke fill'
}
return style
}
function onTextPointerDown(e, t) {
@@ -970,10 +990,35 @@ defineExpose({ loadList, refresh: loadList })
white-space: nowrap;
letter-spacing: 0.12em;
}
.hw-tpl-zone.art {
background: rgba(232, 200, 122, 0.9);
color: #5a3d1a;
font-family: var(--font-brush);
font-size: 10px;
}
.hw-tpl-card-label {
font-size: 12px;
color: #2c2c2c;
font-weight: 500;
display: flex;
align-items: center;
gap: 6px;
flex-wrap: wrap;
}
.hw-tpl-art-tag {
font-size: 10px;
font-weight: 500;
color: #9a4d3a;
background: rgba(196, 92, 92, 0.12);
border: 1px solid rgba(196, 92, 92, 0.28);
border-radius: 999px;
padding: 0 6px;
line-height: 16px;
}
.hw-font-sample {
font-size: 18px;
line-height: 1.2;
color: #7a6550;
}
.hw-tpl-card-desc {
margin-top: 2px;