From 1c33bd6c427a310bf1282886cbc499e0b503e897 Mon Sep 17 00:00:00 2001
From: WindowBird <13870814+windows-bird@user.noreply.gitee.com>
Date: Fri, 7 Nov 2025 14:56:40 +0800
Subject: [PATCH] =?UTF-8?q?=E5=90=8E=E5=8F=B0=E8=8E=B7=E5=8F=96=E5=90=84?=
=?UTF-8?q?=E7=B1=BB=E6=B7=BB=E5=8A=A0=E5=AE=A2=E6=88=B7=E7=9A=84=E7=8A=B6?=
=?UTF-8?q?=E6=80=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
App.vue | 2 +-
common/api/customer.js | 60 ++++++
pages/customer/add/index.vue | 377 +++++++++++++++++++++++++----------
3 files changed, 334 insertions(+), 105 deletions(-)
diff --git a/App.vue b/App.vue
index 0e709ea..6f72ade 100644
--- a/App.vue
+++ b/App.vue
@@ -8,7 +8,7 @@
// 如果还没有 token,则设置一个测试 token
const token = uni.getStorageSync('token')
if (!token) {
- const testToken = 'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImQ0ODJhYzdlLTBiYzgtNGFhNC1hMDI2LWVkMWU4YWQ3YmJkYiJ9._m4s6mcpjAHtk4u9r6LMMfIQHSCXDPCTfiWVOTyopZfbsxVFiLkY4ovec3M3u2E9KKm_jIH2fLhAduW4rfAZHQ'
+ const testToken = 'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjlkN2JjOTU3LTllMTYtNGI5ZC04NWZiLThiZjJlZDI3MjRjNiJ9.hJ0Tf691DnryIMp4TAsKILSy9ueN8SgeMZdp0HwxbgGOIhYl5vOUu9H64tA02jpXkB-Sg5owrBjjJxUG17yA7g'
uni.setStorageSync('token', testToken)
console.log('已设置测试 token:', testToken)
}
diff --git a/common/api/customer.js b/common/api/customer.js
index eaeca8f..779af75 100644
--- a/common/api/customer.js
+++ b/common/api/customer.js
@@ -164,3 +164,63 @@ export const createCustomer = (data) => {
});
};
+/**
+ * 获取客户意向字典数据
+ * @returns {Promise} 返回字典数据数组,包含 dictLabel 和 dictValue
+ */
+export const getCustomerIntentDict = () => {
+ return uni.$uv.http.get(`system/dict/data/type/customer_intent`, {
+ custom: {
+ auth: true
+ }
+ });
+};
+
+/**
+ * 获取客户意向强度字典数据
+ * @returns {Promise} 返回字典数据数组,包含 dictLabel 和 dictValue
+ */
+export const getCustomerIntentLevelDict = () => {
+ return uni.$uv.http.get(`system/dict/data/type/customer_intent_level`, {
+ custom: {
+ auth: true
+ }
+ });
+};
+
+/**
+ * 获取客户来源字典数据
+ * @returns {Promise} 返回字典数据数组,包含 dictLabel 和 dictValue
+ */
+export const getCustomerSourceDict = () => {
+ return uni.$uv.http.get(`system/dict/data/type/customer_source`, {
+ custom: {
+ auth: true
+ }
+ });
+};
+
+/**
+ * 获取客户类型字典数据
+ * @returns {Promise} 返回字典数据数组,包含 dictLabel 和 dictValue
+ */
+export const getCustomerTypeDict = () => {
+ return uni.$uv.http.get(`system/dict/data/type/customer_type`, {
+ custom: {
+ auth: true
+ }
+ });
+};
+
+/**
+ * 获取客户状态字典数据
+ * @returns {Promise} 返回字典数据数组,包含 dictLabel 和 dictValue
+ */
+export const getCustomerStatusDict = () => {
+ return uni.$uv.http.get(`system/dict/data/type/customer_status`, {
+ custom: {
+ auth: true
+ }
+ });
+};
+
diff --git a/pages/customer/add/index.vue b/pages/customer/add/index.vue
index 103be16..5d01af0 100644
--- a/pages/customer/add/index.vue
+++ b/pages/customer/add/index.vue
@@ -17,26 +17,10 @@
客户信息
-
- 客户类型
-
-
-
- 个人
-
-
-
- 企业
-
-
+
+ {{ getCustomerTypeText(formData.customerType) }}
+ 选择客户类型
+ ›
@@ -71,29 +55,16 @@
-
-
+
+ {{ formData.source }}
+ 选择客户来源
+ ›
-
-
-
-
-
-
- {{ getStatusText(formData.status) }}
- 选择客户状态
+
+ {{ formData.intents.join('、') }}
+ 选择客户意向(可多选)
›
@@ -104,6 +75,13 @@
›
+
+
+ {{ getCustomerStatusText(formData.customerStatus) }}
+ 选择客户状态
+ ›
+
+
{{ formData.region }}
@@ -207,25 +185,71 @@
-
-
+
+
- 选择客户状态
+ 选择客户类型
{{ item.label }}
- ✓
+ ✓
-
-
+
+
+
+
+
+
+
+
+
+ 选择客户来源
+
+
+ {{ item.label }}
+ ✓
+
+
+
+
+
+
+
+
+
+
+
+
+ 选择客户意向(可多选)
+
+
+ {{ item.label }}
+ ✓
+
+
+
+
+
@@ -253,6 +277,29 @@
+
+
+
+ 选择客户状态
+
+
+ {{ item.label }}
+ ✓
+
+
+
+
+
+
+
+
+
import { ref, computed, onMounted } from 'vue';
-import { createCustomer, getRegionTree } from '@/common/api';
+import {
+ createCustomer,
+ getRegionTree,
+ getCustomerIntentDict,
+ getCustomerIntentLevelDict,
+ getCustomerSourceDict,
+ getCustomerTypeDict,
+ getCustomerStatusDict
+} from '@/common/api';
import { useUserStore } from '@/store/user';
// 表单数据
const formData = ref({
- customerType: '个人', // 客户类型:个人/企业
+ customerType: '', // 客户类型(dictValue)
name: '', // 客户名称
mobile: '', // 联系电话
wechat: '', // 微信号
- source: '', // 客户来源
- intents: '', // 客户意向(字符串,提交时转换为数组)
- status: '', // 客户状态
- intentLevel: '', // 意向强度
+ source: '', // 客户来源(dictLabel)
+ intents: [], // 客户意向(数组,dictLabel)
+ intentLevel: '', // 意向强度(dictValue)
+ customerStatus: '', // 客户状态(dictValue)
region: '', // 客户地区(显示名称,如:北京/北京/朝阳)
regionIds: [], // 客户地区ID数组 [省ID, 市ID, 区ID]
workWechat: '', // 工作微信(显示名称)
@@ -346,18 +401,31 @@ const formData = ref({
// 显示状态
const saving = ref(false);
-const showStatusPicker = ref(false);
+const showCustomerTypePicker = ref(false);
+const showSourcePicker = ref(false);
+const showIntentPicker = ref(false);
const showIntentLevelPicker = ref(false);
+const showCustomerStatusPicker = ref(false);
const showWorkWechatPicker = ref(false);
const showNextFollowTimePicker = ref(false);
// 临时选择值
-const tempStatus = ref('');
+const tempCustomerType = ref('');
+const tempSource = ref('');
+const tempIntents = ref([]);
const tempIntentLevel = ref('');
+const tempCustomerStatus = ref('');
const tempWorkWechat = ref('');
const tempNextFollowDate = ref('');
const tempNextFollowTime = ref('');
+// 字典数据
+const customerTypeOptions = ref([]); // 客户类型选项
+const sourceOptions = ref([]); // 客户来源选项
+const intentOptions = ref([]); // 客户意向选项
+const intentLevelOptions = ref([]); // 意向强度选项
+const customerStatusOptions = ref([]); // 客户状态选项
+
// 地区树数据
const regionTree = ref([]);
// uv-picker 的列数据
@@ -374,20 +442,63 @@ const addressList = computed(() => {
return [provinces.value, citys.value, areas.value];
});
-// 客户状态选项
-const statusOptions = [
- { label: '潜在', value: '1' },
- { label: '意向', value: '2' },
- { label: '成交', value: '3' },
- { label: '失效', value: '4' }
-];
-
-// 意向强度选项
-const intentLevelOptions = [
- { label: '高', value: '1' },
- { label: '中', value: '2' },
- { label: '低', value: '3' }
-];
+// 加载字典数据
+const loadDictData = async () => {
+ try {
+ // 并行加载所有字典数据
+ const [typeRes, sourceRes, intentRes, intentLevelRes, statusRes] = await Promise.all([
+ getCustomerTypeDict(),
+ getCustomerSourceDict(),
+ getCustomerIntentDict(),
+ getCustomerIntentLevelDict(),
+ getCustomerStatusDict()
+ ]);
+
+ // 处理客户类型数据
+ customerTypeOptions.value = (typeRes || []).map(item => ({
+ label: item.dictLabel,
+ value: item.dictValue
+ }));
+
+ // 处理客户来源数据
+ sourceOptions.value = (sourceRes || []).map(item => ({
+ label: item.dictLabel,
+ value: item.dictValue
+ }));
+
+ // 处理客户意向数据
+ intentOptions.value = (intentRes || []).map(item => ({
+ label: item.dictLabel,
+ value: item.dictValue
+ }));
+
+ // 处理意向强度数据
+ intentLevelOptions.value = (intentLevelRes || []).map(item => ({
+ label: item.dictLabel,
+ value: item.dictValue
+ }));
+
+ // 处理客户状态数据
+ customerStatusOptions.value = (statusRes || []).map(item => ({
+ label: item.dictLabel,
+ value: item.dictValue
+ }));
+
+ console.log('字典数据加载成功:', {
+ customerType: customerTypeOptions.value,
+ source: sourceOptions.value,
+ intent: intentOptions.value,
+ intentLevel: intentLevelOptions.value,
+ customerStatus: customerStatusOptions.value
+ });
+ } catch (err) {
+ console.error('加载字典数据失败:', err);
+ uni.showToast({
+ title: '加载字典数据失败',
+ icon: 'none'
+ });
+ }
+};
// 加载地区树数据
const loadRegionTree = async () => {
@@ -466,32 +577,78 @@ const workWechatOptions = [
{ label: '工作微信4', value: '工作微信4', id: '4' }
];
-// 获取状态文本
-const getStatusText = (status) => {
- const option = statusOptions.find(opt => opt.value === status);
+// 获取客户类型文本
+const getCustomerTypeText = (value) => {
+ const option = customerTypeOptions.value.find(opt => opt.value === value);
return option ? option.label : '';
};
// 获取意向强度文本
-const getIntentLevelText = (level) => {
- return level || '';
+const getIntentLevelText = (value) => {
+ const option = intentLevelOptions.value.find(opt => opt.value === value);
+ return option ? option.label : '';
};
-// 打开状态选择器
-const openStatusPicker = () => {
- tempStatus.value = formData.value.status;
- showStatusPicker.value = true;
+// 获取客户状态文本
+const getCustomerStatusText = (value) => {
+ const option = customerStatusOptions.value.find(opt => opt.value === value);
+ return option ? option.label : '';
};
-// 选择状态
-const selectStatus = (value) => {
- tempStatus.value = value;
+// 打开客户类型选择器
+const openCustomerTypePicker = () => {
+ tempCustomerType.value = formData.value.customerType;
+ showCustomerTypePicker.value = true;
};
-// 确认状态
-const confirmStatus = () => {
- formData.value.status = tempStatus.value;
- showStatusPicker.value = false;
+// 选择客户类型
+const selectCustomerType = (value) => {
+ tempCustomerType.value = value;
+};
+
+// 确认客户类型
+const confirmCustomerType = () => {
+ formData.value.customerType = tempCustomerType.value;
+ showCustomerTypePicker.value = false;
+};
+
+// 打开客户来源选择器
+const openSourcePicker = () => {
+ tempSource.value = formData.value.source;
+ showSourcePicker.value = true;
+};
+
+// 选择客户来源
+const selectSource = (label) => {
+ tempSource.value = label;
+};
+
+// 确认客户来源
+const confirmSource = () => {
+ formData.value.source = tempSource.value;
+ showSourcePicker.value = false;
+};
+
+// 打开客户意向选择器
+const openIntentPicker = () => {
+ tempIntents.value = [...formData.value.intents];
+ showIntentPicker.value = true;
+};
+
+// 切换客户意向(多选)
+const toggleIntent = (label) => {
+ const index = tempIntents.value.indexOf(label);
+ if (index > -1) {
+ tempIntents.value.splice(index, 1);
+ } else {
+ tempIntents.value.push(label);
+ }
+};
+
+// 确认客户意向
+const confirmIntent = () => {
+ formData.value.intents = [...tempIntents.value];
+ showIntentPicker.value = false;
};
// 打开意向强度选择器
@@ -511,6 +668,23 @@ const confirmIntentLevel = () => {
showIntentLevelPicker.value = false;
};
+// 打开客户状态选择器
+const openCustomerStatusPicker = () => {
+ tempCustomerStatus.value = formData.value.customerStatus;
+ showCustomerStatusPicker.value = true;
+};
+
+// 选择客户状态
+const selectCustomerStatus = (value) => {
+ tempCustomerStatus.value = value;
+};
+
+// 确认客户状态
+const confirmCustomerStatus = () => {
+ formData.value.customerStatus = tempCustomerStatus.value;
+ showCustomerStatusPicker.value = false;
+};
+
// 打开地区选择器
const openRegionPicker = () => {
console.log('openRegionPicker called');
@@ -679,9 +853,10 @@ const handleCancel = () => {
uni.navigateBack();
};
-// 组件挂载时加载地区树数据
+// 组件挂载时加载地区树数据和字典数据
onMounted(() => {
loadRegionTree();
+ loadDictData();
});
// 保存
@@ -721,11 +896,8 @@ const handleSave = async () => {
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
};
- // 处理意向设备数组(如果输入的是逗号分隔的字符串,转换为数组)
- let intentsArray = [];
- if (formData.value.intents && formData.value.intents.trim()) {
- intentsArray = formData.value.intents.split(',').map(item => item.trim()).filter(item => item);
- }
+ // 处理意向数组(已经是数组格式,包含dictLabel)
+ const intentsArray = Array.isArray(formData.value.intents) ? formData.value.intents : [];
// 处理地区ID数组(使用已选择的regionIds)
const regionIdsArray = formData.value.regionIds || [];
@@ -739,11 +911,11 @@ const handleSave = async () => {
intentLevel: null,
mobile: formData.value.mobile.trim(),
wechat: formData.value.wechat.trim() || null,
- source: formData.value.source.trim() || null,
- intents: intentsArray, // 数组格式
+ source: formData.value.source || null, // 使用dictLabel
+ intents: intentsArray, // 数组格式,使用dictLabel
followId: userId, // 跟进人ID
remark: formData.value.remark.trim() || null,
- type: '2', // 固定为2
+ type: formData.value.customerType || '2', // 使用dictValue
workWechatId: formData.value.workWechatId || null,
regionIds: regionIdsArray, // 数组格式
// 添加关注点、顾虑点、需求点、痛点字段
@@ -754,12 +926,12 @@ const handleSave = async () => {
follow: {
followTime: formatDateTime(now), // 当前时间作为跟进时间
nextFollowTime: formData.value.nextFollowTime || null,
- customerStatus: formData.value.status || '1',
- customerIntentLevel: formData.value.intentLevel || null
+ customerIntentLevel: formData.value.intentLevel || null, // 使用dictValue
+ customerStatus: formData.value.customerStatus || null // 使用dictValue
},
- customerStatus: formData.value.status || '1',
nextFollowTime: formData.value.nextFollowTime || null,
- customerIntentLevel: formData.value.intentLevel || null
+ customerIntentLevel: formData.value.intentLevel || null, // 使用dictValue
+ customerStatus: formData.value.customerStatus || null // 使用dictValue
};
// 调用API创建客户
@@ -770,10 +942,7 @@ const handleSave = async () => {
icon: 'success'
});
- // 延迟返回上一页
- setTimeout(() => {
- uni.navigateBack();
- }, 1500);
+ // 保存成功后不清空表单,留在当前页面
} catch (error) {
console.error('创建客户失败:', error);
uni.showToast({