chore:认领码正常
This commit is contained in:
@@ -51,6 +51,31 @@
|
||||
<ns-empty v-if="!isLoading && list.length === 0" :isIndex="false"
|
||||
:text="emptyText"></ns-empty>
|
||||
</view>
|
||||
|
||||
<!-- 认领弹层: 支持领取码/名片编号 + 扫码带参预填(与 card_claim_api 文档同步) -->
|
||||
<view v-if="showClaim" class="claim-mask" @tap="closeClaim">
|
||||
<view class="claim-pop" @tap.stop>
|
||||
<view class="claim-pop-title">认领名片</view>
|
||||
<view class="claim-pop-tabs">
|
||||
<view class="claim-tab" :class="{ active: claimMode === 'code' }" @tap="claimMode = 'code'">领取码</view>
|
||||
<view class="claim-tab" :class="{ active: claimMode === 'id' }" @tap="claimMode = 'id'">名片编号</view>
|
||||
</view>
|
||||
<view class="claim-input-wrap">
|
||||
<input class="claim-input" :value="claimInput"
|
||||
:placeholder="claimMode === 'code' ? '输入 8 位领取码(大写字母数字)' : '输入名片编号'"
|
||||
@input="onClaimInput" confirm-type="done" @confirm="submitClaim" />
|
||||
<text v-if="claimInput" class="claim-clear" @tap="claimInput = ''">✕</text>
|
||||
</view>
|
||||
<view class="claim-scan" @tap="scanClaim">
|
||||
<text class="iconfont icon-saomafu"></text>
|
||||
<text>扫码认领(自动识别领取码 / 编号)</text>
|
||||
</view>
|
||||
<view class="claim-pop-actions">
|
||||
<view class="claim-btn-cancel" @tap="closeClaim">取消</view>
|
||||
<view class="claim-btn-confirm" @tap="submitClaim">确认认领</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -66,10 +91,21 @@ export default {
|
||||
keyword: '',
|
||||
onlyFav: false,
|
||||
isLoading: false,
|
||||
emptyText: '暂无名片,可点击右上角「新建」或「认领」添加'
|
||||
emptyText: '暂无名片,可点击右上角「新建」或「认领」添加',
|
||||
// 认领弹层状态(与 card_claim_api 文档同步)
|
||||
showClaim: false,
|
||||
claimInput: '',
|
||||
claimMode: 'code', // code=领取码(主通道), id=名片编号(旧入口兼容)
|
||||
pendingClaimCode: '' // 扫码带参预填的码
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
onLoad(options) {
|
||||
// 扫码带参预填(文档 §5): 二维码/链接带 claim_code 或 card_id 直接进入认领
|
||||
if (options && (options.claim_code || options.card_id)) {
|
||||
this.pendingClaimCode = (options.claim_code || options.card_id || '')
|
||||
.toUpperCase().replace(/\s+/g, '');
|
||||
this.claimMode = options.claim_code ? 'code' : 'id';
|
||||
}
|
||||
this.refresh();
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
@@ -206,35 +242,78 @@ export default {
|
||||
url: '/pages_tool/card/edit'
|
||||
});
|
||||
},
|
||||
// 认领: 打开弹层(支持领取码/名片编号 + 扫码带参预填, 与 card_claim_api 文档同步)
|
||||
onClaimTap() {
|
||||
uni.showModal({
|
||||
title: '认领名片',
|
||||
editable: true,
|
||||
placeholderText: '粘贴商家提供的名片编号(card_id)',
|
||||
success: res => {
|
||||
if (!res.confirm) return;
|
||||
const cardId = (res.content || '').trim();
|
||||
if (!cardId) {
|
||||
uni.showToast({ title: '请输入名片编号', icon: 'none' });
|
||||
this.claimInput = this.pendingClaimCode || '';
|
||||
this.showClaim = true;
|
||||
},
|
||||
onClaimInput(e) {
|
||||
// 输入框自动转大写并过滤空格(文档 §5 checklist)
|
||||
this.claimInput = (e.detail.value || '').toUpperCase().replace(/\s+/g, '');
|
||||
},
|
||||
closeClaim() {
|
||||
this.showClaim = false;
|
||||
},
|
||||
submitClaim() {
|
||||
const code = (this.claimInput || '').trim().toUpperCase().replace(/\s+/g, '');
|
||||
this.claimInput = code;
|
||||
if (!code) {
|
||||
uni.showToast({
|
||||
title: this.claimMode === 'code' ? '请输入领取码' : '请输入名片编号',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.doClaim(code);
|
||||
this.closeClaim();
|
||||
},
|
||||
// 扫码认领: 解析二维码(URL 参数或整串), 自动识别领取码/名片编号
|
||||
scanClaim() {
|
||||
// #ifndef H5
|
||||
uni.scanCode({
|
||||
success: r => {
|
||||
const code = this.parseClaimParam(r.result);
|
||||
if (!code) {
|
||||
uni.showToast({ title: '二维码未包含领取码或名片编号', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
this.doClaim(cardId);
|
||||
}
|
||||
this.claimInput = code;
|
||||
this.claimMode = /^\d+$/.test(code) ? 'id' : 'code';
|
||||
this.doClaim(code);
|
||||
this.closeClaim();
|
||||
},
|
||||
fail: () => {}
|
||||
});
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
uni.showToast({ title: '请在微信/小程序内扫码', icon: 'none' });
|
||||
// #endif
|
||||
},
|
||||
doClaim(cardId) {
|
||||
parseClaimParam(val) {
|
||||
const s = (val || '').trim();
|
||||
if (!s) return '';
|
||||
const m = s.match(/[?&](claim_code|card_id)=([^&]+)/i);
|
||||
if (m) return decodeURIComponent(m[2]).toUpperCase().replace(/\s+/g, '');
|
||||
return s.toUpperCase().replace(/\s+/g, '');
|
||||
},
|
||||
doClaim(code) {
|
||||
uni.showLoading({ title: '认领中…' });
|
||||
// 文档 §2: claim_code 主通道, card_id 旧入口兼容; 二者二选一
|
||||
const payload = this.claimMode === 'code'
|
||||
? { claim_code: code }
|
||||
: { card_id: code };
|
||||
this.$cardApi.cardClaim({
|
||||
data: { card_id: cardId },
|
||||
data: payload,
|
||||
success: res => {
|
||||
uni.hideLoading();
|
||||
if (res.code == 0) {
|
||||
const claimed = res.data && res.data.claimed === false;
|
||||
// claimed=true=新认领; false=早已是自己的(幂等)
|
||||
const isNew = res.data && res.data.claimed === true;
|
||||
uni.showToast({
|
||||
title: claimed ? '该名片已在您的名片夹中' : '认领成功',
|
||||
title: isNew ? '认领成功' : '该名片已在您名下',
|
||||
icon: 'success'
|
||||
});
|
||||
this.refresh();
|
||||
this.refresh(); // 认领后与员工自建/扫描卡同池展示
|
||||
} else {
|
||||
this.handleApiError(res);
|
||||
}
|
||||
@@ -441,4 +520,122 @@ export default {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 认领弹层(与 card_claim_api 文档同步) */
|
||||
.claim-mask {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.45);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.claim-pop {
|
||||
width: 600rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 24rpx;
|
||||
padding: 40rpx 36rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.claim-pop-title {
|
||||
font-size: 34rpx;
|
||||
font-weight: 600;
|
||||
color: #1f2329;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.claim-pop-tabs {
|
||||
display: flex;
|
||||
margin: 32rpx 0 24rpx;
|
||||
background-color: #f3f4f6;
|
||||
border-radius: 14rpx;
|
||||
padding: 6rpx;
|
||||
|
||||
.claim-tab {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: #6b7280;
|
||||
padding: 16rpx 0;
|
||||
border-radius: 10rpx;
|
||||
|
||||
&.active {
|
||||
background-color: #ffffff;
|
||||
color: var(--main-color, #0054a5);
|
||||
font-weight: 600;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.claim-input-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #f7f8fa;
|
||||
border: 2rpx solid #e5e7eb;
|
||||
border-radius: 14rpx;
|
||||
padding: 0 20rpx;
|
||||
height: 84rpx;
|
||||
|
||||
.claim-input {
|
||||
flex: 1;
|
||||
height: 84rpx;
|
||||
font-size: 30rpx;
|
||||
color: #1f2329;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
|
||||
.claim-clear {
|
||||
color: #bbb;
|
||||
font-size: 30rpx;
|
||||
padding: 0 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.claim-scan {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 24rpx;
|
||||
color: var(--main-color, #0054a5);
|
||||
font-size: 26rpx;
|
||||
|
||||
.iconfont {
|
||||
margin-right: 10rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.claim-pop-actions {
|
||||
display: flex;
|
||||
margin-top: 36rpx;
|
||||
|
||||
.claim-btn-cancel,
|
||||
.claim-btn-confirm {
|
||||
flex: 1;
|
||||
height: 84rpx;
|
||||
line-height: 84rpx;
|
||||
text-align: center;
|
||||
border-radius: 14rpx;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.claim-btn-cancel {
|
||||
background-color: #f3f4f6;
|
||||
color: #6b7280;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.claim-btn-confirm {
|
||||
background-color: var(--main-color, #0054a5);
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user