Merge branch 'master' of https://git.nuttyreading.com/wangjinlei/tougao_web into Editorial-Board
This commit is contained in:
@@ -1159,6 +1159,10 @@ colTitle: 'Template title',
|
||||
},
|
||||
tmrEmailEditor: {
|
||||
preview: 'Preview',
|
||||
previewWithVariables: 'Preview (showing variables)',
|
||||
previewWithVariablesTitle: 'Preview (showing variables)',
|
||||
previewWithVariablesHint: 'The expert data is an example, used for variablespelling check only.',
|
||||
close: 'Close',
|
||||
placeholder: 'Please enter email content'
|
||||
},
|
||||
wordCite: {
|
||||
|
||||
@@ -1144,6 +1144,10 @@ const zh = {
|
||||
},
|
||||
tmrEmailEditor: {
|
||||
preview: '预览效果',
|
||||
previewWithVariables: '预览(示例变量)',
|
||||
previewWithVariablesTitle: '预览效果(已替换示例变量)',
|
||||
previewWithVariablesHint: '专家数据仅为示例,仅用于变量拼写检查。',
|
||||
close: '关闭',
|
||||
placeholder: '请输入邮件内容'
|
||||
},
|
||||
wordCite: {
|
||||
|
||||
@@ -4,9 +4,14 @@
|
||||
<div class="title-slot">
|
||||
<slot name="title"></slot>
|
||||
</div>
|
||||
<button @click="showModal = true" class="preview-trigger-btn">
|
||||
<i class="icon-eye"></i> {{ $t('tmrEmailEditor.preview') || '预览' }}
|
||||
</button>
|
||||
<div class="header-actions">
|
||||
<button type="button" @click="openPreview(false)" class="preview-trigger-btn">
|
||||
<i class="icon-eye"></i> {{ $t('tmrEmailEditor.preview') }}
|
||||
</button>
|
||||
<button type="button" @click="openPreview(true)" class="preview-trigger-btn preview-with-vars-btn">
|
||||
<i class="icon-eye"></i> {{ $t('tmrEmailEditor.previewWithVariables') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<textarea
|
||||
@@ -18,19 +23,21 @@
|
||||
></textarea>
|
||||
|
||||
<transition name="fade">
|
||||
<div v-if="showModal" class="tmr-modal-mask" @click.self="showModal = false">
|
||||
<div v-if="showModal" class="tmr-modal-mask" @click.self="closePreviewModal">
|
||||
<div class="tmr-modal-container">
|
||||
<div class="modal-header">
|
||||
<span>{{ $t('tmrEmailEditor.preview') || '邮件预览' }}</span>
|
||||
<button class="close-btn" @click="showModal = false">×</button>
|
||||
<span>{{ modalPreviewTitle }}</span>
|
||||
<button type="button" class="close-btn" @click="closePreviewModal">×</button>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<p v-if="previewWithMockVariables" class="mock-preview-hint">{{ $t('tmrEmailEditor.previewWithVariablesHint') }}</p>
|
||||
|
||||
<div class="common_tmr_email_box" v-html="htmlContentForPreview"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class="confirm-btn" @click="showModal = false">关闭</button>
|
||||
<button type="button" class="confirm-btn" @click="closePreviewModal">{{ $t('tmrEmailEditor.close') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -47,6 +54,14 @@ export default {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
journalList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
journalId: {
|
||||
|
||||
default: ''
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: ''
|
||||
@@ -54,7 +69,28 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showModal: false
|
||||
showModal: false,
|
||||
/** 为 true 时预览会用 variableMockData 替换正文中的 {{变量名}} */
|
||||
previewWithMockVariables: false,
|
||||
/**
|
||||
* 预览「带变量」时的假数据。键名须与模板里 {{键名}} 完全一致(含中文键)。
|
||||
* 可对照本地变量清单维护,例如:约稿变量清单表格.docx
|
||||
*/
|
||||
variableMockData: {
|
||||
// 以下为示例占位,请按实际模板增删改:
|
||||
|
||||
|
||||
submission_url: "https://submission.tmrjournals.com/", // 投稿系统链接
|
||||
eic_name: "Zhang San", // 主编姓名
|
||||
editor_name: "Alice Wong" ,// 责任编辑姓名
|
||||
expert_title: "Prof", // 专家职称 (如 Prof./Dr.)
|
||||
expert_name: "John Doe", // 专家姓名
|
||||
expert_field: "Biomedical Engineering", // 专家研究领域
|
||||
// representative_work_title: "Advanced Applications of AI in Medical Imaging", // 专家代表作标题
|
||||
// ai_content_analysis: "", // AI 约稿理由分析
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -66,12 +102,65 @@ export default {
|
||||
if (!this.value) return '';
|
||||
return this.extractContent(this.value);
|
||||
},
|
||||
// 用于预览的 HTML,保持与输出一致
|
||||
modalPreviewTitle() {
|
||||
if (this.previewWithMockVariables) {
|
||||
return this.$t('tmrEmailEditor.previewWithVariablesTitle');
|
||||
}
|
||||
return this.$t('tmrEmailEditor.preview');
|
||||
},
|
||||
// 用于预览的 HTML;带变量模式会先替换 {{...}}
|
||||
htmlContentForPreview() {
|
||||
return this.value || '';
|
||||
let html = this.value || '';
|
||||
if (this.previewWithMockVariables) {
|
||||
html = this.applyVariableMocks(html);
|
||||
}
|
||||
return html;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openPreview(withMockVariables) {
|
||||
this.previewWithMockVariables = !!withMockVariables;
|
||||
this.showModal = true;
|
||||
},
|
||||
closePreviewModal() {
|
||||
this.showModal = false;
|
||||
this.previewWithMockVariables = false;
|
||||
},
|
||||
/**
|
||||
* 将 HTML 中的 {{ key }} 替换为 variableMockData[key];未配置的键保持原样。
|
||||
*/
|
||||
applyVariableMocks(html) {
|
||||
if (!html) return '';
|
||||
const oneMonthLater = new Date();
|
||||
oneMonthLater.setMonth(oneMonthLater.getMonth() + 1);
|
||||
// 格式化为 YYYY-MM-DD
|
||||
const deadlineStr = oneMonthLater.toISOString().split('T')[0];
|
||||
|
||||
|
||||
const journal_info=this.journalList.find(e=>e.journal_id==this.journalId)
|
||||
|
||||
const map = {
|
||||
...this.variableMockData,
|
||||
journal_abbr: journal_info.jabbr, // 期刊缩写
|
||||
journal_name: journal_info.title,// 期刊全称
|
||||
journal_url: journal_info.website, // 期刊官网链接
|
||||
journal_email: journal_info.email, // 期刊官方邮箱
|
||||
indexing_databases: "ESCI, Scopus, ROAD", // 收录数据库
|
||||
special_support_deadline:deadlineStr
|
||||
} || {};
|
||||
|
||||
|
||||
|
||||
return html.replace(/\{\{\s*([^}]+?)\s*\}\}/g, (full, rawKey) => {
|
||||
const key = String(rawKey).trim();
|
||||
if (!key) return full;
|
||||
if (Object.prototype.hasOwnProperty.call(map, key) && map[key] != null && map[key] !== '') {
|
||||
const val = map[key];
|
||||
return typeof val === 'string' ? val : String(val);
|
||||
}
|
||||
return full;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 核心:剥离外层容器和换行符
|
||||
* 将 <div class="...">line1<br>line2</div> 还原为 line1\nline2
|
||||
@@ -125,6 +214,14 @@ export default {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
justify-content: flex-end;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.preview-trigger-btn {
|
||||
background: #fff;
|
||||
border: 1px solid #dcdfe6;
|
||||
@@ -246,4 +343,15 @@ export default {
|
||||
}
|
||||
|
||||
.confirm-btn:hover { background: #66b1ff; }
|
||||
|
||||
.preview-with-vars-btn {
|
||||
border-style: dashed;
|
||||
}
|
||||
|
||||
.mock-preview-hint {
|
||||
margin: 0 0 12px;
|
||||
font-size: 12px;
|
||||
color: red;
|
||||
line-height: 1.5;
|
||||
}
|
||||
</style>
|
||||
@@ -98,6 +98,8 @@
|
||||
<div class="subject-label" style="margin-bottom: 10px;">{{ $t('mailboxMouldDetail.emailBody') }}:</div>
|
||||
<!-- <TmrEmailEditor
|
||||
v-model="form.body"
|
||||
:journalList="journalList"
|
||||
:journalId="form.journalId"
|
||||
placeholder=""
|
||||
/> -->
|
||||
<CkeditorMail v-model="form.body" />
|
||||
@@ -172,8 +174,9 @@ export default {
|
||||
.then(res => {
|
||||
const list = res || [];
|
||||
const mapped = (Array.isArray(list) ? list : []).map(j => ({
|
||||
...j,
|
||||
journal_id: j.journal_id || j.id,
|
||||
title: j.title || j.name || ''
|
||||
title: j.title || j.name || '',
|
||||
}));
|
||||
this.journalList = mapped;
|
||||
if (fromRouteJournalId) {
|
||||
|
||||
Reference in New Issue
Block a user