From c404c168fef35b7ca20d204a39b9645b81f064e4 Mon Sep 17 00:00:00 2001 From: zlwu <704541015@qq.com> Date: Sat, 3 Oct 2026 11:17:19 +0800 Subject: [PATCH] feat(web-admin): finance confirm by transfer and remove refund confirm tab Co-authored-by: Cursor --- backend/app/api/menu.py | 6 +- backend/app/api/protocol_sample_payment.py | 12 +- backend/app/crud/protocol_sample_payment.py | 46 +++++- web-admin/src/api/protocol-sample-payment.ts | 4 + web-admin/src/router/modules/sqxp.ts | 4 +- .../payment-confirm/RefundConfirmTab.vue | 2 +- .../cell-storage/payment-confirm/index.vue | 140 +++++++++--------- 7 files changed, 133 insertions(+), 81 deletions(-) diff --git a/backend/app/api/menu.py b/backend/app/api/menu.py index 775cdbf2..812879af 100644 --- a/backend/app/api/menu.py +++ b/backend/app/api/menu.py @@ -65,7 +65,7 @@ STATIC_MENU_TREE = [ "name": "CellStoragePaymentConfirm", "path": "payment-confirm", "component": "/cell-storage/payment-confirm/index", - "meta": {"title": "缴退费财务确认及开票", "keepAlive": True, "menuCode": "biz:cellStoragePaymentConfirm:list"}, + "meta": {"title": "缴费财务确认及开票", "keepAlive": True, "menuCode": "biz:cellStoragePaymentConfirm:list"}, }, # 市场侧入库放行审核(总览)暂下线:改由生产/质检入口审核 # { @@ -149,7 +149,7 @@ STATIC_MENU_TREE = [ "name": "BasicInfoInsuranceCompany", "path": "insurance-company", "component": "/basic-info/insurance-company/index", - "meta": {"title": "保险公司及险种价格", "keepAlive": True, "menuCode": "basic-info:insurance-company:list"}, + "meta": {"title": "保险公司及险种价格", "keepAlive": True, "isHide": True, "menuCode": "basic-info:insurance-company:list"}, }, { @@ -193,7 +193,7 @@ STATIC_MENU_TREE = [ "name": "CheckupInstitution", "path": "checkup-institution", "component": "/pilot-service/checkup-institution/index", - "meta": {"title": "体检机构及项目价格", "keepAlive": True, "menuCode": "pilot-service:checkup-institution:list"}, + "meta": {"title": "体检机构及项目价格", "keepAlive": True, "isHide": True, "menuCode": "pilot-service:checkup-institution:list"}, }, { diff --git a/backend/app/api/protocol_sample_payment.py b/backend/app/api/protocol_sample_payment.py index c0b7c0d6..6d739938 100644 --- a/backend/app/api/protocol_sample_payment.py +++ b/backend/app/api/protocol_sample_payment.py @@ -334,8 +334,10 @@ async def submit_payment_transfer_finance( @router.get("/payment-transfers/receipt-confirm") async def list_receipt_confirm( page: int = Query(1, ge=1), - page_size: int = Query(10, ge=1, le=100), + page_size: int = Query(10, ge=1, le=100, alias="pageSize"), keyword: Optional[str] = None, + installmentDueDateStart: Optional[str] = Query(None, alias="installmentDueDateStart"), + installmentDueDateEnd: Optional[str] = Query(None, alias="installmentDueDateEnd"), user: dict = Depends(require_admin_or_super_admin), db: Session = Depends(get_db), ): @@ -349,6 +351,8 @@ async def list_receipt_confirm( page=page, page_size=page_size, user_info=user, + due_date_start=installmentDueDateStart, + due_date_end=installmentDueDateEnd, ) return success_response({"list": items, "total": total, "page": page, "pageSize": page_size}) except PermissionError as e: @@ -358,8 +362,10 @@ async def list_receipt_confirm( @router.get("/payment-transfers/receipt-confirmed") async def list_receipt_confirmed( page: int = Query(1, ge=1), - page_size: int = Query(10, ge=1, le=100), + page_size: int = Query(10, ge=1, le=100, alias="pageSize"), keyword: Optional[str] = None, + installmentDueDateStart: Optional[str] = Query(None, alias="installmentDueDateStart"), + installmentDueDateEnd: Optional[str] = Query(None, alias="installmentDueDateEnd"), user: dict = Depends(require_admin_or_super_admin), db: Session = Depends(get_db), ): @@ -373,6 +379,8 @@ async def list_receipt_confirmed( page=page, page_size=page_size, user_info=user, + due_date_start=installmentDueDateStart, + due_date_end=installmentDueDateEnd, ) return success_response({"list": items, "total": total, "page": page, "pageSize": page_size}) except PermissionError as e: diff --git a/backend/app/crud/protocol_sample_payment.py b/backend/app/crud/protocol_sample_payment.py index 3f2def2d..522a6871 100644 --- a/backend/app/crud/protocol_sample_payment.py +++ b/backend/app/crud/protocol_sample_payment.py @@ -829,12 +829,20 @@ def list_transfers_for_finance( page: int = 1, page_size: int = 10, user_info=None, + due_date_start: Optional[str] = None, + due_date_end: Optional[str] = None, ) -> Tuple[List[Dict[str, Any]], int]: if not tenant_no: return [], 0 st = (pay_status or "").strip() q = ( - db.query(BizProtocolPaymentTransfer, BizCollectionProtocol, BizProtocolPartyCustomer) + db.query( + BizProtocolPaymentTransfer, + BizCollectionProtocol, + BizProtocolPartyCustomer, + BizProtocolPaymentSchedule, + BizProtocolSamplePayment, + ) .join( BizCollectionProtocol, and_( @@ -852,6 +860,21 @@ def list_transfers_for_finance( BizProtocolPartyCustomer.del_flag == 0, ), ) + .outerjoin( + BizProtocolPaymentSchedule, + and_( + BizProtocolPaymentSchedule.id == BizProtocolPaymentTransfer.schedule_id, + BizProtocolPaymentSchedule.del_flag == 0, + ), + ) + .outerjoin( + BizProtocolSamplePayment, + and_( + BizProtocolSamplePayment.id + == BizProtocolPaymentTransfer.sample_payment_id, + BizProtocolSamplePayment.del_flag == 0, + ), + ) .filter( BizProtocolPaymentTransfer.tenant_no == tenant_no, BizProtocolPaymentTransfer.del_flag == 0, @@ -867,8 +890,16 @@ def list_transfers_for_finance( BizProtocolPaymentTransfer.sample_code.like(like), BizProtocolPartyCustomer.mother_name.like(like), BizProtocolPartyCustomer.mother_id_card.like(like), + BizProtocolPartyCustomer.newborn_name.like(like), + BizProtocolPartyCustomer.newborn_id_card.like(like), ) ) + ds = (due_date_start or "").strip().replace("-", "")[:8] + de = (due_date_end or "").strip().replace("-", "")[:8] + if ds: + q = q.filter(BizProtocolPaymentSchedule.due_date >= ds) + if de: + q = q.filter(BizProtocolPaymentSchedule.due_date <= de) if user_info: from app.core.data_scope import apply_data_scope @@ -885,9 +916,20 @@ def list_transfers_for_finance( .all() ) out: List[Dict[str, Any]] = [] - for t, proto, party in rows: + for t, proto, party, sch, sp in rows: item = _transfer_to_dict(db, t, tenant_no) item["protocolNo"] = (proto.protocol_no if proto else "") or "" + item["protocolStatus"] = (proto.protocol_status if proto else "") or "" + item["voidType"] = (proto.void_type if proto else "") or "" item["motherName"] = (party.mother_name if party else "") or "" + item["motherIdCard"] = (party.mother_id_card if party else "") or "" + item["newbornName"] = (party.newborn_name if party else "") or "" + item["newbornIdCard"] = (party.newborn_id_card if party else "") or "" + item["installmentNo"] = sch.schedule_no if sch else None + item["installmentDueDate"] = (sch.due_date if sch else "") or "" + item["dueAmount"] = ( + float(sch.due_amount) if sch and sch.due_amount is not None else None + ) + item["payMode"] = (sp.pay_mode if sp else "") or "" out.append(item) return out, int(total) diff --git a/web-admin/src/api/protocol-sample-payment.ts b/web-admin/src/api/protocol-sample-payment.ts index e9270d9b..50543e1f 100644 --- a/web-admin/src/api/protocol-sample-payment.ts +++ b/web-admin/src/api/protocol-sample-payment.ts @@ -52,6 +52,8 @@ export function fetchPaymentTransferReceiptConfirmList(params?: { page?: number pageSize?: number keyword?: string + installmentDueDateStart?: string + installmentDueDateEnd?: string }) { return request.get>>({ url: '/web/admin/payment-transfers/receipt-confirm', @@ -63,6 +65,8 @@ export function fetchPaymentTransferReceiptConfirmedList(params?: { page?: number pageSize?: number keyword?: string + installmentDueDateStart?: string + installmentDueDateEnd?: string }) { return request.get>>({ url: '/web/admin/payment-transfers/receipt-confirmed', diff --git a/web-admin/src/router/modules/sqxp.ts b/web-admin/src/router/modules/sqxp.ts index 82f40fea..e26a5268 100644 --- a/web-admin/src/router/modules/sqxp.ts +++ b/web-admin/src/router/modules/sqxp.ts @@ -89,7 +89,7 @@ export const sqxpAdminRoutes: AppRouteRecord[] = [ path: 'payment-confirm', component: '/cell-storage/payment-confirm/index', meta: { - title: '缴退费财务确认及开票', + title: '缴费财务确认及开票', keepAlive: true, menuCode: 'biz:cellStoragePaymentConfirm:list' } @@ -290,6 +290,7 @@ export const sqxpAdminRoutes: AppRouteRecord[] = [ meta: { title: '保险公司及险种价格', keepAlive: true, + isHide: true, menuCode: 'basic-info:insurance-company:list' } }, @@ -398,6 +399,7 @@ export const sqxpAdminRoutes: AppRouteRecord[] = [ meta: { title: '体检机构及项目价格', keepAlive: true, + isHide: true, menuCode: 'pilot-service:checkup-institution:list' } }, diff --git a/web-admin/src/views/cell-storage/payment-confirm/RefundConfirmTab.vue b/web-admin/src/views/cell-storage/payment-confirm/RefundConfirmTab.vue index 49099008..33455c5d 100644 --- a/web-admin/src/views/cell-storage/payment-confirm/RefundConfirmTab.vue +++ b/web-admin/src/views/cell-storage/payment-confirm/RefundConfirmTab.vue @@ -1,4 +1,4 @@ - + @@ -378,9 +391,10 @@ label="确认时间" min-width="170" align="center" - header-align="center"> - - + header-align="center" + > + + 取消 - + 退回 @@ -503,7 +513,6 @@ - @@ -514,14 +523,13 @@ import { ref, reactive, onMounted } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' import { Close, Check, RefreshLeft, Search, View } from '@element-plus/icons-vue' + import { fetchProtocolInvoicePendingCount } from '@/api/collection-protocol' import { - fetchReceiptConfirmList, - fetchReceiptConfirmedList, - fetchReceiptConfirmSubmit, - fetchReceiptConfirmReject, - fetchRefundConfirmList, - fetchProtocolInvoicePendingCount - } from '@/api/collection-protocol' + fetchPaymentTransferReceiptConfirmList, + fetchPaymentTransferReceiptConfirmedList, + fetchConfirmPaymentTransfer, + fetchRejectPaymentTransfer + } from '@/api/protocol-sample-payment' import ProtocolFinanceConfirmFields from '@/components/business/protocol-finance-confirm-fields/index.vue' import ClinicalPaymentConfirmTimeline from '@/components/business/clinical-payment-confirm-timeline/index.vue' import { @@ -533,14 +541,12 @@ import { formatPaymentDueDate, payModeLabel, - protocolStatusLabel, protocolStatusDisplayLabel, protocolStatusTagType, loadTransferTypeDict, transferTypeLabel } from '@/utils/protocol-payment-labels' import { formatMoneyDisplay } from '@/utils/money-format' - import RefundConfirmTab from './RefundConfirmTab.vue' import InvoiceRequestTab from './InvoiceRequestTab.vue' defineOptions({ name: 'CellStoragePaymentConfirm' }) @@ -548,14 +554,12 @@ const route = useRoute() const mainTab = ref('payment') const paymentPendingBadge = ref(0) - const refundPendingBadge = ref(0) const invoicePendingBadge = ref(0) function formatTabBadgeCount(count: number): string { return count > 99 ? '99+' : String(count) } - function formatPaymentAmount(v: unknown): string { if (v == null || v === '') return '-' return '¥' + formatMoneyDisplay(v) @@ -591,12 +595,6 @@ return minioBaseUrl ? `${minioBaseUrl}/${url.replace(/^\//, '')}` : url } - function handleAttachmentPreview(file: Record) { - const url = String(file.fileUrl || '') - if (!url) return - window.open(fullFileUrl(url), '_blank') - } - function handleAttachmentDownload(file: Record) { downloadAttachmentFile(file, { fullFileUrl }) } @@ -623,13 +621,11 @@ async function loadTabPendingCounts() { try { - const [paymentRes, refundRes, invRes] = await Promise.all([ - fetchReceiptConfirmList({ page: 1, pageSize: 1 }), - fetchRefundConfirmList({ page: 1, pageSize: 1 }), + const [paymentRes, invRes] = await Promise.all([ + fetchPaymentTransferReceiptConfirmList({ page: 1, pageSize: 1 }), fetchProtocolInvoicePendingCount() ]) paymentPendingBadge.value = paymentRes.total ?? 0 - refundPendingBadge.value = refundRes.total ?? 0 invoicePendingBadge.value = Number(invRes?.count ?? 0) } catch { // 角标加载失败时保留上次数值,避免干扰主流程 @@ -639,7 +635,7 @@ async function loadPending() { pendingLoading.value = true try { - const res = await fetchReceiptConfirmList(buildPendingParams()) + const res = await fetchPaymentTransferReceiptConfirmList(buildPendingParams()) pendingData.value = res.list || [] pendingPagination.total = res.total ?? 0 } finally { @@ -650,7 +646,7 @@ async function loadConfirmed() { confirmedLoading.value = true try { - const res = await fetchReceiptConfirmedList(buildConfirmedParams()) + const res = await fetchPaymentTransferReceiptConfirmedList(buildConfirmedParams()) confirmedData.value = res.list || [] confirmedPagination.total = res.total ?? 0 } finally { @@ -707,7 +703,7 @@ } submitLoading.value = true try { - await fetchReceiptConfirmSubmit(currentDetailId.value, { + await fetchConfirmPaymentTransfer(currentDetailId.value, { financeConfirmAttachments: financeAttachmentsToUrlString(attachments.value) || undefined, financeRemark: financeRemark.value.trim() || undefined }) @@ -730,7 +726,7 @@ } rejectLoading.value = true try { - await fetchReceiptConfirmReject(currentDetailId.value) + await fetchRejectPaymentTransfer(currentDetailId.value) dialogVisible.value = false await loadAll() await loadTabPendingCounts() @@ -760,10 +756,10 @@ onMounted(async () => { await loadTransferTypeDict() const tab = route.query.tab - if (tab === 'refund') { - mainTab.value = 'refund' - } else if (tab === 'invoice') { + if (tab === 'invoice') { mainTab.value = 'invoice' + } else { + mainTab.value = 'payment' } loadTabPendingCounts() if (mainTab.value === 'payment') {