Merge branch 'master' of https://git.nuttyreading.com/wangjinlei/tougao_web into Editorial-Board
This commit is contained in:
@@ -1,96 +1,129 @@
|
||||
<template>
|
||||
<div class="admin-container">
|
||||
<h2>{{ $t('mailboxMould.title') }}</h2>
|
||||
<p class="subtitle">{{ $t('mailboxMould.subtitle') }}</p>
|
||||
|
||||
<div class="toolbar">
|
||||
<el-select
|
||||
v-model="filters.journalId"
|
||||
:placeholder="$t('mailboxMould.journalPlaceholder')"
|
||||
style="width: 300px; margin-right: 10px;"
|
||||
@change="fetchList"
|
||||
>
|
||||
<el-option
|
||||
v-for="j in journalList"
|
||||
:key="j.journal_id"
|
||||
:label="j.title"
|
||||
:value="String(j.journal_id)"
|
||||
></el-option>
|
||||
</el-select>
|
||||
|
||||
<el-tabs v-model="activeTab" @tab-click="handleTabChange">
|
||||
<!-- ========== Tab 1: Templates ========== -->
|
||||
<el-tab-pane :label="$t('mailboxMould.title') || 'Templates'" name="templates">
|
||||
<div class="toolbar">
|
||||
<el-select
|
||||
v-model="tplFilters.journalId"
|
||||
:placeholder="$t('mailboxMould.journalPlaceholder')"
|
||||
style="width: 300px; margin-right: 10px;"
|
||||
@change="fetchTemplates"
|
||||
>
|
||||
<el-option
|
||||
v-for="j in journalList"
|
||||
:key="j.journal_id"
|
||||
:label="j.title"
|
||||
:value="String(j.journal_id)"
|
||||
></el-option>
|
||||
</el-select>
|
||||
|
||||
<el-select
|
||||
v-model="filters.scene"
|
||||
:placeholder="$t('mailboxMould.scenePlaceholder')"
|
||||
clearable
|
||||
style="width: 200px; margin-right: 10px;"
|
||||
@change="fetchList"
|
||||
@clear="fetchList"
|
||||
>
|
||||
<el-option :label="$t('mailboxMould.inviteSubmission')" value="invite_submission"></el-option>
|
||||
<el-option :label="$t('mailboxMould.promoteCitation')" value="promote_citation"></el-option>
|
||||
<el-option :label="$t('mailboxMould.generalThanks')" value="general_thanks"></el-option>
|
||||
</el-select>
|
||||
<el-select
|
||||
v-model="tplFilters.scene"
|
||||
:placeholder="$t('mailboxMould.scenePlaceholder')"
|
||||
clearable
|
||||
style="width: 200px; margin-right: 10px;"
|
||||
@change="fetchTemplates"
|
||||
@clear="fetchTemplates"
|
||||
>
|
||||
<el-option :label="$t('mailboxMould.inviteSubmission')" value="invite_submission"></el-option>
|
||||
<el-option :label="$t('mailboxMould.promoteCitation')" value="promote_citation"></el-option>
|
||||
<el-option :label="$t('mailboxMould.generalThanks')" value="general_thanks"></el-option>
|
||||
</el-select>
|
||||
|
||||
<el-select
|
||||
v-model="filters.language"
|
||||
:placeholder="$t('mailboxMould.languagePlaceholder')"
|
||||
clearable
|
||||
style="width: 120px; margin-right: 10px;"
|
||||
@change="fetchList"
|
||||
@clear="fetchList"
|
||||
>
|
||||
<el-option label="EN" value="en"></el-option>
|
||||
<el-option label="ZH" value="zh"></el-option>
|
||||
</el-select>
|
||||
<el-select
|
||||
v-model="tplFilters.language"
|
||||
:placeholder="$t('mailboxMould.languagePlaceholder')"
|
||||
clearable
|
||||
style="width: 120px; margin-right: 10px;"
|
||||
@change="fetchTemplates"
|
||||
@clear="fetchTemplates"
|
||||
>
|
||||
<el-option label="EN" value="en"></el-option>
|
||||
<el-option label="ZH" value="zh"></el-option>
|
||||
</el-select>
|
||||
|
||||
<el-button type="primary" icon="el-icon-search" @click="fetchList" style="margin-right: 10px;">
|
||||
{{ $t('mailboxMould.searchBtn') }}
|
||||
</el-button>
|
||||
<el-button type="primary" icon="el-icon-search" @click="fetchTemplates" style="margin-right: 10px;">
|
||||
{{ $t('mailboxMould.searchBtn') }}
|
||||
</el-button>
|
||||
|
||||
<div class="right-actions">
|
||||
<el-button type="primary" plain icon="el-icon-plus" @click="handleCreate">{{ $t('mailboxMould.createTemplate') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-table :data="tableData" border style="width: 100%; margin-top: 20px;" v-loading="loading">
|
||||
<el-table-column prop="title" :label="$t('mailboxMould.colTitle')" min-width="220">
|
||||
<template slot-scope="scope">
|
||||
<div class="title-cell">
|
||||
<strong>{{ scope.row.title }}</strong>
|
||||
<div class="right-actions">
|
||||
<el-button type="primary" plain icon="el-icon-plus" @click="handleCreateTemplate">{{ $t('mailboxMould.createTemplate') }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="subject" :label="$t('mailboxMould.colSubject')" min-width="220">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.subject || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="scene" :label="$t('mailboxMould.colScene')">
|
||||
<template slot-scope="scope">
|
||||
<el-tag size="small" type="info">{{ scope.row.scene }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="language" :label="$t('mailboxMould.colLanguage')" width="100">
|
||||
<template slot-scope="scope">
|
||||
{{ String(scope.row.language || '').toUpperCase() }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="version" :label="$t('mailboxMould.colVersion')" width="100"></el-table-column>
|
||||
<el-table-column :label="$t('mailboxMould.colStatus')" width="120">
|
||||
<template slot-scope="scope">
|
||||
<span :class="['status-dot', scope.row.status]"></span>
|
||||
{{ scope.row.status === 'active' ? $t('mailboxMould.active') : $t('mailboxMould.inactive') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="160">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" icon="el-icon-view" @click="handlePreview(scope.row)"></el-button>
|
||||
<el-button type="text" icon="el-icon-edit" @click="handleEdit(scope.row)"></el-button>
|
||||
<el-button type="text" icon="el-icon-delete" class="delete-btn" @click="handleDelete(scope.row)"></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<el-table :data="tplTableData" border style="width: 100%; margin-top: 20px;" v-loading="tplLoading">
|
||||
<el-table-column prop="title" :label="$t('mailboxMould.colTitle')" min-width="220">
|
||||
<template slot-scope="scope">
|
||||
<div class="title-cell"><strong>{{ scope.row.title }}</strong></div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="subject" :label="$t('mailboxMould.colSubject')" min-width="220">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.subject || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="scene" :label="$t('mailboxMould.colScene')">
|
||||
<template slot-scope="scope">
|
||||
<el-tag size="small" type="info">{{ scope.row.scene }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="language" :label="$t('mailboxMould.colLanguage')" width="100">
|
||||
<template slot-scope="scope">
|
||||
{{ String(scope.row.language || '').toUpperCase() }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="version" :label="$t('mailboxMould.colVersion')" width="100"></el-table-column>
|
||||
<el-table-column :label="$t('mailboxMould.colStatus')" width="120">
|
||||
<template slot-scope="scope">
|
||||
<span :class="['status-dot', scope.row.status]"></span>
|
||||
{{ scope.row.status === 'active' ? $t('mailboxMould.active') : $t('mailboxMould.inactive') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="160">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" icon="el-icon-view" @click="handlePreviewTemplate(scope.row)"></el-button>
|
||||
<el-button type="text" icon="el-icon-edit" @click="handleEditTemplate(scope.row)"></el-button>
|
||||
<el-button type="text" icon="el-icon-delete" class="delete-btn" @click="handleDeleteTemplate(scope.row)"></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- ========== Tab 2: Styles ========== -->
|
||||
<el-tab-pane :label="$t('mailboxStyle.title') || 'Styles'" name="styles">
|
||||
<div class="toolbar">
|
||||
<div class="right-actions">
|
||||
<el-button type="primary" icon="el-icon-refresh" @click="fetchStyles">{{ $t('mailboxStyle.searchBtn') }}</el-button>
|
||||
<el-button type="primary" plain icon="el-icon-plus" @click="handleCreateStyle">{{ $t('mailboxStyle.createStyle') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-table :data="styleTableData" border style="width: 100%; margin-top: 20px;" v-loading="styleLoading">
|
||||
<el-table-column prop="name" :label="$t('mailboxStyle.colName')" min-width="220">
|
||||
<template slot-scope="scope">
|
||||
<div class="title-cell"><strong>{{ scope.row.title }}</strong></div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="description" :label="$t('mailboxStyle.colDescription')" min-width="220">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.description || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="160">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" icon="el-icon-view" @click="handlePreviewStyle(scope.row)"></el-button>
|
||||
<el-button type="text" icon="el-icon-edit" @click="handleEditStyle(scope.row)"></el-button>
|
||||
<el-button type="text" icon="el-icon-delete" class="delete-btn" @click="handleDeleteStyle(scope.row)"></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<!-- 预览弹窗(两个 Tab 共用) -->
|
||||
<el-dialog
|
||||
:title="$t('mailboxMould.previewTitle')"
|
||||
:visible.sync="previewVisible"
|
||||
@@ -107,22 +140,32 @@
|
||||
<script>
|
||||
const API = {
|
||||
listTemplates: 'api/mail_template/listTemplates',
|
||||
listStyles: 'api/mail_template/listStyles',
|
||||
getAllJournal: 'api/Journal/getAllJournal',
|
||||
deleteTemplate: 'api/mail_template/deleteTemplate'
|
||||
deleteTemplate: 'api/mail_template/deleteTemplate',
|
||||
deleteStyle: 'api/mail_template/deleteStyle'
|
||||
};
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
searchQuery: '',
|
||||
loading: false,
|
||||
activeTab: 'templates',
|
||||
journalList: [],
|
||||
filters: {
|
||||
|
||||
// --- Templates ---
|
||||
tplLoading: false,
|
||||
tplFilters: {
|
||||
journalId: '',
|
||||
scene: '',
|
||||
language: ''
|
||||
},
|
||||
tableData: [],
|
||||
tplTableData: [],
|
||||
|
||||
// --- Styles ---
|
||||
styleLoading: false,
|
||||
styleTableData: [],
|
||||
|
||||
// --- 共用预览 ---
|
||||
previewVisible: false,
|
||||
previewContent: ''
|
||||
};
|
||||
@@ -131,6 +174,7 @@ export default {
|
||||
this.loadJournals();
|
||||
},
|
||||
methods: {
|
||||
// ========== 公共 ==========
|
||||
loadJournals() {
|
||||
this.$api
|
||||
.post(API.getAllJournal, {})
|
||||
@@ -142,27 +186,36 @@ export default {
|
||||
}));
|
||||
this.journalList = mapped;
|
||||
if (mapped.length > 0) {
|
||||
this.filters.journalId = String(mapped[0].journal_id);
|
||||
this.tplFilters.journalId = String(mapped[0].journal_id);
|
||||
}
|
||||
this.fetchList();
|
||||
this.fetchTemplates();
|
||||
})
|
||||
.catch(() => {
|
||||
this.journalList = [];
|
||||
});
|
||||
},
|
||||
fetchList() {
|
||||
this.loading = true;
|
||||
handleTabChange(tab) {
|
||||
if (tab.name === 'templates' && this.tplTableData.length === 0) {
|
||||
this.fetchTemplates();
|
||||
} else if (tab.name === 'styles' && this.styleTableData.length === 0) {
|
||||
this.fetchStyles();
|
||||
}
|
||||
},
|
||||
|
||||
// ========== Templates ==========
|
||||
fetchTemplates() {
|
||||
this.tplLoading = true;
|
||||
const params = {
|
||||
journal_id: this.filters.journalId || '',
|
||||
scene: this.filters.scene || '',
|
||||
language: this.filters.language || ''
|
||||
journal_id: this.tplFilters.journalId || '',
|
||||
scene: this.tplFilters.scene || '',
|
||||
language: this.tplFilters.language || ''
|
||||
};
|
||||
this.$api
|
||||
.post(API.listTemplates, params)
|
||||
.then(res => {
|
||||
this.loading = false;
|
||||
this.tplLoading = false;
|
||||
const list = (res && res.data && res.data.list) || [];
|
||||
this.tableData = (Array.isArray(list) ? list : []).map(item => ({
|
||||
this.tplTableData = (Array.isArray(list) ? list : []).map(item => ({
|
||||
id: item.template_id || item.id,
|
||||
template_id: item.template_id || item.id,
|
||||
title: item.title,
|
||||
@@ -176,24 +229,22 @@ export default {
|
||||
}));
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
this.tableData = [];
|
||||
this.tplLoading = false;
|
||||
this.tplTableData = [];
|
||||
});
|
||||
},
|
||||
handleCreate() {
|
||||
handleCreateTemplate() {
|
||||
this.$router.push({ path: '/mailboxMouldDetail' });
|
||||
},
|
||||
handleEdit(row) {
|
||||
console.log('Editing:', row);
|
||||
// 跳转到详情页,后续可带上模板 ID
|
||||
handleEditTemplate(row) {
|
||||
const templateId = row && (row.template_id || row.id);
|
||||
this.$router.push({ path: '/mailboxMouldDetail', query: templateId ? { template_id: String(templateId) } : {} });
|
||||
},
|
||||
handlePreview(row) {
|
||||
this.previewContent = row && row.body_html ? row.body_html : (row && row.body ? row.body : '');
|
||||
handlePreviewTemplate(row) {
|
||||
this.previewContent = row && row.body_html ? row.body_html : '';
|
||||
this.previewVisible = true;
|
||||
},
|
||||
handleDelete(row) {
|
||||
handleDeleteTemplate(row) {
|
||||
const templateId = row && (row.template_id || row.id);
|
||||
if (!templateId) return;
|
||||
this.$confirm(this.$t('mailboxMould.deleteConfirm'), this.$t('mailboxMould.colActions'), {
|
||||
@@ -204,7 +255,63 @@ export default {
|
||||
this.$api.post(API.deleteTemplate, { template_id: String(templateId) }).then(res => {
|
||||
if (res && res.code === 0) {
|
||||
this.$message.success(this.$t('mailboxMould.deleteSuccess'));
|
||||
this.fetchList();
|
||||
this.fetchTemplates();
|
||||
} else {
|
||||
this.$message.error((res && res.msg) || this.$t('mailboxMould.deleteFail'));
|
||||
}
|
||||
}).catch(() => {
|
||||
this.$message.error(this.$t('mailboxMould.deleteFail'));
|
||||
});
|
||||
}).catch(() => {});
|
||||
},
|
||||
|
||||
// ========== Styles ==========
|
||||
fetchStyles() {
|
||||
this.styleLoading = true;
|
||||
this.$api
|
||||
.post(API.listStyles, {})
|
||||
.then(res => {
|
||||
this.styleLoading = false;
|
||||
const list = (res && res.data && res.data.list) || [];
|
||||
this.styleTableData = (Array.isArray(list) ? list : []).map(item => ({
|
||||
id: item.style_id || item.id,
|
||||
style_id: item.style_id || item.id,
|
||||
title: item.name,
|
||||
header_html: item.header_html,
|
||||
footer_html: item.footer_html,
|
||||
description: item.description || ''
|
||||
}));
|
||||
})
|
||||
.catch(() => {
|
||||
this.styleLoading = false;
|
||||
this.styleTableData = [];
|
||||
});
|
||||
},
|
||||
handleCreateStyle() {
|
||||
this.$router.push({ path: '/mailboxStyleDetail' });
|
||||
},
|
||||
handleEditStyle(row) {
|
||||
const styleId = row && (row.style_id || row.id);
|
||||
this.$router.push({ path: '/mailboxStyleDetail', query: styleId ? { style_id: String(styleId) } : {} });
|
||||
},
|
||||
handlePreviewStyle(row) {
|
||||
const header = (row && row.header_html) || '';
|
||||
const footer = (row && row.footer_html) || '';
|
||||
this.previewContent = `${header}${footer}`;
|
||||
this.previewVisible = true;
|
||||
},
|
||||
handleDeleteStyle(row) {
|
||||
const styleId = row && (row.style_id || row.id);
|
||||
if (!styleId) return;
|
||||
this.$confirm(this.$t('mailboxMould.deleteConfirm'), this.$t('mailboxMould.colActions'), {
|
||||
confirmButtonText: this.$t('mailboxMould.confirm'),
|
||||
cancelButtonText: this.$t('mailboxMould.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$api.post(API.deleteStyle, { style_id: String(styleId) }).then(res => {
|
||||
if (res && res.code === 0) {
|
||||
this.$message.success(this.$t('mailboxMould.deleteSuccess'));
|
||||
this.fetchStyles();
|
||||
} else {
|
||||
this.$message.error((res && res.msg) || this.$t('mailboxMould.deleteFail'));
|
||||
}
|
||||
@@ -257,4 +364,4 @@ export default {
|
||||
border: 1px solid #eee;
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user