tijiao
This commit is contained in:
@@ -19,8 +19,8 @@ const service = axios.create({
|
|||||||
// baseURL: 'https://submission.tmrjournals.com/', //正式 记得切换
|
// baseURL: 'https://submission.tmrjournals.com/', //正式 记得切换
|
||||||
// baseURL: 'http://www.tougao.com/', //测试本地 记得切换
|
// baseURL: 'http://www.tougao.com/', //测试本地 记得切换
|
||||||
// baseURL: 'http://192.168.110.110/tougao/public/index.php/',
|
// baseURL: 'http://192.168.110.110/tougao/public/index.php/',
|
||||||
baseURL: '/api', //本地
|
// baseURL: '/api', //本地
|
||||||
// baseURL: '/', //正式
|
baseURL: '/', //正式
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -916,17 +916,38 @@ colTitle: 'Template title',
|
|||||||
startConfig: 'Start auto promotion configuration',
|
startConfig: 'Start auto promotion configuration',
|
||||||
notConfigured: 'Not configured',
|
notConfigured: 'Not configured',
|
||||||
searchPlaceholder: 'Name / Email',
|
searchPlaceholder: 'Name / Email',
|
||||||
|
statusAll: 'All status',
|
||||||
searchBtn: 'Search',
|
searchBtn: 'Search',
|
||||||
index: 'No.',
|
index: 'No.',
|
||||||
|
taskName: 'Task Name',
|
||||||
|
taskParams: 'Parameters',
|
||||||
|
templateIdLabel: 'Template ID',
|
||||||
|
styleIdLabel: 'Style ID',
|
||||||
|
deliveryStats: 'Delivery Stats',
|
||||||
|
totalCount: 'Total',
|
||||||
|
sentCount: 'Sent',
|
||||||
|
failCount: 'Failed',
|
||||||
|
bounceCount: 'Bounce',
|
||||||
|
noDeliveryIssue: 'No delivery issues',
|
||||||
|
deliveryIssue: 'Delivery issues',
|
||||||
|
completedText: 'Completed',
|
||||||
expertInfo: 'Expert Info',
|
expertInfo: 'Expert Info',
|
||||||
templateStyle: 'Template / Style',
|
templateStyle: 'Template / Style',
|
||||||
stylePrefix: 'Style',
|
stylePrefix: 'Style',
|
||||||
runAt: 'Execution time',
|
runAt: 'Execution time',
|
||||||
status: 'Status',
|
status: 'Status',
|
||||||
|
state0: 'Draft',
|
||||||
|
state1: 'Running',
|
||||||
|
state2: 'Paused',
|
||||||
|
state3: 'Completed',
|
||||||
|
state4: 'Cancelled',
|
||||||
|
state5: 'Preparing',
|
||||||
paused: 'Paused',
|
paused: 'Paused',
|
||||||
toRun: 'To run',
|
toRun: 'To run',
|
||||||
operation: 'Operation',
|
operation: 'Operation',
|
||||||
preview: 'Preview',
|
preview: 'Preview',
|
||||||
|
previewAction: 'Preview',
|
||||||
|
editAction: 'Edit',
|
||||||
enable: 'Enable',
|
enable: 'Enable',
|
||||||
pause: 'Pause',
|
pause: 'Pause',
|
||||||
previewEditTitle: 'Preview and edit promotion email',
|
previewEditTitle: 'Preview and edit promotion email',
|
||||||
@@ -943,9 +964,50 @@ colTitle: 'Template title',
|
|||||||
configUpdated: 'Configuration updated',
|
configUpdated: 'Configuration updated',
|
||||||
pauseSuccess: 'Paused',
|
pauseSuccess: 'Paused',
|
||||||
enableSuccess: 'Enabled',
|
enableSuccess: 'Enabled',
|
||||||
|
operationFailed: 'Operation failed',
|
||||||
|
selectTaskForLogs: 'Please select a task first (click the view icon in the list)',
|
||||||
|
pushLogTitle: 'Task list',
|
||||||
|
logRefresh: 'Refresh',
|
||||||
|
taskLogStateFilter: 'Status',
|
||||||
|
taskLogStateAll: 'All',
|
||||||
|
taskLogState0: 'Pending',
|
||||||
|
taskLogState1: 'Sent',
|
||||||
|
taskLogState2: 'Failed',
|
||||||
|
taskLogState3: 'Bounced',
|
||||||
|
taskLogState4: 'Cancelled',
|
||||||
|
logColExpert: 'Expert',
|
||||||
|
logColSendTime: 'Sent at',
|
||||||
|
logColPreparedAt: 'Prepared at',
|
||||||
|
logColStatus: 'Status',
|
||||||
|
logColAction: 'Action',
|
||||||
|
emptyLogs: 'No logs',
|
||||||
|
viewFailureReason: 'Reason',
|
||||||
|
editLogTip: 'Edit',
|
||||||
|
deleteLogTip: 'Delete',
|
||||||
|
previewLogTip: 'Preview',
|
||||||
|
logFieldAffiliation: 'Affiliation',
|
||||||
|
logFieldSubject: 'Subject',
|
||||||
|
logFieldSendTime: 'Sent at',
|
||||||
|
logFieldExecutionTime: 'Executed at',
|
||||||
|
saveDetail: 'Save',
|
||||||
|
failureReasonTitle: 'Failure reason',
|
||||||
|
saveDetailSuccess: 'Saved',
|
||||||
|
saveDetailFailed: 'Save failed',
|
||||||
|
logDetailLoadFailed: 'Failed to load detail',
|
||||||
|
logIdMissing: 'Missing log id',
|
||||||
|
logAlreadySent: 'This record is no longer pending; switched to preview',
|
||||||
|
deleteLogConfirm: 'Delete this log entry?',
|
||||||
|
tipTitle: 'Tip',
|
||||||
|
deleteLogSuccess: 'Deleted',
|
||||||
|
deleteLogFailed: 'Delete failed',
|
||||||
|
noFailureReason: 'No failure reason',
|
||||||
deletedSuccess: 'Deleted',
|
deletedSuccess: 'Deleted',
|
||||||
mockPromotionSubject: 'Promotion for {journal}',
|
mockPromotionSubject: 'Promotion for {journal}',
|
||||||
mockPromotionContent: '<p>Dear {name},</p><p>Check out our latest journal updates...</p>'
|
mockPromotionContent: '<p>Dear {name},</p><p>Check out our latest journal updates...</p>'
|
||||||
|
},
|
||||||
|
tmrEmailEditor: {
|
||||||
|
preview: 'Preview',
|
||||||
|
placeholder: 'Please enter email content'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -901,17 +901,38 @@ const zh = {
|
|||||||
startConfig: '立即开始期刊自动推广配置',
|
startConfig: '立即开始期刊自动推广配置',
|
||||||
notConfigured: '尚未配置',
|
notConfigured: '尚未配置',
|
||||||
searchPlaceholder: '姓名 / 邮箱',
|
searchPlaceholder: '姓名 / 邮箱',
|
||||||
|
statusAll: '全部状态',
|
||||||
searchBtn: '搜索',
|
searchBtn: '搜索',
|
||||||
index: '序号',
|
index: '序号',
|
||||||
|
taskName: '任务名称',
|
||||||
|
taskParams: '参数内容',
|
||||||
|
templateIdLabel: '模板ID',
|
||||||
|
styleIdLabel: '风格ID',
|
||||||
|
deliveryStats: '投递统计',
|
||||||
|
totalCount: '总量',
|
||||||
|
sentCount: '已发送',
|
||||||
|
failCount: '失败',
|
||||||
|
bounceCount: '退信',
|
||||||
|
noDeliveryIssue: '无发送异常',
|
||||||
|
deliveryIssue: '投递异常',
|
||||||
|
completedText: '已完成',
|
||||||
expertInfo: '专家信息',
|
expertInfo: '专家信息',
|
||||||
templateStyle: '模板 / 风格',
|
templateStyle: '模板 / 风格',
|
||||||
stylePrefix: '风格',
|
stylePrefix: '风格',
|
||||||
runAt: '执行时间',
|
runAt: '执行时间',
|
||||||
status: '状态',
|
status: '状态',
|
||||||
|
state0: '草稿',
|
||||||
|
state1: '运行中',
|
||||||
|
state2: '暂停',
|
||||||
|
state3: '完成',
|
||||||
|
state4: '取消',
|
||||||
|
state5: '准备',
|
||||||
paused: '已暂停',
|
paused: '已暂停',
|
||||||
toRun: '待执行',
|
toRun: '待执行',
|
||||||
operation: '操作',
|
operation: '操作',
|
||||||
preview: '查看预览',
|
preview: '查看预览',
|
||||||
|
previewAction: '预览',
|
||||||
|
editAction: '编辑',
|
||||||
enable: '开启',
|
enable: '开启',
|
||||||
pause: '暂停',
|
pause: '暂停',
|
||||||
previewEditTitle: '预览并修改推广邮件',
|
previewEditTitle: '预览并修改推广邮件',
|
||||||
@@ -928,9 +949,50 @@ const zh = {
|
|||||||
configUpdated: '配置已更新',
|
configUpdated: '配置已更新',
|
||||||
pauseSuccess: '已暂停',
|
pauseSuccess: '已暂停',
|
||||||
enableSuccess: '已开启',
|
enableSuccess: '已开启',
|
||||||
|
operationFailed: '操作失败',
|
||||||
|
selectTaskForLogs: '请先选择一条任务(点击列表「查看」图标)',
|
||||||
|
pushLogTitle: '任务列表',
|
||||||
|
logRefresh: '刷新',
|
||||||
|
taskLogStateFilter: '发送状态',
|
||||||
|
taskLogStateAll: '全部',
|
||||||
|
taskLogState0: '待发送',
|
||||||
|
taskLogState1: '已发送',
|
||||||
|
taskLogState2: '失败',
|
||||||
|
taskLogState3: '退信',
|
||||||
|
taskLogState4: '取消',
|
||||||
|
logColExpert: '专家信息',
|
||||||
|
logColSendTime: '发送时间',
|
||||||
|
logColPreparedAt: '预处理完成时间',
|
||||||
|
logColStatus: '状态',
|
||||||
|
logColAction: '操作',
|
||||||
|
emptyLogs: '暂无日志',
|
||||||
|
viewFailureReason: '原因',
|
||||||
|
editLogTip: '编辑',
|
||||||
|
deleteLogTip: '删除',
|
||||||
|
previewLogTip: '预览',
|
||||||
|
logFieldAffiliation: '单位/机构',
|
||||||
|
logFieldSubject: '主题',
|
||||||
|
logFieldSendTime: '发送时间',
|
||||||
|
logFieldExecutionTime: '执行时间',
|
||||||
|
saveDetail: '保存',
|
||||||
|
failureReasonTitle: '失败原因',
|
||||||
|
saveDetailSuccess: '保存成功',
|
||||||
|
saveDetailFailed: '保存失败',
|
||||||
|
logDetailLoadFailed: '加载详情失败',
|
||||||
|
logIdMissing: '缺少日志 ID',
|
||||||
|
logAlreadySent: '该记录已非待发送状态,已切换为预览',
|
||||||
|
deleteLogConfirm: '确定删除该条发送记录?',
|
||||||
|
tipTitle: '提示',
|
||||||
|
deleteLogSuccess: '删除成功',
|
||||||
|
deleteLogFailed: '删除失败',
|
||||||
|
noFailureReason: '暂无失败原因',
|
||||||
deletedSuccess: '已删除',
|
deletedSuccess: '已删除',
|
||||||
mockPromotionSubject: '自动推广:{journal}',
|
mockPromotionSubject: '自动推广:{journal}',
|
||||||
mockPromotionContent: '<p>亲爱的 {name},</p><p>请查看我们最新的期刊更新...</p>'
|
mockPromotionContent: '<p>亲爱的 {name},</p><p>请查看我们最新的期刊更新...</p>'
|
||||||
|
},
|
||||||
|
tmrEmailEditor: {
|
||||||
|
preview: '预览效果',
|
||||||
|
placeholder: '请输入邮件内容'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -104,7 +104,7 @@
|
|||||||
:selectedStyleName="selectedStyleName"
|
:selectedStyleName="selectedStyleName"
|
||||||
:saving="saving"
|
:saving="saving"
|
||||||
:title="`${$t('autoPromotion.journalManage')}: ${wizardJournal ? wizardJournal.title : ''}`"
|
:title="`${$t('autoPromotion.journalManage')}: ${wizardJournal ? wizardJournal.title : ''}`"
|
||||||
@open-template-selector="showTemplateDialog = true"
|
@open-template-selector="openTemplateSelector"
|
||||||
@cancel="showWizardDialog = false"
|
@cancel="showWizardDialog = false"
|
||||||
@confirm="saveWizardConfig"
|
@confirm="saveWizardConfig"
|
||||||
/>
|
/>
|
||||||
@@ -114,6 +114,8 @@
|
|||||||
:visible.sync="showTemplateDialog"
|
:visible.sync="showTemplateDialog"
|
||||||
:journalId="wizardJournal ? wizardJournal.journal_id : ''"
|
:journalId="wizardJournal ? wizardJournal.journal_id : ''"
|
||||||
:journalLabel="wizardJournal ? wizardJournal.title : ''"
|
:journalLabel="wizardJournal ? wizardJournal.title : ''"
|
||||||
|
:initial-style-id="templateDialogInitialStyleId"
|
||||||
|
:initial-template-id="templateDialogInitialTemplateId"
|
||||||
:return-source="'autoPromotion'"
|
:return-source="'autoPromotion'"
|
||||||
@confirm="handleTemplateApply"
|
@confirm="handleTemplateApply"
|
||||||
@close-all-dialogs="closeAllDialogs"
|
@close-all-dialogs="closeAllDialogs"
|
||||||
@@ -148,6 +150,8 @@ export default {
|
|||||||
selectedTemplateThumbHtml: '',
|
selectedTemplateThumbHtml: '',
|
||||||
selectedTemplateName: '',
|
selectedTemplateName: '',
|
||||||
selectedStyleName: '',
|
selectedStyleName: '',
|
||||||
|
templateDialogInitialStyleId: '',
|
||||||
|
templateDialogInitialTemplateId: '',
|
||||||
templateNameMap: {},
|
templateNameMap: {},
|
||||||
allJournals: []
|
allJournals: []
|
||||||
};
|
};
|
||||||
@@ -156,6 +160,16 @@ export default {
|
|||||||
this.fetchPromotionJournals();
|
this.fetchPromotionJournals();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
openTemplateSelector() {
|
||||||
|
// 更换模板时优先回显当前已选 style/template;没有则由选择器回落到第一项
|
||||||
|
this.templateDialogInitialStyleId = this.wizardConfig && this.wizardConfig.defaultStyleId
|
||||||
|
? String(this.wizardConfig.defaultStyleId)
|
||||||
|
: '';
|
||||||
|
this.templateDialogInitialTemplateId = this.wizardConfig && this.wizardConfig.defaultTemplateId
|
||||||
|
? String(this.wizardConfig.defaultTemplateId)
|
||||||
|
: '';
|
||||||
|
this.showTemplateDialog = true;
|
||||||
|
},
|
||||||
closeAllDialogs() {
|
closeAllDialogs() {
|
||||||
// 进入“新增模板/跳转列表页”前,先关闭当前页所有弹窗,减少卡顿
|
// 进入“新增模板/跳转列表页”前,先关闭当前页所有弹窗,减少卡顿
|
||||||
this.showWizardDialog = false;
|
this.showWizardDialog = false;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,9 @@ export default {
|
|||||||
props: {
|
props: {
|
||||||
value: { type: String, default: '' },
|
value: { type: String, default: '' },
|
||||||
id: { type: String, default: () => 'tiny-' + +new Date() },
|
id: { type: String, default: () => 'tiny-' + +new Date() },
|
||||||
showSelectTemplateButton: { type: Boolean, default: false }
|
showSelectTemplateButton: { type: Boolean, default: false },
|
||||||
|
// 仅在需要的页面开启“安全初始化内容”
|
||||||
|
useSafeInitContent: { type: Boolean, default: false }
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -125,7 +127,7 @@ autoInlineStyles(htmlContent) {
|
|||||||
height: 500,
|
height: 500,
|
||||||
// 核心配置:允许所有 HTML 标签和样式,这对比邮件模板至关重要
|
// 核心配置:允许所有 HTML 标签和样式,这对比邮件模板至关重要
|
||||||
valid_children: '+body[tr],+body[thead],+body[tbody],+body[table],+body[style],+p[style],+div[style]',
|
valid_children: '+body[tr],+body[thead],+body[tbody],+body[table],+body[style],+p[style],+div[style]',
|
||||||
extended_valid_elements: 'style,meta,title',
|
extended_valid_elements: 'div[*],table[*],tr[*],td[*],img[*],style',
|
||||||
custom_elements: 'style,meta,title',
|
custom_elements: 'style,meta,title',
|
||||||
verify_html: false, // 关闭 HTML 校验,防止自动删掉你的邮件结构
|
verify_html: false, // 关闭 HTML 校验,防止自动删掉你的邮件结构
|
||||||
forced_root_block: '', // 停止自动包裹 <p> 标签
|
forced_root_block: '', // 停止自动包裹 <p> 标签
|
||||||
@@ -162,7 +164,10 @@ autoInlineStyles(htmlContent) {
|
|||||||
init_instance_callback: (editor) => {
|
init_instance_callback: (editor) => {
|
||||||
this.editor = editor;
|
this.editor = editor;
|
||||||
if (this.value) {
|
if (this.value) {
|
||||||
editor.setContent(this.value);
|
const initContent = this.useSafeInitContent
|
||||||
|
? this.prepareContentForEditor(this.value)
|
||||||
|
: this.value;
|
||||||
|
editor.setContent(initContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听内容变化
|
// 监听内容变化
|
||||||
@@ -172,6 +177,21 @@ autoInlineStyles(htmlContent) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 假设 rawHtml 是你那一大串完整的 HTML
|
||||||
|
prepareContentForEditor(rawHtml) {
|
||||||
|
// 1. 分离出 Head 及其之前的部分 (包含 doctype, html, head)
|
||||||
|
const headMatch = rawHtml.match(/([\s\S]*?)<body([\s\S]*?)>/i);
|
||||||
|
this.originalFullHead = headMatch ? headMatch[0] : ''; // 备份头部
|
||||||
|
|
||||||
|
// 2. 提取 Body 内部内容,并将 <body> 换成 <div>
|
||||||
|
// 这样 TinyMCE 就不会因为 fullpage 插件失效而删掉它
|
||||||
|
let bodyContent = rawHtml.replace(/([\s\S]*?)<body([\s\S]*?)>/i, '')
|
||||||
|
.replace(/<\/body>([\s\S]*?)<\/html>/i, '');
|
||||||
|
|
||||||
|
// 返回给编辑器的内容:用一个特殊的 div 包裹
|
||||||
|
return `<div id="mail-body-temp" style="margin:0;padding:0;">${bodyContent}</div>`;
|
||||||
|
},
|
||||||
// 获取经过行内样式转换后的内容
|
// 获取经过行内样式转换后的内容
|
||||||
getInlinedContent() {
|
getInlinedContent() {
|
||||||
if (!this.editor) return '';
|
if (!this.editor) return '';
|
||||||
|
|||||||
174
src/components/page/components/email/TmrEmailEditor.vue
Normal file
174
src/components/page/components/email/TmrEmailEditor.vue
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
<template>
|
||||||
|
<div class="tmr-editor-container">
|
||||||
|
<div class="editor-header">
|
||||||
|
<span class="title"></span>
|
||||||
|
<button @click="showModal = true" class="preview-trigger-btn">
|
||||||
|
<i class="icon-eye"></i> {{ $t('tmrEmailEditor.preview') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<textarea
|
||||||
|
:value="plainText"
|
||||||
|
@input="handleInput"
|
||||||
|
:placeholder="resolvedPlaceholder"
|
||||||
|
class="tmr-textarea"
|
||||||
|
></textarea>
|
||||||
|
|
||||||
|
<transition name="fade">
|
||||||
|
<div v-if="showModal" class="tmr-modal-mask" @click.self="showModal = false">
|
||||||
|
<div class="tmr-modal-container">
|
||||||
|
<div class="modal-header">
|
||||||
|
<span>{{ $t('tmrEmailEditor.preview') }}</span>
|
||||||
|
<button class="close-btn" @click="showModal = false">×</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="common_tmr_email_box" v-html="htmlContentForPreview"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'TmrEmailEditor',
|
||||||
|
props: {
|
||||||
|
value: { type: String, default: '' },
|
||||||
|
placeholder: { type: String, default: '' }
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
showModal: false // 控制弹窗显示
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
resolvedPlaceholder() {
|
||||||
|
return this.placeholder || this.$t('tmrEmailEditor.placeholder');
|
||||||
|
},
|
||||||
|
// 剥离外壳给 textarea 显示
|
||||||
|
plainText() {
|
||||||
|
if (!this.value) return '';
|
||||||
|
const regex = /<div class="common_tmr_email_box">([\s\S]*?)<\/div>/i;
|
||||||
|
const match = this.value.match(regex);
|
||||||
|
const content = (match && match[1]) ? match[1] : this.value;
|
||||||
|
return content.replace(/<br\s*\/?>/gi, '\n');
|
||||||
|
},
|
||||||
|
// 提取内部内容用于预览
|
||||||
|
htmlContentForPreview() {
|
||||||
|
const regex = /<div class="common_tmr_email_box">([\s\S]*?)<\/div>/i;
|
||||||
|
const match = this.value.match(regex);
|
||||||
|
return match ? match[1] : this.value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleInput(e) {
|
||||||
|
const rawValue = e.target.value;
|
||||||
|
const htmlContent = rawValue.replace(/\n/g, '<br>');
|
||||||
|
const finalResult = `<div class="common_tmr_email_box">${htmlContent}</div>`;
|
||||||
|
this.$emit('input', finalResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 1. 基础布局 */
|
||||||
|
.tmr-editor-container { width: 100%; position: relative; }
|
||||||
|
.editor-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 8px 0;
|
||||||
|
}
|
||||||
|
.preview-trigger-btn {
|
||||||
|
background: #f0f2f5;
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
padding: 5px 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #606266;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.preview-trigger-btn:hover { color: #409eff; border-color: #c6e2ff; background: #ecf5ff; }
|
||||||
|
|
||||||
|
.tmr-textarea {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 70vh;
|
||||||
|
padding: 15px;
|
||||||
|
border: 1px solid #e4e7ed;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.6;
|
||||||
|
box-sizing: border-box;
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2. 弹窗动画 */
|
||||||
|
.fade-enter-active, .fade-leave-active { transition: opacity 0.3s; }
|
||||||
|
.fade-enter, .fade-leave-to { opacity: 0; }
|
||||||
|
|
||||||
|
/* 3. 弹窗样式 */
|
||||||
|
.tmr-modal-mask {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 9998;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tmr-modal-container {
|
||||||
|
width: 1000px;
|
||||||
|
max-width: 90%;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header {
|
||||||
|
padding: 15px 20px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn { border: none; background: none; font-size: 20px; cursor: pointer; color: #909399; }
|
||||||
|
|
||||||
|
.modal-body {
|
||||||
|
padding: 20px;
|
||||||
|
min-height: 60vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-footer {
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-btn {
|
||||||
|
background: #409eff;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
padding: 8px 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 确保预览区域样式正确渲染 */
|
||||||
|
.common_tmr_email_box {
|
||||||
|
word-break: break-all;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -96,7 +96,11 @@
|
|||||||
|
|
||||||
<div class="body-editor-container">
|
<div class="body-editor-container">
|
||||||
<div class="subject-label" style="margin-bottom: 10px;">{{ $t('mailboxMouldDetail.emailBody') }}:</div>
|
<div class="subject-label" style="margin-bottom: 10px;">{{ $t('mailboxMouldDetail.emailBody') }}:</div>
|
||||||
<CkeditorMail v-model="form.body" />
|
<TmrEmailEditor
|
||||||
|
v-model="form.body"
|
||||||
|
placeholder=""
|
||||||
|
/>
|
||||||
|
<!-- <CkeditorMail v-model="form.body" /> -->
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</section>
|
</section>
|
||||||
@@ -106,7 +110,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import CkeditorMail from '@/components/page/components/email/CkeditorMail.vue';
|
import CkeditorMail from '@/components/page/components/email/CkeditorMail.vue';
|
||||||
|
import TmrEmailEditor from '@/components/page/components/email/TmrEmailEditor.vue';
|
||||||
const API = {
|
const API = {
|
||||||
getAllJournal: 'api/Article/getJournal',
|
getAllJournal: 'api/Article/getJournal',
|
||||||
getTemplate: 'api/mail_template/getTemplate',
|
getTemplate: 'api/mail_template/getTemplate',
|
||||||
@@ -115,7 +119,7 @@ const API = {
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'mailboxMouldDetail',
|
name: 'mailboxMouldDetail',
|
||||||
components: { CkeditorMail },
|
components: { CkeditorMail,TmrEmailEditor },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
journalLoading: true,
|
journalLoading: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user