Skip to content

一、这个“我的收入”功能是做什么的?

你是一名在线问诊的医生,每天通过图文问诊、开药、健康咨询等方式帮助患者。那你肯定想知道:

  • 上个月一共赚了多少钱?
  • 哪种服务赚得最多?是图文问诊还是开药?
  • 每一笔收入是从哪个患者来的?什么时候到账的?

“我的收入”这个功能,就是给医生看的一张“工资条+明细账本”,让他们能清楚、安全、方便地查看自己的收入情况


二、这个工单的核心要求是什么?

这份工单其实就是一个“任务说明书”,告诉我们这个功能要做到哪几步:

  1. 展示总收入 默认显示最近一个月的总收入,比如“3月收入:12,800元”。
  2. 按服务类型分类 告诉医生这笔钱是从哪里来的:
    • 图文问诊:6,000元
    • 极速问诊:3,000元
    • 开药问诊:3,800元
  3. 提供交易明细 点进去能看到每一笔收入的详细信息:
    • 日期:2025-03-15
    • 患者:张*(脱敏)
    • 服务类型:图文问诊
    • 金额:150元
    • 支付方式:微信支付
    • 状态:已完成
  4. 支持筛选和搜索 医生可以按“时间段”“服务类型”“支付状态”来查找特定记录,比如“查一下所有退款中的订单”。
  5. 安全第一
    • 只有医生本人能看自己的收入;
    • 所有数据传输要加密,防止被偷看;
    • 敏感信息(如患者姓名、金额)要“打码”显示。
  6. 高并发也要稳 每月1号很多医生一起查收入,系统不能卡、不能崩。

三、这个功能是怎么设计和实现的?

我们可以把这个功能想象成一个“自动记账+查账系统”,它由几个部分组成:

1. 前端(医生看到的界面)

  • 医生打开App或网页,点击“我的收入”;
  • 看到一个漂亮的图表:总金额、分类饼图;
  • 可以选择“最近一周”“最近一月”“自定义时间”;
  • 点“查看详情”,看到一条条收入记录。

👉 就像你在支付宝里看“账单”一样。

2. 后端(背后的“大脑”)

这是Java开发负责的部分,主要做三件事:

(1)记账

每当医生完成一次问诊,系统就自动记一笔账,存到数据库里。 比如:

医生ID:1001,服务类型:图文问诊,金额:150,时间:2025-03-15

(2)算总数

医生一进来,系统马上算出他上个月总共赚了多少钱,按类型分类。 为了避免每次都要重新算,系统会提前算好、存起来,就像公司每月1号发工资条。

(3)查明细

医生想看具体每一笔,系统就从数据库里把记录一条条找出来,按时间排序,返回给前端。

3. 数据库(“账本”存放地)

  • 有两个“账本”:
    • 总账本(income_summary):每个医生每月的总收入;
    • 明细账本(income_detail):每一笔收入的详细记录。
  • 为了防止太多人查账时系统卡住,我们给“总金额”加了个缓存(就像把工资条提前打印好),别人一问就直接给,不用现算。

四、用了哪些技术?(通俗解释)

技术通俗解释作用
Java + Spring Boot后台“大脑”的编程语言和框架处理逻辑、接收请求、返回数据
MySQL存数据的“电子账本”存储每一笔收入记录
Redis一个“高速缓存小本本”把常用数据(如总收入)记下来,查得更快
HTTPS给数据加“密码锁”防止别人在传输过程中偷看收入数据
AES加密给敏感信息“打码”比如银行账号、身份证号,存的时候是乱码,只有系统能解开
JMeter压力测试工具模拟1万个医生同时查收入,看系统会不会崩
ELK日志系统记录谁在什么时候查了收入,用于安全审计

五、真实场景举例

场景1:每月1号,医生集中查收入

  • 问题:1万个医生同时点“我的收入”,系统会不会卡?
  • 解决:用 Redis 缓存每个人的总收入,一查就出结果,不现算,系统不卡。

场景2:张医生想查“退款中的订单”

  • 操作:他选择“状态=退款中”,点击搜索;
  • 系统:从“明细账本”里找出所有状态是“退款中”的记录,返回给他;
  • 安全:系统先确认“你是张医生”,才允许你看“张医生的数据”,不能看别人的。

场景3:张医生点开一笔收入,想看患者全名

  • 系统:提示“查看完整信息需验证身份”;
  • 验证后:系统从加密数据中“解码”出患者全名;
  • 同时:记录一条日志:“张医生于8:15查看了患者信息”——用于审计。

六、提现功能怎么实现的呢?

第1步:医生发起提现

  • 在App点击“提现”;
  • 系统显示“当前可提现金额:12,800元”;
  • 医生选择银行卡(或添加新卡),输入金额“10000”,点击“确认”。

第2步:系统做“提现前检查”

系统会自动检查:

  • ✅ 余额是否足够(12,800 ≥ 10,000)
  • ✅ 银行卡是否已实名认证(姓名、身份证、卡号一致)
  • ✅ 是否超过每日提现限额(比如单日最多提5万)
  • ✅ 是否是本人操作(登录账号匹配)

任意一项不通过,就提示失败,钱不会动。

第3步:冻结金额 + 创建提现订单

  • 系统先“冻结”这10,000元,防止重复提现;
  • 创建一条“提现订单”,状态为“处理中”;
  • 记录:时间、金额、银行卡、手续费(如有)。

第4步:调用银行/第三方支付接口打款

  • 系统调用银行代付接口(如招商银行企业代付)或第三方支付平台(如微信商户、支付宝企业);

  • 发送请求:

    json
    {
      "bank_card": "6225********1234",
      "amount": 1000000,  // 单位:分
      "real_name": "张伟",
      "id_card": "11010119900307XXXX",
      "order_no": "W20250401100001"
    }

第5步:接收结果,更新状态

  • 如果银行返回“成功”:
    • 更新提现订单为“已到账”;
    • 扣除可用余额;
    • 发送通知:“10,000元已到账,请注意查收”。
  • 如果返回“失败”:
    • 状态改为“提现失败”;
    • 解冻金额,医生可重新提现;
    • 记录失败原因(如“银行卡号错误”)。

第6步:对账与财务报表

  • 每日凌晨,系统与银行对账单比对,确保“平台记录”和“银行实际打款”一致;
  • 生成财务报表,供财务人员审核。

关键技术与安全措施

技术/机制作用为什么重要
实名认证 + 银行卡三要素验证校验姓名、身份证、卡号是否一致防止提错卡、防欺诈
HTTPS + 敏感信息加密传输过程加密,卡号加密存储防止数据泄露
提现订单状态机待处理 → 处理中 → 成功/失败状态清晰,避免重复打款
分布式锁同一时间只能发起一次提现防止并发重复提交
消息队列(RabbitMQ/Kafka)异步处理打款请求避免接口超时,提升体验
操作日志 + 审计记录谁、什么时候、提了多少钱出问题可追溯
对账系统每日与银行对账确保资金0误差

高并发与异常处理

❓ 如果1万个医生同时提现,系统会不会崩?

  • 使用消息队列异步处理,前端快速返回“已提交”;
  • 后台慢慢处理,避免数据库压力过大。

❓ 提现失败了怎么办?

  • 自动进入“重试队列”,最多重试3次;
  • 仍失败则人工介入,联系银行排查。

❓ 医生提错卡了怎么办?

  • 不支持“提错卡后自动退回”;
  • 需医生提供银行拒收证明,平台人工退款;
  • 强调:提现前必须二次确认银行卡信息

和“我的收入”功能的关系

功能作用
我的收入告诉医生“你赚了多少钱” → 记账 + 查账
医生提现告诉医生“你可以把钱提走” → 资金出账

两者共享同一套数据源:

  • “我的收入”中的“可提现金额” = 提现功能的“最大可提额度”;
  • 提现成功后,同步更新“我的收入”中的“已提现金额”。