feat(c2c): 卖单自动获取账户ID和Kava地址,移除手动输入
后端创建卖单时自动从 identity-service 获取卖家 Kava 地址并存入订单, 前端发布页面自动展示 accountSequence(只读),不再需要手动输入1.0系统ID。 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
2b7a30983e
commit
263f1ecf8e
|
|
@ -57,6 +57,8 @@ export class C2cController {
|
|||
paymentAccount: order.paymentAccount || undefined,
|
||||
paymentQrCode: order.paymentQrCode || undefined,
|
||||
paymentRealName: order.paymentRealName || undefined,
|
||||
// 卖家 Kava 地址
|
||||
sellerKavaAddress: order.sellerKavaAddress || undefined,
|
||||
// 超时信息
|
||||
paymentTimeoutMinutes: order.paymentTimeoutMinutes,
|
||||
confirmTimeoutMinutes: order.confirmTimeoutMinutes,
|
||||
|
|
|
|||
|
|
@ -168,6 +168,8 @@ export class C2cOrderResponseDto {
|
|||
paymentAccount?: string;
|
||||
paymentQrCode?: string;
|
||||
paymentRealName?: string;
|
||||
// 卖家 Kava 地址(绿积分转账地址)
|
||||
sellerKavaAddress?: string;
|
||||
// 超时信息
|
||||
paymentTimeoutMinutes: number;
|
||||
confirmTimeoutMinutes: number;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { C2cOrderRepository, C2cOrderEntity } from '../../infrastructure/persist
|
|||
import { TradingAccountRepository } from '../../infrastructure/persistence/repositories/trading-account.repository';
|
||||
import { RedisService } from '../../infrastructure/redis/redis.service';
|
||||
import { PrismaService } from '../../infrastructure/persistence/prisma/prisma.service';
|
||||
import { IdentityClient } from '../../infrastructure/identity/identity.client';
|
||||
import { Money } from '../../domain/value-objects/money.vo';
|
||||
import Decimal from 'decimal.js';
|
||||
|
||||
|
|
@ -57,6 +58,7 @@ export class C2cService {
|
|||
private readonly tradingAccountRepository: TradingAccountRepository,
|
||||
private readonly redis: RedisService,
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly identityClient: IdentityClient,
|
||||
) {}
|
||||
|
||||
/**
|
||||
|
|
@ -109,16 +111,12 @@ export class C2cService {
|
|||
throw new BadRequestException('数量必须大于0');
|
||||
}
|
||||
|
||||
// 卖单必须提供收款信息
|
||||
// 卖单:自动获取卖家 Kava 地址(用于绿积分转账)
|
||||
let sellerKavaAddress: string | null = null;
|
||||
if (type === C2C_ORDER_TYPE.SELL) {
|
||||
if (!options?.paymentMethod) {
|
||||
throw new BadRequestException('卖单必须提供收款方式');
|
||||
}
|
||||
if (!options?.paymentAccount) {
|
||||
throw new BadRequestException('卖单必须提供收款账号');
|
||||
}
|
||||
if (!options?.paymentRealName) {
|
||||
throw new BadRequestException('卖单必须提供收款人实名');
|
||||
sellerKavaAddress = await this.identityClient.getUserKavaAddress(accountSequence);
|
||||
if (!sellerKavaAddress) {
|
||||
throw new BadRequestException('未找到您的 Kava 钱包地址,请先绑定钱包');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -169,6 +167,8 @@ export class C2cService {
|
|||
paymentAccount: options?.paymentAccount,
|
||||
paymentQrCode: options?.paymentQrCode,
|
||||
paymentRealName: options?.paymentRealName,
|
||||
// 卖家 Kava 地址(卖单时自动获取)
|
||||
sellerKavaAddress,
|
||||
remark: options?.remark,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -111,6 +111,8 @@ export class C2cOrderRepository {
|
|||
paymentAccount?: string;
|
||||
paymentQrCode?: string;
|
||||
paymentRealName?: string;
|
||||
// 卖家 Kava 地址
|
||||
sellerKavaAddress?: string | null;
|
||||
remark?: string;
|
||||
}): Promise<C2cOrderEntity> {
|
||||
const record = await this.prisma.c2cOrder.create({
|
||||
|
|
@ -132,6 +134,8 @@ export class C2cOrderRepository {
|
|||
paymentAccount: data.paymentAccount,
|
||||
paymentQrCode: data.paymentQrCode,
|
||||
paymentRealName: data.paymentRealName,
|
||||
// 卖家 Kava 地址
|
||||
sellerKavaAddress: data.sellerKavaAddress,
|
||||
remark: data.remark,
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -108,7 +108,6 @@ abstract class TradingRemoteDataSource {
|
|||
String? paymentAccount,
|
||||
String? paymentQrCode,
|
||||
String? paymentRealName,
|
||||
String? systemId, // 1.0系统ID(绿积分支付必填)
|
||||
String? remark,
|
||||
});
|
||||
|
||||
|
|
@ -467,7 +466,6 @@ class TradingRemoteDataSourceImpl implements TradingRemoteDataSource {
|
|||
String? paymentAccount,
|
||||
String? paymentQrCode,
|
||||
String? paymentRealName,
|
||||
String? systemId, // 1.0系统ID(绿积分支付必填)
|
||||
String? remark,
|
||||
}) async {
|
||||
try {
|
||||
|
|
@ -483,7 +481,6 @@ class TradingRemoteDataSourceImpl implements TradingRemoteDataSource {
|
|||
if (paymentAccount != null) data['paymentAccount'] = paymentAccount;
|
||||
if (paymentQrCode != null) data['paymentQrCode'] = paymentQrCode;
|
||||
if (paymentRealName != null) data['paymentRealName'] = paymentRealName;
|
||||
if (systemId != null && systemId.isNotEmpty) data['systemId'] = systemId;
|
||||
if (remark != null && remark.isNotEmpty) data['remark'] = remark;
|
||||
|
||||
final response = await client.post(
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ class _C2cPublishPageState extends ConsumerState<C2cPublishPage> {
|
|||
Set<String> _selectedPaymentMethods = {'GREEN_POINTS'}; // 绿积分默认选中且不可取消
|
||||
final _paymentAccountController = TextEditingController();
|
||||
final _paymentRealNameController = TextEditingController();
|
||||
final _systemIdController = TextEditingController(); // 1.0系统ID
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
|
|
@ -41,7 +40,6 @@ class _C2cPublishPageState extends ConsumerState<C2cPublishPage> {
|
|||
_remarkController.dispose();
|
||||
_paymentAccountController.dispose();
|
||||
_paymentRealNameController.dispose();
|
||||
_systemIdController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
@ -400,32 +398,27 @@ class _C2cPublishPageState extends ConsumerState<C2cPublishPage> {
|
|||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// 1.0系统ID(绿积分必填)
|
||||
// 账户ID(自动读取,只读)
|
||||
const Text(
|
||||
'1.0系统ID',
|
||||
'账户ID',
|
||||
style: TextStyle(fontSize: 14, color: _grayText),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
const Text(
|
||||
'买家将通过此ID向您转账绿积分',
|
||||
'买家将通过此账户向您转账绿积分',
|
||||
style: TextStyle(fontSize: 12, color: _grayText),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
TextField(
|
||||
controller: _systemIdController,
|
||||
decoration: InputDecoration(
|
||||
hintText: '请输入您的1.0系统ID',
|
||||
hintStyle: const TextStyle(color: _grayText),
|
||||
filled: true,
|
||||
fillColor: _bgGray,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: const BorderSide(color: _orange, width: 2),
|
||||
),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||||
decoration: BoxDecoration(
|
||||
color: _bgGray,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Text(
|
||||
ref.watch(userNotifierProvider).accountSequence ?? '',
|
||||
style: const TextStyle(fontSize: 15, color: _darkText),
|
||||
),
|
||||
),
|
||||
|
||||
|
|
@ -675,8 +668,6 @@ class _C2cPublishPageState extends ConsumerState<C2cPublishPage> {
|
|||
// 验证条件
|
||||
bool isValid = price > 0 && quantity > 0;
|
||||
if (isSell) {
|
||||
// 卖单必须填写1.0系统ID(因为绿积分是必选的)
|
||||
isValid = isValid && _systemIdController.text.trim().isNotEmpty;
|
||||
// 如果选择了其他支付方式,还需要填写收款账号和姓名
|
||||
if (_selectedPaymentMethods.any((m) => m != 'GREEN_POINTS')) {
|
||||
isValid = isValid &&
|
||||
|
|
@ -774,13 +765,6 @@ class _C2cPublishPageState extends ConsumerState<C2cPublishPage> {
|
|||
|
||||
// 卖单验证收款信息
|
||||
if (isSell) {
|
||||
// 必须填写1.0系统ID(绿积分是必选的)
|
||||
if (_systemIdController.text.trim().isEmpty) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('请填写1.0系统ID'), backgroundColor: _red),
|
||||
);
|
||||
return;
|
||||
}
|
||||
// 如果选择了其他支付方式,需要填写收款账号和姓名
|
||||
if (_selectedPaymentMethods.any((m) => m != 'GREEN_POINTS')) {
|
||||
if (_paymentAccountController.text.trim().isEmpty) {
|
||||
|
|
@ -832,7 +816,7 @@ class _C2cPublishPageState extends ConsumerState<C2cPublishPage> {
|
|||
const SizedBox(height: 8),
|
||||
Text('收款方式: $paymentMethodTexts'),
|
||||
const SizedBox(height: 4),
|
||||
Text('1.0系统ID: ${_systemIdController.text.trim()}'),
|
||||
Text('账户ID: ${ref.read(userNotifierProvider).accountSequence ?? ''}'),
|
||||
if (_selectedPaymentMethods.any((m) => m != 'GREEN_POINTS')) ...[
|
||||
const SizedBox(height: 4),
|
||||
Text('收款账号: ${_paymentAccountController.text.trim()}'),
|
||||
|
|
@ -874,7 +858,6 @@ class _C2cPublishPageState extends ConsumerState<C2cPublishPage> {
|
|||
paymentMethod: isSell ? _selectedPaymentMethods.join(',') : null,
|
||||
paymentAccount: isSell ? _paymentAccountController.text.trim() : null,
|
||||
paymentRealName: isSell ? _paymentRealNameController.text.trim() : null,
|
||||
systemId: isSell ? _systemIdController.text.trim() : null,
|
||||
remark: remark.isEmpty ? null : remark,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@ class C2cTradingNotifier extends StateNotifier<C2cTradingState> {
|
|||
String? paymentAccount,
|
||||
String? paymentQrCode,
|
||||
String? paymentRealName,
|
||||
String? systemId, // 1.0系统ID(绿积分支付必填)
|
||||
String? remark,
|
||||
}) async {
|
||||
state = state.copyWith(isLoading: true, clearError: true);
|
||||
|
|
@ -102,7 +101,6 @@ class C2cTradingNotifier extends StateNotifier<C2cTradingState> {
|
|||
paymentAccount: paymentAccount,
|
||||
paymentQrCode: paymentQrCode,
|
||||
paymentRealName: paymentRealName,
|
||||
systemId: systemId,
|
||||
remark: remark,
|
||||
);
|
||||
state = state.copyWith(isLoading: false, lastOrder: order);
|
||||
|
|
|
|||
Loading…
Reference in New Issue