智慧教务系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1258 lines
47 KiB

<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\service\api\apiService;
use app\model\campus_person_role\CampusPersonRole;
use app\model\customer_resource_changes\CustomerResourceChanges;
use app\model\customer_resources\CustomerResources;
use app\model\dict\Dict;
use app\model\member\Member;
use app\model\personnel\Personnel;
use app\model\resource_sharing\ResourceSharing;
use app\model\six_speed\SixSpeed;
use app\model\six_speed_modification_log\SixSpeedModificationLog;
use app\model\school\SchoolStudent;
use core\base\BaseApiService;
use think\facade\Db;
use think\facade\Event;
use think\facade\Log;
/**
* 客户资源服务层
* Class MemberService
* @package app\service\api\member
*/
class CustomerResourcesService extends BaseApiService
{
public function __construct()
{
parent::__construct();
}
//获取客户资源详情
public function getInfo(array $where, string $field = '*')
{
$res = [
'code' => 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;
}
}