# 数据库课设 **Repository Path**: thewalkers/database-course-design ## Basic Information - **Project Name**: 数据库课设 - **Description**: go+vue+pgsql+redis - **Primary Language**: Go - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2021-06-16 - **Last Updated**: 2025-05-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 数据库课程设计报告 姓名:李天宇 学号:2019082308 ## 题目 超市进销存管理系统 ## 代码及版本管理 [点击跳转](https://gitee.com/thewalkers/database-course-design) ## 题目要求 本项目学生需要通过此项目完成项目数据库设计,信息系统开发等。 系统介绍:系统分为两个权限部分:管理员用户登录模块,普通用户登陆模块。管理员用户登录模块包括:供应商管理,员工管理,商品管理,会员管理,采购管理。普通用户登陆模块包括:个人信息,商品信息,采购信息。本项目实现以下功能: #### 供应商管理 批量录入供应商数据,手动输入供应商编号,供应商名称,供应商简称,地址,公司电话,邮件,联系人,联系人电话,备注。 查询并列出表中所有的供应商信息。 修改指定供应商的信息。 删除指定供应商数据。 #### 商品管理 批量录入商品数据,手动输入商品编号,商品名称,商品单价,供应商编号,商品简介,备注等。 查询并列出所有商品信息。 修改制定商品的商品信息。 删除指定商品数据。 #### 员工管理 批量录入员工数据,手动输入员工编号,员工姓名,员工密码,员工级别,员工电话,员工工资,备注等。 查询并列出所有员工信息。 修改指定员工信息。 删除指定员工数据。 #### 采购管理 录入采购主表数据,手动输入采购清单号,员工编号(外码),采购数量,采购总价,采购时间,备注。 录入采购明细数据,手动输入采购明细号,采购清单号(外码),商品编号(外码),采购数量,商品单价,商品总价,备注。 查询并列出所有采购主表和采购明细信息。 修改指定采购主表信息和采购明细信息。 删除指定采购主表信息和采购明细信息。 普通用户登陆模块。 查询自己的员工信息。 查询所有商品信息。 查询所有的采购信息。 ## 整体架构为 MVC 其中 `model` 为所有在数据库中存的表,在 `go` 中表示的是一个个的结构体 model 的基类为 `gorm.Model`,并让其他的 `model` 都拥有这个基类,那么所有的 `model`就拥有了创建时间,修改时间和删除时间 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0621/213359_cce97316_6513020.png "2021-06-21 21-33-40屏幕截图.png") 接下来展示剩下的所有 `model` 商品类 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0621/213746_c2fce3b0_6513020.png "2021-06-21 21-35-45屏幕截图.png") 菜单类 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0621/213823_9fb51fc8_6513020.png "2021-06-21 21-36-02屏幕截图.png") 员工类 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0621/213936_2456db1a_6513020.png "2021-06-21 21-37-29屏幕截图.png") 供应商类 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0621/213959_a6eeb68c_6513020.png "2021-06-21 21-37-04屏幕截图.png") 采购主表类 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0621/214036_233a9006_6513020.png "2021-06-21 21-36-49屏幕截图.png") 采购明细 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0621/214111_fc264202_6513020.png "2021-06-21 21-36-34屏幕截图.png") 其中 `model` 中还加入了这些 `model` 与数据库进行增删改查的操作。 接下来就是 `Controller` 了 Controller 主要是这些 `model` 和前端进行一定的交互,相互传递 `JSON` 数据 最后就是 `view` 视图层,采用的是 `Vue` 前端主要进行和用户之间进行一定的交互,这一部分包括了对数据进行的校验,本人在写整个项目,后端并没有进行数据校验,后端只对系统本身的异常和数据库的异常进行处理,数据校验全部交给了前端,如果数据校验合格了,那么插入数据库中的数据也没有问题 数据校验的一些代码 ``` editFormRules: { workerid: [ { required: true, message: '请输入员工编号', trigger: 'blur' }, { min: 3, max: 10, message: '员工编号的长度在3~10个字符之间', trigger: 'blur' } ], workername: [ { required: true, message: '请输入员工姓名', trigger: 'blur' }, { min: 3, max: 10, message: '员工姓名的长度在3~10个字符之间', trigger: 'blur' } ], workerpassword: [ { required: true, message: '请输入员工密码', trigger: 'blur' }, { min: 6, max: 15, message: '员工密码的长度在6~15个字符之间', trigger: 'blur' } ], workerlevel: [ { required: true, message: '请输入员工级别', trigger: 'blur' }, { min: 1, max: 3, message: '员工级别的长度在1-3个字符之间', trigger: 'blur' } ], workerphone: [ { required: true, message: '请输入员工电话', trigger: 'blur' }, { min: 11, max: 11, message: '员工密码必须为11位', trigger: 'blur' }, { validator: checkPhone, trigger: 'blur' } ], workersalary: [ { required: true, message: '请输入员工工资', trigger: 'blur' }, { min: 4, max: 11, message: '员工工资的长度在4-10个字符之间', trigger: 'blur' } ], workerothers: [ { required: true, message: '请输入员工工资', trigger: 'blur' } ] } ``` ``` var checkPhone = (rule, value, cb) => { const regMobile = /^(0|86|17951)?(13[0-9]|15[0123456789]|17[678]|18[0-9]|14[57]|)[0-9]{8}$/ if (regMobile.test(value)) { return cb() } cb(new Error('请输入合法的手机号')) } ``` ## 数据库设置E-R图 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0621/214938_ec6912a3_6513020.png "E-R图.png") 以下为创建的员工表,可以看到索引什么的,`gorm` 都给建好了 由于 `gorm` 会自动完成建表和建立索引的操作,只要在创建结构体的时候给每个属性打上标记就可以了,这样就完成表的建立 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0621/215315_76f6d5c7_6513020.png "2021-06-21 数据库表单.png") 剩下的就是设计触发器了,本人其实更想通过在 `go`语言后端的部分完成和触发器一样的效果,但是课程需要还是设计了触发器,自己也百度百科了一下,其实触发器是很难进行维护的,比如本人写个触发器,如果触发器代码错了,还要去找哪个触发器的问题,然后去删除触发器,然后在去重新去设计,然后再去提交,但是如果去改后端代码就方便多了 **删除采购主表的触发器** ``` CREATE OR REPLACE FUNCTION "public"."delete_purchase_master_func"() RETURNS "pg_catalog"."trigger" AS $BODY$ BEGIN IF NEW.is_del = TRUE THEN UPDATE purchase_details SET is_del = TRUE WHERE purchase_detail_master_id = OLD.master_id; END IF; RETURN NEW; END; $BODY$ LANGUAGE plpgsql; CREATE TRIGGER "delete_purchase_master_trigger" AFTER UPDATE of "is_del" ON "purchase_master_tables" FOR EACH ROW EXECUTE PROCEDURE "public"."delete_purchase_master_func"(); ``` **更新商品的触发器** ``` CREATE OR REPLACE FUNCTION "public"."update_goods_func"() RETURNS "pg_catalog"."trigger" AS $BODY$ BEGIN UPDATE purchase_details SET purchase_detail_goods_id = NEW.goods_id, purchase_detail_goods_price = NEW.goods_price WHERE purchase_detail_goods_id = OLD.goods_id; RETURN NEW; END; $BODY$ LANGUAGE plpgsql; CREATE TRIGGER "update_goods_trigger" AFTER UPDATE ON "goods" FOR EACH ROW EXECUTE PROCEDURE "public"."update_goods_func"(); ``` **更新员工的触发器** ``` CREATE OR REPLACE FUNCTION "public"."update_worker_func"() RETURNS "pg_catalog"."trigger" AS $BODY$ BEGIN UPDATE purchase_master_tables SET worker_id = NEW.worker_id WHERE worker_id = OLD.worker_id; RETURN NEW; END; $BODY$ LANGUAGE plpgsql; CREATE TRIGGER "delete_workers_trigger" AFTER UPDATE ON "workers" FOR EACH ROW EXECUTE PROCEDURE "public"."update_worker_func"(); ``` **更新供应商的触发器** ``` CREATE OR REPLACE FUNCTION "public"."update_supplier_func"() RETURNS "pg_catalog"."trigger" AS $BODY$ BEGIN UPDATE goods SET goods_supplier_id = NEW.supplier_id WHERE goods_supplier_id = OLD.supplier_id; RETURN NEW; END; $BODY$ LANGUAGE plpgsql; CREATE TRIGGER "update_supplier_trigger" AFTER UPDATE OF "supplier_id" ON "suppliers" FOR EACH ROW EXECUTE PROCEDURE "public"."update_supplier_func"(); ``` ## 关于 redis 本人也是刚开始接触这个东西,它是类似于 `cache` 的一个进行缓冲的东西,本人目前还是设计不好这个东西,只是在查询操作的时候用到了一下`redis` 就像是 `cache` 和 主存的关系类似,如果能从 `cache` 中找到的化,那么就直接从 `redis` 中直接获取,如果 `redis` 中没有的话,再去从数据库中去找,然后并在 redis 中备份一下。 ## 对于权限管理 本人是将后端发送的数据存到浏览器的 `SessionStorage` 中,进而来判断是管理员,还是普通员工,下图就展现了,不是管理员,则有一定的权限无法进行 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0621/221159_4175bf4d_6513020.png "2021-06-21 设权限.png") ## 一些截图 **登录界面** ![输入图片说明](https://images.gitee.com/uploads/images/2021/0621/221316_4eb68814_6513020.png "2021-06-17 vue.png") **修改信息** **![输入图片说明](https://images.gitee.com/uploads/images/2021/0621/221428_9b879789_6513020.png "2021-06-19 16-55-54屏幕截图.png") **删除信息** ![输入图片说明](https://images.gitee.com/uploads/images/2021/0621/221700_a0297ba7_6513020.png "2021-06-19 20-11-54屏幕截图.png") **显示整体数据** ![输入图片说明](https://images.gitee.com/uploads/images/2021/0621/221749_4ebb034a_6513020.png "2021-06-21 22-16-12屏幕截图.png") **权限展示** ![输入图片说明](https://images.gitee.com/uploads/images/2021/0621/221816_c8bab2d1_6513020.png "2021-06-21 22-16-19屏幕截图.png") **个人信息显示** ![输入图片说明](https://images.gitee.com/uploads/images/2021/0621/221840_e85e4c30_6513020.png "2021-06-21 22-16-25屏幕截图.png") ## 关于测试 本人只是通过 `python` 的 `faker` 去造数据,然后手动的去测增删改查,应该是没有问题的 `python` 代码 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0622/095248_3998186a_6513020.png "2021-06-22 09-52-07屏幕截图.png") `造出数据` ![输入图片说明](https://images.gitee.com/uploads/images/2021/0622/095316_5d8e9606_6513020.png "2021-06-22 09-52-20屏幕截图.png") 如果还存在 `bug`,那我再去改 `bug`,重所周知,`bug`永远存在 ## 总结 这是本人第一次写前后端分离的项目,其中 `go语言` 有一定基础,能看懂代码,但是 `Vue`,`postgres`,`redis` 真的是一点基础都没有,只是之前听过,一个人前后端全去完成还是很难的,比如本人去写前端的时候就是照着视频里面去一步一步去做的,整个项目做下来业务是完成了,但是总是感觉漏洞百出,并没有做到很好,我想这也是学艺不精的缘故。以后会学的更精细化一点,让项目更完美。