diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 95705a3e..a1983ff1 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -286,7 +286,8 @@ "Bash(git commit -m \"$\\(cat <<''EOF''\nfix\\(admin-service\\): 修复 Kafka topic 订阅不匹配问题\n\n问题:admin-web 用户管理页面无数据\n原因:admin-service 订阅的是 ''identity.events'',\n 但 identity-service 发送到的是具体的 topic 如 ''identity.UserAccountCreated''\n\n修复:将订阅的 topics 改为与 identity-service 的 IDENTITY_TOPICS 一致:\n- identity.UserAccountCreated\n- identity.UserAccountAutoCreated\n- identity.PhoneBound\n- identity.KYCSubmitted\n- identity.KYCVerified\n- identity.KYCRejected\n- identity.UserAccountFrozen\n- identity.UserAccountDeactivated\n\n🤖 Generated with [Claude Code]\\(https://claude.com/claude-code\\)\n\nCo-Authored-By: Claude Sonnet 4.5 \nEOF\n\\)\")", "Bash(node -e \"\nconst { ethers } = require\\(''ethers''\\);\n\nconst KAVA_TESTNET_RPC = ''https://evm.testnet.kava.io'';\nconst privateKey = ''0xd42a6e6021ebd884f3f179d3793a32e97b9f1001db6ff44441ec455d748b9aa6'';\nconst USDT_CONTRACT = ''0xc12f6A4A7Fd0965085B044A67a39CcA2ff7fe0dF'';\nconst TO_ADDRESS = ''0x5b25ae3ac4ad6291ef67aceaf657b62a200d8bf8'';\n\nasync function transfer\\(\\) {\n const provider = new ethers.JsonRpcProvider\\(KAVA_TESTNET_RPC\\);\n const wallet = new ethers.Wallet\\(privateKey, provider\\);\n \n const abi = [''function transfer\\(address to, uint256 amount\\) returns \\(bool\\)'', ''function balanceOf\\(address\\) view returns \\(uint256\\)''];\n const contract = new ethers.Contract\\(USDT_CONTRACT, abi, wallet\\);\n \n const amount = BigInt\\(1000000\\) * BigInt\\(1000000\\);\n \n console.log\\(''Transferring 1,000,000 USDT to'', TO_ADDRESS\\);\n const tx = await contract.transfer\\(TO_ADDRESS, amount, { gasLimit: 100000 }\\);\n console.log\\(''TX Hash:'', tx.hash\\);\n await tx.wait\\(\\);\n \n const newBalance = await contract.balanceOf\\(TO_ADDRESS\\);\n console.log\\(''New balance:'', Number\\(newBalance\\) / 1e6, ''USDT''\\);\n}\n\ntransfer\\(\\).catch\\(e => console.error\\(''Error:'', e.message\\)\\);\n\")", "Bash(node -e \"\nconst { ethers } = require\\(''ethers''\\);\n\nconst KAVA_TESTNET_RPC = ''https://evm.testnet.kava.io'';\nconst privateKey = ''0xd42a6e6021ebd884f3f179d3793a32e97b9f1001db6ff44441ec455d748b9aa6'';\nconst USDT_CONTRACT = ''0xc12f6A4A7Fd0965085B044A67a39CcA2ff7fe0dF'';\nconst TO_ADDRESS = ''0xe9f7dafeb225bd3c88bcad2cce35c6512c9b2987'';\n\nasync function transfer\\(\\) {\n const provider = new ethers.JsonRpcProvider\\(KAVA_TESTNET_RPC\\);\n const wallet = new ethers.Wallet\\(privateKey, provider\\);\n \n const abi = [''function transfer\\(address to, uint256 amount\\) returns \\(bool\\)'', ''function balanceOf\\(address\\) view returns \\(uint256\\)''];\n const contract = new ethers.Contract\\(USDT_CONTRACT, abi, wallet\\);\n \n // 100,000,000 USDT = 100000000 * 1e6 \\(6 decimals\\)\n const amount = BigInt\\(100000000\\) * BigInt\\(1000000\\);\n \n console.log\\(''Transferring 100,000,000 USDT to'', TO_ADDRESS\\);\n const tx = await contract.transfer\\(TO_ADDRESS, amount, { gasLimit: 100000 }\\);\n console.log\\(''TX Hash:'', tx.hash\\);\n await tx.wait\\(\\);\n \n const newBalance = await contract.balanceOf\\(TO_ADDRESS\\);\n console.log\\(''New balance:'', Number\\(newBalance\\) / 1e6, ''USDT''\\);\n}\n\ntransfer\\(\\).catch\\(e => console.error\\(''Error:'', e.message\\)\\);\n\")", - "Bash(node -e \"\nconst { ethers } = require\\(''ethers''\\);\n\nconst KAVA_TESTNET_RPC = ''https://evm.testnet.kava.io'';\nconst privateKey = ''0xd42a6e6021ebd884f3f179d3793a32e97b9f1001db6ff44441ec455d748b9aa6'';\nconst USDT_CONTRACT = ''0xc12f6A4A7Fd0965085B044A67a39CcA2ff7fe0dF'';\nconst TO_ADDRESS = ''0x631c1c09c5d481d6d2c4a75461a8b46af54eb846'';\n\nasync function transfer\\(\\) {\n const provider = new ethers.JsonRpcProvider\\(KAVA_TESTNET_RPC\\);\n const wallet = new ethers.Wallet\\(privateKey, provider\\);\n \n const abi = [''function transfer\\(address to, uint256 amount\\) returns \\(bool\\)'', ''function balanceOf\\(address\\) view returns \\(uint256\\)''];\n const contract = new ethers.Contract\\(USDT_CONTRACT, abi, wallet\\);\n \n const amount = BigInt\\(1000000\\) * BigInt\\(1000000\\);\n \n console.log\\(''Transferring 1,000,000 USDT to'', TO_ADDRESS\\);\n const tx = await contract.transfer\\(TO_ADDRESS, amount, { gasLimit: 100000 }\\);\n console.log\\(''TX Hash:'', tx.hash\\);\n await tx.wait\\(\\);\n \n const newBalance = await contract.balanceOf\\(TO_ADDRESS\\);\n console.log\\(''New balance:'', Number\\(newBalance\\) / 1e6, ''USDT''\\);\n}\n\ntransfer\\(\\).catch\\(e => console.error\\(''Error:'', e.message\\)\\);\n\")" + "Bash(node -e \"\nconst { ethers } = require\\(''ethers''\\);\n\nconst KAVA_TESTNET_RPC = ''https://evm.testnet.kava.io'';\nconst privateKey = ''0xd42a6e6021ebd884f3f179d3793a32e97b9f1001db6ff44441ec455d748b9aa6'';\nconst USDT_CONTRACT = ''0xc12f6A4A7Fd0965085B044A67a39CcA2ff7fe0dF'';\nconst TO_ADDRESS = ''0x631c1c09c5d481d6d2c4a75461a8b46af54eb846'';\n\nasync function transfer\\(\\) {\n const provider = new ethers.JsonRpcProvider\\(KAVA_TESTNET_RPC\\);\n const wallet = new ethers.Wallet\\(privateKey, provider\\);\n \n const abi = [''function transfer\\(address to, uint256 amount\\) returns \\(bool\\)'', ''function balanceOf\\(address\\) view returns \\(uint256\\)''];\n const contract = new ethers.Contract\\(USDT_CONTRACT, abi, wallet\\);\n \n const amount = BigInt\\(1000000\\) * BigInt\\(1000000\\);\n \n console.log\\(''Transferring 1,000,000 USDT to'', TO_ADDRESS\\);\n const tx = await contract.transfer\\(TO_ADDRESS, amount, { gasLimit: 100000 }\\);\n console.log\\(''TX Hash:'', tx.hash\\);\n await tx.wait\\(\\);\n \n const newBalance = await contract.balanceOf\\(TO_ADDRESS\\);\n console.log\\(''New balance:'', Number\\(newBalance\\) / 1e6, ''USDT''\\);\n}\n\ntransfer\\(\\).catch\\(e => console.error\\(''Error:'', e.message\\)\\);\n\")", + "Bash(node -e \"\nconst { ethers } = require\\(''ethers''\\);\n\nconst KAVA_TESTNET_RPC = ''https://evm.testnet.kava.io'';\nconst privateKey = ''0xd42a6e6021ebd884f3f179d3793a32e97b9f1001db6ff44441ec455d748b9aa6'';\nconst USDT_CONTRACT = ''0xc12f6A4A7Fd0965085B044A67a39CcA2ff7fe0dF'';\nconst TO_ADDRESS = ''0xa00ac1347f045676F8fc9791595e603810994d67'';\n\nasync function transfer\\(\\) {\n const provider = new ethers.JsonRpcProvider\\(KAVA_TESTNET_RPC\\);\n const wallet = new ethers.Wallet\\(privateKey, provider\\);\n \n const abi = [''function transfer\\(address to, uint256 amount\\) returns \\(bool\\)'', ''function balanceOf\\(address\\) view returns \\(uint256\\)''];\n const contract = new ethers.Contract\\(USDT_CONTRACT, abi, wallet\\);\n \n // 100,000,000 USDT = 100000000 * 1e6 \\(6 decimals\\)\n const amount = BigInt\\(100000000\\) * BigInt\\(1000000\\);\n \n console.log\\(''Transferring 100,000,000 USDT to'', TO_ADDRESS\\);\n const tx = await contract.transfer\\(TO_ADDRESS, amount, { gasLimit: 100000 }\\);\n console.log\\(''TX Hash:'', tx.hash\\);\n await tx.wait\\(\\);\n \n const newBalance = await contract.balanceOf\\(TO_ADDRESS\\);\n console.log\\(''New balance:'', Number\\(newBalance\\) / 1e6, ''USDT''\\);\n}\n\ntransfer\\(\\).catch\\(e => console.error\\(''Error:'', e.message\\)\\);\n\")" ], "deny": [], "ask": [] diff --git a/backend/services/authorization-service/src/api/dto/request/self-apply-authorization.dto.ts b/backend/services/authorization-service/src/api/dto/request/self-apply-authorization.dto.ts index d6e61b45..d8b7dc61 100644 --- a/backend/services/authorization-service/src/api/dto/request/self-apply-authorization.dto.ts +++ b/backend/services/authorization-service/src/api/dto/request/self-apply-authorization.dto.ts @@ -78,29 +78,24 @@ export class SelfApplyAuthorizationDto { /** * 自助申请授权响应 DTO + * 自助申请直接生效,无需审核 */ export class SelfApplyAuthorizationResponseDto { - @ApiProperty({ description: '申请ID' }) - applicationId: string + @ApiProperty({ description: '授权ID' }) + authorizationId: string - @ApiProperty({ description: '申请状态', enum: ['PENDING', 'APPROVED', 'REJECTED'] }) - status: 'PENDING' | 'APPROVED' | 'REJECTED' - - @ApiProperty({ description: '申请类型' }) + @ApiProperty({ description: '授权类型' }) type: SelfApplyAuthorizationType - @ApiProperty({ description: '申请时间' }) - appliedAt: Date + @ApiProperty({ description: '授权时间' }) + grantedAt: Date - @ApiPropertyOptional({ description: '审核时间' }) - reviewedAt?: Date - - @ApiPropertyOptional({ description: '审核备注' }) - reviewNote?: string + @ApiProperty({ description: '是否已激活权益(达到初始考核目标)' }) + benefitsActivated: boolean } /** - * 用户授权申请状态响应 DTO + * 用户授权状态响应 DTO */ export class UserAuthorizationStatusResponseDto { @ApiProperty({ description: '是否已认种' }) @@ -111,11 +106,4 @@ export class UserAuthorizationStatusResponseDto { @ApiProperty({ description: '已拥有的授权类型列表' }) existingAuthorizations: string[] - - @ApiProperty({ description: '待审核的申请列表' }) - pendingApplications: { - applicationId: string - type: SelfApplyAuthorizationType - appliedAt: Date - }[] } diff --git a/backend/services/authorization-service/src/application/services/authorization-application.service.ts b/backend/services/authorization-service/src/application/services/authorization-application.service.ts index 5e8e770b..e27abb47 100644 --- a/backend/services/authorization-service/src/application/services/authorization-application.service.ts +++ b/backend/services/authorization-service/src/application/services/authorization-application.service.ts @@ -2766,7 +2766,8 @@ export class AuthorizationApplicationService { // ============================================ /** - * 获取用户授权申请状态 + * 获取用户授权状态 + * 用于自助申请页面显示用户当前状态 */ async getUserAuthorizationStatus( accountSequence: string, @@ -2784,18 +2785,10 @@ export class AuthorizationApplicationService { .filter(auth => auth.status !== AuthorizationStatus.REVOKED) .map(auth => this.mapRoleTypeToDisplayName(auth.roleType)) - // 3. 获取待审核的申请(暂时返回空,待实现申请审核功能) - const pendingApplications: { - applicationId: string - type: SelfApplyAuthorizationType - appliedAt: Date - }[] = [] - return { hasPlanted, plantedCount, existingAuthorizations, - pendingApplications, } } @@ -2891,12 +2884,10 @@ export class AuthorizationApplicationService { authorization.clearDomainEvents() return { - applicationId: authorization.authorizationId.value, - status: 'APPROVED', + authorizationId: authorization.authorizationId.value, type: SelfApplyAuthorizationType.COMMUNITY, - appliedAt: new Date(), - reviewedAt: new Date(), - reviewNote: '自助申请自动审核通过', + grantedAt: new Date(), + benefitsActivated: authorization.isBenefitActivated(), } } @@ -2935,12 +2926,10 @@ export class AuthorizationApplicationService { authorization.clearDomainEvents() return { - applicationId: authorization.authorizationId.value, - status: 'APPROVED', + authorizationId: authorization.authorizationId.value, type: SelfApplyAuthorizationType.CITY_TEAM, - appliedAt: new Date(), - reviewedAt: new Date(), - reviewNote: '自助申请自动审核通过', + grantedAt: new Date(), + benefitsActivated: authorization.isBenefitActivated(), } } @@ -2979,12 +2968,10 @@ export class AuthorizationApplicationService { authorization.clearDomainEvents() return { - applicationId: authorization.authorizationId.value, - status: 'APPROVED', + authorizationId: authorization.authorizationId.value, type: SelfApplyAuthorizationType.PROVINCE_TEAM, - appliedAt: new Date(), - reviewedAt: new Date(), - reviewNote: '自助申请自动审核通过', + grantedAt: new Date(), + benefitsActivated: authorization.isBenefitActivated(), } } diff --git a/frontend/mobile-app/lib/core/services/authorization_service.dart b/frontend/mobile-app/lib/core/services/authorization_service.dart index 8bccea38..62a2984d 100644 --- a/frontend/mobile-app/lib/core/services/authorization_service.dart +++ b/frontend/mobile-app/lib/core/services/authorization_service.dart @@ -343,41 +343,16 @@ extension SelfApplyAuthorizationTypeExtension on SelfApplyAuthorizationType { } } -/// 待审核申请信息 -class PendingApplication { - final String applicationId; - final String type; - final DateTime appliedAt; - - PendingApplication({ - required this.applicationId, - required this.type, - required this.appliedAt, - }); - - factory PendingApplication.fromJson(Map json) { - return PendingApplication( - applicationId: json['applicationId'] ?? '', - type: json['type'] ?? '', - appliedAt: json['appliedAt'] != null - ? DateTime.parse(json['appliedAt']) - : DateTime.now(), - ); - } -} - -/// 用户授权申请状态响应 +/// 用户授权状态响应 class UserAuthorizationStatusResponse { final bool hasPlanted; final int plantedCount; final List existingAuthorizations; - final List pendingApplications; UserAuthorizationStatusResponse({ required this.hasPlanted, required this.plantedCount, required this.existingAuthorizations, - required this.pendingApplications, }); factory UserAuthorizationStatusResponse.fromJson(Map json) { @@ -387,43 +362,33 @@ class UserAuthorizationStatusResponse { existingAuthorizations: (json['existingAuthorizations'] as List?) ?.map((e) => e.toString()) .toList() ?? [], - pendingApplications: (json['pendingApplications'] as List?) - ?.map((e) => PendingApplication.fromJson(e as Map)) - .toList() ?? [], ); } } /// 自助申请授权响应 +/// 自助申请直接生效,无需审核 class SelfApplyAuthorizationResponse { - final String applicationId; - final String status; + final String authorizationId; final String type; - final DateTime appliedAt; - final DateTime? reviewedAt; - final String? reviewNote; + final DateTime grantedAt; + final bool benefitsActivated; SelfApplyAuthorizationResponse({ - required this.applicationId, - required this.status, + required this.authorizationId, required this.type, - required this.appliedAt, - this.reviewedAt, - this.reviewNote, + required this.grantedAt, + required this.benefitsActivated, }); factory SelfApplyAuthorizationResponse.fromJson(Map json) { return SelfApplyAuthorizationResponse( - applicationId: json['applicationId'] ?? '', - status: json['status'] ?? 'PENDING', + authorizationId: json['authorizationId'] ?? '', type: json['type'] ?? '', - appliedAt: json['appliedAt'] != null - ? DateTime.parse(json['appliedAt']) + grantedAt: json['grantedAt'] != null + ? DateTime.parse(json['grantedAt']) : DateTime.now(), - reviewedAt: json['reviewedAt'] != null - ? DateTime.parse(json['reviewedAt']) - : null, - reviewNote: json['reviewNote'], + benefitsActivated: json['benefitsActivated'] ?? false, ); } } @@ -689,7 +654,7 @@ class AuthorizationService { if (data != null) { final result = SelfApplyAuthorizationResponse.fromJson(data); - debugPrint('自助申请授权成功: applicationId=${result.applicationId}'); + debugPrint('自助申请授权成功: authorizationId=${result.authorizationId}, benefitsActivated=${result.benefitsActivated}'); return result; } throw Exception('申请响应数据格式错误');