chore:交换名片样式更改

This commit is contained in:
2026-10-14 11:24:23 +08:00
parent 36dfbfed67
commit 67af165c14

View File

@@ -76,27 +76,35 @@
</view>
</view>
<!-- 交换名片请求提醒条(参考图: 宫格下方出现对方要交换的名片) -->
<!-- 数据先用假数据占位(exchangeRequest), 接口就绪后替换数据源即可 -->
<view class="exchange-bar" v-if="relation && exchangeRequest" @tap="goExchangeReq">
<!-- 交换名片提醒条(参考图: 宫格下方出现对方要交换的名片) -->
<!-- 数据优先级: ① exchange/lists 的真实待处理请求 ② 最近一次真实交换来的人脉(接口无请求时兜底) -->
<!-- 头部文案与忽略/同意按钮按参考图固定渲染, 不改动名片数据 -->
<view class="exchange-bar" v-if="relation && exchangeItem" @tap="onExchangeBarTap">
<view class="eb-head">
<view class="eb-dot"></view>
<text class="eb-head-text">有 {{ exchangeRequest.count }} 人请求与您交换名片</text>
<!-- 参考图: 蓝色喇叭图标 + 「有 N 人请求与您交换名片」, 数字更大更粗 -->
<text class="eb-head-icon iconfont icon-gonggao"></text>
<view class="eb-head-text">
<text>有</text>
<text class="eb-num">{{ exchangeCount }}</text>
<text>人请求与您交换名片</text>
</view>
<text class="eb-arrow iconfont icon-right"></text>
</view>
<view class="eb-card" @tap.stop="viewExchangeCard">
<image v-if="exchangeRequest.avatar" class="eb-avatar" :src="exchangeRequest.avatar" mode="aspectFill" />
<view v-else class="eb-avatar eb-avatar-ph">{{ exchangeRequest.name.charAt(0) }}</view>
<view class="eb-card" @tap.stop="viewExchangeCard(exchangeItem)">
<image v-if="exchangeItem.avatar" class="eb-avatar" :src="exchangeItem.avatar" mode="aspectFill" />
<view v-else class="eb-avatar eb-avatar-ph">{{ exchangeItem.name.charAt(0) }}</view>
<view class="eb-info">
<view class="eb-name-row">
<text class="eb-name">{{ exchangeRequest.name }}</text>
<text class="eb-name">{{ exchangeItem.name }}</text>
<text class="eb-badge iconfont icon-dui"></text>
</view>
<text class="eb-job">{{ exchangeRequest.job_title }}{{ exchangeRequest.company ? ' · ' + exchangeRequest.company : '' }}</text>
<text class="eb-time">{{ exchangeRequest.time }} 向您发起名片交换</text>
<!-- 参考图: 职位、公司分行显示 -->
<text class="eb-job" v-if="exchangeItem.job_title">{{ exchangeItem.job_title }}</text>
<text class="eb-company" v-if="exchangeItem.company">{{ exchangeItem.company }}</text>
<text class="eb-time">{{ exchangeItem.create_time_txt }} 向您发起名片交换</text>
</view>
<view class="eb-actions">
<view class="eb-act-item" @tap.stop="onIgnoreExchange">
<view class="eb-act-item" @tap.stop="onIgnoreExchange(exchangeItem)">
<view class="eb-act eb-act-ignore">
<!-- ✕ 用 CSS 画, 避免字体图标自带圆圈 -->
<view class="eb-x">
@@ -106,7 +114,7 @@
</view>
<text class="eb-act-text">忽略</text>
</view>
<view class="eb-act-item" @tap.stop="onAgreeExchange">
<view class="eb-act-item" @tap.stop="onAgreeExchange(exchangeItem)">
<view class="eb-act eb-act-agree">
<!-- ✓ 用 CSS 画, 避免字体图标自带圆圈 -->
<view class="eb-check"></view>
@@ -175,15 +183,10 @@ export default {
showShare: false,
shareUrl: '',
qrUrl: '',
// 交换名片请求(静态占位数据, 接口就绪后替换为后端返回)
exchangeRequest: {
count: 1,
name: '名片君',
job_title: '销售经理',
company: '示例科技有限公司',
avatar: '',
time: '今天 14:17'
}
// 交换名片: ① 待处理请求(真实, exchange/lists) ② 最近一次交换来的人脉(真实, contact/lists?source=exchange)
exchangeList: [],
exchangeCount: 0,
latestExchange: null
};
},
computed: {
@@ -231,16 +234,27 @@ export default {
}
return rows;
},
// 是否「待处理请求」(决定头部文案与是否显示忽略/同意)
exchangeIsRequest() {
return this.exchangeList.length > 0;
},
// 提醒条展示对象: 优先真实待处理请求(最新的那条), 否则最近一次真实交换来的人脉
exchangeItem() {
if (this.exchangeList.length > 0) return this.exchangeList[0];
return this.latestExchange;
}
},
onLoad(options) {
this.cardId = decodeURIComponent(options.card_id || '');
this.loadDetail();
this.loadExchange();
},
onShow() {
// 首次进入由 onLoad 负责加载; 从编辑页返回时(onShow 再次触发)刷新
if (this._loadedOnce) {
this.loadDetail();
this.loadExchange();
}
this._loadedOnce = true;
},
@@ -363,16 +377,121 @@ export default {
},
// 「交换名片」提醒条: 点右侧箭头/整条 → 进入交换请求列表页
goExchangeReq() {
uni.navigateTo({ url: '/pages_tool/card/exchange' });
const url = this.cardId
? '/pages_tool/card/exchange?card_id=' + encodeURIComponent(this.cardId)
: '/pages_tool/card/exchange';
uni.navigateTo({ url: url });
},
viewExchangeCard() {
uni.showToast({ title: '查看对方名片(接口待接入)', icon: 'none' });
// 拉取待处理交换请求(只含 status=0), 回填 exchangeList / exchangeCount
// 没有待处理请求时, 再取「最近一次交换来的人脉」作为提醒条的第二个真实数据源
loadExchange() {
this.$cardApi.exchangeLists({
data: { page: 1, page_size: 20 },
success: res => {
const list = (res.code == 0 && res.data) ? (res.data.list || []) : [];
if (list.length > 0) {
// 展示最新那条: create_time / id 都可能缺失, 取到可比较的值再倒序
const ordered = list.slice().sort((a, b) => {
const av = Number(a.create_time) || Number(a.id) || 0;
const bv = Number(b.create_time) || Number(b.id) || 0;
return bv - av;
});
this.exchangeList = ordered;
this.exchangeCount = (res.data && res.data.count) || ordered.length;
this.latestExchange = null;
} else {
this.exchangeList = [];
this.exchangeCount = 0;
this.loadLatestExchange();
}
},
fail: () => {
this.exchangeList = [];
this.exchangeCount = 0;
this.loadLatestExchange();
}
});
},
onIgnoreExchange() {
uni.showToast({ title: '已忽略(接口待接入)', icon: 'none' });
// 第二个真实数据源: 人脉库里来源=交换的最新一条(交换成功后后端会自动双方建人脉)
loadLatestExchange() {
this.$cardApi.contactLists({
data: { page: 1, page_size: 1, source: 'exchange' },
success: res => {
if (res.code != 0 || !res.data) return;
const row = (res.data.list || [])[0];
this.latestExchange = row ? {
id: row.id,
name: row.name || '',
avatar: row.avatar || '',
job_title: row.job_title || '',
company: row.company || '',
create_time_txt: row.create_time_txt || ''
} : null;
// 无待处理请求时的兜底展示: 头部件数按 1 渲染, 与参考图「有 1 人请求与您交换名片」一致
this.exchangeCount = this.latestExchange ? 1 : 0;
},
fail: () => { this.latestExchange = null; this.exchangeCount = 0; }
});
},
onAgreeExchange() {
uni.showToast({ title: '已同意(接口待接入)', icon: 'none' });
// 提醒条整条点击: 待处理请求 → 交换请求列表页; 最近交换 → 我的人脉
onExchangeBarTap() {
if (this.exchangeIsRequest) {
this.goExchangeReq();
} else {
this.goContacts();
}
},
// 点对方名片 → 待处理请求跳对方名片详情; 兜底展示的人脉则回「我的人脉」
viewExchangeCard(item) {
if (!this.exchangeIsRequest) {
this.goContacts();
return;
}
if (!item || !item.from_card_id) return;
uni.navigateTo({
url: '/pages_tool/card/detail?card_id=' + encodeURIComponent(item.from_card_id)
});
},
onIgnoreExchange(item) {
// 兜底展示项不是真实待处理请求, 不能拿人脉 id 去调交换接口
if (!this.exchangeIsRequest || !item || !item.id) {
uni.showToast({ title: '当前没有待处理的交换请求', icon: 'none' });
return;
}
this.$cardApi.exchangeIgnore({
data: { id: item.id },
success: res => {
if (res.code == 0) {
uni.showToast({ title: '已忽略', icon: 'none' });
this.loadExchange();
} else if (res.message) {
uni.showToast({ title: res.message, icon: 'none' });
}
},
fail: () => {}
});
},
onAgreeExchange(item) {
// 兜底展示项不是真实待处理请求, 不能拿人脉 id 去调交换接口
if (!this.exchangeIsRequest || !item || !item.id) {
uni.showToast({ title: '当前没有待处理的交换请求', icon: 'none' });
return;
}
this.$cardApi.exchangeAgree({
data: { id: item.id },
success: res => {
if (res.code == 0) {
// receiver_created=0 也是正常成功(同人脉已存在被跳过), 不当失败
const d = res.data || {};
const txt = d.receiver_created === 0 ? '已交换(人脉已存在)' : '已交换,人脉已互加';
uni.showToast({ title: txt, icon: 'none' });
this.loadExchange();
} else if (res.message) {
uni.showToast({ title: res.message, icon: 'none' });
}
},
fail: () => {}
});
},
closeShare() {
this.showShare = false;
@@ -599,41 +718,55 @@ export default {
}
// 交换名片请求提醒条(参考图: 宫格下方出现对方要交换的名片)
// 数据先用假数据占位(exchangeRequest), 接口就绪后替换数据源即可
// 顶部提醒行为浅蓝底 + 蓝色喇叭图标, 名片区白底, 整条浅蓝描边
.exchange-bar {
margin: 24rpx 24rpx 0;
// 参考图: 整条外框为蓝色描边, 内层名片区白底, 顶部提醒行为浅蓝底
background-color: #ffffff;
border: 2rpx solid #2aa5ff;
border: 2rpx solid #cfe3ff;
border-radius: 16rpx;
overflow: hidden;
box-sizing: border-box;
// 提醒行高度按需求收窄(上下内边距 20rpx → 12rpx)
.eb-head {
display: flex;
align-items: center;
padding: 20rpx 24rpx;
background-color: #eef5ff;
padding: 12rpx 24rpx;
background-color: #eaf3ff;
}
.eb-dot {
width: 10rpx;
height: 10rpx;
margin-right: 12rpx;
border-radius: 50%;
background-color: #2aa5ff;
// 参考图: 蓝色喇叭图标(替换原来的小圆点)
.eb-head-icon {
margin-right: 10rpx;
font-size: 26rpx;
line-height: 1;
color: #2aa5ff;
flex-shrink: 0;
}
.eb-head-text {
flex: 1;
display: flex;
align-items: baseline;
font-size: 24rpx;
line-height: 1.2;
color: #333333;
}
// 参考图: 「有 1 人请求与您交换名片」里的数字更大更粗
.eb-num {
margin: 0 6rpx;
font-size: 26rpx;
line-height: 1.2;
font-weight: 600;
color: #2aa5ff;
}
.eb-arrow {
margin-left: 12rpx;
font-size: 24rpx;
color: #9fb4cc;
flex-shrink: 0;
}
.eb-card {
@@ -645,8 +778,8 @@ export default {
}
.eb-avatar {
width: 80rpx;
height: 80rpx;
width: 88rpx;
height: 88rpx;
border-radius: 50%;
flex-shrink: 0;
background-color: #2aa5ff;
@@ -688,11 +821,22 @@ export default {
color: #2aa5ff;
}
// 参考图: 职位一行、公司一行
.eb-job {
display: block;
margin-top: 8rpx;
font-size: 22rpx;
color: #8a94a6;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.eb-company {
display: block;
margin-top: 6rpx;
font-size: 22rpx;
color: #7b8794;
color: #5a6572;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
@@ -700,7 +844,7 @@ export default {
.eb-time {
display: block;
margin-top: 6rpx;
margin-top: 8rpx;
font-size: 20rpx;
color: #a9b4c0;
}
@@ -718,13 +862,13 @@ export default {
align-items: center;
&:first-child {
margin-right: 24rpx;
margin-right: 26rpx;
}
}
.eb-act {
width: 76rpx;
height: 76rpx;
width: 80rpx;
height: 80rpx;
border-radius: 50%;
display: flex;
align-items: center;
@@ -734,7 +878,7 @@ export default {
// 忽略: 白底细描边圆 + 灰色 ✕
&.eb-act-ignore {
background-color: #ffffff;
border: 2rpx solid #dfe4ea;
border: 2rpx solid #e3e8ef;
}
// 同意: 蓝底实心圆 + 白色 ✓