ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

SpringBoot+Vue纺织品财务系统:从表设计到事务联动的毕设实战

SpringBoot+Vue纺织品财务系统:从表设计到事务联动的毕设实战 简介这是一份基于SpringBootVueMySQL的纺织品企业财务管理系统完整毕业设计源码包面向计算机相关专业做Java毕设或课程设计的同学帮助快速搭建具备前后端分离架构的财务业务Web系统。系统内置三类角色管理员可管理财务人员、收费信息、薪资、支出、报销、员工留言财务人员可审核报销、维护收费/薪资/支出数据、查看公告员工可查询薪资与公告、提交报销和留言。整套源码覆盖SpringBoot后端、Vue前端与MySQL数据库脚本压缩包约19.2MB包含项目源码、数据库文件和说明文档无需从零开始写核心业务逻辑可直接导入开发工具配置运行。当前已有56人学习借鉴适合需要完整项目方案用于演示、二次开发或理解企业财务流程的初学者。资源结构清晰按后端、前端、数据库分层组织便于逐模块阅读可作为毕业设计答辩的参考基础。1. 纺织品企业财务管理系统为什么这种毕设题最考验“业务理解”纺织品企业财务管理系统这类题目在 java 毕业设计里属于典型的中型业务系统。它不像商城、博客那样满地都是也不像 ERP 那样大到没法收尾。它的核心难点不在增删改查而在“纺织业自身的业务规则”——坯布、纱线、色布这些原材料的价格核算方式与标准进销存完全不同货款结算往往按“米数 克重 缸号”走而不是简单的按件计数。这个选题能解决的问题很明确用 springboot 搭后端、vue 做前端、mysql 存数据把纺织品企业的应收应付、成本核算、坯布/色布出入库和财务报表串成一条线。适合的人群也很聚焦——需要完成 java 方向毕业设计的学生以及想快速理解“业务系统怎么从零落地”的初级开发者。我给你的建议是不要把它当 CRUD 项目做要当成“一个真实纺织厂财务科在用的工具”来做。这样论文有东西写答辩有底气代码也有真正的业务深度。2. 先把数据模型立住纺织品财务系统的表设计与字段边界2.1 从业务流程反推表结构而不是从框架反推很多人在 springboot vue mysql 项目里先建 user 表、role 表、menu 表然后才开始想业务表。这个顺序是错的。对纺织品企业财务系统来说先梳理业务流程才靠谱。纺织企业的核心财务链路一般是这样采购纱线/坯布 → 入库 → 投入织造/染色 → 产出色布 → 销售出库 → 收款/付款 → 月末成本核算与报表。这里面每一环都会产生财务凭证而财务凭证又依赖库存数据。我一般会按“主数据 → 业务单据 → 财务凭证 → 报表汇总”四层来设计。主数据包括客户、供应商、纱线/坯布/色布商品档案、仓库业务单据包括采购入库单、销售出库单、生产领料单、成品入库单财务凭证包括应收单、应付单、收付款单、成本调整单报表汇总则是从这些表里聚合出来的视图或统计 SQL。表的数量控制在 1216 张最合适。太多显得啰嗦太少撑不起“财务系统”的定位。不要一上来就设计 30 张表毕业设计的评审老师看重的是“你懂不懂取舍”。2.2 商品档案表怎么设计克重、门幅、缸号是纺织业的命根子纺织业的商品档案和普通商品最大的区别在于同一款面料可能因为克重、门幅、缸号不同价格完全不同。如果只建一张 product 表放 name 和 price后面算成本时会非常痛苦。我建议的字段结构是id、product_code编码、name名称、category分类棉纱/坯布/色布、specification规格描述、gram_weight克重 g/m²、width门幅 cm、unit单位米/千克/匹、default_price默认单价、warehouse_id默认仓库、status、create_time、update_time。关键点是 product_code 必须唯一而且是业务编码而不是自增 id。实际业务里纺织企业的编码规则一般是“分类字母 年月 流水号”比如 P-202501-001 代表坯布类。自增 id 只做表主键业务编码单独一个字段这样后续做 Excel 导入导出时不会乱掉。字段类型上有两个坑要提前避开。克重和门幅不要用 int用 decimal(10,2)单价用 decimal(12,2)。float 和 double 在金额计算上会有精度问题财务系统里一分钱都不能差这个后面避坑章节会展开讲。2.3 财务单据表的设计一个“主表 子表”模式吃透所有单据采购入库单、销售出库单、生产领料单虽然业务语义不同但结构完全可以统一成“主表 子表”模式。主表存单据头信息——单号、往来单位、仓库、日期、经手人、备注、状态子表存单据明细——商品、数量、单价、金额。以采购入库单为例主表字段id、purchase_no单号、supplier_id供应商 id、warehouse_id仓库 id、total_amount总金额、status状态0 草稿 / 1 已入库、operator经手人、remark、create_time。子表字段id、purchase_id主表 id、product_id、quantity、price、amount。这里有个很重要的设计决策主表的 total_amount 可以和子表明细实时算也可以冗余存储。我建议冗余存储因为后面对账、生成凭证、做报表时直接查主表就行不用每次 sum 子表。代价是每次保存单据时要在事务里同时更新主表和子表但这在 springboot 里用 Transactional 就能保证一致性没有复杂度问题。所有单据表都要保留 status 字段。纺织企业的业务节奏经常是“先记一笔月底再正式结算”所以单据需要草稿/确认/已结算多状态流转不要让数据一插入就不可变。建议的建表 SQL 片段以主数据表和采购入库单为例CREATE TABLE product ( id BIGINT PRIMARY KEY AUTO_INCREMENT, product_code VARCHAR(50) NOT NULL UNIQUE COMMENT 业务编码, name VARCHAR(100) NOT NULL COMMENT 品名, category VARCHAR(20) NOT NULL COMMENT 分类:棉纱/坯布/色布, specification VARCHAR(200) COMMENT 规格描述, gram_weight DECIMAL(10,2) DEFAULT 0 COMMENT 克重(g/m2), width DECIMAL(10,2) DEFAULT 0 COMMENT 门幅(cm), unit VARCHAR(10) DEFAULT 米, default_price DECIMAL(12,2) DEFAULT 0 COMMENT 默认单价, warehouse_id BIGINT COMMENT 默认仓库, status TINYINT DEFAULT 1, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ); CREATE TABLE purchase_order ( id BIGINT PRIMARY KEY AUTO_INCREMENT, purchase_no VARCHAR(50) NOT NULL UNIQUE, supplier_id BIGINT NOT NULL, warehouse_id BIGINT NOT NULL, total_amount DECIMAL(12,2) DEFAULT 0, status TINYINT DEFAULT 0 COMMENT 0草稿 1已入库, operator VARCHAR(50), remark VARCHAR(500), create_time DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE purchase_order_item ( id BIGINT PRIMARY KEY AUTO_INCREMENT, purchase_id BIGINT NOT NULL, product_id BIGINT NOT NULL, quantity DECIMAL(12,3) NOT NULL COMMENT 数量, price DECIMAL(12,2) NOT NULL COMMENT 单价, amount DECIMAL(12,2) NOT NULL COMMENT 金额, FOREIGN KEY (purchase_id) REFERENCES purchase_order(id) );这个 SQL 里的关键细节是 quantity 用 decimal(12,3)。纺织面料经常按“米”交易但也可能按“千克”称重保留三位小数可以兼顾两种场景。金额为什么只保留两位小数因为财务上人民币结算只精确到分明细行里显示三位小数会让后续对账产生“分以下怎么处理”的争论。字段注释一定要写全。springboot mybatis 的项目里代码生成器通常会读取表注释和字段注释来生成实体类注释写得好能省掉大量手动补充的时间。3. 用 SpringBoot 实现财务核心逻辑凭证生成与库存联动3.1 Controller-Service-Mapper 三层划分在财务系统里的具体分工springboot 项目里三层架构几乎是约定俗成的但在财务系统里每一层的职责边界要更严格否则后期就是踩坑路。Controller 层只做三件事接收参数、调用 Service、返回统一结果。不要在 Controller 里写任何业务逻辑尤其不要把库存计算写在 Controller 里很多人为了省事真的会这么干结果就是接口一多改一个逻辑要找无数个入口。Service 层承担所有业务规则单据校验、库存更新、凭证生成、金额计算。这里要注意Service 里的方法命名要按“业务动作”来不要用 save、update 这种泛化名称。比如 purchaseOrderService.confirmPurchase() 表示确认入库soundReceivableService.generateReceivableFromOrder() 表示根据订单生成应收单。答辩时老师问你的项目有哪些业务功能你直接报方法名就能讲得清清楚楚。Mapper 层只负责 SQL 和数据映射。财务系统的 Mapper 里动态 SQL 会比较多比如多条件组合查询单据、按月汇总报表这些写在注解里会很难维护建议用 XML 文件。尤其是报表类的统计 SQLxml 里写复杂 JOIN 和 GROUP BY 的体验远好过注解里拼字符串。网关和权限方面如果项目不是很大可以不需要引入 Spring Cloud Gateway 那套。用拦截器或者 Spring Security 做基于角色的接口权限控制就足够了。财务系统里最需要注意的是“越权查看”——出纳不应该看到成本核算接口的数据这个通过给接口加 PreAuthorize(hasRole(FINANCE)) 就能控制住。3.2 入库事务的写法库存、单据、凭证必须同时成功或同时失败采购入库这件事在财务系统里天然是一个事务边界。确认入库时系统要同时做三件事更新库存表的可用库存数量把采购单状态从草稿改为已入库生成一张应付凭证如果还没付款。这三步任何一步失败整个操作都要回滚。我常用的写法是直接在 Service 方法上加 Transactional 注解但要注意三个细节rollbackFor 必须指定 Exception.class默认只对运行时异常回滚如果你的代码里 catch 了异常并抛出自定义业务异常不加 rollbackFor 会导致事务不回滚事务方法里不能 try-catch 吞掉异常一旦 catch 住异常又没抛出事务拦截器感知不到失败库存更新要用悲观锁或者乐观锁不能裸 update。具体实现如下Service public class PurchaseOrderServiceImpl implements PurchaseOrderService { Autowired private PurchaseOrderMapper purchaseOrderMapper; Autowired private PurchaseOrderItemMapper purchaseOrderItemMapper; Autowired private InventoryMapper inventoryMapper; Autowired private PayableMapper payableMapper; Override Transactional(rollbackFor Exception.class) public void confirmPurchase(Long purchaseOrderId, Long operatorId) { // 1. 校验单据状态只有草稿状态才能确认入库 PurchaseOrder order purchaseOrderMapper.selectById(purchaseOrderId); if (order null || order.getStatus() ! 0) { throw new BizException(单据不存在或状态已变更禁止重复入库); } // 2. 获取明细列表逐行更新库存 ListPurchaseOrderItem items purchaseOrderItemMapper.selectByOrderId(purchaseOrderId); for (PurchaseOrderItem item : items) { int count inventoryMapper.increaseStock( order.getWarehouseId(), item.getProductId(), item.getQuantity() ); if (count 0) { throw new BizException(库存更新失败商品ID: item.getProductId()); } } // 3. 更新单据状态 order.setStatus(1); order.setOperator(String.valueOf(operatorId)); purchaseOrderMapper.updateStatus(order); // 4. 生成应付凭证金额 明细总和 BigDecimal total items.stream() .map(PurchaseOrderItem::getAmount) .reduce(BigDecimal.ZERO, BigDecimal::add); Payable payable new Payable(); payable.setSourceType(PURCHASE); payable.setSourceId(purchaseOrderId); payable.setAmount(total); payable.setStatus(0); payableMapper.insert(payable); } }这段代码里 inventoryMapper.increaseStock 是关键——它是原子 SQL 操作不是先 select 后 update。如果先查询库存再用 java 代码加好了再 update会出现并发环境下丢更新的问题。increaseStock 的 SQL 大致是 UPDATE inventory SET quantity quantity #{quantity} WHERE warehouse_id #{warehouseId} AND product_id #{productId}数据库行锁天然保证同一行库存的并发安全。confirmPurchase 方法里前三步的顺序是有讲究的先改库存再改单据状态最后生成凭证。为什么凭证放最后因为凭证金额依赖前两步的校验结果而且凭证表是财务对账的原始依据它一旦生成对应的业务单据就不允许再随意修改。3.3 报表统计 SQL按月汇总的写法与参数边界财务系统的报表模块是另一道坎。常见的需求有“月度采购汇总”“月度销售汇总”“客户欠款统计表”“成本构成分析表”。这些报表用 springboot 自带的查询接口直接返回 List 也行但更推荐在 Mapper 里写统计 SQL让数据库做完聚合应用层只负责组织展示。月度采购汇总的 SQL 大概长这样SELECT DATE_FORMAT(p.create_time, %Y-%m) AS month, COUNT(DISTINCT p.id) AS order_count, SUM(p.total_amount) AS total_amount, SUM(CASE WHEN p.status 1 THEN p.total_amount ELSE 0 END) AS confirmed_amount FROM purchase_order p WHERE p.create_time BETWEEN #{startTime} AND #{endTime} GROUP BY DATE_FORMAT(p.create_time, %Y-%m) ORDER BY month DESC;这里 BETWEEN #{startTime} AND #{endTime} 的边界要注意。如果你传的 startTime 是 2025-06-01 00:00:00endTime 是 2025-06-30 00:00:00那么 6 月 30 日当天的数据会被丢掉。习惯上我传 endTime 时会给它加到 23:59:59或者在 SQL 里用 DATE_ADD(#{endTime}, INTERVAL 1 DAY) 来避坑。还要注意 GROUP BY DATE_FORMAT(create_time, %Y-%m) 这个写法在 mysql 里没问题但如果你以后把数据库迁移到 sql server 或者 oracle函数名和格式符会变。毕业设计里用 mysql 就专注 mysql不要想着写一套 SQL 到处都能跑那不现实。报表接口的另一个坑是空数据问题某个月没有任何采购记录时GROUP BY 的查询会直接不返回这一行前端图表上会出现断档。解决方式是在 java 层补全月份遍历 1 到 12 月查不到就补 0。4. 前端 Vue 页面怎么搭从路由权限到报表可视化4.1 用 Vue Router 组织财务模块页面路由权限按角色动态生成前端这块用 vue3 vite element-plus 是当前 java 毕设里最常见的组合。vue 部分的核心工作有三个页面框架布局、路由权限控制、业务页面实现与接口对接。页面布局上典型的结构是左侧菜单栏顶部面包屑和用户信息右侧内容区域。菜单按财务系统的业务模块分基础资料、采购管理、销售管理、库存管理、应收应付、财务报表、系统管理。vue router 的配置要和菜单栏数据来自同一份路由表避免菜单显示和实际路由不一致。路由权限这里有个关键设计不要把全部路由静态写在 router/index.js 里而是用动态路由 addRoute 的方式登录成功后根据后端返回的角色权限过滤出用户能访问的路由再动态添加。比如出纳角色就只挂载应收应付和收付款页面不挂载成本核算页面。常见做法是后端登录接口同时返回 token 和 permissions 数组前端拿到后通过 router.addRoute 注册动态路由。这个步骤比较绕很多新手容易卡住其实核心就是定义一份完整的路由表带 meta.permissions 标识登录后用用户权限过滤并注册。动态路由的核心代码结构如下// router/index.js const constantRoutes [ { path: /login, component: Login }, { path: /, redirect: /dashboard } ]; // 动态路由表每个路由都声明需要的权限码 const asyncRoutes [ { path: /purchase, component: Layout, meta: { permissions: [purchase:list] }, children: [ { path: order, component: PurchaseOrder, meta: { permissions: [purchase:order] } } ] }, { path: /finance, component: Layout, meta: { permissions: [finance:list] }, children: [ { path: payable, component: PayableList, meta: { permissions: [finance:payable] } }, { path: receivable, component: ReceivableList, meta: { permissions: [finance:receivable] } } ] } ]; // 登录后执行 function setupDynamicRoutes(permissions) { const accessibleRoutes filterRoutes(asyncRoutes, permissions); accessibleRoutes.forEach(route router.addRoute(route)); }这里 filterRoutes 要做两层过滤先过滤一级路由本身是否有权限再过滤它下面的 children 路由。如果一个一级路由的 children 全部被过滤掉了那这个一级路由也要抛弃否则前端菜单会出现一个点了没反应的父菜单。4.2 财务表单页面的防错设计金额字段和日期字段的校验财务系统的前端表单和普通的表单页面最大的区别是——不能只靠后端校验前端必须在用户输入时就挡住低级错误。数字精度问题就是典型场景用户在采购入库单里输入单价 12.345如果前端没限制小数位数传到后端后 decimal(12,2) 的字段会自动四舍五入最后账面金额和用户预期对不上。element-plus 里限制小数位数的写法是自定义校验器const validatePrice (rule, value, callback) { if (!value) return callback(new Error(请输入单价)); const priceStr String(value); if (!/^\d(\.\d{1,2})?$/.test(priceStr)) { return callback(new Error(单价最多保留两位小数)); } callback(); };日期字段也有坑。element-plus 的 date-picker 组件返回的默认值格式是 Date 对象如果你直接把它拼进查询参数传给后端后端拿到的可能是一长串时间戳。习惯做法是在表单提交前做格式化// 将 Date 对象转为 yyyy-MM-dd 字符串 function formatDate(date) { const d new Date(date); const year d.getFullYear(); const month String(d.getMonth() 1).padStart(2, 0); const day String(d.getDate()).padStart(2, 0); return ${year}-${month}-${day}; }财务页面的表格展示建议统一用 element-plus 的 el-table其中金额列一定要设置 alignright这不仅是为了好看更是财务软件的统一规范——金额右对齐方便逐位核对。除了页面组件设计外还要配置 axios 拦截器统一处理 token 过期和接口异常token 失效时前端自动跳转到登录页这个细节在答辩演示时尤其加分。vue 前端的环境配置这里要提醒一句用 vite 创建项目后要确认 node 版本 16否则依赖安装时会一直报错。axios 代理配置要写在 vite.config.js 的 server.proxy 里开发环境才能正确转发 /api 请求到 springboot 的 8080 端口。5. 避坑指南纺织品财务系统里最常见的 5 个翻车现场5.1 金额精度丢失float 让你对不上账现象采购单、销售单金额累计和报表汇总金额差几分钱怎么查都查不出原因。原因mysql 里用了 float 或 double 字段存金额。float 是近似存储0.1 0.2 在二进制里不等于 0.3。财务系统只要跑几笔单据误差就会累积。解决所有金额字段统一用 decimal(12,2)实体类里用 BigDecimal 而不是 Double。BigDecimal 运算时用 setScale(2, RoundingMode.HALF_UP) 来控制精度不要直接调用 doubleValue() 转回 double 再算。5.2 MySQL 连接把项目拖死连接池参数没有调现象本地跑没问题部署到服务器后跑一两个小时就报 Cannot create PoolConnection接口集体超时。原因springboot 默认的 HikariCP 连接池最大连接数是 10财务系统里报表查询特别多长事务占用连接时间过长连接池被耗尽。解决application.yml 里把 maximum-pool-size 调到 2050connection-timeout 设成 30000并且给报表类查询接口的 Service 方法加上 Transactional(readOnly true)让数据库知道这些查询不需要写事务可以走更快的读路径。还有一点mybatis 里如果写了多条 SQL 在一个方法里默认是不会包在同一个事务里的要配置 mybatis 的批量执行器或者手动加 Transactional否则报表数据会出现统计不一致。5.3 前端表格数据错位字段名大小写不一致现象接口返回正常但前端表格有的列有数据有的列全是空。原因springboot 的 jackson 序列化默认输出驼峰命名比如 createTime但前端如果用的是下划线风格的 json 字段或者数据库查询 resultType 没有配置 map-underscore-to-camel-case字段就映射不上。解决application.yml 里设置 mybatis.configuration.map-underscore-to-camel-case: true。同时后端返回的统一响应实体字段也保持驼峰风格前端取值时直接 data.createTime 就行不要写成 data[create_time]。凡是能统一命名风格的就不要用别名字段硬转。5.4 报表查询慢没有索引还想跑全表现象单据量不到一万条按月汇总报表要等三四秒。原因purchase_order 表按 create_time 筛选但这个字段没有索引每次查询都是全表扫描而且 ORDER BY 也会受影响。解决给 create_time 加普通索引给 purchase_order_item 的 purchase_id 加普通索引。如果统计维度是按 warehouse_id create_time可以考虑联合索引但不要过度设计报表查询能在 200ms 内返回就够了。更不要把所有字段都加索引插入时会拖慢事务提交速度。5.5 事务不生效你以为在同一个事务里其实没有现象采购入库后库存改了但应付凭证没生成而且不报错。原因最常见的情况是调用了同类内部的 this.confirmPurchase() 方法绕过 spring 的代理事务注解全部失效。还有一种情况是 Service 方法没有加 rollbackFor Exception.class业务异常被 spring 默认当成了只回滚 RuntimeException 的漏网之鱼。解决controller 调用 service 方法时走的是代理对象事务正常。但 service 内部方法互调必须自己注入自身代理或者把事务方法拆到另一个 Service 里。如果不想引入额外依赖可以用 TransactionTemplate 手动控制事务边界这样最直观Autowired private TransactionTemplate transactionTemplate; public void confirmPurchase(Long orderId) { transactionTemplate.execute(status - { // 执行业务逻辑抛出异常则自动回滚 doConfirmPurchase(orderId); return null; }); }这种写法的好处是事务边界完全由你控制不会再出现“ Transactional 不生效”的玄学问题。缺点是代码会多一层嵌套但对于毕业设计来说正确性远比优雅重要。6. 把项目跑起来部署到服务器的具体步骤与验证清单6.1 构建 springboot 后端并部署到 Linux 服务器后端打包用 maven 的 package 命令但要先确认 application.yml 里的数据库地址已经改成服务器地址不能再是 localhost。mvn clean package -DskipTests # 打包完成后在 target 目录下会生成 xxx.jar # 上传到服务器后用 nohup 方式启动 nohup java -jar textile-finance-system.jar \ --spring.profiles.activeprod \ --server.port8080 \ app.log 21 启动后第一件事不是测试接口而是看日志。springboot 项目里 -Dfile.encodingUTF-8 最好加上否则 Linux 环境默认编码可能导致中文乱码。启动成功的标志是日志里出现 Started Application in 5.2 seconds 类似字样而不是只看进程是否存活。前端 vue 项目在本地构建产出 dist 目录后可以有两种部署方式一种是把 dist 里的静态文件放到 nginx 的 html 目录下另一种是打成 jar 内置到 springboot 里统一提供静态资源。考虑到部署简单程度和毕业答辩演示的便利性我更推荐 nginx 方案配置如下server { listen 80; server_name your-domain-or-ip; root /opt/textile-finance/dist; index index.html; location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location / { try_files $uri $uri/ /index.html; } }try_files 那一行务必要有否则用户在前端路由里刷新页面时会 404。这是 vue 的 history 模式在 nginx 下的经典坑不知道的人每次都要重新走一遍登录才能回到原页面。6.2 初始化测试数据并验证核心流程系统跑起来后不要急着录正式数据。先设计一套完整的测试数据走一遍核心链路验证各环节的数据一致性。我建议按这条链路走一遍创建客户录入“绍兴XX纺织贸易有限公司”创建供应商录入“XX纱线厂”创建商品录入一条棉纱、一条坯布、一条色布克重门幅都填上做一笔采购入库单从供应商采购棉纱 1000 千克单价 25.50 元确认入库后去库存模块查看棉纱库存是否变成 1000去应付模块查看是否生成一笔 25500 元的应付单做一笔销售出库单给客户卖出棉纱 400 千克单价 32.00 元确认出库后去应收模块查看是否生成一笔 12800 元的应收单去报表模块查看月度采购汇总和月度销售汇总核对总数如果每一步都能对上说明项目的主链路是通的。这一步验证的价值在答辩时也很大你可以在演示时当着老师的面把流程走一遍比任何 PPT 都有说服力。还要强调一个验证细节在做完采购入库后连续点两次确认入库按钮看系统是否会报“单据状态已变更禁止重复入库”。这个防重复提交的逻辑既是业务真实需求也是技术考核的加分点——说明你考虑过并发问题。6.3 演示数据与真实数据分离用 mysql 脚本初始化“演示账号”答辩演示时最怕的是演示前不小心把重要数据删了或者登录的账号密码忘了。我的习惯是为毕业设计单独准备一个初始化 sql 脚本里面只放演示账号和少量示例数据保证任何时候重置数据库后系统看起来都是“内容丰富”的。脚本里建议放这几个固定账号管理员 admin / admin123财务经理 finance / finance123普通操作员 operator / operator123。密码不要加密太复杂springboot 里用 MD5 加盐或者至少用 BCrypt 加密但不要自己手写加密算法。初始化脚本里直接插入已经加密好的密文不要在代码里动态生成密码再改数据库。mysql 的初始化脚本执行方式很简单mysql -u root -p textile_finance init_data.sql执行前先备份现有数据库mysqldump 导出全库到 sql 文件这是你所有操作的后悔药。尤其是改了表结构之后发现数据对不上时没有备份就只能手动造数据那个过程真的会让人崩溃。最后说一个小习惯财务系统这种涉及金额的项目我每次改动前后端代码后都会重新走一遍“采购入库 → 应收应付 → 报表汇总”这条最小链路。不为别的只因为金额类 bug 往往不是立刻爆出来的而是几天后发现报表差几分钱。与其在答辩前夜通宵排查不如每次改动花五分钟验证一下。希望这篇笔记能帮你把这个毕业设计做出真正的业务深度不仅仅是跑通 demo——毕竟答辩老师见过的系统太多了能让他眼前一亮的永远是“你理解这个行业的实际问题”。本文还有配套的精品资源点击获取
返回列表