项目中心-支付模块

This commit is contained in:
wangzzpeng
2026-09-30 08:04:16 +08:00
parent 6b88c3805f
commit ce8210fb3f
35 changed files with 2618 additions and 175 deletions

2
src/types/api.d.ts vendored
View File

@@ -28,4 +28,6 @@ export interface FileInfo {
size: number
uploadTime: string
url: string
/** OSS 主键(同源预览用);本地未上传文件为 undefined */
ossId?: string | number
}

View File

@@ -1,7 +1,86 @@
// 财务中心实体(账单/支付/发票/抬头/统计)
/** 账单状态 */
export type BillStatus = '待支付' | '已支付' | '未到期'
/**
* 账单状态(页面展示口径,中文)。
*
* <p>与后端 {@code vm_bill.status} 的英文编码(见 `BillStatusCode`)是多对一的展示映射,
* 转换收口在 `utils/billVo.ts#toBillStatus`。</p>
*/
export type BillStatus = '待支付' | '已支付' | '未到期' | '已取消'
/** 后端账单状态编码(`vm_bill.status` 值域) */
export type BillStatusCode = 'UNSTARTED' | 'PENDING' | 'PAID' | 'CANCELLED'
/**
* 后端账单视图对象 —— `GET /web/bill/list` 的响应元素(对应后端 `BillVo`)。
*
* <p>金额单位 **元**;`id` 为雪花 id 时 JSON 里是字符串,小 id 是数字,一律 `String(id)` 归一。</p>
*/
export interface BillVo {
id: number | string
billNo?: string
projectId?: number | string
projectNo?: string
projectName?: string
userId?: number | string
amount?: number
/** 业务类型字典值:internet_software / hardware_circuit / iot_solution / manufacturing */
bizType?: string
/** 账单类型:ADVANCE / PROGRESS / FINAL / OTHER */
billType?: string
/** 期次名,如「第2期·尾款」(页面「账单名称」列) */
periodName?: string
/** 占项目总额比例(%) */
periodRatio?: number
status?: BillStatusCode | string
/** 支付通道:WECHAT / ALIPAY / BANK / WORKWX */
payChannel?: string
/** 交易流水号(支付成功回写) */
transactionNo?: string
/** 交易名称(支付时回传) */
tradeName?: string
payTime?: string
dueDate?: string
createTime?: string
}
/**
* 后端分期计划视图对象(`vm_bill_plan` + 该期支付单信息,对应 `BillPlanVo`)。
*
* <p>由项目详情「合同财务」那个现成接口 `GET /web/requirementPool/get/finance/{需求id}`
* 的 `billPlans` 下发;收银台「订单明细」复用同一份数据
* (见 `api/finance.ts#getCheckoutBills`),没有再单开端点。</p>
*
* <p>⚠️ 本栈支付口径是**计划 id**:`vm_finance_payment.bill_id` 实测存的就是 `vm_bill_plan.id`,
* 所以收银台 `?ids=` 传的是这个 `id`,而不是 `vm_bill.id`。</p>
*/
export interface BillPlanVo {
id: number | string
projectId?: number | string
projectNo?: string
projectName?: string
userId?: number | string
bizType?: string
/** ⚠️ BigDecimal ⇒ 后端以**字符串**下发("120000.00"),用前必须 `Number()` 归一 */
totalAmount?: number | string
/** 分期总期数 */
periods?: number
/** 本期期次序号(1 起) */
currentPeriod?: number
/** 每期比例规则,如 "40,30,30" */
periodRule?: string
nextDate?: string
/** 计划状态:ACTIVE / DONE / CLOSED / UNSTARTED */
status?: string
/** 该期支付单的商户订单号(页面「账单号」用它);未支付为空 */
orderNo?: string
transactionNo?: string
payChannel?: string
payAmount?: number | string
/** 支付单状态:CREATED / SUCCESS / FAILED / REFUNDED */
payStatus?: string
payTime?: string
}
/** 发票状态 */
export type InvoiceStatus = '已开票' | '开票中' | '未开票'
@@ -9,17 +88,44 @@ export type InvoiceStatus = '已开票' | '开票中' | '未开票'
/** 支付方式 */
export type PayMethod = 'wechat' | 'alipay'
/** 账单 */
/**
* 后端统一支付响应 `org.dromara.pay.domain.PaymentResponse`(字段名与后端一致)。
*
* <p>扫码(Native)渠道回 `codeUrl`;支付宝电脑网站支付回 `formBody`
* ——注意该字段名虽叫 formBody,实测后端走 `pageExecute(request, "GET")`,
* 内容其实是**收银台跳转地址**而非 HTML 表单,前端两种形态都兜住。</p>
*/
export interface PayOrderResponse {
/** 支付渠道:WECHAT / ALIPAY / UNIONPAY */
channel: string
/** 支付场景:JSAPI / NATIVE / WEB_SCAN / WEB_PAGE / APP */
scene: string
/** 扫码支付二维码内容:微信 Native 为 code_url,支付宝订单码为 qr_code */
codeUrl?: string
/** 支付宝电脑网站支付返回的收银台跳转地址 / HTML 表单 */
formBody?: string
/** 支付宝 APP 支付订单串 */
orderString?: string
/** H5 支付链接 */
h5Url?: string
}
/** 账单(页面视图模型;由 `utils/billVo.ts#toBill` 从后端 `BillVo` 映射而来) */
export interface Bill {
id: string
/** 分期计划名,如 '第一期·预付款 比例33%' */
/** 分期计划名,如 '第一期·预付款 比例33%'(后端 `periodName`) */
planName: string
billNo: string
/** 交易流水号(后端 `transactionNo`) */
tradeNo?: string
projectName: string
amount: number
status: BillStatus
createTime: string
/** 支付通道英文编码(WECHAT / ALIPAY / BANK / WORKWX) */
payChannel?: string
/** 支付时间(后端 `payTime`) */
payTime?: string
}
/** 账单查询条件 */

View File

@@ -122,7 +122,22 @@ export interface TeamMember {
/** 项目账单(付款计划) */
export interface ProjectBill {
id: string
/**
* 数据来源:
* - `bill` = 真账单(`vm_bill`)—— `id` 是账单 id,可跳收银台支付;
* - `plan` = 仅付款计划(`vm_bill_plan`)—— 后端未重启(响应无 `bills`)时的只读回落,
* **没有账单 id,不可支付**(计划 id 与账单 id 值域重叠,拿来当收银台入参会查到别的账单)。
*/
source: 'bill' | 'plan'
planName: string
/**
* 期次占比(%),已归一成**可展示文本**(如 `"30"`;非整数比例保留一位小数)。
*
* <p>数据源:账单 `vm_bill.period_ratio`(BigDecimal,字符串下发),回落卡则由
* `periodRule` 第 N 段折算。设计稿卡片标题是「第2期·进度款 比例30%」⇒ 标题 = 期次名 + 比例。
* 缺失/非法时为空串,模板据此不渲染「比例」片段。</p>
*/
periodRatio?: string
billNo: string
amount: number
status: '待支付' | '已支付' | '未到期'
@@ -337,6 +352,39 @@ export interface RequirementMember {
isOwner: boolean | null
}
/**
* 账单(后端 `Bill`,表 `vm_bill`)—— 「合同财务」页签卡片的**数据源**。
*
* <p>设计稿卡片上的字段(「账单号」+ 已支付/待支付/未到期)只有这张表才有;
* 且 `id` 直接就是收银台 `?ids=` 要传的**账单 id**(不是付款计划 id)。</p>
*/
export interface RequirementBill {
id: string
billNo: string | null
projectId: string | null
projectNo: string | null
projectName: string | null
userId: string | null
/** ⚠️ BigDecimal ⇒ 后端以**字符串**下发("24000.00"),用前必须 `Number()` 归一 */
amount: string | number | null
contractId: string | null
/** ADVANCE / PROGRESS / FINAL / OTHER */
billType: string | null
/** 期次名,如「第2期·进度款」 */
periodName: string | null
/** 占项目总额比例(%),如 40.00 */
periodRatio: string | number | null
/** UNSTARTED / PENDING / PAID / CANCELLED */
status: string | null
payChannel: string | null
transactionNo: string | null
tradeName: string | null
payTime: string | null
dueDate: string | null
/** 创建时间(继承 BaseEntity,后端会下发) */
createTime?: string | null
}
/** 付款计划(后端 `BillPlan`,表 `vm_bill_plan`) */
export interface RequirementBillPlan {
id: string
@@ -350,6 +398,21 @@ export interface RequirementBillPlan {
periodRule: string | null
nextDate: string | null
status: string | null
/**
* 该期支付单的商户订单号(`vm_finance_payment.out_trade_no`)——
* **页面「账单号」就显示它**;未支付(该期还没下过单)时为 null。
*/
orderNo: string | null
/** 支付成功回写的交易流水号(`vm_finance_payment.transaction_no`);未支付为 null */
transactionNo: string | null
/** 支付通道:WECHAT/ALIPAY/...;未支付为 null */
payChannel: string | null
/** 该期实付金额(元);未支付为 null */
payAmount: string | number | null
/** 支付单状态:CREATED/SUCCESS/FAILED/REFUNDED;未支付为 null */
payStatus: string | null
/** 支付时间;未支付为 null */
payTime: string | null
}
/** 发票(后端 `Invoice`,表 `vm_invoice`) */
@@ -456,8 +519,17 @@ export interface RequirementFilesVo extends RequirementBaseVo {
requirementAttachments: RequirementAttachment[]
}
/** 「合同财务」页签(后端 `ProjectRequirementFinanceVo`):基础信息 + 付款计划 + 发票 + 合同 */
/**
* 「合同财务」页签(后端 `ProjectRequirementFinanceVo`):基础信息 + 账单 + 付款计划 + 发票 + 合同。
*
* <p><b>卡片优先用 `bills`</b>(真账单:账单号 / 本期金额 / 真状态 / 可支付 id)。
* 该字段**只在含「账单下发」改动的后端构建里才有**——运行态若是旧构建,响应里根本没有
* 这个 key,所以声明成可选,由 `utils/projectVo.ts` 判别后回落到 `billPlans`(只读卡片)。</p>
*/
export interface RequirementFinanceVo extends RequirementBaseVo {
/** 真账单(`vm_bill`);**旧构建不下发该字段(undefined)**,新构建即使无账单也会给空数组 */
bills?: RequirementBill[]
/** 付款计划(`vm_bill_plan`):分期规则,作为 `bills` 缺失时的只读回落 */
billPlans: RequirementBillPlan[]
invoices: RequirementInvoice[]
contracts: RequirementContract[]