Merge branch 'master' of https://git.nuttyreading.com/wangjinlei/tougao_web into Editorial-Board
This commit is contained in:
@@ -1149,9 +1149,9 @@ a {
|
||||
mso-border-top-alt: none !important;
|
||||
border-bottom: none !important;
|
||||
mso-border-bottom-alt: none !important;
|
||||
border: 1px dashed #dcdfe6 !important;
|
||||
/* border: 1px dashed #dcdfe6 !important;
|
||||
border-left: 1px dashed #dcdfe6 !important;
|
||||
border-right: 1px dashed #dcdfe6 !important;
|
||||
border-right: 1px dashed #dcdfe6 !important; */
|
||||
word-break: keep-all !important;
|
||||
/* text-align: justify !important; */
|
||||
}
|
||||
@@ -1283,7 +1283,7 @@ a {
|
||||
}
|
||||
|
||||
.word-container table tbody tr td {
|
||||
text-align: left !important;
|
||||
text-align: center !important;
|
||||
border-left: none !important;
|
||||
mso-border-left-alt: none !important;
|
||||
border-right: none !important;
|
||||
@@ -1292,9 +1292,9 @@ a {
|
||||
mso-border-top-alt: none !important;
|
||||
border-bottom: none !important;
|
||||
mso-border-bottom-alt: none !important;
|
||||
border: 1px dashed #dcdfe6 !important;
|
||||
/* border: 1px dashed #dcdfe6 !important;
|
||||
border-left: 1px dashed #dcdfe6 !important;
|
||||
border-right: 1px dashed #dcdfe6 !important;
|
||||
border-right: 1px dashed #dcdfe6 !important; */
|
||||
word-break: keep-all !important;
|
||||
white-space: pre-wrap !important;
|
||||
/* text-align: justify !important; */
|
||||
|
||||
102
src/common/js/TableUtils.js
Normal file
102
src/common/js/TableUtils.js
Normal file
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* 表格数据处理工具
|
||||
*/
|
||||
export const TableUtils = {
|
||||
/**
|
||||
* 判断是否为表头行
|
||||
* @param {number} rowIndex
|
||||
* @param {Array} table
|
||||
*/
|
||||
isHeaderRow(rowIndex, table) {
|
||||
if (!table || table.length === 0) return false;
|
||||
const head = table[0];
|
||||
// 健壮性检查:确保第一行第一个单元格存在且有rowspan
|
||||
const headerSpan = (head && head[0] && head[0].rowspan) ? head[0].rowspan : 1;
|
||||
return rowIndex < headerSpan;
|
||||
},
|
||||
|
||||
/**
|
||||
* 拆分表头和表体
|
||||
*/
|
||||
splitTable(tableList) {
|
||||
if (!Array.isArray(tableList) || tableList.length === 0) {
|
||||
return { header: [], content: [] };
|
||||
}
|
||||
|
||||
const header = [];
|
||||
const content = [];
|
||||
let cellIdCounter = 0;
|
||||
|
||||
tableList.forEach((row, rowIndex) => {
|
||||
if (Array.isArray(row)) {
|
||||
row.forEach((cell) => {
|
||||
if (cell && typeof cell === 'object') {
|
||||
cell.cellId = `cell-${cellIdCounter++}`;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (this.isHeaderRow(rowIndex, tableList)) {
|
||||
header.push(row);
|
||||
} else {
|
||||
content.push(row);
|
||||
}
|
||||
});
|
||||
|
||||
return { header, content };
|
||||
},
|
||||
|
||||
/**
|
||||
* 处理合并单元格后的逻辑行 ID(用于斑马纹等)
|
||||
*/
|
||||
addRowIdToData(content) {
|
||||
if (!content || content.length === 0) return { rowData: [], rowIds: [] };
|
||||
|
||||
const data = JSON.parse(JSON.stringify(content));
|
||||
const rowIdMap = {};
|
||||
const usedRows = new Set();
|
||||
let idCounter = 0;
|
||||
|
||||
// 1. 建立逻辑行映射
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
if (usedRows.has(i)) continue;
|
||||
|
||||
const rowId = `row-${idCounter++}`;
|
||||
rowIdMap[i] = rowId;
|
||||
usedRows.add(i);
|
||||
|
||||
const row = data[i];
|
||||
for (let j = 0; j < row.length; j++) {
|
||||
const cell = row[j];
|
||||
if (cell && cell.rowspan > 1) {
|
||||
for (let k = 1; k < cell.rowspan; k++) {
|
||||
const nextRowIndex = i + k;
|
||||
if (nextRowIndex < data.length && !rowIdMap[nextRowIndex]) {
|
||||
rowIdMap[nextRowIndex] = rowId;
|
||||
usedRows.add(nextRowIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 注入 rowId 并提取唯一 ID 列表
|
||||
const seenIds = [];
|
||||
data.forEach((row, i) => {
|
||||
const rowId = rowIdMap[i];
|
||||
row.rowId = rowId; // 直接赋值给行对象
|
||||
row.forEach(cell => {
|
||||
if (cell) cell.rowId = rowId;
|
||||
});
|
||||
|
||||
if (rowId && !seenIds.includes(rowId)) {
|
||||
seenIds.push(rowId);
|
||||
}
|
||||
});
|
||||
|
||||
// 取奇数或偶数 ID 用于斑马纹(根据你的需求 index % 2 === 0)
|
||||
const rowIds = seenIds.filter((_, index) => index % 2 === 0);
|
||||
|
||||
return { rowData: data, rowIds };
|
||||
}
|
||||
};
|
||||
@@ -1307,16 +1307,19 @@ export default {
|
||||
},
|
||||
handleImageAdd(type) {
|
||||
this.picStyle = { note: '', picUrl: '', title: '' };
|
||||
this.picStyle1 = { note: '', picUrl: '', title: '' };
|
||||
this.picStyle.visiTitle = 'Add Figure';
|
||||
this.pictVisible = true;
|
||||
},
|
||||
handleTableAdd(type) {
|
||||
this.lineStyle = { note: '', table_data: '', html_data: '' };
|
||||
this.lineStyle1 = { note: '', table_data: '', html_data: '' };
|
||||
this.lineStyle.visiTitle = 'Add Table';
|
||||
this.threeVisible = true;
|
||||
},
|
||||
addUploadWordTable(data) {
|
||||
this.lineStyle = { note: '', table: data.table_data, html_data: data.html_data };
|
||||
this.lineStyle1 = { note: '', table: data.table_data, html_data: data.html_data };
|
||||
|
||||
this.lineStyle.visiTitle = 'Add Table';
|
||||
this.threeVisible = true;
|
||||
@@ -1330,13 +1333,18 @@ export default {
|
||||
this.pictVisible = true;
|
||||
} else if (type == 'table') {
|
||||
this.lineStyle = {};
|
||||
this.lineStyle = {
|
||||
this.lineStyle1 = {};
|
||||
// 1. 提取处理逻辑
|
||||
const formattedData = {
|
||||
...data,
|
||||
table: JSON.parse(data.table_data),
|
||||
html_data: data.html_data,
|
||||
note: data.note,
|
||||
title: data.title
|
||||
// 如果 data 中已经包含了 html_data, note, title,且不需要特殊处理,
|
||||
// 解构赋值 (...data) 其实已经把它们带进来了。
|
||||
};
|
||||
|
||||
// 2. 统一赋值
|
||||
this.lineStyle = formattedData;
|
||||
this.lineStyle1 = { ...formattedData }; // 使用浅拷贝确保两个变量指向不同引用(如果需要独立修改)
|
||||
this.lineStyle.visiTitle = 'Edit Table';
|
||||
this.threeVisible = true;
|
||||
}
|
||||
|
||||
@@ -135,6 +135,9 @@
|
||||
<template slot="comment">
|
||||
<div style="" class="commentList annotations"></div>
|
||||
</template>
|
||||
<template slot="refrences">
|
||||
<div style="" class="" main-id="References">222</div>
|
||||
</template>
|
||||
</common-word>
|
||||
</div>
|
||||
</div>
|
||||
@@ -603,6 +606,7 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
async copyArray(data) {
|
||||
try {
|
||||
// 将数组内容转换为字符串,使用换行符分隔
|
||||
@@ -1524,7 +1528,7 @@ export default {
|
||||
for (let i = 0; i < this.Main_List.length; i++) {
|
||||
this.Main_List[i].text = this.Main_List[i].content;
|
||||
this.Main_List[i].getnum = 0;
|
||||
// this.Main_List[i].checked = false;
|
||||
|
||||
}
|
||||
|
||||
// setTimeout(async () => {
|
||||
|
||||
@@ -1,26 +1,20 @@
|
||||
<template>
|
||||
<div class="ManuscirptList">
|
||||
|
||||
|
||||
<div class="arrlist">
|
||||
<ul class="catalogue-ul">
|
||||
<li class="catalogue-li">
|
||||
<div
|
||||
style=""
|
||||
class="ManuscirptList"
|
||||
>
|
||||
|
||||
<div
|
||||
style=""
|
||||
class="arrlist"
|
||||
>
|
||||
<ul style="width: 100%; height: auto">
|
||||
|
||||
|
||||
<li >
|
||||
<div style="">
|
||||
<div @click="goToListComment(item.am_id,'content')"
|
||||
@click="goToListComment(item.am_id,'content')"
|
||||
v-for="(item, index) in catalogueList"
|
||||
:key="index"
|
||||
:class="['catalogue-item', 'level-' + item.level]"
|
||||
style=""
|
||||
>
|
||||
<div class="title-content-wrapper">
|
||||
<div class="title-content" v-html="item.content"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -86,7 +80,7 @@ export default {
|
||||
|
||||
|
||||
this.catalogueList = this.content.filter(item => {
|
||||
return item.is_h1 == 1 || item.is_h2 == 1 || item.is_h3 == 1;
|
||||
return item.is_h1 == 1 || item.is_h2 == 1 ;
|
||||
}).map(item => {
|
||||
// 增加一个 level 字段进行标记
|
||||
let level = 1;
|
||||
@@ -98,8 +92,8 @@ this.catalogueList = this.content.filter(item => {
|
||||
};
|
||||
})
|
||||
this.catalogueList=[...this.catalogueList,{
|
||||
am_id:'reference',
|
||||
content:'<b><i>References</i></b>',
|
||||
am_id:'References',
|
||||
content:'References',
|
||||
|
||||
level:1,
|
||||
}]
|
||||
@@ -478,57 +472,146 @@ console.log(this.catalogueList,'catalogueList')
|
||||
|
||||
<style scoped>
|
||||
.ManuscirptList {
|
||||
padding-top: 20px;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
background: #f5f5f5 !important;
|
||||
background-color: #f5f5f5 !important; /* Word 导航栏通常是白色的 */
|
||||
border-right: 1px solid #e1e1e1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.catalogue-item{
|
||||
width: 90%;
|
||||
white-space: nowrap; /* 强制不换行 */
|
||||
overflow: hidden; /* 隐藏超出部分 */
|
||||
text-overflow: ellipsis; /* 超出部分显示... */
|
||||
box-sizing: border-box;
|
||||
|
||||
/* 模拟 Word 导航标题 */
|
||||
.word-navigation-header {
|
||||
padding: 12px 16px 0 16px;
|
||||
font-size: 14px;
|
||||
color: rgb(51, 51, 51);
|
||||
color: #333;
|
||||
font-family: "Segoe UI", "Microsoft YaHei", sans-serif;
|
||||
}
|
||||
|
||||
.word-tabs {
|
||||
display: flex;
|
||||
margin-top: 10px;
|
||||
border-bottom: 1px solid #e1e1e1;
|
||||
}
|
||||
|
||||
.word-tabs span {
|
||||
padding: 4px 12px;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
padding: 4px 0px;
|
||||
margin-left: 16px;
|
||||
font-family: "Charis SIL";
|
||||
word-wrap: break-word;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.word-tabs span.active {
|
||||
color: #2b579a; /* Word 经典蓝色 */
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.word-tabs span.active::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: -1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background-color: #2b579a;
|
||||
}
|
||||
|
||||
/* 列表容器 */
|
||||
.arrlist {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
.catalogue-ul {
|
||||
width: 100%;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 基础条目样式 - 模拟 Word 悬浮效果 */
|
||||
.catalogue-item {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding: 6px 16px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
box-sizing: border-box;
|
||||
transition: background-color 0.1s;
|
||||
}
|
||||
|
||||
.catalogue-item:hover {
|
||||
background-color: #eff3f9; /* Word 淡淡的选中蓝 */
|
||||
}
|
||||
|
||||
/* Word 样式的左侧小箭头 */
|
||||
.word-icon-arrow {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 5px solid #666;
|
||||
border-top: 4px solid transparent;
|
||||
border-bottom: 4px solid transparent;
|
||||
margin-right: 8px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.title-content-wrapper {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
.title-content,
|
||||
.title-content span,
|
||||
.title-content b {
|
||||
display: inline; /* 强制内部标签不换行 */
|
||||
font-weight: inherit; /* 继承父级的粗细设置,或者根据需要自定 */
|
||||
font-size: inherit;
|
||||
}
|
||||
.catalogue-item:hover {
|
||||
background-color: #e6f7ff;
|
||||
color: #1890ff;
|
||||
|
||||
/* 重点:Word 常用排版字体 */
|
||||
.title-content {
|
||||
font-weight: bold !important;
|
||||
font-style: normal !important;
|
||||
font-size: 15px;
|
||||
line-height: 1.3;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
/* Times New Roman 增加学术感 */
|
||||
font-family: "Times New Roman", "Charis SIL", "serif";
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* 一级标题:加粗,无缩进 */
|
||||
/* 保持 v-html 内部样式 */
|
||||
::v-deep .title-content b { font-weight: bold; }
|
||||
::v-deep .title-content i { font-style: italic; }
|
||||
|
||||
/* --- Word 风格的层级缩进 --- */
|
||||
|
||||
/* 1级标题 */
|
||||
.level-1 {
|
||||
font-weight: bold;
|
||||
|
||||
padding-left: 0;
|
||||
/* margin-top: 8px; */
|
||||
padding-left: 16px;
|
||||
/* font-style: italic; */
|
||||
}
|
||||
|
||||
/* 二级标题:标准字体,缩进 20px */
|
||||
/* 2级标题 */
|
||||
.level-2 {
|
||||
|
||||
padding-left: 20px;
|
||||
color: #555;
|
||||
padding-left: 36px;
|
||||
}
|
||||
.level-2 .title-content {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 三级标题:稍细字体,缩进 40px */
|
||||
/* 3级标题 */
|
||||
.level-3 {
|
||||
padding-left: 56px;
|
||||
}
|
||||
.level-3 .title-content {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
padding-left: 40px;
|
||||
color: #888;
|
||||
font-style: italic; /* 模仿 Word 的一些三级样式 */
|
||||
/* 隐藏滚动条 */
|
||||
.arrlist::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
}
|
||||
.arrlist::-webkit-scrollbar-thumb {
|
||||
background: #cdcdcd;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -9,7 +9,10 @@ import htmlDocx from 'html-docx-js/dist/html-docx.js';
|
||||
import { Document, Packer, PageOrientation, Paragraph, TextRun } from 'docx'; // 引入 docx.js
|
||||
import html2canvas from 'html2canvas';
|
||||
|
||||
const tableStyle = ` b span{
|
||||
const tableStyle = `*{
|
||||
font-family: 'Charis SIL';
|
||||
}
|
||||
b span{
|
||||
font-weight: bold !important;
|
||||
}
|
||||
i span{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user