参考文献

This commit is contained in:
2026-04-09 11:52:33 +08:00
parent 7527a6ef54
commit 9c44064f51
5 changed files with 191 additions and 185 deletions

View File

@@ -737,6 +737,10 @@ import bottomTinymce from '@/components/page/components/Tinymce';
import catalogue from '@/components/page/components/table/catalogue.vue';
import editPublicRefTableOnly from './editPublicRefTableOnly.vue';
import { extractAutociteIdsFromHtmlString } from '@/utils/autociteHtml.js';
import {
collectCiteHtmlSourcesForMainListItem,
extractAutociteOrderFromMainList
} from '@/utils/autociteMainListOrder.js';
export default {
data() {
return {
@@ -1030,7 +1034,7 @@ export default {
if (draft == null || draft === '') {
return this.articleCiteIdOrder;
}
const order = this.extractAutociteOrderFromMainList(this.Main_List, this.currentContent.am_id, draft);
const order = extractAutociteOrderFromMainList(this.Main_List, this.currentContent.am_id, draft);
return order.length > 0 ? order : this.articleCiteIdOrder;
},
/**
@@ -1045,7 +1049,7 @@ export default {
const citeMap = this.buildDisplayCiteMap(order || []);
list.forEach((p) => {
if (!p || Number(p.type) !== 2) return;
const candidates = this.collectCiteHtmlSourcesForMainListItem(p);
const candidates = collectCiteHtmlSourcesForMainListItem(p);
const ids = [];
candidates.forEach((raw) => {
extractAutociteIdsFromHtmlString(raw).forEach((id) => {
@@ -1073,7 +1077,6 @@ export default {
if (p.table.table_id != null) out[String(p.table.table_id)] = max;
}
});
console.log('[tableLinkCiteMaxMap]', out);
return out;
},
/** 表格抽屉内角标:与 Edit Content 同源,按 Main_List + Title/表/Note 合并稿做全文首次出现排序,避免仍用 articleCiteIdOrder 列表下标 [38] */
@@ -1085,7 +1088,12 @@ export default {
if (draft == null || draft === '') {
return this.articleCiteIdOrder;
}
const order = this.extractAutociteOrderFromMainList(this.Main_List, this.lineStyle.am_id, draft);
/** 正文里 <mytable> 指向本表时,展开用当前抽屉合并稿,角标与「全文该 mytable 之前」顺序一致 */
const citeOpts = {
tableDraftAmId: this.lineStyle.am_id,
tableDraftHtml: draft
};
const order = extractAutociteOrderFromMainList(this.Main_List, this.lineStyle.am_id, draft, citeOpts);
return order.length > 0 ? order : this.articleCiteIdOrder;
}
},
@@ -1535,9 +1543,10 @@ export default {
* 按 Main_List 各段正文中 mycite 首次出现顺序重排参考文献。
* draftAmId + draftHtml合并「当前将保存的这一段」后再扫全文点 Save 时与保存后一致);
* 传 (null, null) 表示完全以 Main_List 已存 content 为准。
* citeOptionsEdit Table 时传入 { tableDraftAmId, tableDraftHtml },使正文 mytable 展开与抽屉稿一致。
*/
reorderReferencesFromMainListBody(draftAmId, draftHtml) {
const order = this.extractAutociteOrderFromMainList(this.Main_List, draftAmId, draftHtml);
reorderReferencesFromMainListBody(draftAmId, draftHtml, citeOptions) {
const order = extractAutociteOrderFromMainList(this.Main_List, draftAmId, draftHtml, citeOptions || {});
if (order.length > 0) {
this.handleReorderReferencesByBody(order);
}
@@ -1587,7 +1596,11 @@ export default {
this.reorderReferencesFromMainListBody(null, null);
return;
}
this.reorderReferencesFromMainListBody(this.lineStyle.am_id, html);
const citeOpts = {
tableDraftAmId: this.lineStyle.am_id,
tableDraftHtml: html
};
this.reorderReferencesFromMainListBody(this.lineStyle.am_id, html, citeOpts);
},
scheduleFlushReorderFromTableModal() {
if (!this.threeVisible || !this.lineStyle || this.lineStyle.am_id == null) return;
@@ -1743,77 +1756,6 @@ export default {
if (sig(next) === sig(refs)) return;
this.chanFerForm = next;
},
/**
* 单条 Main_List 段内、与稿面阅读顺序一致的 HTML 片段(用于统计 mycite 顺序)。
* 表格段:标题 → 表体html_data 或逐单元格 text→ Note图段标题 → 说明。
*/
collectCiteHtmlSourcesForMainListItem(p, draftAmId, draftHtml) {
if (draftAmId != null && p && p.am_id == draftAmId && draftHtml != null) {
return [draftHtml];
}
const out = [];
const typ = p != null && p.type != null ? Number(p.type) : NaN;
if (typ === 2 && p.table) {
const t = p.table;
if (typeof t.title === 'string' && t.title.trim()) out.push(t.title);
if (typeof t.html_data === 'string' && t.html_data.trim()) {
out.push(t.html_data);
} else {
const pushRows = (rows) => {
if (!Array.isArray(rows)) return;
rows.forEach((row) => {
if (!Array.isArray(row)) return;
row.forEach((cell) => {
if (cell && typeof cell.text === 'string' && cell.text) out.push(cell.text);
});
});
};
pushRows(t.tableHeader);
pushRows(t.tableContent);
}
if (typeof t.note === 'string' && t.note.trim()) out.push(t.note);
// 兜底:不同接口版本的表体字段名不一致,深度扫描 table 对象里所有可能含引用的字符串字段。
this.collectCiteStringsDeep(t, out);
return out;
}
if (typ === 1 && p.image) {
const img = p.image;
if (typeof img.title === 'string' && img.title.trim()) out.push(img.title);
if (typeof img.note === 'string' && img.note.trim()) out.push(img.note);
if (out.length === 0) {
if (p && typeof p.content === 'string' && p.content.trim()) out.push(p.content);
if (p && typeof p.text === 'string' && p.text.trim()) out.push(p.text);
}
return out;
}
if (p && typeof p.text === 'string' && p.text.trim()) out.push(p.text);
if (p && typeof p.content === 'string' && p.content.trim()) out.push(p.content);
return out;
},
/**
* 递归收集对象中的字符串字段,覆盖 html/text/content 等异构字段名。
* 仅保留看起来可能包含引用信息的片段,避免噪音过大。
*/
collectCiteStringsDeep(source, out, depth = 0) {
if (!source || depth > 6) return;
if (typeof source === 'string') {
const s = source.trim();
if (!s) return;
const maybeCite = /<(?:mycite|autocite)\b/i.test(s) || /\[[\d\s,\-–—]+\]/.test(s);
if (maybeCite) out.push(s);
return;
}
if (Array.isArray(source)) {
source.forEach((item) => this.collectCiteStringsDeep(item, out, depth + 1));
return;
}
if (typeof source === 'object') {
Object.keys(source).forEach((k) => {
const v = source[k];
this.collectCiteStringsDeep(v, out, depth + 1);
});
}
},
extractBracketCiteNumbersFromText(raw) {
const out = [];
if (!raw || typeof raw !== 'string') return out;
@@ -1842,20 +1784,6 @@ export default {
}
return out;
},
/** 与 word.vue 一致:从各段 HTML 中按出现顺序收集 autocite含表格单元格、表题、表注、图题图注 */
extractAutociteOrderFromMainList(mainList, draftAmId, draftHtml) {
const list = Array.isArray(mainList) ? mainList : [];
const order = [];
list.forEach((p) => {
const candidates = this.collectCiteHtmlSourcesForMainListItem(p, draftAmId, draftHtml);
candidates.forEach((raw) => {
extractAutociteIdsFromHtmlString(raw).forEach((id) => {
if (!order.includes(id)) order.push(id);
});
});
});
return order;
},
/** 编辑弹窗内正文一变立即按全文合并稿重排参考文献(不再防抖,选中/输入后列表马上跟正文一致) */
scheduleReorderFromEditModal(html) {
if (!this.editVisible || !this.currentContent || this.currentContent.am_id == null) return;
@@ -1866,7 +1794,7 @@ export default {
/** 立即按全文合并稿重排参考文献顺序(插入引用后调用,避免编号长期停留在列表序号 [8] */
flushReorderFromEditModal(html) {
if (!this.editVisible || !this.currentContent || this.currentContent.am_id == null) return;
let order = this.extractAutociteOrderFromMainList(this.Main_List, this.currentContent.am_id, html);
let order = extractAutociteOrderFromMainList(this.Main_List, this.currentContent.am_id, html);
if (order.length === 0 && html && /(autocite|mycite)/i.test(html)) {
order = extractAutociteIdsFromHtmlString(html);
}