|
|
@@ -12,7 +12,12 @@
|
|
|
<image :src="clientInfo.avatar" class="client-avatar" mode="aspectFill"></image>
|
|
|
<view class="basic-info">
|
|
|
<text class="client-name">{{ clientInfo.gender }} · {{ clientInfo.name }}</text>
|
|
|
- <text class="client-status">{{ clientInfo.status }}</text>
|
|
|
+ <view class="status-tag-wrapper">
|
|
|
+ <text class="status-tag register-tag registered">已注册</text>
|
|
|
+ <text class="status-tag match-tag" :class="{ 'matched': followForm.matchStatus === 1, 'unmatched': followForm.matchStatus === 0 || followForm.matchStatus === null }">
|
|
|
+ {{ followForm.matchStatus === 1 ? '已匹配' : '未匹配' }}
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
<view class="client-tags">
|
|
|
<text class="tag" v-for="(tag, index) in clientInfo.tags" :key="index">{{ tag }}</text>
|
|
|
</view>
|
|
|
@@ -37,7 +42,7 @@
|
|
|
<text class="copy-btn" @click="handleCopy(clientInfo.contact)">复制</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
- <view class="contact-item">
|
|
|
+ <view class="contact-item" v-if="clientInfo.backupContact">
|
|
|
<text class="contact-label">备用联系方式</text>
|
|
|
<view class="contact-value">
|
|
|
<text class="contact-number">{{ clientInfo.backupContact }}</text>
|
|
|
@@ -77,8 +82,6 @@
|
|
|
|
|
|
<!-- 详细信息 -->
|
|
|
<scroll-view scroll-y class="details-section" v-if="activeTab === 'details'">
|
|
|
- <view class="edit-btn" @click="handleEdit">编辑</view>
|
|
|
-
|
|
|
<!-- 基本信息 -->
|
|
|
<view class="detail-item">
|
|
|
<text class="detail-label">婚姻状况:</text>
|
|
|
@@ -94,7 +97,10 @@
|
|
|
</view>
|
|
|
<view class="detail-item">
|
|
|
<text class="detail-label">收入:</text>
|
|
|
- <text class="detail-value">{{ clientInfo.details.income }}</text>
|
|
|
+ <text class="detail-value">
|
|
|
+ {{ clientInfo.details.income }}
|
|
|
+ <text v-if="clientInfo.details.income && clientInfo.details.income !== '未知'">万元/年</text>
|
|
|
+ </text>
|
|
|
</view>
|
|
|
<view class="detail-item">
|
|
|
<text class="detail-label">购房情况:</text>
|
|
|
@@ -102,7 +108,7 @@
|
|
|
</view>
|
|
|
|
|
|
<!-- 择偶要求详情 -->
|
|
|
- <view class="sub-section-title">择偶要求</view>
|
|
|
+ <view class="sub-section-title requirement-section-title">择偶详细要求</view>
|
|
|
<view class="detail-item">
|
|
|
<text class="detail-label">年龄范围:</text>
|
|
|
<text class="detail-value">{{ clientInfo.details.requirement.ageRange }}</text>
|
|
|
@@ -125,7 +131,7 @@
|
|
|
</view>
|
|
|
|
|
|
<!-- 客户标签 -->
|
|
|
- <view class="sub-section-title">客户标签</view>
|
|
|
+ <view class="sub-section-title tags-section-title">客户标签</view>
|
|
|
<view class="client-tags">
|
|
|
<text class="tag" v-for="(tag, index) in clientInfo.tags" :key="index">{{ tag }}</text>
|
|
|
</view>
|
|
|
@@ -152,22 +158,26 @@
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
+ <!-- 匹配状态 -->
|
|
|
+ <view class="follow-group">
|
|
|
+ <text class="group-label">匹配状态</text>
|
|
|
+ <view class="status-tags-row">
|
|
|
+ <view class="status-tag" :class="{ active: followForm.matchStatus === 0 }" @click="handleMatchStatusChange(0)">未匹配</view>
|
|
|
+ <view class="status-tag" :class="{ active: followForm.matchStatus === 1 }" @click="handleMatchStatusChange(1)">已匹配</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
<!-- 跟进进度 -->
|
|
|
<view class="follow-group">
|
|
|
<text class="group-label">跟进进度</text>
|
|
|
<view class="status-tags-row">
|
|
|
- <view class="status-tag" :class="{ active: followForm.progress === 'matched' }" @click="followForm.progress = 'matched'">已匹配</view>
|
|
|
<view class="status-tag" :class="{ active: followForm.progress === 'notMet' }" @click="followForm.progress = 'notMet'">未见面</view>
|
|
|
<view class="status-tag" :class="{ active: followForm.progress === 'communicating' }" @click="followForm.progress = 'communicating'">沟通中</view>
|
|
|
+ <view class="status-tag" :class="{ active: followForm.invitationStatus === 0 }" @click="handleInvitationStatusChange(0)">未邀约</view>
|
|
|
+ <view class="status-tag" :class="{ active: followForm.invitationStatus === 1 }" @click="handleInvitationStatusChange(1)">已邀约</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
- <!-- 邀约状态 -->
|
|
|
- <view class="follow-group">
|
|
|
- <text class="group-label">邀约状态</text>
|
|
|
- <view class="input-like">{{ followForm.inviteStatus || '未邀约' }}</view>
|
|
|
- </view>
|
|
|
-
|
|
|
<!-- 邀约时间 -->
|
|
|
<view class="follow-group">
|
|
|
<text class="group-label">邀约时间</text>
|
|
|
@@ -199,38 +209,42 @@ export default {
|
|
|
followForm: {
|
|
|
type: 'phone',
|
|
|
progress: 'matched',
|
|
|
- inviteStatus: '未邀约',
|
|
|
+ matchStatus: 0, // 0-未匹配,1-已匹配
|
|
|
+ invitationStatus: 0, // 0-未邀约,1-已邀约
|
|
|
inviteDate: '',
|
|
|
remark: ''
|
|
|
},
|
|
|
+ resourceId: null, // 资源ID
|
|
|
clientInfo: {
|
|
|
id: 1,
|
|
|
- name: '小明',
|
|
|
+ name: '',
|
|
|
gender: '男',
|
|
|
status: '已匹配',
|
|
|
- tags: ['气质男', '小清新'],
|
|
|
- avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=60',
|
|
|
- requirement: '165+ 本科 天津 本地户口 无婚姻经历',
|
|
|
- contact: '123****9912',
|
|
|
- backupContact: '155****4512',
|
|
|
+ tags: [],
|
|
|
+ avatar: '',
|
|
|
+ requirement: '暂无要求',
|
|
|
+ contact: '',
|
|
|
+ backupContact: '',
|
|
|
+ originalPhone: '', // 保存原始手机号用于复制
|
|
|
+ originalBackupPhone: '', // 保存原始备用手机号用于复制
|
|
|
stats: {
|
|
|
- followTimes: 12,
|
|
|
- matchCount: 3,
|
|
|
- phoneCalls: 5,
|
|
|
- interviews: 7
|
|
|
+ followTimes: 0,
|
|
|
+ matchCount: 0,
|
|
|
+ phoneCalls: 0,
|
|
|
+ interviews: 0
|
|
|
},
|
|
|
details: {
|
|
|
- maritalStatus: '离异',
|
|
|
- education: '本科',
|
|
|
- occupation: '企业高管',
|
|
|
- income: '50万/年',
|
|
|
- housing: '已购房',
|
|
|
+ maritalStatus: '',
|
|
|
+ education: '',
|
|
|
+ occupation: '',
|
|
|
+ income: '',
|
|
|
+ housing: '',
|
|
|
requirement: {
|
|
|
- ageRange: '30-40岁',
|
|
|
- height: '175cm以上',
|
|
|
- maritalStatus: '离异无孩或未婚',
|
|
|
- education: '本科及以上',
|
|
|
- other: '外貌或者性格'
|
|
|
+ ageRange: '',
|
|
|
+ height: '',
|
|
|
+ maritalStatus: '',
|
|
|
+ education: '',
|
|
|
+ other: ''
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
@@ -242,13 +256,47 @@ export default {
|
|
|
if (stored === true || stored === false) {
|
|
|
this.isDarkTheme = stored
|
|
|
}
|
|
|
+
|
|
|
+ // 如果已经有resourceId,刷新统计数据
|
|
|
+ if (this.resourceId) {
|
|
|
+ this.loadFollowStatistics(this.resourceId)
|
|
|
+ }
|
|
|
},
|
|
|
onLoad(options) {
|
|
|
- // 从URL参数获取客户ID
|
|
|
- if (options.id) {
|
|
|
- // 这里可以根据ID从API获取客户信息
|
|
|
- console.log('客户ID:', options.id)
|
|
|
- // this.loadClientInfo(options.id)
|
|
|
+ console.log('=== 客户详情页面 onLoad ===')
|
|
|
+ console.log('options:', JSON.stringify(options, null, 2))
|
|
|
+
|
|
|
+ // 从URL参数获取资源ID
|
|
|
+ let resourceId = null
|
|
|
+ if (options.resourceId) {
|
|
|
+ resourceId = options.resourceId
|
|
|
+ console.log('从resourceId参数获取:', resourceId)
|
|
|
+ } else if (options.id) {
|
|
|
+ // 兼容旧的id参数
|
|
|
+ resourceId = options.id
|
|
|
+ console.log('从id参数获取 (兼容):', resourceId)
|
|
|
+ }
|
|
|
+
|
|
|
+ if (resourceId) {
|
|
|
+ // 确保resourceId是数字类型
|
|
|
+ resourceId = parseInt(resourceId)
|
|
|
+ if (isNaN(resourceId) || resourceId <= 0) {
|
|
|
+ console.error('资源ID无效:', resourceId)
|
|
|
+ uni.showToast({
|
|
|
+ title: '资源ID无效',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ console.log('最终使用的resourceId:', resourceId, '类型:', typeof resourceId)
|
|
|
+ this.resourceId = resourceId
|
|
|
+ this.loadClientInfo(resourceId)
|
|
|
+ } else {
|
|
|
+ console.error('未获取到资源ID')
|
|
|
+ uni.showToast({
|
|
|
+ title: '未获取到资源ID',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
@@ -258,13 +306,30 @@ export default {
|
|
|
},
|
|
|
// 复制联系方式
|
|
|
handleCopy(contact) {
|
|
|
+ // 如果传入的是脱敏的手机号,使用原始手机号
|
|
|
+ let phoneToCopy = contact
|
|
|
+ if (contact === this.clientInfo.contact && this.clientInfo.originalPhone) {
|
|
|
+ phoneToCopy = this.clientInfo.originalPhone
|
|
|
+ } else if (contact === this.clientInfo.backupContact && this.clientInfo.originalBackupPhone) {
|
|
|
+ phoneToCopy = this.clientInfo.originalBackupPhone
|
|
|
+ } else {
|
|
|
+ // 尝试从脱敏号码中提取
|
|
|
+ phoneToCopy = contact.replace(/\*+/g, '')
|
|
|
+ }
|
|
|
+
|
|
|
uni.setClipboardData({
|
|
|
- data: contact.replace(/\*+/g, ''),
|
|
|
+ data: phoneToCopy,
|
|
|
success: () => {
|
|
|
uni.showToast({
|
|
|
title: '复制成功',
|
|
|
icon: 'success'
|
|
|
})
|
|
|
+ },
|
|
|
+ fail: () => {
|
|
|
+ uni.showToast({
|
|
|
+ title: '复制失败',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
}
|
|
|
})
|
|
|
},
|
|
|
@@ -272,37 +337,488 @@ export default {
|
|
|
switchTab(tab) {
|
|
|
this.activeTab = tab
|
|
|
},
|
|
|
- // 编辑客户信息
|
|
|
- handleEdit() {
|
|
|
- uni.showToast({
|
|
|
- title: '编辑功能正在开发中',
|
|
|
- icon: 'none'
|
|
|
- })
|
|
|
- },
|
|
|
// 邀约日期变更
|
|
|
onInviteDateChange(e) {
|
|
|
this.followForm.inviteDate = e.detail.value
|
|
|
},
|
|
|
- // 提交跟进(暂时仅提示)
|
|
|
- handleSubmitFollow() {
|
|
|
- uni.showToast({
|
|
|
- title: '跟进已保存',
|
|
|
- icon: 'success'
|
|
|
- })
|
|
|
+ // 匹配状态变更
|
|
|
+ handleMatchStatusChange(status) {
|
|
|
+ this.followForm.matchStatus = status
|
|
|
+ },
|
|
|
+ // 邀约状态变更
|
|
|
+ handleInvitationStatusChange(status) {
|
|
|
+ this.followForm.invitationStatus = status
|
|
|
+ // 如果选择已邀约且没有设置邀约时间,提示用户选择
|
|
|
+ if (status === 1 && !this.followForm.inviteDate) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请选择邀约时间',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 加载最新的跟进信息,更新表单字段
|
|
|
+ async loadLatestFollowInfo(resourceId) {
|
|
|
+ try {
|
|
|
+ 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/latest-follow/${resourceId}`,
|
|
|
+ method: 'GET',
|
|
|
+ header: {
|
|
|
+ 'Content-Type': 'application/json'
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ if (error) {
|
|
|
+ console.error('加载最新跟进信息失败:', error)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (res.statusCode === 200 && res.data && res.data.code === 200) {
|
|
|
+ const followUp = res.data.data
|
|
|
+
|
|
|
+ if (followUp) {
|
|
|
+ // 更新跟进方式(1-电话,2-面谈,3-其他)
|
|
|
+ if (followUp.followType !== null && followUp.followType !== undefined) {
|
|
|
+ const followType = followUp.followType
|
|
|
+ if (followType === 1) {
|
|
|
+ this.followForm.type = 'phone'
|
|
|
+ } else if (followType === 2) {
|
|
|
+ this.followForm.type = 'meet'
|
|
|
+ } else if (followType === 3) {
|
|
|
+ this.followForm.type = 'other'
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新跟进进度(1-已匹配,2-未见面,3-沟通中)
|
|
|
+ if (followUp.followProgress !== null && followUp.followProgress !== undefined) {
|
|
|
+ const progress = followUp.followProgress
|
|
|
+ if (progress === 1) {
|
|
|
+ this.followForm.progress = 'matched'
|
|
|
+ } else if (progress === 2) {
|
|
|
+ this.followForm.progress = 'notMet'
|
|
|
+ } else if (progress === 3) {
|
|
|
+ this.followForm.progress = 'communicating'
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新匹配状态
|
|
|
+ if (followUp.isMatch !== null && followUp.isMatch !== undefined) {
|
|
|
+ this.followForm.matchStatus = parseInt(followUp.isMatch) || 0
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新邀约状态
|
|
|
+ if (followUp.isInvitation !== null && followUp.isInvitation !== undefined) {
|
|
|
+ this.followForm.invitationStatus = parseInt(followUp.isInvitation) || 0
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新邀约时间
|
|
|
+ if (followUp.invitationTime) {
|
|
|
+ const date = new Date(followUp.invitationTime)
|
|
|
+ const year = date.getFullYear()
|
|
|
+ const month = String(date.getMonth() + 1).padStart(2, '0')
|
|
|
+ const day = String(date.getDate()).padStart(2, '0')
|
|
|
+ this.followForm.inviteDate = `${year}-${month}-${day}`
|
|
|
+ } else {
|
|
|
+ this.followForm.inviteDate = ''
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新备注
|
|
|
+ if (followUp.remark !== null && followUp.remark !== undefined) {
|
|
|
+ this.followForm.remark = followUp.remark || ''
|
|
|
+ } else {
|
|
|
+ this.followForm.remark = ''
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('表单字段已更新:', {
|
|
|
+ type: this.followForm.type,
|
|
|
+ progress: this.followForm.progress,
|
|
|
+ matchStatus: this.followForm.matchStatus,
|
|
|
+ invitationStatus: this.followForm.invitationStatus,
|
|
|
+ inviteDate: this.followForm.inviteDate,
|
|
|
+ remark: this.followForm.remark
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ console.log('暂无跟进记录,保持表单当前值')
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.error('加载最新跟进信息异常:', e)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 加载跟进统计数据
|
|
|
+ async loadFollowStatistics(resourceId) {
|
|
|
+ try {
|
|
|
+ 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/follow-statistics/${resourceId}`,
|
|
|
+ method: 'GET',
|
|
|
+ header: {
|
|
|
+ 'Content-Type': 'application/json'
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ if (error) {
|
|
|
+ console.error('加载统计数据失败:', error)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (res.statusCode === 200 && res.data && res.data.code === 200) {
|
|
|
+ const statistics = res.data.data
|
|
|
+ console.log('=== 统计数据响应 ===')
|
|
|
+ console.log('完整响应:', JSON.stringify(res.data, null, 2))
|
|
|
+ console.log('统计数据对象:', statistics)
|
|
|
+ console.log('followCount:', statistics?.followCount, statistics?.follow_count)
|
|
|
+ console.log('matchCount:', statistics?.matchCount, statistics?.match_count)
|
|
|
+ console.log('phoneCount:', statistics?.phoneCount, statistics?.phone_count)
|
|
|
+ console.log('interviewCount:', statistics?.interviewCount, statistics?.interview_count)
|
|
|
+
|
|
|
+ // 更新统计数据(支持驼峰和下划线两种字段名格式)
|
|
|
+ if (this.clientInfo && this.clientInfo.stats) {
|
|
|
+ const followCount = statistics?.followCount ?? statistics?.follow_count ?? 0
|
|
|
+ const matchCount = statistics?.matchCount ?? statistics?.match_count ?? 0
|
|
|
+ const phoneCount = statistics?.phoneCount ?? statistics?.phone_count ?? 0
|
|
|
+ const interviewCount = statistics?.interviewCount ?? statistics?.interview_count ?? 0
|
|
|
+
|
|
|
+ this.clientInfo.stats.followTimes = followCount
|
|
|
+ this.clientInfo.stats.matchCount = matchCount
|
|
|
+ this.clientInfo.stats.phoneCalls = phoneCount
|
|
|
+ this.clientInfo.stats.interviews = interviewCount
|
|
|
+
|
|
|
+ console.log('更新后的统计数据:', {
|
|
|
+ followTimes: this.clientInfo.stats.followTimes,
|
|
|
+ matchCount: this.clientInfo.stats.matchCount,
|
|
|
+ phoneCalls: this.clientInfo.stats.phoneCalls,
|
|
|
+ interviews: this.clientInfo.stats.interviews
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ console.warn('clientInfo或stats不存在')
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ console.error('统计数据接口返回错误:', res.data)
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.error('加载统计数据异常:', e)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 提交跟进
|
|
|
+ async handleSubmitFollow() {
|
|
|
+ if (!this.resourceId) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '资源ID不存在',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ uni.showLoading({
|
|
|
+ title: '保存中...'
|
|
|
+ })
|
|
|
+
|
|
|
+ const baseUrl = process.env.NODE_ENV === 'development'
|
|
|
+ ? 'http://localhost:8083/api' // 开发环境 - 通过网关
|
|
|
+ : 'https://your-domain.com/api' // 生产环境
|
|
|
+
|
|
|
+ // 准备请求数据
|
|
|
+ // 跟进方式转换:phone->1, meet->2, other->3
|
|
|
+ let followType = 1 // 默认电话
|
|
|
+ if (this.followForm.type === 'meet') {
|
|
|
+ followType = 2
|
|
|
+ } else if (this.followForm.type === 'other') {
|
|
|
+ followType = 3
|
|
|
+ }
|
|
|
+
|
|
|
+ // 跟进进度转换:matched->1, notMet->2, communicating->3
|
|
|
+ let progress = 1 // 默认已匹配
|
|
|
+ if (this.followForm.progress === 'notMet') {
|
|
|
+ progress = 2
|
|
|
+ } else if (this.followForm.progress === 'communicating') {
|
|
|
+ progress = 3
|
|
|
+ }
|
|
|
+
|
|
|
+ const requestData = {
|
|
|
+ followType: followType,
|
|
|
+ progress: this.followForm.progress, // 保持字符串格式,后端会转换
|
|
|
+ matchStatus: this.followForm.matchStatus,
|
|
|
+ invitationStatus: this.followForm.invitationStatus,
|
|
|
+ invitationTime: this.followForm.inviteDate || null,
|
|
|
+ remark: this.followForm.remark || '' // 添加备注字段
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('保存跟进数据:', requestData)
|
|
|
+
|
|
|
+ const [error, res] = await uni.request({
|
|
|
+ url: `${baseUrl}/my-resource/update-follow/${this.resourceId}`,
|
|
|
+ method: 'PUT',
|
|
|
+ data: requestData,
|
|
|
+ header: {
|
|
|
+ 'Content-Type': 'application/json'
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ uni.hideLoading()
|
|
|
+
|
|
|
+ if (error) {
|
|
|
+ console.error('保存跟进失败:', error)
|
|
|
+ uni.showToast({
|
|
|
+ title: '保存失败',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (res.statusCode === 200 && res.data && res.data.code === 200) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '跟进已保存',
|
|
|
+ icon: 'success'
|
|
|
+ })
|
|
|
+
|
|
|
+ // 刷新统计数据
|
|
|
+ if (this.resourceId) {
|
|
|
+ this.loadFollowStatistics(this.resourceId)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 重新加载最新的跟进信息,更新表单字段
|
|
|
+ if (this.resourceId) {
|
|
|
+ this.loadLatestFollowInfo(this.resourceId)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 触发资源列表刷新事件
|
|
|
+ uni.$emit('refreshResourceList')
|
|
|
+ } else {
|
|
|
+ const errorMsg = res.data?.message || '保存失败'
|
|
|
+ uni.showToast({
|
|
|
+ title: errorMsg,
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ uni.hideLoading()
|
|
|
+ console.error('保存跟进异常:', e)
|
|
|
+ uni.showToast({
|
|
|
+ title: '保存失败,请稍后重试',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ }
|
|
|
},
|
|
|
// 从API加载客户信息
|
|
|
- async loadClientInfo(id) {
|
|
|
+ async loadClientInfo(resourceId) {
|
|
|
try {
|
|
|
- // 这里调用API获取客户信息
|
|
|
- // const res = await api.matchmaker.getClientInfo(id)
|
|
|
- // this.clientInfo = res.data
|
|
|
+ console.log('=== 开始加载客户信息 ===')
|
|
|
+ console.log('resourceId:', resourceId, '类型:', typeof resourceId)
|
|
|
+
|
|
|
+ uni.showLoading({
|
|
|
+ title: '加载中...'
|
|
|
+ })
|
|
|
+
|
|
|
+ const baseUrl = process.env.NODE_ENV === 'development'
|
|
|
+ ? 'http://localhost:8083/api' // 开发环境 - 通过网关
|
|
|
+ : 'https://your-domain.com/api' // 生产环境
|
|
|
+
|
|
|
+ const requestUrl = `${baseUrl}/my-resource/client-detail/${resourceId}`
|
|
|
+ console.log('请求URL:', requestUrl)
|
|
|
+
|
|
|
+ const [error, res] = await uni.request({
|
|
|
+ url: requestUrl,
|
|
|
+ method: 'GET',
|
|
|
+ timeout: 30000, // 设置30秒超时
|
|
|
+ header: {
|
|
|
+ 'Content-Type': 'application/json'
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ console.log('请求结果 - error:', error)
|
|
|
+ console.log('请求结果 - res:', res)
|
|
|
+
|
|
|
+ uni.hideLoading()
|
|
|
+
|
|
|
+ if (error) {
|
|
|
+ console.error('加载客户信息失败:', error)
|
|
|
+ let errorMsg = '加载失败'
|
|
|
+ if (error.errMsg) {
|
|
|
+ if (error.errMsg.includes('timeout') || error.errMsg.includes('超时')) {
|
|
|
+ errorMsg = '请求超时,请检查网络连接'
|
|
|
+ } else if (error.errMsg.includes('fail')) {
|
|
|
+ errorMsg = '网络连接失败,请检查服务器是否启动'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ uni.showToast({
|
|
|
+ title: errorMsg,
|
|
|
+ icon: 'none',
|
|
|
+ duration: 3000
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (res.statusCode === 200 && res.data && res.data.code === 200) {
|
|
|
+ const data = res.data.data
|
|
|
+
|
|
|
+ console.log('=== 客户详情数据 ===')
|
|
|
+ console.log('完整数据:', JSON.stringify(data, null, 2))
|
|
|
+
|
|
|
+ // 支持驼峰和下划线两种字段名格式
|
|
|
+ const resourceId = data.resourceId || data.resource_id
|
|
|
+ const avatarUrl = data.avatarUrl || data.avatar_url
|
|
|
+ const backupPhone = data.backupPhone || data.backup_phone
|
|
|
+ const marrStatus = data.marrStatus !== undefined ? data.marrStatus : data.marr_status
|
|
|
+ // 择偶要求从my_resource表的mate_selection_criteria字段获取
|
|
|
+ const mateSelectionCriteria = data.mateSelectionCriteria || data.mate_selection_criteria
|
|
|
+
|
|
|
+ // 择偶要求详情字段(从partner_requirement表,用于详情页)
|
|
|
+ const minAge = data.minAge !== undefined ? data.minAge : data.min_age
|
|
|
+ const maxAge = data.maxAge !== undefined ? data.maxAge : data.max_age
|
|
|
+ const minHeight = data.minHeight !== undefined ? data.minHeight : data.min_height
|
|
|
+ const maxHeight = data.maxHeight !== undefined ? data.maxHeight : data.max_height
|
|
|
+ const educationLevel = data.educationLevel !== undefined ? data.educationLevel : data.education_level
|
|
|
+ const salaryRange = data.salaryRange !== undefined ? data.salaryRange : data.salary_range
|
|
|
+ const houseRequirement = data.houseRequirement !== undefined ? data.houseRequirement : data.house_requirement
|
|
|
+ const carRequirement = data.carRequirement !== undefined ? data.carRequirement : data.car_requirement
|
|
|
+ const maritalStatusRequirement = data.maritalStatusRequirement !== undefined ? data.maritalStatusRequirement : data.marital_status_requirement
|
|
|
+ const preferredCity = data.preferredCity || data.preferred_city
|
|
|
+ const otherRequirements = data.otherRequirements || data.other_requirements
|
|
|
+
|
|
|
+ console.log('资源ID:', resourceId)
|
|
|
+ console.log('姓名:', data.name)
|
|
|
+ console.log('头像URL:', avatarUrl)
|
|
|
+ console.log('备用手机号:', backupPhone)
|
|
|
+ console.log('择偶要求(mate_selection_criteria):', mateSelectionCriteria)
|
|
|
+ console.log('择偶要求详情数据:', {
|
|
|
+ minAge, maxAge, minHeight, maxHeight,
|
|
|
+ educationLevel, salaryRange, houseRequirement,
|
|
|
+ carRequirement, maritalStatusRequirement,
|
|
|
+ preferredCity, otherRequirements
|
|
|
+ })
|
|
|
+
|
|
|
+ // 处理标签列表(从后端返回的tags字段,如果没有则使用星座和职业)
|
|
|
+ let clientTags = []
|
|
|
+ if (data.tags && Array.isArray(data.tags) && data.tags.length > 0) {
|
|
|
+ // 使用后端返回的标签
|
|
|
+ clientTags = data.tags
|
|
|
+ } else {
|
|
|
+ // 如果没有tags,使用星座和职业作为标签
|
|
|
+ if (data.constellation) {
|
|
|
+ clientTags.push(data.constellation)
|
|
|
+ }
|
|
|
+ if (data.occupation) {
|
|
|
+ clientTags.push(data.occupation)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 加载匹配状态和邀约状态
|
|
|
+ const isMatch = data.isMatch !== null && data.isMatch !== undefined ? data.isMatch :
|
|
|
+ (data.is_match !== null && data.is_match !== undefined ? data.is_match : 0)
|
|
|
+ const isInvitation = data.isInvitation !== null && data.isInvitation !== undefined ? data.isInvitation :
|
|
|
+ (data.is_Invitation !== null && data.is_Invitation !== undefined ? data.is_Invitation : 0)
|
|
|
+ const invitationTime = data.invitationTime || data.Invitation_time
|
|
|
+
|
|
|
+ this.followForm.matchStatus = parseInt(isMatch) || 0
|
|
|
+ this.followForm.invitationStatus = parseInt(isInvitation) || 0
|
|
|
+ if (invitationTime) {
|
|
|
+ // 将日期转换为YYYY-MM-DD格式
|
|
|
+ const date = new Date(invitationTime)
|
|
|
+ const year = date.getFullYear()
|
|
|
+ const month = String(date.getMonth() + 1).padStart(2, '0')
|
|
|
+ const day = String(date.getDate()).padStart(2, '0')
|
|
|
+ this.followForm.inviteDate = `${year}-${month}-${day}`
|
|
|
+ }
|
|
|
+
|
|
|
+ // 映射数据到clientInfo
|
|
|
+ this.clientInfo = {
|
|
|
+ id: resourceId,
|
|
|
+ name: data.name || '',
|
|
|
+ gender: data.gender === 1 ? '男' : data.gender === 2 ? '女' : '未知',
|
|
|
+ status: '已匹配', // 可以根据实际字段判断
|
|
|
+ tags: clientTags, // 使用处理后的标签列表
|
|
|
+ avatar: avatarUrl || '',
|
|
|
+ requirement: mateSelectionCriteria || '暂无要求', // 择偶要求显示my_resource表的mate_selection_criteria字段
|
|
|
+ contact: data.phone ? data.phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2') : '',
|
|
|
+ backupContact: backupPhone ? backupPhone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2') : '',
|
|
|
+ originalPhone: data.phone || '', // 保存原始手机号
|
|
|
+ originalBackupPhone: backupPhone || '', // 保存原始备用手机号
|
|
|
+ stats: {
|
|
|
+ followTimes: 0, // 将从统计数据接口获取
|
|
|
+ matchCount: 0,
|
|
|
+ phoneCalls: 0,
|
|
|
+ interviews: 0
|
|
|
+ },
|
|
|
+ details: {
|
|
|
+ maritalStatus: this.formatMaritalStatus(marrStatus),
|
|
|
+ education: data.diploma || '未知',
|
|
|
+ occupation: data.occupation || '未知',
|
|
|
+ income: data.income || '未知',
|
|
|
+ housing: data.house === 1 ? '已购房' : data.house === 0 ? '未购房' : '未知',
|
|
|
+ requirement: {
|
|
|
+ ageRange: minAge && maxAge ? `${minAge}-${maxAge}岁` : '不限',
|
|
|
+ height: minHeight ? `${minHeight}cm以上` : '不限',
|
|
|
+ maritalStatus: this.formatMaritalStatusRequirement(maritalStatusRequirement),
|
|
|
+ education: this.formatEducationLevel(educationLevel),
|
|
|
+ other: otherRequirements || ''
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 标签已经在上面处理过了,这里不需要再添加
|
|
|
+
|
|
|
+ console.log('=== 映射后的clientInfo ===')
|
|
|
+ console.log('clientInfo:', JSON.stringify(this.clientInfo, null, 2))
|
|
|
+
|
|
|
+ // 加载跟进统计数据
|
|
|
+ this.loadFollowStatistics(resourceId)
|
|
|
+ } else {
|
|
|
+ uni.showToast({
|
|
|
+ title: res.data.message || '加载失败',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ }
|
|
|
} catch (e) {
|
|
|
+ uni.hideLoading()
|
|
|
console.error('加载客户信息失败:', e)
|
|
|
uni.showToast({
|
|
|
title: '加载失败',
|
|
|
icon: 'none'
|
|
|
})
|
|
|
}
|
|
|
+ },
|
|
|
+ // 格式化婚姻状况
|
|
|
+ formatMaritalStatus(status) {
|
|
|
+ if (status === null || status === undefined) return '未知'
|
|
|
+ switch (status) {
|
|
|
+ case 0: return '未婚'
|
|
|
+ case 1: return '离异'
|
|
|
+ case 2: return '丧偶'
|
|
|
+ default: return '未知'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 格式化婚姻状况要求
|
|
|
+ formatMaritalStatusRequirement(status) {
|
|
|
+ if (status === null || status === undefined) return '不限'
|
|
|
+ switch (status) {
|
|
|
+ case 0: return '不限'
|
|
|
+ case 1: return '未婚'
|
|
|
+ case 2: return '离异'
|
|
|
+ case 3: return '丧偶'
|
|
|
+ default: return '不限'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 格式化学历要求
|
|
|
+ formatEducationLevel(level) {
|
|
|
+ if (level === null || level === undefined) return '不限'
|
|
|
+ switch (level) {
|
|
|
+ case 0: return '不限'
|
|
|
+ case 1: return '高中及以上'
|
|
|
+ case 2: return '专科及以上'
|
|
|
+ case 3: return '本科及以上'
|
|
|
+ case 4: return '硕士及以上'
|
|
|
+ case 5: return '博士及以上'
|
|
|
+ default: return '不限'
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -311,7 +827,7 @@ export default {
|
|
|
<style lang="scss" scoped>
|
|
|
.client-detail {
|
|
|
min-height: 100vh;
|
|
|
- background-color: #FFF9F9;
|
|
|
+ background: linear-gradient(180deg, #FFF5F8 0%, #F8E8F0 50%, #FFF9F9 100%);
|
|
|
padding-top: 90rpx;
|
|
|
}
|
|
|
|
|
|
@@ -353,11 +869,12 @@ export default {
|
|
|
.client-basic-info {
|
|
|
display: flex;
|
|
|
align-items: flex-start;
|
|
|
- padding: 30rpx;
|
|
|
- background-color: #FFFFFF;
|
|
|
+ padding: 35rpx;
|
|
|
+ background: linear-gradient(135deg, #FFFFFF 0%, #FFFBFD 100%);
|
|
|
margin: 20rpx;
|
|
|
- border-radius: 20rpx;
|
|
|
- box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
|
|
+ border-radius: 24rpx;
|
|
|
+ box-shadow: 0 8rpx 24rpx rgba(156, 39, 176, 0.12), 0 2rpx 8rpx rgba(156, 39, 176, 0.08);
|
|
|
+ border: 1rpx solid rgba(243, 229, 245, 0.8);
|
|
|
|
|
|
.client-avatar {
|
|
|
width: 160rpx;
|
|
|
@@ -371,17 +888,57 @@ export default {
|
|
|
flex: 1;
|
|
|
|
|
|
.client-name {
|
|
|
- font-size: 36rpx;
|
|
|
- font-weight: bold;
|
|
|
- color: #333;
|
|
|
- margin-bottom: 10rpx;
|
|
|
+ font-size: 38rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #2C2C2C;
|
|
|
+ margin-bottom: 12rpx;
|
|
|
+ letter-spacing: 0.5rpx;
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+
|
|
|
+ .status-tag-wrapper {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 10rpx;
|
|
|
+ margin-bottom: 18rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .status-tag {
|
|
|
+ display: inline-block;
|
|
|
+ padding: 4rpx 12rpx;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ font-size: 22rpx;
|
|
|
+ font-weight: 500;
|
|
|
+
|
|
|
+ &.register-tag {
|
|
|
+ &.registered {
|
|
|
+ background: #E8F5E9;
|
|
|
+ color: #4CAF50;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &.match-tag {
|
|
|
+ &.matched {
|
|
|
+ background: #E3F2FD;
|
|
|
+ color: #2196F3;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.unmatched {
|
|
|
+ background: #FFF3E0;
|
|
|
+ color: #FF9800;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
.client-status {
|
|
|
- font-size: 28rpx;
|
|
|
+ font-size: 26rpx;
|
|
|
color: #FF6B8A;
|
|
|
- margin-bottom: 15rpx;
|
|
|
+ margin-bottom: 18rpx;
|
|
|
display: inline-block;
|
|
|
+ padding: 4rpx 16rpx;
|
|
|
+ background: linear-gradient(135deg, #FFE5EB 0%, #FFF0F5 100%);
|
|
|
+ border-radius: 12rpx;
|
|
|
+ font-weight: 500;
|
|
|
}
|
|
|
|
|
|
.client-tags {
|
|
|
@@ -390,12 +947,14 @@ export default {
|
|
|
gap: 10rpx;
|
|
|
|
|
|
.tag {
|
|
|
- padding: 8rpx 20rpx;
|
|
|
- background-color: #F3E5F5;
|
|
|
- color: #9C27B0;
|
|
|
- border-radius: 20rpx;
|
|
|
+ padding: 10rpx 22rpx;
|
|
|
+ background: linear-gradient(135deg, #F3E5F5 0%, #E1BEE7 100%);
|
|
|
+ color: #7B1FA2;
|
|
|
+ border-radius: 24rpx;
|
|
|
font-size: 24rpx;
|
|
|
- font-weight: bold;
|
|
|
+ font-weight: 600;
|
|
|
+ box-shadow: 0 2rpx 8rpx rgba(156, 39, 176, 0.15);
|
|
|
+ border: 1rpx solid rgba(156, 39, 176, 0.2);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -403,11 +962,12 @@ export default {
|
|
|
|
|
|
/* 择偶要求 */
|
|
|
.requirement-section {
|
|
|
- padding: 30rpx;
|
|
|
- background-color: #FFFFFF;
|
|
|
+ padding: 35rpx;
|
|
|
+ background: linear-gradient(135deg, #FFFFFF 0%, #FFFBFD 100%);
|
|
|
margin: 0 20rpx 20rpx;
|
|
|
- border-radius: 20rpx;
|
|
|
- box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
|
|
+ border-radius: 24rpx;
|
|
|
+ box-shadow: 0 8rpx 24rpx rgba(156, 39, 176, 0.12), 0 2rpx 8rpx rgba(156, 39, 176, 0.08);
|
|
|
+ border: 1rpx solid rgba(243, 229, 245, 0.8);
|
|
|
|
|
|
.section-title {
|
|
|
display: flex;
|
|
|
@@ -420,26 +980,29 @@ export default {
|
|
|
}
|
|
|
|
|
|
.title-text {
|
|
|
- font-size: 28rpx;
|
|
|
- font-weight: bold;
|
|
|
- color: #333;
|
|
|
+ font-size: 30rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #2C2C2C;
|
|
|
+ letter-spacing: 0.5rpx;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.requirement-content {
|
|
|
font-size: 28rpx;
|
|
|
- color: #666;
|
|
|
- line-height: 1.5;
|
|
|
+ color: #555;
|
|
|
+ line-height: 1.8;
|
|
|
+ font-weight: 400;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 联系方式 */
|
|
|
.contact-section {
|
|
|
- padding: 30rpx;
|
|
|
- background-color: #FFFFFF;
|
|
|
+ padding: 35rpx;
|
|
|
+ background: linear-gradient(135deg, #FFFFFF 0%, #FFFBFD 100%);
|
|
|
margin: 0 20rpx 20rpx;
|
|
|
- border-radius: 20rpx;
|
|
|
- box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
|
|
+ border-radius: 24rpx;
|
|
|
+ box-shadow: 0 8rpx 24rpx rgba(156, 39, 176, 0.12), 0 2rpx 8rpx rgba(156, 39, 176, 0.08);
|
|
|
+ border: 1rpx solid rgba(243, 229, 245, 0.8);
|
|
|
|
|
|
.contact-item {
|
|
|
display: flex;
|
|
|
@@ -453,7 +1016,8 @@ export default {
|
|
|
|
|
|
.contact-label {
|
|
|
font-size: 28rpx;
|
|
|
- color: #333;
|
|
|
+ color: #2C2C2C;
|
|
|
+ font-weight: 500;
|
|
|
}
|
|
|
|
|
|
.contact-value {
|
|
|
@@ -463,16 +1027,25 @@ export default {
|
|
|
|
|
|
.contact-number {
|
|
|
font-size: 28rpx;
|
|
|
- color: #666;
|
|
|
+ color: #555;
|
|
|
+ font-weight: 400;
|
|
|
}
|
|
|
|
|
|
.copy-btn {
|
|
|
- padding: 8rpx 20rpx;
|
|
|
- background-color: #F3E5F5;
|
|
|
- color: #9C27B0;
|
|
|
- border-radius: 20rpx;
|
|
|
+ padding: 10rpx 24rpx;
|
|
|
+ background: linear-gradient(135deg, #F3E5F5 0%, #E1BEE7 100%);
|
|
|
+ color: #7B1FA2;
|
|
|
+ border-radius: 24rpx;
|
|
|
font-size: 24rpx;
|
|
|
- font-weight: bold;
|
|
|
+ font-weight: 600;
|
|
|
+ box-shadow: 0 2rpx 8rpx rgba(156, 39, 176, 0.2);
|
|
|
+ border: 1rpx solid rgba(156, 39, 176, 0.2);
|
|
|
+ transition: all 0.3s;
|
|
|
+
|
|
|
+ &:active {
|
|
|
+ transform: scale(0.95);
|
|
|
+ box-shadow: 0 1rpx 4rpx rgba(156, 39, 176, 0.3);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -526,87 +1099,155 @@ export default {
|
|
|
.tabs-section {
|
|
|
display: flex;
|
|
|
padding: 0 20rpx;
|
|
|
- background-color: #FFFFFF;
|
|
|
+ background: linear-gradient(135deg, #FFFFFF 0%, #FFFBFD 100%);
|
|
|
margin: 0 20rpx 20rpx;
|
|
|
- border-radius: 20rpx;
|
|
|
- box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
|
|
+ border-radius: 24rpx;
|
|
|
+ box-shadow: 0 8rpx 24rpx rgba(156, 39, 176, 0.12), 0 2rpx 8rpx rgba(156, 39, 176, 0.08);
|
|
|
+ border: 1rpx solid rgba(243, 229, 245, 0.8);
|
|
|
|
|
|
.tab {
|
|
|
flex: 1;
|
|
|
text-align: center;
|
|
|
- padding: 20rpx 0;
|
|
|
- font-size: 28rpx;
|
|
|
- color: #666;
|
|
|
- font-weight: bold;
|
|
|
+ padding: 24rpx 0;
|
|
|
+ font-size: 30rpx;
|
|
|
+ color: #888;
|
|
|
+ font-weight: 500;
|
|
|
transition: all 0.3s;
|
|
|
+ position: relative;
|
|
|
|
|
|
&.active {
|
|
|
- color: #9C27B0;
|
|
|
- border-bottom: 4rpx solid #9C27B0;
|
|
|
+ color: #7B1FA2;
|
|
|
+ font-weight: 600;
|
|
|
+
|
|
|
+ &::after {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ bottom: 0;
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
+ width: 60rpx;
|
|
|
+ height: 6rpx;
|
|
|
+ background: linear-gradient(90deg, #9C27B0 0%, #E1BEE7 100%);
|
|
|
+ border-radius: 3rpx;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 详细信息滚动区域 */
|
|
|
.details-section {
|
|
|
- padding: 30rpx 20rpx 100rpx;
|
|
|
- background-color: #FFFFFF;
|
|
|
+ padding: 35rpx 25rpx 100rpx;
|
|
|
+ background: linear-gradient(135deg, #FFFFFF 0%, #FFFBFD 100%);
|
|
|
margin: 0 20rpx 20rpx;
|
|
|
- border-radius: 20rpx;
|
|
|
- box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
|
|
+ border-radius: 24rpx;
|
|
|
+ box-shadow: 0 8rpx 24rpx rgba(156, 39, 176, 0.12), 0 2rpx 8rpx rgba(156, 39, 176, 0.08);
|
|
|
+ border: 1rpx solid rgba(243, 229, 245, 0.8);
|
|
|
box-sizing: border-box;
|
|
|
-
|
|
|
- .edit-btn {
|
|
|
- position: absolute;
|
|
|
- top: 20rpx;
|
|
|
- right: 30rpx;
|
|
|
- padding: 8rpx 25rpx;
|
|
|
- background-color: #F3E5F5;
|
|
|
- color: #9C27B0;
|
|
|
- border-radius: 20rpx;
|
|
|
- font-size: 24rpx;
|
|
|
- font-weight: bold;
|
|
|
- }
|
|
|
+ position: relative;
|
|
|
|
|
|
.detail-item {
|
|
|
display: flex;
|
|
|
- margin-bottom: 25rpx;
|
|
|
+ margin-bottom: 28rpx;
|
|
|
+ padding: 12rpx 0;
|
|
|
+ border-bottom: 1rpx solid rgba(240, 240, 240, 0.6);
|
|
|
+
|
|
|
+ &:last-of-type {
|
|
|
+ border-bottom: none;
|
|
|
+ }
|
|
|
|
|
|
.detail-label {
|
|
|
- width: 180rpx;
|
|
|
+ width: 200rpx;
|
|
|
font-size: 28rpx;
|
|
|
- color: #333;
|
|
|
- font-weight: bold;
|
|
|
+ color: #2C2C2C;
|
|
|
+ font-weight: 500;
|
|
|
+ letter-spacing: 0.3rpx;
|
|
|
}
|
|
|
|
|
|
.detail-value {
|
|
|
flex: 1;
|
|
|
font-size: 28rpx;
|
|
|
- color: #666;
|
|
|
+ color: #555;
|
|
|
+ font-weight: 400;
|
|
|
+ text-align: right;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.sub-section-title {
|
|
|
- font-size: 30rpx;
|
|
|
- font-weight: bold;
|
|
|
- color: #333;
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #2C2C2C;
|
|
|
margin: 30rpx 0 20rpx;
|
|
|
- padding-bottom: 10rpx;
|
|
|
- border-bottom: 2rpx solid #F0F0F0;
|
|
|
+ padding-bottom: 12rpx;
|
|
|
+ border-bottom: 2rpx solid rgba(240, 240, 240, 0.8);
|
|
|
+ letter-spacing: 0.5rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 择偶详细要求部分 - 添加明显的上分隔 */
|
|
|
+ .requirement-section-title {
|
|
|
+ margin-top: 60rpx;
|
|
|
+ padding: 32rpx 24rpx 20rpx;
|
|
|
+ border-top: 3rpx solid rgba(156, 39, 176, 0.15);
|
|
|
+ border-bottom: 2rpx solid rgba(156, 39, 176, 0.1);
|
|
|
+ position: relative;
|
|
|
+ background: linear-gradient(135deg, #F8F4F9 0%, #FFFBFD 100%);
|
|
|
+ border-radius: 16rpx 16rpx 0 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .requirement-section-title::before {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ width: 8rpx;
|
|
|
+ height: 100%;
|
|
|
+ background: linear-gradient(180deg, #9C27B0 0%, #BA68C8 50%, #E1BEE7 100%);
|
|
|
+ border-radius: 0 4rpx 4rpx 0;
|
|
|
+ box-shadow: 2rpx 0 8rpx rgba(156, 39, 176, 0.2);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 客户标签部分 - 添加明显的上分隔 */
|
|
|
+ .tags-section-title {
|
|
|
+ margin-top: 60rpx;
|
|
|
+ padding: 32rpx 24rpx 20rpx;
|
|
|
+ border-top: 3rpx solid rgba(156, 39, 176, 0.15);
|
|
|
+ border-bottom: 2rpx solid rgba(156, 39, 176, 0.1);
|
|
|
+ position: relative;
|
|
|
+ background: linear-gradient(135deg, #F8F4F9 0%, #FFFBFD 100%);
|
|
|
+ border-radius: 16rpx 16rpx 0 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .tags-section-title::before {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ width: 8rpx;
|
|
|
+ height: 100%;
|
|
|
+ background: linear-gradient(180deg, #9C27B0 0%, #BA68C8 50%, #E1BEE7 100%);
|
|
|
+ border-radius: 0 4rpx 4rpx 0;
|
|
|
+ box-shadow: 2rpx 0 8rpx rgba(156, 39, 176, 0.2);
|
|
|
}
|
|
|
|
|
|
.client-tags {
|
|
|
display: flex;
|
|
|
flex-wrap: wrap;
|
|
|
- gap: 10rpx;
|
|
|
+ gap: 12rpx;
|
|
|
+ padding: 20rpx 0;
|
|
|
|
|
|
.tag {
|
|
|
- padding: 8rpx 20rpx;
|
|
|
- background-color: #F3E5F5;
|
|
|
- color: #9C27B0;
|
|
|
- border-radius: 20rpx;
|
|
|
- font-size: 24rpx;
|
|
|
- font-weight: bold;
|
|
|
+ padding: 12rpx 24rpx;
|
|
|
+ background: linear-gradient(135deg, #F3E5F5 0%, #E1BEE7 100%);
|
|
|
+ color: #7B1FA2;
|
|
|
+ border-radius: 24rpx;
|
|
|
+ font-size: 26rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ box-shadow: 0 2rpx 8rpx rgba(156, 39, 176, 0.15);
|
|
|
+ border: 1rpx solid rgba(156, 39, 176, 0.2);
|
|
|
+ transition: all 0.3s;
|
|
|
+
|
|
|
+ &:active {
|
|
|
+ transform: scale(0.95);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|