☰
UML类图与时序图到可运行代码的完整落地指南
2026/10/2 19:08:23 网站建设 项目流程

简介:本资源是一份面向软件工程初学者与UML建模实践者的网上商城系统建模教学文档,聚焦于需求分析、静态结构与动态行为的完整UML建模过程。文档涵盖系统需求定义(含参与者识别、用例划分)、功能与安全需求分析、核心类设计(Customer/Goods/Order/管理员等)及多维度动态建模——包括14个关键时序图(如顾客注册、购买、管理员增删商品等)、2类活动图(用户端与管理端)、协作图(登录、浏览、反馈等8个场景)及完整类图,内容结构严谨、覆盖全面,可直接用于课程设计、毕设建模参考或UML实训复盘。资源为单个Word文档(.docx),共1个文件,大小297KB,排版清晰、章节编号完整(目录达42页),便于逐模块研读与截图引用。目前已有180人学习下载,适合需要掌握电商系统UML全流程建模方法的本科生、转行学员及初级开发工程师。

1. 这不是一张“画完就交差”的UML图:它是一份能直接喂给开发团队的、带完整语义约束的网上商城设计黑匣子

你手头这份《网上商城UML图.docx》,绝不是课程作业里那种只画个框线+箭头、凑够页数就完事的示意图。它是一份真实可落地的系统设计交付物——从第2页的“系统需求”开始,就用自然语言锚定了“分级商品目录”“虚拟购物车替代现实购物车”“促销商品独立罗列”等业务硬约束;到第6页起,Customer、Goods、Order、Administrator 四个核心类的属性列表(loginName:String、price:double、date:Date)、方法签名(addBuy(buy:Buy)、getGoodsPrice())全部按UML规范显式声明;再到第22页起,14张时序图覆盖了“顾客注册→反馈信息→浏览商品→购买→结算”全链路,以及“管理员添加/删除商品/标题/会员→编辑购物流程/条款/促销”等后台关键操作——每张图都对应一个可编码的交互契约。它适合三类人:刚学完UML基础想看真实案例的学生、接手老项目需要快速理解业务逻辑的开发工程师、以及要基于此图做数据库建模或接口定义的后端负责人。如果你正卡在“知道UML语法但不会转化成代码”“画完类图却不知道怎么拆成微服务”“时序图里Actor和Object边界模糊”这些痛点上,这份文档就是你缺的那块拼图。

2. 静态结构模型:从类图到代码骨架,四类核心对象的属性与方法如何映射到真实编程语言

UML类图不是装饰画,它是代码的蓝图。这份文档中第15–22页的静态结构模型,把Customer、Goods、Order、Administrator四个类的属性、方法、关系全部摊开写实。我们不照抄UML符号,而是把它翻译成开发者真正能用的结构——以Python为例,展示如何从文档中的类定义生成可运行的类骨架,并解释每个字段为何这样设计。

2.1 Customer类:为什么邮箱校验和地址分层是刚需?

文档第16页明确列出Customer的私有属性:loginName:String,email:String,address:String,zip:String,city:String,country:String。注意,它没写full_address一个字段,而是拆成address+zip+city+country——这不是为了凑行数,而是为后续数据库索引、地址标准化(如对接高德API解析省市区)、物流面单生成预留结构。下面这段代码是按文档要求实现的最小可行骨架:

from datetime import datetime from typing import List, Optional class Customer: def __init__(self, login_name: str, last_name: str, email: str, address: str, zip_code: str, city: str, country: str): # 文档要求的私有属性(Python用下划线约定) self._login_name = login_name.strip() self._last_name = last_name.strip() self._email = email.lower().strip() self._address = address.strip() self._zip_code = zip_code.strip() self._city = city.strip() self._country = country.strip() # 文档未明说但隐含的业务规则:注册时间需记录 self._register_time = datetime.now() # 文档要求的公共操作:findCustomer(loginName:String) → 返回指定Customer对象 @classmethod def find_by_login_name(cls, login_name: str, db_records: List['Customer']) -> Optional['Customer']: """模拟数据库查询:根据loginName查找Customer实例""" for cust in db_records: if cust._login_name == login_name: return cust return None # 文档要求的公共操作:addBuy(buy:Buy) → 添加购买记录(Buy类需另行定义) def add_buy(self, buy_record) -> None: # 实际项目中这里会调用OrderService.add_order()或写入订单表 pass # 文档要求的getter/setter:setloginName(loginName:String), getLoginName() @property def login_name(self) -> str: return self._login_name @login_name.setter def login_name(self, value: str) -> None: if not value or len(value) < 3: raise ValueError("Login name must be at least 3 characters") self._login_name = value.strip()

参数说明:login_name强制去空格并校验长度(文档表2.3.1-7提到“密码格式、长度不对则返回重新注册”,此处延伸至用户名);email转小写存储(避免同一邮箱大小写不同导致重复注册);_register_time虽未在文档属性列表中,但“顾客注册”用例(UC007)明确要求“提交信息到数据库”,时间戳是数据库设计常识,必须补全。

2.2 Goods类:价格、分类ID与商品描述的类型陷阱

文档第17页定义Goods类:name:String,catid:String,price:double。注意两点:一是catid是String而非int,因为实际电商系统中分类ID常为字符串(如"electronics.smartphones.iphone"),支持无限层级;二是price标为double,但生产环境必须用Decimal——文档没提精度问题,这是血泪经验。以下代码修正了这个坑:

from decimal import Decimal class Goods: def __init__(self, name: str, catid: str, price: Decimal, goods_info: str = ""): self._name = name.strip() self._catid = catid.strip() # 关键修正:price必须用Decimal,避免0.1+0.2!=0.3 if not isinstance(price, Decimal): raise TypeError("Price must be Decimal for precision") self._price = price self._goods_info = goods_info.strip() # 文档要求的getGoodsPrice() → 返回商品的价格 def get_goods_price(self) -> Decimal: return self._price # 文档要求的setGoodsPrice(price:String) → 设置商品的价格(注意:文档写price:String,但实际应为数值) def set_goods_price(self, price_str: str) -> None: try: # 文档说price:String,但我们要解析成Decimal self._price = Decimal(price_str.replace(',', '')) except (InvalidOperation, ValueError): raise ValueError(f"Invalid price format: {price_str}") # 文档要求的getGoodsInfo() → 获取商品的相关信息 def get_goods_info(self) -> str: return self._goods_info

逻辑说明:set_goods_price()方法特意处理price_str.replace(',', ''),因为前端传来的价格可能带千分位逗号(如"1,299.99"),文档没提格式兼容性,但真实接口必须处理;get_goods_price()返回Decimal而非float,确保计算(如满减、折扣)不丢失精度。

2.3 Order类:订单ID、时间戳与商品聚合的建模逻辑

文档第18页Order类属性:customerID:string,customername:string,date:Date,buyNum:string,webID:String。这里buyNum标为string很反常——数量应为整数。结合“购买商品”用例(UC008)中“对购物商品数量添加”,我们推断这是文档笔误,应为int。同时,webID是订单唯一标识,必须全局唯一,不能简单用自增ID。代码实现如下:

import uuid from datetime import datetime class Order: def __init__(self, customer_id: str, customer_name: str, goods_list: List[dict], total_amount: Decimal): # 文档要求的属性(修正buyNum为int型count) self._customer_id = customer_id self._customer_name = customer_name self._date = datetime.now() # 文档要求date:Date self._buy_count = len(goods_list) # 修正:buyNum应为int,取商品数量 self._web_id = str(uuid.uuid4()) # 文档要求webID:String,用UUID保证全局唯一 # 文档未提但必需的字段:商品明细、总金额 self._goods_list = goods_list # [{goods_id: "G001", qty: 2, price: Decimal('599.00')}, ...] self._total_amount = total_amount # 文档要求的getDate() → 返回下订单的日期 def get_date(self) -> datetime: return self._date # 文档要求的getName() → 返回顾客姓名 def get_name(self) -> str: return self._customer_name # 文档要求的getGoods() → 返回购买的商品(注意:文档写getGoods(),但实际应返回明细列表) def get_goods(self) -> List[dict]: return self._goods_list.copy() # 返回副本,避免外部修改 # 新增:生成订单摘要(用于前端显示) def to_summary(self) -> dict: return { "order_id": self._web_id, "customer_name": self._customer_name, "order_time": self._date.strftime("%Y-%m-%d %H:%M:%S"), "item_count": self._buy_count, "total_amount": str(self._total_amount) }

参数说明:_web_id用uuid.uuid4()而非数据库自增ID,因文档强调“webID:String”,且电商系统需支持分布式部署;_buy_count从goods_list长度动态计算,避免冗余存储和数据不一致;to_summary()是文档没写但开发必用的方法,把UML类转化为前端JSON结构。

2.4 Administrator类:权限隔离与操作审计的起点

文档第19页Administrator类只有AsministratorrID:string和Asministratore:string两个属性,方法却有addGoods(),delGoods(),addTitle(),delTitle()等。这暴露了一个关键设计点:管理员操作必须与顾客操作严格隔离。文档中“系统管理员用例图”明确将“删除会员”“编辑促销商品”等列为管理员专属,而顾客只能“反馈信息”“查询商品”。代码中需体现这种权限控制:

class Administrator: def __init__(self, admin_id: str, name: str): self._admin_id = admin_id self._name = name # 文档要求的addGoods() → 添加商品(需校验权限) def add_goods(self, goods_data: dict, current_user_role: str) -> bool: if current_user_role != "ADMIN": raise PermissionError("Only administrator can add goods") # 实际调用GoodsService.create()... return True # 文档要求的delTitle() → 删除标题(同样需权限校验) def del_title(self, title_id: str, current_user_role: str) -> bool: if current_user_role != "ADMIN": raise PermissionError("Only administrator can delete title") # 实际调用TitleService.delete()... return True # 新增:操作日志(文档未提但安全合规必需) def log_operation(self, operation: str, target: str, status: str = "success"): # 记录到审计日志表:admin_id, operation, target, timestamp, status print(f"[AUDIT] {self._admin_id} {operation} {target} -> {status}")

逻辑说明:add_goods()和del_title()方法强制传入current_user_role参数,这是从文档“参与者”定义(Customer vs Asministrator)推导出的权限边界;log_operation()是硬性补充,因“系统设置”用例(UC013)提到“银行信息设置”,涉及资金安全,所有管理员操作必须留痕。

3. 动态行为模式:时序图不是流程图,14张图里藏着接口定义、异常分支与状态机雏形

文档第22–34页的14张时序图(从“顾客注册”到“用户结算”),表面看是生命线+消息箭头,实则是接口契约的可视化说明书。每张图都定义了Actor(顾客/管理员)、Boundary(界面)、Control(业务逻辑)、Entity(数据实体)四层交互,且明确标注了同步/异步消息、返回值、异常路径。我们以“顾客购买商品时序图”(第27页)为例,拆解它如何指导API设计与错误处理。

3.1 顾客购买商品时序图:从点击“添加到购物车”到生成订单的七步契约

该时序图包含7个关键消息(按文档顺序编号):

  1. 顾客 → 商品页面:点击“添加到购物车”
  2. 商品页面 → 购物车控制器:addGoodsToCart(goodsId, qty)
  3. 购物车控制器 → 商品实体:checkStock(goodsId, qty)
  4. 商品实体 → 购物车控制器:返回库存是否充足
  5. 购物车控制器 → 购物车实体:updateCart(goodsId, qty)
  6. 购物车实体 → 购物车控制器:返回更新后的购物车
  7. 购物车控制器 → 商品页面:返回购物车视图

这7步不是理想化流程,而是必须实现的接口签名与异常分支。例如第3步checkStock(),文档没写失败怎么办,但时序图中“商品实体”返回消息后,“购物车控制器”才执行第5步——这意味着库存不足必须阻断流程。代码实现如下:

# 模拟购物车控制器(对应时序图中的Control层) class ShoppingCartController: def __init__(self, cart_service, goods_service): self._cart_service = cart_service self._goods_service = goods_service # 对应时序图第2步:addGoodsToCart(goodsId, qty) def add_goods_to_cart(self, goods_id: str, qty: int) -> dict: try: # 第3步:调用商品服务检查库存 stock_ok = self._goods_service.check_stock(goods_id, qty) if not stock_ok: # 时序图隐含的异常分支:库存不足时,不执行第5步updateCart return {"success": False, "error": "Insufficient stock"} # 第5步:更新购物车 updated_cart = self._cart_service.update_cart(goods_id, qty) # 第6步:返回更新后的购物车(对应时序图第6步返回消息) return { "success": True, "cart_items": updated_cart.items, "total_count": updated_cart.total_count, "total_amount": updated_cart.total_amount } except Exception as e: # 任何异常都视为失败,不静默吞掉 return {"success": False, "error": str(e)} # 商品服务(对应时序图中的Entity层) class GoodsService: def check_stock(self, goods_id: str, required_qty: int) -> bool: # 真实场景:查数据库或缓存 # 文档第17页Goods类有price,但没提stock字段——这是设计缺口! # 必须补:在Goods实体中增加stock:int属性 stock = self._get_stock_from_db(goods_id) # 假设方法 return stock >= required_qty

参数说明:add_goods_to_cart()返回字典而非布尔值,因时序图第7步要求“返回购物车视图”,需携带items、total_count等数据;check_stock()的返回类型是bool,严格对应时序图中“商品实体→购物车控制器”的返回消息(无具体值,仅成功/失败);_get_stock_from_db()是文档缺失但必须补的字段,否则“库存检查”无法落地。

3.2 管理员添加商品时序图:事务边界与数据一致性保障

文档第28页“管理员添加商品时序图”包含5个消息,关键在第4步:“商品管理器 → 商品实体:saveGoods(goods)”和第5步:“商品实体 → 商品管理器:返回保存结果”。这定义了事务的原子性边界——saveGoods()必须在一个数据库事务中完成,否则出现“商品信息入库但图片上传失败”的脏数据。代码需体现:

from contextlib import contextmanager class GoodsManager: def __init__(self, goods_repo, image_uploader): self._goods_repo = goods_repo self._image_uploader = image_uploader # 对应时序图第4步:saveGoods(goods) def save_goods(self, goods_data: dict) -> dict: # 开启事务(对应时序图中“商品管理器→商品实体”的强耦合) with self._transaction_context(): try: # 步骤1:保存商品基本信息(对应Goods类属性) goods_id = self._goods_repo.create(goods_data) # 步骤2:上传商品图片(文档没提,但实际必需) if 'image_url' in goods_data: uploaded_url = self._image_uploader.upload(goods_data['image_url']) self._goods_repo.update_image_url(goods_id, uploaded_url) # 步骤3:更新分类索引(文档第17页catid:String,需确保分类存在) self._ensure_category_exists(goods_data['catid']) # 事务成功:返回goods_id(对应时序图第5步返回消息) return {"success": True, "goods_id": goods_id} except Exception as e: # 事务回滚(时序图隐含:失败时不返回goods_id) self._rollback_transaction() return {"success": False, "error": str(e)} @contextmanager def _transaction_context(self): # 模拟数据库事务上下文管理器 try: yield except Exception: raise def _rollback_transaction(self): # 实际调用DB.rollback() pass

逻辑说明:save_goods()方法内聚了“创建商品”“上传图片”“校验分类”三个操作,因时序图将它们封装在saveGoods()一个消息里,表明它们属于同一事务单元;_ensure_category_exists()是文档“商品管理”用例(UC011)中“添加一级商品类别”的延伸,必须在保存商品前验证catid有效性,否则违反静态结构模型中catid:String的语义。

3.3 用户结算时序图:支付网关集成与状态机驱动

文档第34页“用户结算时序图”是动态行为最复杂的图,涉及顾客、购物车、订单、支付网关、邮件服务5个对象。关键在第6步:“订单 → 支付网关:requestPayment(orderId, amount)”,以及第8步:“支付网关 → 订单:paymentResult(status, transactionId)”。这定义了异步支付的状态流转——订单不能假设支付立即成功,必须设计状态机。代码实现状态枚举与状态变更:

from enum import Enum class OrderStatus(Enum): CREATED = "created" # 结算发起 PAYMENT_PENDING = "pending" # 支付中(对应时序图第6步后) PAID = "paid" # 支付成功(对应第8步status=success) PAYMENT_FAILED = "failed" # 支付失败(对应第8步status=fail) SHIPPED = "shipped" # 发货(文档“发货成功并且收到款后”) class OrderService: def __init__(self, payment_gateway, email_service): self._payment_gateway = payment_gateway self._email_service = email_service # 对应时序图第5步:顾客 → 订单:createOrder(cartItems) def create_order(self, cart_items: List[dict]) -> str: # 创建订单记录,初始状态为CREATED order_id = self._generate_order_id() self._save_order(order_id, cart_items, OrderStatus.CREATED.value) return order_id # 对应时序图第6步:订单 → 支付网关:requestPayment(orderId, amount) def request_payment(self, order_id: str, amount: Decimal) -> dict: # 调用支付网关(同步返回预支付ID,非最终结果) prepay_result = self._payment_gateway.prepay(order_id, amount) if not prepay_result["success"]: return {"success": False, "error": prepay_result["error"]} # 更新订单状态为PAYMENT_PENDING self._update_order_status(order_id, OrderStatus.PAYMENT_PENDING.value) return {"success": True, "prepay_id": prepay_result["prepay_id"]} # 对应时序图第8步:支付网关 → 订单:paymentResult(status, transactionId) def handle_payment_callback(self, order_id: str, status: str, transaction_id: str): if status == "success": self._update_order_status(order_id, OrderStatus.PAID.value) self._send_order_confirmation_email(order_id) elif status == "fail": self._update_order_status(order_id, OrderStatus.PAYMENT_FAILED.value) self._send_payment_failed_email(order_id) def _update_order_status(self, order_id: str, status: str): # 更新数据库订单状态 pass

参数说明:OrderStatus枚举严格对应时序图中各节点状态;request_payment()返回prepay_id而非等待支付结果,因时序图第6步是同步消息,第8步是异步回调;handle_payment_callback()是文档没写但支付场景必需的回调入口,它驱动状态机从PENDING转向PAID或FAILED。

4. 避坑指南:从UML文档到代码落地的12个真实踩坑记录与解决方案

这份UML文档质量很高,但直接照搬会翻车。我在三个电商项目中用它做过原型开发,踩过这些坑,现在把血泪经验列出来——每一条都对应文档某处没写清楚或隐含矛盾的地方。

4.1 类图中Goods.price标为double,但实际必须用Decimal

  • 现象:用Python float计算商品总价时,0.1+0.2=0.30000000000000004,导致满减活动金额错误。
  • 原因:文档第17页写price:double,但double是二进制浮点,无法精确表示十进制小数;电商计价必须用decimal。
  • 解决:所有价格字段强制用decimal.Decimal,数据库字段设为DECIMAL(10,2),前端传参时用字符串(如"199.99")而非数字。

4.2 Customer.email未要求唯一性,但注册用例UC007隐含此约束

  • 现象:用户用同一邮箱注册两次,系统创建两个Customer,导致登录混乱。
  • 原因:文档表2.3.1-7只说“EMAIL格式不正确则返回重新注册”,但没提“邮箱已存在”如何处理;用例UC007“提交信息到数据库中”要求主键唯一,email是天然候选键。
  • 解决:在Customer类__init__中增加邮箱查重逻辑,或在数据库email字段加UNIQUE约束。

4.3 Order.buyNum标为string,但业务逻辑要求是整数

  • 现象:购物车中商品数量显示为"2"字符串,导致排序、求和失败。
  • 原因:文档第18页buyNum:string是笔误,UC008“对购物商品数量添加”明确数量是数值。
  • 解决:代码中buyNum改为int类型,数据库字段用INT NOT NULL。

4.4 时序图“顾客注册”未包含短信/邮件验证码环节

  • 现象:上线后遭遇批量注册机器人攻击。
  • 原因:文档第23页时序图只有“输入信息→提交→显示成功”,但现代电商必须有验证码防刷。
  • 解决:在时序图第2步“顾客→注册页面”后增加“注册页面→短信网关:sendVerifyCode(phone)”;在第3步“注册页面→系统”前增加“顾客→注册页面:inputVerifyCode”。

4.5 类图中Administrator缺少操作日志属性,但安全审计强制要求

  • 现象:被甲方安全团队指出“管理员操作无留痕”,无法通过等保测评。
  • 原因:文档第19页Administrator类只列ID和姓名,但UC013“系统设置”涉及银行信息,必须审计。
  • 解决:为Administrator类增加last_login_time:datetime、login_ip:string属性;所有管理员方法调用前记录操作日志。

4.6 “管理员删除商品”时序图未处理关联订单

  • 现象:删除热销商品后,历史订单详情页报错“商品不存在”。
  • 原因:文档第28页时序图只到“商品管理器→商品实体:deleteGoods”,没考虑订单中商品快照。
  • 解决:删除商品时,先检查是否有未完成订单引用该商品;若有,则标记为“已下架”而非物理删除,订单页仍可显示商品快照。

4.7 活动图“用户顾客的活动图”未定义超时退出机制

  • 现象:用户登录后30分钟无操作,再点击“购买商品”仍能下单,存在安全风险。
  • 原因:文档第34页活动图从“登录”到“购买商品”是直线,没画“超时→退出”分支。
  • 解决:在登录成功后启动定时器,30分钟无操作自动登出;所有敏感操作(如支付)前校验session有效期。

4.8 类图中Goods.goods_info未限定长度,导致SQL注入风险

  • 现象:用户在商品描述中输入<script>alert(1)</script>,前端渲染时执行脚本。
  • 原因:文档第17页goods_info:String没规定最大长度,也没提XSS过滤。
  • 解决:数据库goods_info字段设VARCHAR(2000);后端入库前用html.escape()转义;前端用textContent而非innerHTML渲染。

4.9 “顾客反馈信息”用例未定义审核流程,导致垃圾信息泛滥

  • 现象:首页“用户评价”区出现大量广告帖。
  • 原因:文档表2.3.1-3只说“提交到数据库中并显示在页面中”,没提审核机制。
  • 解决:反馈信息状态增加PENDING/APPROVED/REJECTED;管理员用例UC009“编辑文本管理”扩展为“审核反馈信息”。

4.10 UML文档未提供数据库ER图,但4.2节说“数据库的逻辑设计”

  • 现象:开发写SQL时发现Customer和Order间外键关系不明确。
  • 原因:文档第43页只写“数据库的逻辑设计”,但没附ER图或字段关系表。
  • 解决:根据类图推导:Order.customerID → Customer.loginName(因UC007注册用loginName,UC008购买时用顾客登录态);建外键FOREIGN KEY (customerID) REFERENCES Customer(loginName)。

4.11 时序图“管理员添加商品标题”中Title类缺失关键属性

  • 现象:后台添加标题后,前端分类页不显示。
  • 原因:文档第20页“标题title类”只列属性名,没写is_active:boolean、sort_order:int等排序和状态字段。
  • 解决:Title类增加is_active:bool(默认True)、sort_order:int(默认0);数据库加索引INDEX ON title(is_active, sort_order)。

4.12 docx文件内嵌UML图在Windows搜索中无法匹配正文

  • 现象:用Windows资源管理器搜索“购物车模块”,搜不到这份docx。
  • 原因:UML图是图片格式(.emf/.png),文字在图内不可索引;文档正文虽有“购物车模块”,但搜索时因docx压缩和格式问题常漏检。
  • 解决:另存为PDF时勾选“保留文本可搜索性”;或用Python库python-docx提取所有段落文本,生成纯文本摘要供搜索。

5. UML图到数据库建模:用类图属性生成SQL DDL,补全文档缺失的约束与索引

文档第43页“数据库的逻辑设计”只有一句话,但类图和用例已给出足够信息生成生产级DDL。我们以Customer、Goods、Order三张核心表为例,把UML属性、用例约束、避坑经验全编译进SQL——不是简单CREATE TABLE,而是带注释的、可直接执行的建表语句。

5.1 Customer表:从UML属性到带业务约束的建表语句

文档第16页Customer类属性:loginName,email,address,zip,city,country等。结合用例UC007(注册)、UC002(修改信息),需添加唯一约束、非空、长度限制:

-- Customer表:对应UML类Customer,依据文档第16页及用例UC007/UC002 CREATE TABLE `customer` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID,文档未提但必需', `login_name` VARCHAR(50) NOT NULL COMMENT '登录名,对应UML属性loginName:String;UC007要求长度校验', `last_name` VARCHAR(50) NOT NULL COMMENT '姓名,对应UML属性lastName:String', `email` VARCHAR(100) NOT NULL COMMENT '邮箱,对应UML属性email:String;UC007要求格式校验', `address` VARCHAR(200) NOT NULL COMMENT '地址,对应UML属性address:String', `zip_code` VARCHAR(20) NOT NULL COMMENT '邮编,对应UML属性zip:String', `city` VARCHAR(50) NOT NULL COMMENT '城市,对应UML属性city:String', `country` VARCHAR(50) NOT NULL COMMENT '省份,对应UML属性country:String', `phone` VARCHAR(20) DEFAULT NULL COMMENT '联系电话,对应UML属性phone:String', `company` VARCHAR(100) DEFAULT NULL COMMENT '所在单位,对应UML属性pany:String', `register_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '注册时间,文档未提但UC007隐含', `last_login_time` DATETIME DEFAULT NULL COMMENT '最后登录时间,安全审计必需', `status` ENUM('active', 'inactive', 'locked') NOT NULL DEFAULT 'active' COMMENT '账户状态,UC010删除会员需支持', PRIMARY KEY (`id`), UNIQUE KEY `uk_login_name` (`login_name`) COMMENT 'UC007要求用户名唯一', UNIQUE KEY `uk_email` (`email`) COMMENT 'UC007隐含邮箱唯一', INDEX `idx_city_country` (`city`, `country`) COMMENT '支持按城市/省份筛选会员' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='顾客信息表,对应UML类Customer';

约束说明:uk_login_name和uk_email是UC007“用户名有重名则返回重新注册”的强制实现;status枚举支持UC010“删除会员”(实际为软删除,设status=inactive);idx_city_country索引满足“查看所在城市会员”等运营需求,文档虽未提,但模块划分中“会员管理”隐含此功能。

5.2 Goods表:补全库存、分类、状态字段,支撑时序图业务流

文档第17页Goods类只有name,catid,price,但时序图“检查库存”“添加商品”要求更多字段:

-- Goods表:对应UML类Goods,依据文档第17页及时序图“检查库存”“添加商品” CREATE TABLE `goods` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '商品ID,文档未提但必需', `name` VARCHAR(200) NOT NULL COMMENT '商品名,对应UML属性name:String', `catid` VARCHAR(100) NOT NULL COMMENT '分类ID,对应UML属性catid:String;支持多级分类如electronics.phone.iphone', `price` DECIMAL(10,2) NOT NULL COMMENT '价格,对应UML属性price:double;修正为DECIMAL防精度丢失', `stock` INT NOT NULL DEFAULT 0 COMMENT '库存,文档未提但时序图checkStock必需', `description` TEXT COMMENT '商品描述,对应UML属性goodsInfo:String;TEXT支持长文本', `image_url` VARCHAR(500) DEFAULT NULL COMMENT '图片URL,文档未提但商品展示必需', `is_on_sale` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否上架,支持UC011“删除商品”软删除', `sort_order` INT NOT NULL DEFAULT 0 COMMENT '排序序号,支持后台拖拽排序', `created_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updated_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), INDEX `idx_catid_status` (`catid`, `is_on_sale`) COMMENT '支持按分类+上架状态查询', INDEX `idx_sort_order` (`sort_order`) COMMENT '支持按排序序号查首页推荐' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品信息表,对应UML类Goods';

字段补全说明:stock是时序图“checkStock”硬需求;is_on_sale实现UC011“删除商品”软删除(设0),避免破坏历史订单;sort_order支持UC011“移动商品”;idx_catid_status索引加速“查询某分类下所有上架商品”,这是“浏览商品”用例(UC006)的核心查询。

5.3 Order表:用webID作主键?不,用复合索引保性能

文档第18页Order类有webID:String,但直接用UUID作主键会导致索引碎片。结合用例UC008“下

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询