提交
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: '/', //正式
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -831,26 +831,27 @@ export default {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// },
|
// },
|
||||||
transformHtmlString(inputHtml, type) {
|
transformHtmlString(inputHtml, type, options = {}) {
|
||||||
|
const { keepBr = false } = options;
|
||||||
|
if (!keepBr) {
|
||||||
|
inputHtml = inputHtml.replace(/<br\s*\/?>/g, '');
|
||||||
|
}
|
||||||
// inputHtml = inputHtml.replace(/(<[^>]+) style="[^"]*"/g, '$1'); // 移除style属性
|
// inputHtml = inputHtml.replace(/(<[^>]+) style="[^"]*"/g, '$1'); // 移除style属性
|
||||||
// inputHtml = inputHtml.replace(/(<[^>]+) class="[^"]*"/g, '$1'); // 移除class属性
|
// inputHtml = inputHtml.replace(/(<[^>]+) class="[^"]*"/g, '$1'); // 移除class属性
|
||||||
// inputHtml = inputHtml.replace(/<([a-zA-Z0-9]+)[^>]*>/g, '<$1>'); // 删除标签上的所有属性
|
// inputHtml = inputHtml.replace(/<([a-zA-Z0-9]+)[^>]*>/g, '<$1>'); // 删除标签上的所有属性
|
||||||
|
|
||||||
inputHtml = inputHtml.replace(/<([a-zA-Z0-9]+)([^>]*)>/g, function (match, tag, attributes) {
|
inputHtml = inputHtml.replace(/<([a-zA-Z0-9]+)([^>]*)>/g, function (match, tag, attributes) {
|
||||||
// 使用正则表达式删除属性(保留 data-latex)
|
// 使用正则表达式删除属性(保留 data-latex)
|
||||||
let updatedAttributes = attributes.replace(/\s([a-zA-Z0-9-]+)(="[^"]*")?/g, function (attrMatch, attrName) {
|
let updatedAttributes = attributes.replace(/\s([a-zA-Z0-9-]+)(="[^"]*")?/g, function (attrMatch, attrName) {
|
||||||
// 只保留 data-latex 属性,其他属性删除
|
|
||||||
if (attrName === "data-latex") {
|
if (attrName === "data-latex") {
|
||||||
return attrMatch;
|
return attrMatch;
|
||||||
}
|
}
|
||||||
if (type == 'table' && tag == 'img' && (attrName === "src" || attrName === "width" || attrName === "height")) {
|
if (type == 'table' && tag == 'img' && (attrName === "src" || attrName === "width" || attrName === "height")) {
|
||||||
return attrMatch;
|
return attrMatch;
|
||||||
}
|
}
|
||||||
return ''; // 删除其他属性
|
return '';
|
||||||
});
|
});
|
||||||
|
|
||||||
// 返回标签,保留 data-latex 属性
|
|
||||||
return `<${tag}${updatedAttributes}>`;
|
return `<${tag}${updatedAttributes}>`;
|
||||||
});
|
});
|
||||||
// 2. 删除所有不需要的标签 (除 `strong`, `em`, `sub`, `sup`, `b`, `i` 外的所有标签)
|
// 2. 删除所有不需要的标签 (除 `strong`, `em`, `sub`, `sup`, `b`, `i` 外的所有标签)
|
||||||
@@ -861,14 +862,11 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 3. 删除所有 `<br>` 标签
|
// 去掉样式
|
||||||
inputHtml = inputHtml.replace(/<br\s*\/?>/g, ''); // 删除 <br> 标签
|
|
||||||
// 3. 如果有 `<strong>` 和 `<em>` 标签,去掉内部样式并保留内容
|
|
||||||
inputHtml = inputHtml.replace(/<span[^>]*>/g, '').replace(/<\/span>/g, ''); // 去除span标签
|
inputHtml = inputHtml.replace(/<span[^>]*>/g, '').replace(/<\/span>/g, ''); // 去除span标签
|
||||||
inputHtml = inputHtml.replace(/<strong>/g, '<b>').replace(/<\/strong>/g, '</b>'); // 将 `strong` 替换成 `b`
|
inputHtml = inputHtml.replace(/<strong>/g, '<b>').replace(/<\/strong>/g, '</b>'); // 将 `strong` 替换成 `b`
|
||||||
inputHtml = inputHtml.replace(/<em>/g, '<i>').replace(/<\/em>/g, '</i>'); // 将 `em` 替换成 `i`
|
inputHtml = inputHtml.replace(/<em>/g, '<i>').replace(/<\/em>/g, '</i>'); // 将 `em` 替换成 `i`
|
||||||
|
// 4. 合并相同标签
|
||||||
// 4. 合并相同标签(如多个连续的 <b> 标签)
|
|
||||||
inputHtml = inputHtml.replace(/<b>(.*?)<\/b>\s*<b>/g, '<b>$1'); // 合并连续的 <b> 标签
|
inputHtml = inputHtml.replace(/<b>(.*?)<\/b>\s*<b>/g, '<b>$1'); // 合并连续的 <b> 标签
|
||||||
inputHtml = inputHtml.replace(/<i>(.*?)<\/i>\s*<i>/g, '<i>$1'); // 合并连续的 <i> 标签
|
inputHtml = inputHtml.replace(/<i>(.*?)<\/i>\s*<i>/g, '<i>$1'); // 合并连续的 <i> 标签
|
||||||
|
|
||||||
|
|||||||
@@ -2,16 +2,16 @@
|
|||||||
//记得切换
|
//记得切换
|
||||||
|
|
||||||
//正式
|
//正式
|
||||||
const mediaUrl = '/public/';
|
// const mediaUrl = '/public/';
|
||||||
const baseUrl = '/';
|
// const baseUrl = '/';
|
||||||
|
|
||||||
// const mediaUrl = 'https://submission.tmrjournals.com/public/';
|
// const mediaUrl = 'https://submission.tmrjournals.com/public/';
|
||||||
// // const mediaUrl = 'http://zmzm.tougao.dev.com/public/';
|
// // const mediaUrl = 'http://zmzm.tougao.dev.com/public/';
|
||||||
// const baseUrl = '/api'
|
// const baseUrl = '/api'
|
||||||
|
|
||||||
// const mediaUrl = 'http://tougaotest.tmrjournals.com/public/';
|
const mediaUrl = 'http://tougaotest.tmrjournals.com/public/';
|
||||||
// // const mediaUrl = 'http://zmzm.tougao.dev.com/public/';
|
// const mediaUrl = 'http://zmzm.tougao.dev.com/public/';
|
||||||
// const baseUrl = '/api';
|
const baseUrl = '/api';
|
||||||
|
|
||||||
//本地(正式环境 )
|
//本地(正式环境 )
|
||||||
|
|
||||||
|
|||||||
@@ -225,7 +225,9 @@
|
|||||||
<font style="color: #f56c6c; margin-right: 5px">*</font>
|
<font style="color: #f56c6c; margin-right: 5px">*</font>
|
||||||
Table:
|
Table:
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<common-table
|
<common-table
|
||||||
|
:articleId="articleId"
|
||||||
@getContent="getContent"
|
@getContent="getContent"
|
||||||
v-if="threeVisible"
|
v-if="threeVisible"
|
||||||
ref="commonTable"
|
ref="commonTable"
|
||||||
|
|||||||
@@ -720,7 +720,7 @@ export default {
|
|||||||
article_id: this.$route.query.id
|
article_id: this.$route.query.id
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
console.log('res at line 191:', res);
|
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
this.article_pay_info = {
|
this.article_pay_info = {
|
||||||
fee: res.data.article ? res.data.article.fee : 0,
|
fee: res.data.article ? res.data.article.fee : 0,
|
||||||
@@ -1049,34 +1049,7 @@ export default {
|
|||||||
return e.stage_year + ' Vol.' + e.stage_vol + ' issue.' + e.stage_no + e.stage_pagename + e.stage_page;
|
return e.stage_year + ' Vol.' + e.stage_vol + ' issue.' + e.stage_no + e.stage_pagename + e.stage_page;
|
||||||
},
|
},
|
||||||
|
|
||||||
// 1----保存稿件信息
|
|
||||||
ZsSaveMes() {
|
|
||||||
if (this.detailMes.journal_stage_id == 0) {
|
|
||||||
this.$message.error('Please select an installment!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.$refs.Mes_Form.validate((valid) => {
|
|
||||||
if (valid) {
|
|
||||||
this.$api
|
|
||||||
.post('api/Production/editProduction', this.detailMes)
|
|
||||||
.then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.$message.success(`Successfully save the article!`);
|
|
||||||
this.getData();
|
|
||||||
} else {
|
|
||||||
this.$message.error(res.msg);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
this.$message.error(err);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.$message.error('Please complete Essential Information first!');
|
|
||||||
this.jumpTab(0, this.tabsList[0]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// 2----添加作者操作
|
// 2----添加作者操作
|
||||||
add_Authorclick(index, row) {
|
add_Authorclick(index, row) {
|
||||||
|
|||||||
@@ -831,7 +831,7 @@ export default {
|
|||||||
article_id: this.article_id
|
article_id: this.article_id
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
console.log('res at line 191:', res);
|
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
this.feeStatus=res.data.state
|
this.feeStatus=res.data.state
|
||||||
this.isShowCommit=res.data.state==1?true:false
|
this.isShowCommit=res.data.state==1?true:false
|
||||||
@@ -1146,34 +1146,7 @@ export default {
|
|||||||
return e.stage_year + ' Vol.' + e.stage_vol + ' issue.' + e.stage_no + e.stage_pagename + e.stage_page;
|
return e.stage_year + ' Vol.' + e.stage_vol + ' issue.' + e.stage_no + e.stage_pagename + e.stage_page;
|
||||||
},
|
},
|
||||||
|
|
||||||
// 1----保存稿件信息
|
|
||||||
ZsSaveMes() {
|
|
||||||
if (this.detailMes.journal_stage_id == 0) {
|
|
||||||
this.$message.error('Please select an installment!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.$refs.Mes_Form.validate((valid) => {
|
|
||||||
if (valid) {
|
|
||||||
this.$api
|
|
||||||
.post('api/Production/editProduction', this.detailMes)
|
|
||||||
.then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.$message.success(`Successfully save the article!`);
|
|
||||||
this.getData();
|
|
||||||
} else {
|
|
||||||
this.$message.error(res.msg);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
this.$message.error(err);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.$message.error('Please complete Essential Information first!');
|
|
||||||
this.jumpTab(0, this.tabsList[0]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// 2----添加作者操作
|
// 2----添加作者操作
|
||||||
add_Authorclick(index, row) {
|
add_Authorclick(index, row) {
|
||||||
|
|||||||
@@ -2084,7 +2084,7 @@ export default {
|
|||||||
restaurants[i].value = restaurants[i].email + ' | ' + restaurants[i].firstname + restaurants[i].lastname;
|
restaurants[i].value = restaurants[i].email + ' | ' + restaurants[i].firstname + restaurants[i].lastname;
|
||||||
}
|
}
|
||||||
var results = value ? restaurants.filter(this.createMata(value)) : restaurants;
|
var results = value ? restaurants.filter(this.createMata(value)) : restaurants;
|
||||||
console.log('🚀 ~ .then ~ results177:', results);
|
|
||||||
// 调用 callback 返回建议列表的数据
|
// 调用 callback 返回建议列表的数据
|
||||||
cb(results);
|
cb(results);
|
||||||
// this.form.authorList[num].load = false;
|
// this.form.authorList[num].load = false;
|
||||||
|
|||||||
@@ -11,7 +11,12 @@
|
|||||||
>
|
>
|
||||||
Detailed for MS</el-button
|
Detailed for MS</el-button
|
||||||
>
|
>
|
||||||
<div class="tab_item" v-for="(item, index) in tabsList" @click="jumpTab(index, item)" :class="tabName == item.refName ? 'P_style' : ''">
|
<div
|
||||||
|
class="tab_item"
|
||||||
|
v-for="(item, index) in tabsList"
|
||||||
|
@click="jumpTab(index, item)"
|
||||||
|
:class="tabName == item.refName ? 'P_style' : ''"
|
||||||
|
>
|
||||||
<h5>
|
<h5>
|
||||||
<span>{{ index + 1 }}</span>
|
<span>{{ index + 1 }}</span>
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
@@ -103,10 +108,66 @@
|
|||||||
<el-input v-model="detailMes.tradition_tag" placeholder="eg :Highlights"></el-input>
|
<el-input v-model="detailMes.tradition_tag" placeholder="eg :Highlights"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="Tradition Content :">
|
<el-form-item label="Tradition Content :">
|
||||||
<quill-editor ref="myTextEditor" v-model="detailMes.tradition" :options="editorOption"> </quill-editor>
|
<tinymce
|
||||||
|
type="tradition"
|
||||||
|
:height="160"
|
||||||
|
ref="tinymceChild2"
|
||||||
|
:tinymceOtherInit="{
|
||||||
|
forced_root_block: '',
|
||||||
|
newline_behavior: 'linebreak',
|
||||||
|
}"
|
||||||
|
valid_elements=",br"
|
||||||
|
:wordStyle="`p{font-size: 13px;}`"
|
||||||
|
:isAutomaticUpdate="true"
|
||||||
|
@getContent="getContent"
|
||||||
|
@updateChange="(content) => updateChange('tradition',content)"
|
||||||
|
:value="tradition"
|
||||||
|
class="paste-area text-container"
|
||||||
|
:toolbar="[
|
||||||
|
'bold italic |customBlue removeBlue|myuppercase myuppercasea Line|subscript superscript|clearButton'
|
||||||
|
]"
|
||||||
|
style="
|
||||||
|
line-height: 12px;
|
||||||
|
overflow: auto;
|
||||||
|
font-size: 13px; /* 字体大小 */
|
||||||
|
margin-top: 0pt; /* 段前间距 */
|
||||||
|
margin-bottom: 0pt; /* 段后间距 */
|
||||||
|
"
|
||||||
|
></tinymce>
|
||||||
|
|
||||||
|
<!-- <quill-editor ref="myTextEditor" v-model="detailMes.tradition" :options="editorOption"> </quill-editor> -->
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="Medical history of objective :">
|
<el-form-item label="Medical history of objective :">
|
||||||
<quill-editor ref="myTextEditor" v-model="detailMes.mhoo" :options="editorOption"> </quill-editor>
|
|
||||||
|
<tinymce
|
||||||
|
type="mhooStr"
|
||||||
|
:height="160"
|
||||||
|
ref="tinymceChild3"
|
||||||
|
:tinymceOtherInit="{
|
||||||
|
forced_root_block: '',
|
||||||
|
newline_behavior: 'linebreak',
|
||||||
|
}"
|
||||||
|
valid_elements=",br"
|
||||||
|
:wordStyle="`p{font-size: 13px;}`"
|
||||||
|
:isAutomaticUpdate="true"
|
||||||
|
@getContent="getContent"
|
||||||
|
@updateChange="(content) => updateChange('mhooStr',content)"
|
||||||
|
:value="mhooStr"
|
||||||
|
class="paste-area text-container"
|
||||||
|
:toolbar="[
|
||||||
|
'bold italic |customBlue removeBlue|myuppercase myuppercasea Line|subscript superscript|clearButton'
|
||||||
|
]"
|
||||||
|
style="
|
||||||
|
line-height: 12px;
|
||||||
|
overflow: auto;
|
||||||
|
font-size: 13px; /* 字体大小 */
|
||||||
|
margin-top: 0pt; /* 段前间距 */
|
||||||
|
margin-bottom: 0pt; /* 段后间距 */
|
||||||
|
"
|
||||||
|
></tinymce>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <quill-editor ref="myTextEditor" v-model="detailMes.mhoo" :options="editorOption"> </quill-editor> -->
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="keywords :" prop="keywords">
|
<el-form-item label="keywords :" prop="keywords">
|
||||||
<el-input v-model="detailMes.keywords" placeholder="eg : keyword1,keyword2,keyword3"> </el-input>
|
<el-input v-model="detailMes.keywords" placeholder="eg : keyword1,keyword2,keyword3"> </el-input>
|
||||||
@@ -118,6 +179,7 @@
|
|||||||
<el-form-item label="Acknowledgment :" prop="acknowledgment">
|
<el-form-item label="Acknowledgment :" prop="acknowledgment">
|
||||||
<el-input v-model="detailMes.acknowledgment"></el-input>
|
<el-input v-model="detailMes.acknowledgment"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="Abbreviation :">
|
<el-form-item label="Abbreviation :">
|
||||||
<el-input v-model="detailMes.abbreviation"></el-input>
|
<el-input v-model="detailMes.abbreviation"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -133,7 +195,7 @@
|
|||||||
:wordStyle="`p{font-size: 13px;}`"
|
:wordStyle="`p{font-size: 13px;}`"
|
||||||
:isAutomaticUpdate="true"
|
:isAutomaticUpdate="true"
|
||||||
@getContent="getContent"
|
@getContent="getContent"
|
||||||
@updateChange="updateChange"
|
@updateChange="(content) => updateChange('abstract',content)"
|
||||||
:value="abstract"
|
:value="abstract"
|
||||||
class="paste-area text-container"
|
class="paste-area text-container"
|
||||||
:toolbar="[
|
:toolbar="[
|
||||||
@@ -150,6 +212,9 @@
|
|||||||
|
|
||||||
<!-- <quill-editor ref="myTextEditor" v-model="detailMes.abstract" :options="editorOption"> </quill-editor> -->
|
<!-- <quill-editor ref="myTextEditor" v-model="detailMes.abstract" :options="editorOption"> </quill-editor> -->
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="Executive editor :" prop="executive_editor">
|
||||||
|
<el-input v-model="detailMes.executive_editor"></el-input>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div style="text-align: center; margin: 25px 0 0 0">
|
<div style="text-align: center; margin: 25px 0 0 0">
|
||||||
<el-button type="primary" @click="ZsSaveMes" class="save-btn">
|
<el-button type="primary" @click="ZsSaveMes" class="save-btn">
|
||||||
@@ -997,6 +1062,8 @@ export default {
|
|||||||
journal_special_id: 'None'
|
journal_special_id: 'None'
|
||||||
},
|
},
|
||||||
abstract: '',
|
abstract: '',
|
||||||
|
tradition: '',
|
||||||
|
mhooStr: '',
|
||||||
opInstal: [],
|
opInstal: [],
|
||||||
// opMedical: [
|
// opMedical: [
|
||||||
// {
|
// {
|
||||||
@@ -1358,6 +1425,18 @@ export default {
|
|||||||
message: 'Please enter mechanism',
|
message: 'Please enter mechanism',
|
||||||
trigger: 'blur'
|
trigger: 'blur'
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
executive_editor: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: 'Please enter the executive editor',
|
||||||
|
trigger: 'blur'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: /^[^\u4e00-\u9fa5]*$/,
|
||||||
|
message: 'Please use English characters only',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1381,7 +1460,7 @@ export default {
|
|||||||
// article_id: 6075
|
// article_id: 6075
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
console.log('res at line 1460:', res);
|
|
||||||
if (res.status == 1) {
|
if (res.status == 1) {
|
||||||
this.finalReview = res.data;
|
this.finalReview = res.data;
|
||||||
} else {
|
} else {
|
||||||
@@ -1389,15 +1468,17 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
updateChange(content) {
|
updateChange(type, content) {
|
||||||
this.abstract = content;
|
|
||||||
|
this[type] = content;
|
||||||
},
|
},
|
||||||
|
|
||||||
getTinymceContent(type) {
|
getTinymceContent(type) {
|
||||||
|
|
||||||
this.$refs.tinymceChild1.getContent(type);
|
this.$refs.tinymceChild1.getContent(type);
|
||||||
},
|
},
|
||||||
getContent(type, content) {
|
getContent(type, content) {
|
||||||
console.log('content at line 1449:', content);
|
|
||||||
console.log('type at line 1449:', type);
|
|
||||||
},
|
},
|
||||||
// 跳转文章详情
|
// 跳转文章详情
|
||||||
showdetaileditor(data) {
|
showdetaileditor(data) {
|
||||||
@@ -1459,12 +1540,24 @@ export default {
|
|||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
this.detailMes = res.data.production;
|
this.detailMes = res.data.production;
|
||||||
this.abstract = res.data.production.abstract;
|
this.abstract = res.data.production.abstract?res.data.production.abstract:'';
|
||||||
|
this.tradition = res.data.production.tradition?res.data.production.tradition:'';
|
||||||
|
this.mhooStr = res.data.production.mhoo?res.data.production.mhoo:'';
|
||||||
if (this.abstract != '') {
|
if (this.abstract != '') {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs.tinymceChild1.setContent(this.abstract);
|
this.$refs.tinymceChild1.setContent(this.abstract);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (this.tradition != '') {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.tinymceChild2.setContent(this.tradition);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (this.mhooStr != '') {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.tinymceChild3.setContent(this.mhooStr);
|
||||||
|
});
|
||||||
|
}
|
||||||
this.UpTyFIle = res.data.production.file_pdf;
|
this.UpTyFIle = res.data.production.file_pdf;
|
||||||
this.getArticleFinal(res.data.production.article_id);
|
this.getArticleFinal(res.data.production.article_id);
|
||||||
if (res.data.production.icon != '') {
|
if (res.data.production.icon != '') {
|
||||||
@@ -1753,23 +1846,17 @@ export default {
|
|||||||
return e.stage_year + ' Vol.' + e.stage_vol + ' issue.' + e.stage_no + e.stage_pagename + e.stage_page;
|
return e.stage_year + ' Vol.' + e.stage_vol + ' issue.' + e.stage_no + e.stage_pagename + e.stage_page;
|
||||||
},
|
},
|
||||||
async abstractFormat(content) {
|
async abstractFormat(content) {
|
||||||
content = this.$commonJS.transformHtmlString(content);
|
content = this.$commonJS.transformHtmlString(content,'content',{keepBr:true});
|
||||||
var div = document.createElement('div');
|
var div = document.createElement('div');
|
||||||
div.innerHTML = content;
|
div.innerHTML = content;
|
||||||
|
|
||||||
// 1. 剔除所有 img 标签
|
|
||||||
var imgTags = div.getElementsByTagName('img');
|
var imgTags = div.getElementsByTagName('img');
|
||||||
for (var i = imgTags.length - 1; i >= 0; i--) {
|
for (var i = imgTags.length - 1; i >= 0; i--) {
|
||||||
imgTags[i].parentNode.removeChild(imgTags[i]);
|
imgTags[i].parentNode.removeChild(imgTags[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 新增:剔除所有 table 相关标签(table、tr、td)
|
|
||||||
var tableTags = div.getElementsByTagName('table');
|
var tableTags = div.getElementsByTagName('table');
|
||||||
for (var i = tableTags.length - 1; i >= 0; i--) {
|
for (var i = tableTags.length - 1; i >= 0; i--) {
|
||||||
tableTags[i].parentNode.removeChild(tableTags[i]);
|
tableTags[i].parentNode.removeChild(tableTags[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 替换 strong → b、em → i(原有逻辑)
|
|
||||||
var strongTags = div.getElementsByTagName('strong');
|
var strongTags = div.getElementsByTagName('strong');
|
||||||
for (var i = 0; i < strongTags.length; i++) {
|
for (var i = 0; i < strongTags.length; i++) {
|
||||||
var bTag = document.createElement('b');
|
var bTag = document.createElement('b');
|
||||||
@@ -1782,32 +1869,43 @@ export default {
|
|||||||
iTag.innerHTML = emTags[i].innerHTML;
|
iTag.innerHTML = emTags[i].innerHTML;
|
||||||
emTags[i].parentNode.replaceChild(iTag, emTags[i]);
|
emTags[i].parentNode.replaceChild(iTag, emTags[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理 p 标签 + 解码
|
// 处理 p 标签 + 解码
|
||||||
content = div.innerHTML;
|
content = div.innerHTML;
|
||||||
|
|
||||||
content = content.replace(/^<p>\s*(.*?)\s*<\/p>$/, '$1').trim();
|
content = content.replace(/^<p>\s*(.*?)\s*<\/p>$/, '$1').trim();
|
||||||
|
|
||||||
content = await this.$commonJS.decodeHtml(content);
|
content = await this.$commonJS.decodeHtml(content);
|
||||||
|
content = content.replace(/ |\u00A0/g, ' ');
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
},
|
},
|
||||||
// 1----保存稿件信息
|
// 1----保存稿件信息
|
||||||
async ZsSaveMes() {
|
async ZsSaveMes() {
|
||||||
|
|
||||||
var abstractStr = '';
|
var abstractStr = '';
|
||||||
|
var mhooStr = '';
|
||||||
|
var traditionStr = '';
|
||||||
if (this.detailMes.journal_stage_id == 0) {
|
if (this.detailMes.journal_stage_id == 0) {
|
||||||
this.$message.error('Please select an installment!');
|
this.$message.error('Please select an installment!');
|
||||||
return;
|
return;
|
||||||
|
} if (this.tradition!='') {
|
||||||
|
traditionStr = await this.abstractFormat(this.tradition);
|
||||||
|
}
|
||||||
|
if (this.mhooStr!='') {
|
||||||
|
mhooStr = await this.abstractFormat(this.mhooStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.abstract == '') {
|
if (this.abstract == '') {
|
||||||
this.$message.error('Please input abstract!');
|
this.$message.error('Please input abstract!');
|
||||||
return;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
abstractStr = await this.abstractFormat(this.abstract);
|
abstractStr = await this.abstractFormat(this.abstract);
|
||||||
}
|
}
|
||||||
console.log('abstractStr at line 1820:', abstractStr);
|
|
||||||
|
|
||||||
this.$refs.Mes_Form.validate((valid) => {
|
this.$refs.Mes_Form.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
this.$api
|
this.$api
|
||||||
.post('api/Production/editProduction', { ...this.detailMes, abstract: abstractStr })
|
.post('api/Production/editProduction', { ...this.detailMes, abstract: abstractStr, mhoo: mhooStr, tradition: traditionStr })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
this.$message.success(`Successfully save the article!`);
|
this.$message.success(`Successfully save the article!`);
|
||||||
@@ -2904,30 +3002,30 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
onScroll(e) {
|
onScroll(e) {
|
||||||
const scrollContainer = e.target;
|
const scrollContainer = e.target;
|
||||||
const scrollItems = document.querySelectorAll('.scroll-item');
|
const scrollItems = document.querySelectorAll('.scroll-item');
|
||||||
|
|
||||||
// 遍历所有滚动项,找到“当前在可视区域内”的项
|
|
||||||
for (let i = 0; i < scrollItems.length; i++) {
|
|
||||||
const item = scrollItems[i];
|
|
||||||
// 计算项相对于滚动容器的位置(顶部距离)
|
|
||||||
const itemTop = item.offsetTop - scrollContainer.offsetTop;
|
|
||||||
// 计算项的底部距离
|
|
||||||
const itemBottom = itemTop + item.offsetHeight;
|
|
||||||
|
|
||||||
// 判断:项的顶部 <= 滚动距离,且项的底部 >= 滚动距离(即项在可视区域内)
|
// 遍历所有滚动项,找到“当前在可视区域内”的项
|
||||||
const isInView = (itemTop <= scrollContainer.scrollTop) && (itemBottom >= scrollContainer.scrollTop);
|
for (let i = 0; i < scrollItems.length; i++) {
|
||||||
|
const item = scrollItems[i];
|
||||||
if (isInView) {
|
// 计算项相对于滚动容器的位置(顶部距离)
|
||||||
this.tabIndex = i.toString();
|
const itemTop = item.offsetTop - scrollContainer.offsetTop;
|
||||||
// 先判断tabsList是否存在对应索引,避免报错
|
// 计算项的底部距离
|
||||||
if (this.tabsList[i]) {
|
const itemBottom = itemTop + item.offsetHeight;
|
||||||
this.tabName = this.tabsList[i].refName;
|
|
||||||
|
// 判断:项的顶部 <= 滚动距离,且项的底部 >= 滚动距离(即项在可视区域内)
|
||||||
|
const isInView = itemTop <= scrollContainer.scrollTop && itemBottom >= scrollContainer.scrollTop;
|
||||||
|
|
||||||
|
if (isInView) {
|
||||||
|
this.tabIndex = i.toString();
|
||||||
|
// 先判断tabsList是否存在对应索引,避免报错
|
||||||
|
if (this.tabsList[i]) {
|
||||||
|
this.tabName = this.tabsList[i].refName;
|
||||||
|
}
|
||||||
|
break; // 找到第一个匹配的项就停止
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break; // 找到第一个匹配的项就停止
|
},
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getHight() {
|
getHight() {
|
||||||
this.contentStyleObj.height = window.innerHeight - 60 + 'px';
|
this.contentStyleObj.height = window.innerHeight - 60 + 'px';
|
||||||
@@ -2969,9 +3067,9 @@ export default {
|
|||||||
font-size: 14px !important;
|
font-size: 14px !important;
|
||||||
padding: 6px 10px !important;
|
padding: 6px 10px !important;
|
||||||
}
|
}
|
||||||
.tab_item{
|
.tab_item {
|
||||||
height: 6vh;
|
height: 6vh;
|
||||||
min-height: 60px;
|
min-height: 60px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,14 +5,19 @@
|
|||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { string } from 'html-docx-js/dist/html-docx';
|
import { string } from 'html-docx-js/dist/html-docx';
|
||||||
|
import axios from 'axios';
|
||||||
import htmlDocx from 'html-docx-js/dist/html-docx.js';
|
import htmlDocx from 'html-docx-js/dist/html-docx.js';
|
||||||
import { Document, Packer, PageOrientation, Paragraph, TextRun } from 'docx'; // 引入 docx.js
|
import { Document, Packer, PageOrientation, Paragraph, TextRun } from 'docx'; // 引入 docx.js
|
||||||
import html2canvas from 'html2canvas';
|
import html2canvas from 'html2canvas';
|
||||||
|
import { extractHexImagesFromRTF, hexToBlob } from '@/utils/rtfParser';
|
||||||
const tableStyle = `*{
|
const tableStyle = `
|
||||||
font-family: 'Charis SIL';
|
.word-img-placeholder {
|
||||||
}
|
background: #f0f0f0 ;
|
||||||
b span{
|
}
|
||||||
|
*{
|
||||||
|
font-family: 'Charis SIL';
|
||||||
|
}
|
||||||
|
b span{
|
||||||
font-weight: bold !important;
|
font-weight: bold !important;
|
||||||
}
|
}
|
||||||
i span{
|
i span{
|
||||||
@@ -62,7 +67,6 @@ const tableStyle = `*{
|
|||||||
mos-line-height: 20px !important;
|
mos-line-height: 20px !important;
|
||||||
}
|
}
|
||||||
table tbody tr td{
|
table tbody tr td{
|
||||||
|
|
||||||
text-align:left !important;
|
text-align:left !important;
|
||||||
border-left:none !important;
|
border-left:none !important;
|
||||||
mso-border-left-alt:none !important;
|
mso-border-left-alt:none !important;
|
||||||
@@ -181,6 +185,17 @@ export default {
|
|||||||
wordStyle: {
|
wordStyle: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
|
},
|
||||||
|
valid_elements: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
tinymceOtherInit: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
articleId: {
|
||||||
|
default: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@@ -301,101 +316,97 @@ export default {
|
|||||||
generateUniqueId() {
|
generateUniqueId() {
|
||||||
return 'wmath-' + Math.random().toString(36).substr(2, 9);
|
return 'wmath-' + Math.random().toString(36).substr(2, 9);
|
||||||
},
|
},
|
||||||
|
// 同步将 Hex 字符串转为 Base64
|
||||||
|
hexToBase64Sync(hex, mimeType) {
|
||||||
|
try {
|
||||||
|
// 将 Hex 字符串转为字节数组
|
||||||
|
const bytes = new Uint8Array(hex.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)));
|
||||||
|
|
||||||
|
// 同步转为二进制字符串
|
||||||
|
let binary = '';
|
||||||
|
for (let i = 0; i < bytes.byteLength; i++) {
|
||||||
|
binary += String.fromCharCode(bytes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 window.btoa 生成 base64
|
||||||
|
return `data:${mimeType};base64,${window.btoa(binary)}`;
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Hex to Base64 conversion failed', e);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 按照你要求的 XMLHttpRequest 格式编写
|
||||||
|
uploadSingleImage(base64Data, index) {
|
||||||
|
const _this = this;
|
||||||
|
//转为 Blob
|
||||||
|
const blob = _this.dataURLtoBlob(base64Data);
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
const formData = new FormData();
|
||||||
|
// 按照你截图中的参数名,这里假设是 'file'
|
||||||
|
formData.append('mainImage', blob, `word_img_${index}.png`);
|
||||||
|
formData.append('article_id', this.articleId);
|
||||||
|
xhr.withCredentials = false;
|
||||||
|
xhr.open('POST', _this.baseUrl + 'api/Preaccept/up_img_mainImage');
|
||||||
|
xhr.onload = function () {
|
||||||
|
if (xhr.status !== 200) {
|
||||||
|
console.error('HTTP Error: ' + xhr.status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const json = JSON.parse(xhr.responseText);
|
||||||
|
if (json.code === 0) {
|
||||||
|
// 2. 拼接服务器返回的 URL
|
||||||
|
const finalUrl = _this.mediaUrl + 'articleImage/' + json.data.upurl;
|
||||||
|
// 3. 找到对应的加载中占位图并替换
|
||||||
|
const doc = tinymce.activeEditor.getDoc();
|
||||||
|
const placeholder = doc.querySelector(`img[data-idx="${index}"]`);
|
||||||
|
if (placeholder) {
|
||||||
|
placeholder.src = finalUrl;
|
||||||
|
placeholder.removeAttribute('data-idx'); // 任务完成,移除标记
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('解析响应失败', e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
xhr.send(formData);
|
||||||
|
},
|
||||||
|
|
||||||
|
// 辅助工具:Base64 转 Blob
|
||||||
|
dataURLtoBlob(dataurl) {
|
||||||
|
const arr = dataurl.split(','),
|
||||||
|
mime = arr[0].match(/:(.*?);/)[1],
|
||||||
|
bstr = atob(arr[1]);
|
||||||
|
let n = bstr.length;
|
||||||
|
const u8arr = new Uint8Array(n);
|
||||||
|
while (n--) {
|
||||||
|
u8arr[n] = bstr.charCodeAt(n);
|
||||||
|
}
|
||||||
|
return new Blob([u8arr], { type: mime });
|
||||||
|
},
|
||||||
initTinymce() {
|
initTinymce() {
|
||||||
|
let globalImgCounter = 0; // 放在 init 闭包内,确保计数器持续增长
|
||||||
|
let currentPasteBase64Images = [];
|
||||||
var _this = this;
|
var _this = this;
|
||||||
window.tinymce.init({
|
window.tinymce.init({
|
||||||
|
..._this.tinymceOtherInit,
|
||||||
inline: false, // 使用 iframe 模式
|
inline: false, // 使用 iframe 模式
|
||||||
selector: `#${this.tinymceId}`,
|
selector: `#${this.tinymceId}`,
|
||||||
// noneditable_regexp: "/<wmath>.*?<\/wmath>/g",
|
// noneditable_regexp: "/<wmath>.*?<\/wmath>/g",
|
||||||
content_css: false, // 禁用默认样式
|
content_css: false, // 禁用默认样式
|
||||||
table_resize_bars: true, // 启用拖动调整功能
|
table_resize_bars: true, // 启用拖动调整功能
|
||||||
valid_elements: this.type == 'table' ? '*[*]' : 'img[src|alt|width|height],strong,em,sub,sup,blue,table,b,i,wmath', // 允许的标签和属性
|
valid_elements:
|
||||||
|
this.type == 'table'
|
||||||
|
? '*[*]'
|
||||||
|
: `img[src|alt|width|height],strong,em,sub,sup,blue,table,b,i,wmath${this.valid_elements}`, // 允许的标签和属性
|
||||||
// valid_elements: '*[*]', // 允许所有 HTML 标签
|
// valid_elements: '*[*]', // 允许所有 HTML 标签
|
||||||
noneditable_editable_class: 'MathJax',
|
noneditable_editable_class: 'MathJax',
|
||||||
height: this.height,
|
height: this.height,
|
||||||
paste_preprocess: function (plugin, args) {
|
|
||||||
let content = args.content; // 获取粘贴的内容
|
|
||||||
let tempDiv = document.createElement('div');
|
|
||||||
tempDiv.innerHTML = content;
|
|
||||||
if (tempDiv.querySelector('table')) {
|
|
||||||
console.log('粘贴的内容包含表格');
|
|
||||||
if (_this.type == 'table') {
|
|
||||||
_this.$commonJS.parseTableToArray(content, (tableList) => {
|
|
||||||
var contentHtml = `
|
|
||||||
<div class="thumbnailTableBox wordTableHtml table_Box" style="">
|
|
||||||
<table border="1" style="width: auto; border-collapse: collapse; text-align: center;">
|
|
||||||
${tableList
|
|
||||||
.map((row) => {
|
|
||||||
return `
|
|
||||||
<tr>
|
|
||||||
${row
|
|
||||||
.map((cell) => {
|
|
||||||
return `
|
|
||||||
<td colspan="${cell.colspan || 1}" rowspan="${cell.rowspan || 1}">
|
|
||||||
<span>${cell.text || ''}</span>
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
})
|
|
||||||
.join('')}
|
|
||||||
</tr>
|
|
||||||
`;
|
|
||||||
})
|
|
||||||
.join('')}
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
const container = document.createElement('div');
|
|
||||||
container.innerHTML = contentHtml;
|
|
||||||
|
|
||||||
// _this.updateTableStyles(container); // 根据需要应用额外的样式
|
|
||||||
args.content = container.innerHTML; // 更新处理后的内容
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('Original content:', content); // 输出原始粘贴内容
|
|
||||||
|
|
||||||
// 改进的正则表达式,匹配 $$...$$ 格式的 LaTeX 公式
|
|
||||||
const mathRegex = /\$\$([^$]+)\$\$/g;
|
|
||||||
|
|
||||||
// 如果粘贴的内容包含 $$...$$ 格式的公式,进行处理
|
|
||||||
content = content.replace(mathRegex, function (match, formula) {
|
|
||||||
console.log('Matched formula:', formula); // 输出每个匹配的公式
|
|
||||||
// 将公式包裹在 <wmath> 标签中,保留 $$...$$ 结构
|
|
||||||
return `<wmath data-latex="${match}">${match}</wmath>`;
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('Processed content:', content); // 输出处理后的内容
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新 args.content 为处理后的内容
|
|
||||||
|
|
||||||
// 阻止默认的粘贴行为,确保自定义处理优先执行
|
|
||||||
if (args.event) {
|
|
||||||
args.event.preventDefault();
|
|
||||||
args.event.stopPropagation();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_this.isAutomaticUpdate) {
|
|
||||||
args.content = _this.$commonJS.transformHtmlString(content); // 更新处理后的内容
|
|
||||||
} else {
|
|
||||||
args.content = content;
|
|
||||||
}
|
|
||||||
setTimeout(() => {
|
|
||||||
window.renderMathJax(_this.tinymceId);
|
|
||||||
}, 10);
|
|
||||||
},
|
|
||||||
|
|
||||||
content_style: `
|
content_style: `
|
||||||
${tableStyle}
|
${tableStyle}
|
||||||
${_this.wordStyle}
|
${_this.wordStyle}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
`,
|
`,
|
||||||
|
|
||||||
formats: {
|
formats: {
|
||||||
bold: { inline: 'b' },
|
bold: { inline: 'b' },
|
||||||
italic: { inline: 'i' }
|
italic: { inline: 'i' }
|
||||||
@@ -407,7 +418,6 @@ export default {
|
|||||||
statusbar: false, // 关闭底部状态栏
|
statusbar: false, // 关闭底部状态栏
|
||||||
custom_colors: false,
|
custom_colors: false,
|
||||||
color_map: ['0082AA', 'TMR Blue'],
|
color_map: ['0082AA', 'TMR Blue'],
|
||||||
|
|
||||||
// image
|
// image
|
||||||
plugins: 'texttransform noneditable table image', // 启用 forecolor 和 code 插件
|
plugins: 'texttransform noneditable table image', // 启用 forecolor 和 code 插件
|
||||||
// plugins: 'forecolor code paste table image mathType searchreplace raw', // 启用 forecolor 和 code 插件
|
// plugins: 'forecolor code paste table image mathType searchreplace raw', // 启用 forecolor 和 code 插件
|
||||||
@@ -419,81 +429,76 @@ export default {
|
|||||||
config: 'TeX-AMS-MML_HTMLorMML'
|
config: 'TeX-AMS-MML_HTMLorMML'
|
||||||
},
|
},
|
||||||
// automatic_uploads: false,
|
// automatic_uploads: false,
|
||||||
// images_upload_handler: function (blobInfo, success, failure, progress) {
|
images_upload_handler: function (blobInfo, progress) {
|
||||||
// console.log('blobInfo at line 419:', blobInfo);
|
return new Promise((resolve, reject) => {
|
||||||
// return new Promise(function (resolve, reject) {
|
const xhr = new XMLHttpRequest();
|
||||||
// const xhr = new XMLHttpRequest();
|
const formData = new FormData();
|
||||||
// const formData = new FormData();
|
const file = blobInfo.blob();
|
||||||
// const file = blobInfo.blob();
|
// 1. 处理文件名:优先使用原始文件名,没有则生成
|
||||||
// let filename = file.name;
|
let filename = blobInfo.filename() || `upload_${Date.now()}.png`;
|
||||||
// if (!filename) {
|
// 2. 构造符合你后端要求的参数
|
||||||
// // 如果没有名字,则手动生成一个
|
formData.append('mainImage', file, filename);
|
||||||
// const ext = file.type.split('/').pop(); // 从 MIME 类型获取扩展名,例如 'png'
|
// 优先从路由取 id,其次取 data 里的 articleId
|
||||||
// const timestamp = Date.now();
|
formData.append('article_id', _this.articleId);
|
||||||
// filename = `unnamed_${timestamp}.${ext}`;
|
xhr.withCredentials = false;
|
||||||
// }
|
// 拼接你的 baseUrl
|
||||||
// console.log('file at line 424:', file);
|
xhr.open('POST', _this.baseUrl + '/api/Preaccept/up_img_mainImage');
|
||||||
|
// 上传进度(可选)
|
||||||
|
xhr.upload.onprogress = (e) => {
|
||||||
|
progress((e.loaded / e.total) * 100);
|
||||||
|
};
|
||||||
|
xhr.onload = function () {
|
||||||
|
if (xhr.status !== 200) {
|
||||||
|
reject('HTTP Error: ' + xhr.status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const json = JSON.parse(xhr.responseText);
|
||||||
|
if (json.code === 0) {
|
||||||
|
// 3. 按照你的逻辑返回拼接后的完整 URL
|
||||||
|
const finalUrl = _this.mediaUrl + 'articleImage/' + json.data.upurl;
|
||||||
|
resolve(finalUrl);
|
||||||
|
console.log('手动上传成功:', finalUrl);
|
||||||
|
} else {
|
||||||
|
reject('Upload Error: ' + json.msg);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
reject('Invalid response: ' + xhr.responseText);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// xhr.withCredentials = false;
|
xhr.onerror = function () {
|
||||||
// xhr.open('POST', _this.baseUrl + '/api/Preaccept/up_img_mainImage');
|
reject('网络请求失败');
|
||||||
|
};
|
||||||
// xhr.onload = function () {
|
|
||||||
// if (xhr.status !== 200) {
|
|
||||||
// reject('HTTP Error: ' + xhr.status);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// try {
|
xhr.send(formData);
|
||||||
// const json = JSON.parse(xhr.responseText);
|
});
|
||||||
// console.log('json at line 434:', json);
|
},
|
||||||
// if (json.code != 0) {
|
|
||||||
// reject('Upload Error: ' + json.msg);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// resolve(_this.mediaUrl + 'articleImage/' + json.data.upurl); // ✅ 返回图片 URL 给 TinyMCE 插入
|
|
||||||
// } catch (e) {
|
|
||||||
// reject('Invalid response: ' + xhr.responseText);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// formData.append('mainImage', file, filename);
|
|
||||||
// formData.append('article_id', _this.$route.query.id);
|
|
||||||
// xhr.send(formData);
|
|
||||||
// });
|
|
||||||
// },
|
|
||||||
//设置自定义按钮 myCustomToolbarButton
|
//设置自定义按钮 myCustomToolbarButton
|
||||||
setup(ed) {
|
setup(ed) {
|
||||||
|
let currentPasteImages = [];
|
||||||
_this.$commonJS.initEditorButton(_this, ed);
|
_this.$commonJS.initEditorButton(_this, ed);
|
||||||
|
|
||||||
var currentWmathElement = null;
|
var currentWmathElement = null;
|
||||||
|
|
||||||
ed.on('click', function (e) {
|
ed.on('click', function (e) {
|
||||||
const wmathElement = e.target.closest('wmath');
|
const wmathElement = e.target.closest('wmath');
|
||||||
|
|
||||||
if (wmathElement) {
|
if (wmathElement) {
|
||||||
currentWmathElement = wmathElement; // 👈 保存当前点击的元素
|
currentWmathElement = wmathElement; // 👈 保存当前点击的元素
|
||||||
|
|
||||||
const latexContentRaw = wmathElement.getAttribute('data-latex') || '';
|
const latexContentRaw = wmathElement.getAttribute('data-latex') || '';
|
||||||
console.log('at line 488: raw =', latexContentRaw);
|
console.log('at line 488: raw =', latexContentRaw);
|
||||||
|
|
||||||
// 去除所有 $ 符号
|
// 去除所有 $ 符号
|
||||||
const latexContent = latexContentRaw.replace(/\$/g, '').trim();
|
const latexContent = latexContentRaw.replace(/\$/g, '').trim();
|
||||||
// console.log('at line 489: cleaned =', latexContent);
|
|
||||||
|
|
||||||
// 编码后用于传递到弹窗
|
// 编码后用于传递到弹窗
|
||||||
const encoded = encodeURIComponent(latexContent);
|
const encoded = encodeURIComponent(latexContent);
|
||||||
|
|
||||||
// 给 wmath 添加唯一 data-id,方便后续精准替换
|
// 给 wmath 添加唯一 data-id,方便后续精准替换
|
||||||
let wmathId = wmathElement.getAttribute('data-id');
|
let wmathId = wmathElement.getAttribute('data-id');
|
||||||
if (!wmathId) {
|
if (!wmathId) {
|
||||||
wmathId = 'wmath-' + Math.random().toString(36).substr(2, 9);
|
wmathId = 'wmath-' + Math.random().toString(36).substr(2, 9);
|
||||||
wmathElement.setAttribute('data-id', wmathId);
|
wmathElement.setAttribute('data-id', wmathId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 当前编辑器 ID 也保存下来(如果你有多个编辑器)
|
// 当前编辑器 ID 也保存下来(如果你有多个编辑器)
|
||||||
const editorId = ed.id;
|
const editorId = ed.id;
|
||||||
|
|
||||||
// 打开编辑窗口并传参(传递 data-id + 内容)
|
// 打开编辑窗口并传参(传递 data-id + 内容)
|
||||||
window.open(
|
window.open(
|
||||||
`/LateX?id=${encoded}&wmathId=${wmathId}&editorId=${editorId}`,
|
`/LateX?id=${encoded}&wmathId=${wmathId}&editorId=${editorId}`,
|
||||||
@@ -502,6 +507,17 @@ export default {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// 修改 paste 事件中的逻辑
|
||||||
|
ed.on('paste', (event) => {
|
||||||
|
const rtf = event.clipboardData.getData('text/rtf');
|
||||||
|
if (rtf && rtf.includes('\\pict')) {
|
||||||
|
const extracted = extractHexImagesFromRTF(rtf);
|
||||||
|
extracted.forEach((img, i) => {
|
||||||
|
const base64 = _this.hexToBase64Sync(img.hex, img.mimeType);
|
||||||
|
_this.uploadSingleImage(base64, i);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ed.ui.registry.addButton('uploadWord', {
|
ed.ui.registry.addButton('uploadWord', {
|
||||||
text: 'Word',
|
text: 'Word',
|
||||||
@@ -527,19 +543,12 @@ export default {
|
|||||||
input.click();
|
input.click();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ed.on('init', function () {
|
ed.on('init', function () {
|
||||||
_this.$commonJS.inTinymceButtonClass();
|
_this.$commonJS.inTinymceButtonClass();
|
||||||
const editorBody = ed.getBody();
|
const editorBody = ed.getBody();
|
||||||
|
|
||||||
// 监听点击事件来确保用户可以删除<wmath>元素
|
|
||||||
|
|
||||||
// 创建 MutationObserver 监听内容变化
|
|
||||||
const observer = new MutationObserver(() => {
|
const observer = new MutationObserver(() => {
|
||||||
const currentContent = ed.getContent();
|
const currentContent = ed.getContent();
|
||||||
// console.log('currentContent at line 484:', currentContent)
|
|
||||||
// console.log('currentContent at line 447:', currentContent);
|
|
||||||
|
|
||||||
if (_this.isAutomaticUpdate) {
|
if (_this.isAutomaticUpdate) {
|
||||||
_this.$emit('updateChange', currentContent);
|
_this.$emit('updateChange', currentContent);
|
||||||
// _this.$emit('updateChange', _this.$commonJS.decodeHtml(currentContent));
|
// _this.$emit('updateChange', _this.$commonJS.decodeHtml(currentContent));
|
||||||
@@ -606,6 +615,91 @@ export default {
|
|||||||
e.content = e.content.replace(/<i>/g, '<em>').replace(/<\/i>/g, '</em>');
|
e.content = e.content.replace(/<i>/g, '<em>').replace(/<\/i>/g, '</em>');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
paste_preprocess: function (plugin, args) {
|
||||||
|
let imgIdx = 0;
|
||||||
|
|
||||||
|
const silentPlaceholder = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
|
||||||
|
|
||||||
|
let content = args.content.replace(/(<img[^>]*?)src="file:\/\/\/[^" ]*"/gi, (match, p1) => {
|
||||||
|
// 保留 data-idx, Word 里的尺寸
|
||||||
|
return `${p1}src="${silentPlaceholder}" class="word-img-placeholder" data-idx="${imgIdx++}"`;
|
||||||
|
});
|
||||||
|
let tempDiv = document.createElement('div');
|
||||||
|
tempDiv.innerHTML = content;
|
||||||
|
if (tempDiv.querySelector('table')) {
|
||||||
|
console.log('粘贴的内容包含表格');
|
||||||
|
if (_this.type == 'table') {
|
||||||
|
// 3. 在这里直接消费外部变量 currentPasteBase64Images
|
||||||
|
// content = content.replace(new RegExp(`src="${silentPlaceholder}"`, 'gi'), () => {
|
||||||
|
// // 按顺序取图
|
||||||
|
// const base64Data = currentPasteBase64Images[globalImgCounter] || '';
|
||||||
|
// globalImgCounter++;
|
||||||
|
// return `src="${base64Data}"`;
|
||||||
|
// });
|
||||||
|
_this.$commonJS.parseTableToArray(content, (tableList) => {
|
||||||
|
var contentHtml = `
|
||||||
|
<div class="thumbnailTableBox wordTableHtml table_Box table_Box3333" style="">
|
||||||
|
<table border="1" style="width: auto; border-collapse: collapse; text-align: center;">
|
||||||
|
${tableList
|
||||||
|
.map((row) => {
|
||||||
|
return `
|
||||||
|
<tr>
|
||||||
|
${row
|
||||||
|
.map((cell) => {
|
||||||
|
return `
|
||||||
|
<td colspan="${cell.colspan || 1}" rowspan="${cell.rowspan || 1}">
|
||||||
|
<span>${cell.text || ''}</span>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
})
|
||||||
|
.join('')}
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
})
|
||||||
|
.join('')}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const container = document.createElement('div');
|
||||||
|
container.innerHTML = contentHtml;
|
||||||
|
|
||||||
|
// _this.updateTableStyles(container); // 根据需要应用额外的样式
|
||||||
|
args.content = container.innerHTML; // 更新处理后的内容
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('Original content:', content); // 输出原始粘贴内容
|
||||||
|
|
||||||
|
// 改进的正则表达式,匹配 $$...$$ 格式的 LaTeX 公式
|
||||||
|
const mathRegex = /\$\$([^$]+)\$\$/g;
|
||||||
|
|
||||||
|
// 如果粘贴的内容包含 $$...$$ 格式的公式,进行处理
|
||||||
|
content = content.replace(mathRegex, function (match, formula) {
|
||||||
|
console.log('Matched formula:', formula); // 输出每个匹配的公式
|
||||||
|
// 将公式包裹在 <wmath> 标签中,保留 $$...$$ 结构
|
||||||
|
return `<wmath data-latex="${match}">${match}</wmath>`;
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('Processed content:', content); // 输出处理后的内容
|
||||||
|
}
|
||||||
|
// 更新 args.content 为处理后的内容
|
||||||
|
// 阻止默认的粘贴行为,确保自定义处理优先执行
|
||||||
|
if (args.event) {
|
||||||
|
args.event.preventDefault();
|
||||||
|
args.event.stopPropagation();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_this.isAutomaticUpdate) {
|
||||||
|
args.content = _this.$commonJS.transformHtmlString(content); // 更新处理后的内容
|
||||||
|
} else {
|
||||||
|
args.content = content;
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
window.renderMathJax(_this.tinymceId);
|
||||||
|
}, 10);
|
||||||
|
},
|
||||||
init_instance_callback: (editor) => {
|
init_instance_callback: (editor) => {
|
||||||
if (_this.value) {
|
if (_this.value) {
|
||||||
editor.setContent(_this.value);
|
editor.setContent(_this.value);
|
||||||
@@ -694,19 +788,15 @@ export default {
|
|||||||
},
|
},
|
||||||
//设置内容
|
//设置内容
|
||||||
setContent(value) {
|
setContent(value) {
|
||||||
|
|
||||||
window.tinymce.get(this.tinymceId).setContent(value);
|
window.tinymce.get(this.tinymceId).setContent(value);
|
||||||
},
|
},
|
||||||
//获取内容
|
//获取内容
|
||||||
async getContent(type) {
|
async getContent(type) {
|
||||||
var content = window.tinymce.get(this.tinymceId).getContent();
|
var content = window.tinymce.get(this.tinymceId).getContent();
|
||||||
|
|
||||||
content = content.replace(/<span[^>]*>/g, '').replace(/<\/span>/g, ''); // 去除span标签
|
content = content.replace(/<span[^>]*>/g, '').replace(/<\/span>/g, ''); // 去除span标签
|
||||||
|
|
||||||
content = content.replace(/<strong>/g, '<b>').replace(/<\/strong>/g, '</b>');
|
content = content.replace(/<strong>/g, '<b>').replace(/<\/strong>/g, '</b>');
|
||||||
content = content.replace(/<em>/g, '<i>').replace(/<\/em>/g, '</i>');
|
content = content.replace(/<em>/g, '<i>').replace(/<\/em>/g, '</i>');
|
||||||
content = content.replace(/ /g, ' '); // 将所有 替换为空格
|
content = content.replace(/ /g, ' '); // 将所有 替换为空格
|
||||||
console.log('content at line 632:', content);
|
|
||||||
this.$emit('getContent', type, content);
|
this.$emit('getContent', type, content);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -817,4 +907,8 @@ export default {
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
::v-deep .tox:not(.tox-tinymce-inline) .tox-editor-header {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -452,7 +452,7 @@ export default {
|
|||||||
article_id: this.articleId
|
article_id: this.articleId
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
console.log('res at line 191:', res);
|
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
this.articleInfo = res.data.article_detail;
|
this.articleInfo = res.data.article_detail;
|
||||||
this.journalInfo = res.data.journal_detail;
|
this.journalInfo = res.data.journal_detail;
|
||||||
|
|||||||
@@ -353,7 +353,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
loading.close();
|
loading.close();
|
||||||
console.log('res at line 191:', res);
|
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
this.articleInfo = res.data.article_detail;
|
this.articleInfo = res.data.article_detail;
|
||||||
this.journalInfo = res.data.journal_detail;
|
this.journalInfo = res.data.journal_detail;
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ that.orderInfo=res.data.detail
|
|||||||
article_id: this.articleId
|
article_id: this.articleId
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
console.log('res at line 191:', res);
|
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
this.articleInfo = res.data.article_detail;
|
this.articleInfo = res.data.article_detail;
|
||||||
this.journalInfo = res.data.journal_detail;
|
this.journalInfo = res.data.journal_detail;
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ export default {
|
|||||||
.then((res) => {
|
.then((res) => {
|
||||||
loading.close();
|
loading.close();
|
||||||
this.paymentChecking = true;
|
this.paymentChecking = true;
|
||||||
console.log('res at line 191:', res);
|
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
this.articleBaseInfo = res.data.article_detail;
|
this.articleBaseInfo = res.data.article_detail;
|
||||||
this.journalBaseInfo = res.data.journal_detail;
|
this.journalBaseInfo = res.data.journal_detail;
|
||||||
@@ -169,7 +169,7 @@ export default {
|
|||||||
article_id: this.articleId
|
article_id: this.articleId
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
console.log('res at line 191:', res);
|
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
|
|
||||||
this.hideAlert();
|
this.hideAlert();
|
||||||
|
|||||||
@@ -577,7 +577,7 @@ export default {
|
|||||||
chekEmail(value) {
|
chekEmail(value) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.reviewerForm = {};
|
this.reviewerForm = {};
|
||||||
console.log('value at line 504:', value, this.reviewerForm);
|
|
||||||
if (value) {
|
if (value) {
|
||||||
this.chaSelChose({
|
this.chaSelChose({
|
||||||
email: value
|
email: value
|
||||||
@@ -602,7 +602,7 @@ export default {
|
|||||||
restaurants[i].value = restaurants[i].email;
|
restaurants[i].value = restaurants[i].email;
|
||||||
}
|
}
|
||||||
var results = value ? restaurants.filter(this.createMata(value)) : restaurants;
|
var results = value ? restaurants.filter(this.createMata(value)) : restaurants;
|
||||||
console.log('🚀 ~ .then ~ results177:', results);
|
|
||||||
// 调用 callback 返回建议列表的数据
|
// 调用 callback 返回建议列表的数据
|
||||||
cb(results);
|
cb(results);
|
||||||
// this.form.authorList[num].load = false;
|
// this.form.authorList[num].load = false;
|
||||||
@@ -659,8 +659,7 @@ export default {
|
|||||||
},
|
},
|
||||||
// 选中用户
|
// 选中用户
|
||||||
async chaSelChose(value, num) {
|
async chaSelChose(value, num) {
|
||||||
console.log('value at line 545:', value);
|
|
||||||
|
|
||||||
// console.log(value);
|
// console.log(value);
|
||||||
// console.log(num);
|
// console.log(num);
|
||||||
if (!this.addForm.email) {
|
if (!this.addForm.email) {
|
||||||
@@ -673,7 +672,7 @@ export default {
|
|||||||
email: this.addForm.email
|
email: this.addForm.email
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
console.log('res at line 554:', res);
|
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
this.btn_alert = false;
|
this.btn_alert = false;
|
||||||
this.reviewerForm = res.data.result;
|
this.reviewerForm = res.data.result;
|
||||||
@@ -735,7 +734,7 @@ export default {
|
|||||||
? item.shu.split(',').map(Number)
|
? item.shu.split(',').map(Number)
|
||||||
: [item.shu]
|
: [item.shu]
|
||||||
}));
|
}));
|
||||||
console.log('this.majorValueList at line 903:', this.majorValueList);
|
|
||||||
// if (this.reviewerForm.majorList) {
|
// if (this.reviewerForm.majorList) {
|
||||||
// if (this.reviewerForm.majorList.length >= 1) {
|
// if (this.reviewerForm.majorList.length >= 1) {
|
||||||
// this.reviewerForm.major_a = this.reviewerForm.majorList[0];
|
// this.reviewerForm.major_a = this.reviewerForm.majorList[0];
|
||||||
@@ -755,7 +754,7 @@ export default {
|
|||||||
// this.addForm.major = this.addForm.major_a;
|
// this.addForm.major = this.addForm.major_a;
|
||||||
// }
|
// }
|
||||||
this.$forceUpdate();
|
this.$forceUpdate();
|
||||||
console.log('this.addForm.majorList at line 674:', this.reviewerForm);
|
|
||||||
this.$nextTick(async () => {
|
this.$nextTick(async () => {
|
||||||
// await this.jiLInaoan();
|
// await this.jiLInaoan();
|
||||||
await this.getJournalsForReviewerInEditor();
|
await this.getJournalsForReviewerInEditor();
|
||||||
@@ -778,7 +777,7 @@ export default {
|
|||||||
// this.reviewerForm = {
|
// this.reviewerForm = {
|
||||||
// email: value.email
|
// email: value.email
|
||||||
// };
|
// };
|
||||||
console.log('value at line 529:', value, this.reviewerForm);
|
|
||||||
|
|
||||||
// this.$forceUpdate();
|
// this.$forceUpdate();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -351,7 +351,7 @@ export default {
|
|||||||
onAction: function () {
|
onAction: function () {
|
||||||
// 在选中的文本周围包裹 <blue> 标签
|
// 在选中的文本周围包裹 <blue> 标签
|
||||||
var selectedText = ed.selection.getContent();
|
var selectedText = ed.selection.getContent();
|
||||||
console.log('selectedText at line 529:', selectedText);
|
|
||||||
if (selectedText) {
|
if (selectedText) {
|
||||||
var wrappedText = `<blue>${selectedText}</blue>`;
|
var wrappedText = `<blue>${selectedText}</blue>`;
|
||||||
ed.selection.setContent(wrappedText);
|
ed.selection.setContent(wrappedText);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
<!-- image -->
|
<!-- image -->
|
||||||
<tinymce
|
<tinymce
|
||||||
type="table"
|
type="table"
|
||||||
|
:articleId="articleId"
|
||||||
ref="tinymceChild1"
|
ref="tinymceChild1"
|
||||||
:wordStyle="wordStyle"
|
:wordStyle="wordStyle"
|
||||||
@getContent="getContent"
|
@getContent="getContent"
|
||||||
@@ -33,7 +34,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import Tinymce from '@/components/page/components/Tinymce';
|
import Tinymce from '@/components/page/components/Tinymce';
|
||||||
export default {
|
export default {
|
||||||
props: ['lineStyle'],
|
props: ['lineStyle','articleId'],
|
||||||
components: {
|
components: {
|
||||||
Tinymce
|
Tinymce
|
||||||
},
|
},
|
||||||
|
|||||||
153
src/main.js
153
src/main.js
@@ -59,48 +59,48 @@ async function loadJournalType() {
|
|||||||
let parsedData = null;
|
let parsedData = null;
|
||||||
|
|
||||||
if (cachedString) {
|
if (cachedString) {
|
||||||
try {
|
try {
|
||||||
// 必须先解析 JSON 字符串
|
// 必须先解析 JSON 字符串
|
||||||
parsedData = JSON.parse(cachedString);
|
parsedData = JSON.parse(cachedString);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("缓存数据解析失败,将重新请求 API:", e);
|
console.error("缓存数据解析失败,将重新请求 API:", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 检查解析后的数据是否有效(是数组且长度大于 0)
|
// 2. 检查解析后的数据是否有效(是数组且长度大于 0)
|
||||||
if (parsedData && Array.isArray(parsedData) && parsedData.length > 0) {
|
if (parsedData && Array.isArray(parsedData) && parsedData.length > 0) {
|
||||||
// 缓存有效,直接返回缓存数据
|
// 缓存有效,直接返回缓存数据
|
||||||
return parsedData;
|
return parsedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 如果缓存无效或不存在,执行 API 调用
|
// 3. 如果缓存无效或不存在,执行 API 调用
|
||||||
try {
|
try {
|
||||||
// 第一个 API 调用,使用 await 接收结果
|
// 第一个 API 调用,使用 await 接收结果
|
||||||
const journalRes = await api.post('api/Articletype/getArticleType', {});
|
const journalRes = await api.post('api/Articletype/getArticleType', {});
|
||||||
if (journalRes.status === 1) {
|
if (journalRes.status === 1) {
|
||||||
// 存储 journal data
|
// 存储 journal data
|
||||||
localStorage.setItem('journalTypeData', JSON.stringify(journalRes.data.base));
|
localStorage.setItem('journalTypeData', JSON.stringify(journalRes.data.base));
|
||||||
localStorage.setItem('journalTypeDataAll', JSON.stringify([...journalRes.data.base, ...journalRes.data.supplement]));
|
localStorage.setItem('journalTypeDataAll', JSON.stringify([...journalRes.data.base, ...journalRes.data.supplement]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 第二个 API 调用,串行执行
|
// 第二个 API 调用,串行执行
|
||||||
const medicalRes = await api.post('api/Articletype/getMedicalType', {});
|
const medicalRes = await api.post('api/Articletype/getMedicalType', {});
|
||||||
if (medicalRes.status === 1) {
|
if (medicalRes.status === 1) {
|
||||||
// 存储 medical data
|
// 存储 medical data
|
||||||
localStorage.setItem('opMedicalListData', JSON.stringify(medicalRes.data));
|
localStorage.setItem('opMedicalListData', JSON.stringify(medicalRes.data));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 返回第一个 API 调用的主要数据
|
// 4. 返回第一个 API 调用的主要数据
|
||||||
if (journalRes.status === 1) {
|
if (journalRes.status === 1) {
|
||||||
return journalRes.data.base;
|
return journalRes.data.base;
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 集中处理 API 调用失败
|
// 集中处理 API 调用失败
|
||||||
console.error('Error loading data:', error);
|
console.error('Error loading data:', error);
|
||||||
return []; // 失败时返回一个默认的空数组,避免程序崩溃
|
return []; // 失败时返回一个默认的空数组,避免程序崩溃
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果所有流程都没有返回,默认返回空数组
|
// 如果所有流程都没有返回,默认返回空数组
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -110,7 +110,7 @@ async function loadJournalType() {
|
|||||||
async function loadJournalList() {
|
async function loadJournalList() {
|
||||||
try {
|
try {
|
||||||
const localData = store.state.journalList;
|
const localData = store.state.journalList;
|
||||||
|
|
||||||
if (localData && Array.isArray(localData) && localData.length > 0) {
|
if (localData && Array.isArray(localData) && localData.length > 0) {
|
||||||
return localData;
|
return localData;
|
||||||
}
|
}
|
||||||
@@ -171,51 +171,36 @@ Vue.filter('jtName', function (value) {
|
|||||||
// 使用 ES Module
|
// 使用 ES Module
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
Vue.prototype.$echarts = echarts
|
Vue.prototype.$echarts = echarts
|
||||||
|
|
||||||
|
|
||||||
Vue.prototype.$api = api
|
Vue.prototype.$api = api
|
||||||
|
|
||||||
Vue.config.productionTip = false;
|
Vue.config.productionTip = false;
|
||||||
|
|
||||||
import Editor from "@tinymce/tinymce-vue"; // 默认导入
|
import Editor from "@tinymce/tinymce-vue"; // 默认导入
|
||||||
|
|
||||||
Vue.component("Editor", Editor);
|
Vue.component("Editor", Editor);
|
||||||
|
//自定义组件
|
||||||
|
const components = {
|
||||||
|
'common-table': () => import('@/components/page/components/table/table.vue'),
|
||||||
|
'common-review-article': () => import('@/components/page/components/reviewArticle/index.vue'),
|
||||||
|
'common-editor-article': () => import('@/components/page/components/EditorArticle/index.vue'),
|
||||||
|
'common-editor-article-detail': () => import('@/components/page/components/EditorArticle/detail.vue'),
|
||||||
|
'common-late-x': () => import('@/components/page/components/table/LateX.vue'),
|
||||||
|
'common-major': () => import('@/components/page/components/major/index.vue'),
|
||||||
|
'common-major-list': () => import('@/components/page/components/major/list.vue'),
|
||||||
|
'common-paypal-button': () => import('@/components/page/components/pendingPayment/PayPalButton.vue'),
|
||||||
|
'common-tiff': () => import('@/components/page/components/table/tiff.vue'),
|
||||||
|
'common-content': () => import('@/components/page/components/table/content.vue'),
|
||||||
|
'common-word': () => import('@/components/page/components/table/word.vue'),
|
||||||
|
'common-comment': () => import('@/components/page/components/table/comment.vue'),
|
||||||
|
'common-edit-table': () => import('@/components/page/components/table/editTable.vue'),
|
||||||
|
'common-annotations': () => import('@/components/page/components/table/annotations.vue'),
|
||||||
|
'common-word-html': () => import('@/components/page/components/table/wordHtml.vue'),
|
||||||
|
'common-word-html-type-setting': () => import('@/components/page/components/table/wordHtmlTypesetting.vue'),
|
||||||
|
'common-drag-word': () => import('@/components/page/components/table/dragWord.vue'),
|
||||||
|
};
|
||||||
|
|
||||||
import commonTable from '@/components/page/components/table/table.vue'
|
Object.keys(components).forEach(key => {
|
||||||
Vue.component('common-table', commonTable);
|
Vue.component(key, components[key]);
|
||||||
import commonReviewArticle from '@/components/page/components/reviewArticle/index.vue'
|
});
|
||||||
Vue.component('common-review-article', commonReviewArticle);
|
|
||||||
import commonEditorArticle from '@/components/page/components/EditorArticle/index.vue'
|
|
||||||
Vue.component('common-editor-article', commonEditorArticle);
|
|
||||||
import commonEditorArticleDetail from '@/components/page/components/EditorArticle/detail.vue'
|
|
||||||
Vue.component('common-editor-article-detail', commonEditorArticleDetail);
|
|
||||||
import commonLateX from '@/components/page/components/table/LateX.vue'
|
|
||||||
Vue.component('common-late-x', commonLateX);
|
|
||||||
import commonMajor from '@/components/page/components/major/index.vue'
|
|
||||||
Vue.component('common-major', commonMajor);
|
|
||||||
import commonMajorList from '@/components/page/components/major/list.vue'
|
|
||||||
Vue.component('common-major-list', commonMajorList);
|
|
||||||
import commonPayPalButton from '@/components/page/components/pendingPayment/PayPalButton.vue'
|
|
||||||
Vue.component('common-paypal-button', commonPayPalButton);
|
|
||||||
import commonTiff from '@/components/page/components/table/tiff.vue'
|
|
||||||
Vue.component('common-tiff', commonTiff);
|
|
||||||
import commonContent from '@/components/page/components/table/content.vue'
|
|
||||||
Vue.component('common-content', commonContent);
|
|
||||||
import commonWord from '@/components/page/components/table/word.vue'
|
|
||||||
Vue.component('common-comment', commonComment);
|
|
||||||
import commonEditTable from '@/components/page/components/table/editTable.vue'
|
|
||||||
Vue.component('common-edit-table', commonEditTable);
|
|
||||||
import commonComment from '@/components/page/components/table/comment.vue'
|
|
||||||
Vue.component('common-word', commonWord);
|
|
||||||
import commonAnnotations from '@/components/page/components/table/annotations.vue'
|
|
||||||
Vue.component('common-annotations', commonAnnotations);
|
|
||||||
import commonWordHtml from '@/components/page/components/table/wordHtml.vue'
|
|
||||||
Vue.component('common-word-html', commonWordHtml);
|
|
||||||
import commonWordHtmlTypesetting from '@/components/page/components/table/wordHtmlTypesetting.vue'
|
|
||||||
Vue.component('common-word-html-type-setting', commonWordHtmlTypesetting);
|
|
||||||
|
|
||||||
|
|
||||||
import commonDragWord from '@/components/page/components/table/dragWord.vue'
|
|
||||||
Vue.component('common-drag-word', commonDragWord);
|
|
||||||
Vue.use(VueI18n);
|
Vue.use(VueI18n);
|
||||||
Vue.use(ElementUI, {
|
Vue.use(ElementUI, {
|
||||||
size: 'small',
|
size: 'small',
|
||||||
@@ -228,22 +213,22 @@ const i18n = new VueI18n({
|
|||||||
//使用钩子函数对路由进行权限跳转
|
//使用钩子函数对路由进行权限跳转
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
const currentRoute = to; // 获取当前路由路径,例如 "/home"
|
const currentRoute = to; // 获取当前路由路径,例如 "/home"
|
||||||
console.log('currentRoute at line 211:', currentRoute.meta)
|
|
||||||
if(currentRoute.meta.hideJournal){
|
|
||||||
|
|
||||||
}else{
|
|
||||||
try {
|
|
||||||
// 尝试请求接口(即使失败也继续后续逻辑)
|
|
||||||
await Promise.all([
|
|
||||||
loadJournalList(),
|
|
||||||
loadJournalType()
|
|
||||||
]);
|
|
||||||
} catch (err) {
|
|
||||||
// 仅打印错误,不阻断路由
|
|
||||||
|
|
||||||
}
|
if (currentRoute.meta.hideJournal) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
// 尝试请求接口(即使失败也继续后续逻辑)
|
||||||
|
await Promise.all([
|
||||||
|
loadJournalList(),
|
||||||
|
loadJournalType()
|
||||||
|
]);
|
||||||
|
} catch (err) {
|
||||||
|
// 仅打印错误,不阻断路由
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 无论接口成功/失败,都执行原有跳转逻辑
|
// 无论接口成功/失败,都执行原有跳转逻辑
|
||||||
document.title = `${to.meta.title} | Traditional Medicine Research`;
|
document.title = `${to.meta.title} | Traditional Medicine Research`;
|
||||||
|
|||||||
50
src/utils/rtfParser.js
Normal file
50
src/utils/rtfParser.js
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* 从 RTF 字符串中提取图片并返回 Hex 数组
|
||||||
|
*/
|
||||||
|
export function extractHexImagesFromRTF(rtfData) {
|
||||||
|
|
||||||
|
const images = [];
|
||||||
|
if (!rtfData) return images;
|
||||||
|
|
||||||
|
// 1. 按照图片起始符切分
|
||||||
|
const blocks = rtfData.split('\\pict');
|
||||||
|
|
||||||
|
for (let i = 1; i < blocks.length; i++) {
|
||||||
|
const block = blocks[i];
|
||||||
|
|
||||||
|
// 2. 识别格式
|
||||||
|
let mimeType = '';
|
||||||
|
if (block.includes('\\pngblip')) mimeType = 'image/png';
|
||||||
|
else if (block.includes('\\jpegblip')) mimeType = 'image/jpeg';
|
||||||
|
else continue;
|
||||||
|
|
||||||
|
// 3. 暴力匹配:寻找块中所有连续的 0-9a-f 字符(忽略空格和换行)
|
||||||
|
// 我们找的是最短长度超过 128 位的字符串,这通常就是图片主体
|
||||||
|
const allHexGroups = block.match(/[0-9a-fA-F\s\r\n]{128,}/g);
|
||||||
|
|
||||||
|
if (allHexGroups) {
|
||||||
|
// 取这一组里最长的那段(防止误删中间的控制符)
|
||||||
|
const longestHex = allHexGroups.sort((a, b) => b.length - a.length)[0];
|
||||||
|
const cleanHex = longestHex.replace(/[\s\r\n]/g, '');
|
||||||
|
|
||||||
|
if (cleanHex.length > 256) { // 再次校验长度
|
||||||
|
images.push({
|
||||||
|
mimeType: mimeType,
|
||||||
|
hex: cleanHex
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return images;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 将 Hex 转换为 Blob
|
||||||
|
*/
|
||||||
|
export function hexToBlob(hexString, type) {
|
||||||
|
|
||||||
|
const bytes = new Uint8Array(hexString.length / 2);
|
||||||
|
for (let i = 0; i < hexString.length; i += 2) {
|
||||||
|
bytes[i / 2] = parseInt(hexString.substr(i, 2), 16);
|
||||||
|
}
|
||||||
|
return new Blob([bytes], { type });
|
||||||
|
}
|
||||||
@@ -76,8 +76,8 @@ module.exports = {
|
|||||||
// target: 'http://192.168.110.110/tougao/public/index.php/',
|
// target: 'http://192.168.110.110/tougao/public/index.php/',
|
||||||
// target: 'http://api.tmrjournals.com/public/index.php/',//正式
|
// target: 'http://api.tmrjournals.com/public/index.php/',//正式
|
||||||
// target: 'http://zmzm.tougao.dev.com/',//晓玲
|
// target: 'http://zmzm.tougao.dev.com/',//晓玲
|
||||||
target: 'https://submission.tmrjournals.com/',//正式
|
// target: 'https://submission.tmrjournals.com/',//正式
|
||||||
// target: 'http://tougaotest.tmrjournals.com/public/index.php/',//测试环境
|
target: 'http://tougaotest.tmrjournals.com/public/index.php/',//测试环境
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
pathRewrite: {
|
pathRewrite: {
|
||||||
'^/api': ''
|
'^/api': ''
|
||||||
|
|||||||
Reference in New Issue
Block a user