-
-
全部账单
- {actionable.length > 1 && (
-
- )}
-
+
+
全部账单
{bills.map((b) => {
const id = String(b.id);
- const selectable = canConfirm(b.status);
+ const active = bill && String(bill.id) === id;
return (
-
navigate(`/center/bills?id=${id}`)}
>
- {selectable ? (
-
toggleSelect(id)}
- style={{ marginTop: 4 }}
- />
- ) : (
-
- )}
-
);
})}
)}
-
- {showApplyForm && (
- <>
-
-
info
-
- 确认后账单变为「未打款」,由总部完成打款。如有异议请先联系城市运营经理。
-
-
-
-
- >
- )}
);
}
diff --git a/apps/h5-partner/src/pages/CenterPage.tsx b/apps/h5-partner/src/pages/CenterPage.tsx
index cead5e3..7d96cad 100644
--- a/apps/h5-partner/src/pages/CenterPage.tsx
+++ b/apps/h5-partner/src/pages/CenterPage.tsx
@@ -62,19 +62,14 @@ export default function CenterPage({ variant = 'primary', roleLabel }: CenterPag
}, [loadCenter]);
const finance = useMemo(() => {
- const pending = bills.filter((b) => b.status === 'AWAITING_CONFIRM');
+ const unpaid = bills.filter((b) => b.status === 'UNPAID');
const settled = bills.filter((b) => b.status === 'PAID');
- const paidCount = settled.length;
- const rejectedCount = bills.filter((b) => b.status === 'REJECTED').length;
return {
- pendingBillCount: pending.length,
- rejectedCount,
- pendingTotal: bills
- .filter((b) => b.status === 'AWAITING_CONFIRM' || b.status === 'UNPAID' || b.status === 'REJECTED')
- .reduce((s, b) => s + Number(b.totalAmount || 0), 0),
+ unpaidCount: unpaid.length,
+ pendingTotal: unpaid.reduce((s, b) => s + Number(b.totalAmount || 0), 0),
settledTotal: settled.reduce((s, b) => s + Number(b.totalAmount || 0), 0),
balance: settled.reduce((s, b) => s + Number(b.totalAmount || 0), 0),
- paidCount,
+ paidCount: settled.length,
};
}, [bills]);
@@ -167,20 +162,16 @@ export default function CenterPage({ variant = 'primary', roleLabel }: CenterPag
- {finance.pendingBillCount > 0 && (
+ {finance.unpaidCount > 0 && (
receipt_long
-
- {finance.rejectedCount > 0 ? '待处理账单' : '待确认账单'}
-
+
待打款账单
- {finance.rejectedCount > 0
- ? `您有 ${finance.pendingBillCount} 笔账单待处理(含 ${finance.rejectedCount} 笔已驳回)`
- : `您有 ${finance.pendingBillCount} 笔账单待确认`}
+ 您有 {finance.unpaidCount} 笔账单待财务打款
diff --git a/apps/h5-partner/src/pages/SettlementPage.tsx b/apps/h5-partner/src/pages/SettlementPage.tsx
index 3736726..bc23384 100644
--- a/apps/h5-partner/src/pages/SettlementPage.tsx
+++ b/apps/h5-partner/src/pages/SettlementPage.tsx
@@ -6,7 +6,7 @@ import type { PartnerBillDto, PartnerSettlementPreviewDto } from '@dukang/shared
import { isLoggedIn, request } from '../lib/api';
import { formatBillPeriod, formatIssueLabel } from '../lib/settlement';
-type StatusFilter = 'all' | 'pending' | 'settled' | 'reviewing' | 'rejected';
+type StatusFilter = 'all' | 'unpaid' | 'paid';
function fmtMoney(n: number) {
return n.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
@@ -14,20 +14,16 @@ function fmtMoney(n: number) {
function billStatusLabel(status: string) {
switch (status) {
- case 'AWAITING_CONFIRM': return '待确认';
case 'UNPAID': return '未打款';
case 'PAID': return '已打款';
- case 'REJECTED': return '已驳回';
default: return status;
}
}
function billStatusClass(status: string) {
switch (status) {
- case 'AWAITING_CONFIRM': return 'partner-settlement-status--pending';
case 'UNPAID': return 'partner-settlement-status--reviewing';
case 'PAID': return 'partner-settlement-status--settled';
- case 'REJECTED': return 'partner-settlement-status--rejected';
default: return '';
}
}
@@ -57,10 +53,10 @@ export default function SettlementPage() {
}, [navigate, loadBills]);
const summary = useMemo(() => {
- const pending = bills.filter((b) => b.status === 'AWAITING_CONFIRM');
+ const unpaid = bills.filter((b) => b.status === 'UNPAID');
const settled = bills.filter((b) => b.status === 'PAID');
return {
- pendingTotal: pending.reduce((s, b) => s + Number(b.totalAmount || 0), 0),
+ pendingTotal: unpaid.reduce((s, b) => s + Number(b.totalAmount || 0), 0),
settledTotal: settled.reduce((s, b) => s + Number(b.totalAmount || 0), 0),
};
}, [bills]);
@@ -68,10 +64,8 @@ export default function SettlementPage() {
const filteredBills = useMemo(() => {
return bills.filter((b) => {
if (statusFilter === 'all') return true;
- if (statusFilter === 'pending') return b.status === 'AWAITING_CONFIRM';
- if (statusFilter === 'settled') return b.status === 'PAID';
- if (statusFilter === 'reviewing') return b.status === 'UNPAID';
- if (statusFilter === 'rejected') return b.status === 'REJECTED';
+ if (statusFilter === 'unpaid') return b.status === 'UNPAID';
+ if (statusFilter === 'paid') return b.status === 'PAID';
return true;
});
}, [bills, statusFilter]);
@@ -82,10 +76,8 @@ export default function SettlementPage() {
const statusTabs: Array<{ key: StatusFilter; label: string }> = [
{ key: 'all', label: '全部' },
- { key: 'pending', label: '待确认' },
- { key: 'reviewing', label: '未打款' },
- { key: 'rejected', label: '已驳回' },
- { key: 'settled', label: '已打款' },
+ { key: 'unpaid', label: '未打款' },
+ { key: 'paid', label: '已打款' },
];
return (
@@ -164,12 +156,7 @@ export default function SettlementPage() {
订单分佣 ¥{fmtMoney(Number(bill.orderCommission || 0))}
- {bill.status === 'REJECTED' && bill.rejectReason ? (
-
- 驳回:{bill.rejectReason}
-
- ) : null}
-
+
¥{fmtMoney(Number(bill.totalAmount || 0))}
diff --git a/docs/杜康好客-v3编码手册.md b/docs/杜康好客-v3编码手册.md
index 6135a91..d6b81cd 100644
--- a/docs/杜康好客-v3编码手册.md
+++ b/docs/杜康好客-v3编码手册.md
@@ -72,14 +72,14 @@ C 端购酒核销 · 门店扫码核销+打款 · 合伙人拓店履约 · WebAd
**推广码渠道负责人 / 关联合伙人(v4.0.20)**:规则见 v4-PRD §2.1 与 [`v4.0.20 开发文档`](./杜康好客-v4.0.20-开发文档.md)。表 `promo_code_channel_owner`(多对多主合伙人)+ `common_promo_code.assoc_partner_account_id`。HQ `POST/PUT /admin/promo-codes` 字段 `channelOwnerPartnerIds`、`assocPartnerAccountId`(须主账号 ACTIVE)。`POST /promo/touch` 登录后对关联合伙人 `PartnerCityService.tryBindIfUnbound`(已绑他人静默跳过,不回刷历史;Promo 不 import StoreModule)。合伙人主账号 `GET /partner/promo-codes` 仅返回 `scanCount` / `attributionCount` / `orderCount`(已完成订单),禁止用户/事件/订单明细。H5 入口:合伙人中心 → 运营管理 → 推广码数据。验收:只配渠道负责人不绑用户;只配关联合伙人会进「关联用户」且能看三项汇总;已关联他人扫码流程不中断。
-**合伙人周结算(v4.0.9)**:每周一 08:00 生成上一自然周账单。`GET /partner/settlement/cycle` 账期与出账日;`GET /partner/settlement/preview` 本周一至今预付款预估。零元账单 HQ 可见待审核、不可发送、合伙人端不可见。历史月账不回刷。
+**合伙人周结算(v4.0.9,同步规则已改)**:每周一 08:00 生成上一自然周账单。应付大于 0 即「未打款」并同步合伙人端,无发送/确认/驳回。财务 `POST /admin/partner-bills/:id/mark-paid`(及 batch)标记已打款,body 可带 `paymentRef`、`paymentProofUrls`。已打款不可重算。`GET /partner/settlement/cycle` 账期与出账日;`GET /partner/settlement/preview` 本周一至今预付款预估。零元账单 HQ 可见待审核、合伙人端不可见。历史月账不回刷。
## 5. 验收用例(必过)
**主链路 15 项**:登录、4 SKU、起购、支付+权益、双通道核销、payout、关店不可见、拓店审核、配送完成、退款、T+1/T+30…
**后台 8 项**:商品/门店/订单/权益/核销/工单/日志/财务。
**开发计划任务**:状态 `TODO` 待开发 / `IN_PROGRESS` 开发中 / `DEVELOPED` 已开发 / `RELEASED` 已上线 / `STOPPED` 已停止;版本状态含 `STOPPED` 已停止,关联任务随版本同步(仅当全部关联版本已停止时任务才为已停止)。任务列表「来源工单」链到 `/tickets/support?id=`。
-**财务账单日**:出账当天北京日历日(门店/酒厂 `billDate`;物流账期按北京自然月;合伙人周账按北京自然周,周一 08:00 出上周)。禁止 `toISOString().slice(0,10)` 或服务器本地 `Date` 午夜当账单日。酒厂应付为 0 仍出账(展示无需打款)。合伙人零元账单不同步给合伙人端。
+**财务账单日**:出账当天北京日历日(门店/酒厂 `billDate`;物流账期按北京自然月;合伙人周账按北京自然周,周一 08:00 出上周)。禁止 `toISOString().slice(0,10)` 或服务器本地 `Date` 午夜当账单日。酒厂应付为 0 仍出账(展示无需打款)。合伙人应付大于 0 的账单生成即同步;零元账单不同步给合伙人端。财务打款上传凭证后合伙人可见状态与凭证。
## 6. 技术债(摘要)
diff --git a/docs/杜康好客-v4-PRD.md b/docs/杜康好客-v4-PRD.md
index 2e74fb7..357b757 100644
--- a/docs/杜康好客-v4-PRD.md
+++ b/docs/杜康好客-v4-PRD.md
@@ -84,9 +84,11 @@
| 酒订单 | 账期内已付且 `partner_account_id_at_pay` = 本主合伙人 | 实付 × 支付快照费率 |
| 核销订单 | 账期内名下门店核销 | 核销额 × 出账时核销费率 |
-HQ 财务详情与合伙人确认页均展示两段列表。不再「无快照则全城已付单 × 当前费率」。
+HQ 财务详情与合伙人账单页均展示两段列表。不再「无快照则全城已付单 × 当前费率」。
-- **零元账单**:佣金合计为 0 时 HQ 仍可生成并留在待审核,**不得发送**给合伙人;合伙人端列表/详情不可见。
+- **同步**:应付大于 0 的账单生成后即为「未打款」,直接出现在合伙人端。无总部发送、无合伙人确认、无驳回。
+- **打款**:财务打款后在总部标记已打款,可填凭证号并上传打款凭证照片。合伙人可查看状态与凭证。已打款不可重算;未打款可重算。
+- **零元账单**:佣金合计为 0 时 HQ 仍可生成并留在待审核,不同步给合伙人;合伙人端列表/详情不可见。
- 合伙人 H5 展示当前账期(本周一~本周日)与下次出账时间(下周一 08:00,若尚未过本周一 08:00 则为当日 08:00)。
- **预付款**:当前未出账周期(本周一 00:00 至今)酒单 + 核销按佣金比例算出的预估合计。展示在首页与合伙人中心。与实际打款无关,实际以账单为准。
- 上线前已生成的月账保留,不回刷。
diff --git a/docs/杜康好客-v4-现状对照.md b/docs/杜康好客-v4-现状对照.md
index d60f32c..e829c2c 100644
--- a/docs/杜康好客-v4-现状对照.md
+++ b/docs/杜康好客-v4-现状对照.md
@@ -9,7 +9,7 @@
|------|------|
| 版本线 | **v4.0.21** 接口访问(含 v4.0.20 推广码渠道负责人 + 关联合伙人) |
| 订单佣金 | 区县归属已删除;只认关联 / 代下单选择 |
-| 账单 | 酒订单 / 核销订单分列;合伙人改为周账(周一 08:00);零元不同步合伙人;酒厂含现场提货,零应付仍出账(无需打款) |
+| 账单 | 酒订单 / 核销订单分列;合伙人周账(周一 08:00)生成后应付大于 0 直接同步(未打款),财务打款并上传凭证;零元不同步;酒厂含现场提货,零应付仍出账(无需打款) |
| 活动图 | HQ 上传底图/码栏/文案;**v4.0.15 上传超限自动压缩并提示尺寸**;合伙人选择写入库;HQ 可指定一张图为勾选主合伙人合成下载;子账号不可看活动图 |
## 1. 版本交付
@@ -47,3 +47,4 @@
| 2026-09-16 | v4.0.20:推广码渠道负责人改为可多选主合伙人(H5 只看扫码/归因/订单数);关联合伙人扫码 first-lock,不回刷、已关联他人静默跳过 |
| 2026-09-17 | v4.0.20:PromoModule 改走 CityScope 避免 Nest 循环依赖;本地 Vite 代理默认 `127.0.0.1:3010` |
| 2026-09-26 | v4.0.21:HQ 接口访问。登录/商品加载/门店加载/门店提交按成功百分比放行;审核通知按百分比丢弃企微;订单/核销/账单/门店审核/套餐修改只做通知总开关。总部登录不参与 |
+| 2026-09-26 | 合伙人账单:应付大于 0 生成即同步合伙人端;去掉总部发送、合伙人确认与驳回;财务标记已打款并上传凭证,合伙人可见状态与凭证 |
diff --git a/packages/shared-types/src/settlement.ts b/packages/shared-types/src/settlement.ts
index fb3b146..910dc64 100644
--- a/packages/shared-types/src/settlement.ts
+++ b/packages/shared-types/src/settlement.ts
@@ -146,9 +146,11 @@ export type PartnerBillStatus =
export const PARTNER_BILL_STATUS_LABELS: Record