新建跟进

This commit is contained in:
WindowBird 2025-11-10 10:49:55 +08:00
parent 22554d7638
commit 9e9672abda
5 changed files with 1745 additions and 1 deletions

View File

@ -142,6 +142,28 @@ export const getFollowupDetail = (followId) => {
});
};
/**
* 创建跟进记录
* @param {Object} data 跟进记录数据
* @param {string} data.customerId 客户ID
* @param {string} data.type 跟进方式
* @param {string} data.content 跟进内容
* @param {string} data.picture 图片URL多个用逗号分隔
* @param {string} data.attaches 附件URL多个用逗号分隔
* @param {string} data.followTime 跟进时间 (yyyy-MM-dd HH:mm:ss)
* @param {string} data.nextFollowTime 下次跟进时间 (yyyy-MM-dd HH:mm:ss)
* @param {string} data.customerStatus 客户状态
* @param {string} data.customerIntentLevel 客户意向强度
* @returns {Promise} 返回创建结果
*/
export const createFollowup = (data) => {
return uni.$uv.http.post(`bst/customerFollow`, data, {
custom: {
auth: true
}
});
};
/**
* 获取客户项目列表
* @param {string} customerId 客户ID

View File

@ -0,0 +1,260 @@
<template>
<!-- 客户选择器 - uv-picker -->
<uv-picker
ref="customerPickerRef"
:columns="customerColumns"
keyName="name"
@confirm="onCustomerConfirm"
@cancel="closeCustomerPicker"
></uv-picker>
<!-- 客户状态选择器 - uv-picker -->
<uv-picker
ref="statusPickerRef"
:columns="statusColumns"
keyName="dictLabel"
@confirm="onStatusConfirm"
@cancel="closeStatusPicker"
></uv-picker>
<!-- 意向强度选择器 - uv-picker -->
<uv-picker
ref="intentLevelPickerRef"
:columns="intentLevelColumns"
keyName="dictLabel"
@confirm="onIntentLevelConfirm"
@cancel="closeIntentLevelPicker"
></uv-picker>
<!-- 跟进方式选择器 - uv-picker -->
<uv-picker
ref="followTypePickerRef"
:columns="followTypeColumns"
keyName="dictLabel"
@confirm="onFollowTypeConfirm"
@cancel="closeFollowTypePicker"
></uv-picker>
</template>
<script setup>
import { ref, watch, nextTick } from 'vue';
const props = defineProps({
showCustomerPicker: Boolean,
showStatusPicker: Boolean,
showIntentLevelPicker: Boolean,
showFollowTypePicker: Boolean,
customerList: Array,
statusOptions: Array,
intentLevelOptions: Array,
followTypeOptions: Array,
formData: Object
});
const emit = defineEmits(['update:formData', 'close-picker']);
// ref
const customerPickerRef = ref(null);
const statusPickerRef = ref(null);
const intentLevelPickerRef = ref(null);
const followTypePickerRef = ref(null);
// 使 ref columns
const customerColumns = ref([[]]);
const statusColumns = ref([[]]);
const intentLevelColumns = ref([[]]);
const followTypeColumns = ref([[]]);
// prop
watch(() => props.showCustomerPicker, async (val) => {
if (val && customerPickerRef.value) {
//
if (!props.customerList || props.customerList.length === 0) {
console.warn('客户列表数据未加载');
return;
}
await nextTick();
//
if (props.formData?.customerId) {
const index = props.customerList.findIndex(c => c.id === props.formData.customerId);
if (index >= 0 && customerPickerRef.value.setIndexs) {
customerPickerRef.value.setIndexs([index], true);
}
}
customerPickerRef.value.open();
}
});
watch(() => props.showStatusPicker, async (val) => {
if (val && statusPickerRef.value) {
//
if (!props.statusOptions || props.statusOptions.length === 0) {
console.warn('客户状态数据未加载');
return;
}
await nextTick();
//
if (props.formData?.customerStatus) {
const index = props.statusOptions.findIndex(item => item.dictValue === props.formData.customerStatus);
if (index >= 0 && statusPickerRef.value.setIndexs) {
statusPickerRef.value.setIndexs([index], true);
}
}
statusPickerRef.value.open();
}
});
watch(() => props.showIntentLevelPicker, async (val) => {
if (val && intentLevelPickerRef.value) {
//
if (!props.intentLevelOptions || props.intentLevelOptions.length === 0) {
console.warn('意向强度数据未加载');
return;
}
await nextTick();
//
if (props.formData?.customerIntentLevel) {
const index = props.intentLevelOptions.findIndex(item => item.dictValue === props.formData.customerIntentLevel);
if (index >= 0 && intentLevelPickerRef.value.setIndexs) {
intentLevelPickerRef.value.setIndexs([index], true);
}
}
intentLevelPickerRef.value.open();
}
});
watch(() => props.showFollowTypePicker, async (val) => {
if (val && followTypePickerRef.value) {
//
if (!props.followTypeOptions || props.followTypeOptions.length === 0) {
console.warn('跟进方式数据未加载');
return;
}
await nextTick();
//
if (props.formData?.type) {
const index = props.followTypeOptions.findIndex(item => item.dictValue === props.formData.type);
if (index >= 0 && followTypePickerRef.value.setIndexs) {
followTypePickerRef.value.setIndexs([index], true);
}
}
followTypePickerRef.value.open();
}
});
// columns
watch(() => props.customerList, (newList) => {
if (newList && newList.length > 0) {
customerColumns.value = [newList];
console.log('客户列表 columns 已更新:', customerColumns.value, '数据长度:', newList.length);
} else {
customerColumns.value = [[]];
}
}, { immediate: true, deep: true });
watch(() => props.statusOptions, (newOptions) => {
if (newOptions && newOptions.length > 0) {
statusColumns.value = [newOptions];
console.log('客户状态 columns 已更新:', statusColumns.value, '数据长度:', newOptions.length);
} else {
statusColumns.value = [[]];
}
}, { immediate: true, deep: true });
watch(() => props.intentLevelOptions, (newOptions) => {
if (newOptions && newOptions.length > 0) {
intentLevelColumns.value = [newOptions];
console.log('意向强度 columns 已更新:', intentLevelColumns.value, '数据长度:', newOptions.length);
} else {
intentLevelColumns.value = [[]];
}
}, { immediate: true, deep: true });
watch(() => props.followTypeOptions, (newOptions) => {
if (newOptions && newOptions.length > 0) {
followTypeColumns.value = [newOptions];
console.log('跟进方式 columns 已更新:', followTypeColumns.value, '数据长度:', newOptions.length);
} else {
followTypeColumns.value = [[]];
}
}, { immediate: true, deep: true });
//
const closeCustomerPicker = () => {
emit('close-picker', 'customer');
};
const closeStatusPicker = () => {
emit('close-picker', 'status');
};
const closeIntentLevelPicker = () => {
emit('close-picker', 'intentLevel');
};
const closeFollowTypePicker = () => {
emit('close-picker', 'followType');
};
//
const onCustomerConfirm = (e) => {
const selectedItems = e.value;
if (selectedItems && selectedItems.length > 0) {
const selectedCustomer = selectedItems[0];
if (selectedCustomer && selectedCustomer.id) {
emit('update:formData', {
...props.formData,
customerId: selectedCustomer.id,
customerName: selectedCustomer.name
});
}
}
closeCustomerPicker();
};
//
const onStatusConfirm = (e) => {
const selectedItems = e.value;
if (selectedItems && selectedItems.length > 0) {
const selectedItem = selectedItems[0];
if (selectedItem && selectedItem.dictValue) {
emit('update:formData', {
...props.formData,
customerStatus: selectedItem.dictValue
});
}
}
closeStatusPicker();
};
//
const onIntentLevelConfirm = (e) => {
const selectedItems = e.value;
if (selectedItems && selectedItems.length > 0) {
const selectedItem = selectedItems[0];
if (selectedItem && selectedItem.dictValue) {
emit('update:formData', {
...props.formData,
customerIntentLevel: selectedItem.dictValue
});
}
}
closeIntentLevelPicker();
};
//
const onFollowTypeConfirm = (e) => {
const selectedItems = e.value;
if (selectedItems && selectedItems.length > 0) {
const selectedItem = selectedItems[0];
if (selectedItem && selectedItem.dictValue) {
emit('update:formData', {
...props.formData,
type: selectedItem.dictValue
});
}
}
closeFollowTypePicker();
};
</script>
<style lang="scss" scoped>
// uv-picker
</style>

View File

@ -90,6 +90,13 @@
"navigationStyle": "custom"
}
},
{
"path": "pages/customer/follow/add/index",
"style": {
"navigationBarTitleText": "新建跟进记录",
"navigationStyle": "custom"
}
},
{
"path": "pages/customer/follow/detail/index",
"style": {

View File

@ -299,8 +299,12 @@ const handleProjectMore = (project) => {
//
const handleNewFollowup = () => {
if (!customerId.value) {
uni.$uv.toast('客户信息不完整');
return;
}
uni.navigateTo({
url: `/pages/customer-follow/index?customerId=${customerId.value}&customerName=${customerDetail.value.name}`
url: `/pages/customer/follow/add/index?customerId=${customerId.value}&customerName=${encodeURIComponent(customerDetail.value.name || '')}`
});
};

File diff suppressed because it is too large Load Diff