فهرست منبع

家庭成员接口联调完成

htc 15 ساعت پیش
والد
کامیت
e2a5c7124a
2فایلهای تغییر یافته به همراه148 افزوده شده و 66 حذف شده
  1. 106 33
      pagesMy/familyMember.vue
  2. 42 33
      pagesMy/familyMemberVindicate.vue

+ 106 - 33
pagesMy/familyMember.vue

@@ -1,52 +1,109 @@
 <template>
 	<view class="common_page adffc" :style="{'height':h+'px', 'padding-top':mt+'px'}">
 		<cus-header title="家庭成员" bgColor="#FFFFFF"></cus-header>
-		<div class="add">
-			<div class="btn adfacjc" @tap="handleAdd">
+		<view class="add">
+			<view class="btn adfacjc" @tap="handleAdd">
 				<image src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/10/09/af9133fd-e15e-454d-9152-e4629fd0ce28.png"></image>
 				<text>添加</text>
-			</div>
-		</div>
+			</view>
+		</view>
 		<template v-if="list.length">
-			<div class="list">
+			<view class="list">
 				<up-list @scrolltolower="scrolltolower" style="height: 100%;">
 					<up-list-item v-for="(item, index) in list" :key="index">
-						<div class="box adfacjb">
-							<div class="box-left adfac" @tap="handleEdit(item,index)">
-								<div class="box-left-edit">
+						<view class="box adfacjb">
+							<view class="box-left adfac" @tap="handleEdit(item,index)">
+								<view class="box-left-edit">
 									<image src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/10/09/7799f9f2-1dca-4af3-980b-7f6def10e22f.png"></image>
-								</div>
-								<div class="box-left-info">
-									<div class="box-left-info-top adfac">
-										<div class="name">{{'张琳琳'}}</div>
-										<image class="sex" v-if="item.sex==2" src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/09/12/b6d1fcb3-55ba-4104-b8cd-756b963a4da8.png"></image>
-										<image class="sex" v-else-if="item.sex==1" src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/09/12/a1899fd0-c468-48d9-b554-2f17b75a4157.png"></image>
-										<div class="age" :class="{'women':item.sex==2,'man':item.sex==1}">{{46}}岁</div>
-									</div>
-									<div class="box-left-info-bottom">
-										身份证 {{'340123**********09'}}
-									</div>
-								</div>
-							</div>
-							<div class="box-right" @tap="handleDelete(item,index)">
+								</view>
+								<view class="box-left-info">
+									<view class="box-left-info-top adfac">
+										<view class="name">{{item.name}}</view>
+										<image class="sex" v-if="item.gender==1" src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/09/12/b6d1fcb3-55ba-4104-b8cd-756b963a4da8.png"></image>
+										<image class="sex" v-else-if="item.gender==0" src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/09/12/a1899fd0-c468-48d9-b554-2f17b75a4157.png"></image>
+										<view class="age" :class="{'women':item.gender==1,'man':item.gender==0}">{{item.age}}岁</view>
+									</view>
+									<view class="box-left-info-bottom">
+										身份证 {{item.idCardCopy}}
+									</view>
+								</view>
+							</view>
+							<view class="box-right" @tap="handleDelete(item,index)">
 								<image src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/09/23/ebdf1327-3eeb-4797-8840-cb1ec4840d9a.png"></image>
-							</div>
-						</div>
+							</view>
+						</view>
 					</up-list-item>
 				</up-list>
-			</div>
-		</template>
-		<template v-else>
-			<div class="empty">暂无家庭成员,请添加</div>
+			</view>
 		</template>
+		<view class="dataEmpty" v-else>
+			<page-empty text="暂无家庭成员,请添加"></page-empty>
+		</view>
 	</view>
 </template>
 
 <script setup name="">
 	import CusHeader from '@/components/CusHeader/index.vue'
-	import { ref } from 'vue'
+	import PageEmpty from '@/components/pageEmpty/index.vue'
+	import { ref, onMounted, getCurrentInstance } from 'vue'
+	const { proxy } = getCurrentInstance()
+	
+	const queryParams = ref({
+		page:1,
+		limit:10,
+		userId:''
+	})
+	const isOver = ref(false)
+	const list = ref([])
+	
+	const scrolltolower = () => {
+		if(isOver.value) return
+		getMemberList()
+	}
+	
+	const getMemberList = () => {
+		proxy.$api.get('/core/family/member/page',queryParams.value).then(({data:res})=>{
+			if(res.code!==0) return proxy.$showToast(res.msg)
+			list.value = [...list.value,...res.data.list]
+			list.value.forEach(l=>{
+				l.age = getAge(l.idCard)
+				l.idCardCopy = l.idCard.replace(/^(\d{6})(\d{8})(\d{3}[\dX])$/i,'$1********$3')
+			})
+			queryParams.value.page++;
+			if(list.value.length>=res.data.total) isOver.value = true;
+		})
+	}
+	
+	const isValid = (idCard) => {
+		// 正则表达式校验18位身份证号码(最后一位可以是数字或X/x)
+		const regex = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
+		return typeof idCard === 'string' && regex.test(idCard);
+	  }
+	
+	const getAge = (idCard) => {
+		if (!isValid(idCard)) return 0
 	
-	const list = ref([{sex:1},{sex:2},{sex:2}])
+		// 从身份证的第7位开始,截取8位作为出生日期字符串 (YYYYMMDD)
+		const birthDateStr = idCard.substring(6, 14);
+		const birthYear = parseInt(birthDateStr.substring(0, 4), 10);
+		const birthMonth = parseInt(birthDateStr.substring(4, 6), 10);
+		const birthDay = parseInt(birthDateStr.substring(6, 8), 10);
+	
+		const today = new Date();
+		const currentYear = today.getFullYear();
+		const currentMonth = today.getMonth() + 1; // getMonth() 返回 0-11
+		const currentDay = today.getDate();
+	
+		// 计算周岁
+		let age = currentYear - birthYear;
+	
+		// 如果当前月份小于出生月份,或者月份相同但日期小于出生日期,说明今年的生日还没过
+		if (currentMonth < birthMonth || (currentMonth === birthMonth && currentDay < birthDay)) {
+		  age--;
+		}
+	
+		return age < 0 ? 0 : age; 
+	}
 	
 	const handleAdd = () => {
 		uni.navigateTo({
@@ -56,20 +113,36 @@
 	
 	const handleEdit = (item,index) => {
 		uni.navigateTo({
-			url:'/pagesMy/familyMemberVindicate?member='+encodeURIComponent(JSON.stringify(item))
+			url:'/pagesMy/familyMemberVindicate?id='+item.id
 		})
 	}
 	const handleDelete = (item,index) => {
 		uni.showModal({
 			title:'温馨提示',
-			content:`是否确认删除家庭成员【${item.name||'张琳琳'}】?`,
+			content:`是否确认删除家庭成员【${item.name}】?`,
 			success: (res) => {
 				if(res.confirm){
-					
+					proxy.$api.del('/core/family/member',[item.id]).then(({data:res})=>{
+						if(res.code!==0) return proxy.$showToast(res.msg)
+						proxy.$showToast('删除成功')
+						queryParams.value.page = 1;
+						isOver.value = false;
+						list.value = [];
+						getMemberList()
+					})
 				}
 			}
 		})
 	}
+	
+	onMounted(()=>{
+		try{
+			queryParams.value.userId = JSON.parse(uni.getStorageSync('userInfo')).id;
+			getMemberList()
+		}catch(e){
+			//TODO handle the exception
+		}
+	})
 </script>
 
 <style scoped lang="scss">

+ 42 - 33
pagesMy/familyMemberVindicate.vue

@@ -6,13 +6,13 @@
 			<div class="pre adfac" style="margin-top: 40rpx;">
 				<div class="pre-title"><span>*</span>人员类型</div>
 				<div class="pre-content adfac">
-					<div class="pre-content-box adfac" @tap="changeMember(1,'type')">
-						<image v-if="memberInfo.type==1" src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/10/09/9efae012-a9fd-4a0d-9e14-7ec90001e712.png"></image>
+					<div class="pre-content-box adfac" @tap="changeMember(1,'personnelType')">
+						<image v-if="memberInfo.personnelType==1" src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/10/09/9efae012-a9fd-4a0d-9e14-7ec90001e712.png"></image>
 						<image v-else src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/10/09/5ae64305-d1e0-4ffe-8dc0-f9d3704ac370.png"></image>
 						<text>成人</text>
 					</div>
-					<div class="pre-content-box adfac" @tap="changeMember(2,'type')">
-						<image v-if="memberInfo.type==2" src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/10/09/9efae012-a9fd-4a0d-9e14-7ec90001e712.png"></image>
+					<div class="pre-content-box adfac" @tap="changeMember(2,'personnelType')">
+						<image v-if="memberInfo.personnelType==2" src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/10/09/9efae012-a9fd-4a0d-9e14-7ec90001e712.png"></image>
 						<image v-else src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/10/09/5ae64305-d1e0-4ffe-8dc0-f9d3704ac370.png"></image>
 						<text>学生</text>
 					</div>
@@ -27,34 +27,34 @@
 			<div class="pre adfac">
 				<div class="pre-title"><span>*</span>身份证</div>
 				<div class="pre-content">
-					<up-input v-model="memberInfo.idcard" border="none" style="font-size: 30rpx;color: #252525;" placeholder="请输入身份证"></up-input>
+					<up-input v-model="memberInfo.idCard" border="none" style="font-size: 30rpx;color: #252525;" placeholder="请输入身份证"></up-input>
 				</div>
 			</div>
 			<div class="pre adfac">
 				<div class="pre-title"><span style="color: #FFFFFF;">*</span>义工号</div>
 				<div class="pre-content">
-					<up-input v-model="memberInfo.workNo" border="none" style="font-size: 30rpx;color: #252525;" placeholder="请输入义工号"></up-input>
+					<up-input v-model="memberInfo.volunteerNo" border="none" style="font-size: 30rpx;color: #252525;" placeholder="请输入义工号"></up-input>
 				</div>
 			</div>
 			<div class="pre adfac">
 				<div class="pre-title"><span>*</span>性别</div>
 				<div class="pre-content adfac">
-					<div class="pre-content-box adfac" @tap="changeMember(1,'sex')">
-						<image v-if="memberInfo.sex==1" src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/10/09/9efae012-a9fd-4a0d-9e14-7ec90001e712.png"></image>
+					<div class="pre-content-box adfac" @tap="changeMember(0,'gender')">
+						<image v-if="memberInfo.gender==0" src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/10/09/9efae012-a9fd-4a0d-9e14-7ec90001e712.png"></image>
 						<image v-else src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/10/09/5ae64305-d1e0-4ffe-8dc0-f9d3704ac370.png"></image>
 						<text>男</text>
 					</div>
-					<div class="pre-content-box adfac" @tap="changeMember(2,'sex')">
-						<image v-if="memberInfo.sex==2" src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/10/09/9efae012-a9fd-4a0d-9e14-7ec90001e712.png"></image>
+					<div class="pre-content-box adfac" @tap="changeMember(1,'gender')">
+						<image v-if="memberInfo.gender==1" src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/10/09/9efae012-a9fd-4a0d-9e14-7ec90001e712.png"></image>
 						<image v-else src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/10/09/5ae64305-d1e0-4ffe-8dc0-f9d3704ac370.png"></image>
 						<text>女</text>
 					</div>
 				</div>
 			</div>
-			<div class="pre adfac" v-if="memberInfo.type==2">
+			<div class="pre adfac" v-if="memberInfo.personnelType==2">
 				<div class="pre-title"><span>*</span>就读学校</div>
 				<div class="pre-content">
-					<up-input v-model="memberInfo.school" border="none" style="font-size: 30rpx;color: #252525;" placeholder="请输入就读学校"></up-input>
+					<up-input v-model="memberInfo.currentSchool" border="none" style="font-size: 30rpx;color: #252525;" placeholder="请输入就读学校"></up-input>
 				</div>
 			</div>
 		</div>
@@ -64,18 +64,19 @@
 
 <script setup name="">
 	import CusHeader from '@/components/CusHeader/index.vue'
-	import { onLoad } from '@dcloudio/uni-app';
+	import { onLoad } from '@dcloudio/uni-app' 
 	import { ref, getCurrentInstance } from 'vue'
 	const { proxy } = getCurrentInstance()
 	
 	const title = ref('添加家庭成员')
 	const memberInfo = ref({
-		type:1,
+		userId:'',
+		personnelType:1,
 		name:'',
-		idcard:'',
-		workNo:'',
-		sex:1,
-		school:''
+		idCard:'',
+		volunteerNo:'',
+		gender:0,
+		currentSchool:''
 	})
 	
 	const changeMember = (value,key) => {
@@ -83,25 +84,33 @@
 	}
 	
 	const handleSave = () => {
-		if(!memberInfo.value.type) return proxy.$showToast('请选择人员类型')
 		if(!memberInfo.value.name) return proxy.$showToast('请输入姓名')
-		if(!proxy.$reg.idCard(memberInfo.value.idcard)) return proxy.$showToast('请输入正确的身份证号')
-		if(!memberInfo.value.sex) return proxy.$showToast('请选择性别')
-		if(!memberInfo.value.school&&memberInfo.value.type==2) return proxy.$showToast('请输入就读学校')
-		console.log(memberInfo.value);
+		if(!proxy.$reg.idCard(memberInfo.value.idCard)) return proxy.$showToast('请输入正确的身份证号')
+		if(!memberInfo.value.currentSchool&&memberInfo.value.personnelType==2) return proxy.$showToast('请输入就读学校')
+		memberInfo.value.gender = memberInfo.value.gender??1;
+		if(!memberInfo.value.userId) memberInfo.value.userId = JSON.parse(uni.getStorageSync('userInfo')).id;
+		proxy.$api[memberInfo.value.id?'put':'post']('/core/family/member',memberInfo.value).then(({data:res})=>{
+			if(res.code!==0) return proxy.$showToast(res.msg)
+			proxy.$showToast(memberInfo.value.id?'编辑成功':'添加成功')
+			setTimeout(()=>{
+				uni.redirectTo({
+					url:'/pagesMy/familyMember'
+				})
+			},1500)
+		})
+	}
+	
+	const getMemberInfo = (id) => {
+		proxy.$api.get(`/core/family/member/${id}`).then(({data:res})=>{
+			if(res.code!==0) return this.$showToast(res.msg)
+			memberInfo.value = {...memberInfo.value,...res.data}
+		})
 	}
 	
 	onLoad((options)=>{
-		if (options.member) {
-			try {
-				const memberObject = JSON.parse(decodeURIComponent(options.member));
-				console.log('成功解析的 member 对象:', memberObject);
-				if(memberObject) title.value = '编辑家庭成员';
-			} catch (e) {
-				console.error('解析 member 参数失败:', e);
-			}
-		} else {
-			console.warn('未在URL中找到 member 参数');
+		const id = options?.id;
+		if(id){
+			getMemberInfo(id)
 		}
 	})
 </script>