一、这个“我的收入”功能是做什么的?
你是一名在线问诊的医生,每天通过图文问诊、开药、健康咨询等方式帮助患者。那你肯定想知道:
- 上个月一共赚了多少钱?
- 哪种服务赚得最多?是图文问诊还是开药?
- 每一笔收入是从哪个患者来的?什么时候到账的?
“我的收入”这个功能,就是给医生看的一张“工资条+明细账本”,让他们能清楚、安全、方便地查看自己的收入情况。
二、这个工单的核心要求是什么?
这份工单其实就是一个“任务说明书”,告诉我们这个功能要做到哪几步:
- 展示总收入 默认显示最近一个月的总收入,比如“3月收入:12,800元”。
- 按服务类型分类 告诉医生这笔钱是从哪里来的:
- 图文问诊:6,000元
- 极速问诊:3,000元
- 开药问诊:3,800元
- 提供交易明细 点进去能看到每一笔收入的详细信息:
- 日期:2025-03-15
- 患者:张*(脱敏)
- 服务类型:图文问诊
- 金额:150元
- 支付方式:微信支付
- 状态:已完成
- 支持筛选和搜索 医生可以按“时间段”“服务类型”“支付状态”来查找特定记录,比如“查一下所有退款中的订单”。
- 安全第一
- 只有医生本人能看自己的收入;
- 所有数据传输要加密,防止被偷看;
- 敏感信息(如患者姓名、金额)要“打码”显示。
- 高并发也要稳 每月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次;
- 仍失败则人工介入,联系银行排查。
❓ 医生提错卡了怎么办?
- 不支持“提错卡后自动退回”;
- 需医生提供银行拒收证明,平台人工退款;
- 强调:提现前必须二次确认银行卡信息。
和“我的收入”功能的关系
| 功能 | 作用 |
|---|---|
| 我的收入 | 告诉医生“你赚了多少钱” → 记账 + 查账 |
| 医生提现 | 告诉医生“你可以把钱提走” → 资金出账 |
两者共享同一套数据源:
- “我的收入”中的“可提现金额” = 提现功能的“最大可提额度”;
- 提现成功后,同步更新“我的收入”中的“已提现金额”。