fix(c2c): 积分股→积分值,C2C交易对象修正为积分值(cash)
C2C交易的产品是积分值,支付方式是绿积分(外部1.0系统),与积分股无关。 前端: - c2c_publish_page: 余额卡、数量输入、提示文案、确认弹窗全部改为积分值 - c2c_market_page: 余额概览(availableShares→availableCash)、订单数量标签、接单弹窗 - c2c_order_detail_page: 订单详情、划转提示、确认收款弹窗 后端 c2c.service.ts: - createOrder SELL: freezeShares→freezeCash - takeOrder BUY(taker=卖方): freezeShares→freezeCash - takeOrder SELL(taker=买方): 移除冻结(买方通过外部支付绿积分) - cancelOrder SELL: unfreezeShares→unfreezeCash - expireOrder: unfreezeShares→unfreezeCash,SELL不再解冻taker - executeTransfer: 统一BUY/SELL为单向积分值划转,assetType改为CASH Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
49bcb96c4c
commit
94d4524ee3
|
|
@ -38,15 +38,16 @@ const DEFAULT_CONFIRM_TIMEOUT_MINUTES = 60;
|
|||
/**
|
||||
* C2C 场外交易服务
|
||||
*
|
||||
* 业务流程:
|
||||
* 业务流程(C2C交易的是积分值,支付方式是绿积分/外部1.0系统):
|
||||
* 1. 用户发布广告(createOrder)-> 状态: PENDING
|
||||
* - BUY 类型: 冻结用户的积分值(cashBalance)
|
||||
* - SELL 类型: 冻结用户的积分股(shareBalance)
|
||||
* - BUY 类型: 验证积分值余额,不冻结(买方通过外部支付绿积分)
|
||||
* - SELL 类型: 冻结卖方的积分值(cashBalance)
|
||||
* 2. 其他用户接单(takeOrder)-> 状态: MATCHED
|
||||
* - 对方冻结对应资产
|
||||
* - 接BUY单(taker=卖方): 冻结taker的积分值
|
||||
* - 接SELL单(taker=买方): 不冻结(买方通过外部支付绿积分)
|
||||
* 3. 买方付款后点击确认付款(confirmPayment)-> 状态: PAID
|
||||
* 4. 卖方确认收款(confirmReceived)-> 状态: COMPLETED
|
||||
* - 解冻双方资产并完成转账
|
||||
* - 解冻卖方积分值并划转给买方
|
||||
*/
|
||||
@Injectable()
|
||||
export class C2cService {
|
||||
|
|
@ -144,13 +145,13 @@ export class C2cService {
|
|||
}
|
||||
// #12: 不冻结(买方通过外部1.0系统支付绿积分,系统无法冻结外部资产)
|
||||
} else {
|
||||
// 卖出订单:需要冻结积分股
|
||||
// 卖出订单:需要冻结积分值(C2C交易的是积分值)
|
||||
const quantityMoney = new Money(quantityDecimal);
|
||||
if (account.availableShares.isLessThan(quantityMoney)) {
|
||||
throw new BadRequestException(`积分股余额不足,需要 ${quantity},可用 ${account.availableShares.toString()}`);
|
||||
if (account.availableCash.isLessThan(quantityMoney)) {
|
||||
throw new BadRequestException(`积分值余额不足,需要 ${quantity},可用 ${account.availableCash.toString()}`);
|
||||
}
|
||||
// 冻结积分股
|
||||
await this.tradingAccountRepository.freezeShares(accountSequence, quantityDecimal);
|
||||
// 冻结积分值
|
||||
await this.tradingAccountRepository.freezeCash(accountSequence, quantityDecimal);
|
||||
}
|
||||
|
||||
// 创建订单
|
||||
|
|
@ -288,23 +289,17 @@ export class C2cService {
|
|||
this.logger.log(`C2C部分成交: 原订单 ${orderNo} 拆分,剩余 ${remainingQuantity} 创建新订单 ${remainOrderNo}`);
|
||||
}
|
||||
|
||||
// 接单方需要冻结对应资产
|
||||
// 接单方需要冻结对应资产(C2C交易的是积分值)
|
||||
if (order.type === C2C_ORDER_TYPE.BUY) {
|
||||
// 挂单方要买入积分股,接单方需要有积分股来卖出
|
||||
// 挂单方要买入积分值,接单方(卖方)需要有积分值来卖出
|
||||
const quantityMoney = new Money(quantityDecimal);
|
||||
if (takerAccount.availableShares.isLessThan(quantityMoney)) {
|
||||
throw new BadRequestException(`积分股余额不足,需要 ${quantityDecimal.toString()},可用 ${takerAccount.availableShares.toString()}`);
|
||||
}
|
||||
// 冻结接单方的积分股
|
||||
await this.tradingAccountRepository.freezeShares(takerAccountSequence, quantityDecimal);
|
||||
} else {
|
||||
// 挂单方要卖出积分股,接单方需要有积分值来买入
|
||||
const totalAmountMoney = new Money(totalAmountDecimal);
|
||||
if (takerAccount.availableCash.isLessThan(totalAmountMoney)) {
|
||||
throw new BadRequestException(`积分值余额不足,需要 ${totalAmountDecimal.toString()},可用 ${takerAccount.availableCash.toString()}`);
|
||||
if (takerAccount.availableCash.isLessThan(quantityMoney)) {
|
||||
throw new BadRequestException(`积分值余额不足,需要 ${quantityDecimal.toString()},可用 ${takerAccount.availableCash.toString()}`);
|
||||
}
|
||||
// 冻结接单方的积分值
|
||||
await this.tradingAccountRepository.freezeCash(takerAccountSequence, totalAmountDecimal);
|
||||
await this.tradingAccountRepository.freezeCash(takerAccountSequence, quantityDecimal);
|
||||
} else {
|
||||
// 挂单方要卖出积分值,接单方(买方)通过外部支付绿积分,不冻结
|
||||
}
|
||||
|
||||
// 计算超时时间
|
||||
|
|
@ -369,7 +364,8 @@ export class C2cService {
|
|||
if (order.type === C2C_ORDER_TYPE.BUY) {
|
||||
// BUY 订单未冻结买方资产(买方通过外部支付绿积分),无需解冻
|
||||
} else {
|
||||
await this.tradingAccountRepository.unfreezeShares(accountSequence, quantityDecimal);
|
||||
// SELL 订单:解冻卖方的积分值
|
||||
await this.tradingAccountRepository.unfreezeCash(accountSequence, quantityDecimal);
|
||||
}
|
||||
|
||||
// 更新订单状态
|
||||
|
|
@ -494,146 +490,66 @@ export class C2cService {
|
|||
sellerAccountSequence = order.makerAccountSequence;
|
||||
}
|
||||
|
||||
// 使用事务执行转账
|
||||
// 使用事务执行转账(C2C交易的是积分值,BUY和SELL都是单向划转积分值)
|
||||
await this.prisma.$transaction(async (tx) => {
|
||||
if (order.type === C2C_ORDER_TYPE.BUY) {
|
||||
// BUY订单:买方通过外部支付绿积分,系统只转移卖方积分股给买方(单向)
|
||||
// 1. 解冻卖方积分股并扣除
|
||||
await tx.tradingAccount.update({
|
||||
where: { accountSequence: sellerAccountSequence },
|
||||
data: {
|
||||
frozenShares: { decrement: quantityDecimal.toNumber() },
|
||||
shareBalance: { decrement: quantityDecimal.toNumber() },
|
||||
totalSold: { increment: quantityDecimal.toNumber() },
|
||||
},
|
||||
});
|
||||
// 1. 解冻卖方积分值并扣除
|
||||
await tx.tradingAccount.update({
|
||||
where: { accountSequence: sellerAccountSequence },
|
||||
data: {
|
||||
frozenCash: { decrement: quantityDecimal.toNumber() },
|
||||
cashBalance: { decrement: quantityDecimal.toNumber() },
|
||||
totalSold: { increment: quantityDecimal.toNumber() },
|
||||
},
|
||||
});
|
||||
|
||||
// 2. 买方获得积分股
|
||||
await tx.tradingAccount.update({
|
||||
where: { accountSequence: buyerAccountSequence },
|
||||
data: {
|
||||
shareBalance: { increment: quantityDecimal.toNumber() },
|
||||
totalBought: { increment: quantityDecimal.toNumber() },
|
||||
},
|
||||
});
|
||||
// 2. 买方获得积分值
|
||||
await tx.tradingAccount.update({
|
||||
where: { accountSequence: buyerAccountSequence },
|
||||
data: {
|
||||
cashBalance: { increment: quantityDecimal.toNumber() },
|
||||
totalBought: { increment: quantityDecimal.toNumber() },
|
||||
},
|
||||
});
|
||||
|
||||
// 3. 记录交易流水(买方 — 积分股入账)
|
||||
const buyerAccount = await tx.tradingAccount.findUnique({
|
||||
where: { accountSequence: buyerAccountSequence },
|
||||
});
|
||||
await tx.tradingTransaction.create({
|
||||
data: {
|
||||
accountSequence: buyerAccountSequence,
|
||||
type: 'C2C_BUY',
|
||||
assetType: 'SHARE',
|
||||
amount: quantityDecimal.toNumber(),
|
||||
balanceBefore: new Decimal(buyerAccount!.shareBalance).minus(quantityDecimal).toNumber(),
|
||||
balanceAfter: buyerAccount!.shareBalance,
|
||||
referenceId: order.orderNo,
|
||||
referenceType: 'C2C_ORDER',
|
||||
counterpartyType: 'USER',
|
||||
counterpartyAccountSeq: sellerAccountSequence,
|
||||
memo: `C2C买入 ${order.quantity} 积分股(绿积分支付)`,
|
||||
},
|
||||
});
|
||||
// 3. 记录交易流水(买方 — 积分值入账)
|
||||
const buyerAccount = await tx.tradingAccount.findUnique({
|
||||
where: { accountSequence: buyerAccountSequence },
|
||||
});
|
||||
await tx.tradingTransaction.create({
|
||||
data: {
|
||||
accountSequence: buyerAccountSequence,
|
||||
type: 'C2C_BUY',
|
||||
assetType: 'CASH',
|
||||
amount: quantityDecimal.toNumber(),
|
||||
balanceBefore: new Decimal(buyerAccount!.cashBalance).minus(quantityDecimal).toNumber(),
|
||||
balanceAfter: buyerAccount!.cashBalance,
|
||||
referenceId: order.orderNo,
|
||||
referenceType: 'C2C_ORDER',
|
||||
counterpartyType: 'USER',
|
||||
counterpartyAccountSeq: sellerAccountSequence,
|
||||
memo: `C2C买入 ${order.quantity} 积分值(绿积分支付)`,
|
||||
},
|
||||
});
|
||||
|
||||
// 4. 记录交易流水(卖方 — 积分股扣除)
|
||||
const sellerAccount = await tx.tradingAccount.findUnique({
|
||||
where: { accountSequence: sellerAccountSequence },
|
||||
});
|
||||
await tx.tradingTransaction.create({
|
||||
data: {
|
||||
accountSequence: sellerAccountSequence,
|
||||
type: 'C2C_SELL',
|
||||
assetType: 'SHARE',
|
||||
amount: quantityDecimal.toNumber(),
|
||||
balanceBefore: new Decimal(sellerAccount!.shareBalance).plus(quantityDecimal).toNumber(),
|
||||
balanceAfter: sellerAccount!.shareBalance,
|
||||
referenceId: order.orderNo,
|
||||
referenceType: 'C2C_ORDER',
|
||||
counterpartyType: 'USER',
|
||||
counterpartyAccountSeq: buyerAccountSequence,
|
||||
memo: `C2C卖出 ${order.quantity} 积分股(收到绿积分)`,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// SELL订单:双向交换(积分股 ↔ 积分值),保持现有逻辑
|
||||
// 1. 解冻买方的积分值并扣除
|
||||
await tx.tradingAccount.update({
|
||||
where: { accountSequence: buyerAccountSequence },
|
||||
data: {
|
||||
frozenCash: { decrement: totalAmountDecimal.toNumber() },
|
||||
cashBalance: { decrement: totalAmountDecimal.toNumber() },
|
||||
},
|
||||
});
|
||||
|
||||
// 2. 解冻卖方的积分股并扣除
|
||||
await tx.tradingAccount.update({
|
||||
where: { accountSequence: sellerAccountSequence },
|
||||
data: {
|
||||
frozenShares: { decrement: quantityDecimal.toNumber() },
|
||||
shareBalance: { decrement: quantityDecimal.toNumber() },
|
||||
totalSold: { increment: quantityDecimal.toNumber() },
|
||||
},
|
||||
});
|
||||
|
||||
// 3. 买方获得积分股
|
||||
await tx.tradingAccount.update({
|
||||
where: { accountSequence: buyerAccountSequence },
|
||||
data: {
|
||||
shareBalance: { increment: quantityDecimal.toNumber() },
|
||||
totalBought: { increment: quantityDecimal.toNumber() },
|
||||
},
|
||||
});
|
||||
|
||||
// 4. 卖方获得积分值
|
||||
await tx.tradingAccount.update({
|
||||
where: { accountSequence: sellerAccountSequence },
|
||||
data: {
|
||||
cashBalance: { increment: totalAmountDecimal.toNumber() },
|
||||
},
|
||||
});
|
||||
|
||||
// 5. 记录交易流水(买方)
|
||||
const buyerAccount = await tx.tradingAccount.findUnique({
|
||||
where: { accountSequence: buyerAccountSequence },
|
||||
});
|
||||
await tx.tradingTransaction.create({
|
||||
data: {
|
||||
accountSequence: buyerAccountSequence,
|
||||
type: 'C2C_BUY',
|
||||
assetType: 'SHARE',
|
||||
amount: quantityDecimal.toNumber(),
|
||||
balanceBefore: new Decimal(buyerAccount!.shareBalance).minus(quantityDecimal).toNumber(),
|
||||
balanceAfter: buyerAccount!.shareBalance,
|
||||
referenceId: order.orderNo,
|
||||
referenceType: 'C2C_ORDER',
|
||||
counterpartyType: 'USER',
|
||||
counterpartyAccountSeq: sellerAccountSequence,
|
||||
memo: `C2C买入 ${order.quantity} 积分股,单价 ${order.price}`,
|
||||
},
|
||||
});
|
||||
|
||||
// 6. 记录交易流水(卖方)
|
||||
const sellerAccount = await tx.tradingAccount.findUnique({
|
||||
where: { accountSequence: sellerAccountSequence },
|
||||
});
|
||||
await tx.tradingTransaction.create({
|
||||
data: {
|
||||
accountSequence: sellerAccountSequence,
|
||||
type: 'C2C_SELL',
|
||||
assetType: 'CASH',
|
||||
amount: totalAmountDecimal.toNumber(),
|
||||
balanceBefore: new Decimal(sellerAccount!.cashBalance).minus(totalAmountDecimal).toNumber(),
|
||||
balanceAfter: sellerAccount!.cashBalance,
|
||||
referenceId: order.orderNo,
|
||||
referenceType: 'C2C_ORDER',
|
||||
counterpartyType: 'USER',
|
||||
counterpartyAccountSeq: buyerAccountSequence,
|
||||
memo: `C2C卖出 ${order.quantity} 积分股,单价 ${order.price}`,
|
||||
},
|
||||
});
|
||||
}
|
||||
// 4. 记录交易流水(卖方 — 积分值扣除)
|
||||
const sellerAccount = await tx.tradingAccount.findUnique({
|
||||
where: { accountSequence: sellerAccountSequence },
|
||||
});
|
||||
await tx.tradingTransaction.create({
|
||||
data: {
|
||||
accountSequence: sellerAccountSequence,
|
||||
type: 'C2C_SELL',
|
||||
assetType: 'CASH',
|
||||
amount: quantityDecimal.toNumber(),
|
||||
balanceBefore: new Decimal(sellerAccount!.cashBalance).plus(quantityDecimal).toNumber(),
|
||||
balanceAfter: sellerAccount!.cashBalance,
|
||||
referenceId: order.orderNo,
|
||||
referenceType: 'C2C_ORDER',
|
||||
counterpartyType: 'USER',
|
||||
counterpartyAccountSeq: buyerAccountSequence,
|
||||
memo: `C2C卖出 ${order.quantity} 积分值(收到绿积分)`,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
this.logger.log(`C2C交易转账完成: ${order.orderNo}, 买方: ${buyerAccountSequence}, 卖方: ${sellerAccountSequence}`);
|
||||
|
|
@ -740,18 +656,15 @@ export class C2cService {
|
|||
const quantityDecimal = new Decimal(freshOrder.quantity);
|
||||
const totalAmountDecimal = new Decimal(freshOrder.totalAmount);
|
||||
|
||||
// 解冻双方资产
|
||||
// 解冻卖方的积分值(C2C交易的是积分值,买方不冻结)
|
||||
if (freshOrder.type === C2C_ORDER_TYPE.BUY) {
|
||||
// BUY订单:maker未冻结(买方通过外部支付绿积分),只解冻taker的积分股
|
||||
// BUY订单:maker(买方)未冻结,只解冻taker(卖方)的积分值
|
||||
if (freshOrder.takerAccountSequence) {
|
||||
await this.tradingAccountRepository.unfreezeShares(freshOrder.takerAccountSequence, quantityDecimal);
|
||||
await this.tradingAccountRepository.unfreezeCash(freshOrder.takerAccountSequence, quantityDecimal);
|
||||
}
|
||||
} else {
|
||||
// SELL订单:maker冻结了积分股,taker冻结了积分值
|
||||
await this.tradingAccountRepository.unfreezeShares(freshOrder.makerAccountSequence, quantityDecimal);
|
||||
if (freshOrder.takerAccountSequence) {
|
||||
await this.tradingAccountRepository.unfreezeCash(freshOrder.takerAccountSequence, totalAmountDecimal);
|
||||
}
|
||||
// SELL订单:maker(卖方)冻结了积分值,taker(买方)未冻结
|
||||
await this.tradingAccountRepository.unfreezeCash(freshOrder.makerAccountSequence, quantityDecimal);
|
||||
}
|
||||
|
||||
// 更新订单状态为过期
|
||||
|
|
|
|||
|
|
@ -127,12 +127,12 @@ class _C2cMarketPageState extends ConsumerState<C2cMarketPage>
|
|||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'可用积分股',
|
||||
'可用积分值',
|
||||
style: TextStyle(fontSize: 12, color: AppColors.textSecondaryOf(context)),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
formatAmount(availableShares),
|
||||
formatAmount(availableCash),
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
|
|
@ -389,7 +389,7 @@ class _C2cMarketPageState extends ConsumerState<C2cMarketPage>
|
|||
Text('数量', style: TextStyle(fontSize: 12, color: AppColors.textSecondaryOf(context))),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
'${formatAmount(order.quantity)} 积分股',
|
||||
'${formatAmount(order.quantity)} 积分值',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
|
|
@ -490,7 +490,7 @@ class _C2cMarketPageState extends ConsumerState<C2cMarketPage>
|
|||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
'${formatAmount(order.quantity)} 积分股',
|
||||
'${formatAmount(order.quantity)} 积分值',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
|
|
@ -649,7 +649,7 @@ class _C2cMarketPageState extends ConsumerState<C2cMarketPage>
|
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('可用数量', style: TextStyle(fontSize: 13, color: AppColors.textSecondaryOf(context))),
|
||||
Text('${formatAmount(order.quantity)} 积分股', style: TextStyle(fontSize: 13, color: AppColors.textPrimaryOf(context))),
|
||||
Text('${formatAmount(order.quantity)} 积分值', style: TextStyle(fontSize: 13, color: AppColors.textPrimaryOf(context))),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
|
@ -683,7 +683,7 @@ class _C2cMarketPageState extends ConsumerState<C2cMarketPage>
|
|||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: const BorderSide(color: _orange, width: 2),
|
||||
),
|
||||
suffixText: '积分股',
|
||||
suffixText: '积分值',
|
||||
suffixStyle: TextStyle(color: AppColors.textSecondaryOf(context), fontSize: 14),
|
||||
),
|
||||
),
|
||||
|
|
@ -830,8 +830,8 @@ class _C2cMarketPageState extends ConsumerState<C2cMarketPage>
|
|||
),
|
||||
child: Text(
|
||||
isBuyAction
|
||||
? '您将使用积分值购买对方的积分股'
|
||||
: '您将出售积分股,买方将向您支付绿积分',
|
||||
? '您将使用绿积分购买对方的积分值'
|
||||
: '您将出售积分值,买方将向您支付绿积分',
|
||||
style: TextStyle(fontSize: 12, color: AppColors.textSecondaryOf(context)),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -338,8 +338,8 @@ class _C2cOrderDetailPageState extends ConsumerState<C2cOrderDetailPage> {
|
|||
),
|
||||
const SizedBox(height: 16),
|
||||
_buildInfoRow('订单编号', order.orderNo, canCopy: true),
|
||||
_buildInfoRow('单价', '${formatPrice(order.price)} 积分值/股'),
|
||||
_buildInfoRow('数量', '${formatAmount(order.quantity)} 积分股'),
|
||||
_buildInfoRow('单价', '${formatPrice(order.price)} 积分值'),
|
||||
_buildInfoRow('数量', '${formatAmount(order.quantity)} 积分值'),
|
||||
_buildInfoRow('总金额', '${formatAmount(order.totalAmount)} 积分值'),
|
||||
_buildInfoRow('创建时间', _formatDateTime(order.createdAt)),
|
||||
if (order.remark != null && order.remark!.isNotEmpty)
|
||||
|
|
@ -880,12 +880,12 @@ class _C2cOrderDetailPageState extends ConsumerState<C2cOrderDetailPage> {
|
|||
? [
|
||||
'您已确认付款',
|
||||
'请等待卖方确认收款',
|
||||
'卖方确认后积分股将自动划转到您的账户',
|
||||
'卖方确认后积分值将自动划转到您的账户',
|
||||
]
|
||||
: [
|
||||
'买方已确认付款',
|
||||
'请检查您是否已收到转账',
|
||||
'确认收款后积分股将自动划转给买方',
|
||||
'确认收款后积分值将自动划转给买方',
|
||||
];
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1215,7 +1215,7 @@ class _C2cOrderDetailPageState extends ConsumerState<C2cOrderDetailPage> {
|
|||
Text('金额: ${formatAmount(order.totalAmount)} 积分值'),
|
||||
const SizedBox(height: 16),
|
||||
const Text(
|
||||
'确认后,您的积分股将自动划转给买方,此操作不可撤销。',
|
||||
'确认后,您的积分值将自动划转给买方,此操作不可撤销。',
|
||||
style: TextStyle(fontSize: 12, color: _red),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -192,11 +192,9 @@ class _C2cPublishPageState extends ConsumerState<C2cPublishPage> {
|
|||
}
|
||||
|
||||
Widget _buildBalanceCard(String availableShares, String availableCash) {
|
||||
final isBuy = _selectedType == 0;
|
||||
// BUY: 显示可用积分值(用于验证 #16)
|
||||
// SELL: 显示可用积分股(卖方需要有足够积分股)
|
||||
final label = isBuy ? '可用积分值' : '可用积分股';
|
||||
final balance = isBuy ? availableCash : availableShares;
|
||||
// C2C交易对象是积分值,BUY和SELL都显示可用积分值
|
||||
const label = '可用积分值';
|
||||
final balance = availableCash;
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16),
|
||||
|
|
@ -271,16 +269,14 @@ class _C2cPublishPageState extends ConsumerState<C2cPublishPage> {
|
|||
);
|
||||
}
|
||||
|
||||
// #14: 双向输入 — 积分股数量 ↔ 积分值金额(1:1固定价格,两者相等)
|
||||
// #14: 双向输入 — 积分值数量 ↔ 积分值金额(1:1固定价格,两者相等)
|
||||
Widget _buildQuantityInput(
|
||||
String availableShares,
|
||||
String availableCash,
|
||||
String currentPrice,
|
||||
) {
|
||||
final isBuy = _selectedType == 0;
|
||||
// BUY: 买入积分股,用积分值支付 → 上限是可用积分值
|
||||
// SELL: 卖出积分股 → 上限是可用积分股
|
||||
final maxBalance = isBuy ? availableCash : availableShares;
|
||||
// C2C交易的是积分值,BUY和SELL上限都是可用积分值
|
||||
final maxBalance = availableCash;
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16),
|
||||
|
|
@ -302,12 +298,12 @@ class _C2cPublishPageState extends ConsumerState<C2cPublishPage> {
|
|||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
'价格1:1,积分股数量 = 积分值金额',
|
||||
'价格1:1,积分值数量 = 积分值金额',
|
||||
style: const TextStyle(fontSize: 12, color: _grayText),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// 输入框1: 积分股数量
|
||||
// 输入框1: 积分值数量
|
||||
TextField(
|
||||
controller: _quantityController,
|
||||
keyboardType: const TextInputType.numberWithOptions(decimal: true),
|
||||
|
|
@ -315,7 +311,7 @@ class _C2cPublishPageState extends ConsumerState<C2cPublishPage> {
|
|||
FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,4}')),
|
||||
],
|
||||
decoration: InputDecoration(
|
||||
hintText: '请输入积分股数量',
|
||||
hintText: '请输入积分值数量',
|
||||
hintStyle: const TextStyle(color: _grayText),
|
||||
filled: true,
|
||||
fillColor: _bgGray,
|
||||
|
|
@ -343,7 +339,7 @@ class _C2cPublishPageState extends ConsumerState<C2cPublishPage> {
|
|||
),
|
||||
),
|
||||
),
|
||||
suffixText: '积分股',
|
||||
suffixText: '积分值',
|
||||
suffixStyle: const TextStyle(color: _grayText, fontSize: 14),
|
||||
),
|
||||
onChanged: (val) {
|
||||
|
|
@ -679,9 +675,9 @@ class _C2cPublishPageState extends ConsumerState<C2cPublishPage> {
|
|||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text('积分股数量', style: TextStyle(fontSize: 14, color: _grayText)),
|
||||
const Text('积分值数量', style: TextStyle(fontSize: 14, color: _grayText)),
|
||||
Text(
|
||||
'${formatAmount(quantity.toString())} 积分股',
|
||||
'${formatAmount(quantity.toString())} 积分值',
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
|
|
@ -783,11 +779,11 @@ class _C2cPublishPageState extends ConsumerState<C2cPublishPage> {
|
|||
),
|
||||
const SizedBox(height: 8),
|
||||
const Text(
|
||||
'1. 发布卖出广告后,您的积分股将被冻结直到交易完成或取消\n'
|
||||
'1. 发布卖出广告后,您的积分值将被冻结直到交易完成或取消\n'
|
||||
'2. 发布买入广告不会冻结您的资产\n'
|
||||
'3. 其他用户接单后,需在规定时间内完成交易\n'
|
||||
'4. 买方需在1.0系统中向卖方转账绿积分\n'
|
||||
'5. 卖方确认收到绿积分后,积分股自动划转给买方\n'
|
||||
'5. 卖方确认收到绿积分后,积分值自动划转给买方\n'
|
||||
'6. 如遇问题,请联系客服处理',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
|
|
@ -871,7 +867,7 @@ class _C2cPublishPageState extends ConsumerState<C2cPublishPage> {
|
|||
const SizedBox(height: 16),
|
||||
Text(
|
||||
_selectedType == 1
|
||||
? '发布后,您的积分股将被冻结'
|
||||
? '发布后,您的积分值将被冻结'
|
||||
: '发布后不会冻结您的资产',
|
||||
style: const TextStyle(fontSize: 12, color: _grayText),
|
||||
),
|
||||
|
|
|
|||
Loading…
Reference in New Issue