From 89e5a2162a44d1e8c10b1416e037b6b387e518d4 Mon Sep 17 00:00:00 2001 From: wangbeihong Date: Sun, 8 Mar 2026 03:07:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E7=9B=92=E5=AD=90?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=E8=87=AA=E5=8A=A8=E7=94=9F=E6=88=90=E5=92=8C?= =?UTF-8?q?=E5=94=AF=E4=B8=80=E6=80=A7=E6=A3=80=E6=9F=A5=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=8C=96=E5=88=9B=E5=BB=BA=E5=92=8C=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E7=9B=92=E5=AD=90=E7=9A=84=E7=95=8C=E9=9D=A2=E6=8F=90?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 ++++ app.py | 67 +++++++++++++++++++++++++++++++++++--------- templates/index.html | 5 ++-- 3 files changed, 62 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 1b14ae0..98b0927 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ v1.1 新增能力: - 支持盒子改名和删除。 - 新增盒子时可设置 `前缀 + 起始序号`,内部编号自动递增。 +- 盒子名称自动生成:`基础名称 + 编号范围`,重名自动加 `#2/#3`。 - 首页可直接看到每个盒子的编号范围(如 `A1-A28`)。 - 首页新增概览按钮:快速查看已启用的编号与名称。 - 编辑页支持 `启用/停用`。 @@ -125,6 +126,11 @@ python app.py - 前缀 `A`、起始 `1`、容量 28 -> `A1-A28` - 前缀 `B`、起始 `100`、容量 14 -> `B100-B113` +盒子名生成示例: + +- 基础名称 `电阻盒` + 范围 `A1-A28` -> `电阻盒 A1-A28` +- 若发生重名会自动变为:`电阻盒 A1-A28 #2` + ## 6. 元器件命名建议(简洁版) 为避免命名过长又保证可检索,建议: diff --git a/app.py b/app.py index 936cfde..72f177e 100644 --- a/app.py +++ b/app.py @@ -121,6 +121,33 @@ def slot_range_label(box: Box) -> str: return f"{start_code}-{end_code}" +def compose_box_name(base_name: str, prefix: str, start_number: int, slot_capacity: int) -> str: + base = (base_name or "").strip() + if not base: + base = "盒子" + end_number = start_number + slot_capacity - 1 + return f"{base} {prefix}{start_number}-{prefix}{end_number}" + + +def make_unique_box_name(candidate_name: str, exclude_box_id: int = None) -> str: + name = candidate_name + counter = 2 + while True: + query = Box.query.filter_by(name=name) + if exclude_box_id is not None: + query = query.filter(Box.id != exclude_box_id) + if not query.first(): + return name + name = f"{candidate_name} #{counter}" + counter += 1 + + +def infer_base_name(box: Box) -> str: + pattern = rf"\s+{re.escape(box.slot_prefix)}\d+-{re.escape(box.slot_prefix)}\d+(?:\s+#\d+)?$" + base = re.sub(pattern, "", box.name).strip() + return base or box.name + + def slot_data_for_box(box: Box): components = Component.query.filter_by(box_id=box.id).all() slot_map = {c.slot_index: c for c in components} @@ -263,6 +290,7 @@ def index(): "used_count": len(overview_rows), "slot_range": slot_range_label(box), "overview_rows": overview_rows, + "base_name": infer_base_name(box), } ) @@ -272,16 +300,14 @@ def index(): @app.route("/boxes/create", methods=["POST"]) def create_box(): box_type = request.form.get("box_type", "small_28").strip() - name = request.form.get("name", "").strip() + base_name = request.form.get("name", "").strip() description = request.form.get("description", "").strip() slot_prefix = request.form.get("slot_prefix", "").strip().upper() if box_type not in BOX_TYPES: return "无效盒子类型", 400 - if not name: + if not base_name: return "盒子名称不能为空", 400 - if Box.query.filter_by(name=name).first(): - return "盒子名称已存在,请更换", 400 try: start_number = _parse_non_negative_int(request.form.get("start_number", "1"), 1) @@ -289,12 +315,21 @@ def create_box(): return "起始序号必须是大于等于 0 的整数", 400 meta = BOX_TYPES[box_type] + effective_prefix = slot_prefix or meta["default_prefix"] + generated_name = compose_box_name( + base_name=base_name, + prefix=effective_prefix, + start_number=start_number, + slot_capacity=meta["default_capacity"], + ) + final_name = make_unique_box_name(generated_name) + box = Box( - name=name, + name=final_name, description=description or meta["default_desc"], box_type=box_type, slot_capacity=meta["default_capacity"], - slot_prefix=slot_prefix or meta["default_prefix"], + slot_prefix=effective_prefix, start_number=start_number, ) db.session.add(box) @@ -306,25 +341,29 @@ def create_box(): def update_box(box_id: int): box = Box.query.get_or_404(box_id) - new_name = request.form.get("name", "").strip() + base_name = request.form.get("name", "").strip() description = request.form.get("description", "").strip() slot_prefix = request.form.get("slot_prefix", "").strip().upper() - if not new_name: + if not base_name: return "盒子名称不能为空", 400 - duplicate = Box.query.filter(Box.name == new_name, Box.id != box.id).first() - if duplicate: - return "盒子名称已存在,请更换", 400 - try: start_number = _parse_non_negative_int(request.form.get("start_number", "1"), 1) except ValueError: return "起始序号必须是大于等于 0 的整数", 400 - box.name = new_name + effective_prefix = slot_prefix or BOX_TYPES[box.box_type]["default_prefix"] + generated_name = compose_box_name( + base_name=base_name, + prefix=effective_prefix, + start_number=start_number, + slot_capacity=box.slot_capacity, + ) + + box.name = make_unique_box_name(generated_name, exclude_box_id=box.id) box.description = description or BOX_TYPES[box.box_type]["default_desc"] - box.slot_prefix = slot_prefix or BOX_TYPES[box.box_type]["default_prefix"] + box.slot_prefix = effective_prefix box.start_number = start_number db.session.commit() return redirect(url_for("index")) diff --git a/templates/index.html b/templates/index.html index f24f520..abfa45a 100644 --- a/templates/index.html +++ b/templates/index.html @@ -24,7 +24,7 @@
- + @@ -61,8 +61,9 @@
设置(改名/前缀/起始号) +

输入基础名称后,系统会自动生成: 基础名称 + 编号范围。

- +