批量上传
This commit is contained in:
@@ -526,6 +526,23 @@ colTitle: 'Template title',
|
|||||||
deleteFail: 'Delete failed',
|
deleteFail: 'Delete failed',
|
||||||
previewTitle: 'Template preview',
|
previewTitle: 'Template preview',
|
||||||
previewClose: 'Close',
|
previewClose: 'Close',
|
||||||
|
batchImportBtn: 'Batch import',
|
||||||
|
batchImportTitle: 'Batch import templates (JSON)',
|
||||||
|
batchImportHint:
|
||||||
|
'Paste a JSON array. Each item is saved via the same API as the editor (omit template_id to create; include template_id to update). Fields: title, subject, scene, language (or lang), version, body_html (or body), variables_json (or variables), is_active.',
|
||||||
|
batchImportCommonTip: 'Journal ID is set in the field below; when non-empty it overrides journal_id / journalId on every row.',
|
||||||
|
batchImportJournalId: 'Journal ID',
|
||||||
|
batchImportJournalPlaceholder: 'Match list filter or type manually',
|
||||||
|
batchImportRun: 'Run import',
|
||||||
|
batchImportBadJson: 'Invalid JSON',
|
||||||
|
batchImportEmpty: 'Array must contain at least one object',
|
||||||
|
batchImportMissingJournal: 'Row {index}: missing journal_id (use the input above or put journal_id in JSON)',
|
||||||
|
batchImportMissingField: 'Row {index}: missing {field}',
|
||||||
|
batchImportRowFail: 'Row {index} failed: {msg}',
|
||||||
|
batchImportRowNetwork: 'Row {index}: request error',
|
||||||
|
batchImportDone: 'Done: {ok} succeeded, {fail} failed',
|
||||||
|
batchImportErrorsTitle: 'Errors (first 8)',
|
||||||
|
batchImportSaveFail: 'Save failed',
|
||||||
},
|
},
|
||||||
mailboxStyle: {
|
mailboxStyle: {
|
||||||
title: 'Email Styles',
|
title: 'Email Styles',
|
||||||
@@ -1244,6 +1261,55 @@ colTitle: 'Template title',
|
|||||||
onlySaveConfig: 'Save configuration only',
|
onlySaveConfig: 'Save configuration only',
|
||||||
enableNowNextDay: 'Enable auto promotion now (starts next day)',
|
enableNowNextDay: 'Enable auto promotion now (starts next day)',
|
||||||
factoryCreateBtn: 'Create automated promotion task',
|
factoryCreateBtn: 'Create automated promotion task',
|
||||||
|
factoryBatchImportBtn: 'Batch import (JSON)',
|
||||||
|
factoryBatchImportTitle: 'Batch create tasks (JSON)',
|
||||||
|
factoryBatchImportHintShort: 'Submit a JSON array; non-empty fields merge into each row. You can still edit JSON.',
|
||||||
|
factoryBatchImportHint:
|
||||||
|
'Paste a JSON array… Pick journal (getAllJournal) or type ID; template/style/fetch_ids below override JSON when non-empty. Load promotion fields to tick IDs or type comma-separated fetch_ids; load accounts for j_email_id. expert_type "5" needs partitions/countries. Shorthand: zones, countries, email_id_list.',
|
||||||
|
factoryBatchImportCommonTip: 'Journal from cover or ID field; non-empty template ID, style ID, or fetch_ids override JSON on every row.',
|
||||||
|
factoryBatchImportJournalId: 'Journal ID',
|
||||||
|
factoryBatchImportJournalPick: 'Journal',
|
||||||
|
factoryBatchImportJournalEmpty: 'No journals returned. Check api/Journal/getAllJournal.',
|
||||||
|
factoryBatchImportJournalManualPlaceholder: 'Filled when you pick a cover, or type manually',
|
||||||
|
factoryBatchImportTemplateId: 'Template ID',
|
||||||
|
factoryBatchImportStyleId: 'Style ID',
|
||||||
|
factoryBatchImportJournalPlaceholder: 'Merged into payload',
|
||||||
|
factoryBatchImportTemplatePlaceholder: 'Merged into payload',
|
||||||
|
factoryBatchImportStylePlaceholder: 'Merged into payload',
|
||||||
|
factoryBatchImportFetchIdsLabel: 'Promotion fields (fetch_ids)',
|
||||||
|
factoryBatchImportLoadFields: 'Load available fields',
|
||||||
|
factoryBatchImportFetchTip: 'Uses current journal: pick journal, then load. Search by name or ID (multiple tokens: space or comma). “Select all” selects the filtered list when search is set, otherwise all fields. Checkboxes sync with the comma text; when non-empty, overrides fetch_ids on every row.',
|
||||||
|
factoryBatchImportFetchIdsManual: 'Merged IDs (comma-separated, editable)',
|
||||||
|
factoryBatchImportFetchIdsPlaceholder: 'e.g. 1,2,3 or use checkboxes',
|
||||||
|
factoryBatchImportNeedJournalForFields: 'Select or enter journal ID first',
|
||||||
|
factoryBatchImportLoadAccounts: 'Load accounts for journal',
|
||||||
|
factoryBatchImportAccountsApiTip: 'POST api/email_client/getAccounts with journal_id',
|
||||||
|
factoryBatchImportColEmailId: 'j_email_id',
|
||||||
|
factoryBatchImportColAddress: 'Sender address',
|
||||||
|
factoryBatchImportColQuota: 'Remaining / daily limit',
|
||||||
|
factoryBatchImportCopyEmailIds: 'Copy email_ids (comma)',
|
||||||
|
factoryBatchImportNeedJournalForAccounts: 'Enter journal ID first',
|
||||||
|
factoryBatchImportNoAccounts: 'No mailbox accounts for this journal',
|
||||||
|
factoryBatchImportAccountsFail: 'Failed to load accounts',
|
||||||
|
factoryBatchImportCopyEmailIdsEmpty: 'Load the account list first',
|
||||||
|
factoryBatchImportIdsCopied: 'Copied j_email_id list to clipboard',
|
||||||
|
factoryBatchImportCopyFail: 'Copy failed; select and copy manually',
|
||||||
|
factoryBatchImportSyncToJson: 'Apply top form to JSON',
|
||||||
|
factoryBatchImportSyncFromJson: 'Load first row into form',
|
||||||
|
factoryBatchImportSyncIncludeEmails: 'When applying, set each row email_ids from loaded accounts',
|
||||||
|
factoryBatchImportSyncTip: 'You can still edit JSON manually; non-empty top fields are merged again on submit.',
|
||||||
|
factoryBatchImportJsonFromUiOk: 'JSON updated from the form',
|
||||||
|
factoryBatchImportUiFromJsonOk: 'Form updated from the first JSON row',
|
||||||
|
factoryBatchImportRun: 'Run batch create',
|
||||||
|
factoryBatchImportBadJson: 'Invalid JSON; check brackets and quotes',
|
||||||
|
factoryBatchImportEmpty: 'Array must contain at least one object',
|
||||||
|
factoryBatchImportMissing: 'Row {index}: missing field {field}',
|
||||||
|
factoryBatchImportNeedFetch: 'Row {index}: expert database requires fetch_ids',
|
||||||
|
factoryBatchImportNeedZone: 'Row {index}: expert database requires target_partitions or target_country_ids',
|
||||||
|
factoryBatchImportRowFail: 'Row {index} failed: {msg}',
|
||||||
|
factoryBatchImportRowNetwork: 'Row {index}: request error',
|
||||||
|
factoryBatchImportDone: 'Done: {ok} succeeded, {fail} failed',
|
||||||
|
factoryBatchImportErrorsTitle: 'Errors (first 8)',
|
||||||
factoryDialogTitle: 'Create task',
|
factoryDialogTitle: 'Create task',
|
||||||
factoryJournal: 'Journal',
|
factoryJournal: 'Journal',
|
||||||
factoryJournalPlaceholder: 'Select a journal',
|
factoryJournalPlaceholder: 'Select a journal',
|
||||||
|
|||||||
@@ -515,6 +515,23 @@ const zh = {
|
|||||||
deleteFail: '删除失败',
|
deleteFail: '删除失败',
|
||||||
previewTitle: '模板预览',
|
previewTitle: '模板预览',
|
||||||
previewClose: '关闭',
|
previewClose: '关闭',
|
||||||
|
batchImportBtn: '批量导入',
|
||||||
|
batchImportTitle: '批量导入邮件模板(JSON)',
|
||||||
|
batchImportHint:
|
||||||
|
'粘贴 JSON 数组,每条对应一次保存接口(新建不传 template_id;更新可带 template_id)。字段与编辑页一致:title、subject、scene、language(可用 lang)、version、body_html(可用 body)、variables_json(可用 variables)、is_active。',
|
||||||
|
batchImportCommonTip: '期刊 ID 在下方单独填写;若填写非空,会覆盖每条 JSON 中的 journal_id / journalId。',
|
||||||
|
batchImportJournalId: '期刊 ID',
|
||||||
|
batchImportJournalPlaceholder: '可与列表筛选一致,或手填',
|
||||||
|
batchImportRun: '开始导入',
|
||||||
|
batchImportBadJson: 'JSON 解析失败',
|
||||||
|
batchImportEmpty: '请至少包含一条对象',
|
||||||
|
batchImportMissingJournal: '第 {index} 条:缺少期刊 ID(请填写上方输入框或在 JSON 中提供 journal_id)',
|
||||||
|
batchImportMissingField: '第 {index} 条:缺少字段 {field}',
|
||||||
|
batchImportRowFail: '第 {index} 条保存失败:{msg}',
|
||||||
|
batchImportRowNetwork: '第 {index} 条请求异常',
|
||||||
|
batchImportDone: '完成:成功 {ok},失败 {fail}',
|
||||||
|
batchImportErrorsTitle: '失败明细(最多 8 条)',
|
||||||
|
batchImportSaveFail: '保存失败',
|
||||||
},
|
},
|
||||||
mailboxStyle: {
|
mailboxStyle: {
|
||||||
title: '邮件风格',
|
title: '邮件风格',
|
||||||
@@ -1225,6 +1242,55 @@ const zh = {
|
|||||||
onlySaveConfig: '仅保存配置',
|
onlySaveConfig: '仅保存配置',
|
||||||
enableNowNextDay: '立即激活自动推广(次日开始自动推广)',
|
enableNowNextDay: '立即激活自动推广(次日开始自动推广)',
|
||||||
factoryCreateBtn: '创建自动化推广任务',
|
factoryCreateBtn: '创建自动化推广任务',
|
||||||
|
factoryBatchImportBtn: '临时批量导入',
|
||||||
|
factoryBatchImportTitle: '批量创建推广任务(JSON)',
|
||||||
|
factoryBatchImportHintShort: '数组提交;上方非空项会合并进每条请求,仍可直接改 JSON。',
|
||||||
|
factoryBatchImportHint:
|
||||||
|
'粘贴 JSON 数组…期刊用封面(getAllJournal)或手填 ID;模板/样式/推广领域 fetch_ids 在下方非空则覆盖 JSON。推广领域可「加载可选领域」勾选或手改逗号 ID;填期刊后可查邮箱 j_email_id(getAccounts)。expert_type 为 5 时须分区或国家。简写:zones、countries、email_id_list。',
|
||||||
|
factoryBatchImportCommonTip: '期刊以封面或下方 ID 为准;模板 ID、样式 ID、推广领域 fetch_ids 任一非空则覆盖每条 JSON 中对应字段后再请求接口。',
|
||||||
|
factoryBatchImportJournalId: '期刊 ID',
|
||||||
|
factoryBatchImportJournalPick: '选择期刊',
|
||||||
|
factoryBatchImportJournalEmpty: '未获取到期刊列表,请检查接口或稍后重试',
|
||||||
|
factoryBatchImportJournalManualPlaceholder: '点击上方封面自动填入,也可手改',
|
||||||
|
factoryBatchImportTemplateId: '模板 ID',
|
||||||
|
factoryBatchImportStyleId: '样式 ID',
|
||||||
|
factoryBatchImportJournalPlaceholder: '与 JSON 合并',
|
||||||
|
factoryBatchImportTemplatePlaceholder: '与 JSON 合并',
|
||||||
|
factoryBatchImportStylePlaceholder: '与 JSON 合并',
|
||||||
|
factoryBatchImportFetchIdsLabel: '推广领域 fetch_ids',
|
||||||
|
factoryBatchImportLoadFields: '加载可选领域',
|
||||||
|
factoryBatchImportFetchTip: '依赖当前期刊:先选期刊再加载。上方可搜索名称或 ID(多关键词用空格或逗号);有搜索时「全选」勾选当前筛选结果,无搜索时「全选」为全部。勾选与下方逗号文本同步,非空则覆盖每条 JSON 的 fetch_ids。',
|
||||||
|
factoryBatchImportFetchIdsManual: '合并用 ID(逗号分隔,可手改)',
|
||||||
|
factoryBatchImportFetchIdsPlaceholder: '例:1,2,3;或与勾选联动',
|
||||||
|
factoryBatchImportNeedJournalForFields: '请先选择或填写期刊 ID',
|
||||||
|
factoryBatchImportLoadAccounts: '查询该期刊邮箱',
|
||||||
|
factoryBatchImportAccountsApiTip: 'POST api/email_client/getAccounts,参数 journal_id',
|
||||||
|
factoryBatchImportColEmailId: 'j_email_id',
|
||||||
|
factoryBatchImportColAddress: '发件地址',
|
||||||
|
factoryBatchImportColQuota: '今日剩余 / 日上限',
|
||||||
|
factoryBatchImportCopyEmailIds: '复制 email_ids(逗号)',
|
||||||
|
factoryBatchImportNeedJournalForAccounts: '请先填写期刊 ID',
|
||||||
|
factoryBatchImportNoAccounts: '该期刊下暂无邮箱账号',
|
||||||
|
factoryBatchImportAccountsFail: '拉取邮箱列表失败',
|
||||||
|
factoryBatchImportCopyEmailIdsEmpty: '请先查询出账号列表',
|
||||||
|
factoryBatchImportIdsCopied: '已复制 j_email_id 列表到剪贴板',
|
||||||
|
factoryBatchImportCopyFail: '复制失败,请手动选中复制',
|
||||||
|
factoryBatchImportSyncToJson: '上方选项写入 JSON',
|
||||||
|
factoryBatchImportSyncFromJson: '首条 JSON 回显到上方',
|
||||||
|
factoryBatchImportSyncIncludeEmails: '写入时用当前邮箱列表覆盖每条 email_ids',
|
||||||
|
factoryBatchImportSyncTip: '写入后仍可单独改 JSON;提交时若上方输入框非空仍会再合并覆盖。',
|
||||||
|
factoryBatchImportJsonFromUiOk: '已根据上方选项更新 JSON',
|
||||||
|
factoryBatchImportUiFromJsonOk: '已用首条 JSON 更新上方表单',
|
||||||
|
factoryBatchImportRun: '开始批量创建',
|
||||||
|
factoryBatchImportBadJson: 'JSON 解析失败,请检查括号与引号',
|
||||||
|
factoryBatchImportEmpty: '请至少包含一条对象',
|
||||||
|
factoryBatchImportMissing: '第 {index} 条缺少字段:{field}',
|
||||||
|
factoryBatchImportNeedFetch: '第 {index} 条:专家库需填写 fetch_ids(推广领域)',
|
||||||
|
factoryBatchImportNeedZone: '第 {index} 条:专家库需至少填写分区或国家(target_partitions / target_country_ids)',
|
||||||
|
factoryBatchImportRowFail: '第 {index} 条创建失败:{msg}',
|
||||||
|
factoryBatchImportRowNetwork: '第 {index} 条请求异常',
|
||||||
|
factoryBatchImportDone: '完成:成功 {ok},失败 {fail}',
|
||||||
|
factoryBatchImportErrorsTitle: '失败明细(最多显示 8 条)',
|
||||||
factoryDialogTitle: '创建任务',
|
factoryDialogTitle: '创建任务',
|
||||||
factoryJournal: '期刊',
|
factoryJournal: '期刊',
|
||||||
factoryJournalPlaceholder: '请选择期刊',
|
factoryJournalPlaceholder: '请选择期刊',
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -50,6 +50,9 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
<div class="right-actions">
|
<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>
|
<el-button type="primary" plain icon="el-icon-plus" @click="handleCreateTemplate">{{ $t('mailboxMould.createTemplate') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -136,6 +139,36 @@
|
|||||||
<el-button @click="previewVisible = false">{{ $t('mailboxMould.previewClose') }}</el-button>
|
<el-button @click="previewVisible = false">{{ $t('mailboxMould.previewClose') }}</el-button>
|
||||||
</span>
|
</span>
|
||||||
</el-dialog>
|
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -145,7 +178,8 @@ const API = {
|
|||||||
listStyles: 'api/mail_template/listStyles',
|
listStyles: 'api/mail_template/listStyles',
|
||||||
getAllJournal: 'api/Article/getJournal',
|
getAllJournal: 'api/Article/getJournal',
|
||||||
deleteTemplate: 'api/mail_template/deleteTemplate',
|
deleteTemplate: 'api/mail_template/deleteTemplate',
|
||||||
deleteStyle: 'api/mail_template/deleteStyle'
|
deleteStyle: 'api/mail_template/deleteStyle',
|
||||||
|
saveTemplate: 'api/mail_template/saveTemplate'
|
||||||
};
|
};
|
||||||
// 仅在当前 SPA 会话内记忆筛选(刷新页面即重置)
|
// 仅在当前 SPA 会话内记忆筛选(刷新页面即重置)
|
||||||
const mailboxMouldSessionMemory = {
|
const mailboxMouldSessionMemory = {
|
||||||
@@ -177,7 +211,13 @@ export default {
|
|||||||
|
|
||||||
// --- 共用预览 ---
|
// --- 共用预览 ---
|
||||||
previewVisible: false,
|
previewVisible: false,
|
||||||
previewContent: ''
|
previewContent: '',
|
||||||
|
|
||||||
|
/** 邮件模板 JSON 批量导入(期刊 ID 单独输入,与每条合并后调 saveTemplate) */
|
||||||
|
batchTplImportVisible: false,
|
||||||
|
batchTplImportText: '',
|
||||||
|
batchTplImportJournalId: '',
|
||||||
|
batchTplImporting: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@@ -281,6 +321,147 @@ export default {
|
|||||||
const journalId = this.tplFilters && this.tplFilters.journalId ? String(this.tplFilters.journalId) : '';
|
const journalId = this.tplFilters && this.tplFilters.journalId ? String(this.tplFilters.journalId) : '';
|
||||||
this.$router.push({ path: '/mailboxMouldDetail', query: journalId ? { journal_id: 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) {
|
handleEditTemplate(row) {
|
||||||
this.syncTplFilterMemory();
|
this.syncTplFilterMemory();
|
||||||
const templateId = row && (row.template_id || row.id);
|
const templateId = row && (row.template_id || row.id);
|
||||||
@@ -419,4 +600,39 @@ export default {
|
|||||||
background: #fff;
|
background: #fff;
|
||||||
box-sizing: border-box;
|
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>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user