进销存ERP管理系统源码全解析:Vue3+uniapp+Spring Boot实战

发布时间:2026/10/8 14:35:49
进销存ERP管理系统源码全解析:Vue3+uniapp+Spring Boot实战
简介一份完整的进销存ERP管理系统源码附带小程序端主要面向需要搭建企业进销存、仓库管理系统的开发者及中小型公司IT人员。系统基于.NET与SQL Server开发覆盖电商管理微信、小程序、公众号订单以及轮播图、分类导航等参数设置、销售管理、采购管理、生产管理等核心业务流程适配公众号和小程序对接场景。软件包共7267个文件、46.71MB大小文件类型涵盖前后台页面、交互脚本与图片素材既有大量gif/png图片、js/css前端脚本也有cs后端代码、aspx/ashx动态页面、HTML文件以及小程序相关的wxml、wxss、json配置目录齐全方便对照学习整个ERP项目的前后端结构和小程序联调方式。目前已有9663人学习下载源码已在多家企业正常使用成熟稳定适合二次开发或直接用于了解ERP系统的完整实现思路。1. 进销存ERP管理系统源码从Excel账本到系统化管货只差一个完整工程很多做商贸、仓储的小团队进销存还硬扛在Excel里采购记一张表销售另记一张月底盘点时库存对不上账翻三小时发现是入库单重复录了一行。这套源码解决的就是这个区间的问题——管理后台覆盖采购、销售、库存、财务的全流程单据小程序端给仓管、业务员做移动开单、盘点、查库存两端共用同一套数据库和接口。适合两类人一是要交付项目给客户的开发者二是有Java/Vue3基础、想基于成熟工程改自己业务流程的从业者。把Excel里的手工逻辑换成这套单据流乱账问题能消掉大半。2. 技术栈拆解Vue3后台管理系统 uniapp小程序两端边界怎么划2.1 后台管理端为什么是Vue3 Element Plus而不是JSP页面拆这套源码时后台管理端选型是 Vue3 Vite Element Plus配合 Pinia 管状态、Vue Router 管路由。这个组合在进销存场景里非常合适因为进销存页面高度模板化商品列表是“表格 搜索表单 分页”单据录入是“主表信息 明细表格行内编辑”报表是“筛选项 汇总表格”。Element Plus 的表格、弹窗、级联选择器、日期范围组件都是现成的不用自己造轮子。相比之下老式 JSP jQuery 方案在单据明细行动态增删、联动计算单价×数量金额时要写大量 DOM 操作维护成本很高。Vue3 的响应式数据绑定让明细行计算变成纯前端声明式逻辑。管理后台我拆出来看目录结构是 views 按模块分文件夹purchase、sale、stock、reportapi 目录统一放接口封装这套结构适合团队协作也适合二次开发时快速定位。// api/request.js — 管理后台统一的 axios 实例封装 import axios from axios import { ElMessage } from element-plus const service axios.create({ baseURL: /api, timeout: 10000 }) // 请求拦截从 localStorage 取 token塞进请求头 service.interceptors.request.use(config { const token localStorage.getItem(erp_token) if (token) { config.headers[Authorization] Bearer token } return config }) // 响应拦截HTTP 200 但业务码非 0 时统一报错 service.interceptors.response.use(res { const data res.data if (data.code ! 0) { ElMessage.error(data.msg || 请求失败) return Promise.reject(new Error(data.msg)) } return data }) export default service这段封装解决两个问题一是所有请求自动带鉴权头后端 JWT 过滤器只需要认 Authorization 字段二是业务异常统一弹提示各页面不用重复写 catch。注意 baseURL 配的是/api而不是完整地址这是为了让 Vite 代理在本地开发时把请求转发到后端 8080 端口生产环境再用 Nginx 反向代理后面第 4 章会具体说。2.2 小程序端uniapp打包微信小程序的登录与扫码场景小程序端用了 uniappVue3 语法写一套代码编译到微信小程序。选它的理由很实际进销存移动端页面不复杂主要是列表、表单、扫码、统计卡片uniapp 的uni.request、uni.scanCode封装了多端差异后续如果想出支付宝小程序或 H5同一套代码还能复用。微信小程序登录获取手机号是移动端开单的高频入口业务员不用手输账号微信授权后直接绑定员工身份。template button open-typegetPhoneNumber getphonenumberhandlePhone 微信一键登录 /button /template script setup import { loginByPhone } from /api/auth async function handlePhone(e) { // 用户拒绝授权时 e.detail 为空先做拦截再走后续逻辑 if (!e.detail || !e.detail.code) { uni.showToast({ title: 需要授权手机号才能登录, icon: none }) return } // e.detail.code 是动态令牌不能直接拿手机号交给后端解密 const res await loginByPhone({ code: e.detail.code }) uni.setStorageSync(token, res.data.token) uni.reLaunch({ url: /pages/index/index }) } /script这里有个关键点e.detail.code是微信返回的临时凭证后端要用code2Session接口配合小程序 AppSecret 才能解密出手机号。真机调试时如果后端直接信任前端传来的手机号字段等于把登录接口暴露给任何人伪造身份。这套源码里后端做了 code 换手机号的校验改造时千万别把这一步删掉。2.3 两端业务边界后台管配置小程序管作业拆解这套工程时最值得借鉴的是两端功能划分。管理后台承担的是“配置 管理 报表”类功能商品档案、供应商/客户资料、价格策略、采购订单审核、应收应付核销、经营报表。小程序承担的是“现场作业”类功能仓管员扫码入库、出库复核、库存盘点、业务员查库存、开销售单。这样划分的理由是角色不同——坐在办公室的财务和管理员需要大屏看数据在仓库、门店的人只需要高频的录入和查询移动端页面做重了反而影响效率。仓储管理场景里扫码是关键动作。仓管员拿着手机扫商品条码uni.scanCode拿到码值后调商品查询接口带出商品名、规格、当前库存再输入数量提交。这个链路比在 PC 上搜索商品快得多也是这套源码相比纯网页 ERP 的一个明显优势。2.4 功能模块清单与角色权限模块管理后台功能小程序功能备注系统管理用户、角色、菜单权限、操作日志个人资料、密码修改权限粒度控制到按钮基础资料商品、供应商、客户、仓库、结算账户商品查询商品支持条码、多单位采购管理采购订单、入库单、退货单、应付台账采购收货扫码录入入库后自动生成应付销售管理销售订单、出库单、退货单、应收台账开单、查价、查库存出库后自动生成应收库存管理库存查询、调拨、盘点、库存流水扫码盘点、库存预警流水表是全模块数据核心财务报表销售毛利、采购汇总、应收应付账龄今日销售额卡片报表只读不带单据操作角色权限我拆的时候注意到后端用 RBAC 模型菜单表、角色表、用户角色关联表三张基础表控制粒度可以到按钮级别。比如“采购入库单审核”是一个按钮权限点普通仓管没有这个权限只有采购主管角色才配。二次开发时新加的菜单要在菜单表里注册不然路由能访问但按钮权限校验会挡住操作。3. 核心表设计库存流水、单据头行进销存不乱账的底层逻辑3.1 用流水表反算库存而不是直接改当前库存进销存系统最容易翻车的地方是库存表设计。很多新手把库存设计成base_goods表上的一个stock字段每次出入库直接UPDATE base_goods SET stock stock 数量。单机用没问题一旦多人同时操作事务隔离级别稍低就会覆盖更新库存直接变成负数或凭空多出来。这套源码的做法是建一张stock_flow库存流水表每一次入库、出库、盘点、调拨都写一条流水当前库存由流水聚合算出。CREATE TABLE stock_flow ( id BIGINT UNSIGNED AUTO_INCREMENT COMMENT 流水ID, goods_id BIGINT NOT NULL COMMENT 商品ID, warehouse_id BIGINT NOT NULL COMMENT 仓库ID, flow_type TINYINT NOT NULL COMMENT 1采购入库 2销售出库 3盘点盈亏 4调拨出 5调拨入, change_qty DECIMAL(18,3) NOT NULL COMMENT 变动数量入库为正、出库为负, before_qty DECIMAL(18,3) NOT NULL DEFAULT 0 COMMENT 变动前结存数量, after_qty DECIMAL(18,3) NOT NULL DEFAULT 0 COMMENT 变动后结存数量, biz_order_no VARCHAR(32) NOT NULL COMMENT 来源单据号如PO20240101001, biz_type TINYINT NOT NULL COMMENT 来源单据类型 1采购 2销售 3盘点 4调拨, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 流水时间, create_by BIGINT NOT NULL COMMENT 操作人ID, PRIMARY KEY (id), KEY idx_goods_wh (warehouse_id, goods_id, create_time), KEY idx_biz_order (biz_order_no) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT库存流水表;字段设计上有两个细节值得抄作业。一是change_qty用正负号区分方向入库正数、出库负数聚合时直接SUM(change_qty)就是库存不用在查询条件里写flow_type 1之类。二是冗余了before_qty和after_qty虽然能用流水反推但冗余这两个字段能让对账和回溯快很多——查某笔单据变动前后的库存不用重算全表。biz_order_no一定要加索引因为按单据查流水是天级高频操作。3.2 采购单和销售单为什么必须拆成主表加明细表进销存的单据采购订单、销售订单、入库单、出库单统一用主表加明细表的结构。主表存单据头单号、往来单位、仓库、总金额、状态、制单人、审核时间。明细表存每一行商品商品ID、数量、单价、税率、行金额。不能合并成一张表原因很直观一张采购单可能带 5 行、10 行甚至 50 行商品如果每行都复制一遍供应商、仓库、制单人数据冗余严重而且“整单审核”“整单作废”这种状态也不知道该挂在哪一行。CREATE TABLE purchase_order ( id BIGINT UNSIGNED AUTO_INCREMENT COMMENT 主键, order_no VARCHAR(32) NOT NULL COMMENT 采购单号业务唯一, supplier_id BIGINT NOT NULL COMMENT 供应商ID, warehouse_id BIGINT NOT NULL COMMENT 默认入库仓库, total_amount DECIMAL(18,2) NOT NULL COMMENT 含税总金额, status TINYINT NOT NULL DEFAULT 0 COMMENT 0草稿 1已审核 2部分入库 3已完成 4已作废, operator_id BIGINT NOT NULL COMMENT 制单人, audit_time DATETIME DEFAULT NULL COMMENT 审核时间, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_order_no (order_no) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT采购订单主表; CREATE TABLE purchase_order_item ( id BIGINT UNSIGNED AUTO_INCREMENT COMMENT 主键, order_id BIGINT NOT NULL COMMENT 关联采购订单主表ID, goods_id BIGINT NOT NULL COMMENT 商品ID, qty DECIMAL(18,3) NOT NULL COMMENT 数量, price DECIMAL(18,4) NOT NULL COMMENT 不含税单价, tax_rate DECIMAL(5,2) NOT NULL DEFAULT 0 COMMENT 税率百分比, amount DECIMAL(18,2) NOT NULL COMMENT 行金额含税, PRIMARY KEY (id), KEY idx_order_id (order_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT采购订单明细表;明细表用order_id关联主表不要在明细表里冗余order_no作为外键。单号是业务编号可能被修改比如作废后重新编号一旦改号要同步改所有明细关联主键id就没有这个问题。单据状态机是进销存的业务核心采购单从“草稿”到“已审核”审核后生成入库单入库单部分入库、全部入库后回写主表状态为“已完成”这个流转逻辑在 Service 层原子性地完成。3.3 金额、数量、状态的字段类型选择Decimal 与字典的细节进销存金额计算的精度问题是财务对账时最大的黑匣子。Java 后端如果用float或double存金额0.1 0.2 会得到 0.30000000000000004累加多行后差出好几分钱。这个源码里所有金额字段统一DECIMAL(18,2)数量字段统一DECIMAL(18,3)——数量允许三位小数是因为很多商品按重量公斤或长度米计价而金额最多精确到分就够了。字段类型用途精度选择原因金额单价、行金额、总金额、应收应付DECIMAL(18,2)金额只到分高了浪费存储数量采购/销售/库存数量DECIMAL(18,3)支持小数计量单位运费、长度类商品税率增值税率DECIMAL(5,2)13%、9%、6%保留两位足够单号单据编号VARCHAR(32)前缀日期序号不能用数字类型状态单据状态TINYINT配合字典表翻译不用字符串存单价我建议保留四位小数DECIMAL(18,4)。这在真实业务里很常见批发客户谈的是“不含税价”开票时单价会随税率反推单价保留四位能避免反向计算时产生循环小数误差。金额计算统一在后端用BigDecimal完成前端传过来的单价、数量只作展示和计算参考后端以自己算出的金额为准。3.4 索引设计批发零售查询慢先看这三条索引进销存系统的查询压力集中在几个固定模式按单号查单据、按商品查库存流水、按日期范围查报表。索引没建好数据量到几十万条后任何单据查询都会拖垮接口。拆这套源码时关键索引就是三组单据主表的order_no唯一索引库存流水表的(warehouse_id, goods_id, create_time)复合索引以及明细表的order_id普通索引。-- 库存流水表复合索引按仓库商品维度查区间流水 ALTER TABLE stock_flow ADD INDEX idx_wh_goods_time (warehouse_id, goods_id, create_time); -- 商品表条码索引小程序扫码查询走这里 ALTER TABLE base_goods ADD UNIQUE INDEX uk_barcode (barcode); -- 设置唯一索引防止重复提交生成同号单据 ALTER TABLE purchase_order ADD UNIQUE INDEX uk_order_no (order_no);复合索引的字段顺序不能随意调最左前缀原则要求查询条件里必须带warehouse_id才能用上这个索引。小程序扫码查商品走barcode唯一索引注意如果商品可能有多单位条码就不能加唯一索引改成普通索引然后取第一条。查询慢的时候先用EXPLAIN SELECT ...看key字段有没有命中索引type是all就是全表扫描优先调整索引而不是优化 SQL。4. 从源码到跑通环境配置、数据库初始化、小程序联调的完整步骤4.1 后端启动改配置文件、执行初始化 SQL后端工程拿到的第一步是改数据源配置。默认连接的是本机 MySQL如果你在本机装好 MySQL 8.0建一个空库执行项目sql/目录下的初始化脚本表结构和基础数据管理员账号、菜单、字典就都有了。初始化脚本是按顺序执行的先建表再灌基础数据直接全量跑一遍即可。server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/erp_demo?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: your_password driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: mapper-locations: classpath*:mapper/**/*.xml configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImplserverTimezoneAsia/Shanghai必须显式指定否则 MySQL 驱动和本地时区不一致插入的时间会差 8 小时前端看到的单据时间全是错的。map-underscore-to-camel-case开启后数据库的order_no字段能自动映射到 Java 的orderNo属性。密码改成你自己的数据库密码后在工程根目录执行 Maven 打包mvn clean package -DskipTests然后跑java -jar target/erp-server.jar看到启动成功的日志后端就算起来了。4.2 管理后台启动npm install 与 Vite 代理管理后台是标准的 Vue3 工程依赖安装、本地开发、打包三步走。Node 版本建议 18 以上老版本 Node 跑 Vite 会报错或者热更新极慢。# 进入前端工程目录 cd erp-admin # 安装依赖第一次会比较慢可以换国内镜像源 npm install # 本地开发启动默认端口 5173 npm run dev # 生产打包产物在 dist/ 目录 npm run build本地开发时前端跑 5173 端口后端跑 8080 端口跨域问题靠 Vite 代理解决。vite.config.js里把/api开头的请求转发到http://localhost:8080这样前端代码里的axios请求不需要写完整地址生产部署时也只需要改 Nginx 的转发规则前端代码不用动。// vite.config.js import { defineConfig } from vite import vue from vitejs/plugin-vue export default defineConfig({ plugins: [vue()], server: { port: 5173, proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } })changeOrigin: true很关键它会把请求头里的Host改成目标地址避免后端端口校验类逻辑误杀请求。代理只对开发环境生效生产环境一定要在 Nginx 里配置对应规则这是后端接口在线上访问不到的常见原因之一。4.3 小程序端联调微信开发者工具导入与域名校验小程序工程在微信开发者工具里直接“导入项目”选择erp-miniapp目录AppID 可以先用自己的测试号。uniapp 工程编译到微信小程序后manifest.json里的配置决定了小程序的基础行为——最常踩坑的是域名校验开发阶段默认开启校验真机预览时连不上局域网后端。{ mp-weixin: { appid: 你的小程序AppID, setting: { urlCheck: false }, usingComponents: true } }urlCheck: false表示小程序前端开发者工具不校验请求域名合法性开发期可以请求http://localhost:8080或局域网 IP。但要清楚这个开关只在开发者工具和预览模式有效真机体验版如果关了调试模式微信仍然强制要求请求地址是https且已在小程序后台配置到request合法域名。我每次联调都会在微信开发者工具里打开“不校验合法域名、web-view业务域名、TLS 版本以及 HTTPS 证书”这个选项同时在详情里关掉合法域名校验两头都放开省得玄学问题干扰定位。小程序端登录接口在api/auth.js里首次登录会自动调wx.login获取code和手机号授权码一起发给后端。联调时可以在开发者工具 Network 面板看请求是否到达后端如果请求能到但报 401多半是后端 JWT 密钥配置和后端不一致检查application.yml里的jwt.secret。4.4 全链路验证从登录到库存查询的接口闭环环境都跑起来后按以下链路验证一遍确认整条链路是通的步骤操作预期结果1管理后台登录 admin / admin123跳转首页右上角显示用户名2基础资料新增商品“测试可乐”填条码、零售价列表出现该商品状态为启用3用仓管账号登录小程序扫码或搜索商品能查到“测试可乐”展示库存 04管理后台做一张采购入库单入库 10 件审核后商品库存变为 105小程序重新进库存查询页下拉刷新库存展示 10与后台一致这一步把“前端 → 接口 → 数据库 → 小程序”整条链路串起来了。如果第 4 步入库后第 5 步没变优先查后端日志有没有报错再确认stock_flow表里有没有新流水——没有流水就是入库单没提交成功有流水但小程序没刷新就是缓存问题两个方向排查路径完全不一样。5. 上线避坑五个真实翻车点与排查记录进销存系统的坑不在功能数量而在数据一致性。下面五个问题是我在拆和用这类系统时实打实遇到过的每条按“现象 → 原因 → 解决”写清楚你照着排查能少走不少弯路。5.1 库存变负数并发扣减现场还原现象两个仓管同时给同一款商品出库库存明明只剩 5 件两人各出 3 件结果库存变成 -1系统没拦住。原因出库逻辑写成了“先 SELECT 库存判断够不够再 UPDATE 扣减”。两个请求同时通过 SELECT 查到库存 5都认为够先后执行 UPDATE最后一次扣完变成 -1。事务隔离解决不了这个问题因为 SELECT 在不加锁的情况下读到的都是 5。解决把判断和扣减合并成一条原子 SQL或者用乐观锁。扣减时带条件WHERE stock #{qty}影响行数为 0 说明库存不足直接抛业务异常。UPDATE base_goods SET stock stock - #{qty} WHERE id #{goodsId} AND stock #{qty}如果你的库存表是流水聚合反算的那就在流水表插入时加唯一约束(biz_order_no, goods_id)同一单据同一商品只能入一条流水从源头堵住双写。5.2 金额对不上浮点数和前端提交里的坑现象一张采购单 3 行明细行金额分别是 10.15、20.25、30.35前端合计算出 60.75后端却算出 60.74两边差一分钱对不上。原因浏览器 JavaScript 的浮点运算是 IEEE 754 双精度0.15 0.25 不是整数精确值前端累加时已经产生了误差。更糟的是有些前端代码把算好的合计金额直接提交给后端后端也信了最终入账金额就是错的。解决前端明细行金额只做展示不做存储依据。后端收到单价和数量后用BigDecimal重新计算行金额和总金额覆盖前端传值。数据库金额字段一律DECIMAL(18,2)Java 实体用BigDecimal类型禁止用Double。5.3 单据重复提交双击一下多出一张入库单现象用户在管理后台点“保存入库单”页面卡了 2 秒心急又点了一下结果列表里出现两张单号一模一样的入库单库存加了两次。原因前端按钮没有做 loading 防连点后端也没有幂等校验。两个请求几乎同时到达第一张单还没写完第二张单的“查重”也通过了。解决两条路都要堵。前端保存按钮点击后立即置灰用loading状态锁住后端在purchase_order表建order_no唯一索引重复插入时数据库直接报Duplicate entryService 层捕获后返回友好提示。单据号生成规则建议用日期 序号序号从 Redis 或数据库序列取不要用时间戳否则并发下必然重复。5.4 开发者工具正常、真机连不上域名白名单与 HTTPS现象小程序在开发者工具里请求后端一切正常点“预览”用手机扫码打开后所有接口都报request:fail页面白屏。原因开发者工具默认勾了“不校验合法域名”所以http://192.168.x.x:8080这种内网地址也能通。真机上微信对网络请求有硬校验request合法域名必须在小程序后台配置且要求 HTTPS、已备案内网 IP 根本不在白名单里。解决开发期联调用真机在开发者工具里打开“真机调试”模式同时勾选不校验合法域名真机调试下可以访问局域网地址。生产环境必须把后端接口挂到已备案的 HTTPS 域名下在小程序后台“开发管理 → 服务器域名”里配置request合法域名然后开发者工具的urlCheck重新打开。排这套问题时最容易陷入玄学其实就两条域名配置没加、HTTPS 证书没配好。5.5 接口全部超时数据库连接池耗尽导致的 ERP 连接异常现象某个周一早上后台所有单据接口都转圈几分钟后报“系统繁忙”前端提示 ERP 系统连接异常重启后端服务后恢复但过几小时又复发。原因连接池被打满。周末积压了一批库存报表导出任务有同事导了一个超大 Excel慢查询占用了几十个连接不释放新请求拿不到连接全部排队超时。MySQL 的最大连接数也到了上限服务看起来像挂了实际是资源被占死。解决给连接池配合理的上限和探活语句同时控制报表导出的数据量。spring: datasource: hikari: maximum-pool-size: 20 minimum-idle: 5 connection-timeout: 30000 validation-timeout: 5000maximum-pool-size不要盲目调大数据库连接数是有限资源单实例 20 足够撑住几十人的内部系统。导出 Excel 的接口强制分批查询每批查 500 条写一次 Sheet避免一条 SQL 把全表数据拉进内存。排查时看 HikariCP 的活跃连接数和 MySQL 的SHOW PROCESSLIST卡住的 SQL 一眼就能看出来。6. 进阶验证用一条库存预警SQL校验流水顺带做低库存提醒库存预警是进销存系统的高频需求商品设置了最低库存和最高库存低于最低要采购补货高于最高可能滞销占资金。小程序首页的“库存预警”卡片一般就调一个统计接口。SELECT g.id, g.goods_name, g.unit, g.min_stock, g.max_stock, IFNULL(SUM(sf.change_qty), 0) AS real_stock FROM base_goods g LEFT JOIN stock_flow sf ON sf.goods_id g.id WHERE g.deleted 0 GROUP BY g.id, g.goods_name, g.unit, g.min_stock, g.max_stock HAVING real_stock g.min_stock OR real_stock g.max_stock ORDER BY real_stock ASC;这条 SQL 除了做预警还有一个隐藏价值验证库存数据的正确性。real_stock是从流水表聚合出来的理论库存你把它和管理后台维护的“当前库存”字段对比两边不一致就说明某个单据漏写了流水或者流水重复写了。这个对账习惯救过我很多次——库存模块改造后我以为逻辑没问题一对比发现盘盈亏单写流水时方向搞反了几百条数据改回来差点没加班到天亮。我把这个查询封装成后端接口/api/stock/warning/list小程序端在首页展示预警数量角标点击跳转预警列表。如果只查“当前库存字段”而不是聚合流水就会漏掉那些流水断链的数据预警越做越不准。从那以后我每次交付进销存源码工程前都强制走一遍这个对账 SQL先把自己后端写漏的流水揪出来再谈功能。整套源码Spring Boot 后端 Vue3 管理后台 uniapp 小程序都能直接拿来跑先按第 4 章的步骤把环境拉起来再改业务流程。希望帮到你。本文还有配套的精品资源点击获取