Browse Source

修改 bug

master
王泽彦 9 months ago
parent
commit
02704cdd36
  1. 16
      niucloud/app/api/controller/apiController/CommunicationRecords.php
  2. 26
      niucloud/app/api/controller/apiController/Course.php
  3. 18
      niucloud/app/api/controller/apiController/Personnel.php
  4. 6
      niucloud/app/api/route/route.php
  5. 19
      niucloud/app/service/api/apiService/CommunicationRecordsService.php
  6. 135
      niucloud/app/service/api/apiService/CourseService.php
  7. 247
      niucloud/app/service/api/apiService/PersonnelService.php
  8. 8
      uniapp/api/apiRoute.js
  9. 109
      uniapp/common/util.js
  10. 147
      uniapp/pages/coach/course/info_list.vue
  11. 244
      uniapp/pages/market/clue/clue_info.vue
  12. 8
      uniapp/pages/student/login/login.vue

16
niucloud/app/api/controller/apiController/CommunicationRecords.php

@ -46,4 +46,20 @@ class CommunicationRecords extends BaseApiService
} }
return success('操作成功'); return success('操作成功');
} }
public function edit(Request $request){
$date = date('Y-m-d H:i:s');
$where = [
['id', '=', $request->param('id', '')],
];
$data = [
'remarks' => $request->param('remarks', ''),//备注
'updated_at' => $date
];
$res = (new CommunicationRecordsService())->edit($where,$data);
if(!$res['code']){
return fail('操作失败');
}
return success('操作成功');
}
} }

26
niucloud/app/api/controller/apiController/Course.php

@ -124,4 +124,30 @@ class Course extends BaseApiService
return (new CourseService())->schedule_del($data); return (new CourseService())->schedule_del($data);
} }
/**
* 更新学员课程人员配置
* @param Request $request
* @return \think\Response
*/
public function updateStudentCoursePersonnel(Request $request)
{
try {
$params = $request->all();
// 验证必要参数
if (empty($params['student_course_id'])) {
return fail('学员课程ID不能为空');
}
$res = (new CourseService())->updateStudentCoursePersonnel($params);
if (!$res['code']) {
return fail($res['msg']);
}
return success($res['data'], '更新成功');
} catch (\Exception $e) {
return fail('更新学员课程人员配置失败:' . $e->getMessage());
}
}
} }

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

@ -262,4 +262,22 @@ class Personnel extends BaseApiService
} }
} }
/**
* 获取教练数据列表
* @param Request $request
* @return \think\Response
*/
public function getCoachList(Request $request)
{
try {
$res = (new PersonnelService())->getCoachList();
if (!$res['code']) {
return fail($res['msg']);
}
return success($res['data']);
} catch (\Exception $e) {
return fail('获取教练列表失败:' . $e->getMessage());
}
}
} }

6
niucloud/app/api/route/route.php

@ -224,6 +224,8 @@ Route::group(function () {
//员工端-获取全部人员列表 //员工端-获取全部人员列表
Route::get('personnel/getPersonnelAll', 'apiController.Personnel/getPersonnelAll'); Route::get('personnel/getPersonnelAll', 'apiController.Personnel/getPersonnelAll');
//员工端-获取教练数据列表
Route::get('personnel/getCoachList', 'apiController.Personnel/getCoachList');
//员工端-添加新员工信息 //员工端-添加新员工信息
Route::post('personnel/add', 'apiController.Personnel/add'); Route::post('personnel/add', 'apiController.Personnel/add');
@ -253,6 +255,7 @@ Route::group(function () {
//沟通记录-添加 //沟通记录-添加
Route::post('communicationRecords/add', 'apiController.CommunicationRecords/add'); Route::post('communicationRecords/add', 'apiController.CommunicationRecords/add');
Route::post('communicationRecords/edit', 'apiController.CommunicationRecords/edit');
//校区-获取员工下的全部校区 //校区-获取员工下的全部校区
Route::get('campus/getPersonnelCampus', 'apiController.Campus/getPersonnelCampus'); Route::get('campus/getPersonnelCampus', 'apiController.Campus/getPersonnelCampus');
@ -284,6 +287,9 @@ Route::group(function () {
//员工端-订单管理-创建 //员工端-订单管理-创建
Route::post('orderTable/add', 'apiController.OrderTable/add'); Route::post('orderTable/add', 'apiController.OrderTable/add');
//员工端-更新学员课程人员配置
Route::post('updateStudentCoursePersonnel', 'apiController.Course/updateStudentCoursePersonnel');

19
niucloud/app/service/api/apiService/CommunicationRecordsService.php

@ -86,4 +86,23 @@ class CommunicationRecordsService extends BaseApiService
]; ];
} }
public function edit(array $where, array $data)
{
$model = $this->model;
$edit = $model->where($where)->update($data);
if ($edit) {
$res = [
'code' => 1,
'msg' => '操作成功',
'data' => []
];
} else {
$res = [
'code' => 0,
'msg' => '操作失败',
'data' => []
];
}
return $res;
}
} }

135
niucloud/app/service/api/apiService/CourseService.php

@ -200,17 +200,66 @@ class CourseService extends BaseApiService
$PersonCourseSchedule = new PersonCourseSchedule(); $PersonCourseSchedule = new PersonCourseSchedule();
$student_arr = $PersonCourseSchedule->where('schedule_id',$id)->column('student_id'); $student_arr = $PersonCourseSchedule->where('schedule_id',$id)->column('student_id');
$query = $StudentCourses->where('course_id', $id); // 获取当前时间
$now = date('Y-m-d H:i:s');
// 查询end_date大于当前时间的课程记录
$query = $StudentCourses->where('course_id', $id)
->where('end_date', '>', $now);
if (!empty($student_arr)) { if (!empty($student_arr)) {
$query->whereNotIn('student_id', $student_arr); $query->whereNotIn('student_id', $student_arr);
} }
$res = $query->field('student_id as value')->select()->toArray();
$Student = new Student(); $studentCourses = $query->field('student_id as value, resource_id')->select()->toArray();
foreach ($res as $k => &$v) {
$StudentName = $Student->where('id',$v['value'])->value('name'); // 如果没有符合条件的记录,直接返回空数组
$v['text'] = $StudentName; if (empty($studentCourses)) {
return [];
} }
return $res;
// 收集所有的resource_id
$resourceIds = array_column($studentCourses, 'resource_id');
$resourceIds = array_filter($resourceIds); // 过滤掉空值
if (empty($resourceIds)) {
return [];
}
// 查询客户资源表获取详细信息
$resources = Db::name('customer_resources')
->whereIn('id', $resourceIds)
->field('id, name, source_channel, source, age')
->select()
->toArray();
// 将资源信息与学生ID关联
$result = [];
foreach ($resources as $resource) {
// 查找对应的学生ID
foreach ($studentCourses as $course) {
if ($course['resource_id'] == $resource['id']) {
// 源和来源渠道转换为字典值
$source = get_dict_value("source", $resource['source']);
$sourceChannel = get_dict_value("source_channel", $resource['source_channel']);
$result[] = [
'value' => $course['value'], // 学生ID
'resource_id' => $resource['id'],
'text' => $resource['name'], // 学生姓名
'name' => $resource['name'],
'age' => $resource['age'],
'source' => $source,
'source_channel' => $sourceChannel,
'source_raw' => $resource['source'],
'source_channel_raw' => $resource['source_channel']
];
break;
}
}
}
return $result;
} }
public function addStudent($data) public function addStudent($data)
@ -377,5 +426,77 @@ class CourseService extends BaseApiService
} }
} }
/**
* 更新学员课程人员配置
* @param array $data
* @return array
*/
public function updateStudentCoursePersonnel(array $data)
{
$res = [
'code' => 0,
'msg' => '更新失败',
'data' => []
];
try {
// 开启事务
Db::startTrans();
$studentCourseId = $data['student_course_id'];
$mainCoachId = $data['main_coach_id'] ?? null;
$educationId = $data['education_id'] ?? null;
$assistantIds = $data['assistant_ids'] ?? '';
// 更新学员课程表
$updateData = [
'updated_at' => date('Y-m-d H:i:s')
];
if ($mainCoachId !== null) {
$updateData['main_coach_id'] = $mainCoachId;
}
if ($educationId !== null) {
$updateData['education_id'] = $educationId;
}
if ($assistantIds !== '') {
$updateData['assistant_ids'] = $assistantIds;
}
// 更新学员课程表
$updateResult = Db::name('student_courses')
->where('id', $studentCourseId)
->update($updateData);
if (!$updateResult) {
Db::rollback();
$res['msg'] = '更新学员课程配置失败';
return $res;
}
// 提交事务
Db::commit();
$res = [
'code' => 1,
'msg' => '更新成功',
'data' => [
'student_course_id' => $studentCourseId,
'main_coach_id' => $mainCoachId,
'education_id' => $educationId,
'assistant_ids' => $assistantIds
]
];
} catch (\Exception $e) {
Db::rollback();
$res['msg'] = '更新学员课程人员配置异常:' . $e->getMessage();
}
return $res;
}
} }

247
niucloud/app/service/api/apiService/PersonnelService.php

@ -189,52 +189,51 @@ class PersonnelService extends BaseApiService
$model = $this->model; $model = $this->model;
//存在员工id的时候 //存在员工id的时候
if ((!empty($where['personnel_id']) || isset($where['personnel_id'])) && $where['personnel_id'] !== '') { // if ((!empty($where['personnel_id']) || isset($where['personnel_id'])) && $where['personnel_id'] !== '') {
//查询这个员工的校区id // //查询这个员工的校区id
$campus_id = CampusPersonRole::where('person_id', $where['personnel_id']) // $campus_id = CampusPersonRole::where('person_id', $where['personnel_id'])
->distinct(true) // ->distinct(true)
->column('campus_id'); // ->column('campus_id');
if ($campus_id[0]) { // if ($campus_id[0]) {
//
$person_id_arr = CampusPersonRole::whereIn('campus_id', $campus_id) // $person_id_arr = CampusPersonRole::whereIn('campus_id', $campus_id)
->where(['dept_id' => 3]) // ->where(['dept_id' => 3])
->distinct(true) // ->distinct(true)
->column('person_id'); // ->column('person_id');
if ($person_id_arr) { // if ($person_id_arr) {
//根据校区id获取校区下的全部员工 // //根据校区id获取校区下的全部员工
$model = $model->whereIn('id', $person_id_arr); // $model = $model->whereIn('id', $person_id_arr);
} // }
}else{ // }else{
echo 123;die; // $person_id_arr = CampusPersonRole::whereIn('campus_id', $campus_id)
$person_id_arr = CampusPersonRole::whereIn('campus_id', $campus_id) // ->where(['dept_id' => 3])
->where(['dept_id' => 3]) // ->distinct(true)
->distinct(true) // ->column('person_id');
->column('person_id'); // if ($person_id_arr) {
if ($person_id_arr) { // //根据校区id获取校区下的全部员工
//根据校区id获取校区下的全部员工 // $model = $model->whereIn('id', $person_id_arr);
$model = $model->whereIn('id', $person_id_arr); // }
} // }
} // }
} //
// if (empty($where['account_type'])) {
if (empty($where['account_type'])) { // $model = $model->where('account_type', $where['account_type']);
$model = $model->where('account_type', $where['account_type']); // }
} //
// if (!empty($where['campus'])) {
if (!empty($where['campus'])) { //// $model = $model->where('campus', $where['campus']);
// $model = $model->where('campus', $where['campus']); //
// $person_id_arr = CampusPersonRole::whereIn('campus_id', $where['campus'])
$person_id_arr = CampusPersonRole::whereIn('campus_id', $where['campus']) // ->distinct(true)
->distinct(true) // ->where(['dept_id' => 3])
->where(['dept_id' => 3]) // ->column('person_id');
->column('person_id'); //
// if ($person_id_arr) {
if ($person_id_arr) { // //根据校区id获取校区下的全部员工
//根据校区id获取校区下的全部员工 // $model = $model->whereIn('id', $person_id_arr);
$model = $model->whereIn('id', $person_id_arr); // }
} //
// }
}
$res = $model->field($field) $res = $model->field($field)
@ -573,4 +572,160 @@ class PersonnelService extends BaseApiService
return $prefix . $date . str_pad($sequence, 4, '0', STR_PAD_LEFT); return $prefix . $date . str_pad($sequence, 4, '0', STR_PAD_LEFT);
} }
/**
* 获取教练数据列表
* @return array
*/
public function getCoachList()
{
$res = [
'code' => 0,
'msg' => '获取教练列表失败',
'data' => []
];
try {
// 查询dept_id=2的所有人员关系
$campusPersonRoles = CampusPersonRole::where('dept_id', 2)
->field('person_id')
->select()
->toArray();
if (empty($campusPersonRoles)) {
$res = [
'code' => 1,
'msg' => '暂无教练数据',
'data' => [
'coach_list' => [],
'education_list' => [],
'assistant_list' => []
]
];
return $res;
}
// 提取所有person_id
$personIds = array_unique(array_column($campusPersonRoles, 'person_id'));
// 根据person_id查询Personnel表获取姓名、头像、手机号
$personnelList = $this->model
->whereIn('id', $personIds)
->field('id as person_id, name, head_img, phone')
->select()
->toArray();
if (empty($personnelList)) {
$res = [
'code' => 1,
'msg' => '暂无教练数据',
'data' => [
'coach_list' => [],
'education_list' => [],
'assistant_list' => []
]
];
return $res;
}
// 查询每个人员的具体角色信息
$coachList = [];
$educationList = [];
$assistantList = [];
foreach ($personnelList as $personnel) {
// 查询该人员的角色信息
$roles = CampusPersonRole::where('person_id', $personnel['person_id'])
->where('dept_id', 2)
->with(['sysRole' => function ($query) {
$query->field('role_id, role_name, role_key');
}])
->select()
->toArray();
$roleNames = [];
$roleKeys = [];
foreach ($roles as $role) {
if (!empty($role['sys_role'])) {
$roleNames[] = $role['sys_role']['role_name'];
$roleKeys[] = $role['sys_role']['role_key'];
}
}
$roleNameStr = implode(',', $roleNames);
$roleKeyStr = implode(',', $roleKeys);
// 根据角色名称分类
$personnelData = [
'id' => $personnel['person_id'],
'person_id' => $personnel['person_id'], // 确保person_id字段存在
'name' => $personnel['name'],
'head_img' => $personnel['head_img'],
'phone' => $personnel['phone'],
'role_names' => $roleNameStr,
'role_keys' => $roleKeyStr
];
// 根据角色进行分类 - 使用更灵活的匹配规则
$isCoach = false;
$isEducation = false;
$isAssistant = false;
// 检查是否为教练类角色
if (stripos($roleNameStr, '教练') !== false ||
stripos($roleNameStr, '教师') !== false ||
stripos($roleNameStr, '主教') !== false ||
stripos($roleKeyStr, 'coach') !== false ||
stripos($roleKeyStr, 'teacher') !== false) {
$isCoach = true;
}
// 检查是否为教务类角色
if (stripos($roleNameStr, '教务') !== false ||
stripos($roleKeyStr, 'education') !== false ||
stripos($roleKeyStr, 'academic') !== false) {
$isEducation = true;
}
// 检查是否为助教类角色
if (stripos($roleNameStr, '助教') !== false ||
stripos($roleNameStr, '助理') !== false ||
stripos($roleKeyStr, 'assistant') !== false) {
$isAssistant = true;
}
// 如果没有明确的角色分类,则作为通用人员添加到所有列表
if (!$isCoach && !$isEducation && !$isAssistant) {
$isCoach = $isEducation = $isAssistant = true;
}
// 根据分类结果添加到对应列表
if ($isCoach) {
$coachList[] = $personnelData;
}
if ($isEducation) {
$educationList[] = $personnelData;
}
if ($isAssistant) {
$assistantList[] = $personnelData;
}
}
$res = [
'code' => 1,
'msg' => '获取成功',
'data' => [
'coach_list' => $coachList,
'education_list' => $educationList,
'assistant_list' => $assistantList,
'all_personnel' => $personnelList // 返回所有人员数据,前端可以根据需要自行分类
]
];
} catch (\Exception $e) {
$res['msg'] = '获取教练列表异常:' . $e->getMessage();
}
return $res;
}
} }

8
uniapp/api/apiRoute.js

@ -33,6 +33,10 @@ export default {
async common_getPersonnelAll(data = {}) { async common_getPersonnelAll(data = {}) {
return await http.get('/personnel/getPersonnelAll', data); return await http.get('/personnel/getPersonnelAll', data);
}, },
//公共端-获取教练数据列表
async common_getCoachList(data = {}) {
return await http.get('/personnel/getCoachList', data);
},
//公共端-获取全部课程列表 //公共端-获取全部课程列表
async common_getCourseAll(data = {}) { async common_getCourseAll(data = {}) {
return await http.get('/common/getCourseAll', data); return await http.get('/common/getCourseAll', data);
@ -206,6 +210,10 @@ export default {
async xs_communicationRecordsAdd(data = {}) { async xs_communicationRecordsAdd(data = {}) {
return await http.post('/communicationRecords/add', data); return await http.post('/communicationRecords/add', data);
}, },
//销售端-沟通记录-编辑
async xs_communicationRecordsEdit(data = {}) {
return await http.post('/communicationRecords/edit', data);
},
//销售端-获取好友关系绑定详情 //销售端-获取好友关系绑定详情
async xs_chatGetChatFriendsInfo(data = {}) { async xs_chatGetChatFriendsInfo(data = {}) {
return await http.get('/chat/getChatFriendsInfo', data); return await http.get('/chat/getChatFriendsInfo', data);

109
uniapp/common/util.js

@ -226,63 +226,102 @@ function loginOut() {
}) })
} }
// 全局内存字典缓存
// 使用模块级的变量保存缓存,在整个应用生命周期内都有效
const dictMemoryCache = {};
/** /**
* 获取字典值带1小时缓存 * 获取字典值内存和存储双重缓存
* @param {String} dictKey 字典key * @param {String} dictKey 字典key
* @returns {Promise<Array|Object>} * @returns {Promise<Array|Object>}
*/ */
async function getDict(dictKey) { async function getDict(dictKey) {
console.log(`util.getDict - 开始获取字典: ${dictKey}`); console.log(`getDict - 开始获取字典: ${dictKey}`);
const cacheKey = `dict_${dictKey}`; // 先从内存缓存中获取
const cache = uni.getStorageSync(cacheKey);
const now = Date.now(); const now = Date.now();
if (dictMemoryCache[dictKey] && dictMemoryCache[dictKey].expire > now) {
console.log(`getDict - 使用内存缓存: ${dictKey}`);
return dictMemoryCache[dictKey].data;
}
// 检查缓存是否有效 // 内存缓存不存在或已过期,尝试从存储中获取
if (cache && cache.data && cache.expire > now) { const cacheKey = `dict_${dictKey}`;
console.log(`util.getDict - 使用缓存数据: ${dictKey}, 数据条数: ${cache.data.length}`); try {
return cache.data; const storageCache = uni.getStorageSync(cacheKey);
if (storageCache && storageCache.data && storageCache.expire > now) {
console.log(`getDict - 使用存储缓存: ${dictKey}`);
// 更新内存缓存
dictMemoryCache[dictKey] = storageCache;
return storageCache.data;
}
} catch (e) {
console.error(`getDict - 读取存储缓存异常: ${dictKey}`, e);
} }
console.log(`util.getDict - 缓存无效,请求接口: ${dictKey}`); console.log(`getDict - 缓存无效,请求接口: ${dictKey}`);
// 缓存无效,请求接口 // 缓存不存在或已过期,从服务器获取
try { try {
console.log(`util.getDict - 调用API: common_Dictionary, key=${dictKey}`); // 添加超时处理和重试机制
let retryCount = 0;
// 添加超时处理 const maxRetries = 2;
const timeoutPromise = new Promise((_, reject) => { const fetchWithRetry = async () => {
setTimeout(() => reject(new Error(`字典加载超时: ${dictKey}`)), 3000); try {
}); // 超时控制
const timeoutPromise = new Promise((_, reject) => {
// 实际API请求 setTimeout(() => reject(new Error(`字典请求超时: ${dictKey}`)), 3000);
const apiPromise = marketApi.common_Dictionary({ key: dictKey }); });
// 使用Promise.race来实现超时控制 // 实际API请求
const res = await Promise.race([apiPromise, timeoutPromise]); const apiPromise = marketApi.common_Dictionary({ key: dictKey });
// 使用Promise.race来实现超时控制
return await Promise.race([apiPromise, timeoutPromise]);
} catch (error) {
if (retryCount < maxRetries) {
retryCount++;
console.log(`getDict - 重试第${retryCount}次: ${dictKey}`);
return await fetchWithRetry();
}
throw error;
}
};
console.log(`util.getDict - API响应:`, res); const res = await fetchWithRetry();
if (res && res.code === 1) { if (res && res.code === 1) {
// 处理接口返回的数据,确保返回格式一致 // 处理接口返回的数据
// 接口返回的是 [{name: "抖音", value: "1", sort: 0, memo: ""}, ...]
const formattedData = Array.isArray(res.data) ? res.data : []; const formattedData = Array.isArray(res.data) ? res.data : [];
console.log(`util.getDict - 保存缓存: ${dictKey}, 数据条数: ${formattedData.length}`); if (formattedData.length > 0) {
uni.setStorageSync(cacheKey, { // 设置缓存过期时间,默认1小时
data: formattedData, const cacheData = {
expire: now + 3600 * 1000 data: formattedData,
}); expire: now + 3600 * 1000
console.log(`util.getDict - 字典获取成功: ${dictKey}`); };
// 同时更新内存缓存和存储缓存
dictMemoryCache[dictKey] = cacheData;
try {
uni.setStorageSync(cacheKey, cacheData);
} catch (e) {
console.error(`getDict - 存储缓存异常: ${dictKey}`, e);
}
console.log(`getDict - 字典获取成功: ${dictKey}, 条数: ${formattedData.length}`);
} else {
console.warn(`getDict - 字典数据为空: ${dictKey}`);
}
return formattedData; return formattedData;
} else { } else {
console.error(`util.getDict - API请求失败: ${dictKey}`, res); console.error(`getDict - API请求失败: ${dictKey}`, res);
// 返回空数组而不是抛出异常,避免阻塞流程
return []; return [];
} }
} catch (error) { } catch (error) {
console.error(`util.getDict - 异常: ${dictKey}`, error); console.error(`getDict - 异常: ${dictKey}`, error);
// 返回空数组,避免阻塞流程
return []; return [];
} }
} }

147
uniapp/pages/coach/course/info_list.vue

@ -146,11 +146,32 @@
</view> </view>
</view> </view>
<fui-picker :options="StudentList" :linkage="true" :show="show" :layer="1" @change="change" <fui-modal :show="show" title="选择学员" @click="handleModalClick" :buttons="[]" @cancel="cancel">
<view class="student-list">
<view class="student-item" v-for="(item, index) in StudentList" :key="index" @click="change(item)">
<view class="student-info">
<view class="student-name">{{item.text}}</view>
<view class="student-details">
<text>年龄: {{item.age || '未知'}}</text>
<text>来源: {{item.source || '未知'}}</text>
<text>渠道: {{item.source_channel || '未知'}}</text>
</view>
</view>
</view>
<view class="empty-list" v-if="StudentList.length === 0">
<text>暂无可添加的学员</text>
</view>
</view>
</fui-modal>
<fui-picker :options="StudentList" :linkage="false" :show="false" :layer="1" @change="change"
@cancel="cancel"></fui-picker> @cancel="cancel"></fui-picker>
<fui-actionsheet :show="written_show" :tips="written_tips" :isCancel="isCancel" <fui-actionsheet :show="written_show" :tips="written_tips" :isCancel="isCancel"
:itemList="itemList" @cancel="written_cancel" @click="written_click"></fui-actionsheet> :itemList="itemList" @cancel="written_cancel" @click="written_click"></fui-actionsheet>
<uni-popup ref="popup" type="center">
<view class="popup-content">{{ tipContent }}</view>
</uni-popup>
<AQTabber />
</view> </view>
</template> </template>
@ -315,41 +336,27 @@
}) })
return return
} else { } else {
//
this.show = true this.show = true
} }
// 使
// this.StudentList = [
// {
// text: '',
// value: '1001'
// },
// {
// text: '',
// value: '1002'
// },
// {
// text: '',
// value: '1003'
// },
// {
// text: '',
// value: '1004'
// },
// {
// text: '',
// value: '1005'
// }
// ];
// this.show = true;
}, },
async change(e) { //
handleModalClick(e) {
//
console.log('模态框点击事件', e)
},
async change(student) {
this.show = false this.show = false
// student_idresource_id
let studentId = student.value
let resourceId = student.resource_id
let res = await apiRoute.addStudent({ let res = await apiRoute.addStudent({
student_id: e.value, student_id: studentId,
schedule_id: this.course_id, schedule_id: this.course_id,
time_slot: this.courseInfo.time_slot, time_slot: this.courseInfo.time_slot,
course_date: this.courseInfo.course_date course_date: this.courseInfo.course_date,
resource_id: resourceId // resource_id
}) })
if (res.code != 1) { if (res.code != 1) {
uni.showToast({ uni.showToast({
@ -358,36 +365,14 @@
}) })
return return
} }
this.init()
// 使 uni.showToast({
// const selectedStudent = this.StudentList.find(student => student.value === e.value); title: '添加学员成功',
// if (!selectedStudent) return; icon: 'success'
})
// //
// if (!this.courseInfo.student_courses) {
// this.courseInfo.student_courses = [];
// }
// //
// const now = new Date();
// const futureDate = new Date();
// futureDate.setMonth(futureDate.getMonth() + 3); // 3
// //
// this.courseInfo.student_courses.push({
// student_id: e.value,
// name: selectedStudent.text,
// avatar: '', //
// start_date: now.toISOString().split('T')[0],
// end_date: futureDate.toISOString().split('T')[0],
// status: 'pending' //
// });
// uni.showToast({ //
// title: '', this.init()
// icon: 'success'
// });
}, },
cancel() { cancel() {
this.show = false this.show = false
@ -495,6 +480,54 @@
color: #fff; color: #fff;
} }
} }
/* 学员选择列表样式 */
.student-list {
max-height: 600rpx;
overflow-y: auto;
}
.student-item {
padding: 20rpx 30rpx;
border-bottom: 1px solid #eee;
background-color: #f8f8f8;
margin-bottom: 10rpx;
border-radius: 8rpx;
}
.student-item:active {
background-color: #e0e0e0;
}
.student-info {
display: flex;
flex-direction: column;
}
.student-name {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
}
.student-details {
display: flex;
flex-direction: column;
font-size: 24rpx;
color: #666;
}
.student-details text {
margin-bottom: 6rpx;
}
.empty-list {
padding: 40rpx;
text-align: center;
color: #999;
font-size: 28rpx;
}
.main_section { .main_section {
min-height: 100vh; min-height: 100vh;

244
uniapp/pages/market/clue/clue_info.vue

@ -194,7 +194,7 @@
size="mini" size="mini"
class="remark-btn" class="remark-btn"
@click="openAddRemark(v)"> @click="openAddRemark(v)">
添加备注 {{v.remarks ? '修改备注' : '添加备注'}}
</button> </button>
</view> </view>
<view class="call-remark"> <view class="call-remark">
@ -218,7 +218,7 @@
<uni-popup ref="remarkPopup" type="dialog"> <uni-popup ref="remarkPopup" type="dialog">
<view class="custom-popup-dialog"> <view class="custom-popup-dialog">
<view class="dialog-header"> <view class="dialog-header">
<text class="dialog-title">通话备注</text> <text class="dialog-title">{{currentRecord && currentRecord.remarks ? '修改备注' : '添加备注'}}</text>
</view> </view>
<view class="dialog-content"> <view class="dialog-content">
<view class="remark-textarea-container"> <view class="remark-textarea-container">
@ -248,45 +248,48 @@
<view class="course-edit-container"> <view class="course-edit-container">
<view class="edit-section"> <view class="edit-section">
<view class="section-title">主教练单选</view> <view class="section-title">主教练单选</view>
<view v-if="coachList.length === 0" class="empty-tip">暂无主教练数据</view>
<view class="coach-list"> <view class="coach-list">
<view <view
v-for="coach in coachList" v-for="coach in coachList"
:key="coach.id" :key="coach.person_id"
class="coach-item" class="coach-item"
:class="{selected: selectedMainCoach === coach.id}" :class="{selected: selectedMainCoach === coach.person_id}"
@click="selectMainCoach(coach.id)"> @click="selectMainCoach(coach.person_id)">
<view class="coach-name">{{ coach.name }}</view> <view class="coach-name">{{ coach.name }}</view>
<view class="coach-check" v-if="selectedMainCoach === coach.id"></view> <view class="coach-check" v-if="selectedMainCoach === coach.person_id"></view>
</view> </view>
</view> </view>
</view> </view>
<view class="edit-section"> <view class="edit-section">
<view class="section-title">教务单选</view> <view class="section-title">教务单选</view>
<view v-if="educationList.length === 0" class="empty-tip">暂无教务数据</view>
<view class="coach-list"> <view class="coach-list">
<view <view
v-for="education in educationList" v-for="education in educationList"
:key="education.id" :key="education.person_id"
class="coach-item" class="coach-item"
:class="{selected: selectedEducation === education.id}" :class="{selected: selectedEducation === education.person_id}"
@click="selectEducation(education.id)"> @click="selectEducation(education.person_id)">
<view class="coach-name">{{ education.name }}</view> <view class="coach-name">{{ education.name }}</view>
<view class="coach-check" v-if="selectedEducation === education.id"></view> <view class="coach-check" v-if="selectedEducation === education.person_id"></view>
</view> </view>
</view> </view>
</view> </view>
<view class="edit-section"> <view class="edit-section">
<view class="section-title">助教多选</view> <view class="section-title">助教多选</view>
<view v-if="assistantList.length === 0" class="empty-tip">暂无助教数据</view>
<view class="coach-list"> <view class="coach-list">
<view <view
v-for="assistant in assistantList" v-for="assistant in assistantList"
:key="assistant.id" :key="assistant.person_id"
class="coach-item" class="coach-item"
:class="{selected: selectedAssistants.includes(assistant.id)}" :class="{selected: selectedAssistants.includes(assistant.person_id)}"
@click="toggleAssistant(assistant.id)"> @click="toggleAssistant(assistant.person_id)">
<view class="coach-name">{{ assistant.name }}</view> <view class="coach-name">{{ assistant.name }}</view>
<view class="coach-check" v-if="selectedAssistants.includes(assistant.id)"></view> <view class="coach-check" v-if="selectedAssistants.includes(assistant.person_id)"></view>
</view> </view>
</view> </view>
</view> </view>
@ -621,7 +624,7 @@
// //
openAddRemark(record) { openAddRemark(record) {
this.remark_content = ''; this.remark_content = record.remarks || ''; //
this.currentRecord = record; this.currentRecord = record;
this.$refs.remarkPopup.open(); this.$refs.remarkPopup.open();
}, },
@ -636,50 +639,52 @@
return; return;
} }
//
if (!this.currentRecord || !this.currentRecord.id) {
uni.showToast({
title: '未选中通话记录',
icon: 'none'
});
return;
}
try { try {
uni.showLoading({ uni.showLoading({
title: '提交中...', title: '提交中...',
mask: true mask: true
}); });
// 使
const params = { const params = {
staff_id: this.userInfo.id, // id id: this.currentRecord.id, // ID
resource_id: this.clientInfo.resource_id, // ID remarks: this.remark_content //
resource_type: '', //
communication_type: 'note', // : phone-, note-
communication_result: 'success', //
remarks: this.remark_content, //
tag: null //
}; };
// ID console.log('更新通话记录备注:', params);
if (this.currentRecord && this.currentRecord.id) {
params.related_record_id = this.currentRecord.id; // ID
console.log('添加备注到通话记录:', this.currentRecord);
}
const res = await apiRoute.xs_communicationRecordsAdd(params); //
const res = await apiRoute.xs_communicationRecordsEdit(params);
if (res.code !== 1) { if (res.code !== 1) {
uni.showToast({ uni.showToast({
title: res.msg || '添加备注失败', title: res.msg || '更新备注失败',
icon: 'none' icon: 'none'
}); });
return; return;
} }
uni.showToast({ uni.showToast({
title: '添加备注成功', title: '备注更新成功',
icon: 'success' icon: 'success'
}); });
// //
this.getListCallUp(); await this.getListCallUp();
} catch (error) { } catch (error) {
console.error('添加备注失败:', error); console.error('更新备注失败:', error);
uni.showToast({ uni.showToast({
title: '添加备注失败,请重试', title: '更新备注失败,请重试',
icon: 'none' icon: 'none'
}); });
} finally { } finally {
@ -820,61 +825,67 @@
// //
async getPersonnelList() { async getPersonnelList() {
try { try {
// 使API console.log('getPersonnelList - 开始获取教练数据');
try {
const res = await apiRoute.getPersonnelList(); uni.showLoading({
if (res.code === 1 && res.data) { title: '获取教练数据...'
const personnel = res.data || []; });
// - const res = await apiRoute.common_getCoachList();
this.coachList = personnel.filter(p => { console.log('getPersonnelList - API响应:', res);
return p.role_name && (
p.role_name.includes('教练') || uni.hideLoading();
p.role_name.includes('教师') ||
(p.roles && p.roles.some(role => role.includes('教练') || role.includes('教师'))) if (res.code === 1 && res.data) {
); // 使
}); this.coachList = res.data.coach_list || [];
this.educationList = res.data.education_list || [];
this.educationList = personnel.filter(p => { this.assistantList = res.data.assistant_list || [];
return p.role_name && (
p.role_name.includes('教务') || console.log('getPersonnelList - 教练数据获取成功');
(p.roles && p.roles.some(role => role.includes('教务'))) console.log('教练列表:', this.coachList);
); console.log('教务列表:', this.educationList);
}); console.log('助教列表:', this.assistantList);
return true;
this.assistantList = personnel.filter(p => { } else {
return p.role_name && ( console.warn('API返回错误:', res);
p.role_name.includes('助教') ||
(p.roles && p.roles.some(role => role.includes('助教'))) // API
); uni.showToast({
}); title: res.msg || '获取教练数据失败',
icon: 'none'
console.log('getPersonnelList - 人员列表获取成功'); });
console.log('教练列表:', this.coachList);
console.log('教务列表:', this.educationList);
console.log('助教列表:', this.assistantList);
return true;
} else {
console.warn('API返回错误:', res.msg);
throw new Error(res.msg);
}
} catch (apiError) {
console.warn('使用API获取人员列表失败,使用模拟数据:', apiError);
// API使 // API使
this.coachList = this.getMockCoachList(); this.coachList = this.getMockCoachList();
this.educationList = this.getMockEducationList(); this.educationList = this.getMockEducationList();
this.assistantList = this.getMockAssistantList(); this.assistantList = this.getMockAssistantList();
console.log('getPersonnelList - 使用模拟人员数据'); console.log('getPersonnelList - 使用模拟教练数据');
console.log('模拟教练列表:', this.coachList);
console.log('模拟教务列表:', this.educationList);
console.log('模拟助教列表:', this.assistantList);
return true; return true;
} }
} catch (error) { } catch (error) {
console.error('getPersonnelList - 获取人员列表异常:', error); console.error('getPersonnelList - 获取教练列表异常:', error);
uni.hideLoading();
//
uni.showToast({
title: '网络错误,使用模拟数据',
icon: 'none'
});
// //
this.coachList = this.getMockCoachList(); this.coachList = this.getMockCoachList();
this.educationList = this.getMockEducationList(); this.educationList = this.getMockEducationList();
this.assistantList = this.getMockAssistantList(); this.assistantList = this.getMockAssistantList();
console.log('getPersonnelList - 使用模拟教练数据(异常情况)');
console.log('模拟教练列表:', this.coachList);
console.log('模拟教务列表:', this.educationList);
console.log('模拟助教列表:', this.assistantList);
return false; return false;
} }
}, },
@ -882,60 +893,86 @@
// //
getMockCoachList() { getMockCoachList() {
return [ return [
{ id: 1, name: '张教练' }, { id: 1, person_id: 1, name: '张教练', head_img: '', phone: '' },
{ id: 5, name: '陈教练' }, { id: 5, person_id: 5, name: '陈教练', head_img: '', phone: '' },
{ id: 7, name: '刘教练' } { id: 7, person_id: 7, name: '刘教练', head_img: '', phone: '' }
]; ];
}, },
// //
getMockEducationList() { getMockEducationList() {
return [ return [
{ id: 2, name: '李教务' }, { id: 2, person_id: 2, name: '李教务', head_img: '', phone: '' },
{ id: 8, name: '周教务' } { id: 8, person_id: 8, name: '周教务', head_img: '', phone: '' }
]; ];
}, },
// //
getMockAssistantList() { getMockAssistantList() {
return [ return [
{ id: 3, name: '王助教' }, { id: 3, person_id: 3, name: '王助教', head_img: '', phone: '' },
{ id: 4, name: '赵助教' }, { id: 4, person_id: 4, name: '赵助教', head_img: '', phone: '' },
{ id: 6, name: '孙助教' }, { id: 6, person_id: 6, name: '孙助教', head_img: '', phone: '' },
{ id: 9, name: '钱助教' } { id: 9, person_id: 9, name: '钱助教', head_img: '', phone: '' }
]; ];
}, },
// //
openCourseEditDialog(course) { async openCourseEditDialog(course) {
this.currentCourse = course; this.currentCourse = course;
// //
console.log('打开教练配置弹窗,检查教练数据:', {
coachList: this.coachList,
educationList: this.educationList,
assistantList: this.assistantList
});
//
if (!this.coachList.length && !this.educationList.length && !this.assistantList.length) {
console.log('教练数据为空,重新获取...');
await this.getPersonnelList();
}
// 使person_id
this.selectedMainCoach = course.main_coach_id; this.selectedMainCoach = course.main_coach_id;
this.selectedEducation = course.education_id; this.selectedEducation = course.education_id;
this.selectedAssistants = course.assistant_ids ? course.assistant_ids.split(',').map(Number) : []; this.selectedAssistants = course.assistant_ids ? course.assistant_ids.split(',').map(Number) : [];
console.log('打开教练配置弹窗:', {
course: course,
selectedMainCoach: this.selectedMainCoach,
selectedEducation: this.selectedEducation,
selectedAssistants: this.selectedAssistants,
coachListLength: this.coachList.length,
educationListLength: this.educationList.length,
assistantListLength: this.assistantList.length
});
this.$refs.courseEditPopup.open(); this.$refs.courseEditPopup.open();
}, },
// //
selectMainCoach(coachId) { selectMainCoach(personId) {
this.selectedMainCoach = coachId; this.selectedMainCoach = personId;
console.log('选择主教练:', personId);
}, },
// //
selectEducation(educationId) { selectEducation(personId) {
this.selectedEducation = educationId; this.selectedEducation = personId;
console.log('选择教务:', personId);
}, },
// //
toggleAssistant(assistantId) { toggleAssistant(personId) {
const index = this.selectedAssistants.indexOf(assistantId); const index = this.selectedAssistants.indexOf(personId);
if (index > -1) { if (index > -1) {
this.selectedAssistants.splice(index, 1); this.selectedAssistants.splice(index, 1);
} else { } else {
this.selectedAssistants.push(assistantId); this.selectedAssistants.push(personId);
} }
console.log('切换助教选择:', personId, '当前选中:', this.selectedAssistants);
}, },
// //
@ -948,9 +985,9 @@
const params = { const params = {
student_course_id: this.currentCourse.id, student_course_id: this.currentCourse.id,
main_coach_id: this.selectedMainCoach, main_coach_id: this.selectedMainCoach, // 使person_id
education_id: this.selectedEducation, education_id: this.selectedEducation, // 使person_id
assistant_ids: this.selectedAssistants.join(',') assistant_ids: this.selectedAssistants.join(',') // 使person_id
}; };
console.log('准备保存教练配置:', params); console.log('准备保存教练配置:', params);
@ -981,22 +1018,22 @@
const courseIndex = this.courseInfo.findIndex(c => c.id === this.currentCourse.id); const courseIndex = this.courseInfo.findIndex(c => c.id === this.currentCourse.id);
if (courseIndex > -1) { if (courseIndex > -1) {
// //
const mainCoach = this.coachList.find(c => c.id === this.selectedMainCoach); const mainCoach = this.coachList.find(c => c.person_id === this.selectedMainCoach);
if (mainCoach) { if (mainCoach) {
this.courseInfo[courseIndex].main_coach_id = this.selectedMainCoach; this.courseInfo[courseIndex].main_coach_id = this.selectedMainCoach;
this.courseInfo[courseIndex].main_coach_name = mainCoach.name; this.courseInfo[courseIndex].main_coach_name = mainCoach.name;
} }
// //
const education = this.educationList.find(e => e.id === this.selectedEducation); const education = this.educationList.find(e => e.person_id === this.selectedEducation);
if (education) { if (education) {
this.courseInfo[courseIndex].education_id = this.selectedEducation; this.courseInfo[courseIndex].education_id = this.selectedEducation;
this.courseInfo[courseIndex].education_name = education.name; this.courseInfo[courseIndex].education_name = education.name;
} }
// //
const assistantNames = this.selectedAssistants.map(id => { const assistantNames = this.selectedAssistants.map(personId => {
const assistant = this.assistantList.find(a => a.id === id); const assistant = this.assistantList.find(a => a.person_id === personId);
return assistant ? assistant.name : ''; return assistant ? assistant.name : '';
}).filter(name => name).join(', '); }).filter(name => name).join(', ');
@ -1754,4 +1791,11 @@
width: 40rpx; width: 40rpx;
text-align: center; text-align: center;
} }
.empty-tip {
color: #999;
font-size: 28rpx;
text-align: center;
padding: 40rpx 0;
}
</style> </style>

8
uniapp/pages/student/login/login.vue

@ -72,14 +72,14 @@
value: '3', value: '3',
text: '销售登陆' text: '销售登陆'
}, },
{
value: '2',
text: '教务登陆'
},
{ {
value: '4', value: '4',
text: '学员登陆' text: '学员登陆'
}, },
{
value: '5',
text: '教务登陆'
}
], ],
picker_show_loginType: false, // picker_show_loginType: false, //

Loading…
Cancel
Save