diff --git a/inventory-backend/app/api/v1/import_api.py b/inventory-backend/app/api/v1/import_api.py index 842e5ad..9e4b453 100644 --- a/inventory-backend/app/api/v1/import_api.py +++ b/inventory-backend/app/api/v1/import_api.py @@ -47,9 +47,16 @@ def download_template(): @jwt_required() @permission_required('material_list:operation') def preview_import(): - """Dry-Run 预览 + 验证(不写入数据库)""" + """Dry-Run 预览 + 验证(不写入数据库) + + FormData: + type: 'material' | 'bom' + file: Excel 文件 + mode: 'skip' (默认) | 'update' — update 模式下 DB 重复行显示为「将被更新」而非错误 + """ try: import_type = request.form.get('type', 'material').strip() + mode = request.form.get('mode', 'skip').strip() file = request.files.get('file') if not file: return jsonify({'code': 400, 'msg': '请上传文件'}), 400 @@ -60,11 +67,11 @@ def preview_import(): from io import BytesIO if import_type == 'material': - results = preview_material(BytesIO(file_stream)) + results = preview_material(BytesIO(file_stream), mode=mode) else: results = preview_bom(BytesIO(file_stream)) - success_count = sum(1 for r in results if r['status'] == 'success') + success_count = sum(1 for r in results if r['status'] in ('success', 'update')) error_count = sum(1 for r in results if r['status'] == 'error') return jsonify({ @@ -85,24 +92,33 @@ def preview_import(): @jwt_required() @permission_required('material_list:operation') def execute_import(): - """确认导入执行(事务保护)""" + """确认导入执行 + + Body: + type: 'material' | 'bom' + rows: 待导入行列表 + mode: 'skip' (跳过重复,默认) | 'update' (覆盖更新已有记录) + """ try: data = request.get_json() or {} import_type = data.get('type', 'material').strip() rows = data.get('rows', []) + mode = data.get('mode', 'skip').strip() if not rows: return jsonify({'code': 400, 'msg': '导入数据不能为空'}), 400 if import_type not in ('material', 'bom'): return jsonify({'code': 400, 'msg': 'type 必须为 material 或 bom'}), 400 + if mode not in ('skip', 'update'): + return jsonify({'code': 400, 'msg': 'mode 必须为 skip 或 update'}), 400 - # 仅导入状态为 success 的行 - valid_rows = [r for r in rows if r.get('status') == 'success'] + # 仅导入状态为 success 或 update 的行,error 行不参与导入 + valid_rows = [r for r in rows if r.get('status') in ('success', 'update')] if not valid_rows: - return jsonify({'code': 400, 'msg': '没有可导入的有效数据(全部为error状态)'}), 400 + return jsonify({'code': 400, 'msg': '没有可导入的有效数据'}), 400 if import_type == 'material': - result = execute_material_import(valid_rows) + result = execute_material_import(valid_rows, mode=mode) else: result = execute_bom_import(valid_rows)