Browse Source

修改bug

master
王泽彦 1 year ago
parent
commit
105f75417d
  1. 12
      common/util.js
  2. 4
      pages/market/clue/add_clues.vue
  3. 192
      pages/market/clue/edit_clues.vue
  4. 235
      pages/market/clue/index.vue

12
common/util.js

@ -1,5 +1,5 @@
import {img_domian} from "./config";
import marketApi from '@/api/market.js';
import marketApi from '@/api/apiRoute.js';
function formatTime(time) {
if (typeof time !== 'number' || time < 0) {
@ -231,13 +231,17 @@ async function getDict(dictKey) {
return cache.data;
}
// 缓存无效,请求接口
const res = await marketApi.common_Dictionary({ dictKey });
const res = await marketApi.common_Dictionary({ key: dictKey });
if (res && res.code === 1) {
// 处理接口返回的数据,确保返回格式一致
// 接口返回的是 [{name: "抖音", value: "1", sort: 0, memo: ""}, ...]
const formattedData = Array.isArray(res.data) ? res.data : [];
uni.setStorageSync(cacheKey, {
data: res.data,
data: formattedData,
expire: now + 3600 * 1000
});
return res.data;
return formattedData;
} else {
return [];
}

4
pages/market/clue/add_clues.vue

@ -904,8 +904,8 @@ export default {
return
}
let arr = []
// 兼容后端返回格式
(dictionary.dictionary || dictionary).forEach((v)=>{
// 处理接口返回的数据结构 [{name: "抖音", value: "1", sort: 0, memo: ""}, ...]
dictionary.forEach((v) => {
arr.push({ text: v.name, value: v.value })
})
this.picker_config[inputName].options = arr

192
pages/market/clue/edit_clues.vue

@ -27,6 +27,21 @@
</view>
</view>
</fui-form-item>
<!-- 来源渠道 -->
<fui-form-item
v-if="formData.source == 1"
label="来源渠道"
labelSize='26'
prop="source_channel"
background='#434544'
labelColor='#fff'
:bottomBorder='false'>
<view class="input-title" style="margin-right:14rpx;">
<view class="input-title" style="margin-right:14rpx;" @click="openCicker('source_channel')">
{{ formData.source_channel ? picker_config.source_channel.text : '点击选择' }}
</view>
</view>
</fui-form-item>
<!-- 姓名 -->
<fui-form-item label="姓名" labelSize='26' prop="name" background='#434544' labelColor='#fff' :bottomBorder='false'>
<view class="input-title" style="margin-right:14rpx;">
@ -198,17 +213,17 @@
<fui-form-item label="是否报名" labelSize='26' prop="is_bm" background='#434544' labelColor='#fff' :bottomBorder='false'>
<view class="input-title" style="margin-right:14rpx;">
<fui-radio-group name="radio" v-model="formData.is_bm" >
<fui-radio-group name="radio" v-model="formData.is_bm" :disabled="true">
<view class="fui-list__item" style="display: flex;justify-content: flex-end;">
<fui-label>
<view class="fui-align__center">
<fui-radio :value="1" checked></fui-radio>
<fui-radio :value="1" :disabled="true"></fui-radio>
<text class="fui-text">报名</text>
</view>
</fui-label>
<fui-label :margin="['0','0','0','40rpx']">
<view class="fui-align__center">
<fui-radio :value="2"></fui-radio>
<fui-radio :value="2" :disabled="true"></fui-radio>
<text class="fui-text">未报名</text>
</view>
</fui-label>
@ -463,18 +478,41 @@
methods: {
//初始化
async init() {
await this.getDict('source_channel') //获取字典-来源渠道
await this.getDict('source') //获取字典-来源
await this.getDict('purchasing_power') //获取字典-购买力
await this.getDict('initial_intent') //获取字典-客户初步意向度
await this.getDict('cognitive_idea') //获取字典-认知理念
await this.getDict('status') //获取字典-客户状态
await this.getDict('decision_maker') //获取字典-决策人
await this.getDict('distance') //获取字典-距离
// this.getStaffList()//获取人员列表
// this.getAreaTree()//获取地区树形结构
await this.getInfo() //获取资源共享-详情(客户资源详情)
try {
uni.showLoading({
title: '加载中...',
mask: true
});
// 先加载所有字典数据
const dictPromises = [
this.getDict('source_channel'), //获取字典-来源渠道
this.getDict('source'), //获取字典-来源
this.getDict('purchasing_power'), //获取字典-购买力
this.getDict('initial_intent'), //获取字典-客户初步意向度
this.getDict('cognitive_idea'), //获取字典-认知理念
this.getDict('status'), //获取字典-客户状态
this.getDict('decision_maker'), //获取字典-决策人
this.getDict('distance'), //获取字典-距离
];
await Promise.all(dictPromises);
// 加载校区列表
await this.get_campus_list();
// 获取资源共享详情并回显数据
await this.getInfo();
} catch (error) {
console.error('初始化失败:', error);
uni.showToast({
title: '加载数据失败,请重试',
icon: 'none'
});
} finally {
uni.hideLoading();
}
},
async get_campus_list(){
@ -538,6 +576,7 @@
decision_maker: customerResource.decision_maker || '', //决策人
initial_intent: customerResource.initial_intent || '', //客户初步意向度: high-高, medium-中, low-低
status: customerResource.status || '', //客户状态: active-活跃, inactive-不活跃, pending-待定
campus: customerResource.campus || '', // 校区
//六要素信息
purchasing_power: sixSpeed.purchase_power || '', //购买力
@ -554,24 +593,72 @@
this.formData.promised_visit_time = this.$util.formatToDateTime(sixSpeed.promised_visit_time,
'Y-m-d'); //格式化时间(Y-m-d H:i)
this.formData.optional_class_time = this.$util.formatToDateTime(sixSpeed.promised_visit_time,
this.formData.optional_class_time = this.$util.formatToDateTime(sixSpeed.preferred_class_time,
'Y-m-d'); //格式化时间(Y-m-d H:i)
// 获取校区列表,确保校区选择器数据已加载
await this.get_campus_list()
// 等待所有字典数据加载完成后再进行回显
await this.setPickerText()
},
//下拉窗文本回显
this.picker_config.source_channel.text = customerResource.source_channel_name || '点击选择' //来源渠道
this.picker_config.source.text = customerResource.source_name || '点击选择' //来源
this.picker_config.consultant.text = customerResource.consultant_name || '点击选择' //顾问
this.picker_config.initial_intent.text = customerResource.initial_intent_name || '点击选择' //客户初步意向度
this.picker_config.status.text = customerResource.status_name || '点击选择' //客户状态
this.picker_config.decision_maker.text = customerResource.decision_maker || '点击选择' //决策人
// 设置选择器文本回显
async setPickerText() {
const { customerResource = {}, sixSpeed = {} } = await this.getResourceDetail() || {}
// 设置选择器文本回显
this.setPickerTextByValue('source_channel', this.formData.source_channel, customerResource.source_channel_name)
this.setPickerTextByValue('source', this.formData.source, customerResource.source_name)
this.setPickerTextByValue('consultant', this.formData.consultant, customerResource.consultant_name)
this.setPickerTextByValue('initial_intent', this.formData.initial_intent, customerResource.initial_intent_name)
this.setPickerTextByValue('status', this.formData.status, customerResource.status_name)
this.setPickerTextByValue('decision_maker', this.formData.decision_maker, customerResource.decision_maker_name || customerResource.decision_maker)
this.setPickerTextByValue('campus', this.formData.campus, customerResource.campus_name)
// 六要素相关
this.setPickerTextByValue('purchasing_power', this.formData.purchasing_power, sixSpeed.purchase_power_name)
this.setPickerTextByValue('cognitive_idea', this.formData.cognitive_idea, sixSpeed.concept_awareness_name)
this.setPickerTextByValue('distance', this.formData.distance, sixSpeed.distance_name || sixSpeed.distance)
},
//六要素相关
this.picker_config.purchasing_power.text = sixSpeed.purchase_power_name || '点击选择' //购买力
this.picker_config.cognitive_idea.text = sixSpeed.concept_awareness_name || '点击选择' //认知理念
this.picker_config.distance.text = sixSpeed.distance || '点击选择' //距离
// 根据值设置选择器文本
setPickerTextByValue(pickerName, value, defaultText) {
if (!value) {
this.picker_config[pickerName].text = '点击选择'
return
}
// 先尝试从选项中找到匹配的文本
const options = this.picker_config[pickerName].options || []
const option = options.find(opt => opt.value == value)
if (option) {
this.picker_config[pickerName].text = option.text
} else if (defaultText) {
// 如果找不到匹配的选项但有默认文本,则使用默认文本
this.picker_config[pickerName].text = defaultText
} else {
this.picker_config[pickerName].text = '点击选择'
}
},
await this.get_campus_list()//获取校区
// 获取资源详情(缓存数据,避免重复请求)
async getResourceDetail() {
if (this._resourceDetail) {
return this._resourceDetail
}
let params = {
resource_sharing_id: this.resource_sharing_id
}
let res = await apiRoute.xs_resourceSharingInfo(params)
if (res.code == 1) {
this._resourceDetail = res.data
return res.data
}
return null
},
//获取字典-课程id选择
@ -705,25 +792,17 @@
return
}
let res = await apiRoute.common_Dictionary({
key: key
})
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
// 使用 util.getDict 获取并缓存字典
let dictionary = await this.$util.getDict(key)
if(!dictionary || !Array.isArray(dictionary) || dictionary.length === 0){
uni.showToast({ title: '暂无选项', icon: 'none' })
return
}
let dictionary = res.data.dictionary
let arr = []
dictionary.forEach((v, k) => {
arr.push({
text: v.name,
value: v.value,
})
// 处理接口返回的数据结构 [{name: "抖音", value: "1", sort: 0, memo: ""}, ...]
dictionary.forEach((v) => {
arr.push({ text: v.name, value: v.value })
})
if (inputName == 'source_channel') {
@ -733,10 +812,6 @@
value: '0',
})
}
if (inputName == 'status') {
//插入到arr的头部
console.log(arr)
}
this.picker_config[inputName].options = arr
},
@ -971,15 +1046,26 @@
changeCicker(e) {
console.log('监听-下拉选择器', this.picker_input_name, e)
let input_name = this.picker_input_name
// 更新表单数据
this.formData[input_name] = e.value
this.picker_config[input_name]['text'] = e.text
// 更新选择器文本
this.picker_config[input_name].text = e.text
// 特殊处理:来源选择
if (input_name == 'source') {
if (e.value != 1) {
this.formData.source_channel = '0' //0=线下
if (e.value == 1) {
// 如果选择了线上,则清空来源渠道,等待用户选择
this.formData.source_channel = ''
this.picker_config.source_channel.text = '点击选择'
} else {
this.formData.source_channel = '' //线下
// 如果选择了其他来源,则设置来源渠道为线下
this.formData.source_channel = '0' //0=线下
this.picker_config.source_channel.text = '线下'
}
}
this.cancelCicker()
},
//关闭下拉选择器

235
pages/market/clue/index.vue

@ -15,57 +15,64 @@
</view>
</view>
<view class="card" v-for="(v,k) in tableList_1" :key="k">
<view style="width: 70%;" @click="clue_info(v)">
<view style="display: flex;align-items: center;padding: 20rpx;">
<view>
<image :src="$util.img('/uniapp_src/static/images/index/myk.png')" class="card-image">
</image>
<view class="card-content">
<view class="card-left" @click="clue_info(v)">
<view style="display: flex;align-items: center;padding: 20rpx;">
<view>
<image :src="$util.img('/uniapp_src/static/images/index/myk.png')" class="card-image">
</image>
</view>
<view class="card-text">{{ v.customerResource.name }}</view>
<view class="card-con-span">{{ v.customerResource.phone_number }}</view>
</view>
<view class="card-con">
所属校区:{{ v.customerResource.campus_name }}
</view>
<view class="card-con">
来源:{{ v.customerResource.source }}
</view>
<view class="card-con">
来源渠道:{{ v.customerResource.source_channel }}
</view>
<view class="card-text">{{ v.customerResource.name }}</view>
<view class="card-con-span">{{ v.customerResource.phone_number }}</view>
</view>
<view class="card-con">
所属校区:{{ v.customerResource.campus_name }}
</view>
<view class="card-con">
来源渠道:{{ v.customerResource.source_channel }} <!-- <span
class="card-con-span">{{ v.customerResource.source_channel }}</span> -->
<view class="card-right">
<!--只有注册了member表的账号才可操作IM对话-->
<view class="btn-item" v-if="v.customerResource.member_id" @click.stop>
<image :src="$util.img('/uniapp_src/static/images/index/message.png')" class="image"
@click.stop="openViewMyMessage(v)"></image>
</view>
<view class="btn-item" v-if="v.customerResource.phone_number" @click.stop>
<image :src="$util.img('/uniapp_src/static/images/index/phone.png')" class="image"
@click.stop="dialTel(v)">
</image>
</view>
</view>
</view>
<view class="card-footer">
<view class="card-date">
<view class="card-con">
{{ $util.formatToDateTime((v.customerResource.updated_at || ''), 'm-d H:i') }}
跟进
<view class="card-con" v-if="v.customerResource.communication_time">
{{ $util.formatToDateTime((v.customerResource.communication_time || ''), 'm-d H:i') }}
拨打电话
</view>
<view class="card-con" v-else>
暂未联系
</view>
<view style="margin-left: 30rpx;">
<view style="display: flex;align-items: center;">
<view class="title-x">
是否有效:{{ v.sixSpeed && v.sixSpeed.efficacious === 1 ? '有效' : '无效' }}
</view>
<view style="padding: 12rpx;">
<image v-if="v.customerResource.initial_intent == 'high'"
:src="$util.img('/uniapp_src/static/images/index/intention3.png')"
class="drop-image-x"></image>
<image v-else-if="v.customerResource.initial_intent == 'medium'"
<image v-if="v.sixSpeed.efficacious === 1"
:src="$util.img('/uniapp_src/static/images/index/intention2.png')"
class="drop-image-x"></image>
<image v-else :src="$util.img('/uniapp_src/static/images/index/intention1.png')"
<image v-else :src="$util.img('/uniapp_src/static/images/index/intention3.png')"
class="drop-image-x"></image>
</view>
<view class="title-x">
是否有效:{{ v.customerResource && v.customerResource.initial_intent_name || '' }}</view>
</view>
</view>
</view>
</view>
<!--只有注册了member表的账号才可操作IM对话-->
<view style="width: 15%;">
<image v-if="v.customerResource.member_id"
:src="$util.img('/uniapp_src/static/images/index/message.png')" class="image"
@click="openViewMyMessage(v)"></image>
</view>
<view style="width: 15%;">
<image v-if="v.customerResource.phone_number"
:src="$util.img('/uniapp_src/static/images/index/phone.png')" class="image" @click="dialTel(v)">
</image>
</view>
</view>
</scroll-view>
@ -81,22 +88,34 @@
</view>
</view>
<view class="card" v-for="(v,k) in tableList_2" :key="k">
<view style="width: 80%;">
<view style="display: flex;align-items: center;padding: 20rpx;">
<view>
<image :src="$util.img('/uniapp_src/static/images/index/myk.png')" class="card-image">
</image>
<view class="card-content">
<view class="card-left">
<view style="display: flex;align-items: center;padding: 20rpx;">
<view>
<image :src="$util.img('/uniapp_src/static/images/index/myk.png')" class="card-image">
</image>
</view>
<view class="card-text">{{v.customerResource.name}}</view>
<!-- <view class="card-label">{{v.is_status == 1 ? '试听' : '成交'}}</view>-->
</view>
<view class="card-con">
决策人:{{v.customerResource.name}} <span
class="card-con-span">{{v.customerResource.decision_maker}}</span>
</view>
<view class="card-text">{{v.customerResource.name}}</view>
<!-- <view class="card-label">{{v.is_status == 1 ? '试听' : '成交'}}</view>-->
</view>
<view class="card-con">
决策人:{{v.customerResource.name}} <span
class="card-con-span">{{v.customerResource.decision_maker}}</span>
<view class="card-right">
<view class="btn-item" @click.stop="openAssign(v)">
<view class="ling">分配</view>
</view>
</view>
</view>
<view class="card-footer">
<view class="card-date">
<view class="card-con">
{{ $util.formatToDateTime((v.customerResource.updated_at || ''),'m-d H:i') }} 跟进
<view class="card-con" v-if="v.customerResource.communication_time">
{{ $util.formatToDateTime((v.customerResource.communication_time || ''),'m-d H:i') }} 拨打电话
</view>
<view class="card-con" v-else>
暂未联系
</view>
<view style="margin-left: 30rpx;">
<view style="display: flex;align-items: center;">
@ -116,9 +135,6 @@
</view>
</view>
</view>
<view style="width: 20%;" @click="openAssign(v)">
<view class="ling">分配</view>
</view>
</view>
</scroll-view>
@ -136,7 +152,7 @@
<view class="fui-title">筛选</view>
<scroll-view scroll-y style="height: 720rpx;">
<view class="drawer_box">
<fui-list-cell>
<view class="item">
<view class="title">校区筛选</view>
@ -146,8 +162,8 @@
</view>
</view>
</fui-list-cell>
<fui-list-cell>
<view class="item">
<view class="title">时间筛选</view>
@ -238,7 +254,7 @@
shared_at_str: '', //共享时间|开始时间(Y-m-d)-结束时间(Y-m-d)
phone_number: '', //客户资源表-手机号
name: '', //客户资源表-用户姓名
campus_name:'',
campus_name: '',
},
//数据列表
tableList_1: [], //表格数据
@ -253,7 +269,7 @@
shared_at_str: '', //共享时间|[开始时间(Y-m-d),结束时间(Y-m-d)]
phone_number: '', //客户资源表-手机号
name: '', //客户资源表-用户姓名
campus_name:'',
campus_name: '',
},
//数据列表
tableList_2: [], //表格数据
@ -274,7 +290,7 @@
//抽屉搜索条件展示窗相关
showDrawer: false, //是否展示|false=否
showDrawerForm: {
campus_name:'',
campus_name: '',
shared_at_str: '', //共享时间|[开始时间(Y-m-d),结束时间(Y-m-d)]
phone_number: '', //客户资源表-手机号
name: '', //客户资源表-用户姓名
@ -358,11 +374,11 @@
//获取全部员工
async getPersonnelAll(campus='') {
async getPersonnelAll(campus = '') {
let res = await apiRoute.common_getPersonnelAll({
personnel_id: this.userInfo.id, //客户id
account_type: 'market', //账号类型|teacher=老师,market=销售
campus:campus
campus: campus
})
if (res.code != 1) {
uni.showToast({
@ -411,10 +427,6 @@
//判断是否还有数据
if (this.filteredData_1.page * this.filteredData_1.limit > this.filteredData_1.total) {
this.loading = false
uni.showToast({
title: '暂无更多',
icon: 'none'
})
return
}
@ -470,10 +482,6 @@
//判断是否还有数据
if (this.filteredData_2.page * this.filteredData_2.limit > this.filteredData_2.total) {
this.loading = false
uni.showToast({
title: '暂无更多',
icon: 'none'
})
return
}
@ -556,28 +564,27 @@
return;
}
let param = {
staff_id: this.userInfo.id, //员工id
resource_id: item.customerResource.id, //资源ID
resource_type: '', //资源类型(如设备、文件、系统等)
communication_type: 'phone', //沟通类型: phone-电话, email-邮件, meeting-会议, other-其他
communication_result: 'success', //沟通结果: success-成功, failure-失败, pending-待定
remarks: null, //备注
tag: null, //标签
}
let res = await apiRoute.xs_communicationRecordsAdd(param) //添加通过记录
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
uni.makePhoneCall({
phoneNumber: tel
phoneNumber: tel,
success: () => {
let param = {
staff_id: this.userInfo.id, //员工id
resource_id: item.customerResource.id, //资源ID
resource_type: '', //资源类型(如设备、文件、系统等)
communication_type: 'phone', //沟通类型: phone-电话, email-邮件, meeting-会议, other-其他
communication_result: 'success', //沟通结果: success-成功, failure-失败, pending-待定
remarks: null, //备注
tag: null, //标签
}
apiRoute.xs_communicationRecordsAdd(param).then(ressuccess=>{
if(ressuccess.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
}
})
}
})
},
@ -756,7 +763,55 @@
background: #434544;
border-radius: 16rpx;
display: flex;
align-items: center;
flex-direction: column;
.card-content {
display: flex;
justify-content: space-between;
.card-left {
flex: 1;
padding-right: 10rpx;
}
.card-right {
min-width: 120rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 20rpx;
.btn-item {
margin-bottom: 20rpx;
display: flex;
justify-content: center;
align-items: center;
width: 80rpx;
height: 80rpx;
background-color: rgba(255, 255, 255, 0.1);
border-radius: 50%;
&:last-child {
margin-bottom: 0;
}
.image {
width: 60rpx;
height: 60rpx;
}
}
}
}
.card-footer {
width: 100%;
border-top: 1rpx solid rgba(255, 255, 255, 0.1);
padding: 20rpx;
box-sizing: border-box;
background-color: rgba(0, 0, 0, 0.1);
border-radius: 0 0 16rpx 16rpx;
}
}
.card-image {
@ -810,8 +865,8 @@
}
.image {
width: 70rpx;
height: 70rpx;
width: 60rpx;
height: 60rpx;
}
.neck {

Loading…
Cancel
Save