fix: 留言板区分业务序列号与系统追溯码
语义修正: Product.serial_number = 16位HEX系统追溯码(如000000000000000D) Product.external_serial = 业务产品序列号(如25022) 后端: - ProductMessageItem 新增 external_serial 字段 - search_product_messages 关联查询 Product.external_serial - 关键词搜索也支持按 external_serial 匹配 前端显示: 样品升降台V1J · 序列号: 25022 ← 醒目 追溯码: 000000000000000D ← 10px浅灰小字
This commit is contained in:
@ -38,7 +38,8 @@ class ProductMessageItem(BaseModel):
|
||||
id: str
|
||||
content: str
|
||||
operator_name: str # 留言人中文姓名
|
||||
product_sn: str # 16位SN
|
||||
product_sn: str # 16位HEX系统追溯码
|
||||
external_serial: str | None # 业务产品序列号(如 25022)
|
||||
material_name: str # 物料名称
|
||||
created_at: str # ISO时间字符串
|
||||
|
||||
@ -194,9 +195,9 @@ async def search_product_messages(
|
||||
from app.models.product import Product
|
||||
from app.core.time_utils import BEIJING_TZ
|
||||
|
||||
# 基础查询
|
||||
# 基础查询 — 同时取出 16位追溯码 + 业务序列号
|
||||
stmt = (
|
||||
select(ProductMessage, Product.serial_number, Product.material_name)
|
||||
select(ProductMessage, Product.serial_number, Product.material_name, Product.external_serial)
|
||||
.join(Product, ProductMessage.product_id == Product.id)
|
||||
)
|
||||
|
||||
@ -205,6 +206,7 @@ async def search_product_messages(
|
||||
kw = f"%{keyword.strip()}%"
|
||||
stmt = stmt.where(or_(
|
||||
Product.serial_number.ilike(kw),
|
||||
Product.external_serial.ilike(kw),
|
||||
Product.material_name.ilike(kw),
|
||||
ProductMessage.operator_id.ilike(kw),
|
||||
ProductMessage.content.ilike(kw),
|
||||
@ -227,7 +229,7 @@ async def search_product_messages(
|
||||
name_map = get_display_names(raw_ids)
|
||||
|
||||
items: list[ProductMessageItem] = []
|
||||
for msg, sn, mat_name in rows:
|
||||
for msg, sn, mat_name, ext_sn in rows:
|
||||
t = msg.created_at
|
||||
if t:
|
||||
if t.tzinfo is None:
|
||||
@ -243,6 +245,7 @@ async def search_product_messages(
|
||||
content=msg.content,
|
||||
operator_name=name_map.get(msg.operator_id, msg.operator_id),
|
||||
product_sn=sn or "",
|
||||
external_serial=ext_sn or None,
|
||||
material_name=mat_name or "",
|
||||
created_at=time_str,
|
||||
))
|
||||
|
||||
@ -127,11 +127,15 @@ function MsgRow({ m }: { m: ProductMessageItem }) {
|
||||
<span className="shrink-0 text-xs text-gray-400">{t}</span>
|
||||
</div>
|
||||
<p className="mb-2 text-sm leading-relaxed text-gray-600">{m.content}</p>
|
||||
<div className="flex items-center gap-1 text-xs text-gray-500">
|
||||
<div className="flex flex-col gap-0.5">
|
||||
{m.material_name && (
|
||||
<span className="font-medium text-gray-700">{m.material_name}</span>
|
||||
<span className="text-xs">
|
||||
<span className="font-semibold text-gray-700">{m.material_name}</span>
|
||||
<span className="text-gray-400"> · 序列号: </span>
|
||||
<span className="font-medium text-gray-600">{m.external_serial || "未录入"}</span>
|
||||
</span>
|
||||
)}
|
||||
<span className="font-mono text-gray-400">(SN: {m.product_sn})</span>
|
||||
<span className="text-[10px] text-gray-300 font-mono">追溯码: {m.product_sn}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -30,6 +30,7 @@ export interface ProductMessageItem {
|
||||
content: string;
|
||||
operator_name: string;
|
||||
product_sn: string;
|
||||
external_serial: string | null;
|
||||
material_name: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user