三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

Flask企业物资采购销售管理系统设计与实现

Flask企业物资采购销售管理系统设计与实现

1. 项目概述

这个基于Flask的企业物资采购销售管理系统是我去年为一家中型制造企业开发的内部管理平台。系统最核心的特点就是多角色协同——从采购员、销售经理到仓库管理员和财务人员,每个岗位都有专属的操作界面和功能权限。这种设计不是拍脑袋想出来的,而是源于实际业务中各部门"数据孤岛"的痛点:采购部门不知道库存情况盲目下单,销售团队对在途物资毫无概念随意承诺交期,仓库和财务之间对不上账更是家常便饭。

系统采用Python+Flask+MySQL技术栈,前端用Bootstrap5实现响应式布局。开发周期3个月,上线后企业采购效率提升40%,库存周转率提高25%,最让我意外的是财务对账时间从原来的每周8小时缩短到2小时。下面我就拆解这个系统的设计思路和关键技术实现。

2. 系统架构设计

2.1 角色权限模型设计

系统包含6类核心角色:

  1. 采购专员(采购订单创建、供应商管理)
  2. 销售经理(客户管理、销售订单审批)
  3. 仓库管理员(入库/出库操作、库存盘点)
  4. 财务人员(付款/收款登记、对账)
  5. 部门主管(数据看板、报表导出)
  6. 系统管理员(用户管理、基础配置)

权限控制采用RBAC(基于角色的访问控制)模型,数据库设计包含三张关键表:

class Role(db.Model): __tablename__ = 'roles' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True) permissions = db.Column(db.Integer) users = db.relationship('User', backref='role', lazy='dynamic') class Permission: VIEW = 1 CREATE = 2 EDIT = 4 DELETE = 8 ADMIN = 16

2.2 数据库ER图设计

核心实体包括:

  • 物资表(material):含分类、规格、单位、安全库存等字段
  • 供应商表(supplier):评估等级、账期等业务字段
  • 采购订单表(purchase_order):关联供应商与物资明细
  • 销售订单表(sales_order):含客户信息、交货日期等
  • 库存流水表(inventory_transaction):记录所有出入库操作

特别注意建立了库存快照表(inventory_snapshot)每天凌晨自动备份库存数据,这对后期排查库存差异非常关键。

3. 核心功能实现

3.1 采购-库存联动机制

采购订单审批通过后,系统会自动生成"在途库存"记录。这个设计解决了传统系统中"已采购未入库"物资的盲区问题。关键代码如下:

@app.route('/api/purchase/approve/<int:order_id>', methods=['POST']) @permission_required(Permission.APPROVE) def approve_purchase(order_id): order = PurchaseOrder.query.get_or_404(order_id) for item in order.items: # 创建在途库存记录 transit = InventoryTransit( material_id=item.material_id, quantity=item.quantity, expected_date=order.expected_delivery ) db.session.add(transit) order.status = 'approved' db.session.commit() return jsonify({'status': 'success'})

3.2 销售订单可用量检查

销售创建订单时,系统会实时计算: 可用库存 = 当前库存 + 在途库存 - 已预留库存 前端用AJAX实现实时校验:

$('#material_select').change(function(){ let materialId = $(this).val(); $.get('/api/inventory/available/'+materialId, function(data){ $('#available_qty').text(data.available); }); });

3.3 智能预警模块

系统自动监控以下情况:

  1. 库存低于安全库存(触发采购建议)
  2. 临近保质期物资(优先销售)
  3. 超期未到货的采购订单
  4. 应收账款逾期提醒

使用Celery定时任务每天9:00执行检查:

@app.celery.task def daily_check(): # 低库存检查 materials = Material.query.filter( Material.current_stock < Material.safety_stock ).all() for m in materials: create_alert('low_stock', m.id) # 保质期检查(食品医药类物资) near_expiry = Inventory.query.filter( Inventory.expiry_date < datetime.now() + timedelta(days=30) ).all() ...

4. 关键技术实现

4.1 Flask工厂模式应用

采用应用工厂模式使系统更易维护:

def create_app(config_name): app = Flask(__name__) app.config.from_object(config[config_name]) # 扩展初始化 db.init_app(app) login_manager.init_app(app) # 蓝图注册 from .purchase import purchase as purchase_blueprint app.register_blueprint(purchase_blueprint, url_prefix='/purchase') return app

4.2 报表导出性能优化

当处理万级数据的Excel导出时,常规方法会导致内存溢出。解决方案是使用生成器流式导出:

def generate_large_excel(query): output = BytesIO() writer = pd.ExcelWriter(output, engine='xlsxwriter') # 分批查询 for chunk in pd.read_sql(query.statement, query.session.bind, chunksize=5000): chunk.to_excel(writer, sheet_name='Data', index=False) writer.save() output.seek(0) return output

4.3 操作日志审计

所有关键操作记录日志到数据库和Elasticsearch双写:

def log_operation(user_id, action, details): # 数据库记录 db_log = OperationLog( user_id=user_id, action=action, details=details ) db.session.add(db_log) # Elasticsearch记录 es_log = { '@timestamp': datetime.utcnow(), 'user': user_id, 'operation': action, 'ip': request.remote_addr } es.index(index='operation_logs', body=es_log) db.session.commit()

5. 部署与性能调优

5.1 Nginx+Gunicorn配置

生产环境采用:

  • Nginx作为反向代理
  • Gunicorn多worker进程
  • Supervisor进程管理

典型Gunicorn配置:

gunicorn -w 4 -k gevent --bind 0.0.0.0:5000 --max-requests 1000 --timeout 120 "app:create_app('production')"

5.2 数据库连接池优化

SQLAlchemy连接池关键参数:

SQLALCHEMY_ENGINE_OPTIONS = { 'pool_size': 10, 'max_overflow': 5, 'pool_recycle': 3600, 'pool_pre_ping': True }

6. 踩坑经验

  1. 库存并发问题: 初期直接使用SQL更新库存导致数据不一致,后改用SELECT FOR UPDATE行锁:

    with db.session.begin_nested(): item = Inventory.query.with_for_update().get(material_id) item.quantity -= amount db.session.add(item)
  2. CSV导入内存溢出: 大文件导入改用流式处理:

    def stream_csv(file): while True: line = file.readline() if not line: break yield line.decode('utf-8').strip().split(',')
  3. 跨部门业务流程: 采购-入库-财务的三方对账最初设计不合理,后来增加"采购收货单"作为中间凭证,流程变为: 采购下单 → 供应商送货 → 仓库验收生成收货单 → 财务根据收货单付款

这个项目给我的最大启示是:业务系统开发中,对业务流程的理解深度比技术实现更重要。有次为了优化库存查询速度,我花了三天重写SQL语句,最后发现只要在物资分类表加个缓存,性能立即提升10倍。所以建议大家在开发前,至少花两周时间完整跟岗学习各岗位的实际工作流程。

← 返回列表