总表更新
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -679,6 +679,54 @@ def import_dedupe_total_data():
|
||||
})
|
||||
|
||||
|
||||
@admin_api.route('/dedupe-total-data/delete-import/<import_id>')
|
||||
@admin_required
|
||||
def dedupe_total_data_delete_import_progress(import_id):
|
||||
result, error_response, status = _proxy_backend_java(
|
||||
'GET',
|
||||
f'/api/admin/dedupe-total-data/delete-import/{import_id}',
|
||||
)
|
||||
if error_response is not None:
|
||||
return error_response, status
|
||||
progress = result.get('data') or {}
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'progress': {
|
||||
'status': progress.get('status') or 'pending',
|
||||
'total_rows': progress.get('totalRows') or 0,
|
||||
'processed_rows': progress.get('processedRows') or 0,
|
||||
'asin_count': progress.get('asinCount') or 0,
|
||||
'deleted_count': progress.get('insertedCount') or 0,
|
||||
'skipped_count': progress.get('skippedCount') or 0,
|
||||
'error_message': progress.get('errorMessage') or '',
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@admin_api.route('/dedupe-total-data/delete-import', methods=['POST'])
|
||||
@admin_required
|
||||
def delete_import_dedupe_total_data():
|
||||
file_storage = request.files.get('file')
|
||||
if not file_storage or file_storage.filename == '':
|
||||
return jsonify({'success': False, 'error': '请选择 Excel 文件'})
|
||||
files = {
|
||||
'file': (file_storage.filename, file_storage.stream, file_storage.mimetype or 'application/octet-stream')
|
||||
}
|
||||
result, error_response, status = _proxy_backend_java(
|
||||
'POST',
|
||||
'/api/admin/dedupe-total-data/delete-import',
|
||||
files=files,
|
||||
)
|
||||
if error_response is not None:
|
||||
return error_response, status
|
||||
summary = result.get('data') or {}
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'msg': result.get('message') or '开始删除',
|
||||
'import_id': summary.get('importId') or '',
|
||||
})
|
||||
|
||||
|
||||
@admin_api.route('/dedupe-total-data', methods=['POST'])
|
||||
@admin_required
|
||||
def create_dedupe_total_data():
|
||||
|
||||
@@ -23,6 +23,7 @@ bucket_path = "nanri-image/"
|
||||
file_url_pre = f"https://{bucket}.oss-cn-hangzhou.aliyuncs.com/"
|
||||
|
||||
import os
|
||||
# backend_java_base_url = os.environ.get('BACKEND_JAVA_BASE_URL', 'http://127.0.0.1:18080').rstrip('/')
|
||||
backend_java_base_url = os.environ.get('BACKEND_JAVA_BASE_URL', 'http://8.136.19.173:18080').rstrip('/')
|
||||
os.environ['OSS_ACCESS_KEY_ID'] = accessKeyId
|
||||
os.environ['OSS_ACCESS_KEY_SECRET'] = accessKeySecret
|
||||
|
||||
@@ -251,18 +251,37 @@
|
||||
<!-- 数据去重总数据 -->
|
||||
<div id="panel-dedupe-total-data" class="tab-panel">
|
||||
<div class="form-box">
|
||||
<h3 style="margin-bottom:16px;font-size:15px;">新增总数据</h3>
|
||||
<div class="form-row">
|
||||
<div class="form-group" style="min-width:320px;">
|
||||
<label>上传 Excel 文件(读取 ASIN 列)</label>
|
||||
<input type="file" id="dedupeTotalDataFile" accept=".xlsx,.xls">
|
||||
<div class="form-row" style="align-items:flex-start;gap:16px;">
|
||||
<div style="flex:1;min-width:320px;">
|
||||
<h3 style="margin-bottom:16px;font-size:15px;">新增总数据</h3>
|
||||
<div class="form-row">
|
||||
<div class="form-group" style="min-width:320px;">
|
||||
<label>上传 Excel 文件(读取 ASIN 列)</label>
|
||||
<input type="file" id="dedupeTotalDataFile" accept=".xlsx,.xls">
|
||||
</div>
|
||||
<button class="btn" id="btnAddDedupeTotalData">上传并导入</button>
|
||||
</div>
|
||||
<p class="msg" id="msgDedupeTotalData"></p>
|
||||
<div class="progress-wrap" id="dedupeTotalDataProgressWrap" style="display:none;">
|
||||
<div class="progress-bar"><div class="progress-fill" id="dedupeTotalDataProgressFill"></div></div>
|
||||
<div class="progress-text" id="dedupeTotalDataProgressText"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="flex:1;min-width:320px;">
|
||||
<h3 style="margin-bottom:16px;font-size:15px;">删除匹配总数据</h3>
|
||||
<div class="form-row">
|
||||
<div class="form-group" style="min-width:320px;">
|
||||
<label>上传 Excel 文件(读取 ASIN 列)</label>
|
||||
<input type="file" id="dedupeTotalDataDeleteFile" accept=".xlsx,.xls">
|
||||
</div>
|
||||
<button class="btn btn-danger" id="btnDeleteImportDedupeTotalData">上传并删除</button>
|
||||
</div>
|
||||
<p class="msg" id="msgDeleteDedupeTotalData"></p>
|
||||
<div class="progress-wrap" id="dedupeTotalDataDeleteProgressWrap" style="display:none;">
|
||||
<div class="progress-bar"><div class="progress-fill" id="dedupeTotalDataDeleteProgressFill"></div></div>
|
||||
<div class="progress-text" id="dedupeTotalDataDeleteProgressText"></div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn" id="btnAddDedupeTotalData">上传并导入</button>
|
||||
</div>
|
||||
<p class="msg" id="msgDedupeTotalData"></p>
|
||||
<div class="progress-wrap" id="dedupeTotalDataProgressWrap" style="display:none;">
|
||||
<div class="progress-bar"><div class="progress-fill" id="dedupeTotalDataProgressFill"></div></div>
|
||||
<div class="progress-text" id="dedupeTotalDataProgressText"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-box">
|
||||
@@ -869,12 +888,19 @@
|
||||
}
|
||||
document.getElementById('btnSearchDedupeTotalData').onclick = function() { loadDedupeTotalData(1); };
|
||||
var dedupeImportPollTimer = null;
|
||||
var dedupeDeleteImportPollTimer = null;
|
||||
function stopDedupeImportProgress() {
|
||||
if (dedupeImportPollTimer) {
|
||||
clearInterval(dedupeImportPollTimer);
|
||||
dedupeImportPollTimer = null;
|
||||
}
|
||||
}
|
||||
function stopDedupeDeleteImportProgress() {
|
||||
if (dedupeDeleteImportPollTimer) {
|
||||
clearInterval(dedupeDeleteImportPollTimer);
|
||||
dedupeDeleteImportPollTimer = null;
|
||||
}
|
||||
}
|
||||
function setDedupeImportProgress(percent, text) {
|
||||
var wrap = document.getElementById('dedupeTotalDataProgressWrap');
|
||||
var fill = document.getElementById('dedupeTotalDataProgressFill');
|
||||
@@ -883,6 +909,14 @@
|
||||
fill.style.width = Math.max(0, Math.min(100, percent || 0)) + '%';
|
||||
textEl.textContent = text || '';
|
||||
}
|
||||
function setDedupeDeleteImportProgress(percent, text) {
|
||||
var wrap = document.getElementById('dedupeTotalDataDeleteProgressWrap');
|
||||
var fill = document.getElementById('dedupeTotalDataDeleteProgressFill');
|
||||
var textEl = document.getElementById('dedupeTotalDataDeleteProgressText');
|
||||
wrap.style.display = 'block';
|
||||
fill.style.width = Math.max(0, Math.min(100, percent || 0)) + '%';
|
||||
textEl.textContent = text || '';
|
||||
}
|
||||
function pollDedupeImport(importId) {
|
||||
stopDedupeImportProgress();
|
||||
function tick() {
|
||||
@@ -920,6 +954,43 @@
|
||||
tick();
|
||||
dedupeImportPollTimer = setInterval(tick, 1000);
|
||||
}
|
||||
function pollDedupeDeleteImport(importId) {
|
||||
stopDedupeDeleteImportProgress();
|
||||
function tick() {
|
||||
fetch('/api/admin/dedupe-total-data/delete-import/' + encodeURIComponent(importId))
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(res) {
|
||||
if (!res.success) {
|
||||
stopDedupeDeleteImportProgress();
|
||||
document.getElementById('msgDeleteDedupeTotalData').textContent = res.error || '查询删除进度失败';
|
||||
document.getElementById('msgDeleteDedupeTotalData').className = 'msg err';
|
||||
return;
|
||||
}
|
||||
var progress = res.progress || {};
|
||||
var totalRows = progress.total_rows || 0;
|
||||
var processedRows = progress.processed_rows || 0;
|
||||
var percent = totalRows > 0 ? Math.round(processedRows * 100 / totalRows) : 0;
|
||||
setDedupeDeleteImportProgress(percent, '处理中:已处理 ' + processedRows + ' / ' + totalRows + ',删除 ' + (progress.deleted_count || 0) + ',跳过 ' + (progress.skipped_count || 0));
|
||||
if (progress.status === 'success') {
|
||||
stopDedupeDeleteImportProgress();
|
||||
document.getElementById('msgDeleteDedupeTotalData').textContent = '删除成功:总行数 ' + (progress.total_rows || 0) + ',ASIN 数量 ' + (progress.asin_count || 0) + ',删除 ' + (progress.deleted_count || 0) + ',跳过 ' + (progress.skipped_count || 0);
|
||||
document.getElementById('msgDeleteDedupeTotalData').className = 'msg ok';
|
||||
loadDedupeTotalData(1);
|
||||
} else if (progress.status === 'failed') {
|
||||
stopDedupeDeleteImportProgress();
|
||||
document.getElementById('msgDeleteDedupeTotalData').textContent = progress.error_message || '删除失败';
|
||||
document.getElementById('msgDeleteDedupeTotalData').className = 'msg err';
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
stopDedupeDeleteImportProgress();
|
||||
document.getElementById('msgDeleteDedupeTotalData').textContent = '查询删除进度失败';
|
||||
document.getElementById('msgDeleteDedupeTotalData').className = 'msg err';
|
||||
});
|
||||
}
|
||||
tick();
|
||||
dedupeDeleteImportPollTimer = setInterval(tick, 1000);
|
||||
}
|
||||
|
||||
document.getElementById('btnAddDedupeTotalData').onclick = function() {
|
||||
var fileInput = document.getElementById('dedupeTotalDataFile');
|
||||
@@ -974,6 +1045,62 @@
|
||||
};
|
||||
xhr.send(formData);
|
||||
};
|
||||
document.getElementById('btnDeleteImportDedupeTotalData').onclick = function() {
|
||||
var fileInput = document.getElementById('dedupeTotalDataDeleteFile');
|
||||
var msgEl = document.getElementById('msgDeleteDedupeTotalData');
|
||||
msgEl.textContent = '';
|
||||
msgEl.className = 'msg';
|
||||
stopDedupeDeleteImportProgress();
|
||||
document.getElementById('dedupeTotalDataDeleteProgressWrap').style.display = 'none';
|
||||
if (!fileInput.files || fileInput.files.length === 0) {
|
||||
msgEl.textContent = '请选择 Excel 文件';
|
||||
msgEl.classList.add('err');
|
||||
return;
|
||||
}
|
||||
var file = fileInput.files[0];
|
||||
var lowerName = (file.name || '').toLowerCase();
|
||||
if (!(lowerName.endsWith('.xlsx') || lowerName.endsWith('.xls'))) {
|
||||
msgEl.textContent = '仅支持 .xlsx 或 .xls 文件';
|
||||
msgEl.classList.add('err');
|
||||
return;
|
||||
}
|
||||
if (!confirm('确定按 Excel 中的 ASIN 批量删除匹配的总数据吗?')) {
|
||||
return;
|
||||
}
|
||||
var formData = new FormData();
|
||||
formData.append('file', file);
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', '/api/admin/dedupe-total-data/delete-import', true);
|
||||
xhr.upload.onprogress = function(event) {
|
||||
if (event.lengthComputable) {
|
||||
var percent = Math.round(event.loaded * 100 / event.total);
|
||||
setDedupeDeleteImportProgress(percent, '上传中:' + percent + '%');
|
||||
}
|
||||
};
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState !== 4) return;
|
||||
if (xhr.status < 200 || xhr.status >= 300) {
|
||||
msgEl.textContent = '请求失败';
|
||||
msgEl.className = 'msg err';
|
||||
return;
|
||||
}
|
||||
var res;
|
||||
try { res = JSON.parse(xhr.responseText || '{}'); } catch (e) { res = { success: false, error: '返回格式错误' }; }
|
||||
if (!res.success) {
|
||||
msgEl.textContent = res.error || '删除失败';
|
||||
msgEl.className = 'msg err';
|
||||
return;
|
||||
}
|
||||
setDedupeDeleteImportProgress(100, '上传完成,后端处理中...');
|
||||
pollDedupeDeleteImport(res.import_id);
|
||||
fileInput.value = '';
|
||||
};
|
||||
xhr.onerror = function() {
|
||||
msgEl.textContent = '请求失败';
|
||||
msgEl.className = 'msg err';
|
||||
};
|
||||
xhr.send(formData);
|
||||
};
|
||||
document.getElementById('btnSaveDedupeTotalData').onclick = function() {
|
||||
var itemId = document.getElementById('editDedupeTotalDataId').value;
|
||||
var value = (document.getElementById('editDedupeTotalDataValue').value || '').trim();
|
||||
|
||||
Reference in New Issue
Block a user