Browse Source

修改 bug

master
王泽彦 8 months ago
parent
commit
d74624d2be
  1. 3
      niucloud/app/api/controller/apiController/CustomerResources.php
  2. 18
      niucloud/app/api/controller/apiController/ResourceSharing.php
  3. 7
      niucloud/app/common.php
  4. 13
      niucloud/app/model/dict/Dict.php
  5. 128
      niucloud/app/service/api/apiService/ResourceSharingService.php
  6. 37
      niucloud/app/service/api/common/DictService.php
  7. 4
      uniapp/common/config.js
  8. 137
      uniapp/components/order-form-popup/index.vue
  9. 1031
      uniapp/pages-market/clue/edit_clues.vue
  10. 79
      uniapp/pages-market/clue/index.vue

3
niucloud/app/api/controller/apiController/CustomerResources.php

@ -211,7 +211,8 @@ class CustomerResources extends BaseApiService
"second_visit_status" => $request->param('second_visit_status', ''),
"chasing_orders" => $request->param('chasing_orders', ''),
"consultation_remark" => $request->param('consultation_remark', ''),
"call_intent" => $request->param('call_intent', '')
"call_intent" => $request->param('call_intent', ''),
"emotional_stickiness_score" => $request->param('emotional_stickiness_score', 1),//情感粘度
];

18
niucloud/app/api/controller/apiController/ResourceSharing.php

@ -33,6 +33,15 @@ class ResourceSharing extends BaseApiService
$phone_number = $request->param('phone_number','');//客户资源表-手机号
$campus_name = $request->param('campus_name','');//客户资源表-校区
// 新增搜索参数
$source = $request->param('source','');//来源类型
$source_channel = $request->param('source_channel','');//来源渠道
$attendance_type = $request->param('attendance_type','');//到课类型
$deal_type = $request->param('deal_type','');//成交类型
$valid_type = $request->param('valid_type','');//资源有效类型
$communication_status = $request->param('communication_status','');//沟通情况
$course_search = $request->param('course_search','');//课程检索
$shared_at_str = $request->param('shared_at_str','');//共享时间|[开始时间(Y-m-d),结束时间(Y-m-d)]
$shared_at_arr = [];
if(!empty($shared_at_str)){
@ -46,7 +55,14 @@ class ResourceSharing extends BaseApiService
'shared_at_arr'=>$shared_at_arr,
'name'=>$name,
'phone_number'=>$phone_number,
'campus_name' => $campus_name
'campus_name' => $campus_name,
'source' => $source,
'source_channel' => $source_channel,
'attendance_type' => $attendance_type,
'deal_type' => $deal_type,
'valid_type' => $valid_type,
'communication_status' => $communication_status,
'course_search' => $course_search
];
$res = (new ResourceSharingService())->getList($where);
return success($res);

7
niucloud/app/common.php

@ -1259,10 +1259,17 @@ function get_dict_value($key, $value)
$info['dictionary'] = [];
}
// 如果dictionary是字符串,尝试解析为数组
if (is_string($info['dictionary'])) {
$info['dictionary'] = json_decode($info['dictionary'], true) ?: [];
}
$map = [];
if (is_array($info['dictionary'])) {
foreach ($info['dictionary'] as $item) {
$map[$item['value']] = $item['name'];
}
}
return $map[$value] ?? '';
}

13
niucloud/app/model/dict/Dict.php

@ -33,14 +33,13 @@ class Dict extends BaseModel
*/
protected $name = 'sys_dict';
protected $type = [
'dictionary' => 'json'
];
// 移除JSON自动转换,手动处理以避免类型冲突
// protected $type = [
// 'dictionary' => 'json'
// ];
// 设置json类型字段
protected $json = ['dictionary'];
// 设置JSON数据返回数组
protected $jsonAssoc = true;
// protected $json = ['dictionary'];
// protected $jsonAssoc = true;
/**
* 搜索器:数据字典字典名称

128
niucloud/app/service/api/apiService/ResourceSharingService.php

@ -200,7 +200,8 @@ class ResourceSharingService extends BaseApiService
if (!empty($where['campus_name'])) {
// 先查询匹配的校区ID
$campus = new Campus();
$matched_campus_ids = $campus->where('campus_name', 'like', '%' . $where['campus_name'] . '%')->column('id');
$matched_campus_ids = $campus->where('campus_name', 'like', '%' . $where['campus_name'] . '%')
->column('id');
if (!empty($matched_campus_ids)) {
$resource_conditions[] = ['campus', 'in', $matched_campus_ids];
@ -226,6 +227,16 @@ class ResourceSharingService extends BaseApiService
$resource_conditions[] = ['phone_number', 'like', '%' . $where['phone_number'] . '%'];
}
// 来源查询
if (!empty($where['source'])) {
$resource_conditions[] = ['source', 'like', '%' . $where['source'] . '%'];
}
// 来源渠道查询
if (!empty($where['source_channel'])) {
$resource_conditions[] = ['source_channel', 'like', '%' . $where['source_channel'] . '%'];
}
// 查询符合条件的资源ID
$resource_ids = [];
if (!empty($resource_conditions)) {
@ -249,6 +260,98 @@ class ResourceSharingService extends BaseApiService
->where('shared_at', '<=', $where['shared_at_arr'][1]);
}
// 处理有效性查询 - 需要通过six_speed表关联查询
if (!empty($where['valid_type'])) {
$six_speed_model = new \app\model\six_speed\SixSpeed();
if ($where['valid_type'] === '有效') {
$valid_resource_ids = $six_speed_model->where('efficacious', 1)->column('resource_id');
} else if ($where['valid_type'] === '无效') {
$valid_resource_ids = $six_speed_model->where('efficacious', 0)->column('resource_id');
}
if (isset($valid_resource_ids)) {
if (empty($resource_ids)) {
$resource_ids = $valid_resource_ids;
} else {
$resource_ids = array_intersect($resource_ids, $valid_resource_ids);
}
if (empty($resource_ids)) {
return [
'count' => 0,
'total' => 0,
'current_page' => $page,
'last_page' => 0,
'data' => []
];
}
$model = $model->whereIn('resource_id', $resource_ids);
}
}
// 处理成交类型查询 - 通过订单表关联查询
if (!empty($where['deal_type'])) {
$order_model = new OrderTable();
if ($where['deal_type'] === '已成交') {
$deal_resource_ids = $order_model->where('order_status', 'paid')->column('resource_id');
} else if ($where['deal_type'] === '未成交') {
// 没有付费订单的资源
$paid_resource_ids = $order_model->where('order_status', 'paid')->column('resource_id');
$all_resource_ids = (new CustomerResources())->column('id');
$deal_resource_ids = array_diff($all_resource_ids, $paid_resource_ids);
}
if (isset($deal_resource_ids)) {
if (empty($resource_ids)) {
$resource_ids = $deal_resource_ids;
} else {
$resource_ids = array_intersect($resource_ids, $deal_resource_ids);
}
if (empty($resource_ids)) {
return [
'count' => 0,
'total' => 0,
'current_page' => $page,
'last_page' => 0,
'data' => []
];
}
$model = $model->whereIn('resource_id', $resource_ids);
}
}
// 处理沟通情况查询 - 通过沟通记录表关联查询
if (!empty($where['communication_status'])) {
if ($where['communication_status'] === '已沟通') {
$comm_resource_ids = CommunicationRecords::distinct(true)->column('resource_id');
} else if ($where['communication_status'] === '未沟通') {
// 没有沟通记录的资源
$comm_resource_ids_with_records = CommunicationRecords::distinct(true)->column('resource_id');
$all_resource_ids = (new CustomerResources())->column('id');
$comm_resource_ids = array_diff($all_resource_ids, $comm_resource_ids_with_records);
}
if (isset($comm_resource_ids)) {
if (empty($resource_ids)) {
$resource_ids = $comm_resource_ids;
} else {
$resource_ids = array_intersect($resource_ids, $comm_resource_ids);
}
if (empty($resource_ids)) {
return [
'count' => 0,
'total' => 0,
'current_page' => $page,
'last_page' => 0,
'data' => []
];
}
$model = $model->whereIn('resource_id', $resource_ids);
}
}
// 过滤已分配的资源(只显示可再分配的资源)
// 注意:这里需要用子查询包装OR条件,避免与其他WHERE条件冲突
$model = $model->when($where['shared_by'] > 0, function ($query) use ($where) {
@ -295,6 +398,15 @@ class ResourceSharingService extends BaseApiService
$shared_by_ids = array_column($list['data'], 'shared_by');
$shared_by_ids = array_unique(array_filter($shared_by_ids));
// 获取市场老师ID列表
$consultant_ids = [];
foreach ($list['data'] as $item) {
if (!empty($item['customerResource']) && !empty($item['customerResource']['consultant'])) {
$consultant_ids[] = $item['customerResource']['consultant'];
}
}
$consultant_ids = array_unique(array_filter($consultant_ids));
// 查询分配人员信息
$shared_by_names = [];
if (!empty($shared_by_ids)) {
@ -302,6 +414,13 @@ class ResourceSharingService extends BaseApiService
$shared_by_names = $personnel->whereIn('id', $shared_by_ids)->column('name', 'id');
}
// 查询市场老师信息
$consultant_names = [];
if (!empty($consultant_ids)) {
$personnel = new \app\model\personnel\Personnel();
$consultant_names = $personnel->whereIn('id', $consultant_ids)->column('name', 'id');
}
// 查询最近沟通记录
$communication_times = [];
if (!empty($resource_ids)) {
@ -404,6 +523,13 @@ class ResourceSharingService extends BaseApiService
$item['customerResource']['source_channel'] = get_dict_value('SourceChannel', $item['customerResource']['source_channel']);
$item['customerResource']['campus_name'] = $campus_names[$item['customerResource']['campus']] ?? '';
// 设置市场老师名称
if (!empty($item['customerResource']['consultant'])) {
$item['customerResource']['consultant_name'] = $consultant_names[$item['customerResource']['consultant']] ?? '';
} else {
$item['customerResource']['consultant_name'] = '';
}
// 修复沟通时间字段
$item['customerResource']['communication_time'] = $communication_times[$item['resource_id']] ?? '';

37
niucloud/app/service/api/common/DictService.php

@ -61,17 +61,46 @@ class DictService extends BaseApiService
$key = $dict['key'];
$dictionary = $dict['dictionary'];
// 解析字典值 - 模型已自动处理JSON转换
if (!empty($dictionary) && is_array($dictionary)) {
// 解析字典值 - 手动处理JSON解析
if (!empty($dictionary)) {
if (is_array($dictionary)) {
// 已经是数组格式,直接使用
$result[$key] = $dictionary;
} else if (!empty($dictionary) && is_string($dictionary)) {
// 如果是字符串,尝试解析
} else if (is_string($dictionary)) {
// 处理JSON字符串,可能包含转义字符
// 首先尝试直接解析
$decodedValue = json_decode($dictionary, true);
if (json_last_error() === JSON_ERROR_NONE) {
if (is_array($decodedValue)) {
// 解析结果是数组,直接使用
$result[$key] = $decodedValue;
} else if (is_string($decodedValue)) {
// 解析结果是字符串,可能是双重JSON编码,尝试再次解析
$secondDecodedValue = json_decode($decodedValue, true);
if (json_last_error() === JSON_ERROR_NONE && is_array($secondDecodedValue)) {
$result[$key] = $secondDecodedValue;
} else {
// 字符串解析失败,使用字符串解析方法
$result[$key] = $this->parseStringValue($decodedValue);
}
} else {
$result[$key] = [];
}
} else {
// JSON解析失败,尝试其他方法
$cleanedDictionary = stripcslashes($dictionary);
$decodedValue = json_decode($cleanedDictionary, true);
if (json_last_error() === JSON_ERROR_NONE && is_array($decodedValue)) {
$result[$key] = $decodedValue;
} else {
// 使用字符串解析方法作为最后手段
$result[$key] = $this->parseStringValue($dictionary);
}
}
} else {
$result[$key] = [];
}
} else {
$result[$key] = [];
}

4
uniapp/common/config.js

@ -1,6 +1,6 @@
// 环境变量配置
// const env = 'development'
const env = 'prod'
const env = 'development'
// const env = 'prod'
const isMockEnabled = false // 默认禁用Mock优先模式,仅作为回退
const isDebug = false // 默认启用调试模式
const devurl = 'http://localhost:20080/api'

137
uniapp/components/order-form-popup/index.vue

@ -120,6 +120,7 @@
<script>
import apiRoute from '@/api/apiRoute.js'
import dictUtilSimple from '@/common/dictUtilSimple.js'
export default {
name: 'OrderFormPopup',
@ -158,19 +159,15 @@ export default {
pickerOptions: [],
selectedIndex: 0,
//
courseSelectedIndex: -1,
paymentSelectedIndex: -1,
orderTypeSelectedIndex: -1,
//
courseList: [],
paymentTypes: [
{ value: 'cash', label: '现金支付' },
{ value: 'scan_code', label: '扫码支付' },
{ value: 'subscription', label: '订阅支付' },
{ value: 'wxpay_online', label: '微信在线代付' }
],
orderTypes: [
{ value: '1', label: '新订单' },
{ value: '2', label: '续费订单' },
{ value: '3', label: '内部员工订单' }
]
paymentTypes: [], //
orderTypes: [] //
}
},
computed: {
@ -188,9 +185,10 @@ export default {
visible(newVal) {
console.log('visible changed:', newVal)
if (newVal) {
console.log('开始初始化表单和加载课程列表')
console.log('开始初始化表单和加载数据')
this.initForm()
this.loadCourseList()
this.loadDictionaries() //
}
},
studentInfo: {
@ -205,10 +203,11 @@ export default {
},
mounted() {
console.log('OrderFormPopup mounted, visible:', this.visible)
// visible true
// visible true
if (this.visible) {
console.log('组件挂载时 visible 为 true,开始加载课程列表')
console.log('组件挂载时 visible 为 true,开始加载数据')
this.loadCourseList()
this.loadDictionaries()
}
},
methods: {
@ -224,6 +223,11 @@ export default {
remark: '',
class_id: '1' // ID
}
//
this.courseSelectedIndex = -1
this.paymentSelectedIndex = -1
this.orderTypeSelectedIndex = -1
},
async loadCourseList() {
@ -256,12 +260,84 @@ export default {
}
},
/**
* 加载字典数据 - 支付方式和订单类型
*/
async loadDictionaries() {
console.log('开始加载字典数据')
try {
const dictResult = await dictUtilSimple.getBatchDict(['payment_type', 'order_type'])
console.log('字典数据获取结果:', dictResult)
//
if (dictResult.payment_type && Array.isArray(dictResult.payment_type)) {
this.paymentTypes = dictResult.payment_type.map(item => ({
value: item.value,
label: item.name
}))
console.log('支付方式字典加载成功:', this.paymentTypes)
} else {
console.warn('支付方式字典数据格式不正确:', dictResult.payment_type)
// 使
this.paymentTypes = [
{ value: 'cash', label: '现金支付' },
{ value: 'scan_code', label: '扫码支付' },
{ value: 'subscription', label: '订阅支付' },
{ value: 'wxpay_online', label: '微信在线代付' }
]
}
//
if (dictResult.order_type && Array.isArray(dictResult.order_type)) {
this.orderTypes = dictResult.order_type.map(item => ({
value: item.value,
label: item.name
}))
console.log('订单类型字典加载成功:', this.orderTypes)
} else {
console.warn('订单类型字典数据格式不正确:', dictResult.order_type)
// 使
this.orderTypes = [
{ value: '1', label: '新订单' },
{ value: '2', label: '续费订单' },
{ value: '3', label: '内部员工订单' }
]
}
} catch (error) {
console.error('加载字典数据失败:', error)
// 使
this.paymentTypes = [
{ value: 'cash', label: '现金支付' },
{ value: 'scan_code', label: '扫码支付' },
{ value: 'subscription', label: '订阅支付' },
{ value: 'wxpay_online', label: '微信在线代付' }
]
this.orderTypes = [
{ value: '1', label: '新订单' },
{ value: '2', label: '续费订单' },
{ value: '3', label: '内部员工订单' }
]
}
},
showCoursePicker() {
this.currentPicker = 'course'
this.pickerTitle = '选择课程'
this.pickerOptions = this.courseList
this.pickerValue = [0]
this.selectedIndex = 0 //
//
if (this.formData.course_id) {
const currentIndex = this.courseList.findIndex(item => item.id == this.formData.course_id)
this.courseSelectedIndex = currentIndex >= 0 ? currentIndex : 0
} else {
this.courseSelectedIndex = 0
}
this.pickerValue = [this.courseSelectedIndex]
this.selectedIndex = this.courseSelectedIndex
this.$refs.pickerPopup.open()
},
@ -269,8 +345,17 @@ export default {
this.currentPicker = 'payment'
this.pickerTitle = '选择支付方式'
this.pickerOptions = this.paymentTypes
this.pickerValue = [0]
this.selectedIndex = 0 //
//
if (this.formData.payment_type) {
const currentIndex = this.paymentTypes.findIndex(item => item.value === this.formData.payment_type)
this.paymentSelectedIndex = currentIndex >= 0 ? currentIndex : 0
} else {
this.paymentSelectedIndex = 0
}
this.pickerValue = [this.paymentSelectedIndex]
this.selectedIndex = this.paymentSelectedIndex
this.$refs.pickerPopup.open()
},
@ -278,8 +363,17 @@ export default {
this.currentPicker = 'orderType'
this.pickerTitle = '选择订单类型'
this.pickerOptions = this.orderTypes
this.pickerValue = [0]
this.selectedIndex = 0 //
//
if (this.formData.order_type) {
const currentIndex = this.orderTypes.findIndex(item => item.value === this.formData.order_type)
this.orderTypeSelectedIndex = currentIndex >= 0 ? currentIndex : 0
} else {
this.orderTypeSelectedIndex = 0
}
this.pickerValue = [this.orderTypeSelectedIndex]
this.selectedIndex = this.orderTypeSelectedIndex
this.$refs.pickerPopup.open()
},
@ -293,6 +387,7 @@ export default {
switch (this.currentPicker) {
case 'course':
this.courseSelectedIndex = this.selectedIndex
this.formData.course_id = selectedOption.id
//
if (selectedOption.price !== undefined) {
@ -307,9 +402,11 @@ export default {
console.log('课程选择后更新表单数据:', this.formData)
break
case 'payment':
this.paymentSelectedIndex = this.selectedIndex
this.formData.payment_type = selectedOption.value
break
case 'orderType':
this.orderTypeSelectedIndex = this.selectedIndex
this.formData.order_type = selectedOption.value
break
}

1031
uniapp/pages-market/clue/edit_clues.vue

File diff suppressed because it is too large

79
uniapp/pages-market/clue/index.vue

@ -39,8 +39,8 @@
<view class="card-con" v-if="v.sixSpeed && v.sixSpeed.consultation_remark">
到访备注{{ v.sixSpeed.consultation_remark || '' }}
</view>
<view class="card-con" v-if="v.sixSpeed && v.sixSpeed.consultation_remark">
市场老师{{ v.sixSpeed.consultation_remark || '' }}
<view class="card-con">
市场老师{{ v.customerResource.consultant_name || '测试显示' + v.customerResource.consultant }}
</view>
</view>
<view class="card-right">
@ -383,7 +383,9 @@
//
sourceIndex: 0,
sourceOptions: ['全部', '线上', '线下'],
sourceOptions: ['全部', '线上', '线下'], //
sourceDict: {}, // ID
sourceChannelDict: {}, // ID
attendanceIndex: 0,
attendanceOptions: ['全部', '一访未到', '一访已到', '二访未到', '二访已到', '未到访'],
dealIndex: 0,
@ -510,6 +512,7 @@
//
async init() {
await this.getUserInfo();
await this.initDictData(); //
if (this.segmented_type == 1) {
await this.getList_1();
} else {
@ -517,6 +520,38 @@
}
},
//
async initDictData() {
try {
//
const sourceRes = await apiRoute.common_Dictionary({key: 'source'})
if (sourceRes.code === 1 && sourceRes.data) {
// 使
const sourceData = sourceRes.data
this.sourceOptions = ['全部', ...sourceData.map(item => item.name)]
this.sourceDict = sourceData.reduce((acc, item) => {
acc[item.name] = item.value
return acc
}, {})
console.log('来源字典加载成功:', this.sourceOptions)
}
//
const channelRes = await apiRoute.common_Dictionary({key: 'SourceChannel'})
if (channelRes.code === 1 && channelRes.data) {
// 使
const channelData = channelRes.data
this.sourceChannelDict = channelData.reduce((acc, item) => {
acc[item.name] = item.value
return acc
}, {})
console.log('渠道字典加载成功:', this.sourceChannelDict)
}
} catch (error) {
console.error('字典数据加载失败:', error)
}
},
//
async getUserInfo() {
let res = await apiRoute.getPersonnelInfo({})
@ -628,6 +663,11 @@
return
}
console.log('getList_1 API响应:', res)
console.log('getList_1 第一条数据的customerResource:', res.data.data[0]?.customerResource)
console.log('getList_1 consultant字段:', res.data.data[0]?.customerResource?.consultant)
console.log('getList_1 consultant_name字段:', res.data.data[0]?.customerResource?.consultant_name)
this.tableList_1 = this.tableList_1.concat(res.data.data); // 使 concat
console.log('列表1', this.tableList_1)
@ -681,7 +721,8 @@
return
}
console.log(123123, res)
console.log('API响应数据:', res)
console.log('第一条数据的customerResource:', res.data.data[0]?.customerResource)
this.tableList_2 = this.tableList_2.concat(res.data.data); // 使 concat
@ -987,21 +1028,49 @@
currentFilterData.shared_at_str = ''
}
//
//
if (this.searchForm.source && this.searchForm.source !== '全部') {
currentFilterData.source = this.searchForm.source
} else {
currentFilterData.source = ''
}
//
if (this.searchForm.source_channel) {
currentFilterData.source_channel = this.searchForm.source_channel
} else {
currentFilterData.source_channel = ''
}
//
if (this.searchForm.attendance_type && this.searchForm.attendance_type !== '全部') {
currentFilterData.attendance_type = this.searchForm.attendance_type
} else {
currentFilterData.attendance_type = ''
}
if (this.searchForm.deal_type && this.searchForm.deal_type !== '全部') {
currentFilterData.deal_type = this.searchForm.deal_type
} else {
currentFilterData.deal_type = ''
}
if (this.searchForm.valid_type && this.searchForm.valid_type !== '全部') {
currentFilterData.valid_type = this.searchForm.valid_type
} else {
currentFilterData.valid_type = ''
}
if (this.searchForm.communication_status && this.searchForm.communication_status !== '全部') {
currentFilterData.communication_status = this.searchForm.communication_status
} else {
currentFilterData.communication_status = ''
}
if (this.searchForm.course_search) {
currentFilterData.course_search = this.searchForm.course_search
} else {
currentFilterData.course_search = ''
}
console.log('映射后的筛选数据:', currentFilterData)

Loading…
Cancel
Save