基于Python实现教学档案软件收费标准计费系统
教学档案软件计费模型拆解
在开发教学档案软件时,收费模式通常基于学校规模、存储容量及功能模块进行组合。为了实现自动化的费用计算,我们需要先定义一套标准的计费逻辑。本指南将构建一个包含以下维度的计费系统:
- 基础席位费:按教师账号数量收费,每个账号每年 500 元。
- 存储空间费:按档案数据占用的存储空间收费,前 100GB 免费,超出部分按 10元/GB/年 计算。
- 功能模块费:高级功能(如 OCR 文字识别、电子签章)按年收费,OCR 2000元/年,电子签章 3000元/年。
- 折扣规则:当教师账号数超过 50 个时,总费用享受 9 折优惠。
开发环境初始化
本系统采用 Python 3.10 及 FastAPI 框架构建,FastAPI 具有高性能、自动生成文档的特性,非常适合此类业务逻辑开发。请严格按照以下步骤准备环境。
1. 安装 Python 3.10
Windows 用户访问 https://www.python.org/downloads/ 下载安装包,安装时务必勾选 "Add Python to PATH"。Linux/Mac 用户使用包管理器安装:
2. 创建项目目录与虚拟环境
在终端中执行以下命令,创建独立的项目环境,避免依赖冲突:
```bash mkdir archive_billing_system cd archive_billing_system 创建虚拟环境 python3 -m venv venv 激活虚拟环境 Windows venv\Scripts\activate Linux/Mac source venv/bin/activate ```3. 安装核心依赖库
我们需要安装 FastAPI(Web 框架)、Uvicorn(ASGI 服务器)和 Pydantic(数据验证):
```bash pip install fastapi uvicorn pydantic ```配置文件与数据模型构建
为了确保代码的可维护性,我们将价格常量与数据模型分离。首先创建配置文件 config.py,定义收费标准。
1. 编写配置文件 (config.py)
在项目根目录下创建 config.py,直接复制以下代码:
2. 定义数据模型 (models.py)
创建 models.py,使用 Pydantic 定义请求体的数据结构,这能自动帮我们校验输入数据的类型(如确保存储容量是正整数):
核心计费逻辑代码实现
这是本系统的核心部分,我们需要编写具体的计算逻辑。创建 service.py,实现费用的分段计算。

1. 编写计费服务 (service.py)
在该文件中,我们将处理存储溢出计算、模块费用累加以及最终的折扣逻辑:
```python service.py import config from models import BillingRequest, BillingResponse def calculate_billing(request: BillingRequest) -> BillingResponse: breakdown = {} 1. 计算教师席位费 teacher_cost = request.teacher_count config.PRICE_PER_TEACHER breakdown["teacher_seats_cost"] = teacher_cost 2. 计算存储空间费 storage_cost = 0.0 if request.storage_used_gb > config.FREE_STORAGE_PRICE: billable_gb = request.storage_used_gb - config.FREE_STORAGE_PRICE storage_cost = billable_gb config.PRICE_PER_GB breakdown["storage_cost"] = storage_cost 3. 计算功能模块费 module_cost = 0 active_modules = [] for module in request.enabled_modules: if module in config.MODULE_PRICES: module_cost += config.MODULE_PRICES[module] active_modules.append(module) breakdown["module_cost"] = module_cost breakdown["active_modules"] = active_modules 4. 汇总基础总价 total_before_discount = teacher_cost + storage_cost + module_cost 5. 应用折扣规则 final_price = total_before_discount is_discounted = False if request.teacher_count > config.DISCOUNT_THRESHOLD: final_price = total_before_discount config.DISCOUNT_RATE is_discounted = True breakdown["discount_details"] = f"教师数{request.teacher_count}超过{config.DISCOUNT_THRESHOLD},享受{int(config.DISCOUNT_RATE10)}折优惠" 保留两位小数 final_price = round(final_price, 2) return BillingResponse( total_price=final_price, price_breakdown=breakdown, discount_applied=is_discounted ) ```Web接口开发与调用测试
现在我们将核心逻辑封装成 HTTP API 接口,方便外部系统调用。创建 main.py。
1. 编写主程序 (main.py)
```python main.py from fastapi import FastAPI from models import BillingRequest, BillingResponse import service app = FastAPI(title="教学档案软件计费系统", version="1.0.0") @app.post("/calculate", response_model=BillingResponse, summary="计算档案软件年费") async def calculate_fee(request: BillingRequest): """ 根据教师数量、存储空间和启用的模块计算年度费用。 """ result = service.calculate_billing(request) return result 启动命令提示 if __name__ == "__main__": import uvicorn print("启动服务: uvicorn main:app --reload") uvicorn.run(app, host="0.127.0.0.1", port=8000) ```2. 启动服务
在终端执行以下命令启动 Web 服务:
```bash uvicorn main:app --reload ```终端显示 Application startup complete 即表示启动成功。
3. 接口测试与验证
我们可以使用 curl 命令直接在终端进行测试,或者访问 http://127.0.0.1:8000/docs 使用 Swagger UI 进行可视化测试。
测试场景 1:小规模学校(30 教师,50GB 存储,开启 OCR),不应触发折扣。
```bash curl -X POST "http://127.0.0.1:8000/calculate" \ -H "Content-Type: application/json" \ -d '{ "teacher_count": 30, "storage_used_gb": 50, "enabled_modules": ["ocr"] }' ```预期结果计算:30500 + 0 (存储未超100) + 2000 (OCR) = 17000 元。
测试场景 2:大规模学校(60 教师,150GB 存储,开启 OCR 和电子签章),应触发 9 折。
```bash curl -X POST "http://127.0.0.1:8000/calculate" \ -H "Content-Type: application/json" \ -d '{ "teacher_count": 60, "storage_used_gb": 150, "enabled_modules": ["ocr", "esign"] }' ```预期结果计算: 教师费:60500 = 30000 存储费:(150-100)10 = 500 模块费:2000+3000 = 5000 总计:35500 折后:35500 0.9 = 31950 元。
常见错误处理与日志记录
在生产环境中,必须处理异常输入,例如传入了未定义的模块代码。当前的 Pydantic 模型已经处理了大部分类型校验,但我们可以增强日志记录。修改 service.py 引入 logging:
```python import logging 配置日志 logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) def calculate_billing(request: BillingRequest) -> BillingResponse: logger.info(f"收到计费请求: 教师数={request.teacher_count}, 存储={request.storage_used_gb}") ... 原有计算逻辑 ... 检查无效模块并记录 valid_modules = set(config.MODULE_PRICES.keys()) input_modules = set(request.enabled_modules) invalid = input_modules - valid_modules if invalid: logger.warning(f"检测到无效的模块代码: {invalid},这些模块将被忽略且不收费") ... 返回结果 ... ```通过以上步骤,你已经完成了一个具备完整业务逻辑、数据校验、API 接口和错误处理的教学档案软件计费系统。该系统可以直接作为微服务部署到学校的服务器或云环境中,为前端系统提供标准的费用计算支持。