import pandas as pd import gradio as gr from datetime import datetime import os import json import pymysql from sqlalchemy import create_engine, Column, Integer, String, Float, Text, DateTime, inspect from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker # 阿里云数据库设置 DB_HOST = os.getenv('DB_HOST') # 阿里云数据库主机地址 DB_PORT = int(os.getenv('DB_PORT', '3306')) # 数据库端口,默认3306 DB_USER = os.getenv('DB_USER') # 数据库用户名 DB_PASSWORD = os.getenv('DB_PASSWORD') # 数据库密码 DBNAME = os.getenv('DB_PASSWORD') DB_NAME = os.getenv('DBNAME') # 数据库名称 log = os.getenv('USER') # 登录用户名 password = os.getenv('PASSWORD') # 登录密码 # 创建数据库连接 def get_db_connection(): try: connection = pymysql.connect( host=DB_HOST, port=DB_PORT, user=DB_USER, password=DB_PASSWORD, database=DB_NAME, charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor ) return connection except Exception as e: print(f"数据库连接错误: {e}") return None # 创建SQLAlchemy引擎和会话 def get_db_session(): try: engine = create_engine(f'mysql+pymysql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}') Session = sessionmaker(bind=engine) return Session(), engine except Exception as e: print(f"SQLAlchemy会话创建错误: {e}") return None, None # 定义数据库模型 Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) username = Column(String(50), unique=True, nullable=False) role = Column(String(20), nullable=False) def to_dict(self): return { 'id': self.id, 'username': self.username, 'role': self.role } class PurchaseOrder(Base): __tablename__ = 'purchase_orders' id = Column(Integer, primary_key=True, autoincrement=True) 付款抬头 = Column(String(100)) 合同号 = Column(String(50)) 运编号 = Column(String(50)) 采购编号 = Column(String(50), unique=True) 车辆信息 = Column(Text) 销售合同价 = Column(Float) 采购价 = Column(Float) 费用名称 = Column(String(50)) 费用金额 = Column(Float) 采购款收款抬头 = Column(String(100)) 采购款收款账号信息 = Column(Text) 业务员 = Column(String(50)) 客户名称 = Column(String(100)) 客户国家 = Column(String(50)) 在途状态 = Column(String(50)) 开票类型 = Column(String(20)) 收款状态 = Column(String(50)) 审批状态 = Column(String(50)) 退款说明 = Column(Text) 备注 = Column(Text) timestamp = Column(DateTime, default=datetime.now) 毛利 = Column(Float) def to_dict(self): return { 'id': self.id, '付款抬头': self.付款抬头, '合同号': self.合同号, '运编号': self.运编号, '采购编号': self.采购编号, '车辆信息': self.车辆信息, '销售合同价': self.销售合同价, '采购价': self.采购价, '费用名称': self.费用名称, '费用金额': self.费用金额, '采购款收款抬头': self.采购款收款抬头, '采购款收款账号信息': self.采购款收款账号信息, '业务员': self.业务员, '客户名称': self.客户名称, '客户国家': self.客户国家, '在途状态': self.在途状态, '开票类型': self.开票类型, '收款状态': self.收款状态, '审批状态': self.审批状态, '退款说明': self.退款说明, '备注': self.备注, 'timestamp': self.timestamp.strftime('%Y-%m-%d') if self.timestamp else None, '毛利': self.毛利 } # 初始化数据库 def init_database(): session, engine = get_db_session() if not session or not engine: return False try: # 检查表是否存在 conn = engine.connect() inspector = inspect(engine) # 创建表(如果不存在) if not inspector.has_table('users'): print("创建users表") User.__table__.create(engine) if not inspector.has_table('purchase_orders'): print("创建purchase_orders表") PurchaseOrder.__table__.create(engine) # 检查用户表是否为空,如果为空则添加初始用户 if session.query(User).count() == 0: new_users = [ User(id=1, username='cevcaigou159', role='采购'), User(id=2, username='cevdanzheng789', role='单证'), User(id=3, username='cevcaiwu369', role='财务'), User(id=4, username='cevboss888', role='总经理'), User(id=5, username='cevcaigou357', role='采购'), User(id=6, username='investor888', role='观察员'), User(id=7, username='cevcaigou888', role='采购经理'), User(id=8, username='cevcaigou005', role='采购'), User(id=9, username='cevchuna001', role='出纳'), User(id=10, username='cevcaigou359', role='采购'), User(id=11, username='cevcaigou288', role='采购') ] session.add_all(new_users) session.commit() session.close() return True except Exception as e: print(f"初始化数据库错误: {e}") session.rollback() session.close() return False # 初始化数据库 init_database() # 审批流程控制 def get_next_approval_status(current_status): try: if current_status == '待采购经理/总经理审批': return '待财务审批' elif current_status == '待财务审批': return '已批准' elif current_status == '已批准': return '已付款' return current_status except Exception as e: return "操作有误: {}".format(e) def approve_order(order_id, approver_role): try: session, _ = get_db_session() if not session: return '数据库连接失败' order = session.query(PurchaseOrder).filter(PurchaseOrder.采购编号 == order_id).first() if not order: session.close() return '订单未找到' current_status = order.审批状态 if (current_status == '待采购经理/总经理审批' and approver_role not in ['采购经理', '总经理']) or \ (current_status == '待财务审批' and approver_role != '财务') or \ (current_status == '待出纳审批' and approver_role != '出纳'): session.close() return f'只有{current_status}角色可以批准当前订单' next_status = get_next_approval_status(current_status) order.审批状态 = next_status order.timestamp = datetime.now() session.commit() session.close() return '订单已批准' except Exception as e: if session: session.rollback() session.close() return "操作有误: {}".format(e) # 全局会话状态 session_state = {'user_id': None, 'username': None, 'role': None, 'order_id': None} def login(username): try: session, _ = get_db_session() if not session: return '数据库连接失败' user = session.query(User).filter(User.username == username).first() if user: session_state['user_id'] = user.id session_state['username'] = user.username session_state['role'] = user.role session.close() return "登录成功,用户:{}".format(username) else: session.close() return "用户未找到" except Exception as e: if session: session.close() return "操作有误: {}".format(e) def submit_order1( username, 付款抬头, 运编号, 车辆信息, 销售合同价, 采购价, 费用名称, 费用金额, 采购款收款抬头, 采购款收款账号信息, 在途状态, 开票类型, 收款状态, 退款说明, 备注 ): try: global profit login(username) if session_state['role'] not in ['采购', '采购经理', '单证']: return "只有采购角色可以提交订单" session, _ = get_db_session() if not session: return '数据库连接失败' # 生成采购订单编号 prefix = 'DING00000' if session_state['username'] == 'cevcaigou159': prefix = 'SHEN00000' elif session_state['username'] == 'cevcaigou888': prefix = 'NIU00000' elif session_state['username'] == 'cevdanzheng789': prefix = 'CHEN00000' elif session_state['username'] == 'cevcaigou359': prefix = 'ZHUANG00000' elif session_state['username'] == 'cevcaigou288': prefix = 'GU00000' # 查询已有订单数量 existing_count = session.query(PurchaseOrder).filter( PurchaseOrder.采购编号.like(f"{prefix}%") ).count() n = existing_count + 900 i = n + 1 order_name = f"{prefix}{i}" # 查找现有运编号记录 existing_order = session.query(PurchaseOrder).filter( PurchaseOrder.运编号 == 运编号 ).first() if not existing_order: session.close() return "未找到相关运编号记录" profit = float(销售合同价) * 7 - float(采购价) + float(采购价) * 0.115 # 创建新订单 new_order = PurchaseOrder( 付款抬头=付款抬头, 合同号=existing_order.合同号, 运编号=运编号, 采购编号=order_name, 车辆信息=车辆信息, 销售合同价=float(销售合同价), 采购价=float(采购价), 费用名称=费用名称, 费用金额=float(费用金额) if 费用金额 else 0, 采购款收款抬头=采购款收款抬头, 采购款收款账号信息=采购款收款账号信息, 业务员=existing_order.业务员, 客户名称=existing_order.客户名称, 客户国家=existing_order.客户国家, 在途状态=在途状态, 开票类型=开票类型, 收款状态=收款状态, 审批状态='待采购经理/总经理审批', 退款说明=退款说明, 备注=备注, timestamp=datetime.now(), 毛利=profit ) session.add(new_order) session.commit() session.close() session_state.clear() return "订单已提交" except Exception as e: if session: session.rollback() session.close() return "操作有误: {}".format(e) def submit_order2( username, 付款抬头, 合同号, 运编号, 车辆信息, 销售合同价, 采购价, 费用名称, 费用金额, 采购款收款抬头, 采购款收款账号信息, 业务员, 客户名称, 客户国家, 在途状态, 开票类型, 收款状态, 退款说明, 备注 ): try: global profit login(username) if session_state['role'] not in ['采购', '采购经理', '单证']: return "只有采购角色可以提交订单" session, _ = get_db_session() if not session: return '数据库连接失败' # 生成采购订单编号 prefix = 'DING00000' if session_state['username'] == 'cevcaigou159': prefix = 'SHEN00000' elif session_state['username'] == 'cevcaigou888': prefix = 'NIU00000' elif session_state['username'] == 'cevdanzheng789': prefix = 'CHEN00000' elif session_state['username'] == 'cevcaigou359': prefix = 'ZHUANG00000' elif session_state['username'] == 'cevcaigou288': prefix = 'GU00000' # 查询已有订单数量 existing_count = session.query(PurchaseOrder).filter( PurchaseOrder.采购编号.like(f"{prefix}%") ).count() n = existing_count + 900 i = n + 1 order_name = f"{prefix}{i}" profit = float(销售合同价) * 7.25 - float(采购价) + float(采购价) * 0.115 # 创建新订单 new_order = PurchaseOrder( 付款抬头=付款抬头, 合同号=合同号, 运编号=运编号, 采购编号=order_name, 车辆信息=车辆信息, 销售合同价=float(销售合同价), 采购价=float(采购价), 费用名称=费用名称, 费用金额=float(费用金额) if 费用金额 else 0, 采购款收款抬头=采购款收款抬头, 采购款收款账号信息=采购款收款账号信息, 业务员=业务员, 客户名称=客户名称, 客户国家=客户国家, 在途状态=在途状态, 开票类型=开票类型, 收款状态=收款状态, 审批状态='待采购经理/总经理审批', 退款说明=退款说明, 备注=备注, timestamp=datetime.now(), 毛利=profit ) session.add(new_order) session.commit() session.close() session_state.clear() return "订单已提交" except Exception as e: if session: session.rollback() session.close() return "操作有误: {}".format(e) def format_order(order): try: return f"""
审批状态{order['审批状态']}
付款抬头{order['付款抬头']}
合同号{order['合同号']}
运编号{order['运编号']}
采购编号{order['采购编号']}
车辆信息{order['车辆信息']}
销售合同价(FOB美元){order['销售合同价']}
采购价(人民币){order['采购价']}
费用名称{order['费用名称']}
费用金额{order['费用金额']}
采购款收款抬头{order['采购款收款抬头']}
采购款收款账号信息{order['采购款收款账号信息']}
业务员{order['业务员']}
客户名称{order['客户名称']}
客户国家{order['客户国家']}
在途状态{order['在途状态']}
开票类型{order['开票类型']}
收款状态{order['收款状态']}
退款说明{order['退款说明']}
备注{order['备注']}
时间{order['timestamp']}
毛利{order['毛利']}
当前身份{session_state['username']}
""" except Exception as e: return "操作有误: {}".format(e) def display_orders(username): try: login(username) allowed_roles = [ '采购', '单证', '财务', '总经理', '观察员', '采购经理', '出纳' ] if session_state['role'] not in allowed_roles: return ["请登录后查看订单"] session, _ = get_db_session() if not session: return ["数据库连接失败"] # 将排序条件从timestamp改为id,并使用desc()实现倒序 orders = session.query(PurchaseOrder).order_by(PurchaseOrder.id.desc()).all() order_list = [format_order(order.to_dict()) for order in orders] session.close() session_state.clear() return order_list except Exception as e: if session: session.close() return ["操作有误: {}".format(e)] def approve_order_interface(username, order_id): try: login(username) allowed_roles = ['财务', '总经理', '采购经理', '出纳'] if session_state['role'] not in allowed_roles: return "您没有批准订单的权限" role1 = session_state['role'] result = approve_order(order_id, role1) session_state.clear() return result except Exception as e: return "操作有误: {}".format(e) with gr.Blocks() as app: with gr.TabItem("提交费用(旧运编号)"): username_submit = gr.Textbox(label="用户名") 付款抬头 = gr.Textbox(label="付款抬头") 运编号 = gr.Textbox(label="运编号") 车辆信息 = gr.Textbox(label="车辆信息") 销售合同价 = gr.Textbox(label="销售合同价(FOB美元)") 采购价 = gr.Textbox(label="采购价(人民币)") 费用名称 = gr.Dropdown( choices=[ '采车定金', '采车定金(抵车款)', '采车定金(全额退回)', '采车定金(部分退回)', '采车尾款(含背户费)', '采车尾款', '背户手续费', '系统刷机费', '充电桩费', '保险费(短期交强)', '保险费(长期交强)', '保险费(全险)', '国内运费(市内)', '国内运费', '购置税费', '仓储费', '检测报告费', '车辆用品费', '车辆改装费', '港杂费', '海运费', '海运费+港杂费', '其他费用' ], label="费用名称") 费用金额 = gr.Textbox(label="费用金额") 采购款收款抬头 = gr.Textbox(label="采购款收款抬头") 采购款收款账号信息 = gr.Textbox(label="采购款收款账号信息") 在途状态 = gr.Dropdown( choices=[ '工厂', '4S店', '车管所', '改装店', '运输中', '物流站点', '货代仓库', '装箱', '发运', '到达目的港' ], label="在途状态") 开票类型 = gr.Dropdown( choices=[ '增票', '普票', '低开', '无票' ], label="开票类型") 收款状态 = gr.Textbox(label="收款状态") 退款说明 = gr.Textbox(label="退款说明") 备注 = gr.Textbox(label="备注") submit_button = gr.Button("提交订单") submit_output = gr.HTML(label="输出") submit_button.click(fn=submit_order1, inputs=[ username_submit, 付款抬头,运编号,车辆信息, 销售合同价, 采购价, 费用名称, 费用金额, 采购款收款抬头, 采购款收款账号信息, 在途状态, 开票类型, 收款状态, 退款说明, 备注 ], outputs=submit_output) with gr.TabItem("提交订单(新运编号)"): username_submit = gr.Textbox(label="用户名") 运编号_submit = gr.Textbox(label="运编号") 付款抬头 = gr.Textbox(label="付款抬头") 合同号 = gr.Textbox(label="合同号") 车辆信息 = gr.Textbox(label="车辆信息") 销售合同价 = gr.Textbox(label="销售合同价(FOB美元)") 采购价 = gr.Textbox(label="采购价(人民币)") 费用名称 = gr.Dropdown( choices=[ '采车定金', '采车定金(抵车款)', '采车定金(全额退回)', '采车定金(部分退回)', '采车尾款(含背户费)', '采车尾款', '背户手续费', '系统刷机费', '充电桩费', '保险费(短期交强)', '保险费(长期交强)', '保险费(全险)', '国内运费(市内)', '国内运费', '购置税费', '仓储费', '检测报告费', '车辆用品费', '车辆改装费', '港杂费', '海运费', '海运费+港杂费', '其他费用' ], label="费用名称") 费用金额 = gr.Textbox(label="费用金额") 采购款收款抬头 = gr.Textbox(label="采购款收款抬头") 采购款收款账号信息 = gr.Textbox(label="采购款收款账号信息") 业务员 = gr.Textbox(label="业务员") 客户名称 = gr.Textbox(label="客户名称") 客户国家 = gr.Textbox(label="客户国家") 在途状态 = gr.Dropdown( choices=[ '工厂', '4S店', '车管所', '改装店', '运输中', '物流站点', '货代仓库', '装箱', '发运', '到达目的港' ], label="在途状态") 开票类型 = gr.Dropdown( choices=[ '增票', '普票', '低开', '无票' ], label="开票类型") 收款状态 = gr.Textbox(label="收款状态") 退款说明 = gr.Textbox(label="退款说明") 备注 = gr.Textbox(label="备注") submit_button = gr.Button("提交订单") submit_output = gr.HTML(label="输出") submit_button.click(fn=submit_order2, inputs=[ username_submit, 付款抬头, 合同号, 运编号_submit, 车辆信息, 销售合同价, 采购价, 费用名称, 费用金额, 采购款收款抬头, 采购款收款账号信息, 业务员, 客户名称, 客户国家, 在途状态, 开票类型, 收款状态, 退款说明, 备注 ], outputs=submit_output) with gr.TabItem("所有订单"): username_display = gr.Textbox(label="用户名") display_button = gr.Button("显示所有订单") orders_output = gr.HTML(label="订单") display_button.click(fn=display_orders, inputs=username_display, outputs=orders_output) with gr.TabItem("批准订单"): username_approve = gr.Textbox(label="用户名") order_id = gr.Textbox(label="采购编号") approve_order_button = gr.Button("批准订单") approve_order_output = gr.HTML(label="输出") approve_order_button.click(fn=approve_order_interface, inputs=[username_approve, order_id], outputs=approve_order_output) app.launch(auth=(log, password))