style(admin): unify dialog layouts and dense readonly presentation
This commit is contained in:
@@ -4,6 +4,7 @@ import { computed, reactive, ref, watch } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import AppDialog from '@/shared/components/AppDialog.vue'
|
||||
import OperationErrorToast from '@/shared/components/OperationErrorToast.vue'
|
||||
import InlineHelp from '@/shared/components/InlineHelp.vue'
|
||||
import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
|
||||
import { createTemplate, updateTemplate } from '../api/notificationCenter'
|
||||
import type { NotificationTemplate } from '../types'
|
||||
@@ -24,6 +25,7 @@ watch([open, () => props.template], ([isOpen]) => { if (!isOpen) return; const i
|
||||
function normalizeCode(value: string) { form.code = value.replace(/[^A-Za-z0-9_]/g, '').toUpperCase() }
|
||||
function insertVariable(name: string) { if (!whitelist.value.includes(name)) whitelistText.value = [...whitelist.value, name].join(', '); const textarea = contentInput.value?.textarea; const value = `\${${name}}`; const start = textarea?.selectionStart ?? form.content.length; const end = textarea?.selectionEnd ?? start; form.content = `${form.content.slice(0,start)}${value}${form.content.slice(end)}`.slice(0,10000) }
|
||||
async function submit() {
|
||||
if (submitting.value) return
|
||||
error.value = null
|
||||
if (!/^[A-Z][A-Z0-9_]{0,63}$/.test(form.code)) return ElMessage.warning('模板CODE须以字母开头,仅支持大写字母、数字和下划线')
|
||||
if (!form.name.trim() || !form.category.trim() || !form.title.trim() || !form.content.trim()) return ElMessage.warning('请填写完整模板信息')
|
||||
@@ -35,14 +37,30 @@ async function submit() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AppDialog class="admin-density-dialog" v-model="open" :title="editing ? '编辑消息模板' : '新增消息模板'" width="min(760px, calc(100vw - 28px))" :show-confirm="false" destroy-on-close>
|
||||
<AppDialog class="admin-density-dialog" v-model="open" :title="editing ? `编辑消息模板 · ${template?.templateCode || '—'}` : '新增消息模板'" width="min(760px, calc(100vw - 28px))" fullscreenable :confirm-loading="submitting" :show-confirm="false" destroy-on-close>
|
||||
<OperationErrorToast :details="error" />
|
||||
<el-alert title="首期仅支持站内信;新模板保存为草稿,草稿激活后不可再编辑。" type="info" :closable="false" show-icon />
|
||||
<el-form class="template-form density-form" label-position="top"><div class="form-grid"><el-form-item label="模板CODE" required><el-input :model-value="form.code" maxlength="64" :disabled="editing" placeholder="如:ORDER_SHIPPED_NOTICE" @update:model-value="normalizeCode(String($event))" /></el-form-item><el-form-item label="模板名称" required><el-input v-model="form.name" maxlength="128" placeholder="请输入模板名称" /></el-form-item></div><div class="form-grid"><el-form-item label="业务分类" required><el-input v-model="form.category" maxlength="64" placeholder="请输入业务分类" /></el-form-item><el-form-item label="模板类型"><el-input model-value="站内信" disabled /></el-form-item></div><el-form-item label="消息标题模板" required><el-input v-model="form.title" maxlength="256" show-word-limit placeholder="请输入消息标题模板" /></el-form-item><el-form-item label="消息正文模板" required><el-input ref="contentInput" v-model="form.content" type="textarea" :rows="6" maxlength="10000" show-word-limit placeholder="请输入消息正文模板" /></el-form-item><el-form-item label="变量白名单"><el-input v-model="whitelistText" placeholder="多个变量使用逗号分隔,如 customer_name, order_no" /></el-form-item><div class="variable-row"><span>常用变量</span><el-button v-for="name in ['customer_name','order_no','container_no','amount','date']" :key="name" size="small" @click="insertVariable(name)">{{ name }}</el-button></div><section class="template-preview"><strong>内容预览</strong><p>{{ preview }}</p></section></el-form>
|
||||
<template #footer="{ close }"><div class="dialog-actions"><el-button :disabled="submitting" @click="close">取消</el-button><el-button type="primary" :loading="submitting" @click="submit">保存模板</el-button></div></template>
|
||||
<el-form class="density-form density-dialog-sections" label-position="left" label-width="110px" :disabled="submitting">
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="模板定义">
|
||||
<h3 class="density-dialog-section__title">模板定义 <InlineHelp title="模板说明">仅支持站内信;新模板保存为草稿,草稿激活后不可再编辑。变量须登记到白名单,发送时逐项填写。</InlineHelp></h3>
|
||||
<table class="density-table density-table--editable"><tbody>
|
||||
<tr><td><el-form-item label="模板CODE" required><span v-if="editing">{{ form.code }}</span><el-input v-else :model-value="form.code" maxlength="64" placeholder="如:ORDER_SHIPPED_NOTICE" @update:model-value="normalizeCode(String($event))" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="模板名称" required><el-input v-model="form.name" maxlength="128" placeholder="请输入模板名称" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="业务分类" required><el-input v-model="form.category" maxlength="64" placeholder="请输入业务分类" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="模板类型"><span>站内信</span></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="消息标题模板" required><el-input v-model="form.title" maxlength="256" show-word-limit placeholder="请输入消息标题模板" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="消息正文模板" required><el-input ref="contentInput" v-model="form.content" type="textarea" :rows="6" maxlength="10000" show-word-limit placeholder="请输入消息正文模板" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="变量白名单"><el-input v-model="whitelistText" placeholder="多个变量使用逗号分隔,如 customer_name, order_no" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="常用变量"><div class="variable-row"><el-button v-for="name in ['customer_name','order_no','container_no','amount','date']" :key="name" size="small" @click="insertVariable(name)">{{ name }}</el-button></div></el-form-item></td></tr>
|
||||
</tbody></table>
|
||||
</section>
|
||||
<section class="density-dialog-section template-preview" data-tone="source" aria-label="内容预览"><h3 class="density-dialog-section__title">内容预览</h3><p class="density-dialog-note message-body">{{ preview }}</p></section>
|
||||
</el-form>
|
||||
<template #footer="{ close }"><div class="density-actions density-actions--footer"><el-button :disabled="submitting" @click="close">取消</el-button><el-button type="primary" :loading="submitting" @click="submit">保存模板</el-button></div></template>
|
||||
</AppDialog>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.template-form{margin-top:var(--admin-space-5)}.form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--admin-space-5)}.variable-row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--admin-space-3);margin-bottom:var(--admin-space-5);color:var(--cc-muted);font-size:var(--admin-font-caption)}.variable-row :deep(.el-button){margin-left:0}.template-preview{overflow:hidden;border:1px solid var(--cc-border);border-radius:var(--admin-radius)}.template-preview strong{display:block;padding:var(--admin-space-3) var(--admin-space-5);border-bottom:1px solid var(--cc-border);background:var(--admin-label-bg);font-size:var(--admin-font-body)}.template-preview p{min-height:76px;margin:0;padding:var(--admin-space-5);white-space:pre-wrap;overflow-wrap:anywhere;color:var(--cc-muted);font-size:var(--admin-font-body);line-height:1.7}.dialog-actions{display:flex;justify-content:flex-end;gap:var(--admin-space-4)}.dialog-actions :deep(.el-button){margin-left:0}@media(max-width:560px){.form-grid{grid-template-columns:1fr;gap:0}}
|
||||
.variable-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--admin-space-3); }
|
||||
.variable-row :deep(.el-button) { margin-left: 0; }
|
||||
.message-body { white-space: pre-wrap; overflow-wrap: anywhere; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user