From 14cb99264702454a264610815d2a92ef2eb5d3cf Mon Sep 17 00:00:00 2001
From: wenminjie <1036699586@qq.com>
Date: 星期三, 05 八月 2026 16:04:13 +0800
Subject: [PATCH] 二期后端小程序对接:亲属卡审批查询

---
 rencaika/config/api.uts                                                                                  |    4 
 talent-card-server/src/main/java/com/talentcard/server/business/portal/FamilyCardPortalService.java      |   75 ++++++++++++++++++
 talent-card-server/src/main/java/com/talentcard/server/service/DependentCardApplyService.java            |   16 ++--
 rencaika/pages/family-card-apply/family-card-apply.uvue                                                  |   28 +++++-
 rencaika/services/portal.uts                                                                             |   18 +++-
 talent-card-server/src/main/java/com/talentcard/server/business/portal/DependentCardApplyController.java |   16 ++--
 rencaika/pages/family-card/family-card.uvue                                                              |   36 +++++++-
 talent-card-server/src/main/java/com/talentcard/server/business/portal/FamilyCardPortalController.java   |    1 
 8 files changed, 155 insertions(+), 39 deletions(-)

diff --git a/rencaika/config/api.uts b/rencaika/config/api.uts
index 9fbd12d..ddaf402 100644
--- a/rencaika/config/api.uts
+++ b/rencaika/config/api.uts
@@ -5,7 +5,7 @@
 export const developmentLoginBypassEnabled: boolean = false 
 
 // 后台提供合法域名后仅在此处填写,业务页面不得硬编码域名。
-const developmentBaseUrl = 'http://192.168.110.13:8080'
+const developmentBaseUrl = 'http://192.168.110.8:8080'
 const stagingBaseUrl = ''
 const productionBaseUrl = ''
 
@@ -69,7 +69,7 @@
 	if (name == 'appCompletedOrders') return '/api/app/completed-orders/'
 	if (name == 'appCancelledOrders') return '/api/app/cancelled-orders/'
 	if (name == 'appProcessingApplications') return '/api/app/processing-applications/'
-	if (name == 'appFamilyCards') return '/api/app/family-cards'
+	if (name == 'appFamilyCards') return '/api/app/family-cards/applications'
 	if (name == 'appFreeBenefits') return '/api/app/free-benefits'
 	if (name == 'appAgreements') return '/api/app/agreements/'
 	if (name == 'appUploadImage') return '/api/app/uploads/images'
diff --git a/rencaika/pages/family-card-apply/family-card-apply.uvue b/rencaika/pages/family-card-apply/family-card-apply.uvue
index 56ebecd..8e13c82 100644
--- a/rencaika/pages/family-card-apply/family-card-apply.uvue
+++ b/rencaika/pages/family-card-apply/family-card-apply.uvue
@@ -35,8 +35,9 @@
 
 <script setup lang="uts">
 	import { apiEnvironment } from '../../config/api.uts'
-	import { createFamilyCardApplication } from '../../services/portal.uts'
+	import { createFamilyCardApplication, getTalentCardProfile } from '../../services/portal.uts'
 	import { safeBack } from '../../utils/navigation.uts'
+	const goBack = () => safeBack('/pages/family-card/family-card')
 
 	const navTop = ref(28)
 	const navHeight = ref(32)
@@ -47,6 +48,7 @@
 	const relationIndex = ref(0)
 	const form = ref({ name: '', idCard: '', phone: '', relation: '配偶' })
 	const talentId = ref('')
+	const talentCardId = ref('')
 
 	onLoad((options: any) => {
 		// #ifdef MP-WEIXIN
@@ -58,9 +60,16 @@
 		navRight.value = systemInfo.windowWidth - capsule.right
 		// #endif
 		talentId.value = options != null && options['talentId'] != null ? options['talentId'] as string : (apiEnvironment == 'development' ? '2' : '')
+		resolveTalentCardId()
 	})
 
-	const goBack = () => safeBack('/pages/family-card/family-card')
+	const resolveTalentCardId = () => {
+		if (talentId.value == '') return
+		getTalentCardProfile(talentId.value, (data: any) => {
+			const card = data != null ? data.card : null
+			talentCardId.value = card != null && card.id != null ? '' + card.id : ''
+		}, () => {})
+	}
 	const changeRelation = (event: any) => {
 		const selectedIndex = parseInt(event.detail.value as string)
 		relationIndex.value = selectedIndex
@@ -82,13 +91,18 @@
 			uni.showToast({ title: '请填写正确的手机号', icon: 'none' })
 			return
 		}
+		if (talentCardId.value == '') {
+			isSubmitting.value = false
+			uni.showToast({ title: '未获取到主卡信息,请返回重试', icon: 'none' })
+			return
+		}
 		isSubmitting.value = true
-		createFamilyCardApplication({ talentId: Number(talentId.value), name: form.value.name.trim(), idCard: form.value.idCard.trim(), mobile: form.value.phone.trim(), relationship: form.value.relation }, (data: any) => {
+		createFamilyCardApplication(talentCardId.value, form.value.name.trim(), form.value.idCard.trim(), form.value.phone.trim(), form.value.relation, (data: any) => {
 			uni.setStorageSync('familyCardApplicationResult', {
-				name: data.name || '',
-				relationship: data.relationship || '',
-				applicationNo: data.applicationNo || '',
-				estimatedProcessingTime: data.estimatedProcessingTime || '资料已提交,请耐心等待审核。'
+				name: form.value.name.trim(),
+				relationship: form.value.relation,
+				applicationNo: '',
+				estimatedProcessingTime: '资料已提交,请耐心等待审核。'
 			})
 			uni.redirectTo({ url: '/pages/family-card-success/family-card-success' })
 		}, (error) => {
diff --git a/rencaika/pages/family-card/family-card.uvue b/rencaika/pages/family-card/family-card.uvue
index 1554dc1..40f4c98 100644
--- a/rencaika/pages/family-card/family-card.uvue
+++ b/rencaika/pages/family-card/family-card.uvue
@@ -40,7 +40,7 @@
 
 <script setup lang="uts">
 	import { apiEnvironment } from '../../config/api.uts'
-	import { getFamilyCards } from '../../services/portal.uts'
+	import { getFamilyCards, getTalentCardProfile } from '../../services/portal.uts'
 	import { safeBack } from '../../utils/navigation.uts'
 
 	const navTop = ref(28)
@@ -51,6 +51,7 @@
 	const loading = ref(true)
 	const loadError = ref(false)
 	const talentId = ref('')
+	const talentCardId = ref('')
 	const canUnbind = ref(false)
 
 	onLoad((options: any) => {
@@ -63,18 +64,41 @@
 		navRight.value = systemInfo.windowWidth - capsule.right
 		// #endif
 		talentId.value = options != null && options['talentId'] != null ? options['talentId'] as string : (apiEnvironment == 'development' ? '2' : '')
-		loadFamilyCards()
+		resolveTalentCardId()
 	})
 	onShow(() => {
-		if (talentId.value != '') loadFamilyCards()
+		if (talentCardId.value != '') loadFamilyCards()
 	})
-
 	const goBack = () => safeBack('/pages/profile/profile')
-	const loadFamilyCards = () => {
+
+	const resolveTalentCardId = () => {
 		if (talentId.value == '') { loading.value = false; loadError.value = true; return }
+		getTalentCardProfile(talentId.value, (data: any) => {
+			const card = data != null ? data.card : null
+			talentCardId.value = card != null && card.id != null ? '' + card.id : ''
+			if (talentCardId.value == '') { loading.value = false; loadError.value = true; return }
+			loadFamilyCards()
+		}, () => { loading.value = false; loadError.value = true })
+	}
+	const loadFamilyCards = () => {
+		if (talentCardId.value == '') { loading.value = false; loadError.value = true; return }
 		loading.value = true
 		loadError.value = false
-		getFamilyCards(talentId.value, (data: any) => { familyMembers.value = data as any[]; canUnbind.value = familyMembers.value.some((item: any) => item.canUnbind === true); loading.value = false }, () => { loading.value = false; loadError.value = true })
+				getFamilyCards(talentCardId.value, (data: any) => {
+			const items = (data as any[]) || []
+			familyMembers.value = items.map((item: any) => ({
+				id: item.id,
+				name: item.dependentName != null ? item.dependentName : '',
+				initial: item.dependentName != null && item.dependentName.length > 0 ? item.dependentName.substring(0, 1) : '',
+				relationship: item.relation != null ? item.relation : '',
+				mobile: item.dependentMobile != null ? item.dependentMobile : '',
+				statusText: item.statusText != null ? item.statusText : '',
+				status: item.status,
+				canUnbind: item.status === 1
+			}))
+			canUnbind.value = familyMembers.value.some((item: any) => item.canUnbind === true)
+			loading.value = false
+		}, () => { loading.value = false; loadError.value = true })
 	}
 	const addApplication = () => uni.navigateTo({ url: '/pages/family-card-apply/family-card-apply?talentId=' + encodeURIComponent(talentId.value) })
 	const unbindFamily = () => {
diff --git a/rencaika/services/portal.uts b/rencaika/services/portal.uts
index 67c615b..cbbec3f 100644
--- a/rencaika/services/portal.uts
+++ b/rencaika/services/portal.uts
@@ -188,11 +188,21 @@
 export const getCompletedOrder = (orderNo: string, talentId: string, onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => request<any>({ path: getApiEndpoint('appCompletedOrders') + encodeURIComponent(orderNo), method: 'GET', skipAuth: true, data: { talentId: talentId } }, onSuccess, onError)
 export const getCancelledOrder = (orderNo: string, talentId: string, onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => request<any>({ path: getApiEndpoint('appCancelledOrders') + encodeURIComponent(orderNo), method: 'GET', skipAuth: true, data: { talentId: talentId } }, onSuccess, onError)
 export const getProcessingApplication = (applicationNo: string, talentId: string, onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => request<any>({ path: getApiEndpoint('appProcessingApplications') + encodeURIComponent(applicationNo), method: 'GET', skipAuth: true, data: { talentId: talentId } }, onSuccess, onError)
-export const getFamilyCards = (talentId: string, onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => request<any>({ path: getApiEndpoint('appFamilyCards'), method: 'GET', skipAuth: true, data: { talentId: talentId } }, onSuccess, onError)
+export const getFamilyCards = (talentCardId: string, onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => request<any>({ path: getApiEndpoint('appFamilyCards'), method: 'GET', skipAuth: true, data: { talentCardId: Number(talentCardId) } }, onSuccess, onError)
 export const getFreeBenefit = (talentId: string, merchantId: string, onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => request<any>({ path: getApiEndpoint('appFreeBenefits'), method: 'GET', skipAuth: true, data: { talentId: talentId, merchantId: merchantId } }, onSuccess, onError)
 export const issueFreeBenefitCode = (talentId: string, merchantId: string, onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => request<any>({ path: getApiEndpoint('appFreeBenefits') + '/dynamic-code', method: 'POST', skipAuth: true, data: { talentId: Number(talentId), merchantId: Number(merchantId) } }, onSuccess, onError)
-export const createFamilyCardApplication = (payload: any, onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => request<any>({ path: getApiEndpoint('appFamilyCards') + '/applications', method: 'POST', skipAuth: true, data: payload, idempotencyKey: 'family-card-apply-' + Date.now() }, onSuccess, onError)
-export const unbindFamilyCard = (applicationId: string, talentId: string, onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => request<any>({ path: getApiEndpoint('appFamilyCards') + '/' + encodeURIComponent(applicationId) + '/unbind', method: 'POST', skipAuth: true, data: { talentId: Number(talentId) }, idempotencyKey: 'family-card-unbind-' + applicationId }, onSuccess, onError)
-export const unbindFamilyCards = (applicationIds: string[], talentId: string, onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => request<any>({ path: getApiEndpoint('appFamilyCards') + '/unbind', method: 'POST', skipAuth: true, data: { talentId: Number(talentId), applicationIds: applicationIds.map((id: string) => Number(id)) }, idempotencyKey: 'family-card-unbind-' + applicationIds.join('-') }, onSuccess, onError)
+export const createFamilyCardApplication = (talentCardId: string, dependentName: string, dependentIdCardNo: string, dependentMobile: string, relation: string, onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => request<any>({ path: getApiEndpoint('appFamilyCards'), method: 'POST', skipAuth: true, data: { talentCardId: Number(talentCardId), dependentName: dependentName, dependentIdCardNo: dependentIdCardNo, dependentMobile: dependentMobile, relation: relation }, idempotencyKey: 'family-card-apply-' + talentCardId + '-' + Date.now() }, onSuccess, onError)
+export const unbindFamilyCard = (applicationId: string, talentCardId: string, onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => request<any>({ path: getApiEndpoint('appFamilyCards') + '/' + encodeURIComponent(applicationId) + '/unbind', method: 'POST', skipAuth: true, data: { talentCardId: Number(talentCardId) }, idempotencyKey: 'family-card-unbind-' + applicationId }, onSuccess, onError)
+export const unbindFamilyCards = (applicationIds: string[], talentCardId: string, onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => {
+	let index = 0
+	const runNext = (): void => {
+		if (index >= applicationIds.length) { onSuccess(null); return }
+		const id = applicationIds[index]
+		index = index + 1
+		unbindFamilyCard(id, talentCardId, () => runNext(), onError)
+	}
+	runNext()
+	return () => {}
+}
 export const issueOrderVerificationCode = (orderNo: string, talentId: string, onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => request<any>({ path: getApiEndpoint('appPendingUseOrders') + encodeURIComponent(orderNo) + '/verification-code', method: 'POST', skipAuth: true, data: { talentId: Number(talentId) } }, onSuccess, onError)
 export const refundPendingUseOrder = (orderNo: string, talentId: string, reason: string, onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => request<any>({ path: getApiEndpoint('appPendingUseOrders') + encodeURIComponent(orderNo) + '/refund', method: 'POST', skipAuth: true, data: { talentId: Number(talentId), reason: reason }, idempotencyKey: 'refund-' + orderNo }, onSuccess, onError)
diff --git a/talent-card-server/src/main/java/com/talentcard/server/business/portal/DependentCardApplyController.java b/talent-card-server/src/main/java/com/talentcard/server/business/portal/DependentCardApplyController.java
index fd881b7..fb4a8fc 100644
--- a/talent-card-server/src/main/java/com/talentcard/server/business/portal/DependentCardApplyController.java
+++ b/talent-card-server/src/main/java/com/talentcard/server/business/portal/DependentCardApplyController.java
@@ -6,7 +6,7 @@
 import com.talentcard.server.request.DependentCardApplyRequest;
 import com.talentcard.server.request.DependentCardUnbindRequest;
 import com.talentcard.server.response.DependentCardApplyItemResponse;
-import com.talentcard.server.service.DependentCardApplyService;
+
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.responses.ApiResponses;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -21,12 +21,12 @@
 
 @Tag(name = "家属附属卡申请", description = "小程序家属附属卡申请、查询与解绑")
 @RestController
-@RequestMapping("/api/app/dependent-card-applies")
+@RequestMapping("/api/app/family-cards/applications")
 public class DependentCardApplyController {
 
-	private final DependentCardApplyService service;
+	private final FamilyCardPortalService service;
 
-	public DependentCardApplyController(DependentCardApplyService service) {
+	public DependentCardApplyController(FamilyCardPortalService service) {
 		this.service = service;
 	}
 
@@ -45,7 +45,7 @@
 	public ApiResponse<Void> submit(
 			@Valid @RequestBody DependentCardApplyRequest request
 	) {
-		service.submit(request);
+		service.createByTalentCardId(request);
 		return ApiResponse.success();
 	}
 
@@ -54,7 +54,7 @@
 	public ApiResponse<List<DependentCardApplyItemResponse>> list(
 			@RequestParam Long talentCardId
 	) {
-		return ApiResponse.success(service.list(talentCardId));
+		return ApiResponse.success(service.listByTalentCardId(talentCardId));
 	}
 
 	@Operation(summary = "解绑家属附属卡", description = "仅已通过审核的家属附属卡可以解绑")
@@ -68,6 +68,6 @@
 			@PathVariable Long id,
 			@Valid @RequestBody DependentCardUnbindRequest request
 	) {
-		return ApiResponse.success(service.unbind(id, request));
+		return ApiResponse.success(service.unbindByTalentCardId(id, request));
 	}
-}
\ No newline at end of file
+}
diff --git a/talent-card-server/src/main/java/com/talentcard/server/business/portal/FamilyCardPortalController.java b/talent-card-server/src/main/java/com/talentcard/server/business/portal/FamilyCardPortalController.java
index 28009ab..186ba7b 100644
--- a/talent-card-server/src/main/java/com/talentcard/server/business/portal/FamilyCardPortalController.java
+++ b/talent-card-server/src/main/java/com/talentcard/server/business/portal/FamilyCardPortalController.java
@@ -19,7 +19,6 @@
 	private final FamilyCardPortalService service;
 	public FamilyCardPortalController(FamilyCardPortalService service) { this.service = service; }
 	@GetMapping public ApiResponse<List<Map<String, Object>>> list(@RequestParam Long talentId) { return ApiResponse.success(service.list(talentId)); }
-	@PostMapping("/applications") public ApiResponse<Map<String, Object>> create(@Valid @RequestBody FamilyCardApplicationRequest request) { return ApiResponse.success(service.create(request)); }
 	@PostMapping("/unbind") public ApiResponse<Map<String, Object>> unbindMany(@Valid @RequestBody FamilyCardBatchUnbindRequest request) { return ApiResponse.success(service.unbindMany(request)); }
 	@PostMapping("/{applicationId}/unbind") public ApiResponse<Map<String, Object>> unbind(@PathVariable Long applicationId, @Valid @RequestBody FamilyCardUnbindRequest request) { return ApiResponse.success(service.unbind(applicationId, request)); }
 }
diff --git a/talent-card-server/src/main/java/com/talentcard/server/business/portal/FamilyCardPortalService.java b/talent-card-server/src/main/java/com/talentcard/server/business/portal/FamilyCardPortalService.java
index da681d4..74159fd 100644
--- a/talent-card-server/src/main/java/com/talentcard/server/business/portal/FamilyCardPortalService.java
+++ b/talent-card-server/src/main/java/com/talentcard/server/business/portal/FamilyCardPortalService.java
@@ -6,7 +6,10 @@
 
 import com.talentcard.server.business.BusinessIdGenerator;
 import com.talentcard.server.business.DatabaseRows;
+import com.talentcard.server.request.DependentCardApplyRequest;
+import com.talentcard.server.request.DependentCardUnbindRequest;
 import com.talentcard.server.common.BusinessException;
+import com.talentcard.server.response.DependentCardApplyItemResponse;
 import com.talentcard.server.common.ErrorCode;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
@@ -31,15 +34,49 @@
 			""", talentId).stream().map(DatabaseRows::normalize).map(this::view).toList();
 	}
 
+	@Transactional(readOnly = true)
+	public List<DependentCardApplyItemResponse> listByTalentCardId(Long talentCardId) {
+		Long talentId = talentIdByCardId(talentCardId);
+		return jdbc.queryForList("""
+			select f.id, f.family_name, f.family_mobile, f.relationship, f.status
+			from family_card_application f
+			where f.deleted = 0 and f.talent_id = ? and f.status <> '\u5df2\u89e3\u7ed1'
+			order by f.apply_time desc, f.id desc
+			""", talentId).stream().map(DatabaseRows::normalize).map(this::dependentCardItem).toList();
+	}
+
+	@Transactional
+	public void createByTalentCardId(DependentCardApplyRequest request) {
+		Long talentId = talentIdByCardId(request.talentCardId());
+		create(new FamilyCardApplicationRequest(
+				talentId, request.dependentName(), request.dependentIdCardNo(),
+				request.dependentMobile(), request.relation()
+		));
+	}
+
+	@Transactional
+	public DependentCardApplyItemResponse unbindByTalentCardId(Long id, DependentCardUnbindRequest request) {
+		Long talentId = talentIdByCardId(request.talentCardId());
+		unbind(id, new FamilyCardUnbindRequest(talentId));
+		List<Map<String, Object>> rows = jdbc.queryForList("""
+			select f.id, f.family_name, f.family_mobile, f.relationship, f.status
+			from family_card_application f
+			where f.id = ? and f.talent_id = ? and f.deleted = 0
+			limit 1
+			""", id, talentId).stream().map(DatabaseRows::normalize).toList();
+		if (rows.isEmpty()) throw new BusinessException(ErrorCode.NOT_FOUND, "\u5bb6\u5c5e\u5361\u7533\u8bf7\u4e0d\u5b58\u5728");
+		return dependentCardItem(rows.get(0));
+	}
 	@Transactional
 	public Map<String, Object> create(FamilyCardApplicationRequest request) {
 		Map<String, Object> owner = ownerCard(request.talentId());
 		if (!"卓越人才卡".equals(string(owner.get("cardLevel")))) throw new BusinessException(ErrorCode.CONFLICT, "家庭附属卡仅向卓越人才卡用户开放");
-		if (number(owner.get("isFamilyCardEnabled")) == null || number(owner.get("isFamilyCardEnabled")) != 1 || number(owner.get("familyCardLimit")) == null || number(owner.get("familyCardLimit")) < 1) throw new BusinessException(ErrorCode.CONFLICT, "当前人才卡暂未开通家庭附属卡申请");
 		if (!List.of("配偶", "父母", "子女", "其他").contains(request.relationship().trim())) throw new BusinessException(ErrorCode.BAD_REQUEST, "不支持的家属关系");
 		if (!validIdCard(request.idCard().trim())) throw new BusinessException(ErrorCode.BAD_REQUEST, "身份证号格式不正确");
-		Integer occupied = jdbc.queryForObject("select count(*) from family_card_application where deleted = 0 and talent_id = ? and status in ('待审核', '已通过')", Integer.class, request.talentId());
-		if (occupied != null && occupied >= number(owner.get("familyCardLimit"))) throw new BusinessException(ErrorCode.CONFLICT, "家庭附属卡申请数量已达上限");
+		Integer submitted = jdbc.queryForObject("select count(*) from family_card_application where deleted = 0 and talent_id = ? and status in ('\u5f85\u5ba1\u6838', '\u5df2\u901a\u8fc7', '\u5df2\u9a73\u56de')", Integer.class, request.talentId());
+		if (submitted != null && submitted >= 3) throw new BusinessException(ErrorCode.CONFLICT, "\u540c\u4e00\u5f20\u4e3b\u5361\u6700\u591a\u63d0\u4ea43\u4e2a\u5bb6\u5c5e\u9644\u5c5e\u5361\u7533\u8bf7");
+		Integer occupied = jdbc.queryForObject("select count(*) from family_card_application where deleted = 0 and talent_id = ? and status in ('\u5f85\u5ba1\u6838', '\u5df2\u901a\u8fc7')", Integer.class, request.talentId());
+		if (occupied != null && occupied >= 2) throw new BusinessException(ErrorCode.CONFLICT, "\u8be5\u4e3b\u5361\u5bb6\u5c5e\u9644\u5c5e\u5361\u540d\u989d\u5df2\u6ee1\uff0c\u6700\u591a\u7ed1\u5b9a2\u4e2a");
 		Integer duplicate = jdbc.queryForObject("""
 			select count(*) from family_card_application
 			where deleted = 0 and talent_id = ? and id_card_no = ? and status in ('待审核', '已通过')
@@ -89,6 +126,38 @@
 		return Map.of("applicationIds", applicationIds, "unbound", true);
 	}
 
+	private Long talentIdByCardId(Long talentCardId) {
+		if (talentCardId == null || talentCardId <= 0) throw new BusinessException(ErrorCode.NOT_FOUND, "\u4e3b\u5361\u4e0d\u5b58\u5728\u6216\u5df2\u5931\u6548");
+		List<Map<String, Object>> rows = jdbc.queryForList("""
+			select talent_id from talent_card
+			where id = ? and deleted = 0 and card_type = 'PERSONAL' and status = 1
+			limit 1
+			""", talentCardId).stream().map(DatabaseRows::normalize).toList();
+		if (rows.isEmpty()) throw new BusinessException(ErrorCode.NOT_FOUND, "\u4e3b\u5361\u4e0d\u5b58\u5728\u6216\u5df2\u5931\u6548");
+		return number(rows.get(0).get("talentId"));
+	}
+
+	private DependentCardApplyItemResponse dependentCardItem(Map<String, Object> row) {
+		Integer status = switch (string(row.get("status"))) {
+			case "\u5f85\u5ba1\u6838" -> 0;
+			case "\u5df2\u901a\u8fc7" -> 1;
+			case "\u5df2\u9a73\u56de" -> 2;
+			case "\u5df2\u89e3\u7ed1" -> 3;
+			default -> -1;
+		};
+		String statusText = switch (status) {
+			case 0 -> "\u5f85\u5ba1\u6838";
+			case 1 -> "\u5df2\u901a\u8fc7";
+			case 2 -> "\u5df2\u9a73\u56de";
+			case 3 -> "\u5df2\u89e3\u7ed1";
+			default -> "\u672a\u77e5";
+		};
+		return new DependentCardApplyItemResponse(
+				number(row.get("id")), string(row.get("familyName")),
+				maskMobile(string(row.get("familyMobile"))), status, statusText,
+				string(row.get("relationship"))
+		);
+	}
 	private Map<String, Object> ownerCard(Long talentId) {
 		List<Map<String, Object>> rows = jdbc.queryForList("""
 			select c.card_no, c.card_level, c.is_family_card_enabled, c.family_card_limit, u.name as talent_name, u.mobile as talent_mobile
diff --git a/talent-card-server/src/main/java/com/talentcard/server/service/DependentCardApplyService.java b/talent-card-server/src/main/java/com/talentcard/server/service/DependentCardApplyService.java
index 668919b..ff59058 100644
--- a/talent-card-server/src/main/java/com/talentcard/server/service/DependentCardApplyService.java
+++ b/talent-card-server/src/main/java/com/talentcard/server/service/DependentCardApplyService.java
@@ -145,14 +145,14 @@
 		if (!ELITE_CARD_LEVEL.equals(card.getCardLevel())) {
 			throw new BusinessException(ErrorCode.INTERNAL_ERROR, "仅卓越人才卡可申请家属附属卡");
 		}
-		if (!Integer.valueOf(1).equals(card.getIsFamilyCardEnabled())) {
-			throw new BusinessException(ErrorCode.INTERNAL_ERROR, "该主卡未开通家属附属卡申请权限");
-		}
-		Integer configuredLimit = card.getFamilyCardLimit();
-		if (configuredLimit == null || configuredLimit <= 0) {
-			throw new BusinessException(ErrorCode.INTERNAL_ERROR, "该主卡未配置家属附属卡名额");
-		}
-		return Math.min(configuredLimit, MAX_FAMILY_CARD_COUNT);
+//		if (!Integer.valueOf(1).equals(card.getIsFamilyCardEnabled())) {
+//			throw new BusinessException(ErrorCode.INTERNAL_ERROR, "该主卡未开通家属附属卡申请权限");
+//		}
+//		Integer configuredLimit = card.getFamilyCardLimit();
+//		if (configuredLimit == null || configuredLimit <= 0) {
+//			throw new BusinessException(ErrorCode.INTERNAL_ERROR, "该主卡未配置家属附属卡名额");
+//		}
+		return Math.min(2, MAX_FAMILY_CARD_COUNT);
 	}
 
 	private void recordStatus(

--
Gitblit v1.7.1