Java vue 养老系统源码详解:入住核算单 live-check 缴费入账与预交金收据实践

Java养老系统源码详解:入住核算单 live-check 缴费入账与预交金收据实践

在线演示 :管理端后台

标签:#Java #Spring Boot #MyBatis #养老系统 #入住核算单 #care_bill_payment #changeBiz


1. 入住核算单与缴费入账

合同审批通过后 费用管理 · 入住核算单 出现一行 paymentType=入住;前台录入预交金、押金实缴,后端 CareBillPaymentServiceImpl.pay 调 CareAccountService.changeBiz,bizType=BILL_PAYMENT,并带 care_pay_way 交易方式。

开户在合同生效时 getOrOpen 已完成;核算单只负责应缴实缴对齐,不重复开户。

图1 入住核算单 · 押金/预交金/一次性分项

图2 缴费后账户流水

2. CareBillPaymentDO 与状态常量

复制代码
private static final int TYPE_CHECKIN = 1;
private static final int STATUS_PENDING = 0;
private static final int STATUS_PARTIAL = 1;
private static final int STATUS_DONE = 2;

private static final int WALLET_BALANCE = 1;
private static final int WALLET_DEPOSIT = 2;
private static final int CHANGE_RECHARGE = 1;

@TableName("care_bill_payment")
public class CareBillPaymentDO extends CareOrgBaseDO {
    private Long olderId;
    private Long checkinId;
    private Integer paymentType;
    private BigDecimal depositDue;
    private BigDecimal advanceDue;
    private BigDecimal amountDue;
    private BigDecimal advancePaid;
    private BigDecimal depositPaid;
    private Integer status;
}

3. generateCheckinFromApply(审批通过生成单据)

复制代码
public Long generateCheckinFromApply(CareContractDO contract, CareContractSubmitCheckinReqVO reqVO) {
    CareBillPaymentDO exists = careBillPaymentMapper.selectByCheckinIdAndType(
            contract.getCheckinId(), TYPE_CHECKIN);
    if (exists != null) {
        return exists.getId();
    }
    payment.setPaymentType(TYPE_CHECKIN);
    payment.setTitle("入住核算单");
    payment.setDepositDue(depositDue);
    payment.setAdvanceDue(advanceDue);
    careBillPaymentMapper.insert(payment);
    return payment.getId();
}

4. pay:预交金/押金分钱包 + 缴清扣一次性费

复制代码
public List<Long> pay(CareBillPaymentPayReqVO reqVO) {
    if (advance.compareTo(BigDecimal.ZERO) > 0) {
        flowIds.add(careAccountService.changeBiz(
                exists.getOlderId(), WALLET_BALANCE, CHANGE_RECHARGE,
                advance, "a5", "BILL_PAYMENT", exists.getId(), payRemark, reqVO.getPayWay()));
    }
    if (deposit.compareTo(BigDecimal.ZERO) > 0) {
        flowIds.add(careAccountService.changeBiz(
                exists.getOlderId(), WALLET_DEPOSIT, CHANGE_RECHARGE,
                deposit, "b1", "BILL_PAYMENT", exists.getId(), payRemark, reqVO.getPayWay()));
    }
    if (becomingDone && Objects.equals(exists.getPaymentType(), TYPE_CHECKIN)) {
        flowIds.addAll(deductCheckinOneTimeFees(exists, reqVO.getPayWay()));
    }
}
  • advanceOk && depositOk:分项达标才 STATUS_DONE;被褥/其他一次性费在缴清后从预交金扣。

5. Controller 与 curl

复制代码
@RestController
@RequestMapping("/care/bill-payment")
public class CareBillPaymentController {
    @PostMapping("/pay")
    public CommonResult<List<Long>> pay(@Valid @RequestBody CareBillPaymentPayReqVO reqVO) {
        return success(careBillPaymentService.pay(reqVO));
    }
}

curl -X POST "http://localhost:48080/admin-api/care/bill-payment/pay" \
  -H "Authorization: Bearer {token}" \
  -H "tenant-id: 123" \
  -H "Content-Type: application/json" \
  -d '{"id":6001,"advancePaid":5000,"depositPaid":2000,"payWay":"1"}'

补充:缴清顺序与一次性费用

pay 里要先 updateById 把核算单标为已缴清 ,再扣被褥等一次性费;否则 deductCheckinOneTimeFees 仍被「入住核算未缴清」拦住(社区版已按此顺序修复)。

图3 费用管理 · 入住核算单筛选

图4 合同生效后才会生成 TYPE_CHECKIN 核算单

复制代码
// CareBillPaymentServiceImpl.pay(逻辑顺序)
careBillPaymentMapper.updateById(doneUpdate); // status=STATUS_DONE
if (becomingDone && Objects.equals(exists.getPaymentType(), TYPE_CHECKIN)) {
    flowIds.addAll(deductCheckinOneTimeFees(exists, reqVO.getPayWay()));
    deductCheckinMonthBillFullIfNeeded(exists, reqVO.getPayWay());
}
钱包 changeType 典型科目
预交金 充值 a5
押金 充值 b1
预交金 扣费 a1/a2/a3 一次性
复制代码
curl -G "http://localhost:48080/admin-api/care/bill-payment/page"   -H "Authorization: Bearer {token}" -H "tenant-id: 123"   --data-urlencode "paymentType=1" --data-urlencode "status=0"

图5 缴清后首月整单扣费依赖计费设置(见 30 篇)

6. 踩坑

  • 重复 pay:STATUS_DONE 抛 BILL_PAYMENT_STATUS_ERROR。
  • 只传 amount 老字段:整笔当预交金,新前端应拆 advancePaid/depositPaid。
  • 缴清但未扣一次性费:检查 becomingDone 与 feeItems 是否入库。
  • tenant-id:流水按租户隔离,联调必带。

补充:日志与排错顺序

  1. 浏览器 Network 看 /admin-api 返回 code/msg。

  2. IDEA 断点 Service 入口,确认 tenant-id 与业务 id。

  3. 查库 status 与界面一致(勿只改 checkin 不改 bed)。

  4. 定时任务看 infra_job 日志与 @TenantJob 租户上下文。

    curl -X POST -H "tenant-id: 123" -H "Content-Type: application/json"
    -d "{"phone":"13900001001","password":"123456","accountType":2}"
    http://127.0.0.1:8086/app-api/care/family-auth/login

联调:application-local 与 tenant-id

本地 zhijian-server 联调时,管理端请求统一带头:

复制代码
yudao:
  tenant:
    enable: true
spring:
  profiles:
    active: local

curl -H "Authorization: Bearer {token}" -H "tenant-id: 123" \
  "http://localhost:48080/admin-api/care/..."

403 先查角色是否勾选菜单按钮权限;401 查 token 是否过期。多园环境 rootDeptId 与登录部门一致,否则计费/报表可能看到空列表。

模块路径(Maven)

模块 典型包路径
institution zhijian-module-institution/.../service/
hub zhijian-module-hub/.../service/hub/
bi zhijian-module-bi/.../service/bi/
monitor zhijian-module-monitor/.../
community zhijian-module-community/.../
medical zhijian-module-medical/.../

交付裁剪时 zhijian-server/pom.xml 注释未购业态 JAR,并执行 care_maven_delivery_menu_crop.sql 隐藏菜单,避免「有菜单无 API」。

与 hub 中台衔接

老人主档 care_older 在 hub;机构业务 care_checkin / care_contract 在 institution。中台档案页不存 bed_id,床态以 care_bed.status 为准(见 24 篇)。跨模块只通过 olderId、SPI Bridge 或 REST,不在 hub 里直接 join institution 大表。

演示站对照

在线演示:管理端后台 --- 登录后左侧菜单与源码 @PreAuthorize 权限码一致;改 SQL 菜单后需重新登录刷新路由。


Gitee 社区版源码 :https://gitee.com/xinzexingjian-data_0/older_care

相关推荐
不磕了还不行14 分钟前
用 Vue + Element UI 把元宝搜索的返回值做成“能点开检查的证据卡片”
前端·vue.js·ui
全栈练习生18 分钟前
大模型原理之自适应推理
python·ai
实名上网宋凯宣9 小时前
Django
后端·python·django
天河归来10 小时前
第三方接口不稳定,如何让核心任务继续完成
java·大数据
如若12310 小时前
【论文复现】CoFailMed:从零复现医学图像分割的共享失败审计,含完整代码流程与科研绘图
人工智能·python
Knight_AL10 小时前
Java 文件下载时文件名中的 `#` 被转换成 `%23`?一次 URL 编码与解码问题排查
java·开发语言
FRing0311 小时前
vue2干货总结2(v-bind、v-for、v-model、指令修饰符、v-bind操作class和style)
开发语言·前端·vue.js·vue2
砚底藏山河11 小时前
python量化自定义周期 K 线合成
java·开发语言·数据库·python·金融
视觉小萌新12 小时前
AI Class 3 · Chapter 1:变量、字符串、list/dict、if/for(python学习-小白版-有经验可跳过)
python·学习·list
猿究院_夏燊12 小时前
MySQL 的四种隔离级别
java·数据库·mysql