v2.0.8: конвертация .doc → .docx через convert-service перед upload
Deploy contracts-flask / validate (push) Successful in 0s

This commit is contained in:
2026-07-16 10:42:21 +04:00
parent c677206d03
commit de05d746cc
3 changed files with 65 additions and 10 deletions
+57 -2
View File
@@ -12,6 +12,8 @@
* - statusToHTML() — рендер статуса (↑ N%, ✓)
* - renderFiles() — рендер всей таблицы
var CONVERT_URL = '/convert-doc';
/**
* statusToHTML(status) — Чистая функция: структура → HTML (Фаза 1).
*
@@ -26,6 +28,7 @@ function statusToHTML(st) {
if (!st || !st.kind) return '';
switch (st.kind) {
case 'connecting': return '⏳ соединение... ' + (st.elapsed || 0) + 'с';
case 'converting': return '⏳ конвертация... ' + (st.elapsed || 0) + 'с';
case 'uploading': return '⏳ отправка... ' + (st.elapsed || 0) + 'с';
case 'uploaded': return '<span class="status-ok">✓</span>';
case 'unzipping': return '⏳ распаковка...';
@@ -203,6 +206,40 @@ window.toggleClassifyDetail = async function(i) {
}
};
/**
* convertDoc(file, onProgress) — .doc → .docx через внешний libreoffice-сервис.
* С честным счётчиком времени.
*/
function convertDoc(file, onProgress) {
var startTime = Date.now();
if (onProgress) onProgress({ kind: 'converting', elapsed: 0 });
var fd = new FormData();
fd.append('files', file, file.name);
var timer = setInterval(function() {
var elapsed = Math.floor((Date.now() - startTime) / 1000);
if (onProgress) onProgress({ kind: 'converting', elapsed: elapsed });
}, 1000);
return fetch(CONVERT_URL + '?_=' + Date.now(), { method: 'POST', body: fd })
.then(function(r) {
if (!r.ok) throw new Error('Конвертация: HTTP ' + r.status);
return r.blob();
})
.then(function(blob) {
clearInterval(timer);
if (blob.size === 0) throw new Error('Конвертация: пустой результат');
return new File([blob], file.name.replace(/\.doc$/i, '.docx'), {
type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
lastModified: Date.now()
});
})
.catch(function(e) {
clearInterval(timer);
throw e;
});
}
/**
* ⛔ НЕ МЕНЯТЬ ⛔ uploadFile — fetch-загрузка с честным счётчиком времени.
*
@@ -430,8 +467,17 @@ async function addRegularFile(file, zipSource) {
render(state);
try {
// .doc → конвертация через libreoffice-сервис
var uploadTarget = file;
if (file.name.toLowerCase().endsWith('.doc')) {
uploadTarget = await convertDoc(file, function(st) {
state.files[rowIdx].status = st;
render(state);
});
state.files[rowIdx].name = uploadTarget.name;
}
// fetch-загрузка с честным счётчиком времени
var resp = await uploadFile(file, function(st) {
var resp = await uploadFile(uploadTarget, function(st) {
state.files[rowIdx].status = st;
render(state);
}, zipSource);
@@ -523,7 +569,16 @@ async function onFilesSelected(newFiles) {
delete entry._pendingFile;
var f = pendingFile;
try {
var resp = await uploadFile(f, function(st) {
// .doc → конвертация через libreoffice-сервис
var uploadTarget = f;
if (f.name.toLowerCase().endsWith('.doc')) {
uploadTarget = await convertDoc(f, function(st) {
entry.status = st;
render(state);
});
entry.name = uploadTarget.name;
}
var resp = await uploadFile(uploadTarget, function(st) {
entry.status = st;
render(state);
});