From ccedf7a9fa492fac36117589b366b4dff48204f5 Mon Sep 17 00:00:00 2001 From: wangzeyan <258785420@qq.com> Date: Thu, 12 Jun 2025 13:46:38 +0800 Subject: [PATCH 01/13] =?UTF-8?q?=E4=BF=AE=E6=94=B9bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apiService/CustomerResourcesService.php | 98 ++++++++++--------- 1 file changed, 50 insertions(+), 48 deletions(-) diff --git a/niucloud/app/service/api/apiService/CustomerResourcesService.php b/niucloud/app/service/api/apiService/CustomerResourcesService.php index 838d087b..3a4ea94d 100644 --- a/niucloud/app/service/api/apiService/CustomerResourcesService.php +++ b/niucloud/app/service/api/apiService/CustomerResourcesService.php @@ -37,17 +37,18 @@ class CustomerResourcesService extends BaseApiService } //获取客户资源详情 - public function getInfo(array $where,string $field = '*'){ + public function getInfo(array $where, string $field = '*') + { $res = [ 'code' => 0, 'msg' => '操作失败', 'data' => [] ]; $model = new CustomerResources(); - if(!empty($where['member_id'])){ + if (!empty($where['member_id'])) { $model = $model->where('member_id', $where['member_id']); } - if(!empty($where['phone_number'])){ + if (!empty($where['phone_number'])) { $model = $model->where('phone_number', $where['phone_number']); } $data = $model->field($field) @@ -60,30 +61,30 @@ class CustomerResourcesService extends BaseApiService 'initial_intent_name' ]) ->find(); - if ($data){ + if ($data) { $data = $data->toArray(); $res['code'] = 1; $res['data'] = $data; - }else{ + } else { $res['msg'] = '暂无数据'; } return $res; } //获取全部客户资源数据 - public function getAll(array $where,string $field = '*') + public function getAll(array $where, string $field = '*') { $res = [ 'code' => 0, 'msg' => '操作失败', 'data' => [] ]; - if(!$where){ + if (!$where) { $res['msg'] = '查询条件不能为空'; return $res; } $model = new CustomerResources(); - if(!empty($where['name'])){ + if (!empty($where['name'])) { $model = $model->where('name', 'like', "%{$where['name']}%"); } $data = $model->field($field) @@ -153,10 +154,11 @@ class CustomerResourcesService extends BaseApiService 'event_type' => 'add'//事件类型"add=添加,edit=修改 ];//事件类型"add=添加,edit=修改 - Event::trigger('CalculatePerformance', $event_data)->queue(); + Event::trigger('CalculatePerformance', $event_data, true); return $res; } catch (\Exception $exception) { Db::rollback(); + $res['msg'] = $exception->getMessage(); return $res; } } @@ -199,9 +201,9 @@ class CustomerResourcesService extends BaseApiService if ($customer_resources) { $customer_resources = $customer_resources->toArray(); - if(!$customer_resources['member_id'] && $six_speed){ + if (!$customer_resources['member_id'] && $six_speed) { //新数据存在一访问 或者旧数据存在一访的情况 && 这用户没注册过member账号的情况下才给他创建member账号 - if(!empty($six_speed_data['first_visit_status']) || $six_speed['first_visit_status']){ + if (!empty($six_speed_data['first_visit_status']) || $six_speed['first_visit_status']) { $sex = 0; switch ($customer_resources_data['gender']) { case 'male'://男 @@ -217,16 +219,16 @@ class CustomerResourcesService extends BaseApiService $password = create_password($customer_resources_data['phone_number']);//创建密码 //给用户创建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(),//成为会员时间 + '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){ + if ($member_id) { $customer_resources_data['member_id'] = $member_id; - }else{ + } else { Db::rollback(); $res['msg'] = '创建用户账号失败'; return $res; @@ -424,13 +426,13 @@ class CustomerResourcesService extends BaseApiService $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(客户状态) + '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);//字段与字典值列表的映射关系 @@ -441,16 +443,16 @@ class CustomerResourcesService extends BaseApiService $new_values_arr = json_decode($v['new_values'], true); //判断有没有修改过"顾问"字段 - if(in_array('consultant',$modified_fields_arr)){ + 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){ + 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'], @@ -474,13 +476,13 @@ class CustomerResourcesService extends BaseApiService $old_value = $old_values_arr[$m_v] ?? ''; $new_value = $new_values_arr[$m_v] ?? ''; - if(in_array($m_v,$fieldDictKeyArr)){ + if (in_array($m_v, $fieldDictKeyArr)) { $dict = $dict_arr[$m_v]; - foreach($dict as $d_v){ - if($d_v['value'] == $old_value){ + foreach ($dict as $d_v) { + if ($d_v['value'] == $old_value) { $old_value = $d_v['name']; } - if($d_v['value'] == $new_value){ + if ($d_v['value'] == $new_value) { $new_value = $d_v['name']; } } @@ -533,10 +535,10 @@ class CustomerResourcesService extends BaseApiService $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-否) + '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);//字段与字典值列表的映射关系 @@ -547,16 +549,16 @@ class CustomerResourcesService extends BaseApiService $new_values_arr = json_decode($v['new_value'], true); //判断有没有修改过"顾问(人员)"字段 - if(in_array('staff_id',$modified_fields_arr)){ + 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){ + 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'], @@ -580,13 +582,13 @@ class CustomerResourcesService extends BaseApiService $old_value = $old_values_arr[$m_v] ?? ''; $new_value = $new_values_arr[$m_v] ?? ''; - if(in_array($m_v,$fieldDictKeyArr)){ + if (in_array($m_v, $fieldDictKeyArr)) { $dict = $dict_arr[$m_v]; - foreach($dict as $d_v){ - if($d_v['value'] == $old_value){ + foreach ($dict as $d_v) { + if ($d_v['value'] == $old_value) { $old_value = $d_v['name']; } - if($d_v['value'] == $new_value){ + if ($d_v['value'] == $new_value) { $new_value = $d_v['name']; } } @@ -643,7 +645,7 @@ class CustomerResourcesService extends BaseApiService foreach ($fieldDictMapping as $field => $key) { $result[$field] = $dictMap[$key]['dictionary'] ?? []; //判断是不是获取的"来源渠道"的字典 - if($field == 'source_channel'){ + if ($field == 'source_channel') { $append_arr = [ "name" => "线下", "value" => "0", @@ -651,7 +653,7 @@ class CustomerResourcesService extends BaseApiService "memo" => "", ]; //插入到数组头部 - array_unshift($result[$field],$append_arr); + array_unshift($result[$field], $append_arr); } } From db0dc664548dff6613882997a11019248933c8d8 Mon Sep 17 00:00:00 2001 From: liutong <836164388@qq.com> Date: Thu, 12 Jun 2025 16:46:51 +0800 Subject: [PATCH 02/13] =?UTF-8?q?refactor(attendance):=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E5=91=98=E5=B7=A5=E8=80=83=E5=8B=A4=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构了 edit 方法,支持多种考勤状态的处理 - 增加了对签到、签退和请假的单独处理逻辑 - 优化了参数验证和错误提示 - 调整了查询条件,支持按状态和签退时间查询 --- .../controller/apiController/Attendance.php | 145 ++++++++++-------- .../apiController/CustomerResources.php | 2 +- .../api/apiService/AttendanceService.php | 12 ++ 3 files changed, 96 insertions(+), 63 deletions(-) diff --git a/niucloud/app/api/controller/apiController/Attendance.php b/niucloud/app/api/controller/apiController/Attendance.php index 704874cf..a3a0a87f 100644 --- a/niucloud/app/api/controller/apiController/Attendance.php +++ b/niucloud/app/api/controller/apiController/Attendance.php @@ -42,9 +42,12 @@ class Attendance extends BaseApiService //员工考勤-编辑(员工打卡/请假/签退) public function edit(Request $request){ + $id =$request->param('id','');//考勤表id $campus_id =$request->param('campus_id','');//校区ID $staff_id =$this->member_id;//人员ID $attendance_date =$request->param('attendance_date','');//考勤日期 + $leave_start_time =$request->param('leave_start_time','');//请假开始时间 + $leave_end_time =$request->param('leave_end_time','');//请假结束时间 $remarks =$request->param('remarks','');//备注 $status =$request->param('status','');//考勤状态: present-出勤, absent-缺勤, late-迟到, leave_early-早退,leave-请假,sign_out-签退 $longitude = $request->param('longitude','');//经度 @@ -56,106 +59,124 @@ class Attendance extends BaseApiService return fail('缺少定位坐标'); } - if(empty($campus_id) || empty($attendance_date) || empty($status)){ + if(empty($attendance_date) || empty($status)){ return fail('缺少参数'); } + if(!in_array($status,['present','absent','late','leave_early','leave','sign_out'])){ return fail('状态类型不正确'); } - //获取校区的经纬度坐标 - $campus_data = (new CampusService)->getInfo($campus_id);//查校区详情 - $campus_lng = $campus_data['campus_coordinates']['lng'];//校区经度坐标 - $campus_lat = $campus_data['campus_coordinates']['lat'];//校区纬度坐标 - $radius = 1500.0;//打卡半径(米) //判断签到+签退时是否超出打卡范围 - if(in_array($status,['present','sign_out'])){ - $isInCheckRange = (new CommonService())->isInCheckRange((float)$campus_lng, (float)$campus_lat, (float)$longitude, (float)$latitude, (float)$radius); + if(in_array($status,['present','sign_out']) && !empty($campus_id)){ + //获取校区的经纬度坐标 + $campus_data = (new CampusService)->getInfo($campus_id);//查校区详情 + $campus_lng = $campus_data['campus_coordinates']['lng'];//校区经度坐标 + $campus_lat = $campus_data['campus_coordinates']['lat'];//校区纬度坐标 + $radius = 1500.0;//打卡半径(米) + + $isInCheckRange = (new CommonService())->isInCheckRange((float)$campus_lng, (float)$campus_lat, (float)$longitude, (float)$latitude, (float)$radius);//判断是否在打卡范围内 if(!$isInCheckRange){ return fail("超出打卡范围,规定打卡范围({$radius}米)"); } } - - //查询数据是否存在,一天一个校区同一个人只能产生一条数据 + //查询数据是否存在,一天一个校区同一个人可能有多条打卡记录数据,只要有1条打卡没签退就不能新增新的打卡记录 $date_h = date('H:i:s'); $obj = (new AttendanceService()); $info = $obj->info([ + 'id'=>$id, 'campus_id'=>$campus_id, 'staff_id'=>$staff_id, 'attendance_date'=>$attendance_date, ])['data']; - //如果是签退的时候就是修改 - if($status == 'sign_out'){ - if (($info['status'] ?? '') != 'present') { - return fail('未查询到今日签到信息,无法签退'); + //判断是打卡 + if($status == 'present'){ + $model = new \app\model\attendance\Attendance(); + $model = $model->where('staff_id',$staff_id)->where('status','present'); + if($campus_id === '0' || $campus_id === 0 || !empty($campus_id)){ + $model = $model->where('campus_id',$campus_id); + } + if(!empty($attendance_date)){ + $model = $model->where('attendance_date',$attendance_date); + } + + // 获取今天所有考勤记录 + $records = $model->order('id', 'desc')->select()->toArray(); + // Step 1: 检查是否有未签退的记录 + foreach ($records as $record) { + if (empty($record['check_out_time'])) { + return fail('今日有签到记录未签退,请先签退后再试'); + } + } + + //插入打卡记录 + $data = [ + 'campus_id'=>$campus_id ?? 0,// + 'staff_id'=>$staff_id,// + 'attendance_date'=>$attendance_date,// + 'check_in_time'=>$date_h,// + 'status'=>$status,// + 'coordinate'=>$coordinate,//坐标|经度,纬度 + 'remarks'=>$remarks,// + ]; + $res = $obj->addData($data); + if(!$res['code']){ + return fail($res['msg']); + } + return success($res['data']); + } + //判断是签退 + if($status == 'sign_out'){ + if($info['attendance_date'] != $attendance_date && $info['status'] != 'present'){ + return fail('为找到今日签到记录'); } //签退的情况 $where = [ - 'id'=>$info['id'] + 'id'=>$info['id'] ]; $data = [ 'check_out_time'=>$date_h,//签退时间 'coordinate'=>$coordinate,//坐标|经度,纬度 + 'remarks' => $remarks,// ]; //执行修改操作 $res = $obj->editData($where,$data); - }else{ - //如果是签到/请假 - $data = [ - 'campus_id'=>$campus_id,//校区ID - 'staff_id'=>$staff_id,//人员ID - 'attendance_date'=>$attendance_date,//考勤日期 - 'coordinate'=>$coordinate,//坐标|经度,纬度 - 'status'=>$status,//考勤状态 - ]; - //如果是签到的情况 - if($info){ - if($status == 'present' && $info['status'] == 'present'){ - //更新签到数据 - //执行修改操作 - $edit_data = [ - 'check_in_time'=>$date_h,//签到时间 - 'coordinate'=>$coordinate,//坐标|经度,纬度 - 'status'=>$status//考勤状态 - ]; - $res = $obj->editData(['id'=>$info['id']],$edit_data); - if(!$res['code']){ - return fail($res['msg']); - } - return success($res['data']); - } - $status_arr = (new \app\model\attendance\Attendance())::STATUS; - $status_name = $status_arr[$info['status']] ?? ''; - if(!$status_name){ - $status_name = '考勤'; - } - return fail("今日已{$status_name}重复操作"); - }else{ - $data['check_in_time'] = $date_h;//签到时间 - if($remarks){ - $data['remarks'] = $remarks; - } - //执行创建操作 - $res = $obj->addData($data); - if(!$res['code']){ - return fail($res['msg']); - } - return success($res['data']); + if(!$res['code']){ + return fail($res['msg']); + } + return success($res['data']); + } + //判断是请假 + if($status == 'leave'){ + //判断今日是否存在打卡记录,判断今日的打开记录是否已经签退,是则不可以再请假了 + if($info && $info['status'] == 'present' && $info['attendance_date'] == $attendance_date && !empty($info['check_out_time'])){ + return fail('今日已签退,无法进行请假操作'); } + $data = [ + 'campus_id' => $campus_id ?? 0, + 'staff_id' => $staff_id, + 'attendance_date' => $attendance_date, + 'leave_start_time' => $leave_start_time, + 'leave_end_time' => $leave_end_time, + 'status' => $status, + 'coordinate' => $coordinate, + 'remarks' => $remarks, + ]; - - - - - + //创建请假记录 + $res = $obj->addData($data); + if(!$res['code']){ + return fail($res['msg']); + } + return success($res['data']); } } } diff --git a/niucloud/app/api/controller/apiController/CustomerResources.php b/niucloud/app/api/controller/apiController/CustomerResources.php index 7f7072fe..f58175ec 100644 --- a/niucloud/app/api/controller/apiController/CustomerResources.php +++ b/niucloud/app/api/controller/apiController/CustomerResources.php @@ -166,7 +166,7 @@ class CustomerResources extends BaseApiService "preferred_class_time" => $optional_class_time,//可选上课时间 "distance" => $request->param('distance', ''),//距离 "communication" => $request->param('communication', ''),//沟通备注 - "staff_id" => $request->param('staff_id', ''),//人员ID + "staff_id" => $request->param('staff_id', ''),//人员ID//如果没有就是当前登录人的员工id "first_visit_status" => $request->param('first_visit_status', null),//一访情况 "second_visit_status" => $request->param('second_visit_status', null),//二访情况 diff --git a/niucloud/app/service/api/apiService/AttendanceService.php b/niucloud/app/service/api/apiService/AttendanceService.php index 1eb2a255..883168af 100644 --- a/niucloud/app/service/api/apiService/AttendanceService.php +++ b/niucloud/app/service/api/apiService/AttendanceService.php @@ -91,6 +91,18 @@ class AttendanceService extends BaseApiService if (!empty($where['attendance_date'])) { $model = $model->where('attendance_date', $where['attendance_date']); } + if(!empty($where['status'])){ + $model = $model->where('status', $where['status']); + } + if(!empty($where['check_out_time'])){ + if($where['check_out_time'] === 'null'){ + $where['check_out_time'] = null; + $model = $model->where('check_out_time', null); + }else{ + $model = $model->whereIn('check_out_time', $where['check_out_time']); + } + + } $data = $model->field($field)->find(); if ($data) { $res = [ From d9f0cb75aa587ba21a6703f846060cdfa1e3e52f Mon Sep 17 00:00:00 2001 From: liutong <836164388@qq.com> Date: Thu, 12 Jun 2025 17:07:23 +0800 Subject: [PATCH 03/13] =?UTF-8?q?fix(attendance):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=A1=A5=E5=8D=A1=E6=97=B6=E8=AF=B7=E5=81=87=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增逻辑处理今天有请假情况下的打卡记录更新 - 使用事务确保数据一致性 - 优化了打卡记录插入流程 --- .../controller/apiController/Attendance.php | 59 ++++++++++++++----- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/niucloud/app/api/controller/apiController/Attendance.php b/niucloud/app/api/controller/apiController/Attendance.php index a3a0a87f..0d4c999c 100644 --- a/niucloud/app/api/controller/apiController/Attendance.php +++ b/niucloud/app/api/controller/apiController/Attendance.php @@ -16,6 +16,7 @@ use app\service\admin\campus\CampusService; use app\service\api\apiService\AttendanceService; use app\service\api\apiService\CommonService; use core\base\BaseApiService; +use think\facade\Db; /** * 员工考勤控制器相关接口 @@ -115,21 +116,51 @@ class Attendance extends BaseApiService } } - //插入打卡记录 - $data = [ - 'campus_id'=>$campus_id ?? 0,// - 'staff_id'=>$staff_id,// - 'attendance_date'=>$attendance_date,// - 'check_in_time'=>$date_h,// - 'status'=>$status,// - 'coordinate'=>$coordinate,//坐标|经度,纬度 - 'remarks'=>$remarks,// - ]; - $res = $obj->addData($data); - if(!$res['code']){ - return fail($res['msg']); + //获取今天请假的数据(leave_end_time>当前时间的 && attendance_date=当前日期的)请假数据,更新leave_end_time=当前时间 + //请假的id + $leave_id_arr = new \app\model\attendance\Attendance(); + if($campus_id === '0' || $campus_id === 0 || !empty($campus_id)){ + $leave_id_arr = $leave_id_arr->where('campus_id',$campus_id); + } + $leave_id_arr = $leave_id_arr->where('staff_id',$staff_id) + ->where('status','leave') + ->where('attendance_date',$attendance_date) + ->where('leave_end_time','>=',$date_h)->column('id'); + + Db::startTrans(); + try { + if($leave_id_arr){ + $update = \app\model\attendance\Attendance::whereIn('id',$leave_id_arr)->update([ + 'leave_end_time'=>$date_h, + 'updated_at'=>$date_h, + ]); + if(!$update){ +// Db::rollback(); +// return fail('更新请假数据失败'); + } + } + + //插入打卡记录 + $data = [ + 'campus_id'=>$campus_id ?? 0,// + 'staff_id'=>$staff_id,// + 'attendance_date'=>$attendance_date,// + 'check_in_time'=>$date_h,// + 'status'=>$status,// + 'coordinate'=>$coordinate,//坐标|经度,纬度 + 'remarks'=>$remarks,// + ]; + $res = $obj->addData($data); + Db::commit(); + if(!$res['code']){ + Db::rollback(); + return fail($res['msg']); + } + return success($res['data']); + }catch (\Exception $e){ + Db::rollback(); + return fail('操作失败'); } - return success($res['data']); } //判断是签退 if($status == 'sign_out'){ From 6f402e1a94eefdecde1c22b35896f76b1d741ba3 Mon Sep 17 00:00:00 2001 From: liutong <836164388@qq.com> Date: Thu, 12 Jun 2025 17:16:09 +0800 Subject: [PATCH 04/13] =?UTF-8?q?fix(app):=20=E4=BF=AE=E5=A4=8D=E7=AD=BE?= =?UTF-8?q?=E5=88=B0=E8=AE=B0=E5=BD=95=E6=9B=B4=E6=96=B0=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E5=92=8C=E6=9F=A5=E8=AF=A2=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新签到记录时,使用当前时间戳代替固定日期 - 优化签到记录查询逻辑,增加对未签退记录的判断 - 添加校园 ID 过滤条件,提高查询准确性 --- .../controller/apiController/Attendance.php | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/niucloud/app/api/controller/apiController/Attendance.php b/niucloud/app/api/controller/apiController/Attendance.php index 0d4c999c..c5824fa2 100644 --- a/niucloud/app/api/controller/apiController/Attendance.php +++ b/niucloud/app/api/controller/apiController/Attendance.php @@ -132,7 +132,7 @@ class Attendance extends BaseApiService if($leave_id_arr){ $update = \app\model\attendance\Attendance::whereIn('id',$leave_id_arr)->update([ 'leave_end_time'=>$date_h, - 'updated_at'=>$date_h, + 'updated_at'=>date('Y-m-d H:i:s'), ]); if(!$update){ // Db::rollback(); @@ -159,13 +159,28 @@ class Attendance extends BaseApiService return success($res['data']); }catch (\Exception $e){ Db::rollback(); + dd(123123,$e->getMessage()); return fail('操作失败'); } } //判断是签退 if($status == 'sign_out'){ - if($info['attendance_date'] != $attendance_date && $info['status'] != 'present'){ - return fail('为找到今日签到记录'); + if(!empty($id)){ + $info = \app\model\attendance\Attendance::where('id',$id)->find(); + }else{ + $info = \app\model\attendance\Attendance::where('attendance_date',$attendance_date) + ->where('check_out_time',null) + ->where('status','present') + ->where('staff_id',$staff_id); + if($campus_id){ + $info = $info->where('campus_id',$campus_id); + } + $info = $info->find(); + } + + + if(!$info){ + return fail('为找到签到记录'); } //签退的情况 From bf41e62ea788c40db1a7fc23b34db0f75cc74f6d Mon Sep 17 00:00:00 2001 From: liutong <836164388@qq.com> Date: Thu, 12 Jun 2025 19:32:52 +0800 Subject: [PATCH 05/13] =?UTF-8?q?feat(customer-resources):=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=AE=A2=E6=88=B7=E8=B5=84=E6=BA=90=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=B9=B6=E4=BC=98=E5=8C=96=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 CustomerResources 控制器中添加了通过手机号查询客户资源的功能 - 优化了客户资源数据的校验逻辑,包括联系电话长度限制 - 在 CustomerResources 模型中添加了决策人类型名称的获取方法 - 更新了 CustomerResourcesService 服务中的查询逻辑,支持按手机号筛选 --- .../apiController/CustomerResources.php | 23 +++++++++++++--- .../customer_resources/CustomerResources.php | 27 +++++++++++++++++++ .../apiService/CustomerResourcesService.php | 5 +++- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/niucloud/app/api/controller/apiController/CustomerResources.php b/niucloud/app/api/controller/apiController/CustomerResources.php index f58175ec..4f8afca8 100644 --- a/niucloud/app/api/controller/apiController/CustomerResources.php +++ b/niucloud/app/api/controller/apiController/CustomerResources.php @@ -28,12 +28,14 @@ class CustomerResources extends BaseApiService public function getAll(Request $request){ $name = $request->param('name', '');//客户姓名 - if(empty($name)){ - return fail("缺少客户姓名"); + $phone_number = $request->param('phone_number', '');//客户手机号 + if(empty($name) && empty($phone_number)){ + return fail("缺少查询参数"); } $where = [ - 'name'=>$name + 'name'=>$name, + 'phone_number'=>$phone_number ]; $res = (new CustomerResourcesService())->getAll($where); if(!$res['code']){ @@ -93,6 +95,11 @@ class CustomerResources extends BaseApiService return fail("缺少必填项{$k}"); } } + + if (strlen($customer_resources_data['phone_number']) > 12) { + return fail("联系电话不能超过12位"); + } + foreach($six_speed_data as $k=>$v){ if(!isset($v) || $v === ''){ return fail("缺少必填项{$k}"); @@ -177,6 +184,16 @@ class CustomerResources extends BaseApiService return fail("缺少必填项{$k}"); } } + + if (strlen($customer_resources_data['phone_number']) > 12) { + return fail("联系电话不能超过12位"); + } + + //如果六要素人员id没有就是当前登录人的员工id + if(empty($six_speed_data['staff_id'])){ + $six_speed_data['staff_id'] = $this->member_id; + } + foreach($six_speed_data as $k=>$v){ // 排除 first_visit_status 和 second_visit_status 的必填校验 if (in_array($k, ['first_visit_status', 'second_visit_status'])) { diff --git a/niucloud/app/model/customer_resources/CustomerResources.php b/niucloud/app/model/customer_resources/CustomerResources.php index ae42a928..30a93c58 100644 --- a/niucloud/app/model/customer_resources/CustomerResources.php +++ b/niucloud/app/model/customer_resources/CustomerResources.php @@ -341,6 +341,33 @@ class CustomerResources extends BaseModel } } + /** + * 获取决策人类型名称 + * @param $value + * @param $data + * @return array|mixed|string + */ + public function getDecisionMakerNameAttr($value, $data) + { + $key = 'decision_maker'; + $val = (String)$data['decision_maker'] ?? ''; + if ((!empty($val) || isset($val)) && $val !== '') { + $dict = Dict::where('key',$key)->find(); + $dictionary = $dict['dictionary'] ?? []; + // 查找匹配的 name + $res = $val; + foreach ($dictionary as $item) { + if ($item['value'] == $val) { + $res = $item['name']; + break; + } + } + return $res; + } else { + return $val; + } + } + } diff --git a/niucloud/app/service/api/apiService/CustomerResourcesService.php b/niucloud/app/service/api/apiService/CustomerResourcesService.php index 838d087b..6483fe29 100644 --- a/niucloud/app/service/api/apiService/CustomerResourcesService.php +++ b/niucloud/app/service/api/apiService/CustomerResourcesService.php @@ -86,12 +86,15 @@ class CustomerResourcesService extends BaseApiService if(!empty($where['name'])){ $model = $model->where('name', 'like', "%{$where['name']}%"); } + if(!empty($where['phone_number'])){ + $model = $model->where('phone_number', $where['phone_number']); + } $data = $model->field($field) ->with([ 'resourceSharingHasMany' ]) ->append([ - 'initial_intent_name' + 'initial_intent_name', ]) ->select()->toArray(); if (!$data) { From 3b91a6f78b379d8cba33a1912075806de8df974b Mon Sep 17 00:00:00 2001 From: liutong <836164388@qq.com> Date: Fri, 13 Jun 2025 11:50:43 +0800 Subject: [PATCH 06/13] =?UTF-8?q?feat(ResourceSharing):=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=AE=A2=E6=88=B7=E8=B5=84=E6=BA=90=E5=85=B1=E4=BA=AB?= =?UTF-8?q?=E7=AD=9B=E9=80=89=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 ResourceSharing 控制器中添加了 name 和 phone_number 参数 - 在 CustomerResources 模型中添加了 member_id 字段 - 在 ResourceSharingService 服务中实现了根据客户姓名和手机号筛选资源共享记录的功能 --- .../apiController/ResourceSharing.php | 7 +++++-- .../customer_resources/CustomerResources.php | 3 ++- .../api/apiService/ResourceSharingService.php | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/niucloud/app/api/controller/apiController/ResourceSharing.php b/niucloud/app/api/controller/apiController/ResourceSharing.php index e87b153c..b2eb8cc6 100644 --- a/niucloud/app/api/controller/apiController/ResourceSharing.php +++ b/niucloud/app/api/controller/apiController/ResourceSharing.php @@ -28,9 +28,10 @@ class ResourceSharing extends BaseApiService { $user_id = $this->member_id;//当前登陆的用户id - $page = $request->param('page','1');// - $limit = $request->param('limit','10');// $shared_by = $request->param('shared_by','');//共享人ID + $name = $request->param('name','');////客户资源表-姓名 + $phone_number = $request->param('phone_number','');//客户资源表-手机号 + $shared_at_str = $request->param('shared_at_str','');//共享时间|[开始时间(Y-m-d),结束时间(Y-m-d)] $shared_at_arr = []; if(!empty($shared_at_str)){ @@ -42,6 +43,8 @@ class ResourceSharing extends BaseApiService $where = [ 'shared_by'=>$shared_by, 'shared_at_arr'=>$shared_at_arr, + 'name'=>$name, + 'phone_number'=>$phone_number, ]; $res= (new ResourceSharingService())->getList($where); return success($res); diff --git a/niucloud/app/model/customer_resources/CustomerResources.php b/niucloud/app/model/customer_resources/CustomerResources.php index 30a93c58..cee4efec 100644 --- a/niucloud/app/model/customer_resources/CustomerResources.php +++ b/niucloud/app/model/customer_resources/CustomerResources.php @@ -89,7 +89,8 @@ class CustomerResources extends BaseModel 'updated_at' => '更新时间', 'deleted_at' => '逻辑删除时间', 'status' => '客户状态', - 'member_label' => '资源标签' + 'member_label' => '资源标签', + 'member_id' => '客户登录标识' ]; public function orderTable() diff --git a/niucloud/app/service/api/apiService/ResourceSharingService.php b/niucloud/app/service/api/apiService/ResourceSharingService.php index 7024ab7f..58a672f9 100644 --- a/niucloud/app/service/api/apiService/ResourceSharingService.php +++ b/niucloud/app/service/api/apiService/ResourceSharingService.php @@ -12,6 +12,7 @@ namespace app\service\api\apiService; use app\model\campus_person_role\CampusPersonRole; +use app\model\customer_resources\CustomerResources; use app\model\order_table\OrderTable; use app\model\resource_sharing\ResourceSharing; use core\base\BaseApiService; @@ -47,8 +48,25 @@ class ResourceSharingService extends BaseApiService ->distinct(true) ->column('person_id'); + $resource_id_arr = [];//客户资源表id + //客户资源表名字 + if(!empty($where['name'])){ + $resource_id = (new CustomerResources())->where('name', 'like', "%{$where['name']}%")->column('id'); + $resource_id_arr = array_merge($resource_id_arr,$resource_id); + } + //客户资源表手机号 + if(!empty($where['phone_number'])){ + $resource_id = (new CustomerResources())->where('phone_number', 'like', "%{$where['phone_number']}%")->column('id'); + $resource_id_arr = array_merge($resource_id_arr,$resource_id); + } + //去重 + $resource_id_arr = array_unique($resource_id_arr); + $model = $this->model; + if($resource_id_arr){ + $model = $model->whereIn('resource_id',$resource_id_arr); + } if ((!empty($where['shared_by']) || isset($where['shared_by'])) && $where['shared_by'] !== '') { $model = $model->where('shared_by', $where['shared_by']); From 03c3ab95a9809cd22894854dce5348296dfaeffb Mon Sep 17 00:00:00 2001 From: liutong <836164388@qq.com> Date: Fri, 13 Jun 2025 17:43:41 +0800 Subject: [PATCH 07/13] =?UTF-8?q?feat(api):=20=E6=B7=BB=E5=8A=A0=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD=E5=92=8C=E5=85=AC?= =?UTF-8?q?=E5=85=B1=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增订单管理相关接口和功能,包括订单列表、详情和创建 - 添加获取全部课程列表和班级列表的公共接口 - 在路由中注册新接口 - 实现订单管理的服务层逻辑 --- .../api/controller/apiController/Common.php | 18 +++ .../controller/apiController/OrderTable.php | 120 ++++++++++++++++ niucloud/app/api/route/route.php | 12 ++ niucloud/app/model/order_table/OrderTable.php | 5 +- .../service/api/apiService/CommonService.php | 26 ++++ .../api/apiService/OrderTableService.php | 128 ++++++++++++++++++ 6 files changed, 308 insertions(+), 1 deletion(-) create mode 100644 niucloud/app/api/controller/apiController/OrderTable.php create mode 100644 niucloud/app/service/api/apiService/OrderTableService.php diff --git a/niucloud/app/api/controller/apiController/Common.php b/niucloud/app/api/controller/apiController/Common.php index 7bccd8bd..9d2f4873 100644 --- a/niucloud/app/api/controller/apiController/Common.php +++ b/niucloud/app/api/controller/apiController/Common.php @@ -92,5 +92,23 @@ class Common extends BaseApiService return success($res['data']); } + //获取全部课程列表 + public function getCourseAll(Request $request) + { + $where = []; + $res = (new CommonService())->getCourseAllList($where); + return success($res); + } + + //获取全部班级列表 + public function getClassAll(Request $request) + { + $where = [ + 'status' => $request->param('status', '') + ]; + $res = (new CommonService())->getClassAllList($where); + return success($res); + } + } diff --git a/niucloud/app/api/controller/apiController/OrderTable.php b/niucloud/app/api/controller/apiController/OrderTable.php new file mode 100644 index 00000000..08b2065f --- /dev/null +++ b/niucloud/app/api/controller/apiController/OrderTable.php @@ -0,0 +1,120 @@ +param('resource_id', '');//客户资源表school_customer_resources表id(两个参数2选1) + $staff_id = $request->param('staff_id', '');//员工表school_personnel表id(两个参数2选1) + if (empty($resource_id) && empty($staff_id)) { + return fail('缺少参数'); + } + + $where = [ + 'resource_id' => $resource_id, + 'staff_id' => $staff_id, + ]; + + $res = (new OrderTableService())->getList($where); + + return success($res); + } + + //订单-详情 + public function info(Request $request) + { + $resource_id = $request->param('resource_id', '');//客户资源表school_customer_resources表id(两个参数2选1) + $staff_id = $request->param('staff_id', '');//员工表school_personnel表id(两个参数2选1) + if (empty($resource_id) && empty($staff_id)) { + return fail('缺少参数'); + } + + $where = [ + 'resource_id' => $resource_id, + 'staff_id' => $staff_id, + ]; + + $res = (new OrderTableService())->getInfo($where); + + if (!$res['code']) { + return fail($res['msg']); + } + + return success($res['data']); + } + + //订单-创建 + public function add(Request $request) + { + + $params = $request->params([ + ["payment_type", ""], // 付款类型必填验证 + ["course_id", ""], // 课程ID必填验证 + ["class_id", ""], // 班级ID必填验证 + ["staff_id", ""], // 员工ID必填验证 + ["resource_id", ""], // 客户资源表ID必填验证 + ]); + + foreach($params as $k=>$v){ + if(empty($v)){ + return fail('缺少参数'); + } + } + + + $course = \app\model\course\Course::where('id', $params['course_id'])->find(); + if (!$course) { + return fail('课程不存在'); + } + $course = $course->toArray(); + $order_amount = $course['price'];//课程的价格 + + + $data = [ + 'payment_type' => $params['payment_type'],//付款类型: cash-现金支付, scan_code-扫码支付, subscription-订阅支付 + 'order_amount' => $order_amount,//订单金额 + 'course_id' => $params['course_id'],//课程ID + 'class_id' => $params['class_id'],//班级ID + 'staff_id' => $params['staff_id'],//员工表ID + 'resource_id' => $params['resource_id'],//客户资源表id + ]; + + + + + + $res = (new OrderTableService())->addData($data); + + if (!$res['code']) { + return fail($res['msg']); + } + + return success([]); + } +} diff --git a/niucloud/app/api/route/route.php b/niucloud/app/api/route/route.php index 8d542f04..b0d47cd4 100644 --- a/niucloud/app/api/route/route.php +++ b/niucloud/app/api/route/route.php @@ -183,6 +183,11 @@ Route::group(function () { //获取微信小程序openid Route::post('common/getMiniWxOpenId', 'apiController.Common/getMiniWxOpenId'); + //公共端-获取全部课程列表 + Route::get('common/getCourseAll', 'apiController.Common/getCourseAll'); + //公共端-获取全部班级列表 + Route::get('common/getClassAll', 'apiController.Common/getClassAll'); + @@ -267,6 +272,13 @@ Route::group(function () { //员工端-用户聊天-修改未读消息数量 Route::post('chat/editUnreadCount', 'apiController.Chat/editUnreadCount'); + //员工端-订单管理-列表 + Route::get('orderTable', 'apiController.OrderTable/index'); + //员工端-订单管理-详情 + Route::get('orderTable/info', 'apiController.OrderTable/info'); + //员工端-订单管理-创建 + Route::post('orderTable/add', 'apiController.OrderTable/add'); + diff --git a/niucloud/app/model/order_table/OrderTable.php b/niucloud/app/model/order_table/OrderTable.php index 04532570..2c2d28c3 100644 --- a/niucloud/app/model/order_table/OrderTable.php +++ b/niucloud/app/model/order_table/OrderTable.php @@ -78,19 +78,22 @@ class OrderTable extends BaseModel - + //客户资源表-客户姓名 public function customerResources(){ return $this->hasOne(CustomerResources::class, 'id', 'resource_id')->joinType('left')->withField('name,id')->bind(['resource_id_name'=>'name']); } + //课程表-课程名称 public function course(){ return $this->hasOne(Course::class, 'id', 'course_id')->joinType('left')->withField('course_name,id')->bind(['course_id_name'=>'course_name']); } + //班级表-班级名称 public function classGrade(){ return $this->hasOne(ClassGrade::class, 'id', 'class_id')->joinType('left')->withField('class_name,id')->bind(['class_id_name'=>'class_name']); } + //员工表-员工姓名 public function personnel(){ return $this->hasOne(Personnel::class, 'id', 'staff_id')->joinType('left')->withField('name,id')->bind(['staff_id_name'=>'name']); } diff --git a/niucloud/app/service/api/apiService/CommonService.php b/niucloud/app/service/api/apiService/CommonService.php index 1f0e82cf..2e31b14a 100644 --- a/niucloud/app/service/api/apiService/CommonService.php +++ b/niucloud/app/service/api/apiService/CommonService.php @@ -11,6 +11,8 @@ namespace app\service\api\apiService; +use app\model\class_grade\ClassGrade; +use app\model\course\Course; use app\model\dict\Dict; use app\model\member\Member; use app\model\sys\SysConfig; @@ -265,5 +267,29 @@ class CommonService extends BaseApiService ]; } + //获取全部课程列表 + public function getCourseAllList(array $where, string $field = '*') + { + $model = (new Course()); + $res = $model->field($field) + ->select() + ->toArray();//员工信息 + return $res; + } + + //获取全部班级列表 + public function getClassAllList(array $where, string $field = '*') + { + $model = (new ClassGrade()); + if(!empty($where['status'])){ + $model = $model->where('status',$where['status']); + } + $res = $model->field($field) + ->select() + ->toArray();//员工信息 + return $res; + } + + } diff --git a/niucloud/app/service/api/apiService/OrderTableService.php b/niucloud/app/service/api/apiService/OrderTableService.php new file mode 100644 index 00000000..09989091 --- /dev/null +++ b/niucloud/app/service/api/apiService/OrderTableService.php @@ -0,0 +1,128 @@ +getPageParam();//获取请求参数中的页码+分页数 + $page = $page_params['page']; + $limit = $page_params['limit']; + + $model = new OrderTable(); + //员工表id + if (!empty($where['staff_id'])) { + $model = $model->where('staff_id', $where['staff_id']); + } + + //客户资源表id + if (!empty($where['resource_id'])) { + $model = $model->where('resource_id', $where['resource_id']); + } + + $data = $model + ->append([ + 'customerResources', + 'course', + 'classGrade', + 'personnel' + ]) + ->order('id','desc') + ->paginate([ + 'list_rows' => $limit, + 'page' => $page, + ])->toArray(); + + return $data; + } + + //查询详情 + public function getInfo(array $where) + { + $model = new OrderTable(); + //判断用没有员工id + if (!empty($where['staff_id'])) { + $model = $model->where('staff_id', $where['staff_id']); + } + //判断用没有客户资源id + if (!empty($where['resource_id'])) { + $model = $model->where('resource_id', $where['resource_id']); + } + $data = $model + ->append([ + 'customerResources', + 'course', + 'classGrade', + 'personnel' + ]) + ->find(); + + + if ($data) { + $data = $data->toArray(); + $res = [ + 'code' => 1, + 'msg' => '操作成功', + 'data' => $data + ]; + return $res; + } else { + $res = [ + 'code' => 0, + 'msg' => '暂无数据', + 'data' => [] + ]; + return $res; + } + } + + //创建订单 + public function addData(array $data) + { + $success = OrderTable::create($data); + + $res = [ + 'code' => 1, + 'msg' => '操作成功', + 'data' => [] + ]; + if (!$success) { + $res = [ + 'code' => 0, + 'msg' => '操作失败', + 'data' => [] + ]; + } + return $res; + } +} From 1a8c90142731fc1f071dec54a35b850e76a7d31a Mon Sep 17 00:00:00 2001 From: liutong <836164388@qq.com> Date: Fri, 13 Jun 2025 17:56:40 +0800 Subject: [PATCH 08/13] =?UTF-8?q?feat(api):=20=E6=B7=BB=E5=8A=A0=E5=AD=A6?= =?UTF-8?q?=E7=94=9F=E7=AB=AF=E8=AE=A2=E5=8D=95=E7=AE=A1=E7=90=86=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增学生端订单管理列表接口 - 新增学生端订单管理详情接口 - 新增学生端订单管理创建接口 --- niucloud/app/api/route/route.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/niucloud/app/api/route/route.php b/niucloud/app/api/route/route.php index b0d47cd4..b283bfb9 100644 --- a/niucloud/app/api/route/route.php +++ b/niucloud/app/api/route/route.php @@ -396,6 +396,13 @@ Route::group(function () { //学生端-作业详情 Route::get('xy/assignment/info', 'apiController.Assignment/info'); + //学生端-订单管理-列表 + Route::get('xy/orderTable', 'apiController.OrderTable/index'); + //学生端-订单管理-详情 + Route::get('xy/orderTable/info', 'apiController.OrderTable/info'); + //学生端-订单管理-创建 + Route::post('xy/orderTable/add', 'apiController.OrderTable/add'); + From 49e36aef45281202cce8f764eaad48778e544d28 Mon Sep 17 00:00:00 2001 From: LLL <15374889135@163.com> Date: Fri, 13 Jun 2025 18:15:50 +0800 Subject: [PATCH 09/13] =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/controller/apiController/ClassApi.php | 39 ++++++++++++++- niucloud/app/api/route/route.php | 3 +- .../apiService/TeachingResearchService.php | 11 ++--- .../service/api/apiService/jlClassService.php | 47 ++++++++++++++++++- 4 files changed, 89 insertions(+), 11 deletions(-) diff --git a/niucloud/app/api/controller/apiController/ClassApi.php b/niucloud/app/api/controller/apiController/ClassApi.php index 24b8d248..d8c22f2a 100644 --- a/niucloud/app/api/controller/apiController/ClassApi.php +++ b/niucloud/app/api/controller/apiController/ClassApi.php @@ -69,6 +69,20 @@ class ClassApi extends BaseApiService 'id' => $id, ]; $res = (new PhysicalTestService())->getInfo($where); + $physicalTestReport = []; + if (isset($res['data']['physical_test_report'])) { + $value = $res['data']['physical_test_report']; + if (is_string($value)) { + if (strpos($value, ',') !== false) { + $physicalTestReport = array_map('trim', explode(',', $value)); + } else { + $physicalTestReport = [$value]; + } + } elseif (is_array($value)) { + $physicalTestReport = $value; + } + } + $res['data']['physical_test_report'] = $physicalTestReport; if(!$res['code']){ return fail($res['msg']); } @@ -96,19 +110,40 @@ class ClassApi extends BaseApiService //添加作业 public function addJlPublishJob(Request $request) { + $id = $this->member_id; $data = $this->request->params([ ["class_id",0], ["classes_id_name",''], - ["content_text",''], + ["description",''], ["content_type",''], ["course_id",0], ["course_id_name",''], ["student_id",''], ["students_ids_name",''], ["type",''], + ["personnel_id",$id], ]); + if (isset($data['student_id'])) { + if (is_string($data['student_id']) && strpos($data['student_id'], ',') !== false) { + $studentIds = explode(',', $data['student_id']); + $studentIds = array_map('trim', $studentIds); + } elseif (is_array($data['student_id'])) { + $studentIds = $data['student_id']; + } else { + $studentIds = [(string)$data['student_id']]; + } + $studentIds = array_map('intval', $studentIds); + } else { + $studentIds = []; + } + $data['student_id'] = $studentIds; return success('操作成功', (new jlClassService())->addPublishJob($data)); } - + //获取我的页面统计个数 + public function getStatisticsInfo() + { + $id = $this->member_id; + return success('操作成功', (new jlClassService())->getStatisticsInfo($id)); + } } diff --git a/niucloud/app/api/route/route.php b/niucloud/app/api/route/route.php index 8d542f04..c235ec91 100644 --- a/niucloud/app/api/route/route.php +++ b/niucloud/app/api/route/route.php @@ -277,7 +277,8 @@ Route::group(function () { - + //添加作业 + Route::get('class/Statistics/info', 'apiController.classApi/getStatisticsInfo'); //添加作业 Route::get('class/jlPublishJob/add', 'apiController.classApi/addJlPublishJob'); //添加作业-获取课程列表 diff --git a/niucloud/app/service/api/apiService/TeachingResearchService.php b/niucloud/app/service/api/apiService/TeachingResearchService.php index 547949a0..d8d696e6 100644 --- a/niucloud/app/service/api/apiService/TeachingResearchService.php +++ b/niucloud/app/service/api/apiService/TeachingResearchService.php @@ -59,12 +59,11 @@ class TeachingResearchService extends BaseApiService $field = 'id,title,image,type,content,status,create_time,update_time,delete_time,table_type,user_permission,url,exam_papers_id'; $LessonCourseTeaching = new LessonCourseTeaching(); $info = $LessonCourseTeaching->field($field)->where([['id', "=", $id]])->findOrEmpty()->toArray(); - if (is_array($info) && isset($info['type']) && $info['type'] == 2 && !empty($info['url']) && is_string($info['url'])) { - $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https://" : "http://"; - $domain = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? 'localhost'; - $info['url'] = $protocol . $domain . '/' . $info['url']; - } - +// if (is_array($info) && isset($info['type']) && $info['type'] == 2 && !empty($info['url']) && is_string($info['url'])) { +// $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https://" : "http://"; +// $domain = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? 'localhost'; +// $info['url'] = $protocol . $domain . '/' . $info['url']; +// } return $info; } diff --git a/niucloud/app/service/api/apiService/jlClassService.php b/niucloud/app/service/api/apiService/jlClassService.php index 115420f4..e1565f72 100644 --- a/niucloud/app/service/api/apiService/jlClassService.php +++ b/niucloud/app/service/api/apiService/jlClassService.php @@ -12,6 +12,7 @@ namespace app\service\api\apiService; use app\model\class_grade\ClassGrade; +use app\model\course_schedule\CourseSchedule; use app\model\student\Student; use app\model\assignment\Assignment; use app\model\course\Course; @@ -148,9 +149,51 @@ class jlClassService extends BaseApiService public function addPublishJob($data) { $Assignment = new Assignment(); - $res = $Assignment->create($data); - return $res; + foreach ($data['student_id'] as $v) { + $data['student_id'] = $v; + $Assignment->create($data); + } + return true; } + public function getStatisticsInfo($id) + { + $CourseSchedule = new CourseSchedule(); + $courseNum = $CourseSchedule->where('coach_id', $id)->count(); + $classNum = $this->model->where('head_coach', $id)->count(); + $studentInfo = $this->model->where('head_coach', $id) + ->with(['classPersonnelRel' => function($query) { + $query->select(); + }]); + $studentInfo = $studentInfo->select()->toArray(); + $studentNum = 0; + foreach ($studentInfo as $v){ + $studentNum += count($v['classPersonnelRel']); + } + // 获取当前时间戳 + $now = time(); + $firstDayOfMonth = date('Y-m-01', $now); + $lastDayOfMonth = date('Y-m-t', $now); + $classMonthNum = $this->model->where('head_coach', $id)->whereBetween('created_at', [$firstDayOfMonth, $lastDayOfMonth])->count(); + $courseMonthNum = $CourseSchedule->where('coach_id', $id)->whereBetween('course_date', [$firstDayOfMonth, $lastDayOfMonth])->count(); + $studentMonthInfo = $this->model->where('head_coach', $id)->whereBetween('created_at', [$firstDayOfMonth, $lastDayOfMonth]) + ->with(['classPersonnelRel' => function($query) { + $query->select(); + }]); + $studentMonthInfo = $studentMonthInfo->select()->toArray(); + $studentMonthNum = 0; + foreach ($studentMonthInfo as $v){ + $studentMonthNum += count($v['classPersonnelRel']); + } + $arr = [ + 'courseNum' => $courseNum, + 'classNum' => $classNum, + 'studentNum' => $studentNum, + 'classMonthNum' => $classMonthNum, + 'courseMonthNum' => $courseMonthNum, + 'studentMonthNum' => $studentMonthNum, + ]; + return $arr; + } } From a76319e4904fa6ae43fe553a5ec19fb2555198ac Mon Sep 17 00:00:00 2001 From: wangzeyan <258785420@qq.com> Date: Fri, 13 Jun 2025 20:28:23 +0800 Subject: [PATCH 10/13] =?UTF-8?q?feat(app):=20=E6=B7=BB=E5=8A=A0=E8=B5=84?= =?UTF-8?q?=E6=BA=90=E8=87=AA=E5=8A=A8=E5=88=86=E9=85=8D=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=B9=B6=E4=BC=98=E5=8C=96=E5=AE=A2=E6=88=B7=E8=B5=84=E6=BA=90?= =?UTF-8?q?=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增资源自动分配任务和相关配置 - 客户资源添加和编辑接口增加角色类型和体验课数量字段 - 统计接口增加已分配资源数量统计 - 优化客户资源查询和日志列表接口 --- admin/src/app/views/setting/system.vue | 42 ++++--- .../app/adminapi/controller/sys/Config.php | 3 +- .../apiController/CustomerResources.php | 108 +++++++++--------- .../controller/apiController/Statistics.php | 23 +++- niucloud/app/common.php | 51 ++++++--- niucloud/app/dict/schedule/schedule.php | 13 +++ .../job/custmer/ResourceAutoAllocation.php | 20 ++++ .../custom/SalesPerformanceListener.php | 3 +- .../CustomerResourcesService.php | 70 +++++++----- 9 files changed, 213 insertions(+), 120 deletions(-) create mode 100644 niucloud/app/job/custmer/ResourceAutoAllocation.php diff --git a/admin/src/app/views/setting/system.vue b/admin/src/app/views/setting/system.vue index be1bcacb..f0d4ccc3 100644 --- a/admin/src/app/views/setting/system.vue +++ b/admin/src/app/views/setting/system.vue @@ -87,25 +87,36 @@ - -

{{ t('serviceInformation') }}

+ + - - --> + + + + + + + + + + + + + + + + + +

市场配置

+ + - - - - - -
@@ -154,6 +165,7 @@ const formData = reactive>({ wechat_code: '', enterprise_wechat: '', tel: '', + auto_distribution_time: '', }) const setFormData = async () => { diff --git a/niucloud/app/adminapi/controller/sys/Config.php b/niucloud/app/adminapi/controller/sys/Config.php index a373f7e9..406a5280 100644 --- a/niucloud/app/adminapi/controller/sys/Config.php +++ b/niucloud/app/adminapi/controller/sys/Config.php @@ -49,7 +49,8 @@ class Config extends BaseAdminController [ "front_end_name", "" ], [ "front_end_logo", "" ], [ "front_end_icon", "" ], - [ "icon", "" ] + [ "icon", "" ], + [ "auto_distribution_time", "" ], ]); (new ConfigService())->setWebSite($data); diff --git a/niucloud/app/api/controller/apiController/CustomerResources.php b/niucloud/app/api/controller/apiController/CustomerResources.php index 4f8afca8..ffcf7027 100644 --- a/niucloud/app/api/controller/apiController/CustomerResources.php +++ b/niucloud/app/api/controller/apiController/CustomerResources.php @@ -11,6 +11,7 @@ namespace app\api\controller\apiController; +use app\model\personnel\Personnel; use app\Request; use app\service\api\apiService\CustomerResourcesService; use core\base\BaseApiService; @@ -25,44 +26,50 @@ class CustomerResources extends BaseApiService //获取全部客户资源 - public function getAll(Request $request){ + public function getAll(Request $request) + { $name = $request->param('name', '');//客户姓名 $phone_number = $request->param('phone_number', '');//客户手机号 - if(empty($name) && empty($phone_number)){ + if (empty($name) && empty($phone_number)) { return fail("缺少查询参数"); } $where = [ - 'name'=>$name, - 'phone_number'=>$phone_number + 'name' => $name, + 'phone_number' => $phone_number ]; $res = (new CustomerResourcesService())->getAll($where); - if(!$res['code']){ + if (!$res['code']) { return fail($res['msg']); } return success($res['data']); } //客户资源添加 - public function add(Request $request){ + public function add(Request $request) + { $date = date('Y-m-d'); $promised_visit_time = $request->param('promised_visit_time', ''); - if($promised_visit_time){ - $promised_visit_time = date('Y-m-d H:i:s',strtotime($promised_visit_time)); + if ($promised_visit_time) { + $promised_visit_time = date('Y-m-d H:i:s', strtotime($promised_visit_time)); } $optional_class_time = $request->param('optional_class_time', ''); - if($optional_class_time){ - $optional_class_time = date('Y-m-d H:i:s',strtotime($optional_class_time)); - } - + if ($optional_class_time) { + $optional_class_time = date('Y-m-d H:i:s', strtotime($optional_class_time)); + } + $personnel = new Personnel(); + $role_id = $personnel->alias("a") + ->join(['school_campus_person_role' => 'b'], 'a.id = b.person_id', 'left') + ->where(['a.id' => $request->param('consultant', '')]) + ->value('b.role_id'); $customer_resources_data = [ - "create_year_month"=>date('Y-m'), - "create_date"=>date('Y-m-d'), + "create_year_month" => date('Y-m'), + "create_date" => $date, "source_channel" => $request->param('source_channel', ''), "source" => $request->param('source', ''), "consultant" => $request->param('consultant', ''), @@ -78,6 +85,9 @@ class CustomerResources extends BaseApiService "cognitive_idea" => $request->param('cognitive_idea', ''), "optional_class_time" => $optional_class_time, "distance" => $request->param('distance', ''), +// 新资源有2节体验课 + "trial_class_count" => 2, + "rf_type" => get_role_type($role_id), ]; $six_speed_data = [ @@ -90,61 +100,56 @@ class CustomerResources extends BaseApiService "staff_id" => $request->param('staff_id', ''),//人员ID ]; - foreach($customer_resources_data as $k=>$v){ - if(!isset($v) || $v === ''){ - return fail("缺少必填项{$k}"); - } - } - if (strlen($customer_resources_data['phone_number']) > 12) { return fail("联系电话不能超过12位"); } - foreach($six_speed_data as $k=>$v){ - if(!isset($v) || $v === ''){ + foreach ($six_speed_data as $k => $v) { + if (!isset($v) || $v === '') { return fail("缺少必填项{$k}"); } } //验证手机号是否存在 - $info = (new CustomerResourcesService())->getInfo(['phone_number'=>$customer_resources_data['phone_number']]); - if(!empty($info['data']['id'])){ + $info = (new CustomerResourcesService())->getInfo(['phone_number' => $customer_resources_data['phone_number']]); + if (!empty($info['data']['id'])) { return fail("手机号已存在"); } - $res = (new CustomerResourcesService())->addData($customer_resources_data,$six_speed_data); - if(!$res['code']){ + $res = (new CustomerResourcesService())->addData($customer_resources_data, $six_speed_data); + if (!$res['code']) { return fail($res['msg']); } return success([]); } //客户资源-编辑 - public function edit(Request $request){ + public function edit(Request $request) + { $resource_sharing_id = $request->param('resource_sharing_id', '');//资源共享id $customer_resources_id = $request->param('id', '');//客户资源表id $promised_visit_time = $request->param('promised_visit_time', ''); - if($promised_visit_time){ - $promised_visit_time = date('Y-m-d H:i:s',strtotime($promised_visit_time)); + if ($promised_visit_time) { + $promised_visit_time = date('Y-m-d H:i:s', strtotime($promised_visit_time)); } $optional_class_time = $request->param('optional_class_time', ''); - if($optional_class_time){ - $optional_class_time = date('Y-m-d H:i:s',strtotime($optional_class_time)); + if ($optional_class_time) { + $optional_class_time = date('Y-m-d H:i:s', strtotime($optional_class_time)); } - if(empty($customer_resources_id)){ + if (empty($customer_resources_id)) { return fail("缺少客户id"); } - $where=[ - 'id'=>$customer_resources_id + $where = [ + 'id' => $customer_resources_id ]; //客户资源数据 @@ -179,8 +184,8 @@ class CustomerResources extends BaseApiService "second_visit_status" => $request->param('second_visit_status', null),//二访情况 ]; - foreach($customer_resources_data as $k=>$v){ - if(!isset($v) || $v === ''){ + foreach ($customer_resources_data as $k => $v) { + if (!isset($v) || $v === '') { return fail("缺少必填项{$k}"); } } @@ -190,51 +195,52 @@ class CustomerResources extends BaseApiService } //如果六要素人员id没有就是当前登录人的员工id - if(empty($six_speed_data['staff_id'])){ + if (empty($six_speed_data['staff_id'])) { $six_speed_data['staff_id'] = $this->member_id; } - foreach($six_speed_data as $k=>$v){ + foreach ($six_speed_data as $k => $v) { // 排除 first_visit_status 和 second_visit_status 的必填校验 if (in_array($k, ['first_visit_status', 'second_visit_status'])) { continue; } - if(!isset($v) || $v === ''){ + if (!isset($v) || $v === '') { return fail("缺少必填项{$k}"); } } - $res = (new CustomerResourcesService())->editData($where,$customer_resources_data,$six_speed_data); - if(!$res['code']){ + $res = (new CustomerResourcesService())->editData($where, $customer_resources_data, $six_speed_data); + if (!$res['code']) { return fail($res['msg']); } return success([]); } //客户资源-修改记录列表 - public function getEditLogList(Request $request){ + public function getEditLogList(Request $request) + { //前端要传递分页(page,limit)参数 - $customer_resource_id = $request->param('customer_resource_id',''); - $type = $request->param('type','resource');//查询类型|resource=客户资源,six_speed=六要素 + $customer_resource_id = $request->param('customer_resource_id', ''); + $type = $request->param('type', 'resource');//查询类型|resource=客户资源,six_speed=六要素 - if(empty($customer_resource_id) || empty($type)){ + if (empty($customer_resource_id) || empty($type)) { return fail('缺少必要参数'); } - if(!in_array($type,['resource','six_speed'])){ + if (!in_array($type, ['resource', 'six_speed'])) { return fail('类型不正确'); } $where = [ - 'customer_resource_id' =>$customer_resource_id + 'customer_resource_id' => $customer_resource_id ]; - if($type == 'resource'){ + if ($type == 'resource') { //resource=客户资源 - $res =(new CustomerResourcesService())->getCustomerResourceChangesEditLog($where); - }else{ - $res =(new CustomerResourcesService())->getSixSpeedModificationEditLog($where); + $res = (new CustomerResourcesService())->getCustomerResourceChangesEditLog($where); + } else { + $res = (new CustomerResourcesService())->getSixSpeedModificationEditLog($where); } return success($res); diff --git a/niucloud/app/api/controller/apiController/Statistics.php b/niucloud/app/api/controller/apiController/Statistics.php index 19e6c2e2..0ed9996e 100644 --- a/niucloud/app/api/controller/apiController/Statistics.php +++ b/niucloud/app/api/controller/apiController/Statistics.php @@ -14,6 +14,8 @@ namespace app\api\controller\apiController; use app\Request; use app\service\api\apiService\CommonService; use core\base\BaseApiService; +use app\model\customer_resources\CustomerResources; +use think\facade\Db; /** * 统计控制器相关接口 @@ -43,15 +45,28 @@ class Statistics extends BaseApiService if(in_array('market',$role_key_arr) || in_array('market_manager',$role_key_arr)){ //市场人员统计数据(地推拉人头的) + $monthtotal = CustomerResources::where('consultant',$personnel_id)->where('create_time','between',[$firstDayOfMonth,$lastDayOfMonth])->count('id'); + $alltotal = CustomerResources::where('consultant',$personnel_id)->count('id'); + //已分配的数量 + $yfpsl = Db::table('school_resource_sharing') + ->whereIn('resource_id', function($query) { + $query->table('school_customer_resources') + ->where('consultant', 1) + ->field('id'); + }) + ->where('user_id', '!=', 1) + ->group('resource_id') + ->count(); $data = [ 'date_range'=>$dateRange,//拼接日期范围字符串 'role_type'=>'market_type',//角色类型|market_type=市场,sale_type=销售 +// 本月总数 //本月 'month' => [ - 'new_total' => ($newTotal = rand(100, 500)),//拉新总人数 - 'new_total_rate' => min(100, round($newTotal / 1000 * 100, 2)),//拉新总人数比例(不超过100%) - 'assigned_sales' => ($assignedSales = rand(50, 300)),//已分配给销售的人数 - 'assigned_sales_rate' => min(100, round($assignedSales / $newTotal * 100, 2)),//已分配给销售的人数比例(不超过100%) + 'new_total' => $monthtotal,//拉新总人数 + 'new_total_rate' => $alltotal ? round($monthtotal/$alltotal*100,2) : 0,//拉新总人数比例(不超过100%) + 'assigned_sales' => $yfpsl, + 'assigned_sales_rate' => $alltotal ? round($yfpsl/$alltotal*100,2) : 0,//已分配给销售的人数比例(不超过100%) 'yesterday_new' => ($yesterdayNew = rand(5, 50)),//昨日拉新 'yesterday_new_rate' => min(100, round($yesterdayNew / $newTotal * 100, 2)),//昨日拉新比例(不超过100%) 'today_new' => ($todayNew = rand(1, 20)),//今日拉新 diff --git a/niucloud/app/common.php b/niucloud/app/common.php index bba165f5..86381b34 100644 --- a/niucloud/app/common.php +++ b/niucloud/app/common.php @@ -1030,18 +1030,18 @@ function get_last_time($time = null) return $text; } -function get_campus_where($user_id,$field="campus_id") +function get_campus_where($user_id, $field = "campus_id") { $where = []; $person = new Personnel(); $campusPersonRole = new CampusPersonRole(); - if($user_id > 1){ + if ($user_id > 1) { $person_id = $person->where(['sys_user_id' => $user_id])->value("id"); $role_info = $campusPersonRole->where(['person_id' => $person_id])->find(); - if (!in_array($role_info['role_id'], [1,7,8])) { - if($role_info['campus_id']){ - $where[] = [$field,'=',$role_info['campus_id']]; + if (!in_array($role_info['role_id'], [1, 7, 8])) { + if ($role_info['campus_id']) { + $where[] = [$field, '=', $role_info['campus_id']]; } } } @@ -1144,6 +1144,7 @@ function decryptWechatPayNotify($ciphertext, $nonce, $associatedData, $key) $associatedData ); } + /** * 判断是否为手机号 */ @@ -1154,12 +1155,13 @@ function isPhone($mobile) /** * 体测评分 - * @param int $age年龄 - * @param int $gender性别( 1:男,2:女) - * @param int $height身高 - * @param int $weight体重 + * @param int $age年龄 + * @param int $gender性别( 1:男,2:女) + * @param int $height身高 + * @param int $weight体重 */ -function calculateChildHealthScore($age, $gender, $height, $weight) { +function calculateChildHealthScore($age, $gender, $height, $weight) +{ // WHO 标准数据(简化版)——单位:cm/kg // 示例使用中位数及上下限估算(实际可使用更精确的Z-score或百分位表) @@ -1220,13 +1222,13 @@ function calculateChildHealthScore($age, $gender, $height, $weight) { } -function get_dict_value($key,$value){ +function get_dict_value($key, $value) +{ $dict = new \app\model\dict\Dict(); $field = 'id,name,key,dictionary,memo,create_time,update_time'; $info = $dict->field($field)->where([['key', '=', $key]])->findOrEmpty()->toArray(); - if($info['dictionary'] == null) - { + if ($info['dictionary'] == null) { $info['dictionary'] = []; } @@ -1242,11 +1244,26 @@ function get_dict_value($key,$value){ //$date = 年月 $campus_person_role_id 人员角色表id //$field complete_num 完成数量 expire_num 到期数量 renew_num 续费数量 resource_num 分配的资源数量 visit_num 到访数量 //$num 增加数量 默认1 -function set_summary($date,$campus_person_role_id,$field,$num=1){ +function set_summary($date, $campus_person_role_id, $field, $num = 1) +{ $personnel_summary = new PersonnelSummary(); $personnel_summary->where([ - ['task_date','=',$date], - ['campus_person_role_id','=',$campus_person_role_id] - ])->inc($field,$num)->update(); + ['task_date', '=', $date], + ['campus_person_role_id', '=', $campus_person_role_id] + ])->inc($field, $num)->update(); return true; } + +/** + * 根据角色id获取角色类型 + */ +function get_role_type($role_id) +{ + $role_type = [ + 1 => 'market', + 2 => 'sale', + 3 => 'teacher' + ]; + $dept_id = \app\model\sys\SysRole::find($role_id)->value('dept_id'); + return $role_type[$dept_id] ?? 'other'; +} \ No newline at end of file diff --git a/niucloud/app/dict/schedule/schedule.php b/niucloud/app/dict/schedule/schedule.php index d6822344..7709b7e4 100644 --- a/niucloud/app/dict/schedule/schedule.php +++ b/niucloud/app/dict/schedule/schedule.php @@ -22,5 +22,18 @@ return [ ], 'class' => 'app\job\transfer\schedule\CheckFinish', 'function' => '' + ], + [ + 'key' => 'resource_auto_allocation', + 'name' => '自动分配资源', + 'desc' => '', + 'time' => [ + 'type' => 'day', + 'day' => 1, + 'hour' => 0, + 'min' => 5 + ], + 'class' => 'app\job\transfer\schedule\CheckFinish', + 'function' => '' ] ]; diff --git a/niucloud/app/job/custmer/ResourceAutoAllocation.php b/niucloud/app/job/custmer/ResourceAutoAllocation.php new file mode 100644 index 00000000..fb26380c --- /dev/null +++ b/niucloud/app/job/custmer/ResourceAutoAllocation.php @@ -0,0 +1,20 @@ + + //遍历资源列表按照资源数量的最少的人员优先分配 + return true; + } +} \ No newline at end of file diff --git a/niucloud/app/listener/custom/SalesPerformanceListener.php b/niucloud/app/listener/custom/SalesPerformanceListener.php index 9617b924..9650cb42 100644 --- a/niucloud/app/listener/custom/SalesPerformanceListener.php +++ b/niucloud/app/listener/custom/SalesPerformanceListener.php @@ -107,12 +107,13 @@ class SalesPerformanceListener if ($exists) { // 更新已有记录 - return (new PerformanceRecords())->where('id', $exists['id'])->update([ + (new PerformanceRecords())->where('id', $exists['id'])->update([ 'performance_value' => $data['performance_value'], 'order_status' => $data['order_status'], 'remarks' => $data['remarks'], 'updated_at' => date('Y-m-d H:i:s') ]); + return true; } else { // 创建新记录 $data['created_at'] = date('Y-m-d H:i:s'); diff --git a/niucloud/app/service/admin/customer_resources/CustomerResourcesService.php b/niucloud/app/service/admin/customer_resources/CustomerResourcesService.php index e53f7954..82a80a01 100644 --- a/niucloud/app/service/admin/customer_resources/CustomerResourcesService.php +++ b/niucloud/app/service/admin/customer_resources/CustomerResourcesService.php @@ -27,6 +27,7 @@ use app\model\six_speed_modification_log\SixSpeedModificationLog; use app\model\student_courses\StudentCourses; use app\service\admin\member\MemberLabelService; use core\base\BaseAdminService; +use think\facade\Event; /** @@ -94,7 +95,7 @@ class CustomerResourcesService extends BaseAdminService } - $search_model->where(get_campus_where($this->uid,'campus')); + $search_model->where(get_campus_where($this->uid, 'campus')); return $this->pageQuery($search_model, function ($item, $key) { $item = $this->makeUp($item); @@ -111,8 +112,6 @@ class CustomerResourcesService extends BaseAdminService } - - /** * 获取客户资源信息 * @param int $id @@ -156,19 +155,30 @@ class CustomerResourcesService extends BaseAdminService return fail("超级管理员不允许添加资源"); } - if($this->model->where(['phone_number' => $data['phone_number']])->find()){ + if ($this->model->where(['phone_number' => $data['phone_number']])->find()) { return fail("资源重复添加"); } $sixSpeed = new SixSpeed(); -// $data['member_label'] = json_encode($data['member_label']); + $role_id = $personnel->alias("a") + ->join(['school_campus_person_role' => 'b'], 'a.id = b.person_id', 'left') + ->where(['a.id' => $data['consultant']]) + ->value('b.role_id'); + $data['rf_type'] = get_role_type($role_id); +// $data['member_label'] = json_encode($data['member_label']); +// 新资源有2节体验课 + $data['trial_class_count'] = 2; $res = $this->model->create($data); + $event_data = [ + 'customer_resources_id' => $res->id,//客户资源表id + 'event_type' => 'add'//事件类型"add=添加,edit=修改 + ];//事件类型"add=添加,edit=修改 + Event::trigger('CalculatePerformance', $event_data, true); + - $role_id = $personnel->alias("a")->join(['school_campus_person_role' => 'b'], 'a.id = b.person_id', 'left') - ->where(['a.id' => $data['consultant']])->value('b.role_id'); $resourceSharing->insert([ 'resource_id' => $res->id, 'user_id' => $data['consultant'], @@ -218,10 +228,10 @@ class CustomerResourcesService extends BaseAdminService // return fail("操作失败"); // } - if($this->model->where([ - ['phone_number','=',$data['phone_number']], - ['id','<>',$id] - ])->find()){ + if ($this->model->where([ + ['phone_number', '=', $data['phone_number']], + ['id', '<>', $id] + ])->find()) { return fail("资源重复添加"); } @@ -443,7 +453,6 @@ class CustomerResourcesService extends BaseAdminService } - public function log_list(array $data = []) { $customer_resource_changes = new CustomerResourceChanges(); @@ -453,7 +462,6 @@ class CustomerResourcesService extends BaseAdminService } - $search_model = $customer_resource_changes ->alias("a") ->join(['school_personnel' => 'b'], 'a.operator_id = b.id', 'left') @@ -463,26 +471,26 @@ class CustomerResourcesService extends BaseAdminService return $this->pageQuery($search_model, function ($item, $key) { - $fieldZhArr = CustomerResources::FieldZh; + $fieldZhArr = CustomerResources::FieldZh; $modified_fields = json_decode($item['modified_fields'], true); $type = []; foreach ($modified_fields as $key => $value) { $type[] = $fieldZhArr[$value]; } - $item['type'] = implode("
",$type); + $item['type'] = implode("
", $type); $old_values = json_decode($item['old_values'], true); $new_values = json_decode($item['new_values'], true); $values = []; foreach ($old_values as $key => $value) { - $old_value = $this->fields($key,$value); - $new_value = $this->fields($key,$new_values[$key]); + $old_value = $this->fields($key, $value); + $new_value = $this->fields($key, $new_values[$key]); - $values[] = $old_value.'->'.$new_value; + $values[] = $old_value . '->' . $new_value; } - $item['values'] = implode("
",$values); + $item['values'] = implode("
", $values); }); @@ -497,7 +505,6 @@ class CustomerResourcesService extends BaseAdminService } - $search_model = $studentCourses ->alias("a") ->join(['school_student' => 'b'], 'a.student_id = b.id', 'left') @@ -542,41 +549,42 @@ class CustomerResourcesService extends BaseAdminService return $this->pageQuery($search_model, function ($item, $key) { - $arr = ['cash' => '现金支付','scan_code' => '扫码支付','subscription' => '订阅支付']; + $arr = ['cash' => '现金支付', 'scan_code' => '扫码支付', 'subscription' => '订阅支付']; $item['type'] = $arr[$item['payment_type']]; $item['order_status'] = $item['order_status'] == 'pending' ? '待支付' : '已支付'; }); } - public function fields($filed,$value){ - if(!$value){ + public function fields($filed, $value) + { + if (!$value) { return '空'; } $campus = new Campus(); $member_label = new MemberLabel(); switch ($filed) { case 'initial_intent': - return get_dict_value('preliminarycustomerintention',$value); + return get_dict_value('preliminarycustomerintention', $value); break; case 'source': - return get_dict_value('source',$value); + return get_dict_value('source', $value); break; case 'purchasing_power': - return get_dict_value('customer_purchasing_power',$value); + return get_dict_value('customer_purchasing_power', $value); break; case 'cognitive_idea': - return get_dict_value('cognitive_concept',$value); + return get_dict_value('cognitive_concept', $value); break; case 'source_channel': - return get_dict_value('SourceChannel',$value); + return get_dict_value('SourceChannel', $value); break; case 'status': - return get_dict_value('kh_status',$value); + return get_dict_value('kh_status', $value); break; case 'member_label': - $label_name = $member_label->where('label_id','in',$value)->column('label_name'); - return implode("-",$label_name); + $label_name = $member_label->where('label_id', 'in', $value)->column('label_name'); + return implode("-", $label_name); break; case 'campus': return $campus->where(['id' => $value])->value("campus_name"); From cc1a20a70535cc28d471b73038fd6922887ce4d1 Mon Sep 17 00:00:00 2001 From: wangzeyan <258785420@qq.com> Date: Sat, 14 Jun 2025 08:47:12 +0800 Subject: [PATCH 11/13] =?UTF-8?q?feat(app):=20=E6=B7=BB=E5=8A=A0=E8=B5=84?= =?UTF-8?q?=E6=BA=90=E8=87=AA=E5=8A=A8=E5=88=86=E9=85=8D=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=B9=B6=E4=BC=98=E5=8C=96=E5=AE=A2=E6=88=B7=E8=B5=84=E6=BA=90?= =?UTF-8?q?=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增资源自动分配任务和相关配置 - 客户资源添加和编辑接口增加角色类型和体验课数量字段 - 统计接口增加已分配资源数量统计 - 优化客户资源查询和日志列表接口 --- .../apiController/CustomerResources.php | 51 +++++++------------ .../controller/apiController/Statistics.php | 9 ++-- niucloud/app/common.php | 4 +- .../api/apiService/ResourceSharingService.php | 48 +++++++++-------- 4 files changed, 51 insertions(+), 61 deletions(-) diff --git a/niucloud/app/api/controller/apiController/CustomerResources.php b/niucloud/app/api/controller/apiController/CustomerResources.php index ffcf7027..2f144fbe 100644 --- a/niucloud/app/api/controller/apiController/CustomerResources.php +++ b/niucloud/app/api/controller/apiController/CustomerResources.php @@ -51,7 +51,7 @@ class CustomerResources extends BaseApiService { $date = date('Y-m-d'); - + $param = $request->param(); $promised_visit_time = $request->param('promised_visit_time', ''); if ($promised_visit_time) { $promised_visit_time = date('Y-m-d H:i:s', strtotime($promised_visit_time)); @@ -67,24 +67,24 @@ class CustomerResources extends BaseApiService ->join(['school_campus_person_role' => 'b'], 'a.id = b.person_id', 'left') ->where(['a.id' => $request->param('consultant', '')]) ->value('b.role_id'); + $customer_resources_data = [ "create_year_month" => date('Y-m'), "create_date" => $date, - "source_channel" => $request->param('source_channel', ''), - "source" => $request->param('source', ''), - "consultant" => $request->param('consultant', ''), - "name" => $request->param('name', ''), - "age" => $request->param('age', ''), - "gender" => $request->param('gender', ''), - "phone_number" => $request->param('phone_number', ''), - "demand" => $request->param('demand', ''), - "decision_maker" => $request->param('decision_maker', ''), - "initial_intent" => $request->param('initial_intent', ''), - "status" => $request->param('status', ''), - "purchasing_power" => $request->param('purchasing_power', ''), - "cognitive_idea" => $request->param('cognitive_idea', ''), + "source_channel" => $param['source_channel'] ?? '', + "source" => $param['source'] ?? '', + "consultant" => $param['consultant'] ?? 0, + "name" => $param['name'] ?? '', + "gender" => $param['gender'] ?? 'other',//性别 + "phone_number" => $param['phone_number'] ?? '', + "demand" => $param['demand'] ?? '', + "decision_maker" => $param['decision_maker'] ?? 0, + "initial_intent" => $param['initial_intent'] ?? 'low',//客户初步意向度 + "status" => $param['status'] ?? 'pending',//客户状态 + "purchasing_power" => $param['purchasing_power'], + "cognitive_idea" => $param['cognitive_idea'], "optional_class_time" => $optional_class_time, - "distance" => $request->param('distance', ''), + "distance" => $param['distance'], // 新资源有2节体验课 "trial_class_count" => 2, "rf_type" => get_role_type($role_id), @@ -104,19 +104,12 @@ class CustomerResources extends BaseApiService return fail("联系电话不能超过12位"); } - foreach ($six_speed_data as $k => $v) { - if (!isset($v) || $v === '') { - return fail("缺少必填项{$k}"); - } - } - //验证手机号是否存在 $info = (new CustomerResourcesService())->getInfo(['phone_number' => $customer_resources_data['phone_number']]); if (!empty($info['data']['id'])) { return fail("手机号已存在"); } - $res = (new CustomerResourcesService())->addData($customer_resources_data, $six_speed_data); if (!$res['code']) { return fail($res['msg']); @@ -158,12 +151,12 @@ class CustomerResources extends BaseApiService "source" => $request->param('source', ''),//来源 "name" => $request->param('name', ''),//姓名 "age" => $request->param('age', ''),//年龄 - "gender" => $request->param('gender', ''),//性别 + "gender" => $request->param('gender', 'other'),//性别 "phone_number" => $request->param('phone_number', ''),//联系电话 "demand" => $request->param('demand', ''),//需求 "decision_maker" => $request->param('decision_maker', ''),//决策人 - "initial_intent" => $request->param('initial_intent', ''),//客户初步意向度 - "status" => $request->param('status', ''),//客户状态 + "initial_intent" => $request->param('initial_intent', 'low'),//客户初步意向度 + "status" => $request->param('status', 'pending'),//客户状态 "purchasing_power" => $request->param('purchasing_power', ''),//购买力 "cognitive_idea" => $request->param('cognitive_idea', ''),//认知理念 "optional_class_time" => $optional_class_time,//可选上课时间 @@ -184,11 +177,6 @@ class CustomerResources extends BaseApiService "second_visit_status" => $request->param('second_visit_status', null),//二访情况 ]; - foreach ($customer_resources_data as $k => $v) { - if (!isset($v) || $v === '') { - return fail("缺少必填项{$k}"); - } - } if (strlen($customer_resources_data['phone_number']) > 12) { return fail("联系电话不能超过12位"); @@ -204,9 +192,6 @@ class CustomerResources extends BaseApiService if (in_array($k, ['first_visit_status', 'second_visit_status'])) { continue; } - if (!isset($v) || $v === '') { - return fail("缺少必填项{$k}"); - } } diff --git a/niucloud/app/api/controller/apiController/Statistics.php b/niucloud/app/api/controller/apiController/Statistics.php index 0ed9996e..1f9fa5be 100644 --- a/niucloud/app/api/controller/apiController/Statistics.php +++ b/niucloud/app/api/controller/apiController/Statistics.php @@ -45,7 +45,8 @@ class Statistics extends BaseApiService if(in_array('market',$role_key_arr) || in_array('market_manager',$role_key_arr)){ //市场人员统计数据(地推拉人头的) - $monthtotal = CustomerResources::where('consultant',$personnel_id)->where('create_time','between',[$firstDayOfMonth,$lastDayOfMonth])->count('id'); + $monthtotal = CustomerResources::where('consultant',$personnel_id) + ->where('created_at','between',[$firstDayOfMonth,$lastDayOfMonth])->count('id'); $alltotal = CustomerResources::where('consultant',$personnel_id)->count('id'); //已分配的数量 $yfpsl = Db::table('school_resource_sharing') @@ -54,7 +55,7 @@ class Statistics extends BaseApiService ->where('consultant', 1) ->field('id'); }) - ->where('user_id', '!=', 1) + ->where('user_id', '<>', 1) ->group('resource_id') ->count(); $data = [ @@ -68,9 +69,9 @@ class Statistics extends BaseApiService 'assigned_sales' => $yfpsl, 'assigned_sales_rate' => $alltotal ? round($yfpsl/$alltotal*100,2) : 0,//已分配给销售的人数比例(不超过100%) 'yesterday_new' => ($yesterdayNew = rand(5, 50)),//昨日拉新 - 'yesterday_new_rate' => min(100, round($yesterdayNew / $newTotal * 100, 2)),//昨日拉新比例(不超过100%) + 'yesterday_new_rate' => min(100, round($yesterdayNew / $alltotal * 100, 2)),//昨日拉新比例(不超过100%) 'today_new' => ($todayNew = rand(1, 20)),//今日拉新 - 'today_new_rate' => min(100, round($todayNew / $newTotal * 100, 2)),//今日拉新比例(不超过100%) + 'today_new_rate' => min(100, round($todayNew / $alltotal * 100, 2)),//今日拉新比例(不超过100%) ], //上月 'last_month' => [ diff --git a/niucloud/app/common.php b/niucloud/app/common.php index 86381b34..c3e56fb4 100644 --- a/niucloud/app/common.php +++ b/niucloud/app/common.php @@ -1264,6 +1264,6 @@ function get_role_type($role_id) 2 => 'sale', 3 => 'teacher' ]; - $dept_id = \app\model\sys\SysRole::find($role_id)->value('dept_id'); - return $role_type[$dept_id] ?? 'other'; + $dept = \app\model\sys\SysRole::find($role_id); + return $role_type[$dept->dept_id] ?? 'other'; } \ No newline at end of file diff --git a/niucloud/app/service/api/apiService/ResourceSharingService.php b/niucloud/app/service/api/apiService/ResourceSharingService.php index 58a672f9..d8dff106 100644 --- a/niucloud/app/service/api/apiService/ResourceSharingService.php +++ b/niucloud/app/service/api/apiService/ResourceSharingService.php @@ -40,48 +40,51 @@ class ResourceSharingService extends BaseApiService $person_id = $this->member_id;//当前登录的员工id //查当前用户的归属校区 - $campus_id = CampusPersonRole::where('person_id',$person_id) + $campus_id = CampusPersonRole::where('person_id', $person_id) ->distinct(true) ->column('campus_id'); - //查当前用户校区下的全部员工id - $person_id_arr = CampusPersonRole::whereIn('campus_id',$campus_id) - ->distinct(true) - ->column('person_id'); + if ($campus_id) { + //查当前用户校区下的全部员工id + $person_id_arr = CampusPersonRole::whereIn('campus_id', $campus_id) + ->distinct(true) + ->column('person_id'); + } $resource_id_arr = [];//客户资源表id //客户资源表名字 - if(!empty($where['name'])){ + if (!empty($where['name'])) { $resource_id = (new CustomerResources())->where('name', 'like', "%{$where['name']}%")->column('id'); - $resource_id_arr = array_merge($resource_id_arr,$resource_id); + $resource_id_arr = array_merge($resource_id_arr, $resource_id); } //客户资源表手机号 - if(!empty($where['phone_number'])){ + if (!empty($where['phone_number'])) { $resource_id = (new CustomerResources())->where('phone_number', 'like', "%{$where['phone_number']}%")->column('id'); - $resource_id_arr = array_merge($resource_id_arr,$resource_id); + $resource_id_arr = array_merge($resource_id_arr, $resource_id); } //去重 $resource_id_arr = array_unique($resource_id_arr); $model = $this->model; - if($resource_id_arr){ - $model = $model->whereIn('resource_id',$resource_id_arr); - } - - if ((!empty($where['shared_by']) || isset($where['shared_by'])) && $where['shared_by'] !== '') { - $model = $model->where('shared_by', $where['shared_by']); + if ($resource_id_arr) { + $model = $model->whereIn('resource_id', $resource_id_arr); } if (!empty($where['shared_at_arr'])) { $model = $model->where('shared_at', '>=', $where['shared_at_arr'][0])->where('shared_at', '<=', $where['shared_at_arr'][1]); } + $model = $model->when(!empty($person_id_arr), function ($query) use ($person_id_arr) { + $query->whereIn('user_id', $person_id_arr); + }); - $model = $model->whereIn('user_id', $person_id_arr); + if ((!empty($where['shared_by']) || isset($where['shared_by'])) && $where['shared_by'] !== '') { + $model = $model->whereOr('shared_by', $where['shared_by']); + } //分页查询 $res = $model->with([ - 'customerResource'=>function($query){ - $query->append(['initial_intent_name']); + 'customerResource' => function ($query) { + $query->append(['initial_intent_name']); } ])->paginate([ 'list_rows' => $limit, @@ -113,15 +116,16 @@ class ResourceSharingService extends BaseApiService } $data = $model->with([ - 'customerResource'=>function($query){ + 'customerResource' => function ($query) { $query->with([ - 'sixSpeed'=>function($query_2){ + 'sixSpeed' => function ($query_2) { $query_2->append([ 'purchase_power_name',//购买力 'concept_awareness_name',//认知理念 ]); }, - 'personnel'=>function($query_2){} + 'personnel' => function ($query_2) { + } ])->append([ 'source_channel_name',//来源渠道 'source_name',//来源 @@ -133,7 +137,7 @@ class ResourceSharingService extends BaseApiService ]); } ])->field($field)->find(); - if($data){ + if ($data) { $data = $data->toArray(); } if (!empty($data['customerResource'])) { From e4c982a1a2ee51757869df2bfcacbca15bf71b38 Mon Sep 17 00:00:00 2001 From: wangzeyan <258785420@qq.com> Date: Mon, 16 Jun 2025 18:19:10 +0800 Subject: [PATCH 12/13] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E4=BF=9D=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- niucloud/app/common.php | 6 +++++- .../app/service/api/login/LoginService.php | 18 ++++++------------ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/niucloud/app/common.php b/niucloud/app/common.php index c3e56fb4..10d6aa5c 100644 --- a/niucloud/app/common.php +++ b/niucloud/app/common.php @@ -1266,4 +1266,8 @@ function get_role_type($role_id) ]; $dept = \app\model\sys\SysRole::find($role_id); return $role_type[$dept->dept_id] ?? 'other'; -} \ No newline at end of file +} + +/** + * 获取顶级部门 + */ \ No newline at end of file diff --git a/niucloud/app/service/api/login/LoginService.php b/niucloud/app/service/api/login/LoginService.php index 3ce056fa..0cbf1284 100644 --- a/niucloud/app/service/api/login/LoginService.php +++ b/niucloud/app/service/api/login/LoginService.php @@ -371,18 +371,12 @@ class LoginService extends BaseApiService $expire_time = env('system.api_token_expire_time') ?? 3600; //生成token $token_info = TokenAuth::createToken($member_info->id, AppTypeDict::PERSONNEL, ['id' => $member_info->id, 'member_id'=>$member_info->id, 'phone' => $member_info->phone, 'user_type' => $params['login_type']], $expire_time); - event("PersonnelLogin", $member_info); - - //login_type|1=教练,2=销售 - $user_type = '';//1=教练,2=销售 - //判断员工账户的类型是教练还是销售 - if($member_info['account_type']=='market' && $params['login_type'] == 2){ - //销售登陆 - $user_type = 2; - }elseif($member_info['account_type']=='teacher' && $params['login_type'] == 1){ - //教师登陆 - $user_type = 1; - } +// + $depts = (new CampusPersonRole())->where('person_id', $member_info->id)->column('dept_id'); + + $user_type = CampusPersonRole::where('person_id', $member_info->id)-> + $event = event("PersonnelLogin", $member_info); + dd($event); return [ 'token' => $token_info['token'],//token From f80304b9a449919a984df92393f239843baca4fa Mon Sep 17 00:00:00 2001 From: wangzeyan <258785420@qq.com> Date: Mon, 16 Jun 2025 19:08:18 +0800 Subject: [PATCH 13/13] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- niucloud/app/api/controller/login/Login.php | 10 ---------- niucloud/app/service/api/login/LoginService.php | 9 +++------ 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/niucloud/app/api/controller/login/Login.php b/niucloud/app/api/controller/login/Login.php index 2ad930a0..6e2d3426 100644 --- a/niucloud/app/api/controller/login/Login.php +++ b/niucloud/app/api/controller/login/Login.php @@ -125,16 +125,6 @@ class Login extends BaseController ]); //验证码验证 $result = (new LoginService())->loginByPersonnel($data); - - if(!$result['user_type']){ - if($data['login_type'] == 1){ - $msg = '暂无教练权限'; - }else{ - $msg = '暂无销售权限'; - } - return fail($msg);//code|0错误 - } - return success($result);//code|1正确 } diff --git a/niucloud/app/service/api/login/LoginService.php b/niucloud/app/service/api/login/LoginService.php index 0cbf1284..b1537d94 100644 --- a/niucloud/app/service/api/login/LoginService.php +++ b/niucloud/app/service/api/login/LoginService.php @@ -354,6 +354,7 @@ class LoginService extends BaseApiService { //查询员工信息 $member_info = (new Personnel())->where('phone', $params['phone'])->find(); + if(!$member_info){ throw new ApiException('账号不存在'); } @@ -371,13 +372,9 @@ class LoginService extends BaseApiService $expire_time = env('system.api_token_expire_time') ?? 3600; //生成token $token_info = TokenAuth::createToken($member_info->id, AppTypeDict::PERSONNEL, ['id' => $member_info->id, 'member_id'=>$member_info->id, 'phone' => $member_info->phone, 'user_type' => $params['login_type']], $expire_time); -// + //获取用户部门ids(1市场、2教师、3销售) $depts = (new CampusPersonRole())->where('person_id', $member_info->id)->column('dept_id'); - - $user_type = CampusPersonRole::where('person_id', $member_info->id)-> - $event = event("PersonnelLogin", $member_info); - dd($event); - + $user_type = in_array($params['login_type'],$depts) ? $params['login_type'] : ''; return [ 'token' => $token_info['token'],//token 'expires_time' => $token_info['params']['exp'],//过期时间