接待 线索类型的客户逻辑

This commit is contained in:
zhonghua.li
2026-05-02 20:57:28 +08:00
parent 382132c0d9
commit f4341af66e
3 changed files with 194 additions and 3 deletions

View File

@@ -51,8 +51,17 @@
<text>{{ tag.text }}</text> <text>{{ tag.text }}</text>
</view> </view>
</view> </view>
<view class="customer-footer" v-if="item.phone || item.budget"> <view class="customer-footer">
<text class="customer-phone" v-if="item.phone">{{ item.phone }}</text> <view class="customer-footer-left">
<text
class="customer-phone"
v-if="item.phone"
@click.stop="copyPhone(item.phone)"
>{{ item.phone }}</text>
<view class="reception-link-wrap" @click.stop="goPrepareReception(item)">
<text class="reception-link-text">准备接待</text>
</view>
</view>
<text class="customer-budget" v-if="item.budget">{{ item.budget }}</text> <text class="customer-budget" v-if="item.budget">{{ item.budget }}</text>
</view> </view>
</view> </view>
@@ -62,6 +71,9 @@
<script> <script>
import { getApiUrl } from '@/common/config.js'; import { getApiUrl } from '@/common/config.js';
/** 与 furniture_reception_entry 读取的 key 一致 */
const RECEPTION_FORM_PREFILL_KEY = 'workbench-reception-form-prefill';
export default { export default {
name: 'CustomerList', name: 'CustomerList',
@@ -88,6 +100,97 @@
this.loadCustomerList(); this.loadCustomerList();
}, },
methods: { methods: {
copyPhone(phone) {
const text = (phone || '').toString().trim();
if (!text) return;
uni.setClipboardData({
data: text,
success: () => {
uni.showToast({ title: '复制成功', icon: 'success' });
},
fail: () => {
uni.showToast({ title: '复制失败', icon: 'none' });
}
});
},
buildReceptionPrefillPayload(item) {
const r = item.rawData || {};
const s = (v) => {
if (v === undefined || v === null) return '';
return String(v).trim();
};
const prefill = {};
const idStr = s(r.id);
if (idStr) {
prefill.id = idStr;
}
const customerName = s(r.customerName) || s(item.name);
if (customerName) {
prefill.customerName = customerName;
}
const contact = s(r.contact) || s(item.phone);
if (contact) {
prefill.contact = contact;
}
const customerSource = s(r.customerSource);
if (customerSource) {
prefill.customerSource = customerSource;
}
const gender = s(r.gender);
if (gender) {
prefill.gender = gender;
}
const age = s(r.age);
if (age) {
prefill.age = age;
}
const dealershipId = s(r.dealershipId);
if (dealershipId) {
prefill.dealershipId = dealershipId;
}
const dealershipName = s(r.dealershipName);
if (dealershipName) {
prefill.dealershipName = dealershipName;
}
const intendedModel = s(r.intendedModel) || s(item.budget);
if (intendedModel) {
prefill.intendedModel = intendedModel;
}
const infoCard = s(r.infoCard);
if (infoCard) {
prefill.infoCard = infoCard;
}
const remark = s(r.remark);
if (remark) {
prefill.remark = remark;
}
const detailedAddress = s(r.detailedAddress);
if (detailedAddress) {
prefill.detailedAddress = detailedAddress;
}
const rc = Number(r.recordingCount);
prefill.recordingCount = Number.isFinite(rc) ? rc : (Number(item.serviceCount) || 0);
const cc = Number(r.contactCount);
prefill.contactCount = Number.isFinite(cc) ? cc : (Number(item.serviceCount) || 0);
return prefill;
},
goPrepareReception(item) {
try {
const prefill = this.buildReceptionPrefillPayload(item);
uni.setStorageSync(RECEPTION_FORM_PREFILL_KEY, JSON.stringify(prefill));
} catch (e) {
console.error('[CustomerList] 准备接待预填写入失败:', e);
uni.showToast({ title: '预填数据失败', icon: 'none' });
return;
}
uni.navigateTo({
url: '/pages-subpackage/furniture_reception/furniture_reception_entry?tab=reception',
fail: (err) => {
console.error('[CustomerList] 跳转接待页失败:', err);
uni.showToast({ title: '页面跳转失败', icon: 'none' });
}
});
},
onInputChange() { onInputChange() {
// 输入框变化时,可以在这里添加实时搜索逻辑(如果需要) // 输入框变化时,可以在这里添加实时搜索逻辑(如果需要)
}, },
@@ -413,6 +516,23 @@
margin-bottom: 20rpx; margin-bottom: 20rpx;
gap: 12rpx; gap: 12rpx;
} }
/* 与 furniture_reception/serviceListFurniture 中状态文案(如 service-status-indicator__text一致的轻量文字链接近常见「线索」类入口 */
.reception-link-wrap {
display: inline-flex;
align-items: center;
flex-shrink: 0;
padding: 8rpx 0 6rpx;
border-bottom: 1rpx solid rgba(0, 122, 255, 0.38);
box-sizing: border-box;
}
.reception-link-text {
font-size: 26rpx;
font-weight: 400;
color: #007aff;
line-height: 1.35;
}
.tag-item { .tag-item {
padding: 8rpx 16rpx; padding: 8rpx 16rpx;
@@ -443,16 +563,30 @@
align-items: center; align-items: center;
padding-top: 16rpx; padding-top: 16rpx;
border-top: 1px solid #F0F0F0; border-top: 1px solid #F0F0F0;
gap: 16rpx;
}
.customer-footer-left {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
gap: 16rpx;
flex: 1;
min-width: 0;
} }
.customer-phone { .customer-phone {
font-size: 28rpx; font-size: 28rpx;
color: #333; color: #333;
padding: 8rpx 0;
flex-shrink: 0;
} }
.customer-budget { .customer-budget {
font-size: 26rpx; font-size: 26rpx;
color: #1976D2; color: #1976D2;
flex-shrink: 0;
} }
</style> </style>

View File

@@ -81,6 +81,11 @@ import TagManagementPanel from "./tag_management_panel.vue";
incomingTab: { incomingTab: {
type: String, type: String,
default: '' default: ''
},
/** 从客户列表等入口写入本地缓存的一次性预填(不含销售字段,由 loadCurrentUserInfo 填充) */
receptionPrefill: {
type: Object,
default: null
} }
}, },
// #ifdef APP // #ifdef APP
@@ -395,6 +400,36 @@ import TagManagementPanel from "./tag_management_panel.vue";
}; };
// 重新加载当前登录用户信息 // 重新加载当前登录用户信息
this.loadCurrentUserInfo(); this.loadCurrentUserInfo();
this.applyReceptionPrefillFromProp();
},
applyReceptionPrefillFromProp() {
const p = this.receptionPrefill;
if (!p || typeof p !== 'object') {
return;
}
const allowed = [
'id',
'customerName',
'contact',
'customerSource',
'gender',
'age',
'dealershipId',
'dealershipName',
'intendedModel',
'infoCard',
'remark',
'detailedAddress',
'recordingCount',
'contactCount'
];
const slice = {};
allowed.forEach((k) => {
if (Object.prototype.hasOwnProperty.call(p, k)) {
slice[k] = p[k];
}
});
this.receptionForm = { ...this.receptionForm, ...slice };
}, },
onReceptionCancel() { onReceptionCancel() {
// 组件内部已处理取消逻辑,这里只需要重置表单数据 // 组件内部已处理取消逻辑,这里只需要重置表单数据

View File

@@ -1,10 +1,13 @@
<template> <template>
<furniture-reception-impl :incomingTab="incomingTab" /> <furniture-reception-impl :incomingTab="incomingTab" :receptionPrefill="receptionPrefill" />
</template> </template>
<script> <script>
import FurnitureReceptionImpl from './furniture_reception-impl.vue'; import FurnitureReceptionImpl from './furniture_reception-impl.vue';
/** 与 CustomerList 写入的 key 一致:客户管理「准备接待」预填开始接待表单 */
const RECEPTION_FORM_PREFILL_KEY = 'workbench-reception-form-prefill';
export default { export default {
name: 'FurnitureReceptionEntry', name: 'FurnitureReceptionEntry',
components: { components: {
@@ -13,12 +16,31 @@ export default {
data() { data() {
return { return {
incomingTab: '', incomingTab: '',
receptionPrefill: null,
}; };
}, },
onLoad(options = {}) { onLoad(options = {}) {
const allowed = ['status', 'reception', 'tag']; const allowed = ['status', 'reception', 'tag'];
const raw = options.tab != null ? String(options.tab) : ''; const raw = options.tab != null ? String(options.tab) : '';
this.incomingTab = allowed.includes(raw) ? raw : 'reception'; this.incomingTab = allowed.includes(raw) ? raw : 'reception';
try {
const rawPrefill = uni.getStorageSync(RECEPTION_FORM_PREFILL_KEY);
if (!rawPrefill) {
return;
}
try {
const parsed = typeof rawPrefill === 'string' ? JSON.parse(rawPrefill) : rawPrefill;
if (parsed && typeof parsed === 'object') {
this.receptionPrefill = parsed;
}
} catch (parseErr) {
console.warn('[FurnitureReceptionEntry] 接待表单预填 JSON 无效:', parseErr);
} finally {
uni.removeStorageSync(RECEPTION_FORM_PREFILL_KEY);
}
} catch (e) {
console.warn('[FurnitureReceptionEntry] 读取接待表单预填失败:', e);
}
}, },
}; };
</script> </script>