Browse Source

客户详情页修改功能,线索审核 三级联动地址

yuxy 4 weeks ago
parent
commit
2da671dbd0

+ 74 - 13
LiangZhiYUMao/pages/matchmaker-workbench/my-resources.vue

@@ -37,8 +37,12 @@
 			</view>
 			<view class="resource-list-container">
 				<view class="resource-item" v-for="(item, index) in getRegisteredDisplayData" :key="getRegisteredItemKey(item, index)" @click="handleResourceClickSafe(item, index)">
-				<!-- 右上角选中图标 -->
+				<!-- 右上角选中图标(左移) -->
 				<view class="select-icon">✓-</view>
+				<!-- 编辑按钮 -->
+				<view class="edit-icon" @click.stop="handleEdit(item.id || item.resourceId || item.resource_id)">
+					<text class="edit-text">编辑</text>
+				</view>
 				
 				<view class="resource-header">
 					<image 
@@ -110,8 +114,12 @@
 			</view>
 			<view class="resource-list-container">
 				<view class="resource-item" v-for="(item, index) in getUnregisteredDisplayData" :key="getUnregisteredItemKey(item, index)" @click="handleResourceClickSafe(item, index)">
-				<!-- 右上角选中图标 -->
+				<!-- 右上角选中图标(左移) -->
 				<view class="select-icon">✓-</view>
+				<!-- 编辑按钮 -->
+				<view class="edit-icon" @click.stop="handleEdit(item.id || item.resourceId || item.resource_id)">
+					<text class="edit-text">编辑</text>
+				</view>
 				
 				<view class="resource-header">
 					<image 
@@ -142,6 +150,11 @@
 						<text class="label" v-for="(label, idx) in item.labels" :key="idx">{{ label }}</text>
 					</view>
 
+					<!-- 未审核通过原因 -->
+					<view class="reject-reason" v-if="item.status === 2 && item.rejectReason">
+						<text class="reject-reason-text">审核未通过原因:{{ item.rejectReason }}</text>
+					</view>
+
 					<view class="requirement-box">
 						<text class="requirement-label">择偶要求:</text>
 						<text class="requirement-content">{{ item.requirement }}</text>
@@ -677,6 +690,7 @@ export default {
 						name: item.name || '',
 						gender: item.gender === 1 ? '男' : item.gender === 2 ? '女' : '未知',
 						status: item.status !== undefined && item.status !== null ? item.status : 0,
+						rejectReason: item.rejectReason || item.reject_reason || '',
 						isUser: isUser,
 						userId: userId,
 						isMatch: isMatch,
@@ -692,16 +706,14 @@ export default {
 			// 加载我的资源数据(改为分页加载)
 			async loadMyResources() {
 				try {
-					// 根据当前标签加载对应数据
-					if (this.currentTab === 'resource') {
-						// 重置资源列表
-						this.registeredPageNum = 1
-						await this.loadRegisteredPage(1)
-					} else {
-						// 重置线索列表
-						this.unregisteredPageNum = 1
-						await this.loadUnregisteredPage(1)
-					}
+					// 重置分页
+					this.registeredPageNum = 1
+					this.unregisteredPageNum = 1
+					// 同时加载资源和线索,进入页面即可两端都查询完毕
+					await Promise.all([
+						this.loadRegisteredPage(1),
+						this.loadUnregisteredPage(1)
+					])
 				} catch (e) {
 					console.error('加载资源数据失败:', e)
 				}
@@ -811,6 +823,23 @@ export default {
 				})
 		},
 		// 精准匹配
+		// 编辑资源
+		handleEdit(id) {
+			// 跳转到资源录入页面(编辑模式),传递资源ID
+			uni.navigateTo({
+				url: `/pages/matchmaker-workbench/resource-input?resourceId=${id}`,
+				success: () => {
+					console.log('跳转到编辑页面,resourceId:', id)
+				},
+				fail: (err) => {
+					console.error('跳转失败:', err)
+					uni.showToast({
+						title: '跳转失败',
+						icon: 'none'
+					})
+				}
+			})
+		},
 		handleMatch(id) {
 			// 查找资源项
 			const allResources = [...this.registeredResources, ...this.unregisteredResources]
@@ -1382,7 +1411,7 @@ export default {
 		.select-icon {
 			position: absolute;
 			top: 20rpx;
-			right: 20rpx;
+			right: 120rpx; /* 左移,为编辑按钮留出空间 */
 			width: 40rpx;
 			height: 40rpx;
 			background: #FF4444;
@@ -1395,6 +1424,26 @@ export default {
 			font-weight: bold;
 			z-index: 10;
 		}
+		
+		.edit-icon {
+			position: absolute;
+			top: 20rpx;
+			right: 20rpx;
+			padding: 8rpx 20rpx;
+			background: linear-gradient(135deg, #9C27B0 0%, #BA68C8 100%);
+			border-radius: 20rpx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			z-index: 10;
+			box-shadow: 0 2rpx 8rpx rgba(156, 39, 176, 0.3);
+			
+			.edit-text {
+				color: #FFFFFF;
+				font-size: 24rpx;
+				font-weight: 500;
+			}
+		}
 
 		.resource-header {
 			display: flex;
@@ -1656,6 +1705,18 @@ export default {
 		}
 	}
 
+	/* 审核未通过原因 */
+	.reject-reason {
+		margin-top: 12rpx;
+		padding: 14rpx 16rpx;
+		background: #FFF3E0;
+		border: 1rpx solid #FFCC80;
+		border-radius: 10rpx;
+		color: #E65100;
+		font-size: 24rpx;
+		line-height: 1.5;
+	}
+
 	/* 添加按钮 */
 	.add-button {
 		position: fixed;

+ 575 - 94
LiangZhiYUMao/pages/matchmaker-workbench/resource-input.vue

@@ -5,7 +5,7 @@
 			<view class="header-left" @click="goBack">
 				<text class="back-icon">←</text>
 			</view>
-			<text class="header-title">信息录入</text>
+			<text class="header-title">{{ isEditMode ? '编辑信息' : '信息录入' }}</text>
 			<view class="header-right">
 				<text class="more-icon">⋯</text>
 			</view>
@@ -88,11 +88,29 @@
 					</view>
 					<view class="form-item">
 						<text class="form-label">住址<text class="required">*</text></text>
-						<input type="text" class="form-input" placeholder="请输入住址" v-model="formData.address" />
+						<!-- 省市区三级联动选择器 -->
+						<picker mode="multiSelector" :range="addressMultiArray" :value="addressMultiIndex" @columnchange="onAddressColumnChange" @change="onAddressChange">
+							<view class="form-input picker-input">
+								<text v-if="addressDisplayText" class="picker-text">{{ addressDisplayText }}</text>
+								<text v-else class="placeholder">请选择省市区</text>
+								<text class="picker-arrow">▼</text>
+							</view>
+						</picker>
+						<!-- 详细地址输入框 -->
+						<input type="text" class="form-input address-detail-input" placeholder="请输入详细地址(街道、门牌号等)" v-model="formData.addressDetail" style="margin-top: 15rpx;" />
 					</view>
 					<view class="form-item">
 						<text class="form-label">户籍地</text>
-						<input type="text" class="form-input" placeholder="请输入户籍地" v-model="formData.domicile" />
+						<!-- 省市区三级联动选择器 -->
+						<picker mode="multiSelector" :range="domicileMultiArray" :value="domicileMultiIndex" @columnchange="onDomicileColumnChange" @change="onDomicileChange">
+							<view class="form-input picker-input">
+								<text v-if="domicileDisplayText" class="picker-text">{{ domicileDisplayText }}</text>
+								<text v-else class="placeholder">请选择省市区</text>
+								<text class="picker-arrow">▼</text>
+							</view>
+						</picker>
+						<!-- 详细地址输入框 -->
+						<input type="text" class="form-input address-detail-input" placeholder="请输入详细地址(街道、门牌号等)" v-model="formData.domicileDetail" style="margin-top: 15rpx;" />
 					</view>
 					<view class="form-item">
 						<text class="form-label">职业</text>
@@ -184,7 +202,7 @@
 
 		<!-- 底部提交按钮 -->
 		<view class="submit-bar">
-			<button class="submit-btn" @click="handleSubmit">提交</button>
+			<button class="submit-btn" @click="handleSubmit">{{ isEditMode ? '确认修改' : '提交' }}</button>
 		</view>
 	</view>
 </template>
@@ -197,6 +215,8 @@ export default {
 		return {
 			activeSection: 'basic',
 			currentUserId: null, // 当前登录用户的用户ID
+			resourceId: null, // 编辑模式下的资源ID
+			isEditMode: false, // 是否为编辑模式
 			formData: {
 				name: '',
 				age: null,
@@ -207,8 +227,10 @@ export default {
 				marrStatus: null,
 				diploma: '',
 				income: '',
-				address: '',
-				domicile: '',
+				address: '', // 住址(省市区+详细地址组合)
+				addressDetail: '', // 住址详细地址
+				domicile: '', // 户籍地(省市区+详细地址组合)
+				domicileDetail: '', // 户籍地详细地址
 				occupation: '',
 				house: null,
 				car: null,
@@ -216,6 +238,20 @@ export default {
 				phone: '',
 				backupPhone: ''
 			},
+			// 住址省市区数据
+			addressProvinces: [],
+			addressCities: [],
+			addressAreas: [],
+			addressMultiArray: [[], [], []], // 三级联动数据
+			addressMultiIndex: [0, 0, 0], // 三级联动索引
+			addressDisplayText: '', // 住址显示文本
+			// 户籍地省市区数据
+			domicileProvinces: [],
+			domicileCities: [],
+			domicileAreas: [],
+			domicileMultiArray: [[], [], []], // 三级联动数据
+			domicileMultiIndex: [0, 0, 0], // 三级联动索引
+			domicileDisplayText: '', // 户籍地显示文本
 			genderOptions: ['男', '女'],
 			genderIndex: 0,
 			constellationOptions: ['白羊座', '金牛座', '双子座', '巨蟹座', '狮子座', '处女座', '天秤座', '天蝎座', '射手座', '摩羯座', '水瓶座', '双鱼座'],
@@ -271,7 +307,7 @@ export default {
 			return filtered
 		}
 	},
-	onLoad() {
+	onLoad(options) {
 		// 获取当前登录用户信息
 		const userInfo = uni.getStorageSync('userInfo') || {}
 		const userId = uni.getStorageSync('userId')
@@ -287,14 +323,218 @@ export default {
 		this.currentUserId = rawUserId
 		console.log('当前登录用户ID:', this.currentUserId)
 		
+		// 检查是否为编辑模式
+		if (options && options.resourceId) {
+			this.resourceId = parseInt(options.resourceId)
+			this.isEditMode = true
+			console.log('编辑模式,资源ID:', this.resourceId)
+			// 加载资源详情
+			this.loadResourceDetail()
+		}
+		
 		// 加载标签分类和标签列表
 		this.loadCategories()
 		this.loadTags()
+		
+		// 加载省市区数据
+		this.loadAddressProvinces()
+		this.loadDomicileProvinces()
 	},
 	methods: {
 		goBack() {
 			uni.navigateBack()
 		},
+		// 加载资源详情(编辑模式)
+		async loadResourceDetail() {
+			if (!this.resourceId) return
+			
+			try {
+				uni.showLoading({ title: '加载中...' })
+				const baseUrl = process.env.NODE_ENV === 'development' 
+					? 'http://localhost:8083/api'  // 开发环境 - 通过网关
+					: 'https://your-domain.com/api'  // 生产环境
+				
+				const [error, res] = await uni.request({
+					url: `${baseUrl}/my-resource/detail/${this.resourceId}`,
+					method: 'GET'
+				})
+				
+				uni.hideLoading()
+				
+				if (error) {
+					console.error('加载资源详情失败:', error)
+					uni.showToast({
+						title: '加载资源详情失败',
+						icon: 'none'
+					})
+					return
+				}
+				
+				if (res.statusCode === 200 && res.data) {
+					// 检查返回的code
+					if (res.data.code === 200 && res.data.data) {
+						const resource = res.data.data
+						console.log('资源详情:', resource)
+						
+						// 填充表单数据
+						this.formData.name = resource.name || ''
+						this.formData.age = resource.age || null
+						this.formData.gender = resource.gender || null
+						if (this.formData.gender) {
+							this.genderIndex = this.formData.gender - 1 // 1-男,2-女 -> 0,1
+						}
+						this.formData.constellation = resource.constellation || ''
+						if (this.formData.constellation) {
+							const index = this.constellationOptions.indexOf(this.formData.constellation)
+							if (index >= 0) {
+								this.constellationIndex = index
+							}
+						}
+						this.formData.height = resource.height || null
+						this.formData.weight = resource.weight || null
+						this.formData.marrStatus = resource.marrStatus !== null && resource.marrStatus !== undefined ? resource.marrStatus : null
+						if (this.formData.marrStatus !== null && this.formData.marrStatus >= 0) {
+							this.maritalStatusIndex = this.formData.marrStatus
+						}
+						this.formData.diploma = resource.diploma || ''
+						if (this.formData.diploma) {
+							const index = this.diplomaOptions.indexOf(this.formData.diploma)
+							if (index >= 0) {
+								this.diplomaIndex = index
+							}
+						}
+						this.formData.income = resource.income || ''
+						
+						// 解析地址和户籍地
+						this.parseAddress(resource.address || '')
+						this.parseDomicile(resource.domicile || '')
+						
+						this.formData.occupation = resource.occupation || ''
+						this.formData.house = resource.house !== null && resource.house !== undefined ? resource.house : null
+						if (this.formData.house !== null && this.formData.house !== undefined) {
+							this.houseIndex = this.formData.house
+						}
+						this.formData.car = resource.car !== null && resource.car !== undefined ? resource.car : null
+						if (this.formData.car !== null && this.formData.car !== undefined) {
+							this.carIndex = this.formData.car
+						}
+						this.formData.mateSelectionCriteria = resource.mateSelectionCriteria || ''
+						this.formData.phone = resource.phone || ''
+						this.formData.backupPhone = resource.backupPhone || ''
+						
+						// 加载标签(需要先加载标签列表)
+						// 这里假设标签会在 loadTags 之后加载,所以需要延迟处理
+						this.$nextTick(() => {
+							// 加载资源关联的标签
+							this.loadResourceTags()
+						})
+					} else {
+						// 资源不存在或其他错误
+						const errorMessage = res.data.message || res.data.msg || '请求的资源不存在'
+						uni.showToast({
+							title: errorMessage,
+							icon: 'none',
+							duration: 2000
+						})
+						// 延迟返回上一页
+						setTimeout(() => {
+							uni.navigateBack()
+						}, 2000)
+					}
+				} else {
+					uni.showToast({
+						title: '加载资源详情失败',
+						icon: 'none'
+					})
+					setTimeout(() => {
+						uni.navigateBack()
+					}, 2000)
+				}
+			} catch (e) {
+				uni.hideLoading()
+				console.error('加载资源详情异常:', e)
+				uni.showToast({
+					title: '加载资源详情失败',
+					icon: 'none'
+				})
+			}
+		},
+		// 解析地址(分离省市区和详细地址)
+		parseAddress(fullAddress) {
+			if (!fullAddress) return
+			
+			// 简单的地址解析:假设格式为 "省 市 区 详细地址"
+			// 这里可以根据实际情况调整解析逻辑
+			const parts = fullAddress.split(' ')
+			if (parts.length >= 3) {
+				// 前三个部分可能是省市区
+				const regionParts = parts.slice(0, 3)
+				this.addressDisplayText = regionParts.join(' ')
+				this.formData.addressDetail = parts.slice(3).join(' ') || ''
+				
+				// 尝试匹配省市区并设置选择器
+				this.matchAddressRegion(regionParts)
+			} else {
+				// 如果格式不符合,将整个地址作为详细地址
+				this.formData.addressDetail = fullAddress
+			}
+		},
+		// 解析户籍地(分离省市区和详细地址)
+		parseDomicile(fullDomicile) {
+			if (!fullDomicile) return
+			
+			const parts = fullDomicile.split(' ')
+			if (parts.length >= 3) {
+				const regionParts = parts.slice(0, 3)
+				this.domicileDisplayText = regionParts.join(' ')
+				this.formData.domicileDetail = parts.slice(3).join(' ') || ''
+				
+				// 尝试匹配省市区并设置选择器
+				this.matchDomicileRegion(regionParts)
+			} else {
+				this.formData.domicileDetail = fullDomicile
+			}
+		},
+		// 匹配地址省市区(简化版,实际可能需要更复杂的匹配逻辑)
+		async matchAddressRegion(regionParts) {
+			// 这里简化处理,实际应该根据省市区名称匹配
+			// 暂时只设置显示文本,不自动选择
+		},
+		// 匹配户籍地省市区(简化版)
+		async matchDomicileRegion(regionParts) {
+			// 这里简化处理,实际应该根据省市区名称匹配
+			// 暂时只设置显示文本,不自动选择
+		},
+		// 加载资源关联的标签
+		async loadResourceTags() {
+			if (!this.resourceId) return
+			
+			try {
+				const baseUrl = process.env.NODE_ENV === 'development' 
+					? 'http://localhost:8083/api'
+					: 'https://your-domain.com/api'
+				
+				// 调用获取资源标签ID列表的接口
+				const [error, res] = await uni.request({
+					url: `${baseUrl}/my-resource/tag-ids/${this.resourceId}`,
+					method: 'GET'
+				})
+				
+				if (error) {
+					console.error('加载资源标签失败:', error)
+					return
+				}
+				
+				if (res.statusCode === 200 && res.data && res.data.code === 200) {
+					// 后端直接返回标签ID列表
+					const tagIds = res.data.data || []
+					this.selectedTagIds = tagIds.filter(id => id !== null && id !== undefined)
+					console.log('资源标签ID列表:', this.selectedTagIds)
+				}
+			} catch (e) {
+				console.error('加载资源标签异常:', e)
+			}
+		},
 		// 加载标签分类列表
 		async loadCategories() {
 			try {
@@ -511,10 +751,10 @@ export default {
 				return
 			}
 			
-			// 验证住址
-			if (!this.formData.address || !this.formData.address.trim()) {
+			// 验证住址(省市区或详细地址至少有一个)
+			if (!this.addressDisplayText && (!this.formData.addressDetail || !this.formData.addressDetail.trim())) {
 				uni.showToast({
-					title: '请输入住址',
+					title: '请选择省市区或输入详细地址',
 					icon: 'none'
 				})
 				return
@@ -634,8 +874,10 @@ export default {
 					marrStatus: marrStatusValue, // 直接使用处理后的值,不需要再次转换
 					diploma: safeString(this.formData.diploma),
 					income: safeString(this.formData.income),
-					address: safeString(this.formData.address),
-					domicile: safeString(this.formData.domicile),
+					// 组合住址:省市区 + 详细地址
+					address: this.buildFullAddress(this.addressDisplayText, this.formData.addressDetail),
+					// 组合户籍地:省市区 + 详细地址
+					domicile: this.buildFullAddress(this.domicileDisplayText, this.formData.domicileDetail),
 					occupation: safeString(this.formData.occupation),
 					house: safeParseInt(this.formData.house),
 					car: safeParseInt(this.formData.car),
@@ -673,65 +915,83 @@ export default {
 					return
 				}
 				
-				// 调用检查接口
-				const checkUrl = `${baseUrl}/my-resource/check-phone?phone=${encodeURIComponent(phone || '')}${backupPhone ? '&backupPhone=' + encodeURIComponent(backupPhone) : ''}`
-				const [checkError, checkRes] = await uni.request({
-					url: checkUrl,
-					method: 'GET'
-				})
-				
-				if (checkError) {
-					console.error('检查手机号失败:', checkError)
-					uni.hideLoading()
-					uni.showToast({
-						title: '检查手机号失败,请重试',
-						icon: 'none'
+				// 编辑模式下跳过手机号检查(因为可能是自己的手机号)
+				// 新增模式下检查手机号是否已存在
+				if (!this.isEditMode) {
+					// 调用检查接口
+					const checkUrl = `${baseUrl}/my-resource/check-phone?phone=${encodeURIComponent(phone || '')}${backupPhone ? '&backupPhone=' + encodeURIComponent(backupPhone) : ''}`
+					const [checkError, checkRes] = await uni.request({
+						url: checkUrl,
+						method: 'GET'
 					})
-					return
-				}
-				
-				if (checkRes.statusCode === 200 && checkRes.data && checkRes.data.code === 200) {
-					const checkResult = checkRes.data.data
-					const existingResource = checkResult.existingResource
 					
-					// 如果发现重复的手机号,提示用户
-					if (checkResult.phoneExists || checkResult.backupPhoneExists || checkResult.phoneAsBackupExists || checkResult.backupPhoneAsMainExists) {
-						let message = '该手机号已经绑定资源啦'
-						
-						// 根据不同的检查结果,显示具体的手机号类型
-						if (checkResult.phoneExists) {
-							message = '该主手机号已经绑定资源啦'
-						} else if (checkResult.phoneAsBackupExists) {
-							message = '该主手机号已经作为备用手机号绑定资源啦'
-						} else if (checkResult.backupPhoneAsMainExists) {
-							message = '该备用手机号已经作为主手机号绑定资源啦'
-						} else if (checkResult.backupPhoneExists) {
-							message = '该备用手机号已经绑定资源啦'
-						}
-						
+					if (checkError) {
+						console.error('检查手机号失败:', checkError)
 						uni.hideLoading()
 						uni.showToast({
-							title: message,
-							icon: 'none',
-							duration: 3000
+							title: '检查手机号失败,请重试',
+							icon: 'none'
 						})
 						return
 					}
+					
+					if (checkRes.statusCode === 200 && checkRes.data && checkRes.data.code === 200) {
+						const checkResult = checkRes.data.data
+						const existingResource = checkResult.existingResource
+						
+						// 如果发现重复的手机号,提示用户
+						if (checkResult.phoneExists || checkResult.backupPhoneExists || checkResult.phoneAsBackupExists || checkResult.backupPhoneAsMainExists) {
+							let message = '该手机号已经绑定资源啦'
+							
+							// 根据不同的检查结果,显示具体的手机号类型
+							if (checkResult.phoneExists) {
+								message = '该主手机号已经绑定资源啦'
+							} else if (checkResult.phoneAsBackupExists) {
+								message = '该主手机号已经作为备用手机号绑定资源啦'
+							} else if (checkResult.backupPhoneAsMainExists) {
+								message = '该备用手机号已经作为主手机号绑定资源啦'
+							} else if (checkResult.backupPhoneExists) {
+								message = '该备用手机号已经绑定资源啦'
+							}
+							
+							uni.hideLoading()
+							uni.showToast({
+								title: message,
+								icon: 'none',
+								duration: 3000
+							})
+							return
+						}
+					}
 				}
 				
-				// 构建请求URL,包含当前登录用户的ID作为参数(将作为红娘ID)
-				let url = `${baseUrl}/my-resource/add`
-				// 确保currentUserId是有效的整数才添加到URL中
-				if (this.currentUserId !== null && this.currentUserId !== undefined) {
-					const userId = parseInt(this.currentUserId)
-					if (!isNaN(userId) && userId > 0) {
-						url += `?currentUserId=${userId}`
+				// 根据是否为编辑模式选择不同的接口
+				let url, method, successMessage
+				if (this.isEditMode && this.resourceId) {
+					// 编辑模式:调用更新接口
+					url = `${baseUrl}/my-resource/update/${this.resourceId}`
+					method = 'PUT'
+					successMessage = '修改成功'
+					console.log('编辑模式 - 更新接口URL:', url, 'resourceId:', this.resourceId)
+				} else {
+					// 新增模式:调用添加接口
+					url = `${baseUrl}/my-resource/add`
+					method = 'POST'
+					// 确保currentUserId是有效的整数才添加到URL中
+					if (this.currentUserId !== null && this.currentUserId !== undefined) {
+						const userId = parseInt(this.currentUserId)
+						if (!isNaN(userId) && userId > 0) {
+							url += `?currentUserId=${userId}`
+						}
 					}
+					console.log('新增模式 - 添加接口URL:', url)
 				}
 				
+				console.log('提交请求 - URL:', url, 'Method:', method, 'isEditMode:', this.isEditMode, 'resourceId:', this.resourceId)
+				
 				const res = await uni.request({
 					url: url,
-					method: 'POST',
+					method: method,
 					data: submitData,
 					header: {
 						'Content-Type': 'application/json'
@@ -741,51 +1001,68 @@ export default {
 				uni.hideLoading()
 
 				if (res[1].statusCode === 200 && res[1].data.code === 200) {
-					// 获取返回的资源类型信息
-					const responseData = res[1].data.data
-					const resourceType = responseData && responseData.resourceType ? responseData.resourceType : '资源'
-					const isUser = responseData && responseData.isUser !== undefined ? responseData.isUser : null
-					
-					// 根据资源类型显示不同的成功提示
-					let successMessage = '添加资源成功'
-					if (isUser === 0 || resourceType === '线索') {
-						successMessage = '提交线索成功'
-					} else if (isUser === 1 || resourceType === '资源') {
-						successMessage = '添加资源成功'
+					if (this.isEditMode) {
+						// 编辑模式:显示修改成功
+						uni.showToast({
+							title: successMessage,
+							icon: 'success'
+						})
+					} else {
+						// 新增模式:获取返回的资源类型信息
+						const responseData = res[1].data.data
+						const resourceType = responseData && responseData.resourceType ? responseData.resourceType : '资源'
+						const isUser = responseData && responseData.isUser !== undefined ? responseData.isUser : null
+						
+						// 根据资源类型显示不同的成功提示
+						if (isUser === 0 || resourceType === '线索') {
+							successMessage = '提交线索成功'
+						} else if (isUser === 1 || resourceType === '资源') {
+							successMessage = '添加资源成功'
+						}
+						
+						uni.showToast({
+							title: successMessage,
+							icon: 'success'
+						})
 					}
 					
-					uni.showToast({
-						title: successMessage,
-						icon: 'success'
-					})
-					
 					// 延迟跳转到我的资源列表页面并刷新
 					setTimeout(() => {
-						// 获取页面栈,检查是否已经有我的资源列表页面
-						const pages = getCurrentPages()
-						const myResourcesPageIndex = pages.findIndex(page => {
-							return page.route && page.route.includes('matchmaker-workbench/my-resources')
-						})
-						
-						if (myResourcesPageIndex >= 0 && myResourcesPageIndex < pages.length - 1) {
-							// 如果我的资源列表页面已经在页面栈中(且不是当前页),返回到该页面
-							const delta = pages.length - myResourcesPageIndex - 1
+						if (this.isEditMode) {
+							// 编辑模式:直接返回上一页并刷新
 							uni.navigateBack({
-								delta: delta,
 								success: () => {
 									// 触发刷新事件
 									uni.$emit('refreshResourceList')
 								}
 							})
 						} else {
-							// 如果我的资源列表页面不在页面栈中,跳转到该页面
-							uni.redirectTo({
-								url: '/pages/matchmaker-workbench/my-resources',
-								success: () => {
-									// 触发刷新事件
-									uni.$emit('refreshResourceList')
-								}
+							// 新增模式:获取页面栈,检查是否已经有我的资源列表页面
+							const pages = getCurrentPages()
+							const myResourcesPageIndex = pages.findIndex(page => {
+								return page.route && page.route.includes('matchmaker-workbench/my-resources')
 							})
+							
+							if (myResourcesPageIndex >= 0 && myResourcesPageIndex < pages.length - 1) {
+								// 如果我的资源列表页面已经在页面栈中(且不是当前页),返回到该页面
+								const delta = pages.length - myResourcesPageIndex - 1
+								uni.navigateBack({
+									delta: delta,
+									success: () => {
+										// 触发刷新事件
+										uni.$emit('refreshResourceList')
+									}
+								})
+							} else {
+								// 如果我的资源列表页面不在页面栈中,跳转到该页面
+								uni.redirectTo({
+									url: '/pages/matchmaker-workbench/my-resources',
+									success: () => {
+										// 触发刷新事件
+										uni.$emit('refreshResourceList')
+									}
+								})
+							}
 						}
 					}, 1500)
 				} else {
@@ -803,6 +1080,201 @@ export default {
 					icon: 'none'
 				})
 			}
+		},
+		// 组合完整地址(省市区 + 详细地址)
+		buildFullAddress(regionText, detailText) {
+			let fullAddress = ''
+			if (regionText && regionText.trim()) {
+				fullAddress = regionText.trim()
+			}
+			if (detailText && detailText.trim()) {
+				if (fullAddress) {
+					fullAddress += ' ' + detailText.trim()
+				} else {
+					fullAddress = detailText.trim()
+				}
+			}
+			return fullAddress || null
+		},
+		// ========== 住址省市区相关方法 ==========
+		// 加载住址省份列表
+		async loadAddressProvinces() {
+			try {
+				const provinces = await api.area.getProvinces()
+				this.addressProvinces = provinces || []
+				this.addressMultiArray[0] = this.addressProvinces.map(p => p.name)
+				// 默认加载第一个省份的城市
+				if (this.addressProvinces.length > 0) {
+					await this.loadAddressCities(0)
+				}
+			} catch (e) {
+				console.error('加载住址省份失败:', e)
+			}
+		},
+		// 加载住址城市列表
+		async loadAddressCities(provinceIndex) {
+			const province = this.addressProvinces[provinceIndex]
+			if (!province || !province.id) return
+			
+			try {
+				const cities = await api.area.getCities(province.id)
+				this.addressCities = cities || []
+				this.addressMultiArray[1] = this.addressCities.map(c => c.name)
+				// 默认加载第一个城市的区域
+				if (this.addressCities.length > 0) {
+					await this.loadAddressAreas(0)
+				} else {
+					this.addressMultiArray[2] = []
+				}
+			} catch (e) {
+				console.error('加载住址城市失败:', e)
+				this.addressCities = []
+				this.addressMultiArray[1] = []
+				this.addressMultiArray[2] = []
+			}
+		},
+		// 加载住址区域列表
+		async loadAddressAreas(cityIndex) {
+			const city = this.addressCities[cityIndex]
+			if (!city || !city.id) return
+			
+			try {
+				const areas = await api.area.getAreas(city.id)
+				this.addressAreas = areas || []
+				this.addressMultiArray[2] = this.addressAreas.map(a => a.name)
+			} catch (e) {
+				console.error('加载住址区域失败:', e)
+				this.addressAreas = []
+				this.addressMultiArray[2] = []
+			}
+		},
+		// 住址列变化事件
+		async onAddressColumnChange(e) {
+			const column = e.detail.column
+			const row = e.detail.value
+			
+			if (column === 0) {
+				// 选择了省份
+				this.addressMultiIndex[0] = row
+				this.addressMultiIndex[1] = 0
+				this.addressMultiIndex[2] = 0
+				await this.loadAddressCities(row)
+			} else if (column === 1) {
+				// 选择了城市
+				this.addressMultiIndex[1] = row
+				this.addressMultiIndex[2] = 0
+				await this.loadAddressAreas(row)
+			} else if (column === 2) {
+				// 选择了区域
+				this.addressMultiIndex[2] = row
+			}
+		},
+		// 住址确认选择事件
+		onAddressChange(e) {
+			const values = e.detail.value
+			this.addressMultiIndex = values
+			
+			// 更新显示文本
+			const provinceName = this.addressMultiArray[0][values[0]] || ''
+			const cityName = this.addressMultiArray[1][values[1]] || ''
+			const areaName = this.addressMultiArray[2][values[2]] || ''
+			
+			let displayText = ''
+			if (provinceName) displayText += provinceName
+			if (cityName) displayText += (displayText ? ' ' : '') + cityName
+			if (areaName) displayText += (displayText ? ' ' : '') + areaName
+			
+			this.addressDisplayText = displayText
+		},
+		// ========== 户籍地省市区相关方法 ==========
+		// 加载户籍地省份列表
+		async loadDomicileProvinces() {
+			try {
+				const provinces = await api.area.getProvinces()
+				this.domicileProvinces = provinces || []
+				this.domicileMultiArray[0] = this.domicileProvinces.map(p => p.name)
+				// 默认加载第一个省份的城市
+				if (this.domicileProvinces.length > 0) {
+					await this.loadDomicileCities(0)
+				}
+			} catch (e) {
+				console.error('加载户籍地省份失败:', e)
+			}
+		},
+		// 加载户籍地城市列表
+		async loadDomicileCities(provinceIndex) {
+			const province = this.domicileProvinces[provinceIndex]
+			if (!province || !province.id) return
+			
+			try {
+				const cities = await api.area.getCities(province.id)
+				this.domicileCities = cities || []
+				this.domicileMultiArray[1] = this.domicileCities.map(c => c.name)
+				// 默认加载第一个城市的区域
+				if (this.domicileCities.length > 0) {
+					await this.loadDomicileAreas(0)
+				} else {
+					this.domicileMultiArray[2] = []
+				}
+			} catch (e) {
+				console.error('加载户籍地城市失败:', e)
+				this.domicileCities = []
+				this.domicileMultiArray[1] = []
+				this.domicileMultiArray[2] = []
+			}
+		},
+		// 加载户籍地区域列表
+		async loadDomicileAreas(cityIndex) {
+			const city = this.domicileCities[cityIndex]
+			if (!city || !city.id) return
+			
+			try {
+				const areas = await api.area.getAreas(city.id)
+				this.domicileAreas = areas || []
+				this.domicileMultiArray[2] = this.domicileAreas.map(a => a.name)
+			} catch (e) {
+				console.error('加载户籍地区域失败:', e)
+				this.domicileAreas = []
+				this.domicileMultiArray[2] = []
+			}
+		},
+		// 户籍地列变化事件
+		async onDomicileColumnChange(e) {
+			const column = e.detail.column
+			const row = e.detail.value
+			
+			if (column === 0) {
+				// 选择了省份
+				this.domicileMultiIndex[0] = row
+				this.domicileMultiIndex[1] = 0
+				this.domicileMultiIndex[2] = 0
+				await this.loadDomicileCities(row)
+			} else if (column === 1) {
+				// 选择了城市
+				this.domicileMultiIndex[1] = row
+				this.domicileMultiIndex[2] = 0
+				await this.loadDomicileAreas(row)
+			} else if (column === 2) {
+				// 选择了区域
+				this.domicileMultiIndex[2] = row
+			}
+		},
+		// 户籍地确认选择事件
+		onDomicileChange(e) {
+			const values = e.detail.value
+			this.domicileMultiIndex = values
+			
+			// 更新显示文本
+			const provinceName = this.domicileMultiArray[0][values[0]] || ''
+			const cityName = this.domicileMultiArray[1][values[1]] || ''
+			const areaName = this.domicileMultiArray[2][values[2]] || ''
+			
+			let displayText = ''
+			if (provinceName) displayText += provinceName
+			if (cityName) displayText += (displayText ? ' ' : '') + cityName
+			if (areaName) displayText += (displayText ? ' ' : '') + areaName
+			
+			this.domicileDisplayText = displayText
 		}
 	}
 }
@@ -1013,12 +1485,21 @@ export default {
 		.placeholder {
 			color: #999;
 		}
+		
+		.picker-text {
+			color: #333;
+			flex: 1;
+		}
 
-	.picker-arrow {
-		font-size: 24rpx;
-		color: #999;
+		.picker-arrow {
+			font-size: 24rpx;
+			color: #999;
+		}
+	}
+	
+	.address-detail-input {
+		margin-top: 15rpx;
 	}
-}
 }
 
 .submit-bar {

+ 55 - 3
service/homePage/src/main/java/com/zhentao/controller/MyResourceController.java

@@ -369,12 +369,64 @@ public class MyResourceController {
     @PutMapping("/update/{resourceId}")
     public Result<MyResource> updateResource(
             @PathVariable Integer resourceId,
-            @RequestBody MyResource myResource) {
+            @RequestBody java.util.Map<String, Object> requestBody) {
         try {
+            // 从请求体中提取资源信息和标签ID列表
+            MyResource myResource = new MyResource();
+            
+            // 使用ObjectMapper转换资源信息
+            com.fasterxml.jackson.databind.ObjectMapper objectMapper = new com.fasterxml.jackson.databind.ObjectMapper();
+            try {
+                // 先创建一个Map,排除tagIds字段
+                java.util.Map<String, Object> resourceMap = new java.util.HashMap<>(requestBody);
+                resourceMap.remove("tagIds");
+                myResource = objectMapper.convertValue(resourceMap, MyResource.class);
+            } catch (Exception e) {
+                System.err.println("转换资源信息失败,使用手动设置: " + e.getMessage());
+                // 如果转换失败,手动设置字段
+                if (requestBody.containsKey("name")) myResource.setName((String) requestBody.get("name"));
+                if (requestBody.containsKey("age")) myResource.setAge(requestBody.get("age") != null ? Integer.valueOf(requestBody.get("age").toString()) : null);
+                if (requestBody.containsKey("gender")) myResource.setGender(requestBody.get("gender") != null ? Integer.valueOf(requestBody.get("gender").toString()) : null);
+                if (requestBody.containsKey("constellation")) myResource.setConstellation((String) requestBody.get("constellation"));
+                if (requestBody.containsKey("height")) myResource.setHeight(requestBody.get("height") != null ? Integer.valueOf(requestBody.get("height").toString()) : null);
+                if (requestBody.containsKey("weight")) myResource.setWeight(requestBody.get("weight") != null ? Integer.valueOf(requestBody.get("weight").toString()) : null);
+                if (requestBody.containsKey("marrStatus")) myResource.setMarrStatus(requestBody.get("marrStatus") != null ? Integer.valueOf(requestBody.get("marrStatus").toString()) : null);
+                if (requestBody.containsKey("diploma")) myResource.setDiploma((String) requestBody.get("diploma"));
+                if (requestBody.containsKey("income")) myResource.setIncome((String) requestBody.get("income"));
+                if (requestBody.containsKey("address")) myResource.setAddress((String) requestBody.get("address"));
+                if (requestBody.containsKey("domicile")) myResource.setDomicile((String) requestBody.get("domicile"));
+                if (requestBody.containsKey("occupation")) myResource.setOccupation((String) requestBody.get("occupation"));
+                if (requestBody.containsKey("house")) myResource.setHouse(requestBody.get("house") != null ? Integer.valueOf(requestBody.get("house").toString()) : null);
+                if (requestBody.containsKey("car")) myResource.setCar(requestBody.get("car") != null ? Integer.valueOf(requestBody.get("car").toString()) : null);
+                if (requestBody.containsKey("phone")) myResource.setPhone((String) requestBody.get("phone"));
+                if (requestBody.containsKey("backupPhone")) myResource.setBackupPhone((String) requestBody.get("backupPhone"));
+                if (requestBody.containsKey("mateSelectionCriteria")) myResource.setMateSelectionCriteria((String) requestBody.get("mateSelectionCriteria"));
+            }
+            
+            // 设置资源ID和更新时间
             myResource.setResourceId(resourceId);
-            // 更新更新时间
             myResource.setUpdateTime(new java.util.Date());
-            boolean success = myResourceService.updateById(myResource);
+            
+            // 提取标签ID列表
+            java.util.List<Integer> tagIds = null;
+            if (requestBody.containsKey("tagIds") && requestBody.get("tagIds") != null) {
+                Object tagIdsObj = requestBody.get("tagIds");
+                if (tagIdsObj instanceof java.util.List) {
+                    tagIds = new java.util.ArrayList<>();
+                    for (Object item : (java.util.List<?>) tagIdsObj) {
+                        if (item != null) {
+                            tagIds.add(Integer.valueOf(item.toString()));
+                        }
+                    }
+                }
+            }
+            
+            System.out.println("=== 更新资源数据 ===");
+            System.out.println("资源ID: " + resourceId);
+            System.out.println("标签ID列表: " + tagIds);
+            
+            // 调用Service方法更新资源(包括标签)
+            boolean success = myResourceService.updateResource(myResource, tagIds);
             if (success) {
                 return Result.success("资源信息更新成功", myResource);
             } else {

+ 8 - 0
service/homePage/src/main/java/com/zhentao/service/MyResourceService.java

@@ -23,6 +23,14 @@ public interface MyResourceService extends IService<MyResource> {
      */
     boolean addResource(MyResource myResource, List<Integer> tagIds);
     
+    /**
+     * 更新资源信息(包括标签)
+     * @param myResource 资源信息
+     * @param tagIds 标签ID列表(可选)
+     * @return 是否成功
+     */
+    boolean updateResource(MyResource myResource, List<Integer> tagIds);
+    
     /**
      * 分页查询资源列表
      * @param matchmakerId 红娘ID

+ 63 - 0
service/homePage/src/main/java/com/zhentao/service/impl/MyResourceServiceImpl.java

@@ -184,6 +184,69 @@ public class MyResourceServiceImpl extends ServiceImpl<MyResourceMapper, MyResou
         return result;
     }
     
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateResource(MyResource myResource, List<Integer> tagIds) {
+        // 处理备用手机号:如果为空字符串,设置为null;如果有值,去除首尾空格
+        if (myResource.getBackupPhone() != null) {
+            String trimmed = myResource.getBackupPhone().trim();
+            if (trimmed.isEmpty()) {
+                myResource.setBackupPhone(null);
+            } else {
+                myResource.setBackupPhone(trimmed);
+            }
+        }
+        
+        // 处理择偶标准:如果为空字符串,设置为null;如果有值,去除首尾空格
+        if (myResource.getMateSelectionCriteria() != null) {
+            String trimmed = myResource.getMateSelectionCriteria().trim();
+            if (trimmed.isEmpty()) {
+                myResource.setMateSelectionCriteria(null);
+            } else {
+                myResource.setMateSelectionCriteria(trimmed);
+            }
+        }
+        
+        // 更新资源基本信息
+        boolean result = this.updateById(myResource);
+        
+        System.out.println("=== 更新资源基本信息 ===");
+        System.out.println("资源ID: " + myResource.getResourceId());
+        System.out.println("更新结果: " + result);
+        
+        // 更新标签关联
+        if (result && myResource.getResourceId() != null) {
+            System.out.println("=== 开始更新标签关联 ===");
+            System.out.println("资源ID: " + myResource.getResourceId());
+            System.out.println("新标签ID列表: " + tagIds);
+            
+            // 删除旧的标签关联
+            com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<MyResourceTag> deleteWrapper = 
+                new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<>();
+            deleteWrapper.eq("resource_id", myResource.getResourceId());
+            int deleteCount = myResourceTagMapper.delete(deleteWrapper);
+            System.out.println("删除旧标签关联数量: " + deleteCount);
+            
+            // 插入新的标签关联
+            if (tagIds != null && !tagIds.isEmpty()) {
+                Date now = new Date();
+                for (Integer tagId : tagIds) {
+                    if (tagId != null) {
+                        MyResourceTag resourceTag = new MyResourceTag();
+                        resourceTag.setResourceId(myResource.getResourceId());
+                        resourceTag.setTagId(tagId);
+                        resourceTag.setCreateTime(now);
+                        int tagInsertResult = myResourceTagMapper.insert(resourceTag);
+                        System.out.println("插入标签关联 - tagId: " + tagId + ", 结果: " + tagInsertResult);
+                    }
+                }
+            }
+            System.out.println("=== 标签关联更新完成 ===");
+        }
+        
+        return result;
+    }
+    
     /**
      * 获取红娘当日已上传的线索数量(只统计未注册用户,isUser=0或null)
      * @param matchmakerId 红娘ID