Commit fb0f4d9b by pangchong

refactor(table-editor): 优化表格列操作及跨列更新逻辑

- 格式化 AiAssistant 组件中表格相关关键词数组,提升代码可读性
- 修正 NodeTree 组件中删除列确认提示的模板字符串格式
- 精简 TableBatchModal 组件中跨列合并提示的HTML结构
- 合并 TableBatchModal 中类型定义及事件触发函数的参数写法,代码更简洁
- 优化 remapEntryColRefs2 函数,调整表格 ENTRY 和 SPANSPEC 属性更新的代码结构,提升可维护性
- 统一 TableEditor 组件中批量操作相关函数的参数定义格式
- 保持代码风格一致,修正部分箭头函数及数组过滤后的换行格式
parent 77427bde
...@@ -523,7 +523,20 @@ export const FAQ_DATABASE: FaqItem[] = [ ...@@ -523,7 +523,20 @@ export const FAQ_DATABASE: FaqItem[] = [
category: 'table', category: 'table',
categoryName: '表格编辑', categoryName: '表格编辑',
title: '如何使用批量操作弹窗一次性增删多行 / 多列?', title: '如何使用批量操作弹窗一次性增删多行 / 多列?',
keywords: ['批量增删', '批量加行', '批量加列', '批量删除行', '批量操作', 'tablebatch', 'spanspec', '跨列合并', 'pl', 'piliang', 'kl', 'kualie'], keywords: [
'批量增删',
'批量加行',
'批量加列',
'批量删除行',
'批量操作',
'tablebatch',
'spanspec',
'跨列合并',
'pl',
'piliang',
'kl',
'kualie'
],
synonyms: ['怎么一次加5行', '批量插入多列', '一次删多行', '表格批量管理', '加列合并跨列'], synonyms: ['怎么一次加5行', '批量插入多列', '一次删多行', '表格批量管理', '加列合并跨列'],
answer: '通过 TableBatchModal 弹窗可以极其高效地批量操作大型表格,并支持跨列扩展与子节点初始化:', answer: '通过 TableBatchModal 弹窗可以极其高效地批量操作大型表格,并支持跨列扩展与子节点初始化:',
steps: [ steps: [
...@@ -562,7 +575,23 @@ export const FAQ_DATABASE: FaqItem[] = [ ...@@ -562,7 +575,23 @@ export const FAQ_DATABASE: FaqItem[] = [
category: 'table', category: 'table',
categoryName: '表格编辑', categoryName: '表格编辑',
title: '表格列规范(COLSPEC)与删除列时的级联更新是如何工作的?', title: '表格列规范(COLSPEC)与删除列时的级联更新是如何工作的?',
keywords: ['列宽', 'colspec', 'colwidth', '删除列', '删除colspec', 'spanspec联动', '列宽调整', '比例分配', '表格宽度', 'lk', 'liewan', 'kb', 'kuanbi', 'scl', 'shanchulie'], keywords: [
'列宽',
'colspec',
'colwidth',
'删除列',
'删除colspec',
'spanspec联动',
'列宽调整',
'比例分配',
'表格宽度',
'lk',
'liewan',
'kb',
'kuanbi',
'scl',
'shanchulie'
],
synonyms: ['怎么调列宽', '大纲树删除colspec', '删除列节点', '删除列后跨列怎么变', '表格各列宽度比例', 'colspec是什么'], synonyms: ['怎么调列宽', '大纲树删除colspec', '删除列节点', '删除列后跨列怎么变', '表格各列宽度比例', 'colspec是什么'],
answer: '航空 CALS 表格通过 `<COLSPEC>` 标签定义每列的名称(colname)与宽度比例(colwidth),在调整或删除列时具备完善的级联保护:', answer: '航空 CALS 表格通过 `<COLSPEC>` 标签定义每列的名称(colname)与宽度比例(colwidth),在调整或删除列时具备完善的级联保护:',
steps: [ steps: [
......
...@@ -1454,7 +1454,7 @@ export function useNodeTree( ...@@ -1454,7 +1454,7 @@ export function useNodeTree(
if (node.tagName === 'COLSPEC') { if (node.tagName === 'COLSPEC') {
const colName = node.attributes.COLNAME || node.attributes.colname || '' const colName = node.attributes.COLNAME || node.attributes.colname || ''
const colNum = node.attributes.COLNUM || node.attributes.colnum || '' const colNum = node.attributes.COLNUM || node.attributes.colnum || ''
const colLabel = colNum ? `第 ${colNum} 列` : (colName ? `列 ${colName}` : '该列') const colLabel = colNum ? `第 ${colNum} 列` : colName ? `列 ${colName}` : '该列'
content = `确定要删除 ${colLabel} (<COLSPEC>) 吗?该操作将连带删除表格中该列的所有单元格,并自动更新跨列定义,且不可撤销!` content = `确定要删除 ${colLabel} (<COLSPEC>) 吗?该操作将连带删除表格中该列的所有单元格,并自动更新跨列定义,且不可撤销!`
} }
......
...@@ -26,13 +26,7 @@ export interface TableBatchModalProps { ...@@ -26,13 +26,7 @@ export interface TableBatchModalProps {
} }
/** 批量操作弹框确认事件类型 */ /** 批量操作弹框确认事件类型 */
export type ConfirmEmit = ( export type ConfirmEmit = (event: 'confirm', count: number, action: string, cellChildTags: string[], selectedSpanIds?: string[]) => void
event: 'confirm',
count: number,
action: string,
cellChildTags: string[],
selectedSpanIds?: string[]
) => void
/** 单元格初始化段落节点选项 */ /** 单元格初始化段落节点选项 */
export const CELL_CHILD_OPTIONS = [ export const CELL_CHILD_OPTIONS = [
......
...@@ -87,13 +87,7 @@ export function useTableBatchModal(emit: ConfirmEmit, formRef?: Ref<FormInst | n ...@@ -87,13 +87,7 @@ export function useTableBatchModal(emit: ConfirmEmit, formRef?: Ref<FormInst | n
return return
} }
if (form.count !== null) { if (form.count !== null) {
emit( emit('confirm', form.count, pendingAction.value, form.cellChildTags, form.selectedSpanIds)
'confirm',
form.count,
pendingAction.value,
form.cellChildTags,
form.selectedSpanIds
)
show.value = false show.value = false
} }
} }
......
...@@ -23,9 +23,7 @@ ...@@ -23,9 +23,7 @@
<!-- 相邻跨列(SPANSPEC)合并选项:仅在有相邻跨列定义时展示 --> <!-- 相邻跨列(SPANSPEC)合并选项:仅在有相邻跨列定义时展示 -->
<n-form-item v-if="spanCandidates.length > 0" label="合并到相邻跨列 (SPANSPEC)" path="selectedSpanIds"> <n-form-item v-if="spanCandidates.length > 0" label="合并到相邻跨列 (SPANSPEC)" path="selectedSpanIds">
<div class="w-full bg-fill-2 p-3 rounded border border-divider flex flex-col gap-2.5"> <div class="w-full bg-fill-2 p-3 rounded border border-divider flex flex-col gap-2.5">
<div class="text-[11px] text-color3"> <div class="text-[11px] text-color3">检测到新增列与以下跨列相邻,默认已勾选合并到跨列范围:</div>
检测到新增列与以下跨列相邻,默认已勾选合并到跨列范围:
</div>
<div v-for="item in spanCandidates" :key="item.spanId" class="flex items-start"> <div v-for="item in spanCandidates" :key="item.spanId" class="flex items-start">
<CommonCheckboxSingle <CommonCheckboxSingle
:checked="form.selectedSpanIds.includes(item.spanId)" :checked="form.selectedSpanIds.includes(item.spanId)"
......
...@@ -1081,13 +1081,19 @@ export function useTableEditor(props: { node: XmlNode }, options?: { mergeModalR ...@@ -1081,13 +1081,19 @@ export function useTableEditor(props: { node: XmlNode }, options?: { mergeModalR
const remapEntryColRefs2 = (sec?: XmlNode) => { const remapEntryColRefs2 = (sec?: XmlNode) => {
if (!sec) return if (!sec) return
sec.children.filter(c => c.tagName === 'ROW').forEach(row => { sec.children
row.children.filter(c => c.tagName === 'ENTRY').forEach(entry => { .filter((c) => c.tagName === 'ROW')
.forEach((row) => {
row.children
.filter((c) => c.tagName === 'ENTRY')
.forEach((entry) => {
const cn = entry.attributes.COLNAME || entry.attributes.colname const cn = entry.attributes.COLNAME || entry.attributes.colname
if (cn) { if (cn) {
const newCn = getNewColName2(cn) const newCn = getNewColName2(cn)
if (newCn === null) { delete entry.attributes.COLNAME; delete entry.attributes.colname } if (newCn === null) {
else if (newCn !== undefined) { delete entry.attributes.COLNAME
delete entry.attributes.colname
} else if (newCn !== undefined) {
if (entry.attributes.COLNAME !== undefined) entry.attributes.COLNAME = newCn if (entry.attributes.COLNAME !== undefined) entry.attributes.COLNAME = newCn
if (entry.attributes.colname !== undefined) entry.attributes.colname = newCn if (entry.attributes.colname !== undefined) entry.attributes.colname = newCn
} }
...@@ -1097,14 +1103,24 @@ export function useTableEditor(props: { node: XmlNode }, options?: { mergeModalR ...@@ -1097,14 +1103,24 @@ export function useTableEditor(props: { node: XmlNode }, options?: { mergeModalR
if (ns && ne) { if (ns && ne) {
let newNs = getNewColName2(ns) let newNs = getNewColName2(ns)
let newNe = getNewColName2(ne) let newNe = getNewColName2(ne)
if (newNs === null) { const next = colIdx < remainingColSpecs2.length ? colIdx : colIdx - 1; newNs = next >= 0 ? `col${next + 1}` : null } if (newNs === null) {
if (newNe === null) { const prev = colIdx > 0 ? colIdx - 1 : 0; newNe = `col${prev + 1}` } const next = colIdx < remainingColSpecs2.length ? colIdx : colIdx - 1
newNs = next >= 0 ? `col${next + 1}` : null
}
if (newNe === null) {
const prev = colIdx > 0 ? colIdx - 1 : 0
newNe = `col${prev + 1}`
}
if (newNs && newNe && parseInt(newNs.slice(3)) < parseInt(newNe.slice(3))) { if (newNs && newNe && parseInt(newNs.slice(3)) < parseInt(newNe.slice(3))) {
entry.attributes.NAMEST = newNs; entry.attributes.NAMEEND = newNe entry.attributes.NAMEST = newNs
delete entry.attributes.namest; delete entry.attributes.nameend entry.attributes.NAMEEND = newNe
delete entry.attributes.namest
delete entry.attributes.nameend
} else { } else {
delete entry.attributes.NAMEST; delete entry.attributes.namest delete entry.attributes.NAMEST
delete entry.attributes.NAMEEND; delete entry.attributes.nameend delete entry.attributes.namest
delete entry.attributes.NAMEEND
delete entry.attributes.nameend
} }
} }
}) })
...@@ -1115,15 +1131,26 @@ export function useTableEditor(props: { node: XmlNode }, options?: { mergeModalR ...@@ -1115,15 +1131,26 @@ export function useTableEditor(props: { node: XmlNode }, options?: { mergeModalR
remapEntryColRefs2(tbody) remapEntryColRefs2(tbody)
// 同步更新 SPANSPEC 的 NAMEST / NAMEEND // 同步更新 SPANSPEC 的 NAMEST / NAMEEND
tgroup.children.filter(c => c.tagName === 'SPANSPEC').forEach(spanSpec => { tgroup.children
.filter((c) => c.tagName === 'SPANSPEC')
.forEach((spanSpec) => {
const ns = spanSpec.attributes.NAMEST || spanSpec.attributes.namest const ns = spanSpec.attributes.NAMEST || spanSpec.attributes.namest
const ne = spanSpec.attributes.NAMEEND || spanSpec.attributes.nameend const ne = spanSpec.attributes.NAMEEND || spanSpec.attributes.nameend
if (ns && ne) { if (ns && ne) {
let newNs = getNewColName2(ns) let newNs = getNewColName2(ns)
let newNe = getNewColName2(ne) let newNe = getNewColName2(ne)
if (newNs === null) { const next = colIdx < remainingColSpecs2.length ? colIdx : colIdx - 1; newNs = next >= 0 ? `col${next + 1}` : null } if (newNs === null) {
if (newNe === null) { const prev = colIdx > 0 ? colIdx - 1 : 0; newNe = `col${prev + 1}` } const next = colIdx < remainingColSpecs2.length ? colIdx : colIdx - 1
if (newNs && newNe) { spanSpec.attributes.NAMEST = newNs; spanSpec.attributes.NAMEEND = newNe } newNs = next >= 0 ? `col${next + 1}` : null
}
if (newNe === null) {
const prev = colIdx > 0 ? colIdx - 1 : 0
newNe = `col${prev + 1}`
}
if (newNs && newNe) {
spanSpec.attributes.NAMEST = newNs
spanSpec.attributes.NAMEEND = newNe
}
} }
}) })
...@@ -1804,12 +1831,7 @@ export function useTableEditor(props: { node: XmlNode }, options?: { mergeModalR ...@@ -1804,12 +1831,7 @@ export function useTableEditor(props: { node: XmlNode }, options?: { mergeModalR
} }
]) ])
const handleColAddSelect = ( const handleColAddSelect = (key: string, cellChildTags?: string[] | null, selectedSpanIds?: string[], count = 1) => {
key: string,
cellChildTags?: string[] | null,
selectedSpanIds?: string[],
count = 1
) => {
let activeColIdx: number | undefined = undefined let activeColIdx: number | undefined = undefined
const targetCellId = selectedCellIds.value[0] || contextMenu.value.cellId const targetCellId = selectedCellIds.value[0] || contextMenu.value.cellId
...@@ -2454,12 +2476,7 @@ export function useTableBatchActions(deps: { ...@@ -2454,12 +2476,7 @@ export function useTableBatchActions(deps: {
} }
/** 确认执行批量操作(由 TableBatchModal 的 @confirm 事件触发) */ /** 确认执行批量操作(由 TableBatchModal 的 @confirm 事件触发) */
const executeBatchAction = ( const executeBatchAction = (count: number, action: string, cellChildTags: string[], selectedSpanIds?: string[]) => {
count: number,
action: string,
cellChildTags: string[],
selectedSpanIds?: string[]
) => {
const { cellId, rowId, colIdx } = deps.contextMenu.value const { cellId, rowId, colIdx } = deps.contextMenu.value
if (cellId && !deps.selectedCellIds.value.includes(cellId)) { if (cellId && !deps.selectedCellIds.value.includes(cellId)) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment