Refactor document versioning to extract fields from uploaded .docx files on the server side
- Removed the `fields` parameter from the version upload form, as it is now extracted from the uploaded .docx file using the `extractContentControls` function. - Updated related types and interfaces to reflect the new structure of version fields. - Modified the OpenAPI specification to document the changes in the versioning process. - Adjusted tests to ensure compliance with the new behavior, including validation for the absence of the `fields` parameter. - Implemented a new function `extractDocumentSnapshot` to handle the extraction of content controls and document properties from .docx files. - Updated metadata and versioning services to align with the new extraction logic.
This commit is contained in:
parent
bc61f0fd2e
commit
cdae1ceedd
17 changed files with 380 additions and 179 deletions
|
|
@ -125,10 +125,12 @@ function unescapeXml(value) {
|
|||
.replace(/&/g, "&");
|
||||
}
|
||||
|
||||
/** ถอด <Property name value> ทั้งชุดจาก custom.xml — ไว้ --list และหา pid ที่ใช้แล้ว */
|
||||
/** ถอด <property name value> ทั้งชุดจาก custom.xml — ไว้ --list และหา pid ที่ใช้แล้ว
|
||||
* (match ทั้งพิมพ์เล็กของตัว stamp จริง/setCustomDocProps และพิมพ์ใหญ่ <Property>
|
||||
* ที่ script นี้เคยเขียนก่อน 2026-10-30 — อ่านไฟล์เก่าที่ stampค้างไว้ได้) */
|
||||
function readProperties(xml) {
|
||||
const properties = [];
|
||||
const regex = /<Property\s+[^>]*name="([^"]*)"[^>]*>([\s\S]*?)<\/Property>|<Property\s+[^>]*name="([^"]*)"[^>]*\/>/g;
|
||||
const regex = /<property\s+[^>]*name="([^"]*)"[^>]*>([\s\S]*?)<\/property>|<property\s+[^>]*name="([^"]*)"[^>]*\/>/gi;
|
||||
let match;
|
||||
while ((match = regex.exec(xml)) !== null) {
|
||||
const name = match[1] ?? match[3];
|
||||
|
|
@ -148,7 +150,10 @@ function usedPids(xml) {
|
|||
}
|
||||
|
||||
function propertyXml(name, pid, value) {
|
||||
return ` <Property fmtid="${CUSTOM_FMTID}" pid="${pid}" name="${escapeXml(name)}"><vt:lpwstr>${escapeXml(value)}</vt:lpwstr></Property>\n`;
|
||||
// `<property>` พิมพ์เล็กตาม schema OOXML (ct_Property) — ตรงกับตัว stamp จริง
|
||||
// setCustomDocProps ของ lib/lib-tmpl.ts เพื่อให้ getCustomDocProps/getDocProps
|
||||
// (ที่ /api/template/extract กับ fields ของ version ใช้อ่าน) มองเห็นด้วย
|
||||
return ` <property fmtid="${CUSTOM_FMTID}" pid="${pid}" name="${escapeXml(name)}"><vt:lpwstr>${escapeXml(value)}</vt:lpwstr></property>\n`;
|
||||
}
|
||||
|
||||
/** upsert property ลง custom.xml (สร้างไฟล์ใหม่ถ้ายังไม่มี) — คืน XML ที่พร้อมเขียนกลับ zip */
|
||||
|
|
@ -156,9 +161,10 @@ function upsertProperties(existingXml, entries) {
|
|||
// เอา Property เก่าของชื่อที่จะเขียนทิ้งก่อน (replace แบบตัวเอง)
|
||||
let xml = existingXml;
|
||||
for (const entry of entries) {
|
||||
// gi — ถอดของเก่าทั้งพิมพ์เล็ก (ตัวจริง) และพิมพ์ใหญ่ (ที่ script นี้เคยเขียน) ก่อนแทรกใหม่
|
||||
const removal = new RegExp(
|
||||
`\\s*<Property\\s+[^>]*name="${escapeXml(entry.name).replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}"[^>]*>([\\s\\S]*?)</Property>`,
|
||||
"g",
|
||||
`\\s*<property\\s+[^>]*name="${escapeXml(entry.name).replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}"[^>]*>([\\s\\S]*?)</property>`,
|
||||
"gi",
|
||||
);
|
||||
xml = xml.replace(removal, "");
|
||||
}
|
||||
|
|
@ -189,7 +195,7 @@ function ensurePartRegistered(zip) {
|
|||
.asText()
|
||||
.replace(
|
||||
/<\/Types>/,
|
||||
` <Override PartName="/docProps/custom.xml" ContentType="application/vnd.openxmlformats-officedocument.document-properties.custom+xml"/>\n</Types>`,
|
||||
` <Override PartName="/docProps/custom.xml" ContentType="application/vnd.openxmlformats-officedocument.custom-properties+xml"/>\n</Types>`,
|
||||
);
|
||||
zip.file(CT_PATH, updated);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue