批量上传
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -50,6 +50,9 @@
|
||||
</el-button>
|
||||
|
||||
<div class="right-actions">
|
||||
<el-button type="warning" plain icon="el-icon-upload2" @click="openTemplateBatchImportDialog">{{
|
||||
$t('mailboxMould.batchImportBtn')
|
||||
}}</el-button>
|
||||
<el-button type="primary" plain icon="el-icon-plus" @click="handleCreateTemplate">{{ $t('mailboxMould.createTemplate') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -136,6 +139,36 @@
|
||||
<el-button @click="previewVisible = false">{{ $t('mailboxMould.previewClose') }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
:title="$t('mailboxMould.batchImportTitle')"
|
||||
:visible.sync="batchTplImportVisible"
|
||||
width="720px"
|
||||
append-to-body
|
||||
:close-on-click-modal="false"
|
||||
custom-class="mailbox-mould-batch-import-dialog"
|
||||
@closed="batchTplImporting = false"
|
||||
>
|
||||
<p class="batch-tpl-hint">{{ $t('mailboxMould.batchImportHint') }}</p>
|
||||
<p class="batch-tpl-tip">{{ $t('mailboxMould.batchImportCommonTip') }}</p>
|
||||
<div class="batch-tpl-journal-row">
|
||||
<span class="batch-tpl-label">{{ $t('mailboxMould.batchImportJournalId') }}</span>
|
||||
<el-input
|
||||
v-model="batchTplImportJournalId"
|
||||
clearable
|
||||
size="small"
|
||||
:placeholder="$t('mailboxMould.batchImportJournalPlaceholder')"
|
||||
class="batch-tpl-journal-input"
|
||||
/>
|
||||
</div>
|
||||
<el-input v-model="batchTplImportText" type="textarea" :rows="14" class="batch-tpl-textarea" spellcheck="false" />
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button size="small" @click="batchTplImportVisible = false">{{ $t('mailboxMould.cancel') }}</el-button>
|
||||
<el-button type="primary" size="small" :loading="batchTplImporting" @click="runTemplateBatchImport">{{
|
||||
$t('mailboxMould.batchImportRun')
|
||||
}}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -145,7 +178,8 @@ const API = {
|
||||
listStyles: 'api/mail_template/listStyles',
|
||||
getAllJournal: 'api/Article/getJournal',
|
||||
deleteTemplate: 'api/mail_template/deleteTemplate',
|
||||
deleteStyle: 'api/mail_template/deleteStyle'
|
||||
deleteStyle: 'api/mail_template/deleteStyle',
|
||||
saveTemplate: 'api/mail_template/saveTemplate'
|
||||
};
|
||||
// 仅在当前 SPA 会话内记忆筛选(刷新页面即重置)
|
||||
const mailboxMouldSessionMemory = {
|
||||
@@ -177,7 +211,13 @@ export default {
|
||||
|
||||
// --- 共用预览 ---
|
||||
previewVisible: false,
|
||||
previewContent: ''
|
||||
previewContent: '',
|
||||
|
||||
/** 邮件模板 JSON 批量导入(期刊 ID 单独输入,与每条合并后调 saveTemplate) */
|
||||
batchTplImportVisible: false,
|
||||
batchTplImportText: '',
|
||||
batchTplImportJournalId: '',
|
||||
batchTplImporting: false
|
||||
};
|
||||
},
|
||||
created() {
|
||||
@@ -281,6 +321,147 @@ export default {
|
||||
const journalId = this.tplFilters && this.tplFilters.journalId ? String(this.tplFilters.journalId) : '';
|
||||
this.$router.push({ path: '/mailboxMouldDetail', query: journalId ? { journal_id: journalId } : {} });
|
||||
},
|
||||
openTemplateBatchImportDialog() {
|
||||
const cur = String((this.tplFilters && this.tplFilters.journalId) || '').trim();
|
||||
if (cur) this.batchTplImportJournalId = cur;
|
||||
if (!this.batchTplImportText || !String(this.batchTplImportText).trim()) {
|
||||
this.batchTplImportText = this.defaultTemplateBatchImportSample();
|
||||
}
|
||||
this.batchTplImportVisible = true;
|
||||
},
|
||||
defaultTemplateBatchImportSample() {
|
||||
return (
|
||||
'[\n' +
|
||||
' {\n' +
|
||||
' "title": "示例标题",\n' +
|
||||
' "subject": "示例主题",\n' +
|
||||
' "scene": "invite_submission",\n' +
|
||||
' "language": "en",\n' +
|
||||
' "version": "1.0.0",\n' +
|
||||
' "body_html": "<p>正文 HTML</p>",\n' +
|
||||
' "variables_json": "",\n' +
|
||||
' "is_active": 1\n' +
|
||||
' }\n' +
|
||||
']\n'
|
||||
);
|
||||
},
|
||||
/** 与 mailboxMouldDetail._doSave 提交 saveTemplate 字段对齐;支持 body、lang、variables 别名 */
|
||||
normalizeMailTemplateSavePayload(row) {
|
||||
if (!row || typeof row !== 'object') return {};
|
||||
const bodyHtml =
|
||||
row.body_html != null
|
||||
? String(row.body_html)
|
||||
: row.body != null
|
||||
? String(row.body)
|
||||
: '';
|
||||
const bodyTextRaw = row.body_text != null ? String(row.body_text) : '';
|
||||
const bodyText =
|
||||
bodyTextRaw.trim() ||
|
||||
bodyHtml
|
||||
.replace(/<[^>]+>/g, ' ')
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim();
|
||||
const lang = String(row.language != null ? row.language : row.lang != null ? row.lang : 'en').toLowerCase();
|
||||
let isActive = '1';
|
||||
if (row.is_active === 0 || row.is_active === '0' || row.is_active === false) isActive = '0';
|
||||
const out = {
|
||||
journal_id: String(row.journal_id != null ? row.journal_id : row.journalId != null ? row.journalId : '').trim(),
|
||||
scene: String(row.scene || 'invite_submission'),
|
||||
language: lang,
|
||||
title: String(row.title || ''),
|
||||
subject: String(row.subject || ''),
|
||||
body_html: bodyHtml,
|
||||
body_text: bodyText,
|
||||
variables_json: String(
|
||||
row.variables_json != null ? row.variables_json : row.variables != null ? row.variables : ''
|
||||
),
|
||||
version: String(row.version != null ? row.version : '1.0.0'),
|
||||
is_active: isActive
|
||||
};
|
||||
const tid = row.template_id != null ? row.template_id : row.id;
|
||||
if (tid != null && String(tid).trim() !== '') out.template_id = String(tid).trim();
|
||||
return out;
|
||||
},
|
||||
applyTemplateBatchImportJournal(payload) {
|
||||
const jid = String(this.batchTplImportJournalId || '').trim();
|
||||
if (jid) payload.journal_id = jid;
|
||||
},
|
||||
validateMailTemplateSavePayload(p, index) {
|
||||
if (!p.journal_id || !String(p.journal_id).trim()) {
|
||||
return this.$t('mailboxMould.batchImportMissingJournal', { index: index + 1 });
|
||||
}
|
||||
if (!p.title || !String(p.title).trim()) {
|
||||
return this.$t('mailboxMould.batchImportMissingField', { index: index + 1, field: 'title' });
|
||||
}
|
||||
if (!p.subject || !String(p.subject).trim()) {
|
||||
return this.$t('mailboxMould.batchImportMissingField', { index: index + 1, field: 'subject' });
|
||||
}
|
||||
if (!p.body_html || !String(p.body_html).trim()) {
|
||||
return this.$t('mailboxMould.batchImportMissingField', { index: index + 1, field: 'body_html' });
|
||||
}
|
||||
return '';
|
||||
},
|
||||
async runTemplateBatchImport() {
|
||||
let rows;
|
||||
try {
|
||||
rows = JSON.parse(this.batchTplImportText || '[]');
|
||||
} catch (e) {
|
||||
this.$message.error(this.$t('mailboxMould.batchImportBadJson'));
|
||||
return;
|
||||
}
|
||||
if (!Array.isArray(rows) || !rows.length) {
|
||||
this.$message.warning(this.$t('mailboxMould.batchImportEmpty'));
|
||||
return;
|
||||
}
|
||||
this.batchTplImporting = true;
|
||||
let ok = 0;
|
||||
let fail = 0;
|
||||
const errLines = [];
|
||||
try {
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
const payload = this.normalizeMailTemplateSavePayload(rows[i]);
|
||||
this.applyTemplateBatchImportJournal(payload);
|
||||
const ve = this.validateMailTemplateSavePayload(payload, i);
|
||||
if (ve) {
|
||||
fail++;
|
||||
errLines.push(ve);
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
const res = await this.$api.post(API.saveTemplate, payload);
|
||||
if (res && res.code === 0) {
|
||||
ok++;
|
||||
} else {
|
||||
fail++;
|
||||
errLines.push(
|
||||
this.$t('mailboxMould.batchImportRowFail', {
|
||||
index: i + 1,
|
||||
msg: (res && res.msg) || this.$t('mailboxMould.batchImportSaveFail')
|
||||
})
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
fail++;
|
||||
errLines.push(this.$t('mailboxMould.batchImportRowNetwork', { index: i + 1 }));
|
||||
}
|
||||
}
|
||||
this.$message.success(this.$t('mailboxMould.batchImportDone', { ok, fail }));
|
||||
if (errLines.length) {
|
||||
this.$notify({
|
||||
title: this.$t('mailboxMould.batchImportErrorsTitle'),
|
||||
message: errLines.slice(0, 8).join('\n'),
|
||||
type: fail && !ok ? 'error' : 'warning',
|
||||
duration: 12000
|
||||
});
|
||||
}
|
||||
this.batchTplImportVisible = false;
|
||||
this.syncTplFilterMemory();
|
||||
this.fetchTemplates();
|
||||
} finally {
|
||||
this.batchTplImporting = false;
|
||||
}
|
||||
},
|
||||
handleEditTemplate(row) {
|
||||
this.syncTplFilterMemory();
|
||||
const templateId = row && (row.template_id || row.id);
|
||||
@@ -419,4 +600,39 @@ export default {
|
||||
background: #fff;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.batch-tpl-hint {
|
||||
font-size: 12px;
|
||||
line-height: 1.55;
|
||||
color: #606266;
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
.batch-tpl-tip {
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
color: #909399;
|
||||
margin: 0 0 12px;
|
||||
}
|
||||
.batch-tpl-journal-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.batch-tpl-label {
|
||||
flex-shrink: 0;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #606266;
|
||||
min-width: 72px;
|
||||
}
|
||||
.batch-tpl-journal-input {
|
||||
flex: 1;
|
||||
max-width: 360px;
|
||||
}
|
||||
.mailbox-mould-batch-import-dialog .batch-tpl-textarea >>> textarea {
|
||||
font-family: Consolas, 'Courier New', monospace;
|
||||
font-size: 12px;
|
||||
line-height: 1.45;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user