接待 线索类型的客户逻辑
This commit is contained in:
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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() {
|
||||||
// 组件内部已处理取消逻辑,这里只需要重置表单数据
|
// 组件内部已处理取消逻辑,这里只需要重置表单数据
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user