0, 'msg' => '操作失败', 'data' => [] ]; $model = new CustomerResources(); if (!empty($where['member_id'])) { $model = $model->where('member_id', $where['member_id']); } if (!empty($where['phone_number'])) { $model = $model->where('phone_number', $where['phone_number']); } $data = $model->field($field) ->with([ 'memberHasOne', 'resourceSharingHasMany' ]) ->append([ 'gender_name', 'initial_intent_name' ]) ->find(); if ($data) { $data = $data->toArray(); $res['code'] = 1; $res['data'] = $data; } else { $res['msg'] = '暂无数据'; } return $res; } //获取全部客户资源数据 public function getAll(array $where, string $field = '*') { $res = [ 'code' => 0, 'msg' => '操作失败', 'data' => [] ]; if (!$where) { $res['msg'] = '查询条件不能为空'; return $res; } $model = new CustomerResources(); if (!empty($where['name'])) { $model = $model->where('name', 'like', "%{$where['name']}%"); } if(!empty($where['phone_number'])){ $model = $model->where('phone_number', 'like', "%{$where['phone_number']}%"); } $data = $model->field($field) ->with([ 'resourceSharingHasMany' ]) ->append([ 'initial_intent_name', ]) ->select()->toArray(); if (!$data) { $res['msg'] = '暂无数据'; return $res; } $res['code'] = 1; $res['msg'] = '操作成功'; $res['data'] = $data; return $res; } //添加数据 public function addData(array $customer_resources_data, array $six_speed_data, array $student_data = [], $staff_id = 0, $role_id = 0) { $date = date('Y-m-d H:i:s'); $customer_resources_data['updated_at'] = $date; $six_speed_data['updated_at'] = $date; $res = [ 'code' => 0, 'msg' => '操作失败' ]; //开启事物 Db::startTrans(); try { $resource_id = CustomerResources::insertGetId($customer_resources_data);//客户资源表 if (!$resource_id) { Db::rollback(); return $res; } $six_speed_data['resource_id'] = $resource_id; $sixSpeedAdd = SixSpeed::create($six_speed_data); if (!$sixSpeedAdd) { Db::rollback(); return $res; } // 资源共享表新增记录 - 使用传入的staff_id和role_id $resourceSharing = new ResourceSharing(); $resourceSharing->insert([ 'resource_id' => $resource_id, 'user_id' => $staff_id, // 使用传入的登录人staff_id 'role_id' => $role_id // 使用传入的登录人role_id ]); // 转介绍奖励逻辑:当source=3且有referral_resource_id时发放奖励 if ($customer_resources_data['source'] == '3' && !empty($customer_resources_data['referral_resource_id'])) { $this->grantReferralReward($customer_resources_data['referral_resource_id'], $resource_id); } // 添加school_student表记录 if (!empty($student_data)) { $student_data['user_id'] = $resource_id; // 设置user_id为新添加的客户资源ID $student_data['updated_at'] = $date; $student_data['created_at'] = $date; $studentAdd = SchoolStudent::create($student_data); if (!$studentAdd) { Db::rollback(); $res['msg'] = '添加学员记录失败'; return $res; } } Db::commit(); $res = [ 'code' => 1, 'msg' => '操作成功' ]; $event_data = [ 'customer_resources_id' => $resource_id,//客户资源表id 'event_type' => 'add'//事件类型"add=添加,edit=修改 ];//事件类型"add=添加,edit=修改 Event::trigger('CalculatePerformance', $event_data, true); return $res; } catch (\Exception $exception) { Db::rollback(); $res['msg'] = $exception->getMessage(); return $res; } } //客户资源-编辑 public function editData(array $where, array $customer_resources_data, array $six_speed_data) { $operator_id = $this->member_id;//当前登录用户的id(日志操作人的id) $campus_id = 0;//日志操作人校区的id $campus_id_arr = CampusPersonRole::where('person_id', $operator_id)->column('campus_id'); if (count($campus_id_arr)) { if (count($campus_id_arr) > 1) { $campus_id = 0; } else { $campus_id = $campus_id_arr[0]; } } $res = [ 'code' => 0, 'msg' => '操作失败', 'data' => [] ]; if (!$where) { $res['msg'] = '查询条件不能为空'; return $res; } $date = date('Y-m-d H:i:s'); $customer_resources_data['updated_at'] = $date; $six_speed_data['updated_at'] = $date; try { $customer_resources = CustomerResources::where('id', $where['id'])->find(); $six_speed = SixSpeed::where('resource_id', $where['id'])->find(); if ($customer_resources) { $customer_resources = $customer_resources->toArray(); if (!$customer_resources['member_id'] && $six_speed) { $sex = 0; switch ($customer_resources_data['gender']) { case 'male'://男 $sex = 1; break; case 'female'://女 $sex = 2; break; default://其他 $sex = 0; break; } $password = create_password($customer_resources_data['phone_number']);//创建密码 //开启事物 // Db::startTrans(); //给用户创建member账号 $member_id = Member::insertGetId([ 'username' => $customer_resources_data['phone_number'],//会员用户名 'mobile' => $customer_resources_data['phone_number'],//手机号 'password' => $password,//会员密码 'nickname' => $customer_resources_data['name'],//会员昵称 'sex' => $sex,//性别 0保密 1男 2女 'member_time' => time(),//成为会员时间 ]); if ($member_id) { $customer_resources_data['member_id'] = $member_id; } else { Db::rollback(); $res['msg'] = '创建用户账号失败'; return $res; } } } $update_1 = CustomerResources::where('id', $where['id'])->update($customer_resources_data);//客户资源表 if (!$update_1) { // Db::rollback(); return $res; } //更近客户资源日志表 $compareData = (new CommonService)->compareData($customer_resources, $customer_resources_data); if ($compareData['changed_fields']) { $data = [ "customer_resource_id" => $where['id'],//客户资源的ID "operator_id" => $operator_id,//操作人的ID "campus_id" => $campus_id,//操作人校区的ID|如果这人有2校区就填0 "modified_fields" => $compareData['changed_fields_json'],//修改的哪些字段 "old_values" => $compareData['old_values_json'],//修改前的值 "new_values" => $compareData['new_values_json'],//修改后的值 ]; $id = CustomerResourceChanges::insertGetId($data); if (!$id) { // Db::rollback(); return $res; } } $six_speed_data['resource_id'] = $where['id']; //查六要素是否存在 if ($six_speed) { $six_speed = $six_speed->toArray(); //更新六要素 $sixSpeedUpdate = SixSpeed::where('id', $six_speed['id'])->update($six_speed_data); if (!$sixSpeedUpdate) { // Db::rollback(); return $res; } //更近六要素日志表 $compareData = (new CommonService)->compareData($six_speed, $six_speed_data); if ($compareData['changed_fields']) { $data = [ "operator_id" => $operator_id,//操作人的ID "campus_id" => $campus_id,//操作人校区的ID|如果这人有2校区就填0 "customer_resource_id" => $where['id'],//客户资源的ID "modified_field" => $compareData['changed_fields_json'],//修改的哪些字段 "old_value" => $compareData['old_values_json'],//修改前的值 "new_value" => $compareData['new_values_json'],//修改后的值 ]; $id = SixSpeedModificationLog::insertGetId($data); if (!$id) { // Db::rollback(); return $res; } } } else { //创建六要素 $sixSpeedUpdate = SixSpeed::create($six_speed_data); if (!$sixSpeedUpdate) { // Db::rollback(); return $res; } } // Db::commit(); $res = [ 'code' => 1, 'msg' => '操作成功' ]; return $res; } catch (\Exception $exception) { Db::rollback(); dd($exception); Log::error(print_r($exception, true)); return $exception->getMessage(); } } //客户资源(学生个人资料)-编辑 public function editInfo(array $where, array $data) { $res = [ 'code' => 0, 'msg' => '操作失败', 'data' => [] ]; if (!$where) { $res['msg'] = '查询条件不能为空'; return $res; } $customer_resources_data = [ 'name' => $data['name'], // 姓名 'gender' => $data['gender'], // 性别(male:男, female:女) 'age' => $data['age'], // 年龄 'phone_number' => $data['phone_number'], // 手机号 ]; $date = date('Y-m-d H:i:s'); $customer_resources_data['updated_at'] = $date; //开启事物 Db::startTrans(); try { $customer_resources = CustomerResources::where('member_id', $where['member_id'])->find(); if ($customer_resources) { $customer_resources = $customer_resources->toArray(); } $update_1 = CustomerResources::where('id', $customer_resources['id'])->update($customer_resources_data);//客户资源表 if (!$update_1) { Db::rollback(); return $res; } //更新学生账户登录表 $member_data = [ 'username' => $data['phone_number'], 'mobile' => $data['phone_number'], 'update_time' => time() ]; if (!empty($data['headimg'])) { $member_data['headimg'] = $data['headimg']; } $update_member = Member::where('member_id', $where['member_id'])->update($member_data); if (!$update_member) { Db::rollback(); return $res; } //更近客户资源日志表 $compareData = (new CommonService)->compareData($customer_resources, $customer_resources_data); if ($compareData['changed_fields']) { $data = [ "customer_resource_id" => $customer_resources['id'],//客户资源的ID "operator_id" => 0,//操作人的ID "campus_id" => 0,//操作人校区的ID|如果这人有2校区就填0 "modified_fields" => $compareData['changed_fields_json'],//修改的哪些字段 "old_values" => $compareData['old_values_json'],//修改前的值 "new_values" => $compareData['new_values_json'],//修改后的值 ]; $id = CustomerResourceChanges::insertGetId($data); if (!$id) { Db::rollback(); return $res; } } Db::commit(); $res = [ 'code' => 1, 'msg' => '操作成功' ]; return $res; } catch (\Exception $exception) { Db::rollback(); return $res; } } //客户资源-获取客户资源修改记录列表 public function getCustomerResourceChangesEditLog(array $where) { $page_params = $this->getPageParam();//获取请求参数中的页码+分页数 $page = $page_params['page']; $limit = $page_params['limit']; //客户资源修改记录表 $data = CustomerResourceChanges::where('customer_resource_id', $where['customer_resource_id']) ->order('created_at', 'desc') ->with([ 'personnel' => function ($query) { } ]) ->paginate([ 'list_rows' => $limit, 'page' => $page, ]) ->toArray(); $fieldZhArr = CustomerResources::FieldZh;//字段中文映射常量 //需要获取字段与字典key的映射关系数组 $fieldDictArr = [ 'source_channel' => 'SourceChannel',//field=>dict_key(来源渠道) 'source' => 'source',//field=>dict_key(来源) 'gender' => 'zy_sex',//field=>dict_key(性别) 'purchasing_power' => 'customer_purchasing_power',//field=>dict_key(购买力) 'cognitive_idea' => 'cognitive_concept',//field=>dict_key(认知理念) 'initial_intent' => 'preliminarycustomerintention',//field=>dict_key(客户初步意向度) 'status' => 'kh_status',//field=>dict_key(客户状态) ]; $dict_arr = $this->getFieldDictionary($fieldDictArr);//字段与字典值列表的映射关系 $consultant_id_arr = []; foreach ($data['data'] as $v) { $modified_fields_arr = json_decode($v['modified_fields'], true); $old_values_arr = json_decode($v['old_values'], true); $new_values_arr = json_decode($v['new_values'], true); //判断有没有修改过"顾问"字段 if (in_array('consultant', $modified_fields_arr)) { $consultant_id_arr[] = $old_values_arr['consultant']; $consultant_id_arr[] = $new_values_arr['consultant']; } } $consultant_id_arr = array_unique($consultant_id_arr);//去重 $dict_arr['consultant'] = [];//获取员工信息列表 if ($consultant_id_arr) { $personnel = Personnel::whereIn('id', $consultant_id_arr)->field('id,name')->select()->toArray(); foreach ($personnel as $v) { $dict_arr['consultant'][] = [ "name" => $v['name'], "value" => $v['id'], "sort" => 0, "memo" => "", ]; } } $fieldDictKeyArr = array_keys($fieldDictArr); $list = []; foreach ($data['data'] as $v) { $modified_fields_arr = json_decode($v['modified_fields'], true); $old_values_arr = json_decode($v['old_values'], true); $new_values_arr = json_decode($v['new_values'], true); $update_arr = []; foreach ($modified_fields_arr as $m_v) { $old_value = $old_values_arr[$m_v] ?? ''; $new_value = $new_values_arr[$m_v] ?? ''; if (in_array($m_v, $fieldDictKeyArr)) { $dict = $dict_arr[$m_v]; foreach ($dict as $d_v) { if ($d_v['value'] == $old_value) { $old_value = $d_v['name']; } if ($d_v['value'] == $new_value) { $new_value = $d_v['name']; } } } //一些字典和外键相关的字段值处理 $update_arr[] = [ 'field_name_en' => $m_v, 'field_name_zh' => $fieldZhArr[$m_v] ?? $m_v, 'old_value' => $old_value, 'new_value' => $new_value, ]; } $list[] = [ 'id' => $v['id'],//日志id 'modification_time' => $v['modification_time'],//修改时间 'staff_id_name' => $v['staff_id_name'],//修改人的名字 'update_arr' => $update_arr,//数据变更数组 ]; } $data['data'] = $list; return $data; } //客户资源-获取六要素修改记录列表 public function getSixSpeedModificationEditLog(array $where) { $page_params = $this->getPageParam();//获取请求参数中的页码+分页数 $page = $page_params['page']; $limit = $page_params['limit']; //六要素修改记录表 $data = SixSpeedModificationLog::where('operator_id', $where['customer_resource_id']) ->order('created_at', 'desc') ->with([ 'personnel' => function ($query) { } ]) ->paginate([ 'list_rows' => $limit, 'page' => $page, ]) ->toArray(); $fieldZhArr = SixSpeed::FieldZh;//字段中文映射常量 //需要获取字段与字典key的映射关系数组 $fieldDictArr = [ 'purchase_power' => 'customer_purchasing_power',//field=>dict_key(需求购买力) 'concept_awareness' => 'cognitive_concept',//field=>dict_key(认知理念) 'call_intent' => 'preliminarycustomerintention',//field=>dict_key(电话后的意向程度) 'is_closed' => 'global_true_or_false',//field=>dict_key(是否关单: 1-是, 0-否) ]; $dict_arr = $this->getFieldDictionary($fieldDictArr);//字段与字典值列表的映射关系 $consultant_id_arr = [];//顾问(人员)id数组 foreach ($data['data'] as $v) { $modified_fields_arr = json_decode($v['modified_field'], true); $old_values_arr = json_decode($v['old_value'], true); $new_values_arr = json_decode($v['new_value'], true); //判断有没有修改过"顾问(人员)"字段 if (in_array('staff_id', $modified_fields_arr)) { $consultant_id_arr[] = $old_values_arr['staff_id']; $consultant_id_arr[] = $new_values_arr['staff_id']; } } $consultant_id_arr = array_unique($consultant_id_arr);//去重 $dict_arr['consultant'] = [];//获取员工信息列表 if ($consultant_id_arr) { $personnel = Personnel::whereIn('id', $consultant_id_arr)->field('id,name')->select()->toArray(); foreach ($personnel as $v) { $dict_arr['consultant'][] = [ "name" => $v['name'], "value" => $v['id'], "sort" => 0, "memo" => "", ]; } } $fieldDictKeyArr = array_keys($fieldDictArr); $list = []; foreach ($data['data'] as $v) { $modified_fields_arr = json_decode($v['modified_field'], true); $old_values_arr = json_decode($v['old_value'], true); $new_values_arr = json_decode($v['new_value'], true); $update_arr = []; foreach ($modified_fields_arr as $m_v) { $old_value = $old_values_arr[$m_v] ?? ''; $new_value = $new_values_arr[$m_v] ?? ''; if (in_array($m_v, $fieldDictKeyArr)) { $dict = $dict_arr[$m_v]; foreach ($dict as $d_v) { if ($d_v['value'] == $old_value) { $old_value = $d_v['name']; } if ($d_v['value'] == $new_value) { $new_value = $d_v['name']; } } } //一些字典和外键相关的字段值处理 $update_arr[] = [ 'field_name_en' => $m_v, 'field_name_zh' => $fieldZhArr[$m_v] ?? $m_v, 'old_value' => $old_value, 'new_value' => $new_value, ]; } $list[] = [ 'id' => $v['id'],//日志id 'modification_time' => $v['updated_at'],//修改时间 'staff_id_name' => $v['staff_id_name'],//修改人的名字 'update_arr' => $update_arr,//数据变更数组 ]; } $data['data'] = $list; return $data; } /** * 根据字段和字典键映射关系,获取字段对应字典项 * * @param array $fieldDictMapping 字段 => 字典 key 映射数组 * @return array 字段 => 字典列表 */ public function getFieldDictionary(array $fieldDictMapping): array { // 获取所有需要的字典 key 列表 $dictKeys = array_values($fieldDictMapping); if (empty($dictKeys)) { return []; } // 查询字典数据 - 使用正确的表名 $dictData = \think\facade\Db::table('school_sys_dict')->whereIn('key', $dictKeys)->select()->toArray(); //使用 array_column 构建 key => dict 的映射 $dictMap = array_column($dictData, null, 'key'); // 以 key 字段为索引 // 构建字段 => 字典项的映射 $result = []; foreach ($fieldDictMapping as $field => $key) { $dictionary = []; if (isset($dictMap[$key]['dictionary']) && !empty($dictMap[$key]['dictionary'])) { // 数据库中的字段是双层JSON编码,需要两次解码 $jsonString = json_decode($dictMap[$key]['dictionary'], true); if (is_string($jsonString)) { $dictionary = json_decode($jsonString, true) ?: []; } else { $dictionary = $jsonString ?: []; } } $result[$field] = $dictionary; //判断是不是获取的"来源渠道"的字典 if ($field == 'source_channel') { $append_arr = [ "name" => "线下", "value" => "0", "sort" => 0, "memo" => "", ]; //插入到数组头部 array_unshift($result[$field], $append_arr); } } return $result; } /** * 发放转介绍奖励 * @param int $referral_resource_id 推荐人资源ID * @param int $new_resource_id 新客户资源ID * @return void */ private function grantReferralReward($referral_resource_id, $new_resource_id) { try { // 查找推荐人信息 $referralResource = CustomerResources::where('id', $referral_resource_id)->find(); if (!$referralResource) { Log::error("转介绍奖励发放失败:推荐人资源不存在,ID: $referral_resource_id"); return; } // 奖励配置(可以后续移到配置文件中) $rewardConfig = [ 'gift_name' => '转介绍奖励', 'gift_type' => 'referral_reward', 'reward_amount' => 100, // 奖励金额,可配置 ]; // 插入奖励记录到shcool_resources_gift表 $giftData = [ 'gift_name' => $rewardConfig['gift_name'], 'gift_type' => $rewardConfig['gift_type'], 'gift_time' => time(), 'giver_id' => $new_resource_id, // 新客户作为赠送来源 'resource_id' => $referral_resource_id, // 推荐人作为接收者 'order_id' => 0, // 非订单相关奖励 'gift_status' => 1, // 已发放状态 'use_time' => 0, 'create_time' => time(), 'update_time' => time(), 'delete_time' => 0, ]; Db::table('shcool_resources_gift')->insert($giftData); Log::info("转介绍奖励发放成功:推荐人ID $referral_resource_id,新客户ID $new_resource_id"); } catch (\Exception $e) { Log::error("转介绍奖励发放异常:" . $e->getMessage()); } } public function updateUserCourseInfo($data) { // 验证必要参数 if (empty($data['id'])) { return ['code' => false, 'msg' => '缺少必要参数id']; } try { // 更新school_student_courses表中的字段 $update_data = []; // 更新主教练ID if (isset($data['main_coach_id'])) { $update_data['main_coach_id'] = $data['main_coach_id']; } // 更新助教IDs if (isset($data['assistant_ids'])) { $update_data['assistant_ids'] = $data['assistant_ids']; } // 更新教务ID if (isset($data['education_id'])) { $update_data['education_id'] = $data['education_id']; } // 如果没有需要更新的数据,直接返回成功 if (empty($update_data)) { return ['code' => true, 'msg' => '更新成功']; } // 执行更新操作 $res = \think\facade\Db::name('student_courses') ->where('id', $data['id']) ->update($update_data); if ($res !== false) { return ['code' => true, 'msg' => '更新成功']; } else { return ['code' => false, 'msg' => '更新失败']; } } catch (\Exception $e) { return ['code' => false, 'msg' => '更新失败:' . $e->getMessage()]; } } /** * 获取客户赠品记录列表 * @param array $where 查询条件 * @return array */ public function getGiftRecordList(array $where) { try { $resource_id = $where['resource_id'] ?? 0; if (empty($resource_id)) { return ['code' => false, 'msg' => '缺少客户资源ID']; } // 查询赠品记录,同时关联查询赠送人信息 $gift_records = Db::table('shcool_resources_gift') ->alias('g') ->leftJoin('customer_resources cr', 'g.giver_id = cr.id') ->where('g.resource_id', $resource_id) ->where('g.delete_time', 0) ->where('g.gift_status', 1) ->where('g.order_id', 0) ->field([ 'g.*', 'cr.name as giver_name', 'cr.phone_number as giver_phone' ]) ->order('g.create_time', 'desc') ->select() ->toArray(); // 处理数据格式 $formatted_records = []; foreach ($gift_records as $record) { $formatted_records[] = [ 'id' => $record['id'], 'gift_name' => $record['gift_name'], 'gift_type' => $record['gift_type'], 'gift_type_text' => $this->getGiftTypeText($record['gift_type']), 'gift_time' => $record['gift_time'], 'gift_time_formatted' => date('Y-m-d H:i:s', $record['gift_time']), 'giver_id' => $record['giver_id'], 'giver_name' => $record['giver_name'] ?: '系统赠送', 'giver_phone' => $record['giver_phone'] ?: '', 'order_id' => $record['order_id'], 'gift_status' => $record['gift_status'], 'gift_status_text' => $this->getGiftStatusText($record['gift_status']), 'use_time' => $record['use_time'], 'use_time_formatted' => $record['use_time'] ? date('Y-m-d H:i:s', $record['use_time']) : '', 'create_time' => date('Y-m-d H:i:s', $record['create_time']) ]; } return [ 'code' => true, 'msg' => '获取成功', 'data' => $formatted_records ]; } catch (\Exception $e) { Log::error('获取赠品记录失败:' . $e->getMessage()); return [ 'code' => false, 'msg' => '获取赠品记录失败:' . $e->getMessage() ]; } } /** * 获取赠品类型文本 * @param string $gift_type * @return string */ private function getGiftTypeText($gift_type) { $type_map = [ 'referral_reward' => '转介绍奖励', 'sign_reward' => '签到奖励', 'course_reward' => '课程奖励', 'activity_reward' => '活动奖励', 'other' => '其他' ]; return $type_map[$gift_type] ?? $gift_type; } /** * 获取赠品状态文本 * @param int $gift_status * @return string */ private function getGiftStatusText($gift_status) { $status_map = [ 0 => '已失效', 1 => '可使用', 2 => '已使用' ]; return $status_map[$gift_status] ?? '未知状态'; } /** * 获取学生标签信息 * @param array $where * @return array */ public function getStudentLabel($where) { try { $label_id = $where['label_id'] ?? ''; if (empty($label_id)) { return [ 'code' => false, 'msg' => '标签ID不能为空' ]; } // 查询学生标签信息 $label_info = Db::table('school_student_label') ->where('label_id', $label_id) ->field('label_id, label_name, memo') ->find(); return [ 'code' => true, 'msg' => '获取成功', 'data' => $label_info ]; } catch (\Exception $e) { Log::error('获取学生标签失败:' . $e->getMessage()); return [ 'code' => false, 'msg' => '获取学生标签失败:' . $e->getMessage() ]; } } /** * 获取所有学生标签列表 * @return array */ public function getAllStudentLabels() { try { // 查询所有学生标签信息 $label_list = Db::table('school_student_label') ->field('label_id, label_name, memo, sort') ->order('sort asc, label_id asc') ->select(); // 确保返回数组格式 $result = []; if ($label_list) { foreach ($label_list as $label) { $result[] = [ 'label_id' => (int)$label['label_id'], 'label_name' => $label['label_name'], 'memo' => $label['memo'], 'sort' => (int)$label['sort'] ]; } } return [ 'code' => true, 'msg' => '获取成功', 'data' => $result ]; } catch (\Exception $e) { Log::error('获取学生标签列表失败:' . $e->getMessage()); return [ 'code' => false, 'msg' => '获取学生标签列表失败:' . $e->getMessage() ]; } } /** * 搜索学员(用于课程安排) * @param array $where 搜索条件 * @param string $field 返回字段 * @return array */ public function searchStudents(array $where, string $field = '*') { $res = [ 'code' => 0, 'msg' => '操作失败', 'data' => [] ]; try { // 构建查询条件 $query = Db::table('school_student') ->alias('s') ->leftJoin('school_student_courses sc', 's.id = sc.student_id') ->where('s.deleted_at', 0) ->where('s.status', 1); // 只查询状态正常的学员 // 按姓名搜索 if (!empty($where['name'])) { $query->where('s.name', 'like', "%{$where['name']}%"); } // 按手机号搜索 if (!empty($where['phone_number'])) { $query->where('s.contact_phone', 'like', "%{$where['phone_number']}%"); } // 获取学员基本信息和课程信息 $students = $query ->field([ 's.id as student_id', 's.name', 's.age', 's.contact_phone', 's.gender', 's.birthday', 's.campus_id', 's.class_id', 's.trial_class_count', 's.headimg', 's.first_come', 's.second_come', 's.user_id as resource_id', 'sc.id as student_course_id', 'sc.total_hours', 'sc.use_total_hours', 'sc.gift_hours', 'sc.use_gift_hours', 'sc.start_date', 'sc.end_date', 'sc.course_id' ]) ->group('s.id') ->order('s.created_at DESC') ->select(); if (!$students) { $res['msg'] = '暂无学员数据'; return $res; } // 处理数据格式,计算课程进度 $result = []; foreach ($students as $student) { $totalHours = intval($student['total_hours'] ?: 0) + intval($student['gift_hours'] ?: 0); $usedHours = intval($student['use_total_hours'] ?: 0) + intval($student['use_gift_hours'] ?: 0); $remainingHours = $totalHours - $usedHours; // 判断是否为体验课学员 $isTrialStudent = empty($student['student_course_id']); // 判断是否需要续费 $needsRenewal = false; if (!$isTrialStudent) { // 检查到期时间 if ($student['end_date']) { $daysUntilExpiry = (strtotime($student['end_date']) - time()) / (24 * 3600); if ($daysUntilExpiry <= 10) { $needsRenewal = true; } } // 检查剩余课时 if ($remainingHours < 4) { $needsRenewal = true; } } $result[] = [ 'id' => $student['student_id'], 'student_id' => $student['student_id'], 'name' => $student['name'], 'age' => floatval($student['age'] ?: 0), 'phone_number' => $student['contact_phone'], 'contact_phone' => $student['contact_phone'], 'gender' => $student['gender'], 'birthday' => $student['birthday'], 'campus_id' => $student['campus_id'], 'class_id' => $student['class_id'], 'trial_class_count' => intval($student['trial_class_count'] ?: 0), 'headimg' => $student['headimg'], 'first_come' => $student['first_come'], 'second_come' => $student['second_come'], 'resource_id' => intval($student['resource_id'] ?: 0), // 客户资源表ID 'person_type' => 'student', // 标识为学员类型 'courseStatus' => $isTrialStudent ? '体验课' : '正式课', 'isTrialStudent' => $isTrialStudent, 'is_formal_student' => !$isTrialStudent, // 有付费课程记录的为正式学员,可以选固定课 'needsRenewal' => $needsRenewal, 'student_course_info' => [ 'id' => $student['student_course_id'], 'total_hours' => $student['total_hours'], 'use_total_hours' => $student['use_total_hours'], 'gift_hours' => $student['gift_hours'], 'use_gift_hours' => $student['use_gift_hours'], 'start_date' => $student['start_date'], 'end_date' => $student['end_date'], 'course_id' => $student['course_id'] ], 'course_progress' => [ 'total' => $totalHours, 'used' => $usedHours, 'remaining' => $remainingHours, 'percentage' => $totalHours > 0 ? round(($usedHours / $totalHours) * 100, 1) : 0 ], 'remainingHours' => $remainingHours, 'totalHours' => $totalHours, 'usedHours' => $usedHours, 'expiryDate' => $student['end_date'] ]; } $res['code'] = 1; $res['msg'] = '操作成功'; $res['data'] = $result; } catch (\Exception $e) { Log::error('搜索学员失败:' . $e->getMessage()); $res['msg'] = '搜索学员失败:' . $e->getMessage(); } return $res; } /** * 根据资源ID和学员ID获取预设学员信息(不受状态限制) * @param array $where 查询条件 * @return array */ public function getPresetStudentInfo(array $where) { $res = [ 'code' => 0, 'msg' => '操作失败', 'data' => [] ]; try { $resourceId = $where['resource_id'] ?? 0; $studentId = $where['student_id'] ?? 0; if (!$resourceId && !$studentId) { $res['msg'] = '缺少必要参数'; return $res; } // 构建查询条件 - 不限制status状态 $query = Db::table('school_student') ->alias('s') ->leftJoin('school_student_courses sc', 's.id = sc.student_id') ->leftJoin('school_customer_resources cr', 's.user_id = cr.id') ->where('s.deleted_at', 0) ->where('s.id', $studentId); // 获取学员基本信息和课程信息 $student = $query ->field([ 's.id as student_id', 's.name', 's.age', 's.contact_phone', 's.gender', 's.birthday', 's.campus_id', 's.class_id', 's.trial_class_count', 's.headimg', 's.first_come', 's.second_come', 's.user_id as resource_id', 's.status as student_status', 'cr.phone_number', 'cr.member_id', 'sc.id as student_course_id', 'sc.total_hours', 'sc.use_total_hours', 'sc.gift_hours', 'sc.use_gift_hours', 'sc.start_date', 'sc.end_date', 'sc.course_id' ]) ->find(); if (!$student) { $res['msg'] = '学员不存在'; return $res; } // 计算课程进度和状态 $totalHours = intval($student['total_hours'] ?: 0) + intval($student['gift_hours'] ?: 0); $usedHours = intval($student['use_total_hours'] ?: 0) + intval($student['use_gift_hours'] ?: 0); $remainingHours = $totalHours - $usedHours; // 判断是否为体验课学员 $isTrialStudent = empty($student['student_course_id']); // 判断是否需要续费 $needsRenewal = false; if (!$isTrialStudent) { // 检查到期时间 if ($student['end_date']) { $daysUntilExpiry = (strtotime($student['end_date']) - time()) / (24 * 3600); if ($daysUntilExpiry <= 10) { $needsRenewal = true; } } // 检查剩余课时 if ($remainingHours < 4) { $needsRenewal = true; } } $result = [ 'id' => $student['student_id'], 'student_id' => $student['student_id'], 'name' => $student['name'], 'age' => floatval($student['age'] ?: 0), 'phone_number' => $student['contact_phone'] ?: $student['phone_number'], 'contact_phone' => $student['contact_phone'] ?: $student['phone_number'], 'gender' => $student['gender'], 'birthday' => $student['birthday'], 'campus_id' => $student['campus_id'], 'class_id' => $student['class_id'], 'trial_class_count' => intval($student['trial_class_count'] ?: 0), 'headimg' => $student['headimg'], 'first_come' => $student['first_come'], 'second_come' => $student['second_come'], 'resource_id' => $student['resource_id'], 'member_id' => $student['member_id'], 'student_status' => $student['student_status'], 'person_type' => 'student', 'courseStatus' => $isTrialStudent ? '体验课' : '正式课', 'isTrialStudent' => $isTrialStudent, 'is_formal_student' => !$isTrialStudent, // 有付费课程记录的为正式学员,可以选固定课 'needsRenewal' => $needsRenewal, 'student_course_info' => [ 'id' => $student['student_course_id'], 'total_hours' => $student['total_hours'], 'use_total_hours' => $student['use_total_hours'], 'gift_hours' => $student['gift_hours'], 'use_gift_hours' => $student['use_gift_hours'], 'start_date' => $student['start_date'], 'end_date' => $student['end_date'], 'course_id' => $student['course_id'] ], 'course_progress' => [ 'total' => $totalHours, 'used' => $usedHours, 'remaining' => $remainingHours, 'percentage' => $totalHours > 0 ? round(($usedHours / $totalHours) * 100, 1) : 0 ], 'remainingHours' => $remainingHours, 'totalHours' => $totalHours, 'usedHours' => $usedHours, 'expiryDate' => $student['end_date'] ]; $res['code'] = 1; $res['msg'] = '操作成功'; $res['data'] = $result; } catch (\Exception $exception) { $res['msg'] = '获取预设学员信息失败:' . $exception->getMessage(); } return $res; } }