拓冰建站拓冰建站
首页 / 资讯中心 / 正文

网上书店管理系统课程设计:需求分析、数据库设计与Python Flask实现

简介这份《软件工程网上书店管理系统详细课程设计报告》面向高校软件工程、计算机相关专业的课程设计学习者以及需要完成类似Web数据库项目实践的学生。报告完整覆盖从引言、可行性研究、需求分析到总体设计、概要设计、详细设计、软件测试与页面效果分析的全流程可作为课程设计写作与系统开发的参考范本。资源包内含1个PDF文件约991KB内容按章节组织包含功能层次图、数据库表结构设计、用例关系示意及测试方案等关键材料。目前已有166人学习下载。读者可从中获取网上书店管理系统的需求描述、前后台功能划分、SQL Server 2005与Visual Studio 2005技术选型思路以及图书、会员、订单、购物车、评价等数据表设计细节适合对照撰写报告、梳理开发流程或查漏补缺。1. 网上书店管理系统课程设计从需求文档到可运行原型的完整路径很多软件工程课程设计最后卡住的地方不是代码写不出来而是需求文档、数据库设计、模块划分和最终演示对不上。网上书店管理系统这个题目之所以经典是因为它把软件工程的核心环节都串起来了用户注册登录、图书检索、购物车、订单管理、后台维护每个模块都能对应到需求分析、概要设计、详细设计、编码和测试。如果你正在做软件工程课程设计或者需要一份能讲清楚“为什么这么设计”的参考这个方向值得认真做一遍。它不需要复杂框架用 Java 或 Python 加 MySQL 就能跑通重点是把工程化的思路体现出来而不是堆功能。下面按实际动手顺序把需求、设计、建库、编码和排错拆开讲。2. 需求分析与用例建模先想清楚谁在什么场景下做什么2.1 从业务场景反推功能边界网上书店管理系统的需求分析最容易犯的错是功能列了一大堆但角色和场景没对齐。常见做法是先画用例图再写用例规约。角色一般分三类游客、注册会员、管理员。游客能浏览图书、搜索、查看详情会员能加购物车、下单、查看订单管理员能管理图书、分类、订单状态和用户。我一般会先列一张场景表把每个角色在什么条件下触发什么动作写清楚。比如“会员在图书详情页点击加入购物车”这个场景前置条件是已登录且库存大于零后置条件是购物车条目增加。这张表直接决定后面数据库里购物车表要不要存单价快照、要不要做库存校验。提示需求阶段不要急着想表结构先把“谁、在什么页面、点了什么、系统返回什么”写顺后面设计会省很多返工。2.2 用例规约的写法与课程设计评分点课程设计报告里用例规约是体现软件工程规范的关键。每个用例至少写清楚用例名称、参与者、前置条件、基本流程、备选流程、后置条件。以“用户下单”为例基本流程是校验登录、校验库存、生成订单、扣减库存、清空购物车备选流程包括库存不足、未登录、支付超时。很多同学只写基本流程备选流程空着答辩时被问“库存不够怎么办”就答不上来。建议至少给下单、登录、图书管理三个核心用例写完备选流程。这部分内容在报告里占分不低而且直接指导后面的异常处理代码。2.3 需求文档到设计模型的映射需求文档写完不是放着要能映射到设计模型。常见做法是用例图对应功能模块活动图对应业务流程类图对应实体和关系。比如“购物车”这个用例在类图里对应 Cart 和 CartItem 两个类在数据库里对应 cart 和 cart_item 两张表。这一步做扎实后面写详细设计时就不用重新想逻辑。我习惯在需求文档每个用例后面加一行“设计映射”注明对应的类或表评审时一眼就能看出覆盖是否完整。3. 数据库设计与建表MySQL 下五张核心表的字段与约束3.1 实体关系梳理与表结构规划网上书店管理系统的数据库设计核心实体有用户、图书、分类、购物车、订单、订单明细。常见做法是用户和图书多对多通过购物车和订单关联。分类和图书是一对多订单和订单明细是一对多。下面是一套可以直接在 MySQL 里执行的建表语句字段类型和约束都按课程设计常见要求设置。注意密码字段存哈希不要存明文金额用 decimal不要用 float。-- 用户表存注册会员和管理员 CREATE TABLE user ( user_id INT NOT NULL AUTO_INCREMENT COMMENT 用户ID, username VARCHAR(50) NOT NULL COMMENT 登录名, password_hash VARCHAR(128) NOT NULL COMMENT 密码哈希, role TINYINT NOT NULL DEFAULT 0 COMMENT 0会员 1管理员, email VARCHAR(100) DEFAULT NULL, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (user_id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户表; -- 图书表存图书基本信息和库存 CREATE TABLE book ( book_id INT NOT NULL AUTO_INCREMENT, title VARCHAR(200) NOT NULL COMMENT 书名, author VARCHAR(100) DEFAULT NULL, price DECIMAL(10,2) NOT NULL DEFAULT 0.00, stock INT NOT NULL DEFAULT 0 COMMENT 库存数量, category_id INT DEFAULT NULL, cover_url VARCHAR(255) DEFAULT NULL, description TEXT, PRIMARY KEY (book_id), KEY idx_category (category_id), KEY idx_title (title) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT图书表; -- 购物车表一个用户一条购物车记录 CREATE TABLE cart ( cart_id INT NOT NULL AUTO_INCREMENT, user_id INT NOT NULL, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (cart_id), UNIQUE KEY uk_user (user_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT购物车表; -- 购物车明细记录每本书的数量和加入时单价 CREATE TABLE cart_item ( item_id INT NOT NULL AUTO_INCREMENT, cart_id INT NOT NULL, book_id INT NOT NULL, quantity INT NOT NULL DEFAULT 1, price_snapshot DECIMAL(10,2) NOT NULL COMMENT 加入时单价, PRIMARY KEY (item_id), KEY idx_cart (cart_id), KEY idx_book (book_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT购物车明细; -- 订单表记录订单头和状态 CREATE TABLE orders ( order_id INT NOT NULL AUTO_INCREMENT, user_id INT NOT NULL, total_amount DECIMAL(10,2) NOT NULL DEFAULT 0.00, status TINYINT NOT NULL DEFAULT 0 COMMENT 0待支付 1已支付 2已发货 3已完成 4已取消, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (order_id), KEY idx_user (user_id), KEY idx_status (status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT订单表; -- 订单明细记录每笔订单买了哪些书 CREATE TABLE order_item ( detail_id INT NOT NULL AUTO_INCREMENT, order_id INT NOT NULL, book_id INT NOT NULL, quantity INT NOT NULL, price DECIMAL(10,2) NOT NULL COMMENT 下单时单价, PRIMARY KEY (detail_id), KEY idx_order (order_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT订单明细;建表时几个参数要特别注意price_snapshot和order_item.price都是价格快照防止图书调价后历史订单金额对不上stock字段在扣减时要加行锁或乐观锁版本号否则并发下单会超卖role用 tinyint 区分会员和管理员比字符串省空间也方便索引。3.2 索引与约束的取舍课程设计里索引不用建太多但几个关键查询要覆盖。图书按分类查所以category_id加索引按书名搜索title加索引订单按用户和状态查user_id和status分别加索引。外键约束在课程设计里可以加但生产环境常因性能问题去掉这里建议加上以体现完整性比如cart_item的book_id引用book.book_id。注意如果使用外键插入顺序必须先主表后从表删除时先从表后主表否则会报 1452 或 1451 错误。3.3 初始化数据与测试数据准备建完表要插测试数据否则演示时页面空白。至少准备 3 个分类、10 本图书、2 个用户一个会员一个管理员。密码哈希可以用 BCrypt 或 SHA-256 加盐课程设计里用 SHA-256 加固定盐也能过但报告里要说明生产环境应使用 BCrypt。INSERT INTO user (username, password_hash, role, email) VALUES (member01, 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8, 0, member01test.com), (admin01, 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8, 1, admin01test.com); INSERT INTO book (title, author, price, stock, category_id, description) VALUES (软件工程导论, 张海藩, 45.00, 20, 1, 经典教材), (数据库系统概论, 王珊, 52.00, 15, 1, 数据库课程常用), (Java编程思想, Bruce Eckel, 108.00, 8, 2, Java进阶);测试数据要覆盖边界库存为 0 的书、价格为零的书、已取消的订单。这样测试时才能验证异常分支。4. 核心模块编码用 Python Flask 跑通登录、购物车和下单4.1 项目结构与依赖安装后端用 Python Flask 加 SQLAlchemy前端用 Jinja2 模板适合课程设计快速出原型。项目结构按功能分目录models放实体类routes放蓝图templates放页面static放样式和脚本。pip install flask flask-sqlalchemy flask-login pymysql cryptographyflask-login管理会话pymysql连 MySQLcryptography用于密码哈希。数据库连接串写在config.py里格式为mysqlpymysql://user:passwordlocalhost:3306/bookstore?charsetutf8mb4。4.2 登录与权限校验的实现登录模块要处理三件事验证用户名密码、写入会话、根据角色跳转。下面是一个最小可用的登录路由密码校验用werkzeug.security的check_password_hash。from flask import Blueprint, request, redirect, url_for, render_template, flash from flask_login import login_user, logout_user, login_required, current_user from werkzeug.security import check_password_hash from models import User auth_bp Blueprint(auth, __name__) auth_bp.route(/login, methods[GET, POST]) def login(): if request.method POST: username request.form.get(username, ).strip() password request.form.get(password, ) user User.query.filter_by(usernameusername).first() # 用户不存在或密码错误统一提示避免暴露账号是否存在 if not user or not check_password_hash(user.password_hash, password): flash(用户名或密码错误) return render_template(login.html) login_user(user) # 管理员跳后台会员跳首页 if user.role 1: return redirect(url_for(admin.dashboard)) return redirect(url_for(shop.index)) return render_template(login.html) auth_bp.route(/logout) login_required def logout(): logout_user() return redirect(url_for(auth.login))这里的关键参数是check_password_hash的哈希算法要和注册时一致。注册时用generate_password_hash默认是 pbkdf2如果数据库里存的是 SHA-256这里就要换成对应的校验函数。课程设计里建议统一用generate_password_hash报告里写清楚算法。4.3 购物车与订单事务处理购物车加购逻辑要判断是否已存在同一本书存在则数量加一不存在则新建明细。下单时要把购物车明细转成订单明细扣减库存清空购物车这三步必须在一个事务里。from flask import Blueprint, request, jsonify from flask_login import login_required, current_user from models import db, Cart, CartItem, Book, Order, OrderItem cart_bp Blueprint(cart, __name__) cart_bp.route(/cart/add, methods[POST]) login_required def add_to_cart(): book_id request.json.get(book_id) book Book.query.get(book_id) if not book or book.stock 0: return jsonify({code: 1, msg: 库存不足}) cart Cart.query.filter_by(user_idcurrent_user.user_id).first() if not cart: cart Cart(user_idcurrent_user.user_id) db.session.add(cart) db.session.flush() item CartItem.query.filter_by(cart_idcart.cart_id, book_idbook_id).first() if item: item.quantity 1 else: item CartItem(cart_idcart.cart_id, book_idbook_id, quantity1, price_snapshotbook.price) db.session.add(item) db.session.commit() return jsonify({code: 0, msg: 已加入购物车}) cart_bp.route(/order/create, methods[POST]) login_required def create_order(): cart Cart.query.filter_by(user_idcurrent_user.user_id).first() if not cart: return jsonify({code: 1, msg: 购物车为空}) items CartItem.query.filter_by(cart_idcart.cart_id).all() if not items: return jsonify({code: 1, msg: 购物车为空}) try: order Order(user_idcurrent_user.user_id, total_amount0, status0) db.session.add(order) db.session.flush() total 0 for it in items: book Book.query.get(it.book_id) # 扣库存前再次校验防止并发超卖 if book.stock it.quantity: raise ValueError(f《{book.title}》库存不足) book.stock - it.quantity detail OrderItem(order_idorder.order_id, book_idit.book_id, quantityit.quantity, priceit.price_snapshot) db.session.add(detail) total it.price_snapshot * it.quantity order.total_amount total # 清空购物车明细 CartItem.query.filter_by(cart_idcart.cart_id).delete() db.session.commit() return jsonify({code: 0, order_id: order.order_id}) except ValueError as e: db.session.rollback() return jsonify({code: 1, msg: str(e)}) except Exception: db.session.rollback() return jsonify({code: 1, msg: 下单失败请重试})事务边界是db.session.commit()之前的所有操作任何一步抛异常都要rollback。库存扣减用book.stock - it.quantity在并发下可能超卖课程设计里可以接受但报告里要提到生产环境应使用SELECT ... FOR UPDATE或乐观锁版本号。4.4 图书检索与分页查询图书列表要支持按分类筛选、按书名模糊搜索、分页。用 SQLAlchemy 的filter和paginate实现。shop_bp.route(/books) def book_list(): page request.args.get(page, 1, typeint) keyword request.args.get(kw, ).strip() category_id request.args.get(cat, typeint) query Book.query if keyword: query query.filter(Book.title.like(f%{keyword}%)) if category_id: query query.filter_by(category_idcategory_id) pagination query.order_by(Book.book_id.desc()).paginate( pagepage, per_page10, error_outFalse) return render_template(book_list.html, paginationpagination, keywordkeyword, category_idcategory_id)per_page设 10 是课程设计演示的常见值太大页面太长太小翻页太多。error_outFalse保证页码越界时返回空列表而不是 404。5. 避坑与排查课程设计里最容易翻车的五个地方5.1 中文乱码数据库、连接串和页面三处都要设 utf8mb4现象图书标题插入后变成问号或者页面显示乱码。原因通常是数据库字符集不是 utf8mb4或者连接串没指定 charset。解决建库时用CREATE DATABASE bookstore DEFAULT CHARSET utf8mb4连接串加?charsetutf8mb4Flask 模板文件保存为 UTF-8 无 BOM。5.2 库存超卖并发下单时库存扣成负数现象两个用户同时下单同一本书库存只剩 1 本结果两个订单都成功库存变成 -1。原因查询库存和扣减库存之间没有锁。解决课程设计里可以在扣减前用SELECT ... FOR UPDATE锁行或者用UPDATE book SET stock stock - %s WHERE book_id %s AND stock %s判断影响行数。5.3 外键约束报错插入顺序和删除顺序搞反现象插入购物车明细时报Cannot add or update a child row: a foreign key constraint fails。原因cart_item.book_id引用的图书不存在或者先插了从表。解决先插主表再插从表删除时先删从表再删主表。测试数据初始化时按 user、book、cart、cart_item、orders、order_item 的顺序执行。5.4 会话丢失Flask-Login 的 secret_key 没设或改了现象登录成功后跳转又变成未登录。原因app.secret_key没设置或每次重启随机生成。解决在config.py里写死一个固定字符串比如SECRET_KEY bookstore-course-design-2024不要用os.urandom。5.5 价格精度用 float 导致订单金额出现 0.30000000000000004现象购物车总价计算出现长小数。原因Python float 和 MySQL float 都有精度问题。解决数据库用DECIMAL(10,2)Python 用decimal.Decimal或直接依赖数据库计算显示时用round(total, 2)。6. 从课程设计到可演示原型三个提升报告质量的技巧6.1 用测试用例表覆盖异常分支课程设计报告里加一张测试用例表比只贴截图更有说服力。表里至少包含正常登录、密码错误、库存不足下单、未登录加购、管理员删除图书。每条写输入、预期输出、实际输出、是否通过。下面是一个示例格式。编号测试项输入预期输出实际输出结论T01会员登录member01/123456跳转首页跳转首页通过T02密码错误member01/wrong提示用户名或密码错误提示用户名或密码错误通过T03库存不足下单库存0的书提示库存不足提示库存不足通过T04未登录加购无会话跳转登录页跳转登录页通过这张表放在测试章节答辩时直接翻到这一页比口头解释管用。6.2 用活动图说明下单流程的异常分支报告里的活动图不要只画正常流程把库存不足、未登录、支付超时三个分支画进去。用 PlantUML 或 Visio 都行关键是分支要对应到代码里的if判断。我一般会在活动图下面附一段说明指出每个分支对应的异常处理代码位置评审老师一看就知道不是抄的。6.3 部署与演示的检查清单演示前按这个清单过一遍数据库服务是否启动、连接串密码是否正确、测试数据是否插入、管理员账号能否登录、下单后库存是否减少、订单状态能否在后台修改。我自己的习惯是演示前用 Postman 或浏览器无痕模式跑一遍完整流程从注册到下单到后台发货确认没有遗漏。这个习惯帮我省过好几次答辩翻车。希望帮到你。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门