fix: 代理
This commit is contained in:
@@ -47,6 +47,11 @@ export interface AgentRecharge {
|
||||
recharge_source?: AgentRechargeSource | null
|
||||
recharge_source_name?: string | null
|
||||
payment_voucher_key?: string[] | string // 凭证附件列表;历史数据可能为单字符串或逗号字符串
|
||||
external_transaction_no?: string | null // 线下人工申报的交易流水号,与在线 payment_transaction_id 互不覆盖
|
||||
offline_payment_method_id?: number | null // 线下收款方式字典ID,仅线下充值有值
|
||||
offline_payment_method_code?: string | null // 线下收款方式稳定编码快照
|
||||
offline_payment_method_name?: string | null // 线下收款方式名称快照
|
||||
other_voucher_key?: string[] | null // 其他凭证对象存储Key列表,仅线下充值有值
|
||||
rejection_reason?: string | null // 拒绝原因
|
||||
remark?: string // 运营备注
|
||||
submitter_name?: string | null // 提交人名称
|
||||
@@ -98,6 +103,9 @@ export interface CreateAgentRechargeOfflineRequest {
|
||||
payment_method: 'offline'
|
||||
shop_id: number
|
||||
payment_voucher_key: string[] // 线下支付凭证附件列表(payment_method=offline 时必填)
|
||||
offline_payment_method_id: number // 线下收款方式字典ID,取自收款方式字典启用项
|
||||
external_transaction_no: string // 线下交易流水号,OCR 预填后人工确认
|
||||
other_voucher_key?: string[] // 其他凭证对象存储Key列表,最多 5 个
|
||||
remark?: string // 运营备注,最多 1000 字
|
||||
}
|
||||
|
||||
@@ -112,6 +120,19 @@ export interface AgentRechargePaymentMethods {
|
||||
max_amount: number
|
||||
}
|
||||
|
||||
// 代理自充可用支付方式和金额范围(GET /api/admin/agent-self-recharge-payment-methods)
|
||||
export type AgentSelfRechargePaymentMethods = AgentRechargePaymentMethods
|
||||
|
||||
// 识别付款凭证中的交易流水号请求
|
||||
export interface AgentRechargePaymentVoucherOcrRequest {
|
||||
payment_voucher_key: string // 付款凭证对象存储Key,必须指向已上传的图片类型附件
|
||||
}
|
||||
|
||||
// 识别付款凭证中的交易流水号响应(只返回交易流水号预填值)
|
||||
export interface AgentRechargePaymentVoucherOcrResponse {
|
||||
external_transaction_no: string
|
||||
}
|
||||
|
||||
// 在线充值支付及钱包到账状态
|
||||
export interface AgentRechargePaymentStatusResponse {
|
||||
recharge_id: number
|
||||
|
||||
302
src/types/api/employeeCollection.ts
Normal file
302
src/types/api/employeeCollection.ts
Normal file
@@ -0,0 +1,302 @@
|
||||
/**
|
||||
* 员工代收款相关类型定义
|
||||
*
|
||||
* 依据后端 OpenAPI(员工代收款分组):
|
||||
* - 列表响应为 { items, page, size, total }
|
||||
* - 账单状态与申请状态均为数字枚举
|
||||
* - 金额单位为「分」,附件字段为对象存储 Key 数组
|
||||
*/
|
||||
|
||||
import type { BaseResponse, PaginationParams } from './common'
|
||||
|
||||
// ========== 收款方式字典 ==========
|
||||
|
||||
export interface EmployeeCollectionPaymentMethod {
|
||||
id: number
|
||||
code: string
|
||||
name: string
|
||||
sort: number
|
||||
enabled: boolean
|
||||
remark?: string | null
|
||||
created_at?: string | null
|
||||
updated_at?: string | null
|
||||
}
|
||||
|
||||
/** 收款方式列表查询参数,后端返回 { items, page, size, total } */
|
||||
export interface EmployeeCollectionPaymentMethodQueryParams {
|
||||
page?: number
|
||||
page_size?: number
|
||||
enabled?: boolean
|
||||
keyword?: string
|
||||
}
|
||||
|
||||
export interface CreateEmployeeCollectionPaymentMethodRequest {
|
||||
code: string
|
||||
name: string
|
||||
sort?: number
|
||||
enabled?: boolean
|
||||
remark?: string
|
||||
}
|
||||
|
||||
export interface UpdateEmployeeCollectionPaymentMethodRequest {
|
||||
code?: string
|
||||
name?: string
|
||||
sort?: number
|
||||
enabled?: boolean
|
||||
remark?: string
|
||||
}
|
||||
|
||||
// ========== 通用列表结构 ==========
|
||||
|
||||
/** 后端列表统一返回 { items, page, size, total } */
|
||||
export interface EmployeeCollectionListData<T> {
|
||||
items?: T[] | null
|
||||
list?: T[] | null
|
||||
total?: number
|
||||
page?: number
|
||||
size?: number
|
||||
page_size?: number
|
||||
}
|
||||
|
||||
// ========== 员工代收款账单 ==========
|
||||
|
||||
/** 账单状态:0 待核销 / 1 部分核销 / 2 已核销 / 3 已关闭 */
|
||||
export type EmployeeCollectionBillStatus = number
|
||||
|
||||
/** 账单责任人(员工)快照 */
|
||||
export interface EmployeeCollectionDebtorSnapshot {
|
||||
account_id?: number | null
|
||||
account_name?: string | null
|
||||
account_type?: string | null
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
/** 账单客户 / 店铺快照 */
|
||||
export interface EmployeeCollectionCustomerSnapshot {
|
||||
shop_id?: number | null
|
||||
seller_shop_id?: number | null
|
||||
buyer_id?: number | null
|
||||
buyer_type?: string | null
|
||||
buyer_nickname?: string | null
|
||||
asset_identifier?: string | null
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
export interface EmployeeCollectionBill {
|
||||
id: number
|
||||
source_type?: string | null
|
||||
source_type_name?: string | null
|
||||
source_id?: number | null
|
||||
source_no?: string | null
|
||||
debtor_account_id?: number | null
|
||||
debtor_snapshot?: EmployeeCollectionDebtorSnapshot | null
|
||||
customer_snapshot?: EmployeeCollectionCustomerSnapshot | null
|
||||
receivable_amount?: number | null // 应收金额(分)
|
||||
received_amount?: number | null // 已核销金额(分)
|
||||
reserved_amount?: number | null // 审批中预占金额(分)
|
||||
remaining_amount?: number | null // 未核销金额(分)
|
||||
status: EmployeeCollectionBillStatus
|
||||
status_name?: string | null
|
||||
approval_pending?: boolean // 是否存在审批中的核销申请
|
||||
closed_reason?: string | null
|
||||
closed_at?: string | null
|
||||
created_at?: string | null
|
||||
updated_at?: string | null
|
||||
}
|
||||
|
||||
/** 核销申请详情中的账单分摊 */
|
||||
export interface EmployeeCollectionAllocation {
|
||||
id?: number
|
||||
bill_id: number
|
||||
amount: number // 本次分摊金额(分)
|
||||
status?: number | null // 0 审批中预占 / 1 已通过 / 2 已驳回或已释放
|
||||
status_name?: string | null
|
||||
bill_status?: number | null
|
||||
bill_status_name?: string | null
|
||||
bill_source_type?: string | null
|
||||
bill_source_no?: string | null
|
||||
bill_receivable_amount?: number | null
|
||||
bill_received_amount?: number | null
|
||||
bill_reserved_amount?: number | null
|
||||
created_at?: string | null
|
||||
released_at?: string | null
|
||||
}
|
||||
|
||||
/** 账单详情中的核销分摊(含所属核销申请信息) */
|
||||
export interface EmployeeCollectionBillAllocation {
|
||||
id?: number
|
||||
amount: number
|
||||
application_id?: number | null
|
||||
application_status?: number | null
|
||||
application_status_name?: string | null
|
||||
attempt_id?: number | null
|
||||
status?: number | null
|
||||
status_name?: string | null
|
||||
created_at?: string | null
|
||||
released_at?: string | null
|
||||
}
|
||||
|
||||
/** 来源订单退款冲销关联(账单详情 refunds) */
|
||||
export interface EmployeeCollectionBillRefund {
|
||||
id?: number
|
||||
refund_id?: number
|
||||
source_order_id?: number
|
||||
refund_amount?: number | null // 本次退款成功金额(分)
|
||||
reduced_amount?: number | null // 实际冲减应收金额(分)
|
||||
bill_receivable_amount?: number | null // 冲销前账单应收金额快照(分)
|
||||
outcome?: string | null // closed_full / reduced / hint_only
|
||||
outcome_name?: string | null
|
||||
created_at?: string | null
|
||||
}
|
||||
|
||||
/** 账单详情(接口返回 { bill, refunds, allocations, applications }) */
|
||||
export interface EmployeeCollectionBillDetailData {
|
||||
bill: EmployeeCollectionBill
|
||||
refunds?: EmployeeCollectionBillRefund[] | null
|
||||
allocations?: EmployeeCollectionBillAllocation[] | null
|
||||
applications?: EmployeeCollectionBillApplication[] | null
|
||||
}
|
||||
|
||||
/** 账单统计 */
|
||||
export interface EmployeeCollectionBillStatistics {
|
||||
receivable_total: number // 应收总金额(分)
|
||||
received_total: number // 已收款(已核销)总金额(分)
|
||||
unsettled_total: number // 未结(未核销)总金额(分)
|
||||
pending_bill_count: number // 待处理账单数量
|
||||
}
|
||||
|
||||
export interface EmployeeCollectionBillQueryParams extends PaginationParams {
|
||||
source_type?: string
|
||||
source_no?: string
|
||||
status?: EmployeeCollectionBillStatus
|
||||
debtor_account_id?: number
|
||||
customer_id?: number
|
||||
created_from?: string
|
||||
created_to?: string
|
||||
}
|
||||
|
||||
export interface CloseEmployeeCollectionBillRequest {
|
||||
reason: string
|
||||
}
|
||||
|
||||
export type CloseEmployeeCollectionBillResult = EmployeeCollectionBill
|
||||
|
||||
// ========== 核销申请 ==========
|
||||
|
||||
/** 申请状态:0 审批中 / 1 已通过 / 2 已驳回 / 3 已撤销或已关闭 */
|
||||
export type EmployeeCollectionApplicationStatus = number
|
||||
|
||||
/** 审批尝试记录(历史材料不被覆盖) */
|
||||
export interface EmployeeCollectionApplicationAttempt {
|
||||
id?: number
|
||||
attempt_no?: number
|
||||
approval_instance_id?: number | null
|
||||
approval_status?: number | null // 通用审批实例状态
|
||||
approval_status_name?: string | null
|
||||
approval_opinion?: string | null
|
||||
acting_reason?: string | null
|
||||
external_transaction_no?: string | null
|
||||
paid_amount?: number | null
|
||||
paid_at?: string | null
|
||||
payer_name?: string | null
|
||||
payment_method_id?: number | null
|
||||
payment_method_code?: string | null
|
||||
payment_method_name?: string | null
|
||||
payment_voucher_keys?: string[] | null
|
||||
remark?: string | null
|
||||
submitted_by_account_id?: number | null
|
||||
allocation_snapshot?: Array<Record<string, string>> | null
|
||||
created_at?: string | null
|
||||
}
|
||||
|
||||
export interface EmployeeCollectionApplication {
|
||||
id: number
|
||||
applicant_account_id?: number | null
|
||||
acting_operator_id?: number | null // 0 表示本人办理
|
||||
acting_reason?: string | null
|
||||
payment_method_id?: number | null
|
||||
payment_method_code?: string | null
|
||||
payment_method_name?: string | null
|
||||
paid_amount?: number | null // 人工确认的付款金额(分)
|
||||
paid_at?: string | null
|
||||
payer_name?: string | null
|
||||
external_transaction_no?: string | null
|
||||
payment_voucher_keys?: string[] | null
|
||||
remark?: string | null
|
||||
status: EmployeeCollectionApplicationStatus
|
||||
status_name?: string | null
|
||||
terminal_reason?: string | null
|
||||
decided_at?: string | null
|
||||
latest_approval_instance_id?: number | null
|
||||
latest_attempt_id?: number | null
|
||||
created_at?: string | null
|
||||
updated_at?: string | null
|
||||
}
|
||||
|
||||
/** 账单详情中的核销申请(含该申请的审批尝试记录) */
|
||||
export interface EmployeeCollectionBillApplication extends EmployeeCollectionApplication {
|
||||
attempts?: EmployeeCollectionApplicationAttempt[] | null
|
||||
}
|
||||
|
||||
/** 申请详情(接口返回 { application, allocations, attempts }) */
|
||||
export interface EmployeeCollectionApplicationDetailData {
|
||||
application: EmployeeCollectionApplication
|
||||
allocations?: EmployeeCollectionAllocation[] | null
|
||||
attempts?: EmployeeCollectionApplicationAttempt[] | null
|
||||
}
|
||||
|
||||
export interface EmployeeCollectionApplicationQueryParams extends PaginationParams {
|
||||
status?: EmployeeCollectionApplicationStatus
|
||||
applicant_account_id?: number
|
||||
payment_method_id?: number
|
||||
created_from?: string
|
||||
created_to?: string
|
||||
}
|
||||
|
||||
export interface EmployeeCollectionAllocationRequest {
|
||||
bill_id: number
|
||||
amount: number
|
||||
}
|
||||
|
||||
export interface EmployeeCollectionApplicationRequest {
|
||||
payment_method_id: number
|
||||
paid_amount: number
|
||||
paid_at: string
|
||||
payer_name: string
|
||||
external_transaction_no: string
|
||||
payment_voucher_keys: string[]
|
||||
remark?: string
|
||||
allocations: EmployeeCollectionAllocationRequest[]
|
||||
acting_reason?: string
|
||||
}
|
||||
|
||||
export interface EmployeeCollectionApplicationSubmitResult {
|
||||
allocations?: EmployeeCollectionAllocation[] | null
|
||||
application?: EmployeeCollectionApplication | null
|
||||
approval_instance_id?: number | null
|
||||
approval_status?: number | null
|
||||
approval_status_name?: string | null
|
||||
attempt?: EmployeeCollectionApplicationAttempt | null
|
||||
}
|
||||
|
||||
// ========== 响应类型 ==========
|
||||
|
||||
export type EmployeeCollectionPaymentMethodListResponse = BaseResponse<
|
||||
EmployeeCollectionPaymentMethod[] | EmployeeCollectionListData<EmployeeCollectionPaymentMethod>
|
||||
>
|
||||
export type EmployeeCollectionPaymentMethodResponse = BaseResponse<EmployeeCollectionPaymentMethod>
|
||||
export type DeleteEmployeeCollectionPaymentMethodResponse = BaseResponse<null>
|
||||
export type EmployeeCollectionBillListResponse = BaseResponse<
|
||||
EmployeeCollectionListData<EmployeeCollectionBill>
|
||||
>
|
||||
export type EmployeeCollectionBillResponse = BaseResponse<EmployeeCollectionBillDetailData>
|
||||
export type EmployeeCollectionBillStatisticsResponse =
|
||||
BaseResponse<EmployeeCollectionBillStatistics>
|
||||
export type CloseEmployeeCollectionBillResponse = BaseResponse<CloseEmployeeCollectionBillResult>
|
||||
export type EmployeeCollectionApplicationListResponse = BaseResponse<
|
||||
EmployeeCollectionListData<EmployeeCollectionApplication>
|
||||
>
|
||||
export type EmployeeCollectionApplicationResponse =
|
||||
BaseResponse<EmployeeCollectionApplicationDetailData>
|
||||
export type EmployeeCollectionApplicationSubmitResponse =
|
||||
BaseResponse<EmployeeCollectionApplicationSubmitResult>
|
||||
@@ -135,4 +135,5 @@ export * from './audit'
|
||||
// 企业微信审批配置相关
|
||||
export * from './wecom'
|
||||
|
||||
|
||||
// 员工代收款相关
|
||||
export * from './employeeCollection'
|
||||
|
||||
@@ -45,6 +45,14 @@ export interface PaymentMerchant {
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付商户详情:仅在详情页短暂使用,凭证字段经过脱敏/白名单处理,
|
||||
* 不用于列表、编辑表单或持久化状态。
|
||||
*/
|
||||
export interface PaymentMerchantDetail extends PaymentMerchant {
|
||||
credentials: PaymentCredentials
|
||||
}
|
||||
|
||||
export interface PaymentMerchantQueryParams extends PaginationParams {
|
||||
/** 可选:按名称模糊筛选 */
|
||||
name?: string
|
||||
@@ -132,6 +140,7 @@ export interface UpdateWechatAuthorizationRequest {
|
||||
|
||||
export type PaymentMerchantResponse = BaseResponse<PaymentMerchant>
|
||||
export type PaymentMerchantPageResponse = BaseResponse<PaymentMerchantPageResult>
|
||||
export type PaymentMerchantDetailResponse = BaseResponse<PaymentMerchantDetail>
|
||||
export type PaymentMerchantPoolResponse = BaseResponse<PaymentMerchantPool>
|
||||
export type PaymentMerchantPoolPageResponse = BaseResponse<PaymentMerchantPoolPageResult>
|
||||
export type WechatAuthorizationResponse = BaseResponse<WechatAuthorizationConfig>
|
||||
@@ -205,3 +214,146 @@ export interface PaymentMerchantPoolMemberOption {
|
||||
payment_method: PaymentMerchantMethod
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* 商户凭证字段枚举:必填键由 `payment_method` 与 `provider_type` 组合决定,
|
||||
* 可选键为允许附带但非必须的字段,键名与渠道配置字段一致。
|
||||
*/
|
||||
export interface PaymentCredentialFieldSpec {
|
||||
required: string[]
|
||||
optional: string[]
|
||||
}
|
||||
|
||||
export const PAYMENT_CREDENTIAL_FIELD_SPECS: Record<
|
||||
PaymentMerchantProviderType,
|
||||
PaymentCredentialFieldSpec
|
||||
> = {
|
||||
wechat: {
|
||||
required: [
|
||||
'wx_mch_id',
|
||||
'wx_api_v3_key',
|
||||
'wx_cert_content',
|
||||
'wx_key_content',
|
||||
'wx_serial_no',
|
||||
'wx_notify_url'
|
||||
],
|
||||
optional: ['wx_api_v2_key']
|
||||
},
|
||||
wechat_v2: {
|
||||
required: ['wx_mch_id', 'wx_api_v2_key', 'wx_notify_url'],
|
||||
optional: []
|
||||
},
|
||||
fuiou: {
|
||||
required: [
|
||||
'fy_mchnt_cd',
|
||||
'fy_ins_cd',
|
||||
'fy_term_id',
|
||||
'fy_private_key',
|
||||
'fy_public_key',
|
||||
'fy_api_url',
|
||||
'fy_notify_url'
|
||||
],
|
||||
optional: []
|
||||
},
|
||||
alipay: {
|
||||
required: [
|
||||
'ali_app_id',
|
||||
'ali_private_key',
|
||||
'ali_public_key',
|
||||
'ali_notify_url',
|
||||
'ali_return_url'
|
||||
],
|
||||
optional: ['ali_production', 'ali_pay_expire_minutes']
|
||||
}
|
||||
}
|
||||
|
||||
export function getPaymentCredentialFieldSpec(
|
||||
providerType: PaymentMerchantProviderType
|
||||
): PaymentCredentialFieldSpec {
|
||||
return PAYMENT_CREDENTIAL_FIELD_SPECS[providerType] || { required: [], optional: [] }
|
||||
}
|
||||
|
||||
/** 凭证字段中的布尔字段:值必须为布尔值 */
|
||||
export const PAYMENT_CREDENTIAL_BOOLEAN_KEYS: string[] = ['ali_production']
|
||||
|
||||
/** 凭证字段中的整数字段:值必须为正整数 */
|
||||
export const PAYMENT_CREDENTIAL_INTEGER_KEYS: string[] = ['ali_pay_expire_minutes']
|
||||
|
||||
/** `merchant_identity` 必须与其值保持一致的凭证字段 */
|
||||
export const PAYMENT_MERCHANT_IDENTITY_KEYS: Record<PaymentMerchantProviderType, string> = {
|
||||
wechat: 'wx_mch_id',
|
||||
wechat_v2: 'wx_mch_id',
|
||||
fuiou: 'fy_mchnt_cd',
|
||||
alipay: 'ali_app_id'
|
||||
}
|
||||
|
||||
export interface PaymentCredentialEntryInput {
|
||||
key: string
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface PaymentCredentialValidationResult {
|
||||
credentials: PaymentCredentials | null
|
||||
error: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验并转换商户凭证输入:字段枚举、必填键、值类型与商户标识一致性。
|
||||
*/
|
||||
export function buildPaymentCredentials(
|
||||
providerType: PaymentMerchantProviderType,
|
||||
merchantIdentity: string,
|
||||
entries: PaymentCredentialEntryInput[]
|
||||
): PaymentCredentialValidationResult {
|
||||
const spec = getPaymentCredentialFieldSpec(providerType)
|
||||
const allowedKeys = [...spec.required, ...spec.optional]
|
||||
const credentials: Record<string, PaymentCredentialValue> = {}
|
||||
|
||||
for (const entry of entries) {
|
||||
const key = entry.key.trim()
|
||||
if (!key) {
|
||||
return { credentials: null, error: '请填写凭证字段名' }
|
||||
}
|
||||
if (!allowedKeys.includes(key)) {
|
||||
return { credentials: null, error: `凭证字段 ${key} 不属于当前服务商支持的字段` }
|
||||
}
|
||||
if (!entry.value) {
|
||||
return { credentials: null, error: `请填写凭证字段 ${key} 的值` }
|
||||
}
|
||||
if (Object.prototype.hasOwnProperty.call(credentials, key)) {
|
||||
return { credentials: null, error: `凭证字段 ${key} 重复` }
|
||||
}
|
||||
|
||||
if (PAYMENT_CREDENTIAL_BOOLEAN_KEYS.includes(key)) {
|
||||
if (entry.value !== 'true' && entry.value !== 'false') {
|
||||
return { credentials: null, error: `凭证字段 ${key} 必须为布尔值 true 或 false` }
|
||||
}
|
||||
credentials[key] = entry.value === 'true'
|
||||
continue
|
||||
}
|
||||
|
||||
if (PAYMENT_CREDENTIAL_INTEGER_KEYS.includes(key)) {
|
||||
const numberValue = Number(entry.value)
|
||||
if (!Number.isInteger(numberValue) || numberValue <= 0) {
|
||||
return { credentials: null, error: `凭证字段 ${key} 必须为正整数` }
|
||||
}
|
||||
credentials[key] = numberValue
|
||||
continue
|
||||
}
|
||||
|
||||
credentials[key] = entry.value
|
||||
}
|
||||
|
||||
for (const key of spec.required) {
|
||||
if (!Object.prototype.hasOwnProperty.call(credentials, key)) {
|
||||
return { credentials: null, error: `缺少必填凭证字段 ${key}` }
|
||||
}
|
||||
}
|
||||
|
||||
const identityKey = PAYMENT_MERCHANT_IDENTITY_KEYS[providerType]
|
||||
if (identityKey && credentials[identityKey] !== merchantIdentity.trim()) {
|
||||
return { credentials: null, error: `商户标识必须与凭证字段 ${identityKey} 的值一致` }
|
||||
}
|
||||
|
||||
return { credentials, error: '' }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import type { BaseResponse, PaginationData, PaginationParams } from './common'
|
||||
|
||||
export type WecomBusinessType = 'refund_approval' | 'offline_recharge_approval'
|
||||
export type WecomBusinessType =
|
||||
| 'refund_approval'
|
||||
| 'offline_recharge_approval'
|
||||
| 'employee_collection_approval'
|
||||
|
||||
export interface WecomApplication {
|
||||
id: number
|
||||
|
||||
Reference in New Issue
Block a user