← 返回图文规格书

自选充值 · 金额格式与弱反馈 · 技术确认清单

wallet 项目代码回填 · 2026-09-01 · 对应路由 /wallet/business(C2C 购买列表,无「自选」字面命名)
Ken 口径(2026-08-31):各种金额格式、各种弱反馈(Toast / 轻提示 / 页内一行字)应以老平台代码为准,多数配置或模板在后端/服务端,不是产品臆测。下表「我们看到的」仅来自 H5 实页截图 + Nova 原型,不能当定案;请技术填「代码位置」与「确认结果」。
请技术优先查:

A. 金额格式(按展示位)

wallet 映射说明:自选购买 ≈ src/views/wallet/business/;无 i18n,messageCode 填 FE_LITERAL:文案 或 API 字段路径,未实现标「未实现」。

# 展示位 我们看到的(待核实) 预期后端字段 / API 代码位置(文件·函数·配置 key) 技术确认结果
A1顶栏余额¥ 999,999商户可用余额(分转元)components/counter/header-title.vue · handleRefresh · formatNumberToThousandutils/base.js
API: GET /counter/front/merchant/getAvailableBalance · getAvailableBalanceapi/counter.js
前端格式化 接口返回 number(分),展示 Math.floor(res / 100)¥{{ formatNumberToThousand(balance) }}有 ¥ 前缀 + 千分位,整数无小数。用于存款/取款页 CounterHeaderTitle showType="balance";本地缓存 counterBalanceRC
A2筛选标签「100C以内」区间文案带 CsellPageAmountRangeConfigfilter-sort.vue · parseAmountRangeConfig
API: GET /order/front/buyOrder/v2/buyTradeType
兜底: amount-select-popup.vue · DEFAULT_AMOUNT_RANGE_LIST
API 配置 标签为 ${startAmount}-${endAmount}(如 1-100),不带 C 后缀;接口空时用前端默认 0-1000 等。
A3列表「可售 105」整数、无单位后缀amountbusiness/com/card.vue L21-22
API: POST .../buyOrder/v2/sellPage · getBuyLists
API 原值 展示 {{ info.amount }} C,整数 raw number + 前端字面量 C(DINPro 字体)。
A4成单量 99+成单量99+historyChildFinishCountbusiness/com/card.vue L13前端封顶 >= 99 显示 99+,否则原值;字段来自 sellPage 列表。
A5购买成功弱反馈内金额可售 105(无 C)锁单响应business/index.vue · proceedDepositBuy
deposit-popup.vue(购买前弹窗)
无对应 Toast 购买成功不弹「已选择…可售…」类 Toast;成功走 uiType 外跳或 jumpToIMWithEmbeddedToUrl。金额仅在购买弹窗内 {{ info.amount }}元 展示。
A6卖方 IM「可售 105 C」句末带 CIM 推送utils/wallet/index.js · jumpToIM / buildJumpToIMWalletUrl外站 IM 聊天室为独立 H5 域名,本仓库无卖方首条话术模板;wallet 买单 uiType=3 仅拼 tid 跳转,不像 counter deposit 那样 post chatMsgInit
A7沟通页订单卡大字105 + 小字「元」订单 amount外跳 IM(不在本仓库)
本仓近似: components/order-cashier-card.vue L18-20
IM 内订单卡不在 wallet 项目。订单收银台列表为 {{ item.amount }}元(raw + 前端「元」),无大小字分层。
A8订单列表+¥105账单/订单 APIbill/com/card.vue · handleGetSymbol
order-cashier-card.vue
API 账单列表: +/- + amount + currency(如 +105 C),非 +¥;收银台存单卡为 amount + 元
A9订单详情 · 申请金额整数 105订单详情bill/com/details.vue L11 · 头部 h2API 原值 购买/出售详情标题区 {{ amount }} {{ currency }},无单独「申请金额」字段名;手续费 feeQuantity.toFixed(2)
A10订单详情 · 实际到账105.00 / 0.00actualAmountbill/com/details.vue L45-46、L50API 原值 actualAmount 直接渲染(后端决定小数位);退回金额 reimburseAmount.toFixed(2) 前端固定 2 位(四舍五入)。
A11倒计时条内时间04:30 MM:SS过期时间戳components/countdown.vue
orders-accepted-dialog.vue
前端 通用倒计时为剩余秒数 + 可选 unit(默认 Ns),非 MM:SS。卖家接单弹窗: endTimestamp = sendTime + limitTime*1000(WS ToConfirmOrder)。
A12赠送语内金额赠送 3rebateRatio/giftRatiodeposit-popup.vue L10-14 · floatNumCut(multiplyAllFloat(ratio, amount), 2)
card.vue · 送X%
前端计算 弹窗: 「赠送 N 元」= 比例×amount 截断 2 位;列表卡片: 「送 X%」= multiplyOnlyFloat(ratio,100)
A13stock 与订单 amount 关系1:1 锁单?buyFromSellListbusiness/index.vue · proceedDepositBuy · quantity: depositInfo.amount
API: POST .../buyOrder/v2/buyFromSellList
1:1 列表 amount 原样作为 quantity 下单,前端无 C→CNY 换算;mergeCodes 内 payType 走撮合 IM(utils/counter/index.js)。

金额格式化总规则(wallet 汇总)

问题技术回答
C 币 decimalPlaces列表库存/下单 quantity:整数 raw,后缀 C 由前端拼接;余额/折合用 floatNumCut 默认 2 位截断(不四舍五入)
CNY 展示是否 always 2 位小数。弹窗主金额整数 +「元」;fee/gift 用 2 位截断;账单 actualAmount 跟 API;仅 feeQuantity/reimburseAmounttoFixed(2)
列表库存 vs 订单金额是否同币种是,同为 C 币数量(amount/quantity);订单收银台/账单展示「元」或 currency 字段由 API 决定。
格式化在前端还是后端(或各半)各半:列表/订单主金额为 API 原值;比例衍生金额、余额、限额千分位在前端(utils/base.js)。
统一工具类 / 方法名floatNumCutformatMinTwoDecimalsformatNumberToThousandmultiplyAllFloatmultiplyOnlyFloat(均在 src/utils/base.js)。

B. 弱反馈(Toast / 轻提示 / 页内一行)

# 触发场景 类型 我们看到的文案(待核实) messageCode / key(待填) 代码位置 技术确认结果
B1切换自选 TabToast已切换自选报价wallet.business.tab.selfSelect(未实现)business/index.vue(无 Tab 切换)未实现 wallet business 页无「自选/快捷」Tab;counter 侧 methods-deposit.vue 切换通道也无 Toast
B2切换快捷 TabToast已切换快捷存款wallet.business.tab.quickDeposit(未实现)同上未实现
B3付款方式筛选变更Toast付款方式:{选项}wallet.business.filter.payTypeChanged(未实现;{选项}=tradeTypeListChecked 展示名)filter-sort.vue · handlePaymentSelecthandleChange未实现 仅触发 handleFilterSortChange 静默刷新列表,无 Toast。
B4金额筛选变更Toast金额筛选:{选项}wallet.business.filter.amountRangeChanged(未实现;{选项}=amountText / 区间 label)filter-sort.vue · handleAmountSelect未实现 同上,静默刷新。
B5可售数量排序Toast按可售数量从高到低…wallet.business.sort.residualQty(未实现;三态:''/true/falsefilter-sort.vue · handleResidualQuantitySortAsc未实现 三态排序(默认/升/降)仅 emit 刷新,无 Toast。
B6筛选无结果页内空态暂无符合当前条件的报价FE_LITERAL:暂无数据pull-refresh.emptyTextcomponents/pull-refresh.vue L25
business/index.vue · dataStatus='empty'
前端常量 通用文案 「暂无数据」,非 PRD 定制句。
B7报价失效 · 点购买Toast当前报价已失效…buyFromSellList.response.msg + response.code(动态;前端拼接 ${msg}【${code}】);实名拦截 code=6286business/index.vue · proceedDepositBuy L1064-1068API message 失败时 toast 接口 msg,无固定「报价失效」messageKey。
B8购买成功Toast已选择{label},可售 {stock}wallet.business.buy.selected(未实现;{label}=支付方式名,{stock}=amountproceedDepositBuy 成功分支未实现 成功不 Toast,直接外跳/进 IM/关弹窗。
B9付款人姓名为空Toast请填写付款人姓名wallet.business.payerName.required(未实现)全仓库 grep 无匹配未实现 wallet 购买流无「付款人姓名」字段;仅有卖出绑卡「收款人姓名」(payment-account)。
B10付款人姓名已提交Toast付款人姓名已确认wallet.business.payerName.confirmed(未实现)全仓库 grep 无匹配未实现
B11锁单成功Toast已创建存款订单…wallet.business.order.created(未实现;成功走 uiType 分支无 Toast)proceedDepositBuy / IM 跳转未实现 撮合单创建成功无该 Toast;未完成单用 ConfirmTip 强提示(见 C5)。
B12复制订单号Toast已复制订单号:{orderNo}FE_LITERAL:复制成功utils/base.js#copyToClipboard;无 orderNo 拼接)utils/base.js · copyToClipboard
bill/details.vue · 订单号复制
前端常量 Toast 为 「复制成功」,不含订单号;风控横幅复制走同一方法。
B13取消成功Toast存款订单已取消…卖家:wallet.seller.adCancelOrder.silent(刻意无 Toast);买家拒单:WS:HaveRejectedOrderFE_LITERAL:支付商家未接单,请更换通道尝试.layout/wallet.vue · handleCloseOrdersAcceptedDialog
init-ws.js · HaveRejectedOrder
刻意无 Toast 卖家拒单/取消不弹成功提示;买家侧 WS 触发未接单 Toast。
B14回单驳回Toast回单已驳回…wallet.order.receiptRejected(未实现);近似:WS:WALLET_ORDER_END.content(API 直出)init-ws.jsorder-status-notification.vuewallet 未实现 无固定驳回 Toast;订单结束通知用 WS payload title/content
B15存款成功Toast存款已到账WS:WALLET_ORDER_ENDpayload.title + payload.contenttype=success|partialsuccessinit-ws.js · global.vue · order-status-notification.vueAPI 推送 文案来自 WS JSON,非前端写死「存款已到账」。

wallet 购买流已有 Toast 补充:请先勾选同意后下单(deposit-popup)、您还未完成实名认证(ConfirmTip)、支付商家未接单,请更换通道尝试【code】(proceedDepositBuy catch / WS)、手机号绑定相关(DepositPhoneVerifyPopup)。

C. 强提示 / 页内固定文案(非 Toast)

# 场景 / 状态 我们看到的文案 来源猜测 代码位置 技术确认结果
C1自选锁定 · 卖方首条 IM已锁定自选报价…IM 推送外跳聊天室(utils/wallet/index.js · jumpToIM不在本仓库 IM 消息体由聊天室服务/后端推送,wallet 前端无该模板字符串。
C2待付款 · 倒计时条请 {MM:SS} 内付款…前端模板外跳 IM;本仓 countdown.vue 仅秒数IM 内文案不在本仓库 wallet 通用倒计时非 MM:SS 模板句。
C3已付款 · 锁层已付款 / 请等待对方查收APIorder-cashier-card.vue · viewStatusDesc \|\| statusDesc订单收银台状态文案跟 API 字段,前端只渲染;具体「已付款」等字取决于后端返回。
C4已付款 · 底栏请等待 09:59 对方发货中…外跳 IM不在本仓库 wallet 卖出底栏固定文案为「请保持在线,离开页面将暂停受理订单」(order-cashier.vue L41-43)。
C5强制退出弹窗充值订单未完成…前端常量wallet: business/index.vue L931-936 · 购买订单未完成,请尽快查看!
counter: methods-deposit.vue L517 · 充值订单未完成,请尽快查看!
wallet C2C 未完成撮合单用 ConfirmTip;文案写死,按钮「查看」跳 IM。
C6赠送语5分钟内上传回单…活动配置deposit-popup.vue · 赠送/手续费行
order-cashier-card.vue · 限时赠送N元
无「5分钟回单」句;现有为比例算出的「赠送 N 元」或列表「送 X%」,数据来自 buyOrderConfig 的 ratio 字段。
C7回单驳回 · 原因图片未显示完整…审核返回WS → order-status-notification.vue · infos.content驳回原因若展示,走订单结束/风控 WS 的 API content,非前端枚举;wallet 无单独「回单驳回原因」组件。

IM 聊天室回填(c-play · c:\newProject\c-play · 2026-09-01) — 对应上文 A6/A7/A11/A12、B8–B15、C1–C7 等「外跳 IM / 不在本仓库」条目。messageCode 规则:无 i18n;已实现 FE_LITERAL:文案WS msgObject.text;未做标注「未实现」。

A. 金额格式(IM 对应项)

# 展示位 我们看到的(待核实) 预期后端字段 / API 代码位置(c-play) 技术确认结果
A6卖方 IM「可售 105 C」句末带 CWS 文本 / order-infomsg/order-info/index.tsx L58-62
msg/index.tsx disPlayType 1 · msgObject.text
前端 代码无「可售」字面。订单信息卡(disPlayType 2):{quantity} c + 标签「交易数量」,quantity 为 API 整数原值。文本话术(disPlayType 1):msgObject.text HTML 直出,无写死「可售 XXX C」;若 PRD 可见该句,来自后端 WS 推送。
A7沟通页订单卡大字105 + 小字「元」amountmsg/payment/index.tsx L396-398
msg/c-info/index.tsx L62-66
status-mask/index.tsx L283-286
前端 floor 支付卡(dt3):{Math.floor(amount)}整数大字 + 小字「元」。卖方放币卡(dt8/CInfo)同模式 +「交易金额」。完成蒙层:±{Math.floor(Number(amount))} 整数无「元」。订单号:支付卡 mchOrderNo 后 10 位;蒙层 后 12 位
A11倒计时条内时间04:30 MM:SSendTimestampapp/components/count-down.tsx
msg/payment/index.tsx L545-549
msg/c-info/index.tsx L86-90
MM:SS CountDownisStatic=false)格式化为 MM:SS(小时并入分钟)。deadline 来自 init 映射(container.tsx · adExpireTimeout/orderConfirmTimeout/releaseConfirmTimeout,秒级 ×1000)。另 CountDownSeconds 为纯整数秒(提醒他/接单按钮)。
A12赠送语内金额赠送 3rebateRatio · rebateTimeLimitmsg/btn-list/index.tsx · RebateTag L11-57
msg/c-info/index.tsx L69-75
前端计算 ① RebateTag:{ceil(rebateTimeLimit/60)}分钟内 +(checkEmail?「发送邮件完成付款」:「上传回单订单到账」)+「,赠送」+ formatRebateAmount(accMul(rebateRatio,amount)) +「元」(截断 2 位)。② CInfo:{sellOrderRebate}元 API 原值 +「限时奖励/奖励过期」。无 PRD 固定「5分钟」句

金额格式化总规则(c-play 汇总)

问题技术回答
C 币 decimalPlacesorder-info 卡 quantity整数 raw + 前端 c
CNY 展示是否 always 2 位小数。支付卡/CInfo 主金额 Math.floor 整数 +「元」;蒙层实际到账/手续费/赠送用 2 位(截断或 toFixed)。
格式化在前端还是后端各半:主金额/quantity/rebate 来自 API/WS;floor、截断 2 位、MM:SS、文案拼接在前端。
统一工具 / 方法formatRebateAmount(btn-list)、accMul/addMul(serviceClient)、truncateMoney2Display/formatAmount(status-mask)、Math.floor(payment/c-info)。

B. 弱反馈(IM 对应项)

# 触发场景 类型 文案(待核实) messageCode / key 代码位置(c-play) 技术确认结果
B8购买成功Toast已选择{label},可售 {stock}im.buy.selected(未实现)msg-container/index.tsx(进 IM 后)未实现 进入聊天室无「已选择…可售…」Toast;状态靠支付卡 UI 更新。
B9付款人姓名为空Toast请填写付款人姓名FE_LITERAL:请输入2-20位中文或英文字符payer-name-panel/index.tsx L91-95
API: backfillPayerName
前端常量 校验失败 Toast 「请输入2-20位中文或英文字符」(非 PRD「请填写付款人姓名」)。API 失败:dataObj.msgFE_LITERAL:提交失败。条件:init payerNamePopup + tradeType===2
B10付款人姓名已提交Toast付款人姓名已确认im.payerName.confirmed(未实现)msg-container/index.tsx · handlePayerNameSubmit未实现 API 成功后无成功 Toast,关面板 + sessionStorage 标记。
B11锁单成功Toast已创建存款订单…im.order.created(未实现)不适用 锁单在 wallet;IM 仅接收已创建订单的 init/历史。
B12复制订单号Toast已复制订单号:{orderNo}FE_LITERAL:复制成功lib/client.ts · copyToClipboard
payment / order-info / c-info / status-mask
前端常量 Toast 「复制成功」/「复制失败」不含订单号
B13取消成功Toast存款订单已取消…msg-container/index.tsx · Accept 面板混合 取消结果多为 status-mask「已取消」强提示,或 WS disPlayType 9 warning toast(msgObject.text)。Accept 取消:FE_LITERAL:取消成功/取消失败
B14回单驳回Toast回单已驳回…WS disPlayType 9 → msgObject.textmsg-container/index.tsx L969-974API/WS 动态 disPlayType===9 时 toast msgObject.text无固定「回单已驳回」key
B15存款成功Toast存款已到账FE_LITERAL:已完成(蒙层,非 Toast)status-mask/index.tsx · showOrderFinished强提示 完成走 disPlayType 5/12 → StatusMask 全屏「已完成」tradeSceneType 6/7),非「存款已到账」Toast

IM Toast 补充:提醒成功(btn 5)、正在连接...(WS 重连)、群聊已解散您正在与客服沟通,请勿重复操作验证不通过/checkPayPass 返回 msg。邮件「发送完成」:普通回单发 WS 5008/买单确认付款;「我要催单」仅关面板无 WS。

C. 强提示 / 页内固定文案(IM 对应项)

# 场景 / 状态 文案 来源 代码位置(c-play) 技术确认结果
C1自选锁定 · 卖方首条 IM已锁定自选报价…WS/APImsg/index.tsx disPlayType 1API 直出 msgObject.text HTML 渲染,前端无写死模板。快捷指令:getChatConfigcommandList[].msgContent
C2待付款 · 倒计时条请 {MM:SS} 内付款…前端模板msg/payment/index.tsx L543-555前端模板 请 [CountDown MM:SS] 内付款,超时将自动取消订单。(tips/index.tsx 另有状态条模板但 container 未挂载。)
C3已付款 · 锁层已付款 / 请等待对方查收前端+状态msg/payment/index.tsx L277-311
msg/index.tsx errText
前端推导 tradeStatus∈[3,4,6,7,8] 或买家发过含「我已支付,请查收,谢谢」文本 → 锁层「已付款」 + 「请等待对方查收」
C4已付款 · 底栏请等待 09:59 对方发货中…前端模板msg/payment/index.tsx L543-554
msg/c-info/index.tsx L84-92
前端模板 买家已付:请等待 [MM:SS] 对方发货中...(动态非固定 09:59)。卖家:请 [MM:SS] 内发货,超时将自动发货 / c-info「超时官方自动确认」。
C5强制退出弹窗充值订单未完成…lib/iframe-fullscreen-helper.ts未实现 无 wallet 式 ConfirmTip「订单未完成」;仅有 beforeunload 监听,无 PRD 定制文案。
C6赠送语5分钟内上传回单…活动配置msg/btn-list/index.tsx RebateTag
msg/c-info/index.tsx
前端计算 RebateTag:{ceil(rebateTimeLimit/60)}分钟内 + 上传/邮件文案 + 赠送 N元。CInfo:{sellOrderRebate}元 +「限时奖励」。无固定「5分钟」句
C7回单驳回 · 原因图片未显示完整…审核返回msg-container/index.tsx disPlayType 9 / disPlayType 1API 直出 无独立驳回原因组件;走 WS 文本 msgObject.text 或 disPlayType 9 toast,前端不枚举

D. 业务架构(与金额/提示相关)

依据:wallet-order BuyOrderV2Controller / BuyCounterInfoServiceImplWalletSellOrderPageVOPayConstants.PayModelCounterUITypeEnum,以及前端回填结论(A13/B7/B11)。
#问题技术回答
D1 自选购买创建的订单类型(撮合 / CTC / 其他) 按支付方式分流,不是单一类型。
入口:wallet business 页(C2C 卖单列表)→ POST /front/buyOrder/v2/buyFromSellList → 资金侧 placePayOrder
返回 PlacePayOrderVO.uiTypeCounterUITypeEnum)决定后续:
  • uiType=3 跳聊天室 → 撮合类(payModel 为 MATCH/预约撮合/OTC 撮合,或需凭证撮合通道)
  • uiType=1/2 外跳/内嵌浏览器 → 三方/电子钱包等非 IM 撮合
  • uiType=4/5 USDT / ZHOTC 页
产品「自选」在代码中无独立订单类型名;业务上是「从卖单列表购买」的存款单,撮合与否由通道 payModel / payTypeCode 决定。
D2 报价列表 API 路径 + 主要 DTO 字段名 列表:POST /front/buyOrder/v2/sellPage
返回 TradeCommonPageResult<WalletSellOrderPageVO>,主要字段: amountquantitytradeTypeaccountType/accountTypeNamehistoryChildFinishCountmatchPayLevelcurrencyfeeRatiogiftRatiorebateRatiopayTypeCodepayTypeNameurlcustomTypeNamedzqbPinned

筛选项/区间配置:GET /front/buyOrder/v2/buyTradeType
返回 BuyOrderConfigVO:支付方式列表 + sellPageAmountRangeConfig(JSON:startAmount/endAmount/sort)。

点击购买前配置:POST /front/buyOrder/v2/buyOrderConfig(手续费/返利/赠送)。
D3 购买/锁单 API 路径 + 失败码列表 路径:POST /front/buyOrder/v2/buyFromSellList
入参 WalletBuyDTOpayTypeCode(必填)、quantity(必填,= 列表 amount 1:1)、可选 channelId/channelCode(电子钱包)、可选 phoneNo/smsCode(撮合通道命中手机校验时)。
成功:返回 PlacePayOrderVO(含 orderNouiTypepayModeltypeCode 等),前端按 uiType 跳转,无购买成功 Toast

与金额/提示相关的失败码(wallet 6000–6999 段 + 特殊码):
  • 6286 请先实名后再购买(前端 ConfirmTip/Toast,文档 B7 已标)
  • 100032 WALLET_BUY_ERROR「支付商家未接单,请更换通道尝试」(前端常拼 【code】
  • 6208 金额必须大于 0
  • 6262 对方未接单,请重新下单
  • 6265 库存不足
  • 6276 订单已成交或已下架,请更换订单或稍后尝试
  • 6287 买单下单失败,请稍后再试
  • 其它:通道维护、重复提交(6106)、手机验证码类(6200+)等;多数失败 Toast 为接口 msg 直出 + 可选 code 拼接,无固定「报价失效」messageKey
另:进行中撮合单 GET /front/buyOrder/v2/getInProgressMatchOrder → 触发 C5 强提示。
D4 是否与老板口径「C 币非撮合」冲突?代码里如何区分 不直接冲突,口径需拆开说:
1)列表上的「C」是库存/数量展示单位(前端拼 C),下单 quantity 与列表 amount 1:1不存在「因单位叫 C 就判定非撮合」
2)是否撮合看通道模型,不看币种字面:
  • PayModel.isMatchModel(payModel):极速撮合(1)、预约撮合(5)、OTC 撮合(4) → 偏 IM/撮合链路
  • typeCode ∈ MATCH_TYPE_LIST*:如 JSCK、WXCK_MATCH、ZFBCK_MATCH… → 撮合存款通道族
  • PayModel.ZHOTC_MODEL(6) 等虚拟币模型 → 老板常说的「C/68C 通道」更接近这类,走 ZHOTC/余额兑换,不是卖单列表撮合锁单
  • 电子钱包/三方:uiType 外跳浏览器,亦非 IM 撮合
3)前端区分:下单成功后看 uiType(3=聊天室撮合;1/2=浏览器;4/5=USDT/OTC 页)。后端区分:看返回的 payModel + typeCode
结论:「自选列表购买」可以下出撮合单;「C 币展示」≠「非撮合」。若老板指 ZHOTC/余额 C,那是另一条产品线,勿与 business 卖单列表混为一谈。

金额 / 提示 × 架构串联(一句话)

链路节点金额提示
sellPage 列表API amount + 前端 C筛选项变更无 Toast;空态「暂无数据」
buyFromSellListquantity = amount 1:1失败 API msg;成功无 Toast,按 uiType 跳
uiType=3 → IM支付卡 floor(amount)+「元」;quantity+「 c」WS 文本/锁层/倒计时模板;完成 StatusMask
账单/详情amount+currency / actualAmount复制「复制成功」;结束态 WS content