diff --git a/inventory-backend/app/models/inbound/semi.py b/inventory-backend/app/models/inbound/semi.py index a2b9520..d750a8b 100644 --- a/inventory-backend/app/models/inbound/semi.py +++ b/inventory-backend/app/models/inbound/semi.py @@ -1,5 +1,6 @@ # app/models/inbound/semi.py from app.extensions import db +import json class StockSemi(db.Model): @@ -41,11 +42,17 @@ class StockSemi(db.Model): production_time_range = db.Column(db.String(255)) quality_status = db.Column(db.String(50)) + + # [修改] 质量报告 (存储 JSON 字符串: 图片列表 + 链接) quality_report_link = db.Column(db.Text) + + # [新增] 到货图片 (存储 JSON 字符串) + arrival_photo = db.Column(db.Text) + detail_link = db.Column(db.Text) remark = db.Column(db.Text) - # [新增] 全局打印流水号 (请务必确保数据库已添加此列) + # [新增] 全局打印流水号 global_print_id = db.Column(db.Integer) # 关系定义 @@ -56,6 +63,18 @@ class StockSemi(db.Model): man_val = float(self.manual_cost or 0) unit_total = raw_val + man_val + # 辅助解析函数:将数据库存储的 JSON 字符串转为 List + def parse_img_list(json_str): + if not json_str: + return [] + try: + # 兼容旧数据:如果不是 JSON 格式(比如是单个 URL),则包装成 list + if not json_str.startswith('['): + return [json_str] + return json.loads(json_str) + except: + return [] + return { 'id': self.id, 'base_id': self.base_id, @@ -86,14 +105,19 @@ class StockSemi(db.Model): 'raw_material_cost': raw_val, 'manual_cost': man_val, 'unit_total_cost': unit_total, + 'total_price': float(self.total_price or 0), + 'production_manager': self.production_manager, 'production_time_range': self.production_time_range, - 'production_start_time': str(self.production_start_time) if self.production_start_time else '', 'production_end_time': str(self.production_end_time) if self.production_end_time else '', 'quality_status': self.quality_status, - 'quality_report_link': self.quality_report_link, + + # [修改] 解析 JSON 字符串为数组返回给前端 + 'quality_report_link': parse_img_list(self.quality_report_link), + 'arrival_photo': parse_img_list(self.arrival_photo), + 'detail_link': self.detail_link, 'remark': self.remark, diff --git a/inventory-backend/app/services/inbound/semi_service.py b/inventory-backend/app/services/inbound/semi_service.py index 72427c2..27f5c62 100644 --- a/inventory-backend/app/services/inbound/semi_service.py +++ b/inventory-backend/app/services/inbound/semi_service.py @@ -1,12 +1,10 @@ # app/services/inbound/semi_service.py from app.extensions import db from app.models.base import MaterialBase -# --------------------------------------------------------------------- -# ❌ 头部禁止导入 StockSemi,防止 Circular Import -# --------------------------------------------------------------------- from datetime import datetime from sqlalchemy import or_, func, text import traceback +import json class SemiInboundService: @@ -42,7 +40,7 @@ class SemiInboundService: @staticmethod def handle_inbound(data): - # ✅ 【关键修复】局部导入 Model,解决循环引用 + # 局部导入 Model,解决循环引用 from app.models.inbound.semi import StockSemi try: @@ -79,7 +77,6 @@ class SemiInboundService: except: pass - # ✅ 优化:处理 time_range 字符串,防止前端传数组导致存入 None time_range_str = None raw_range = data.get('production_time_range') if isinstance(raw_range, list): @@ -94,9 +91,7 @@ class SemiInboundService: unit_total_cost = raw_cost + manual_cost total_value = unit_total_cost * in_qty - # ------------------------------------------------------------------ - # 4. 获取全局打印流水号 (跨表唯一) - # ------------------------------------------------------------------ + # 4. 获取全局打印流水号 next_global_id = 0 try: seq_sql = text("SELECT nextval('global_print_seq')") @@ -106,22 +101,25 @@ class SemiInboundService: print("❌ 数据库序列 global_print_seq 不存在,请执行SQL创建!") raise e - # ------------------------------------------------------------------ - # 5. 自动生成 SKU (格式: 00000001) - # ------------------------------------------------------------------ + # 5. 自动生成 SKU generated_sku = str(next_global_id).zfill(10) final_sku = data.get('sku') if not final_sku: final_sku = generated_sku - # ------------------------------------------------------------------ # 6. 条码逻辑处理 - # ------------------------------------------------------------------ final_barcode = data.get('barcode') if not final_barcode: final_barcode = final_sku - # 7. 创建记录 + # 7. 图片列表转 JSON 字符串处理 + arrival_list = data.get('arrival_photo', []) + quality_report_list = data.get('quality_report_link', []) + + if not isinstance(arrival_list, list): arrival_list = [] + if not isinstance(quality_report_list, list): quality_report_list = [] + + # 8. 创建记录 new_stock = StockSemi( base_id=material.id, global_print_id=next_global_id, @@ -152,7 +150,10 @@ class SemiInboundService: manual_cost=manual_cost, total_price=total_value, - quality_report_link=data.get('quality_report_link'), + # [核心修改] 将列表转为 JSON 字符串存储 + arrival_photo=json.dumps(arrival_list), + quality_report_link=json.dumps(quality_report_list), + detail_link=data.get('detail_link'), remark=data.get('remark') ) @@ -190,7 +191,6 @@ class SemiInboundService: 'bom_version': 'bom_version', 'work_order_code': 'work_order_code', 'production_manager': 'production_manager', - 'quality_report_link': 'quality_report_link', 'detail_link': 'detail_link', 'remark': 'remark' } @@ -199,6 +199,17 @@ class SemiInboundService: if frontend_key in data: setattr(stock, db_attr, data[frontend_key]) + # [核心修改] 图片字段更新 (List -> JSON String) + if 'arrival_photo' in data: + imgs = data['arrival_photo'] + if isinstance(imgs, list): + stock.arrival_photo = json.dumps(imgs) + + if 'quality_report_link' in data: + imgs = data['quality_report_link'] + if isinstance(imgs, list): + stock.quality_report_link = json.dumps(imgs) + # 时间处理 if 'production_start_time' in data: try: @@ -317,11 +328,9 @@ class SemiInboundService: items = [] for item in current_items: stats = stock_map.get(item.base_id, {'total_stock': 0, 'total_avail': 0}) - d = item.to_dict() d['sum_stock'] = stats['total_stock'] d['sum_available'] = stats['total_avail'] - items.append(d) return {"total": pagination.total, "items": items} diff --git a/inventory-web/src/views/stock/inbound/semi.vue b/inventory-web/src/views/stock/inbound/semi.vue index f9edf4d..75171a3 100644 --- a/inventory-web/src/views/stock/inbound/semi.vue +++ b/inventory-web/src/views/stock/inbound/semi.vue @@ -4,14 +4,14 @@
打印机 IP: 192.168.9.205
尺寸: 40mm x 30mm
@@ -420,9 +588,9 @@ \ No newline at end of file