表格参考文献的预览
This commit is contained in:
169
src/common/js/citeTablePreview.js
Normal file
169
src/common/js/citeTablePreview.js
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
/**
|
||||||
|
* 表格弹窗预览:将单元格内空 mycite 转为可见 [n],与 word.vue renderCiteLabels 一致(纯函数,无 Vue 依赖)
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function formatCiteNumbers(nums) {
|
||||||
|
if (!nums || !nums.length) return '';
|
||||||
|
const sorted = [...new Set(nums)].sort((a, b) => a - b);
|
||||||
|
const result = [];
|
||||||
|
let i = 0;
|
||||||
|
while (i < sorted.length) {
|
||||||
|
let j = i;
|
||||||
|
while (j < sorted.length - 1 && sorted[j + 1] === sorted[j] + 1) j++;
|
||||||
|
if (j - i >= 2) {
|
||||||
|
result.push(`${sorted[i]}–${sorted[j]}`);
|
||||||
|
} else {
|
||||||
|
for (let k = i; k <= j; k++) result.push(sorted[k]);
|
||||||
|
}
|
||||||
|
i = j + 1;
|
||||||
|
}
|
||||||
|
return result.join(', ');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sortAutociteIdsByCiteNumber(ids, citeMap) {
|
||||||
|
const map = citeMap || {};
|
||||||
|
const uniq = [...new Set(ids.map(String))];
|
||||||
|
return uniq.sort((a, b) => {
|
||||||
|
const na = map[a];
|
||||||
|
const nb = map[b];
|
||||||
|
const ha = na != null && na !== '';
|
||||||
|
const hb = nb != null && nb !== '';
|
||||||
|
if (ha && hb) return Number(na) - Number(nb);
|
||||||
|
if (ha) return -1;
|
||||||
|
if (hb) return 1;
|
||||||
|
return String(a).localeCompare(String(b));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Array} refs - chanFerForm,项含 p_refer_id
|
||||||
|
* @param {Array<string|number>} bodyCiteIdOrder - 正文首次出现顺序;空则按列表行序 1..n
|
||||||
|
*/
|
||||||
|
export function buildCiteMapFromRefs(refs, bodyCiteIdOrder) {
|
||||||
|
const refList = Array.isArray(refs) ? refs : [];
|
||||||
|
const refIdSet = new Set(
|
||||||
|
refList.map((r) => (r && r.p_refer_id != null ? String(r.p_refer_id) : '')).filter(Boolean)
|
||||||
|
);
|
||||||
|
|
||||||
|
let orderedIds = [];
|
||||||
|
if (Array.isArray(bodyCiteIdOrder) && bodyCiteIdOrder.length > 0) {
|
||||||
|
orderedIds = bodyCiteIdOrder.map(String);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orderedIds.length === 0) {
|
||||||
|
const map = {};
|
||||||
|
refList.forEach((row, idx) => {
|
||||||
|
const key = row && row.p_refer_id != null ? String(row.p_refer_id) : '';
|
||||||
|
if (key) map[key] = idx + 1;
|
||||||
|
});
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
const filtered = [];
|
||||||
|
orderedIds.forEach((id) => {
|
||||||
|
if (refIdSet.has(id) && !filtered.includes(id)) filtered.push(id);
|
||||||
|
});
|
||||||
|
const map = {};
|
||||||
|
filtered.forEach((id, idx) => {
|
||||||
|
map[id] = idx + 1;
|
||||||
|
});
|
||||||
|
let next = filtered.length + 1;
|
||||||
|
refList.forEach((r) => {
|
||||||
|
const key = r && r.p_refer_id != null ? String(r.p_refer_id) : '';
|
||||||
|
if (!key || map[key] != null) return;
|
||||||
|
map[key] = next++;
|
||||||
|
});
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
function escAttr(s) {
|
||||||
|
return String(s || '')
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/</g, '<');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} html
|
||||||
|
* @param {Array} refs - chanFerForm
|
||||||
|
* @param {Object} citeMap - p_refer_id -> 显示序号
|
||||||
|
*/
|
||||||
|
export function renderCiteLabelsInHtml(html, refs, citeMap) {
|
||||||
|
if (!html || typeof html !== 'string') return html || '';
|
||||||
|
if (!Array.isArray(refs) || refs.length === 0) return html;
|
||||||
|
|
||||||
|
/** 与稿面一致:历史/表格 JSON 中可能为 <autocite> */
|
||||||
|
let h = html.replace(/<\/autocite>/gi, '</mycite>').replace(/<autocite\b/gi, '<mycite');
|
||||||
|
|
||||||
|
const refList = refs;
|
||||||
|
const refMap = refList.reduce((acc, item) => {
|
||||||
|
const key = item && item.p_refer_id != null ? String(item.p_refer_id) : '';
|
||||||
|
if (key) acc[key] = item;
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
let normalized = h.replace(/<mycite\b[^>]*\/?>[\s\S]*?(?:<\/mycite>)?/gi, (fullTag) => {
|
||||||
|
const attrMatch = fullTag.match(/\bdata-id\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/i);
|
||||||
|
const dataId = (attrMatch && (attrMatch[1] || attrMatch[2] || attrMatch[3])) || '';
|
||||||
|
if (!dataId) return '';
|
||||||
|
return `<mycite data-id="${escAttr(dataId)}"></mycite>`;
|
||||||
|
});
|
||||||
|
const citeGroupRe = /(?:<mycite\s+data-id="([^"]*)"\s*><\/mycite>\s*)+/gi;
|
||||||
|
normalized = normalized.replace(citeGroupRe, (groupMatch) => {
|
||||||
|
const ids = [];
|
||||||
|
const innerRe = /<mycite\s+data-id="([^"]*)"\s*><\/mycite>/gi;
|
||||||
|
let m;
|
||||||
|
while ((m = innerRe.exec(groupMatch)) !== null) {
|
||||||
|
m[1].split(',').forEach((part) => {
|
||||||
|
const id = part.trim();
|
||||||
|
if (id) ids.push(id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const sortedAll = sortAutociteIdsByCiteNumber(ids, citeMap);
|
||||||
|
const validIds = sortedAll.filter((id) => refMap[id]);
|
||||||
|
const sortedIds = validIds.length ? sortAutociteIdsByCiteNumber(validIds, citeMap) : [];
|
||||||
|
const map = citeMap || {};
|
||||||
|
|
||||||
|
const parts = sortedIds.map((id) => {
|
||||||
|
const ref = refMap[id];
|
||||||
|
const no = ref ? map[id] : null;
|
||||||
|
const num = no != null && no !== '' ? String(no) : null;
|
||||||
|
return { id, ref, num };
|
||||||
|
});
|
||||||
|
|
||||||
|
const numsForLabel = parts
|
||||||
|
.map((p) => p.num)
|
||||||
|
.filter((n) => n != null && n !== '')
|
||||||
|
.map(Number);
|
||||||
|
const label = numsForLabel.length > 0 ? formatCiteNumbers(numsForLabel) : '';
|
||||||
|
if (!label) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const dataIdAttr = escAttr(sortedIds.join(','));
|
||||||
|
return `<mycite data-id="${dataIdAttr}">[${label}]</mycite>`;
|
||||||
|
});
|
||||||
|
return normalized.replace(/<mycite[^>]*data-id=""[^>]*>[\s\S]*?<\/mycite>/gi, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function applyCiteLabelsToTableRows(rows, refs, citeMap) {
|
||||||
|
if (!Array.isArray(rows) || !rows.length) return rows;
|
||||||
|
if (!Array.isArray(refs) || refs.length === 0) return rows;
|
||||||
|
|
||||||
|
return rows.map((row) => {
|
||||||
|
if (!Array.isArray(row)) return row;
|
||||||
|
const nextRow = row.map((cell) => {
|
||||||
|
if (!cell || typeof cell !== 'object') return cell;
|
||||||
|
const t = cell.text;
|
||||||
|
const lower = typeof t === 'string' ? t.toLowerCase() : '';
|
||||||
|
if (!lower || (!lower.includes('mycite') && !lower.includes('autocite'))) return cell;
|
||||||
|
const next = renderCiteLabelsInHtml(t, refs, citeMap);
|
||||||
|
if (next === t) return cell;
|
||||||
|
return { ...cell, text: next };
|
||||||
|
});
|
||||||
|
// TableUtils.addRowIdToData 会给数组行对象挂 rowId,渲染 oddColor 依赖它,不能在 map 后丢失
|
||||||
|
if (row.rowId != null) {
|
||||||
|
nextRow.rowId = row.rowId;
|
||||||
|
}
|
||||||
|
return nextRow;
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -1035,7 +1035,6 @@ str = str.replace(regex, function (match, content, offset, fullString) {
|
|||||||
const cells = row.querySelectorAll('th, td'); // 获取每个行中的单元格(包括 <th> 和 <td>)
|
const cells = row.querySelectorAll('th, td'); // 获取每个行中的单元格(包括 <th> 和 <td>)
|
||||||
return await Promise.all(
|
return await Promise.all(
|
||||||
Array.from(cells).map(async (cell) => {
|
Array.from(cells).map(async (cell) => {
|
||||||
console.log("🚀 ~ parseTableToArray777 ~ cell:", cell);
|
|
||||||
|
|
||||||
const text = await this.extractMathJaxLatex(cell);
|
const text = await this.extractMathJaxLatex(cell);
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -57,6 +57,8 @@
|
|||||||
table: 'api/Preaccept/getMainTables'
|
table: 'api/Preaccept/getMainTables'
|
||||||
}"
|
}"
|
||||||
:articleId="articleId"
|
:articleId="articleId"
|
||||||
|
:bodyCiteIdOrder="articleCiteIdOrder"
|
||||||
|
:chanFerForm="chanFerForm"
|
||||||
:content="ManuscirptContent"
|
:content="ManuscirptContent"
|
||||||
ref="commonWordHtmlTypeSetting"
|
ref="commonWordHtmlTypeSetting"
|
||||||
@onDragStart="onDragStart"
|
@onDragStart="onDragStart"
|
||||||
|
|||||||
@@ -681,11 +681,12 @@ export default {
|
|||||||
const noCite = ref ? citeMap[String(id)] : null;
|
const noCite = ref ? citeMap[String(id)] : null;
|
||||||
const noTable =
|
const noTable =
|
||||||
useTableBracketNums && tableNums[String(id)] != null ? tableNums[String(id)] : null;
|
useTableBracketNums && tableNums[String(id)] != null ? tableNums[String(id)] : null;
|
||||||
|
// 单元格内 [n] 按 Original order(table 序号)匹配;角标展示与正文一致,优先用 citeMap 对应序号
|
||||||
const num =
|
const num =
|
||||||
noTable != null && noTable !== '' && !Number.isNaN(Number(noTable))
|
noCite != null && noCite !== '' && !Number.isNaN(Number(noCite))
|
||||||
? String(noTable)
|
? String(noCite)
|
||||||
: noCite != null && noCite !== ''
|
: noTable != null && noTable !== '' && !Number.isNaN(Number(noTable))
|
||||||
? String(noCite)
|
? String(noTable)
|
||||||
: null;
|
: null;
|
||||||
return { id, ref, num };
|
return { id, ref, num };
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -58,9 +58,25 @@
|
|||||||
<script>
|
<script>
|
||||||
import { TableUtils } from '@/common/js/TableUtils';
|
import { TableUtils } from '@/common/js/TableUtils';
|
||||||
import { mediaUrl } from '@/common/js/commonJS.js';
|
import { mediaUrl } from '@/common/js/commonJS.js';
|
||||||
|
import {
|
||||||
|
buildCiteMapFromRefs,
|
||||||
|
applyCiteLabelsToTableRows
|
||||||
|
} from '@/common/js/citeTablePreview.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TablePreviewer',
|
name: 'TablePreviewer',
|
||||||
|
props: {
|
||||||
|
/** 与稿面 chanFerForm 一致,用于把单元格内 <mycite> 显示为 [n] */
|
||||||
|
referenceList: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
/** 正文引用首次出现顺序(p_refer_id),与 GenerateCharts articleCiteIdOrder 一致 */
|
||||||
|
bodyCiteIdOrder: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
visible: false,
|
visible: false,
|
||||||
@@ -70,23 +86,32 @@ export default {
|
|||||||
mediaUrl,
|
mediaUrl,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
previewCiteMap() {
|
||||||
|
return buildCiteMapFromRefs(this.referenceList, this.bodyCiteIdOrder);
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async open(type, item,isNoBg) {
|
async open(type, item, isNoBg) {
|
||||||
this.visible = true;
|
this.visible = true;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
const hideOddRowBg = isNoBg === true || isNoBg === 'true' || isNoBg === 1 || isNoBg === '1';
|
||||||
|
|
||||||
if (type === 'table') {
|
if (type === 'table') {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
try {
|
try {
|
||||||
const processed = this.processTableData(item.table);
|
const processed = this.processTableData(item.table, {
|
||||||
|
refs: this.referenceList,
|
||||||
|
citeMap: this.previewCiteMap
|
||||||
|
});
|
||||||
this.processedItem = Object.freeze({
|
this.processedItem = Object.freeze({
|
||||||
...item,
|
...item,
|
||||||
table: {
|
table: {
|
||||||
...item.table,
|
...item.table,
|
||||||
tableHeader: processed.tableHeader,
|
tableHeader: processed.tableHeader,
|
||||||
tableContent: processed.tableContent,
|
tableContent: processed.tableContent,
|
||||||
oddRowIds: isNoBg ? [] : processed.oddRowIds
|
oddRowIds: hideOddRowBg ? [] : processed.oddRowIds
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -97,6 +122,7 @@ export default {
|
|||||||
}, 50);
|
}, 50);
|
||||||
} else {
|
} else {
|
||||||
this.processedItem = item;
|
this.processedItem = item;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数学公式渲染
|
// 数学公式渲染
|
||||||
@@ -105,12 +131,20 @@ export default {
|
|||||||
}, 500);
|
}, 500);
|
||||||
},
|
},
|
||||||
|
|
||||||
processTableData(rawContent) {
|
processTableData(rawContent, citeCtx) {
|
||||||
try {
|
try {
|
||||||
const tableList = typeof rawContent === 'string' ? JSON.parse(rawContent) : rawContent;
|
const tableList = typeof rawContent === 'string' ? JSON.parse(rawContent) : rawContent;
|
||||||
const { header, content } = TableUtils.splitTable(tableList);
|
const { header, content } = TableUtils.splitTable(tableList);
|
||||||
const { rowData, rowIds } = TableUtils.addRowIdToData(content);
|
const { rowData, rowIds } = TableUtils.addRowIdToData(content);
|
||||||
return { tableHeader: header, tableContent: rowData, oddRowIds: rowIds };
|
const refs = citeCtx && citeCtx.refs;
|
||||||
|
const citeMap = citeCtx && citeCtx.citeMap;
|
||||||
|
let tableHeader = header;
|
||||||
|
let tableContent = rowData;
|
||||||
|
if (Array.isArray(refs) && refs.length > 0 && citeMap && typeof citeMap === 'object') {
|
||||||
|
tableHeader = applyCiteLabelsToTableRows(header, refs, citeMap);
|
||||||
|
tableContent = applyCiteLabelsToTableRows(rowData, refs, citeMap);
|
||||||
|
}
|
||||||
|
return { tableHeader, tableContent, oddRowIds: rowIds };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return { tableHeader: [], tableContent: [], oddRowIds: [] };
|
return { tableHeader: [], tableContent: [], oddRowIds: [] };
|
||||||
}
|
}
|
||||||
@@ -238,6 +272,16 @@ export default {
|
|||||||
background: rgb(250, 231, 232) !important;
|
background: rgb(250, 231, 232) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 与稿面 mycite 引用样式一致,弹窗内可见 [n] */
|
||||||
|
.table_Box ::v-deep mycite {
|
||||||
|
display: inline;
|
||||||
|
vertical-align: baseline;
|
||||||
|
color: rgb(0, 130, 170) !important;
|
||||||
|
cursor: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: rgba(0, 130, 170, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
.table-fade-enter-active, .table-fade-leave-active { transition: opacity 0.3s ease; }
|
.table-fade-enter-active, .table-fade-leave-active { transition: opacity 0.3s ease; }
|
||||||
.table-fade-enter, .table-fade-leave-to { opacity: 0; }
|
.table-fade-enter, .table-fade-leave-to { opacity: 0; }
|
||||||
</style>
|
</style>
|
||||||
@@ -1102,21 +1102,21 @@
|
|||||||
:key="`body-${it.id}-${idx}`"
|
:key="`body-${it.id}-${idx}`"
|
||||||
:class="['cite-preview-item', { 'is-active': idx === citePreviewActiveIndex }]"
|
:class="['cite-preview-item', { 'is-active': idx === citePreviewActiveIndex }]"
|
||||||
>
|
>
|
||||||
<div class="cite-preview-line cite-preview-num-auth">
|
<span class="cite-preview-line cite-preview-num-auth">
|
||||||
<span class="cite-preview-num">{{ it.no }}.</span>
|
<span class="cite-preview-num">{{ it.no }}.</span>
|
||||||
<span v-if="it.author" class="cite-preview-auth">{{ it.author }}</span>
|
<span v-if="it.author" class="cite-preview-auth">{{ it.author }}</span>
|
||||||
</div>
|
</span>
|
||||||
<div v-if="it.title && it.title !== '-'" class="cite-preview-line cite-preview-article-title">
|
<span v-if="it.title && it.title !== '-'" class="cite-preview-line cite-preview-article-title">
|
||||||
{{ it.title }}
|
{{ it.title }}
|
||||||
</div>
|
</span>
|
||||||
<div
|
<span
|
||||||
v-if="it.joura || it.dateno"
|
v-if="it.joura || it.dateno"
|
||||||
class="cite-preview-line cite-preview-journal-row"
|
class="cite-preview-line cite-preview-journal-row"
|
||||||
>
|
>
|
||||||
<em v-if="it.joura" class="cite-preview-journal">{{ it.joura }}</em>
|
<em v-if="it.joura" class="cite-preview-journal">{{ it.joura }}</em>
|
||||||
<span v-if="it.joura && it.dateno"> </span>
|
<span v-if="it.joura && it.dateno"> </span>
|
||||||
<span v-if="it.dateno" class="cite-preview-dateno">{{ it.dateno }}</span>
|
<span v-if="it.dateno" class="cite-preview-dateno">{{ it.dateno }}</span>
|
||||||
</div>
|
</span>
|
||||||
<a v-if="it.doi" class="cite-preview-doi" :href="it.doi" target="_blank">{{ it.doi }}</a>
|
<a v-if="it.doi" class="cite-preview-doi" :href="it.doi" target="_blank">{{ it.doi }}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -253,9 +253,10 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<DynamicTable
|
<DynamicTable
|
||||||
ref="myTableModal"
|
ref="myTableModal"
|
||||||
|
:reference-list="chanFerForm || []"
|
||||||
/>
|
:body-cite-id-order="bodyCiteIdOrder || []"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -264,7 +265,18 @@
|
|||||||
import { mediaUrl } from '@/common/js/commonJS.js'; // 引入通用逻辑
|
import { mediaUrl } from '@/common/js/commonJS.js'; // 引入通用逻辑
|
||||||
import DynamicTable from './DynamicTable.vue';
|
import DynamicTable from './DynamicTable.vue';
|
||||||
export default {
|
export default {
|
||||||
props: ['articleId', 'imgWidth', 'imgHeight', 'scale', 'isEdit', 'isShowEdit', 'urlList', 'content'],
|
props: [
|
||||||
|
'articleId',
|
||||||
|
'imgWidth',
|
||||||
|
'imgHeight',
|
||||||
|
'scale',
|
||||||
|
'isEdit',
|
||||||
|
'isShowEdit',
|
||||||
|
'urlList',
|
||||||
|
'content',
|
||||||
|
'chanFerForm',
|
||||||
|
'bodyCiteIdOrder'
|
||||||
|
],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
identity: localStorage.getItem('U_role'),
|
identity: localStorage.getItem('U_role'),
|
||||||
|
|||||||
@@ -465,9 +465,10 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<DynamicTable
|
<DynamicTable
|
||||||
ref="myTableModal"
|
ref="myTableModal"
|
||||||
|
:reference-list="chanFerForm || []"
|
||||||
/>
|
:body-cite-id-order="bodyCiteIdOrder || []"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -476,7 +477,20 @@ import DynamicTable from './DynamicTable.vue';
|
|||||||
import { mediaUrl } from '@/common/js/commonJS.js'; // 引入通用逻辑
|
import { mediaUrl } from '@/common/js/commonJS.js'; // 引入通用逻辑
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['articleId', 'imgWidth', 'imgHeight', 'scale', 'isEdit', 'isShowEdit', 'urlList', 'content'],
|
props: [
|
||||||
|
'articleId',
|
||||||
|
'imgWidth',
|
||||||
|
'imgHeight',
|
||||||
|
'scale',
|
||||||
|
'isEdit',
|
||||||
|
'isShowEdit',
|
||||||
|
'urlList',
|
||||||
|
'content',
|
||||||
|
/** 参考文献列表,供表格预览把 mycite 显示为 [n] */
|
||||||
|
'chanFerForm',
|
||||||
|
/** 正文引用顺序,与稿面 articleCiteIdOrder 一致 */
|
||||||
|
'bodyCiteIdOrder'
|
||||||
|
],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isShowComment: false,
|
isShowComment: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user