chore: customize branding for Baihua

This commit is contained in:
汤学会 2026-06-14 21:05:49 +08:00
parent df9a4b485d
commit e90d296047
68 changed files with 173 additions and 280 deletions

View File

@ -6,7 +6,7 @@ product
## Users ## Users
嘉恒五金 ERP 面向采购、销售、仓库、生产、财务、售后和管理人员。用户通常在真实业务现场或办公室中处理订单、入库、出库、生产台账、发货、权限和经营数据,需要快速、准确、少解释地完成工作。 百华五金 ERP 面向采购、销售、仓库、生产、财务、售后和管理人员。用户通常在真实业务现场或办公室中处理订单、入库、出库、生产台账、发货、权限和经营数据,需要快速、准确、少解释地完成工作。
## Product Purpose ## Product Purpose

View File

@ -1,6 +1,6 @@
# ForgeFlow ERP # ForgeFlow ERP
宁波嘉恒智能科技有限公司五金行业 ERP 初始骨架,采用前后端分离架构: 宁波百华智能科技有限公司五金行业 ERP 初始骨架,采用前后端分离架构:
- 前端Vue 3 + Vite - 前端Vue 3 + Vite
- 后端FastAPI - 后端FastAPI

View File

@ -1866,7 +1866,7 @@ def _default_miniapp_product_import_point_name(db: Session) -> str:
.order_by(MiniAppAttendancePoint.name.asc()) .order_by(MiniAppAttendancePoint.name.asc())
.limit(1) .limit(1)
) )
or "宁波嘉恒智能科技有限公司" or "宁波百华智能科技有限公司"
) )

View File

@ -119,13 +119,13 @@ def _get_notice_creator_phone(db: Session) -> str:
def _assistant_config_read(row: AiAssistantConfig | None) -> AiAssistantConfigRead: def _assistant_config_read(row: AiAssistantConfig | None) -> AiAssistantConfigRead:
if not row: if not row:
return AiAssistantConfigRead( return AiAssistantConfigRead(
assistant_name="嘉恒工艺助手", assistant_name="百华工艺助手",
provider_name="", provider_name="",
api_base_url="", api_base_url="",
api_key=None, api_key=None,
model_name="", model_name="",
temperature=0.3, temperature=0.3,
system_prompt="你是宁波嘉恒智能五金 ERP 的企业助手,优先解释业务流程、字段含义、数据异常和操作步骤。", system_prompt="你是宁波百华智能五金 ERP 的企业助手,优先解释业务流程、字段含义、数据异常和操作步骤。",
enabled=False, enabled=False,
config_id=None, config_id=None,
api_key_configured=False, api_key_configured=False,

View File

@ -6,7 +6,7 @@ from sqlalchemy.engine import URL
class Settings(BaseSettings): class Settings(BaseSettings):
app_name: str = Field(default="Jiaheng Hardware ERP API", alias="APP_NAME") app_name: str = Field(default="Baihua Hardware ERP API", alias="APP_NAME")
app_env: str = Field(default="dev", alias="APP_ENV") app_env: str = Field(default="dev", alias="APP_ENV")
app_host: str = Field(default="0.0.0.0", alias="APP_HOST") app_host: str = Field(default="0.0.0.0", alias="APP_HOST")
app_port: int = Field(default=8000, alias="APP_PORT") app_port: int = Field(default=8000, alias="APP_PORT")

View File

@ -49,5 +49,5 @@ def root() -> dict[str, str]:
return { return {
"name": settings.app_name, "name": settings.app_name,
"env": settings.app_env, "env": settings.app_env,
"message": "Jiaheng Hardware ERP API is running.", "message": "Baihua Hardware ERP API is running.",
} }

View File

@ -49,7 +49,7 @@ class MiniAppPersonAttendancePoint(Base):
class MiniAppProduct(Base): class MiniAppProduct(Base):
__tablename__ = "products" __tablename__ = "products"
attendance_point_name: Mapped[str] = mapped_column(String(128), primary_key=True, server_default=text("'宁波嘉恒智能科技有限公司'")) attendance_point_name: Mapped[str] = mapped_column(String(128), primary_key=True, server_default=text("'宁波百华智能科技有限公司'"))
project_no: Mapped[str] = mapped_column(String(64), primary_key=True) project_no: Mapped[str] = mapped_column(String(64), primary_key=True)
product_name: Mapped[str] = mapped_column(String(255), primary_key=True) product_name: Mapped[str] = mapped_column(String(255), primary_key=True)
device_no: Mapped[str] = mapped_column(String(64), primary_key=True) device_no: Mapped[str] = mapped_column(String(64), primary_key=True)
@ -74,7 +74,7 @@ class MiniAppProductionReport(Base):
__tablename__ = "production_reports" __tablename__ = "production_reports"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True) id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
attendance_point_name: Mapped[str] = mapped_column(String(128), server_default=text("'宁波嘉恒智能科技有限公司'")) attendance_point_name: Mapped[str] = mapped_column(String(128), server_default=text("'宁波百华智能科技有限公司'"))
session_id: Mapped[int] = mapped_column(BigInteger) session_id: Mapped[int] = mapped_column(BigInteger)
employee_phone: Mapped[str] = mapped_column(ForeignKey("personnel.phone")) employee_phone: Mapped[str] = mapped_column(ForeignKey("personnel.phone"))
report_date: Mapped[object] = mapped_column(Date) report_date: Mapped[object] = mapped_column(Date)
@ -103,7 +103,7 @@ class MiniAppProductionReportItem(Base):
id: Mapped[int] = mapped_column(BigInteger, primary_key=True) id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
report_id: Mapped[int] = mapped_column(ForeignKey("production_reports.id")) report_id: Mapped[int] = mapped_column(ForeignKey("production_reports.id"))
attendance_point_name: Mapped[str] = mapped_column(String(128), server_default=text("'宁波嘉恒智能科技有限公司'")) attendance_point_name: Mapped[str] = mapped_column(String(128), server_default=text("'宁波百华智能科技有限公司'"))
device_no: Mapped[str] = mapped_column(String(64)) device_no: Mapped[str] = mapped_column(String(64))
project_no: Mapped[str] = mapped_column(String(64)) project_no: Mapped[str] = mapped_column(String(64))
product_name: Mapped[str] = mapped_column(String(255)) product_name: Mapped[str] = mapped_column(String(255))

View File

@ -167,7 +167,7 @@ class AiAssistantConfig(Base):
__tablename__ = "sys_ai_assistant_config" __tablename__ = "sys_ai_assistant_config"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True) id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
assistant_name: Mapped[str] = mapped_column(String(100), server_default=text("'嘉恒工艺助手'")) assistant_name: Mapped[str] = mapped_column(String(100), server_default=text("'百华工艺助手'"))
provider_name: Mapped[str | None] = mapped_column(String(100), nullable=True) provider_name: Mapped[str | None] = mapped_column(String(100), nullable=True)
api_base_url: Mapped[str | None] = mapped_column(String(255), nullable=True) api_base_url: Mapped[str | None] = mapped_column(String(255), nullable=True)
api_key: Mapped[str | None] = mapped_column(String(512), nullable=True) api_key: Mapped[str | None] = mapped_column(String(512), nullable=True)

View File

@ -30,7 +30,7 @@ class BroadcastMessageRead(BroadcastMessageCreate):
class AiAssistantConfigUpdate(BaseModel): class AiAssistantConfigUpdate(BaseModel):
assistant_name: str = Field(default="嘉恒工艺助手", min_length=1, max_length=100) assistant_name: str = Field(default="百华工艺助手", min_length=1, max_length=100)
provider_name: str | None = None provider_name: str | None = None
api_base_url: str | None = None api_base_url: str | None = None
api_key: str | None = None api_key: str | None = None

View File

@ -6,7 +6,7 @@ from app.schemas.domain import CostInsight, InventoryLotSummary, MiniAppField, O
def get_dashboard_payload() -> DashboardPayload: def get_dashboard_payload() -> DashboardPayload:
return DashboardPayload( return DashboardPayload(
company="宁波嘉恒智能科技有限公司", company="宁波百华智能科技有限公司",
overview=[ overview=[
OverviewMetric( OverviewMetric(
code="sales_open", code="sales_open",

View File

@ -58,7 +58,7 @@ MENU_PERMISSION_TREE = [
("MENU_PURCHASE_ORDER", "采购订单", []), ("MENU_PURCHASE_ORDER", "采购订单", []),
("MENU_PURCHASE_RECEIPT", "到货入库", []), ("MENU_PURCHASE_RECEIPT", "到货入库", []),
("MENU_QUALITY_INSPECTION", "质量检验", []), ("MENU_QUALITY_INSPECTION", "质量检验", []),
("MENU_INVENTORY_LEDGER", "嘉恒仓库", []), ("MENU_INVENTORY_LEDGER", "百华仓库", []),
], ],
), ),
( (

View File

@ -16,7 +16,7 @@ CREATE TABLE IF NOT EXISTS sys_broadcast_message (
CREATE TABLE IF NOT EXISTS sys_ai_assistant_config ( CREATE TABLE IF NOT EXISTS sys_ai_assistant_config (
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID', id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
assistant_name VARCHAR(100) NOT NULL DEFAULT '嘉恒工艺助手' COMMENT '助手名称', assistant_name VARCHAR(100) NOT NULL DEFAULT '百华工艺助手' COMMENT '助手名称',
provider_name VARCHAR(100) NULL COMMENT 'LLM供应商名称', provider_name VARCHAR(100) NULL COMMENT 'LLM供应商名称',
api_base_url VARCHAR(255) NULL COMMENT 'LLM API基础地址', api_base_url VARCHAR(255) NULL COMMENT 'LLM API基础地址',
api_key VARCHAR(512) NULL COMMENT 'LLM API密钥', api_key VARCHAR(512) NULL COMMENT 'LLM API密钥',

View File

@ -71,7 +71,7 @@ SET role_name = '采购专员', remark = '供应商、采购订单、到货和
WHERE role_code = 'PURCHASER'; WHERE role_code = 'PURCHASER';
UPDATE sys_role UPDATE sys_role
SET role_name = '仓库管理人员', remark = '到货、质检、嘉恒仓库、发货台账相关作业' SET role_name = '仓库管理人员', remark = '到货、质检、百华仓库、发货台账相关作业'
WHERE role_code = 'WAREHOUSE'; WHERE role_code = 'WAREHOUSE';
UPDATE sys_role UPDATE sys_role

View File

@ -152,7 +152,7 @@ CREATE TABLE IF NOT EXISTS sys_broadcast_message (
CREATE TABLE IF NOT EXISTS sys_ai_assistant_config ( CREATE TABLE IF NOT EXISTS sys_ai_assistant_config (
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID', id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
assistant_name VARCHAR(100) NOT NULL DEFAULT '嘉恒工艺助手' COMMENT '助手名称', assistant_name VARCHAR(100) NOT NULL DEFAULT '百华工艺助手' COMMENT '助手名称',
provider_name VARCHAR(100) NULL COMMENT 'LLM供应商名称', provider_name VARCHAR(100) NULL COMMENT 'LLM供应商名称',
api_base_url VARCHAR(255) NULL COMMENT 'LLM API基础地址', api_base_url VARCHAR(255) NULL COMMENT 'LLM API基础地址',
api_key VARCHAR(512) NULL COMMENT 'LLM API密钥', api_key VARCHAR(512) NULL COMMENT 'LLM API密钥',

View File

@ -308,7 +308,7 @@ SELECT
(SELECT id FROM md_unit WHERE unit_code = 'PCS'), (SELECT id FROM md_unit WHERE unit_code = 'PCS'),
(SELECT id FROM md_unit WHERE unit_code = 'PCS'), (SELECT id FROM md_unit WHERE unit_code = 'PCS'),
500.000000, 0.000000, 500.000000, 0.000000,
0.0000, 'ACTIVE', '宁波嘉恒智能本体示例成品用于演示销售、MRP、工单、成本闭环' 0.0000, 'ACTIVE', '宁波百华智能本体示例成品用于演示销售、MRP、工单、成本闭环'
FROM DUAL FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM md_item WHERE item_code = 'FG-BT-001'); WHERE NOT EXISTS (SELECT 1 FROM md_item WHERE item_code = 'FG-BT-001');
@ -594,7 +594,7 @@ INSERT INTO em_equipment (
SELECT SELECT
'EQ-QA-01', '终检包装工位 01', '检验工位', 'EQ-QA-01', '终检包装工位 01', '检验工位',
(SELECT id FROM md_work_center WHERE center_code = 'WC-QA-01'), (SELECT id FROM md_work_center WHERE center_code = 'WC-QA-01'),
'嘉恒内部配置', 'QA-STATION', '2024-03-10', 1.50, 4.00, 300.00, '百华内部配置', 'QA-STATION', '2024-03-10', 1.50, 4.00, 300.00,
DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 25 DAY), DATE_ADD(CURRENT_TIMESTAMP, INTERVAL 20 DAY), DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 25 DAY), DATE_ADD(CURRENT_TIMESTAMP, INTERVAL 20 DAY),
'IDLE', '终检与包装工位' 'IDLE', '终检与包装工位'
FROM DUAL FROM DUAL

View File

@ -265,7 +265,7 @@ class SalesOrderDeliveryTraceTest(unittest.TestCase):
def _seed_inventory_ledger_employee_permission(self) -> Employee: def _seed_inventory_ledger_employee_permission(self) -> Employee:
return self._seed_employee_permission( return self._seed_employee_permission(
"MENU_INVENTORY_LEDGER", "MENU_INVENTORY_LEDGER",
"嘉恒仓库", "百华仓库",
"INVENTORY_LEDGER", "INVENTORY_LEDGER",
"WAREHOUSE", "WAREHOUSE",
"仓库人员", "仓库人员",

View File

@ -214,7 +214,7 @@ class SelectedStockLotProductionIssueTest(unittest.TestCase):
self.db.add( self.db.add(
MiniAppProductionReport( MiniAppProductionReport(
id=9000 + item_id, id=9000 + item_id,
attendance_point_name="宁波嘉恒智能科技有限公司", attendance_point_name="宁波百华智能科技有限公司",
session_id=8000 + item_id, session_id=8000 + item_id,
employee_phone="13800000000", employee_phone="13800000000",
report_date=timestamp.date(), report_date=timestamp.date(),
@ -238,7 +238,7 @@ class SelectedStockLotProductionIssueTest(unittest.TestCase):
item = MiniAppProductionReportItem( item = MiniAppProductionReportItem(
id=item_id, id=item_id,
report_id=9000 + item_id, report_id=9000 + item_id,
attendance_point_name="宁波嘉恒智能科技有限公司", attendance_point_name="宁波百华智能科技有限公司",
device_no="", device_no="",
project_no=self.product.item_code, project_no=self.product.item_code,
product_name=self.product.item_name, product_name=self.product.item_name,

View File

@ -1,4 +1,4 @@
# 嘉恒智能五金 ERP 生产使用案例 # 百华智能五金 ERP 生产使用案例
## 案例背景 ## 案例背景

View File

@ -2,7 +2,7 @@
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Change 嘉恒仓库盘库 into a current-selected-warehouse-only flow: select a warehouse bar first, click 盘库, confirm/export one locked warehouse sheet, import only that same stocktake workbook, show a modal diff immediately, and confirm to reset that warehouse inventory and unlock it. **Goal:** Change 百华仓库盘库 into a current-selected-warehouse-only flow: select a warehouse bar first, click 盘库, confirm/export one locked warehouse sheet, import only that same stocktake workbook, show a modal diff immediately, and confirm to reset that warehouse inventory and unlock it.
**Architecture:** Backend becomes the source of truth for single-warehouse stocktake rules, workbook validation token checks, import overwrite behavior, and current-warehouse history filtering. Frontend removes multi-warehouse selection from the stocktake dialog and renders two blocks: a stocktake flow block for the currently selected warehouse and a stocktake records block filtered to that warehouse. The diff review is opened as a modal immediately after each import; cancel closes the modal and leaves the warehouse locked for re-import. **Architecture:** Backend becomes the source of truth for single-warehouse stocktake rules, workbook validation token checks, import overwrite behavior, and current-warehouse history filtering. Frontend removes multi-warehouse selection from the stocktake dialog and renders two blocks: a stocktake flow block for the currently selected warehouse and a stocktake records block filtered to that warehouse. The diff review is opened as a modal immediately after each import; cancel closes the modal and leaves the warehouse locked for re-import.
@ -1072,7 +1072,7 @@ Expected: Vite exits code 0. Existing chunk warning is acceptable.
Use the running ERP UI and verify: Use the running ERP UI and verify:
```text ```text
1. Select 原材料库 in 嘉恒仓库 warehouse bar. 1. Select 原材料库 in 百华仓库 warehouse bar.
2. Click 盘库. 2. Click 盘库.
3. Dialog shows 当前仓库:原材料库 and no multi-warehouse checkbox cards. 3. Dialog shows 当前仓库:原材料库 and no multi-warehouse checkbox cards.
4. Click 确认盘库并导出仓库清单. 4. Click 确认盘库并导出仓库清单.

View File

@ -2,7 +2,7 @@
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Build a "盘库" feature in 嘉恒仓库 that locks selected warehouses, exports stocktake sheets, imports counted results, shows a side-by-side diff, posts adjustments, records audit logs, and unlocks warehouses after confirmation. **Goal:** Build a "盘库" feature in 百华仓库 that locks selected warehouses, exports stocktake sheets, imports counted results, shows a side-by-side diff, posts adjustments, records audit logs, and unlocks warehouses after confirmation.
**Architecture:** Backend owns stocktake locking, snapshots, Excel import/export, diff calculation, and inventory adjustment transactions. Frontend adds a stocktake entry above the warehouse bar, drives a wizard-style dialog, and renders a code-diff-like two-table comparison before confirmation. Inventory mutation endpoints must call a shared lock guard so locked warehouses cannot be changed outside stocktake. **Architecture:** Backend owns stocktake locking, snapshots, Excel import/export, diff calculation, and inventory adjustment transactions. Frontend adds a stocktake entry above the warehouse bar, drives a wizard-style dialog, and renders a code-diff-like two-table comparison before confirmation. Inventory mutation endpoints must call a shared lock guard so locked warehouses cannot be changed outside stocktake.
@ -1955,7 +1955,7 @@ Create `frontend/src/components/StocktakeDialog.vue`:
<section class="stocktake-shell"> <section class="stocktake-shell">
<header class="stocktake-head"> <header class="stocktake-head">
<div> <div>
<p class="eyebrow">嘉恒仓库 · 盘库</p> <p class="eyebrow">百华仓库 · 盘库</p>
<h3>{{ activeStocktake ? activeStocktake.stocktake_no : "新建盘库" }}</h3> <h3>{{ activeStocktake ? activeStocktake.stocktake_no : "新建盘库" }}</h3>
</div> </div>
<button class="ghost-button" type="button" @click="$emit('close')">关闭</button> <button class="ghost-button" type="button" @click="$emit('close')">关闭</button>
@ -2125,7 +2125,7 @@ async function startStocktake() {
try { try {
activeStocktake.value = await postResource("/inventory/stocktakes", { activeStocktake.value = await postResource("/inventory/stocktakes", {
warehouse_ids: selectedWarehouseIds.value, warehouse_ids: selectedWarehouseIds.value,
remark: "嘉恒仓库盘库" remark: "百华仓库盘库"
}); });
activeStep.value = "export"; activeStep.value = "export";
emit("message", `盘库单 ${activeStocktake.value.stocktake_no} 已创建并锁库`); emit("message", `盘库单 ${activeStocktake.value.stocktake_no} 已创建并锁库`);
@ -2684,7 +2684,7 @@ Expected: PASS.
Run the app using the project's normal backend/frontend commands, then verify: Run the app using the project's normal backend/frontend commands, then verify:
```text ```text
1. 打开 采购与库存 -> 嘉恒仓库。 1. 打开 采购与库存 -> 百华仓库。
2. 点击仓库 bar 上方“盘库”。 2. 点击仓库 bar 上方“盘库”。
3. 默认勾选当前仓库。 3. 默认勾选当前仓库。
4. 点击“开始盘库并锁库”。 4. 点击“开始盘库并锁库”。

View File

@ -2,7 +2,7 @@
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Rebuild the 嘉恒仓库盘库 interaction so users can clearly start locked stocktakes, export/import sheets, review side-by-side differences, confirm adjustments, and continue unfinished stocktakes without confusing tab jumps or silent states. **Goal:** Rebuild the 百华仓库盘库 interaction so users can clearly start locked stocktakes, export/import sheets, review side-by-side differences, confirm adjustments, and continue unfinished stocktakes without confusing tab jumps or silent states.
**Architecture:** Keep the existing backend stocktake tables and core service flow. Add a small frontend workflow helper to centralize stocktake state decisions, then refactor `StocktakeDialog.vue` into a status-driven panel instead of a freely clickable five-tab wizard. Backend changes are limited to regression tests unless implementation finds an API defect. **Architecture:** Keep the existing backend stocktake tables and core service flow. Add a small frontend workflow helper to centralize stocktake state decisions, then refactor `StocktakeDialog.vue` into a status-driven panel instead of a freely clickable five-tab wizard. Backend changes are limited to regression tests unless implementation finds an API defect.
@ -1243,7 +1243,7 @@ Expected: command exits with code `0`.
Start backend and frontend using the project's normal local commands, then verify these paths in the browser: Start backend and frontend using the project's normal local commands, then verify these paths in the browser:
```text ```text
1. Open 嘉恒仓库 and click 盘库. 1. Open 百华仓库 and click 盘库.
2. Warehouse cards show 可盘库 or active stocktake status. 2. Warehouse cards show 可盘库 or active stocktake status.
3. Start a stocktake for one warehouse. 3. Start a stocktake for one warehouse.
4. Dialog moves to 导出清单 and shows the selected warehouse name. 4. Dialog moves to 导出清单 and shows the selected warehouse name.

View File

@ -12,7 +12,7 @@
## Scope And Decisions ## Scope And Decisions
- Add this only under `嘉恒仓库 -> 原材料库 -> 出库 -> 退货出库`. - Add this only under `百华仓库 -> 原材料库 -> 出库 -> 退货出库`.
- This is for material that already entered the warehouse and was later found quality/performance-unqualified. - This is for material that already entered the warehouse and was later found quality/performance-unqualified.
- This is not the same as purchase quality inspection rejection. Existing `PENDING_QC` / `REJECTED` quality flow stays unchanged. - This is not the same as purchase quality inspection rejection. Existing `PENDING_QC` / `REJECTED` quality flow stays unchanged.
- Raw material remains weight-only. Do not introduce raw-material quantity fields. - Raw material remains weight-only. Do not introduce raw-material quantity fields.
@ -1956,7 +1956,7 @@ Expected: first command finds the new feature in planned files. Second command m
Run the backend and frontend using the projects existing local start commands. If the commands are already running, reuse them. Then verify: Run the backend and frontend using the projects existing local start commands. If the commands are already running, reuse them. Then verify:
```text ```text
1. Open 嘉恒仓库. 1. Open 百华仓库.
2. Select 原材料库. 2. Select 原材料库.
3. Confirm 出库 row shows 生产出库、委外出库、报废出库、退货出库. 3. Confirm 出库 row shows 生产出库、委外出库、报废出库、退货出库.
4. Click 退货出库. 4. Click 退货出库.

View File

@ -2,7 +2,7 @@
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Add 嘉恒仓库“退货库” for customer-returned products that can be reworked, move the current “退货处理” entry into warehouse inbound operations, and add 废料库“退货废料入库” for customer-returned products judged as scrap. **Goal:** Add 百华仓库“退货库” for customer-returned products that can be reworked, move the current “退货处理” entry into warehouse inbound operations, and add 废料库“退货废料入库” for customer-returned products judged as scrap.
**Architecture:** Treat customer returns as inventory movement. `RETURN` warehouse lots represent returned finished goods waiting for rework and are locked until `返工出库`; customer-return scrap bypasses the return warehouse and enters `SCRAP` directly while retaining delivery-line and source-material traceability. The old 发货与售后退货入口 is removed from navigation, but existing return order/disposition tables remain the trace backbone. **Architecture:** Treat customer returns as inventory movement. `RETURN` warehouse lots represent returned finished goods waiting for rework and are locked until `返工出库`; customer-return scrap bypasses the return warehouse and enters `SCRAP` directly while retaining delivery-line and source-material traceability. The old 发货与售后退货入口 is removed from navigation, but existing return order/disposition tables remain the trace backbone.
@ -12,11 +12,11 @@
## Confirmed Business Rules ## Confirmed Business Rules
- “发货与售后”的“退货处理”入口去掉,退货登记逻辑移动到“嘉恒仓库 -> 退货库 -> 入库 -> 退货入库”。 - “发货与售后”的“退货处理”入口去掉,退货登记逻辑移动到“百华仓库 -> 退货库 -> 入库 -> 退货入库”。
- “退货库”只存放客户退回后判定可以返工的产品。 - “退货库”只存放客户退回后判定可以返工的产品。
- 退货库入库后的批次默认“待返工/锁定”,不能作为成品库存销售。 - 退货库入库后的批次默认“待返工/锁定”,不能作为成品库存销售。
- 退货库出库只有“返工出库”,出库后扣减退货库库存并生成返工处置/返工工单。 - 退货库出库只有“返工出库”,出库后扣减退货库库存并生成返工处置/返工工单。
- 客户退回后判定报废的产品不进入退货库,用户在“嘉恒仓库 -> 废料库 -> 入库 -> 退货废料入库”登记。 - 客户退回后判定报废的产品不进入退货库,用户在“百华仓库 -> 废料库 -> 入库 -> 退货废料入库”登记。
- 退货库需要“期初入库”,用于初始化历史退货待返工库存。 - 退货库需要“期初入库”,用于初始化历史退货待返工库存。
- 退货品明细必须展示发货单号或发货批次号,并通过发货明细追溯成品批次、原材料库存批次号、来源材料。 - 退货品明细必须展示发货单号或发货批次号,并通过发货明细追溯成品批次、原材料库存批次号、来源材料。
@ -26,7 +26,7 @@
- Add `RETURN` warehouse and default location. - Add `RETURN` warehouse and default location.
- Add `delivery_item_id` to `rt_return_item`. - Add `delivery_item_id` to `rt_return_item`.
- Modify `backend/app/api/routes/master_data.py` - Modify `backend/app/api/routes/master_data.py`
- Add 嘉恒退货库 definition and auto-ensure location. - Add 百华退货库 definition and auto-ensure location.
- Modify `backend/app/api/routes/inventory.py` - Modify `backend/app/api/routes/inventory.py`
- Add `RETURN` warehouse label, sample opening rows, inbound/outbound permissions, lot number rules, and customer-return scrap inbound operation. - Add `RETURN` warehouse label, sample opening rows, inbound/outbound permissions, lot number rules, and customer-return scrap inbound operation.
- Modify `backend/app/services/stocktake.py` - Modify `backend/app/services/stocktake.py`
@ -1418,7 +1418,7 @@ Update the workspace title/description:
```vue ```vue
title="成品发货与交付管理" title="成品发货与交付管理"
description="发货退回后的库存处理已迁移到嘉恒仓库的退货库和废料库。" description="发货退回后的库存处理已迁移到百华仓库的退货库和废料库。"
``` ```
- [ ] **Step 2: Remove return-management child menu from App** - [ ] **Step 2: Remove return-management child menu from App**
@ -1563,7 +1563,7 @@ Expected: static test passes and build exits 0.
Open the ERP frontend and verify: Open the ERP frontend and verify:
```text ```text
1. 嘉恒仓库出现第六个仓库:退货库。 1. 百华仓库出现第六个仓库:退货库。
2. 退货库入库区有:期初入库、退货入库。 2. 退货库入库区有:期初入库、退货入库。
3. 退货库出库区有:返工出库。 3. 退货库出库区有:返工出库。
4. 废料库入库区有:退货废料入库。 4. 废料库入库区有:退货废料入库。

View File

@ -2,7 +2,7 @@
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Add a fifth "废料库" to 嘉恒仓库 for production scrap, offcuts, defective goods, opening stock, outsourcing scrap return, and scrap sale outbound. **Goal:** Add a fifth "废料库" to 百华仓库 for production scrap, offcuts, defective goods, opening stock, outsourcing scrap return, and scrap sale outbound.
**Architecture:** Reuse the current warehouse ledger architecture: one new warehouse type `SCRAP`, one tab in `InventoryLedgerView.vue`, existing `wh_stock_lot` / `wh_stock_balance` / `wh_inventory_txn` tables, existing stocktake flow, and existing opening inventory import/export. Scrap inventory is weight-only and can reference existing material/product items rather than introducing a new scrap catalog. **Architecture:** Reuse the current warehouse ledger architecture: one new warehouse type `SCRAP`, one tab in `InventoryLedgerView.vue`, existing `wh_stock_lot` / `wh_stock_balance` / `wh_inventory_txn` tables, existing stocktake flow, and existing opening inventory import/export. Scrap inventory is weight-only and can reference existing material/product items rather than introducing a new scrap catalog.
@ -1324,7 +1324,7 @@ npm run dev
``` ```
Expected manual checks: Expected manual checks:
- 嘉恒仓库 shows five warehouse tabs: 原材料库、半成品库、成品库、辅料库、废料库. - 百华仓库 shows five warehouse tabs: 原材料库、半成品库、成品库、辅料库、废料库.
- 废料库 tab uses the same card style and selected style as the other four warehouses. - 废料库 tab uses the same card style and selected style as the other four warehouses.
- 废料库 list is weight-only and does not show quantity columns. - 废料库 list is weight-only and does not show quantity columns.
- 入库 bar shows 生产废料入库、期初入库、委外废料入库. - 入库 bar shows 生产废料入库、期初入库、委外废料入库.

View File

@ -2,7 +2,7 @@
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Make `嘉恒仓库 -> 成品库 -> 销售出库` the only place that creates delivery outbound records, while `发货与售后 -> 发货管理` becomes a read-only delivery ledger with traceability. **Goal:** Make `百华仓库 -> 成品库 -> 销售出库` the only place that creates delivery outbound records, while `发货与售后 -> 发货管理` becomes a read-only delivery ledger with traceability.
**Architecture:** Keep the existing `/sales/deliveries` API as the single write path for delivery creation. Extend the warehouse sales-out drawer to support both sales-order delivery and direct customer delivery, and remove the create path from the delivery management page. Preserve traceability through existing `DeliveryItem.lot_id -> StockLot.source_material_lot_id/source_material_sub_batch_no/source_material_summary` fields. **Architecture:** Keep the existing `/sales/deliveries` API as the single write path for delivery creation. Extend the warehouse sales-out drawer to support both sales-order delivery and direct customer delivery, and remove the create path from the delivery management page. Preserve traceability through existing `DeliveryItem.lot_id -> StockLot.source_material_lot_id/source_material_sub_batch_no/source_material_summary` fields.
@ -872,7 +872,7 @@ Expected:
Open the ERP frontend and verify: Open the ERP frontend and verify:
```text ```text
嘉恒仓库 -> 成品库 -> 销售出库 百华仓库 -> 成品库 -> 销售出库
``` ```
Expected UI behavior: Expected UI behavior:

View File

@ -2,7 +2,7 @@
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Add a warehouse-level “流水” entry in 嘉恒仓库 so each of the six warehouses can view paginated, searchable, sortable inbound/outbound inventory transactions. **Goal:** Add a warehouse-level “流水” entry in 百华仓库 so each of the six warehouses can view paginated, searchable, sortable inbound/outbound inventory transactions.
**Architecture:** Keep `wh_inventory_txn` as the single source of truth. Add a new backend pagination endpoint for warehouse-level transaction ledger queries, then add a right-side drawer in `InventoryLedgerView.vue` that follows the active warehouse tab and displays summary cards, filters, and transaction rows. Keep the existing material-level stock detail drawer unchanged. **Architecture:** Keep `wh_inventory_txn` as the single source of truth. Add a new backend pagination endpoint for warehouse-level transaction ledger queries, then add a right-side drawer in `InventoryLedgerView.vue` that follows the active warehouse tab and displays summary cards, filters, and transaction rows. Keep the existing material-level stock detail drawer unchanged.
@ -12,7 +12,7 @@
## Confirmed Requirements ## Confirmed Requirements
- Add a “流水” icon/text button in 嘉恒仓库, positioned on the right side of the existing inbound/outbound operation bar. - Add a “流水” icon/text button in 百华仓库, positioned on the right side of the existing inbound/outbound operation bar.
- The button follows the active warehouse tab: 原材料库、半成品库、成品库、辅料库、废料库、退货库. - The button follows the active warehouse tab: 原材料库、半成品库、成品库、辅料库、废料库、退货库.
- Clicking opens a right-side drawer titled `{当前仓库名} · 出入库流水`. - Clicking opens a right-side drawer titled `{当前仓库名} · 出入库流水`.
- The drawer shows summary cards, filters, and a paginated table. - The drawer shows summary cards, filters, and a paginated table.
@ -774,7 +774,7 @@ In the same Vue file, before `<StocktakeDialog`, add:
```vue ```vue
<FormDrawer <FormDrawer
:open="warehouseLedgerDrawerOpen" :open="warehouseLedgerDrawerOpen"
eyebrow="嘉恒仓库 · 库级流水" eyebrow="百华仓库 · 库级流水"
:title="`${activeInventoryLabel} · 出入库流水`" :title="`${activeInventoryLabel} · 出入库流水`"
tag="库存流水" tag="库存流水"
wide wide
@ -1214,7 +1214,7 @@ http://localhost:5173/inventory-ledger
Manual expected results after login: Manual expected results after login:
- 嘉恒仓库 page renders. - 百华仓库 page renders.
- Select 原材料库, click `流水`, drawer title is `原材料库 · 出入库流水`. - Select 原材料库, click `流水`, drawer title is `原材料库 · 出入库流水`.
- Switch 成品库 while the drawer is open, drawer reloads and title becomes `成品库 · 出入库流水`. - Switch 成品库 while the drawer is open, drawer reloads and title becomes `成品库 · 出入库流水`.
- Search box can filter by a known material or batch keyword. - Search box can filter by a known material or batch keyword.

View File

@ -704,7 +704,7 @@ Expected: all pass.
Open the ERP in the browser and check: Open the ERP in the browser and check:
```text ```text
1. 嘉恒仓库 -> 成品库 -> 产品明细抽屉 1. 百华仓库 -> 成品库 -> 产品明细抽屉
2. 库存批次明细表 2. 库存批次明细表
3. 库存流水表 3. 库存流水表
4. 采购订单详情抽屉 4. 采购订单详情抽屉

View File

@ -104,4 +104,4 @@ Expected: all backend tests pass.
Run frontend dev server and open `http://127.0.0.1:5173/` in the in-app browser. Run frontend dev server and open `http://127.0.0.1:5173/` in the in-app browser.
Expected: page loads with title `嘉恒智能五金 ERP` and no console errors. Expected: page loads with title `百华智能五金 ERP` and no console errors.

View File

@ -2,7 +2,7 @@
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 把嘉恒仓库的半成品库从“通用物料/产品库存”改为“产品 + 已完成工序”的半成品库存模型。 **Goal:** 把百华仓库的半成品库从“通用物料/产品库存”改为“产品 + 已完成工序”的半成品库存模型。
**Architecture:** 后端继续使用 `md_item.id` 表示产品,但用 `StockLot.source_line_id``InventoryTxn.source_line_id` 记录产品需规清单中的 `route_operation_id`,从而区分同一产品不同工序阶段的半成品。前端半成品入库从 `/master-data/process-routes` 展开产品工序选项,半成品出库和库存明细按 `item_id + source_line_id` 过滤与展示,避免跨工序混扣库存。 **Architecture:** 后端继续使用 `md_item.id` 表示产品,但用 `StockLot.source_line_id``InventoryTxn.source_line_id` 记录产品需规清单中的 `route_operation_id`,从而区分同一产品不同工序阶段的半成品。前端半成品入库从 `/master-data/process-routes` 展开产品工序选项,半成品出库和库存明细按 `item_id + source_line_id` 过滤与展示,避免跨工序混扣库存。
@ -575,7 +575,7 @@ Expected: PASS.
- [ ] **Step 4: Manual UI sanity check if local server is already running** - [ ] **Step 4: Manual UI sanity check if local server is already running**
Open the inventory page, select `嘉恒仓库 -> 半成品库` and verify: Open the inventory page, select `百华仓库 -> 半成品库` and verify:
```text ```text
半成品入库字段显示“产品工序” 半成品入库字段显示“产品工序”

View File

@ -6,7 +6,7 @@
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Add `嘉恒仓库 -> 成品库 -> 返工入库`, binding finished-goods rework inbound to existing `退货库 -> 返工出库` disposition records, with raw-material stock-lot traceability and quantity-based finished inventory updates. **Goal:** Add `百华仓库 -> 成品库 -> 返工入库`, binding finished-goods rework inbound to existing `退货库 -> 返工出库` disposition records, with raw-material stock-lot traceability and quantity-based finished inventory updates.
**Architecture:** Reuse the existing generic warehouse inbound route and drawer. Add a new inbound business type `REWORK_IN` that is allowed only in `FINISHED` warehouses, validates `RETURN_DISPOSITION` source documents, derives remaining rework-return quantity from existing finished inbound stock lots, and records raw-material source stock lot trace fields. The frontend adds a finished-warehouse operation, loads return dispositions, filters pending/partial rework dispositions by product, and submits `source_doc_type/source_doc_id/source_line_id` through the generic inbound flow. **Architecture:** Reuse the existing generic warehouse inbound route and drawer. Add a new inbound business type `REWORK_IN` that is allowed only in `FINISHED` warehouses, validates `RETURN_DISPOSITION` source documents, derives remaining rework-return quantity from existing finished inbound stock lots, and records raw-material source stock lot trace fields. The frontend adds a finished-warehouse operation, loads return dispositions, filters pending/partial rework dispositions by product, and submits `source_doc_type/source_doc_id/source_line_id` through the generic inbound flow.
@ -977,7 +977,7 @@ http://127.0.0.1:5173/
Manual checks: Manual checks:
- Login if needed. - Login if needed.
- Navigate to `嘉恒仓库`. - Navigate to `百华仓库`.
- Select `成品库`. - Select `成品库`.
- Confirm the inbound operation row shows `返工入库`. - Confirm the inbound operation row shows `返工入库`.
- Click `返工入库`. - Click `返工入库`.

View File

@ -319,7 +319,7 @@ nano /opt/ForgeFlow-ERP/backend/.env
推荐内容: 推荐内容:
```env ```env
APP_NAME=Jiaheng Hardware ERP API APP_NAME=Baihua Hardware ERP API
APP_ENV=staging-dev APP_ENV=staging-dev
APP_HOST=0.0.0.0 APP_HOST=0.0.0.0
APP_PORT=8000 APP_PORT=8000
@ -802,7 +802,7 @@ API 请求地址是 http://<腾讯云公网IP>:8000/api/...
验证: 验证:
```text ```text
嘉恒仓库六大库能打开,出入库弹窗能打开 百华仓库六大库能打开,出入库弹窗能打开
``` ```
- [ ] **Step 4: 生产执行页面** - [ ] **Step 4: 生产执行页面**

View File

@ -1497,7 +1497,7 @@ ERP 工单台账中返工工单累计良品 8、废品 2。
Manual flow: Manual flow:
```text ```text
嘉恒仓库 -> 成品库 -> 返工入库 百华仓库 -> 成品库 -> 返工入库
-> 选择返工工单 JH0001 对应工单 -> 选择返工工单 JH0001 对应工单
-> 入库 8 件 -> 入库 8 件
``` ```
@ -1515,7 +1515,7 @@ Expected:
Manual flow: Manual flow:
```text ```text
嘉恒仓库 -> 废料库 -> 返工废料入库 百华仓库 -> 废料库 -> 返工废料入库
-> 选择同一返工工单 -> 选择同一返工工单
-> 入库 2 件对应废料重量 -> 入库 2 件对应废料重量
-> 勾选结单 -> 勾选结单

View File

@ -2,7 +2,7 @@
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 为嘉恒仓库 6 大库的入库与出库操作区分别增加“特殊入库”“特殊出库”,允许在强制填写说明后,精确到库存明细行进行受控库存调整,并把说明写入所有变更记录。 **Goal:** 为百华仓库 6 大库的入库与出库操作区分别增加“特殊入库”“特殊出库”,允许在强制填写说明后,精确到库存明细行进行受控库存调整,并把说明写入所有变更记录。
**Architecture:** 新增独立的“特殊调整”后端服务与审计主/明细表,库存变动仍复用现有 `wh_stock_lot`、`wh_stock_balance`、`wh_inventory_txn` 三层账本。前端在现有 `InventoryLedgerView.vue` 的仓库出入库操作矩阵中增加特殊操作入口,打开专用抽屉完成说明填写、明细选择、调整前后预览和提交。 **Architecture:** 新增独立的“特殊调整”后端服务与审计主/明细表,库存变动仍复用现有 `wh_stock_lot`、`wh_stock_balance`、`wh_inventory_txn` 三层账本。前端在现有 `InventoryLedgerView.vue` 的仓库出入库操作矩阵中增加特殊操作入口,打开专用抽屉完成说明填写、明细选择、调整前后预览和提交。
@ -1743,8 +1743,8 @@ http://127.0.0.1:5173/
Manual checks: Manual checks:
- 嘉恒仓库 6 大库的入库操作区都有“特殊入库”。 - 百华仓库 6 大库的入库操作区都有“特殊入库”。
- 嘉恒仓库 6 大库的出库操作区都有“特殊出库”。 - 百华仓库 6 大库的出库操作区都有“特殊出库”。
- 未填写说明时,不能添加/提交特殊调整明细。 - 未填写说明时,不能添加/提交特殊调整明细。
- 原材料库特殊出库只能填写重量,提交后对应库存批次重量减少。 - 原材料库特殊出库只能填写重量,提交后对应库存批次重量减少。
- 辅料库特殊入库只按数量增加,不写入重量。 - 辅料库特殊入库只按数量增加,不写入重量。

View File

@ -2,7 +2,7 @@
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Implement原材料库存批次号全库递增、生产出库单批次合并工单、小程序按材料库存批次号报工、以及嘉恒仓库“生产工单入库”统一闭环成品/余料/废料。 **Goal:** Implement原材料库存批次号全库递增、生产出库单批次合并工单、小程序按材料库存批次号报工、以及百华仓库“生产工单入库”统一闭环成品/余料/废料。
**Architecture:** Add a small system-config service for the raw lot prefix, keep ERP production work orders as the internal container, and make raw stock lot IDs the external production-facing identifier. Production outbound becomes single-lot and merges into a deterministic daily work order; production work-order inbound becomes one transactional backend API that posts finished goods, returns surplus to the original raw lot, posts scrap, and optionally settles the work order. **Architecture:** Add a small system-config service for the raw lot prefix, keep ERP production work orders as the internal container, and make raw stock lot IDs the external production-facing identifier. Production outbound becomes single-lot and merges into a deterministic daily work order; production work-order inbound becomes one transactional backend API that posts finished goods, returns surplus to the original raw lot, posts scrap, and optionally settles the work order.
@ -1859,7 +1859,7 @@ Add a `FormDrawer` in `InventoryLedgerView.vue`:
```html ```html
<FormDrawer <FormDrawer
:open="productionWorkOrderInboundDrawerOpen" :open="productionWorkOrderInboundDrawerOpen"
eyebrow="嘉恒仓库 · 生产工单入库" eyebrow="百华仓库 · 生产工单入库"
title="生产工单入库" title="生产工单入库"
tag="工单闭环" tag="工单闭环"
wide wide
@ -2144,12 +2144,12 @@ Smoke flow:
1. Open `http://127.0.0.1:5173`. 1. Open `http://127.0.0.1:5173`.
2. Go to 系统拓展 and verify 原材料库存批次号前缀 shows `YL`. 2. Go to 系统拓展 and verify 原材料库存批次号前缀 shows `YL`.
3. Go to 嘉恒仓库原材料库 and create a raw inbound test lot; verify lot number is `YL0001` or the next available `YL` sequence. 3. Go to 百华仓库原材料库 and create a raw inbound test lot; verify lot number is `YL0001` or the next available `YL` sequence.
4. Use 原材料库 · 生产出库, select one material stock lot and one product, submit. 4. Use 原材料库 · 生产出库, select one material stock lot and one product, submit.
5. Verify 工单台账 has work order `YYYYMMDD-YLxxxx-产品名称`. 5. Verify 工单台账 has work order `YYYYMMDD-YLxxxx-产品名称`.
6. Submit another production outbound for the same day, same lot, same product. 6. Submit another production outbound for the same day, same lot, same product.
7. Verify it merges into the same work order and adds another issue line. 7. Verify it merges into the same work order and adds another issue line.
8. Open 嘉恒仓库 · 生产工单入库, select that work order, enter finished qty, verify surplus/scrap defaults are filled. 8. Open 百华仓库 · 生产工单入库, select that work order, enter finished qty, verify surplus/scrap defaults are filled.
9. Change surplus or scrap beyond 15%; verify deviation remark is required. 9. Change surplus or scrap beyond 15%; verify deviation remark is required.
10. Check “本次入库后结单”, submit, confirm second prompt, verify work order status becomes 已结单. 10. Check “本次入库后结单”, submit, confirm second prompt, verify work order status becomes 已结单.

View File

@ -42,11 +42,11 @@
- Modify `backend/app/api/routes/inventory.py` - Modify `backend/app/api/routes/inventory.py`
- Validate warehouse form personnel fields against `MENU_INVENTORY_LEDGER`. - Validate warehouse form personnel fields against `MENU_INVENTORY_LEDGER`.
- Modify `backend/app/api/routes/production.py` - Modify `backend/app/api/routes/production.py`
- Validate completion/production inbound receiver fields against `MENU_INVENTORY_LEDGER` when the UI flow belongs to 嘉恒仓库. - Validate completion/production inbound receiver fields against `MENU_INVENTORY_LEDGER` when the UI flow belongs to 百华仓库.
- Modify `backend/app/api/routes/sales.py` - Modify `backend/app/api/routes/sales.py`
- Validate delivery shipper fields against `MENU_DELIVERY_MANAGEMENT` for 发货概览 delivery endpoints. - Validate delivery shipper fields against `MENU_DELIVERY_MANAGEMENT` for 发货概览 delivery endpoints.
- Modify `backend/app/api/routes/returns.py` - Modify `backend/app/api/routes/returns.py`
- Validate return handler fields against the page permission used by that route. Current return-management route redirects to 嘉恒仓库, so warehouse return flows use `MENU_INVENTORY_LEDGER`. - Validate return handler fields against the page permission used by that route. Current return-management route redirects to 百华仓库, so warehouse return flows use `MENU_INVENTORY_LEDGER`.
- Modify `backend/app/api/routes/equipment.py` - Modify `backend/app/api/routes/equipment.py`
- Validate maintenance owner fields against `MENU_EQUIPMENT_MANAGEMENT`. - Validate maintenance owner fields against `MENU_EQUIPMENT_MANAGEMENT`.
@ -1610,7 +1610,7 @@ Start or use the existing local app, log in as an admin, and verify:
3. 销售订单新增:能看到“销售人员”,选项只包含有客户名录/销售订单权限的人。 3. 销售订单新增:能看到“销售人员”,选项只包含有客户名录/销售订单权限的人。
4. 采购订单新增:采购员只包含有采购订单权限的人。 4. 采购订单新增:采购员只包含有采购订单权限的人。
5. 到货入库:接收人只包含有到货入库权限的人。 5. 到货入库:接收人只包含有到货入库权限的人。
6. 嘉恒仓库内接收人/经办人/发货人只包含有嘉恒仓库权限的人。 6. 百华仓库内接收人/经办人/发货人只包含有百华仓库权限的人。
7. 设备管理负责人只包含有设备管理权限的人。 7. 设备管理负责人只包含有设备管理权限的人。
8. 尝试用接口提交一个无权限人员 ID后端返回中文错误不保存单据。 8. 尝试用接口提交一个无权限人员 ID后端返回中文错误不保存单据。
``` ```

View File

@ -187,7 +187,7 @@ class SystemPermissionManagementTest(unittest.TestCase):
now = datetime(2026, 6, 8, 9, 0, 0) now = datetime(2026, 6, 8, 9, 0, 0)
self.company = Department( self.company = Department(
dept_code="JH", dept_code="JH",
dept_name="嘉恒总公司", dept_name="百华总公司",
parent_id=None, parent_id=None,
org_node_type="COMPANY", org_node_type="COMPANY",
dept_type="ADMIN", dept_type="ADMIN",
@ -331,7 +331,7 @@ SET role_name = '采购专员', remark = '供应商、采购订单、到货和
WHERE role_code = 'PURCHASER'; WHERE role_code = 'PURCHASER';
UPDATE sys_role UPDATE sys_role
SET role_name = '仓库管理人员', remark = '到货、质检、嘉恒仓库、发货台账相关作业' SET role_name = '仓库管理人员', remark = '到货、质检、百华仓库、发货台账相关作业'
WHERE role_code = 'WAREHOUSE'; WHERE role_code = 'WAREHOUSE';
UPDATE sys_role UPDATE sys_role
@ -498,7 +498,7 @@ Append these tests to `SystemPermissionManagementTest` in `backend/tests/test_sy
tree = build_org_tree(self.db) tree = build_org_tree(self.db)
self.assertEqual(len(tree), 1) self.assertEqual(len(tree), 1)
self.assertEqual(tree[0].node_label, "嘉恒总公司") self.assertEqual(tree[0].node_label, "百华总公司")
purchase = tree[0].children[0] purchase = tree[0].children[0]
self.assertEqual(purchase.node_label, "采购部") self.assertEqual(purchase.node_label, "采购部")
self.assertEqual(purchase.manager_employee_id, self.manager_employee_id) self.assertEqual(purchase.manager_employee_id, self.manager_employee_id)
@ -792,7 +792,7 @@ MENU_PERMISSION_TREE = [
("MENU_PURCHASE_ORDER", "采购订单", []), ("MENU_PURCHASE_ORDER", "采购订单", []),
("MENU_PURCHASE_RECEIPT", "到货入库", []), ("MENU_PURCHASE_RECEIPT", "到货入库", []),
("MENU_QUALITY_INSPECTION", "质量检验", []), ("MENU_QUALITY_INSPECTION", "质量检验", []),
("MENU_INVENTORY_LEDGER", "嘉恒仓库", []), ("MENU_INVENTORY_LEDGER", "百华仓库", []),
], ],
), ),
( (

View File

@ -2,7 +2,7 @@
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 让嘉恒仓库 6 大库所有出入库填单都采用正式纸质单据风格,保存后生成 PDF 留档,并支持在各库流水中预览、下载、重新生成 PDF以及按当前筛选时间范围导出流水 Excel 清单。 **Goal:** 让百华仓库 6 大库所有出入库填单都采用正式纸质单据风格,保存后生成 PDF 留档,并支持在各库流水中预览、下载、重新生成 PDF以及按当前筛选时间范围导出流水 Excel 清单。
**Architecture:** 采用“双轨归档”:生产主链路继续使用 `生产领料出库单`、`生产入库结算单`,其它仓库出入库统一使用新增 `仓库出入库单`。后端以库存流水 `wh_inventory_txn` 为核心收集归档上下文和导出 Excel前端抽取通用纸质单据底座在仓库流水抽屉复用现有 `DocumentArchiveActions` **Architecture:** 采用“双轨归档”:生产主链路继续使用 `生产领料出库单`、`生产入库结算单`,其它仓库出入库统一使用新增 `仓库出入库单`。后端以库存流水 `wh_inventory_txn` 为核心收集归档上下文和导出 Excel前端抽取通用纸质单据底座在仓库流水抽屉复用现有 `DocumentArchiveActions`
@ -1133,7 +1133,7 @@ Create `frontend/src/components/documentForms/WarehouseDocumentFormShell.vue`:
<form class="warehouse-document-form" @submit.prevent="$emit('submit')"> <form class="warehouse-document-form" @submit.prevent="$emit('submit')">
<header class="warehouse-document-head"> <header class="warehouse-document-head">
<div> <div>
<span class="warehouse-document-kicker">嘉恒仓库</span> <span class="warehouse-document-kicker">百华仓库</span>
<h2>{{ title }}</h2> <h2>{{ title }}</h2>
</div> </div>
<dl> <dl>

View File

@ -431,8 +431,8 @@ class DocumentArchiveServiceTest(unittest.TestCase):
self.customer = Customer( self.customer = Customer(
id=1, id=1,
customer_code="CUS001", customer_code="CUS001",
customer_name="嘉恒客户", customer_name="百华客户",
short_name="嘉恒", short_name="百华",
status="ACTIVE", status="ACTIVE",
created_at=now, created_at=now,
updated_at=now, updated_at=now,
@ -1789,7 +1789,7 @@ const props = defineProps({
}, },
companyName: { companyName: {
type: String, type: String,
default: "嘉恒仓库 ERP" default: "百华仓库 ERP"
}, },
tone: { tone: {
type: String, type: String,

View File

@ -185,7 +185,7 @@ const props = defineProps({
}, },
companyName: { companyName: {
type: String, type: String,
default: "宁波嘉恒智能科技有限公司" default: "宁波百华智能科技有限公司"
}, },
metaLabel: { metaLabel: {
type: String, type: String,
@ -496,7 +496,7 @@ defineProps({
}, },
companyName: { companyName: {
type: String, type: String,
default: "嘉恒仓库" default: "百华仓库"
}, },
signatureLabels: { signatureLabels: {
type: Array, type: Array,

View File

@ -4,14 +4,14 @@
当前系统同时存在两个发货相关入口: 当前系统同时存在两个发货相关入口:
- `嘉恒仓库 -> 成品库 -> 销售出库` - `百华仓库 -> 成品库 -> 销售出库`
- `发货与售后 -> 发货管理` - `发货与售后 -> 发货管理`
两个入口都会影响发货单、成品库存和后续退货追溯,容易让用户不知道应该在哪里执行发货,也容易造成业务口径重复。 两个入口都会影响发货单、成品库存和后续退货追溯,容易让用户不知道应该在哪里执行发货,也容易造成业务口径重复。
## 目标 ## 目标
采用方案 A将发货执行入口统一到 `嘉恒仓库 -> 成品库 -> 销售出库`,将 `发货与售后 -> 发货管理` 调整为发货台账/交付查询。 采用方案 A将发货执行入口统一到 `百华仓库 -> 成品库 -> 销售出库`,将 `发货与售后 -> 发货管理` 调整为发货台账/交付查询。
目标效果: 目标效果:
@ -25,7 +25,7 @@
### 成品库销售出库 ### 成品库销售出库
`嘉恒仓库 -> 成品库 -> 销售出库` 是唯一新增发货入口。 `百华仓库 -> 成品库 -> 销售出库` 是唯一新增发货入口。
该入口支持两种模式: 该入口支持两种模式:

View File

@ -1,14 +1,14 @@
# 嘉恒仓库库级出入库流水设计 # 百华仓库库级出入库流水设计
## 背景 ## 背景
嘉恒仓库已经承载原材料库、半成品库、成品库、辅料库、废料库、退货库六类库存。当前页面支持点击某个物料查看该物料的批次台账和库存流水,但缺少“站在某一个仓库整体视角查看所有出入库流水”的入口。 百华仓库已经承载原材料库、半成品库、成品库、辅料库、废料库、退货库六类库存。当前页面支持点击某个物料查看该物料的批次台账和库存流水,但缺少“站在某一个仓库整体视角查看所有出入库流水”的入口。
本设计在仓库页新增库级流水入口。入口跟随当前选中的仓库 tab用于查看当前仓库下所有物料、批次和业务单据产生的出入库流水。 本设计在仓库页新增库级流水入口。入口跟随当前选中的仓库 tab用于查看当前仓库下所有物料、批次和业务单据产生的出入库流水。
## 目标 ## 目标
- 在嘉恒仓库页面的出入库操作区右侧新增一个“流水”图标按钮,位置对应用户截图红框区域。 - 在百华仓库页面的出入库操作区右侧新增一个“流水”图标按钮,位置对应用户截图红框区域。
- 当前选中哪个仓库 tab点击按钮就查看该仓库的出入库流水。 - 当前选中哪个仓库 tab点击按钮就查看该仓库的出入库流水。
- 六大仓库都支持库级流水:原材料库、半成品库、成品库、辅料库、废料库、退货库。 - 六大仓库都支持库级流水:原材料库、半成品库、成品库、辅料库、废料库、退货库。
- 流水数据来自统一库存流水表 `wh_inventory_txn`,不新增另一套流水记录体系。 - 流水数据来自统一库存流水表 `wh_inventory_txn`,不新增另一套流水记录体系。
@ -23,7 +23,7 @@
## 页面入口 ## 页面入口
嘉恒仓库页面的出入库操作区右侧新增一个图标按钮。 百华仓库页面的出入库操作区右侧新增一个图标按钮。
按钮要求: 按钮要求:
@ -245,7 +245,7 @@ GET /inventory/transaction-ledger
前端静态测试: 前端静态测试:
- 嘉恒仓库页面存在“流水”入口。 - 百华仓库页面存在“流水”入口。
- 六大仓库 tab 都可打开同一流水抽屉。 - 六大仓库 tab 都可打开同一流水抽屉。
- 请求使用 `/inventory/transaction-ledger` - 请求使用 `/inventory/transaction-ledger`
- 旧物料级库存流水仍保留。 - 旧物料级库存流水仍保留。
@ -256,7 +256,7 @@ GET /inventory/transaction-ledger
浏览器冒烟: 浏览器冒烟:
- 登录后进入嘉恒仓库。 - 登录后进入百华仓库。
- 切换任意仓库 tab。 - 切换任意仓库 tab。
- 点击“流水”按钮。 - 点击“流水”按钮。
- 抽屉标题和当前仓库一致。 - 抽屉标题和当前仓库一致。

View File

@ -12,7 +12,7 @@
## 目标 ## 目标
- 在 `嘉恒仓库 -> 成品库` 的入库区新增 `返工入库` - 在 `百华仓库 -> 成品库` 的入库区新增 `返工入库`
- `返工入库` 必须选择产品,并关联该产品未完成回库的返工出库记录。 - `返工入库` 必须选择产品,并关联该产品未完成回库的返工出库记录。
- 选择产品后,系统带出该产品对应的原材料库存批次号多选框,用 `JH...` 原材料库存批次号做追溯。 - 选择产品后,系统带出该产品对应的原材料库存批次号多选框,用 `JH...` 原材料库存批次号做追溯。
- 成品库仍以数量为主维度,重量只作为辅助信息或追溯信息,不作为主要库存口径。 - 成品库仍以数量为主维度,重量只作为辅助信息或追溯信息,不作为主要库存口径。
@ -21,7 +21,7 @@
## 业务入口 ## 业务入口
`嘉恒仓库 -> 成品库 -> 入库 -> 返工入库` `百华仓库 -> 成品库 -> 入库 -> 返工入库`
该入口建议复用当前普通仓库入库抽屉样式,不另起一个完全不同的页面。字段建议为: 该入口建议复用当前普通仓库入库抽屉样式,不另起一个完全不同的页面。字段建议为:

View File

@ -15,7 +15,7 @@
- 生产工单号改为 `YYYYMMDD-库存批次号-产品名称`,例如 `20260607-YL0001-钢制碗` - 生产工单号改为 `YYYYMMDD-库存批次号-产品名称`,例如 `20260607-YL0001-钢制碗`
- 同一天、同一个库存批次号、同一个产品的生产出库合并为同一张未结单工单。 - 同一天、同一个库存批次号、同一个产品的生产出库合并为同一张未结单工单。
- 小程序原“工单号”业务语义调整为“材料库存批次号”,员工按材料库存批次号报工。 - 小程序原“工单号”业务语义调整为“材料库存批次号”,员工按材料库存批次号报工。
- 嘉恒仓库“流水”按钮旁新增“生产工单入库”入口,统一处理成品入库、生产余料入库、生产废料入库。 - 百华仓库“流水”按钮旁新增“生产工单入库”入口,统一处理成品入库、生产余料入库、生产废料入库。
- “生产工单入库”中系统计算理论成品、理论余料、理论废料作为辅助默认值,用户可修改。 - “生产工单入库”中系统计算理论成品、理论余料、理论废料作为辅助默认值,用户可修改。
- 当用户修改余料或废料后,与理论值偏差超过上下 15%,必须弹窗填写说明,但不禁止入库。 - 当用户修改余料或废料后,与理论值偏差超过上下 15%,必须弹窗填写说明,但不禁止入库。
- “生产工单入库”不默认结单。只有用户主动勾选“本次入库后结单”才结单,并且提交前必须二次确认。 - “生产工单入库”不默认结单。只有用户主动勾选“本次入库后结单”才结单,并且提交前必须二次确认。
@ -159,13 +159,13 @@ YYYYMMDD-库存批次号-产品名称
## 生产工单入库入口 ## 生产工单入库入口
嘉恒仓库页面,“流水”按钮旁新增: 百华仓库页面,“流水”按钮旁新增:
```text ```text
生产工单入库 生产工单入库
``` ```
入口跟随嘉恒仓库整体,不放在某一个具体仓库的入库/出库行里。因为这个操作一次会同时影响成品库、原材料库和废料库。 入口跟随百华仓库整体,不放在某一个具体仓库的入库/出库行里。因为这个操作一次会同时影响成品库、原材料库和废料库。
点击后打开较宽抽屉,避免表格和计算字段拥挤。该入口不使用小弹窗承载主流程。 点击后打开较宽抽屉,避免表格和计算字段拥挤。该入口不使用小弹窗承载主流程。
@ -443,7 +443,7 @@ max(Q * (G - N) + S * G - W, 0)
- 原材料库生产出库 UI 只能选择一个材料库存批次号。 - 原材料库生产出库 UI 只能选择一个材料库存批次号。
- 生产出库提交 payload 只包含一个库存批次。 - 生产出库提交 payload 只包含一个库存批次。
- 嘉恒仓库流水按钮旁显示“生产工单入库”。 - 百华仓库流水按钮旁显示“生产工单入库”。
- 生产工单入库选择工单后自动填理论值。 - 生产工单入库选择工单后自动填理论值。
- 修改成品数量后自动重算余料和废料理论值。 - 修改成品数量后自动重算余料和废料理论值。
- 偏差超过 15% 时弹出说明框。 - 偏差超过 15% 时弹出说明框。
@ -465,7 +465,7 @@ max(Q * (G - N) + S * G - W, 0)
3. 调整生产出库为单库存批次,并实现同日同批同产品工单合并。 3. 调整生产出库为单库存批次,并实现同日同批同产品工单合并。
4. 调整小程序报工同步逻辑,按材料库存批次号匹配未结单工单。 4. 调整小程序报工同步逻辑,按材料库存批次号匹配未结单工单。
5. 新增生产工单入库后端接口。 5. 新增生产工单入库后端接口。
6. 新增嘉恒仓库“生产工单入库”前端入口和交互。 6. 新增百华仓库“生产工单入库”前端入口和交互。
7. 联调工单台账、成品入库、余料入库、废料入库、发货追溯。 7. 联调工单台账、成品入库、余料入库、废料入库、发货追溯。
8. 补齐自动化测试和启动检查。 8. 补齐自动化测试和启动检查。

View File

@ -1,8 +1,8 @@
# 嘉恒仓库全出入库单据纸质化与归档设计 # 百华仓库全出入库单据纸质化与归档设计
## 背景 ## 背景
嘉恒仓库已经有 6 大库:原材料库、半成品库、成品库、辅料库、废料库、退货库。当前出入库业务主要通过抽屉表单完成,保存后形成库存流水。用户已经认可 `原材料库 · 客料入库` 的纸质填单样板,但该样板目前只完成填写 UI没有生成 PDF 归档,也没有预览和下载入口。 百华仓库已经有 6 大库:原材料库、半成品库、成品库、辅料库、废料库、退货库。当前出入库业务主要通过抽屉表单完成,保存后形成库存流水。用户已经认可 `原材料库 · 客料入库` 的纸质填单样板,但该样板目前只完成填写 UI没有生成 PDF 归档,也没有预览和下载入口。
现有归档体系已覆盖销售订单、采购订单、到货入库单、质量校验单、生产领料出库单、生产入库结算单。仓库里大量非生产分支仍未纳入正式单据化:客料、委外、销售、退货、返工、特殊出入库、期初等。为避免后续继续碎片化,本方案把“所有仓库出入库填单纸质化、保存后 PDF 归档、流水入口预览下载、流水 Excel 导出”作为统一仓库单据化工程。 现有归档体系已覆盖销售订单、采购订单、到货入库单、质量校验单、生产领料出库单、生产入库结算单。仓库里大量非生产分支仍未纳入正式单据化:客料、委外、销售、退货、返工、特殊出入库、期初等。为避免后续继续碎片化,本方案把“所有仓库出入库填单纸质化、保存后 PDF 归档、流水入口预览下载、流水 Excel 导出”作为统一仓库单据化工程。
@ -167,7 +167,7 @@
所有仓库出入库抽屉采用统一纸质单据底座: 所有仓库出入库抽屉采用统一纸质单据底座:
- 抬头:嘉恒仓库、单据标题、单据编号或提交后生成提示。 - 抬头:百华仓库、单据标题、单据编号或提交后生成提示。
- 基础信息区:仓库、库位、业务类型、来源/去向、经办人、时间。 - 基础信息区:仓库、库位、业务类型、来源/去向、经办人、时间。
- 明细区:物料/产品/半成品/废料/退货品、库存批次号、来源库存批次号、数量、重量、单价、金额。 - 明细区:物料/产品/半成品/废料/退货品、库存批次号、来源库存批次号、数量、重量、单价、金额。
- 辅助信息区:运单号、运费、辅助照片、用途、包装备注、退货/返工/委外方、说明。 - 辅助信息区:运单号、运费、辅助照片、用途、包装备注、退货/返工/委外方、说明。
@ -227,7 +227,7 @@ PDF 不得出现:
### 各库流水抽屉 ### 各库流水抽屉
`嘉恒仓库 -> 工具 -> 流水` 中新增 `单据留档` 列。 `百华仓库 -> 工具 -> 流水` 中新增 `单据留档` 列。
每条流水根据后端返回的归档字段展示: 每条流水根据后端返回的归档字段展示:

View File

@ -2,7 +2,7 @@
## 背景 ## 背景
系统已经完成销售订单、采购订单、到货入库单、质量校验单的正式单据化与 PDF 归档。嘉恒仓库仍以业务抽屉和库存流水为主,用户在办理生产出库、生产入库、生产余料入库、生产废料入库时,缺少一张可预览、可下载、可留档的正式业务单据。 系统已经完成销售订单、采购订单、到货入库单、质量校验单的正式单据化与 PDF 归档。百华仓库仍以业务抽屉和库存流水为主,用户在办理生产出库、生产入库、生产余料入库、生产废料入库时,缺少一张可预览、可下载、可留档的正式业务单据。
仓库业务入口很多6 大库中存在采购、生产、委外、退货、销售、特殊调整等多条链路。如果一次性把所有出入库按钮都接入 PDF容易形成重复模板和重复归档逻辑。本次先以生产主链路作为第一期样板抽出仓库作业单通用底座后续再扩展到委外、退货、销售出库、特殊出入库。 仓库业务入口很多6 大库中存在采购、生产、委外、退货、销售、特殊调整等多条链路。如果一次性把所有出入库按钮都接入 PDF容易形成重复模板和重复归档逻辑。本次先以生产主链路作为第一期样板抽出仓库作业单通用底座后续再扩展到委外、退货、销售出库、特殊出入库。
@ -190,7 +190,7 @@
### 操作弹窗 ### 操作弹窗
生产主链路现有入口保留,不改变用户从嘉恒仓库进入业务的习惯。 生产主链路现有入口保留,不改变用户从百华仓库进入业务的习惯。
本期只做两类升级: 本期只做两类升级:

View File

@ -44,13 +44,13 @@
| 模块 | 页面 | 单据 | 当前问题 | 优先级 | | 模块 | 页面 | 单据 | 当前问题 | 优先级 |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| 嘉恒仓库 | `InventoryLedgerView.vue` | 特殊入库单 / 特殊出库单 | 明细编辑区仍像现代卡片控件,和纸质单据割裂 | P0 | | 百华仓库 | `InventoryLedgerView.vue` | 特殊入库单 / 特殊出库单 | 明细编辑区仍像现代卡片控件,和纸质单据割裂 | P0 |
| 嘉恒仓库 | `InventoryLedgerView.vue` | 生产出库单 | 已使用纸质外壳,但来源批次选择、产品/BOM信息仍需统一纸质表格语言 | P0 | | 百华仓库 | `InventoryLedgerView.vue` | 生产出库单 | 已使用纸质外壳,但来源批次选择、产品/BOM信息仍需统一纸质表格语言 | P0 |
| 嘉恒仓库 | `InventoryLedgerView.vue` | 生产台账入库结算单 | 已有纸质外壳和摘要格,但三库联动字段、异常说明区域仍需与纸质单据模板对齐 | P0 | | 百华仓库 | `InventoryLedgerView.vue` | 生产台账入库结算单 | 已有纸质外壳和摘要格,但三库联动字段、异常说明区域仍需与纸质单据模板对齐 | P0 |
| 嘉恒仓库 | `InventoryLedgerView.vue` | 生产入库单 / 返工入库单 | 结单区和摘要区仍有旧卡片感 | P1 | | 百华仓库 | `InventoryLedgerView.vue` | 生产入库单 / 返工入库单 | 结单区和摘要区仍有旧卡片感 | P1 |
| 嘉恒仓库 | `InventoryLedgerView.vue` | 销售出库单 | 已套纸质外壳,但销售订单关联、包装备注、发货明细区域需统一 | P1 | | 百华仓库 | `InventoryLedgerView.vue` | 销售出库单 | 已套纸质外壳,但销售订单关联、包装备注、发货明细区域需统一 | P1 |
| 嘉恒仓库 | `InventoryLedgerView.vue` | 原材料退货出库单、退货入库单、退货废料入库单、返工出库单 | 已套纸质外壳,但字段区仍有普通表单/表格痕迹 | P1 | | 百华仓库 | `InventoryLedgerView.vue` | 原材料退货出库单、退货入库单、退货废料入库单、返工出库单 | 已套纸质外壳,但字段区仍有普通表单/表格痕迹 | P1 |
| 嘉恒仓库 | `InventoryLedgerView.vue` | 期初入库、委外入库/出库、报废出库、售卖出库等通用分支 | 通用分支第一阶段只统一了生产余料/废料一部分,仍需逐个验收 | P1 | | 百华仓库 | `InventoryLedgerView.vue` | 期初入库、委外入库/出库、报废出库、售卖出库等通用分支 | 通用分支第一阶段只统一了生产余料/废料一部分,仍需逐个验收 | P1 |
### 需要补充纸质化或确认是否作为单据 ### 需要补充纸质化或确认是否作为单据
@ -60,7 +60,7 @@
| 发货概览 | `ReturnManagementView.vue` | 退货/返工/废料处置 | 属于业务凭证,需要与退货库单据闭环统一 | P1 | | 发货概览 | `ReturnManagementView.vue` | 退货/返工/废料处置 | 属于业务凭证,需要与退货库单据闭环统一 | P1 |
| 发货概览 | `ScrapReworkView.vue` | 报废返工处理 | 若仍在使用,应按退货/返工处置单统一;若已被仓库/退货库替代,应清理或降级为台账 | P2 | | 发货概览 | `ScrapReworkView.vue` | 报废返工处理 | 若仍在使用,应按退货/返工处置单统一;若已被仓库/退货库替代,应清理或降级为台账 | P2 |
| 生产执行 | `CompletionReceiptView.vue` | 成品入库 | 旧入口如果仍可用,需要和仓库生产入库/生产台账入库统一;如果已被新流程替代,应标记为旧入口 | P2 | | 生产执行 | `CompletionReceiptView.vue` | 成品入库 | 旧入口如果仍可用,需要和仓库生产入库/生产台账入库统一;如果已被新流程替代,应标记为旧入口 | P2 |
| 嘉恒仓库 | `StocktakeDialog.vue` | 盘库单 | 盘库会改库存,应纳入纸质盘库单和 PDF 归档,但可排在特殊出入库之后 | P2 | | 百华仓库 | `StocktakeDialog.vue` | 盘库单 | 盘库会改库存,应纳入纸质盘库单和 PDF 归档,但可排在特殊出入库之后 | P2 |
## 推荐方案 ## 推荐方案

View File

@ -1,4 +1,4 @@
# 宁波嘉恒智能科技有限公司 ERP 设计方案 # 宁波百华智能科技有限公司 ERP 设计方案
## 1. 项目定位 ## 1. 项目定位

View File

@ -1,6 +1,6 @@
# 采购使用说明手册 # 采购使用说明手册
适用模块:`采购与库存 -> 采购订单`、`采购与库存 -> 到货入库`、`采购与库存 -> 质量检验`、`采购与库存 -> 嘉恒仓库`。 适用模块:`采购与库存 -> 采购订单`、`采购与库存 -> 到货入库`、`采购与库存 -> 质量检验`、`采购与库存 -> 百华仓库`。
本手册面向采购专员、仓库管理人员和管理人员,用于说明从采购下单、锁单、到货、质检、入库、退货到合同生成的完整操作方式。 本手册面向采购专员、仓库管理人员和管理人员,用于说明从采购下单、锁单、到货、质检、入库、退货到合同生成的完整操作方式。
@ -251,14 +251,14 @@ flowchart TD
| 已拒收 | 不进入可用库存,采购和仓库需要协同处理。 | | 已拒收 | 不进入可用库存,采购和仓库需要协同处理。 |
| 待质检 | 暂时不可用,不能当作可生产库存。 | | 待质检 | 暂时不可用,不能当作可生产库存。 |
如果材料入仓后才发现质量或性能问题,应在嘉恒仓库的 `原材料库 -> 退货出库` 中办理退货。 如果材料入仓后才发现质量或性能问题,应在百华仓库的 `原材料库 -> 退货出库` 中办理退货。
## 9. 原材料退货出库 ## 9. 原材料退货出库
入口: 入口:
```text ```text
采购与库存 -> 嘉恒仓库 -> 原材料库 -> 出库 -> 退货出库 采购与库存 -> 百华仓库 -> 原材料库 -> 出库 -> 退货出库
``` ```
适用场景: 适用场景:
@ -284,9 +284,9 @@ flowchart TD
| 某张采购订单是否锁单 | 采购与库存 -> 采购订单 | | 某张采购订单是否锁单 | 采购与库存 -> 采购订单 |
| 某采购订单到了多少 | 采购与库存 -> 到货入库 | | 某采购订单到了多少 | 采购与库存 -> 到货入库 |
| 到货是否质检放行 | 采购与库存 -> 质量检验 | | 到货是否质检放行 | 采购与库存 -> 质量检验 |
| 材料是否形成库存批次 | 采购与库存 -> 嘉恒仓库 -> 原材料库 | | 材料是否形成库存批次 | 采购与库存 -> 百华仓库 -> 原材料库 |
| 某采购订单是否存在退货 | 采购与库存 -> 采购订单,查看警示标记 | | 某采购订单是否存在退货 | 采购与库存 -> 采购订单,查看警示标记 |
| 某材料批次来源采购单 | 嘉恒仓库 -> 原材料库 -> 批次明细 | | 某材料批次来源采购单 | 百华仓库 -> 原材料库 -> 批次明细 |
## 11. 常见问题 ## 11. 常见问题

View File

@ -1,6 +1,6 @@
# 销售使用说明手册 # 销售使用说明手册
适用模块:`基础资料 -> 客户名录`、`订单与计划 -> 销售订单列表`、`采购与库存 -> 采购订单`、`采购与库存 -> 嘉恒仓库 -> 成品库 -> 销售出库`、`发货概览 -> 发货台账`。 适用模块:`基础资料 -> 客户名录`、`订单与计划 -> 销售订单列表`、`采购与库存 -> 采购订单`、`采购与库存 -> 百华仓库 -> 成品库 -> 销售出库`、`发货概览 -> 发货台账`。
本手册面向销售人员、管理人员和仓库发货人员,用于说明客户维护、销售订单创建、合同生成、采购联动、成品发货、发货追溯和客户退货处理。 本手册面向销售人员、管理人员和仓库发货人员,用于说明客户维护、销售订单创建、合同生成、采购联动、成品发货、发货追溯和客户退货处理。
@ -174,19 +174,19 @@ flowchart TD
## 8. 销售出库 ## 8. 销售出库
销售出库目前在嘉恒仓库的成品库中办理。 销售出库目前在百华仓库的成品库中办理。
入口: 入口:
```text ```text
采购与库存 -> 嘉恒仓库 -> 成品库 -> 出库 -> 销售出库 采购与库存 -> 百华仓库 -> 成品库 -> 出库 -> 销售出库
``` ```
销售出库用于把成品库存发给客户,并回写销售订单已发数量。 销售出库用于把成品库存发给客户,并回写销售订单已发数量。
操作步骤: 操作步骤:
1. 进入嘉恒仓库。 1. 进入百华仓库。
2. 选择 `成品库` 2. 选择 `成品库`
3. 点击出库区的 `销售出库` 3. 点击出库区的 `销售出库`
4. 选择是否关联销售订单。 4. 选择是否关联销售订单。
@ -230,12 +230,12 @@ flowchart TD
## 10. 客户退货处理 ## 10. 客户退货处理
客户退货不再放在旧的 `发货与售后 -> 退货处理` 中,而是在嘉恒仓库中按退回品去向处理。 客户退货不再放在旧的 `发货与售后 -> 退货处理` 中,而是在百华仓库中按退回品去向处理。
| 客户退货判断 | 操作入口 | 说明 | | 客户退货判断 | 操作入口 | 说明 |
| --- | --- | --- | | --- | --- | --- |
| 可返工 | 嘉恒仓库 -> 退货库 -> 入库 -> 退货入库 | 退货品进入退货库,后续可返工出库。 | | 可返工 | 百华仓库 -> 退货库 -> 入库 -> 退货入库 | 退货品进入退货库,后续可返工出库。 |
| 不可返工,直接报废 | 嘉恒仓库 -> 废料库 -> 入库 -> 退货废料入库 | 退货品直接进入废料库。 | | 不可返工,直接报废 | 百华仓库 -> 废料库 -> 入库 -> 退货废料入库 | 退货品直接进入废料库。 |
退货入库时,应选择原发货批次或发货明细,系统会追溯到原销售订单、产品和原材料库存批次。 退货入库时,应选择原发货批次或发货明细,系统会追溯到原销售订单、产品和原材料库存批次。
@ -262,8 +262,8 @@ flowchart TD
| 生成销售合同 | 订单与计划 -> 销售订单列表 | | 生成销售合同 | 订单与计划 -> 销售订单列表 |
| 看销售订单是否采购联动 | 订单与计划 -> 销售订单列表,或采购与库存 -> 采购订单 | | 看销售订单是否采购联动 | 订单与计划 -> 销售订单列表,或采购与库存 -> 采购订单 |
| 看销售订单是否发货 | 发货概览 -> 发货台账 | | 看销售订单是否发货 | 发货概览 -> 发货台账 |
| 办理销售发货 | 采购与库存 -> 嘉恒仓库 -> 成品库 -> 销售出库 | | 办理销售发货 | 采购与库存 -> 百华仓库 -> 成品库 -> 销售出库 |
| 办理客户退货 | 采购与库存 -> 嘉恒仓库 -> 退货库或废料库 | | 办理客户退货 | 采购与库存 -> 百华仓库 -> 退货库或废料库 |
## 12. 常见问题 ## 12. 常见问题

View File

@ -1,12 +1,12 @@
# 仓库使用说明手册 # 仓库使用说明手册
适用模块:`采购与库存 -> 嘉恒仓库`、`生产执行 -> 工单台账`、`采购与库存 -> 到货入库`、`采购与库存 -> 质量检验`、`发货概览 -> 发货台账`。 适用模块:`采购与库存 -> 百华仓库`、`生产执行 -> 工单台账`、`采购与库存 -> 到货入库`、`采购与库存 -> 质量检验`、`发货概览 -> 发货台账`。
本手册面向仓库管理人员、生产管理人员和管理人员,用于说明嘉恒仓库六大库的库存口径、出入库操作、库存批次、流水、盘库和追溯方式。 本手册面向仓库管理人员、生产管理人员和管理人员,用于说明百华仓库六大库的库存口径、出入库操作、库存批次、流水、盘库和追溯方式。
## 1. 嘉恒仓库总览 ## 1. 百华仓库总览
嘉恒仓库目前包含六大库: 百华仓库目前包含六大库:
| 仓库 | 主要对象 | 主计量口径 | 说明 | | 仓库 | 主要对象 | 主计量口径 | 说明 |
| --- | --- | --- | --- | | --- | --- | --- | --- |
@ -29,7 +29,7 @@
```mermaid ```mermaid
flowchart TD flowchart TD
A["进入嘉恒仓库"] --> B["选择仓库"] A["进入百华仓库"] --> B["选择仓库"]
B --> C["查看库存总览"] B --> C["查看库存总览"]
B --> D["选择入库操作"] B --> D["选择入库操作"]
B --> E["选择出库操作"] B --> E["选择出库操作"]
@ -313,7 +313,7 @@ flowchart TD
入口: 入口:
```text ```text
嘉恒仓库 -> 选择仓库 -> 点击流水图标 百华仓库 -> 选择仓库 -> 点击流水图标
``` ```
流水用于回答: 流水用于回答:
@ -332,7 +332,7 @@ flowchart TD
入口: 入口:
```text ```text
嘉恒仓库 -> 选择仓库 -> 盘库 百华仓库 -> 选择仓库 -> 盘库
``` ```
盘库规则: 盘库规则:

View File

@ -3,10 +3,10 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg?v=4" /> <link rel="icon" type="image/png" href="/logo-mark.png" />
<link rel="alternate icon" type="image/png" href="/logo.png" /> <link rel="alternate icon" type="image/png" href="/logo-mark.png" />
<link rel="apple-touch-icon" href="/logo.png" /> <link rel="apple-touch-icon" href="/logo-mark.png" />
<title>嘉恒智能五金 ERP</title> <title>百华智能五金 ERP</title>
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>

View File

@ -1,54 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="238 65 828 828" role="img" aria-label="嘉恒智能">
<defs>
<linearGradient id="logoBlue" x1="258" y1="166" x2="1047" y2="748" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#12a6df"/>
<stop offset="0.48" stop-color="#087fc3"/>
<stop offset="1" stop-color="#005ba8"/>
</linearGradient>
<linearGradient id="logoBlueDark" x1="313" y1="279" x2="936" y2="688" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#0d8ed0"/>
<stop offset="1" stop-color="#004f9c"/>
</linearGradient>
</defs>
<g fill="none" fill-rule="evenodd">
<path
fill="url(#logoBlueDark)"
d="M651 53l22 67 70 1-57 41 21 68-56-42-57 42 22-68-57-41 70-1z"
/>
<path stroke="#087fc3" stroke-width="18" stroke-linecap="round" d="M651 188v88"/>
<path
fill="url(#logoBlue)"
d="M650 244 516 167 238 328v314l278 160 134-77V613L516 691 332 585V385l184-106 134 77z"
/>
<path
fill="url(#logoBlue)"
d="M654 244 788 167l278 161v314L788 802l-134-77V613l134 78 184-106V385L788 279l-134 77z"
/>
<path
fill="url(#logoBlueDark)"
d="M574 179c0-26 28-43 51-30l108 62c16 9 26 26 26 44v142l122 70c23 13 23 47 0 60l-122 70v142c0 18-10 35-26 44l-108 62c-23 13-51-4-51-30V597L452 527c-23-13-23-47 0-60l122-70z"
/>
<path
stroke="#fff"
stroke-width="50"
stroke-linecap="round"
stroke-linejoin="round"
d="M651 275v204M651 479 512 398M651 479l139-81M651 479v205M651 684l-139-81M651 684l139-81"
/>
<path
stroke="#fff"
stroke-width="42"
stroke-linecap="round"
stroke-linejoin="round"
d="M390 433v119l126 73M914 433v119l-126 73"
/>
<path
fill="#087fc3"
d="M229 883c181-76 665-76 846 0-220-38-626-38-846 0z"
/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 509 KiB

After

Width:  |  Height:  |  Size: 120 KiB

View File

@ -1,54 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1304" height="1028" viewBox="0 0 1304 1028" role="img" aria-label="宁波嘉恒智能科技有限公司 logo">
<defs>
<linearGradient id="logoBlue" x1="258" y1="166" x2="1047" y2="748" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#12a6df"/>
<stop offset="0.48" stop-color="#087fc3"/>
<stop offset="1" stop-color="#005ba8"/>
</linearGradient>
<linearGradient id="logoBlueDark" x1="313" y1="279" x2="936" y2="688" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#0d8ed0"/>
<stop offset="1" stop-color="#004f9c"/>
</linearGradient>
</defs>
<g fill="none" fill-rule="evenodd">
<path
fill="url(#logoBlueDark)"
d="M651 53l22 67 70 1-57 41 21 68-56-42-57 42 22-68-57-41 70-1z"
/>
<path stroke="#087fc3" stroke-width="18" stroke-linecap="round" d="M651 188v88"/>
<path
fill="url(#logoBlue)"
d="M650 244 516 167 238 328v314l278 160 134-77V613L516 691 332 585V385l184-106 134 77z"
/>
<path
fill="url(#logoBlue)"
d="M654 244 788 167l278 161v314L788 802l-134-77V613l134 78 184-106V385L788 279l-134 77z"
/>
<path
fill="url(#logoBlueDark)"
d="M574 179c0-26 28-43 51-30l108 62c16 9 26 26 26 44v142l122 70c23 13 23 47 0 60l-122 70v142c0 18-10 35-26 44l-108 62c-23 13-51-4-51-30V597L452 527c-23-13-23-47 0-60l122-70z"
/>
<path
stroke="#fff"
stroke-width="50"
stroke-linecap="round"
stroke-linejoin="round"
d="M651 275v204M651 479 512 398M651 479l139-81M651 479v205M651 684l-139-81M651 684l139-81"
/>
<path
stroke="#fff"
stroke-width="42"
stroke-linecap="round"
stroke-linejoin="round"
d="M390 433v119l126 73M914 433v119l-126 73"
/>
<path
fill="#087fc3"
d="M229 883c181-76 665-76 846 0-220-38-626-38-846 0z"
/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -4,9 +4,9 @@
<div v-else :class="shellClass"> <div v-else :class="shellClass">
<aside class="sidebar"> <aside class="sidebar">
<div class="brand"> <div class="brand">
<img class="brand-logo" src="/logo.svg" alt="宁波嘉恒智能科技有限公司 logo" /> <img class="brand-logo" src="/logo-mark.png" alt="宁波百华智能科技有限公司 logo" />
<div> <div>
<h1>嘉恒智能</h1> <h1>百华智能</h1>
</div> </div>
</div> </div>
@ -60,7 +60,7 @@
<div class="sidebar-footer"> <div class="sidebar-footer">
<div class="status-chip"> <div class="status-chip">
<span class="status-dot"></span> <span class="status-dot"></span>
采购嘉恒仓库生产发货财务售后系统拓展已接入真实业务流 采购百华仓库生产发货财务售后系统拓展已接入真实业务流
</div> </div>
</div> </div>
</aside> </aside>
@ -186,7 +186,7 @@
</span> </span>
<div> <div>
<p class="eyebrow">AI 助手</p> <p class="eyebrow">AI 助手</p>
<h3>嘉恒工艺助手</h3> <h3>百华工艺助手</h3>
<p>当前为内置占位对话真实 LLM 可在 08 系统拓展中配置</p> <p>当前为内置占位对话真实 LLM 可在 08 系统拓展中配置</p>
</div> </div>
</div> </div>
@ -326,7 +326,7 @@ const chatMessages = ref([
{ {
id: 1, id: 1,
role: "assistant", role: "assistant",
content: "你好,我是嘉恒工艺助手。你可以问我系统操作路径、字段含义、业务流程或异常排查。" content: "你好,我是百华工艺助手。你可以问我系统操作路径、字段含义、业务流程或异常排查。"
} }
]); ]);
const changePasswordForm = ref({ const changePasswordForm = ref({
@ -523,7 +523,7 @@ const navStages = [
key: "procurement", key: "procurement",
step: "04", step: "04",
label: "采购与库存", label: "采购与库存",
desc: "采购、自家料入库、质量检验和嘉恒仓库。", desc: "采购、自家料入库、质量检验和百华仓库。",
tail: "采购", tail: "采购",
icon: "warehouse", icon: "warehouse",
iconPaths: [ iconPaths: [
@ -589,7 +589,7 @@ const navStages = [
}, },
{ {
key: "inventory-ledger", key: "inventory-ledger",
label: "嘉恒仓库", label: "百华仓库",
icon: "warehouse", icon: "warehouse",
to: { name: "inventory-ledger" }, to: { name: "inventory-ledger" },
routeNames: ["inventory-ledger"], routeNames: ["inventory-ledger"],
@ -765,7 +765,7 @@ const navStages = [
]; ];
const isAuthLayout = computed(() => route.meta.layout === "auth"); const isAuthLayout = computed(() => route.meta.layout === "auth");
const currentTitle = computed(() => route.meta.title || "嘉恒智能五金 ERP"); const currentTitle = computed(() => route.meta.title || "百华智能五金 ERP");
const shellClass = computed(() => ({ const shellClass = computed(() => ({
shell: true, shell: true,
"admin-shell": true, "admin-shell": true,

View File

@ -4,7 +4,7 @@
<section class="stocktake-shell"> <section class="stocktake-shell">
<header class="stocktake-head"> <header class="stocktake-head">
<div> <div>
<p class="eyebrow">嘉恒仓库 · 盘库</p> <p class="eyebrow">百华仓库 · 盘库</p>
<h3>{{ activeStocktake ? activeStocktake.stocktake_no : "新建盘库" }}</h3> <h3>{{ activeStocktake ? activeStocktake.stocktake_no : "新建盘库" }}</h3>
</div> </div>
<button class="ghost-button" type="button" @click="$emit('close')">关闭</button> <button class="ghost-button" type="button" @click="$emit('close')">关闭</button>

View File

@ -46,7 +46,7 @@ const props = defineProps({
}, },
companyName: { companyName: {
type: String, type: String,
default: "宁波嘉恒智能科技有限公司" default: "宁波百华智能科技有限公司"
}, },
metaLabel: { metaLabel: {
type: String, type: String,

View File

@ -66,7 +66,7 @@ const props = defineProps({
}, },
companyName: { companyName: {
type: String, type: String,
default: "嘉恒仓库 ERP" default: "百华仓库 ERP"
}, },
tone: { tone: {
type: String, type: String,

View File

@ -36,7 +36,7 @@ defineProps({
}, },
companyName: { companyName: {
type: String, type: String,
default: "嘉恒仓库" default: "百华仓库"
}, },
signatureLabels: { signatureLabels: {
type: Array, type: Array,

View File

@ -14539,11 +14539,11 @@ body .login-line-brand {
position: relative; position: relative;
z-index: 2; z-index: 2;
display: inline-grid; display: inline-grid;
grid-template-columns: 48px minmax(0, max-content); grid-template-columns: minmax(116px, 150px) minmax(0, max-content);
gap: 12px; gap: 12px;
align-items: center; align-items: center;
justify-self: start; justify-self: start;
max-width: min(280px, 100%); max-width: min(380px, 100%);
padding: 10px 15px 10px 10px; padding: 10px 15px 10px 10px;
border: 1px solid rgba(148, 163, 184, 0.2); border: 1px solid rgba(148, 163, 184, 0.2);
border-radius: 20px; border-radius: 20px;
@ -14558,10 +14558,11 @@ body .login-line-brand {
body .login-line-brand .login-logo, body .login-line-brand .login-logo,
body .login-production-layout .login-logo { body .login-production-layout .login-logo {
width: 48px; width: 150px;
height: 48px; height: 48px;
border-radius: 16px; border-radius: 14px;
object-fit: contain; object-fit: contain;
object-position: center;
background: rgba(255, 255, 255, 0.94); background: rgba(255, 255, 255, 0.94);
box-shadow: 0 12px 32px rgba(2, 6, 23, 0.28); box-shadow: 0 12px 32px rgba(2, 6, 23, 0.28);
} }
@ -15785,13 +15786,13 @@ body .login-production-layout .login-security-foot p {
} }
body .login-line-brand { body .login-line-brand {
grid-template-columns: 42px minmax(0, max-content); grid-template-columns: minmax(96px, 128px) minmax(0, max-content);
border-radius: 17px; border-radius: 17px;
} }
body .login-line-brand .login-logo, body .login-line-brand .login-logo,
body .login-production-layout .login-logo { body .login-production-layout .login-logo {
width: 42px; width: 128px;
height: 42px; height: 42px;
} }

View File

@ -2,7 +2,7 @@
<ProcessWorkspace <ProcessWorkspace
eyebrow="发货概览" eyebrow="发货概览"
title="成品销售出库交付工作台" title="成品销售出库交付工作台"
description="发货概览模块只保留成品发运;客户退货、退货废料和返工出库统一到嘉恒仓库办理。" description="发货概览模块只保留成品发运;客户退货、退货废料和返工出库统一到百华仓库办理。"
panel-tag="交付主流程" panel-tag="交付主流程"
stage-code="06" stage-code="06"
:sections="sections" :sections="sections"

View File

@ -1,7 +1,7 @@
<template> <template>
<section class="page-grid"> <section class="page-grid">
<section class="panel inventory-unified-panel"> <section class="panel inventory-unified-panel">
<div class="warehouse-switchboard" role="tablist" aria-label="嘉恒仓库库存类型"> <div class="warehouse-switchboard" role="tablist" aria-label="百华仓库库存类型">
<button <button
v-for="tab in inventoryTabs" v-for="tab in inventoryTabs"
:key="tab.key" :key="tab.key"
@ -1331,7 +1331,7 @@
<FormDrawer <FormDrawer
:open="openingImportDrawerOpen" :open="openingImportDrawerOpen"
eyebrow="嘉恒仓库 · 期初导入" eyebrow="百华仓库 · 期初导入"
:title="`${activeInventoryLabel}期初库存导入`" :title="`${activeInventoryLabel}期初库存导入`"
tag="库存初始化" tag="库存初始化"
wide wide
@ -1899,7 +1899,7 @@
<FormDrawer <FormDrawer
:open="warehouseLedgerDrawerOpen" :open="warehouseLedgerDrawerOpen"
eyebrow="嘉恒仓库 · 库级流水" eyebrow="百华仓库 · 库级流水"
:title="`${activeInventoryLabel} · 出入库流水`" :title="`${activeInventoryLabel} · 出入库流水`"
tag="库存流水" tag="库存流水"
wide wide
@ -2055,7 +2055,7 @@
<FormDrawer <FormDrawer
:open="productionWorkOrderInboundDrawerOpen" :open="productionWorkOrderInboundDrawerOpen"
eyebrow="嘉恒仓库 · 生产台账入库" eyebrow="百华仓库 · 生产台账入库"
title="生产台账入库" title="生产台账入库"
description="按在生产的材料库存批次号统一办理成品入库、生产余料入库和生产废料入库。" description="按在生产的材料库存批次号统一办理成品入库、生产余料入库和生产废料入库。"
tag="材料批次闭环" tag="材料批次闭环"

View File

@ -13,11 +13,11 @@
</div> </div>
<main class="login-production-cockpit" @click.stop> <main class="login-production-cockpit" @click.stop>
<section class="login-line-area" aria-label="嘉恒五金冲压产线"> <section class="login-line-area" aria-label="百华五金冲压产线">
<div class="login-line-brand"> <div class="login-line-brand">
<img class="login-logo" src="/logo.svg" alt="宁波嘉恒智能科技有限公司 logo" /> <img class="login-logo login-logo-wordmark" src="/logo.png" alt="宁波百华智能科技有限公司 logo" />
<div> <div>
<span>嘉恒智能</span> <span>百华智能</span>
</div> </div>
</div> </div>
@ -98,7 +98,7 @@
<div class="login-console-frame"> <div class="login-console-frame">
<div class="login-control-console"> <div class="login-control-console">
<div class="login-panel-head"> <div class="login-panel-head">
<h2>嘉恒智能五金 ERP</h2> <h2>百华智能五金 ERP</h2>
</div> </div>
<form class="login-form" @submit.prevent="handleLogin"> <form class="login-form" @submit.prevent="handleLogin">

View File

@ -1,8 +1,8 @@
<template> <template>
<ProcessWorkspace <ProcessWorkspace
eyebrow="采购与库存" eyebrow="采购与库存"
title="采购与嘉恒仓库工作台" title="采购与百华仓库工作台"
description="覆盖采购下单、自家料到货、质检和嘉恒仓库出入库台账。" description="覆盖采购下单、自家料到货、质检和百华仓库出入库台账。"
panel-tag="仓库主流程" panel-tag="仓库主流程"
stage-code="04" stage-code="04"
:sections="sections" :sections="sections"
@ -44,7 +44,7 @@ const sections = [
{ {
key: "inventory-ledger", key: "inventory-ledger",
step: "04-4", step: "04-4",
label: "嘉恒仓库", label: "百华仓库",
desc: "统一处理原材料、半成品、成品、辅料的出入库和批次流水。", desc: "统一处理原材料、半成品、成品、辅料的出入库和批次流水。",
permission: "MENU_INVENTORY_LEDGER", permission: "MENU_INVENTORY_LEDGER",
component: InventoryLedgerView component: InventoryLedgerView

View File

@ -1471,7 +1471,7 @@ function renderPurchaseContractHtml(contractOrders) {
<div class="contract-no">合同编号${escapeHtml(contractNo)}</div> <div class="contract-no">合同编号${escapeHtml(contractNo)}</div>
<div class="meta-grid"> <div class="meta-grid">
<div><strong>甲方采购方</strong>${escapeHtml("嘉恒智能五金")}</div> <div><strong>甲方采购方</strong>${escapeHtml("百华智能五金")}</div>
<div><strong>乙方供应方</strong>${escapeHtml(normalizeContractText(supplier?.supplier_name))}</div> <div><strong>乙方供应方</strong>${escapeHtml(normalizeContractText(supplier?.supplier_name))}</div>
<div><strong>乙方联系人</strong>${escapeHtml(normalizeContractText(supplier?.contact_name))}</div> <div><strong>乙方联系人</strong>${escapeHtml(normalizeContractText(supplier?.contact_name))}</div>
<div><strong>乙方电话</strong>${escapeHtml(normalizeContractText(supplier?.contact_phone))}</div> <div><strong>乙方电话</strong>${escapeHtml(normalizeContractText(supplier?.contact_phone))}</div>
@ -1530,7 +1530,7 @@ function renderPurchaseContractHtml(contractOrders) {
日期 日期
</div> </div>
</div> </div>
<p class="muted">该合同由嘉恒智能五金 ERP 按当前采购订单数据自动生成</p> <p class="muted">该合同由百华智能五金 ERP 按当前采购订单数据自动生成</p>
</main> </main>
</body> </body>
</html>`; </html>`;

View File

@ -961,7 +961,7 @@ function renderContractHtml(orders) {
<div class="meta-grid"> <div class="meta-grid">
<div><strong>甲方买方</strong>${escapeHtml(normalizeContractText(customer?.customer_name))}</div> <div><strong>甲方买方</strong>${escapeHtml(normalizeContractText(customer?.customer_name))}</div>
<div><strong>乙方卖方</strong>${escapeHtml("嘉恒智能五金")}</div> <div><strong>乙方卖方</strong>${escapeHtml("百华智能五金")}</div>
<div><strong>甲方联系人</strong>${escapeHtml(normalizeContractText(customer?.contact_name))}</div> <div><strong>甲方联系人</strong>${escapeHtml(normalizeContractText(customer?.contact_name))}</div>
<div><strong>甲方电话</strong>${escapeHtml(normalizeContractText(customer?.contact_phone))}</div> <div><strong>甲方电话</strong>${escapeHtml(normalizeContractText(customer?.contact_phone))}</div>
<div><strong>合同日期</strong>${escapeHtml(currentDateText())}</div> <div><strong>合同日期</strong>${escapeHtml(currentDateText())}</div>
@ -1033,7 +1033,7 @@ function renderContractHtml(orders) {
日期 日期
</div> </div>
</div> </div>
<p class="muted">该合同由嘉恒智能五金 ERP 按当前销售订单数据自动生成</p> <p class="muted">该合同由百华智能五金 ERP 按当前销售订单数据自动生成</p>
</main> </main>
</body> </body>
</html>`; </html>`;

View File

@ -419,13 +419,13 @@ function buildEmptyBroadcastForm() {
function buildEmptyAssistantForm() { function buildEmptyAssistantForm() {
return { return {
assistant_name: "嘉恒工艺助手", assistant_name: "百华工艺助手",
provider_name: "", provider_name: "",
api_base_url: "", api_base_url: "",
api_key: "", api_key: "",
model_name: "", model_name: "",
temperature: 0.3, temperature: 0.3,
system_prompt: "你是宁波嘉恒智能五金 ERP 的企业助手,优先解释业务流程、字段含义、数据异常和操作步骤。", system_prompt: "你是宁波百华智能五金 ERP 的企业助手,优先解释业务流程、字段含义、数据异常和操作步骤。",
enabled: false enabled: false
}; };
} }
@ -567,7 +567,7 @@ function restoreSectionSnapshot(sectionKey) {
if (sectionKey === "assistant") { if (sectionKey === "assistant") {
Object.assign(assistantForm, { Object.assign(assistantForm, {
assistant_name: snapshot.assistant_name || "嘉恒工艺助手", assistant_name: snapshot.assistant_name || "百华工艺助手",
provider_name: snapshot.provider_name || "", provider_name: snapshot.provider_name || "",
api_base_url: snapshot.api_base_url || "", api_base_url: snapshot.api_base_url || "",
api_key: "", api_key: "",
@ -585,7 +585,7 @@ function restoreSectionSnapshot(sectionKey) {
function applyAssistantConfig(config) { function applyAssistantConfig(config) {
assistantConfig.value = config || {}; assistantConfig.value = config || {};
Object.assign(assistantForm, { Object.assign(assistantForm, {
assistant_name: config?.assistant_name || "嘉恒工艺助手", assistant_name: config?.assistant_name || "百华工艺助手",
provider_name: config?.provider_name || "", provider_name: config?.provider_name || "",
api_base_url: config?.api_base_url || "", api_base_url: config?.api_base_url || "",
api_key: "", api_key: "",