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.
569 lines
21 KiB
569 lines
21 KiB
<?php
|
|
// +----------------------------------------------------------------------
|
|
// | Niucloud-admin 企业快速开发的多应用管理平台
|
|
// +----------------------------------------------------------------------
|
|
// | 官方网址:https://www.niucloud.com
|
|
// +----------------------------------------------------------------------
|
|
// | niucloud团队 版权所有 开源版本可自由商用
|
|
// +----------------------------------------------------------------------
|
|
// | Author: Niucloud Team
|
|
// +----------------------------------------------------------------------
|
|
|
|
namespace app\service\api\member;
|
|
|
|
use app\model\assignment\Assignment;
|
|
use app\model\attendance\Attendance;
|
|
use app\model\campus\Campus;
|
|
use app\model\class_grade\ClassGrade;
|
|
use app\model\class_resources_rel\ClassResourcesRel;
|
|
use app\model\communication_records\CommunicationRecords;
|
|
use app\model\contract_sign\ContractSign;
|
|
use app\model\course\Course;
|
|
use app\model\course_schedule\CourseSchedule;
|
|
use app\model\member\Member;
|
|
use app\model\person_course_schedule\PersonCourseSchedule;
|
|
use app\model\service_logs\ServiceLogs;
|
|
use app\model\student_courses\StudentCourses;
|
|
use app\service\core\member\CoreMemberService;
|
|
use core\base\BaseApiService;
|
|
use core\exception\ApiException;
|
|
use core\util\Barcode;
|
|
use think\facade\Db;
|
|
use think\facade\Log;
|
|
use think\Model;
|
|
|
|
/**
|
|
* 会员服务层
|
|
* Class MemberService
|
|
* @package app\service\api\member
|
|
*/
|
|
class MemberService extends BaseApiService
|
|
{
|
|
public function __construct()
|
|
{
|
|
parent::__construct();
|
|
$this->model = new Member();
|
|
}
|
|
|
|
/**
|
|
* 新增会员
|
|
*/
|
|
public function add(array $data)
|
|
{
|
|
return $this->model->create($data)?->member_id ?? 0;
|
|
}
|
|
|
|
/**
|
|
* 更新会员
|
|
* @param array $data
|
|
* @return true
|
|
*/
|
|
public function edit(array $data)
|
|
{
|
|
$member = $this->findMemberInfo(['member_id' => $this->member_id]);
|
|
|
|
if ($member->isEmpty()) throw new ApiException('MEMBER_NOT_EXIST');
|
|
$member->allowField(['nickname', 'headimg', 'birthday', 'sex', 'last_visit_time'])->save($data);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 获取会员信息
|
|
* @return array
|
|
*/
|
|
public function getInfo()
|
|
{
|
|
$field = 'member_id, username, member_no, mobile, register_channel, nickname, headimg, member_level, member_label, login_ip, login_type, login_time, create_time, last_visit_time, last_consum_time, sex, status, birthday, point, balance, growth, is_member, member_time, is_del, province_id, city_id, district_id, address, location, money, money_get, wx_openid, weapp_openid, commission, commission_get, commission_cash_outing';
|
|
return $this->model->where([['member_id', '=', $this->member_id]])->with(['member_level_name_bind'])->field($field)->append(['sex_name'])->findOrEmpty()->toArray();
|
|
}
|
|
|
|
/**
|
|
* 检测会员信息是否存在
|
|
* @return int
|
|
*/
|
|
public function getCount($condition)
|
|
{
|
|
return $this->model->where($condition)->count();
|
|
}
|
|
|
|
/**
|
|
* 会员中心信息
|
|
*/
|
|
public function center()
|
|
{
|
|
$field = 'member_id, username, member_no, mobile, register_channel, nickname, headimg, member_level, member_label, login_ip, login_type, login_time, create_time, last_visit_time, last_consum_time, sex, status, birthday, point, balance, growth, is_member, member_time, is_del, province_id, city_id, district_id, address, location, money, money_get, commission, commission_get, commission_cash_outing';
|
|
return $this->model->where([['member_id', '=', $this->member_id]])->field($field)->append(['sex_name'])->findOrEmpty()->toArray();
|
|
}
|
|
|
|
/**
|
|
* 获取会员的模型对象(todo 慎用!!! 现主要用于登录)
|
|
* @param array $data
|
|
* @return Member|array|mixed|Model !!! 仔细看,返回值是模型对象 如果想要判断是否为空 请用 $member->isEmpty()
|
|
*/
|
|
public function findMemberInfo(array $data)
|
|
{
|
|
//会员账号
|
|
if (!empty($data['username']))
|
|
$where[] = ['username', '=', $data['username']];
|
|
//会员手机号
|
|
if (!empty($data['mobile']))
|
|
$where[] = ['mobile', '=', $data['mobile']];
|
|
//会员id
|
|
if (!empty($data['member_id']))
|
|
$where[] = ['member_id', '=', $data['member_id']];
|
|
//微信公众号openid
|
|
if (!empty($data['wx_openid']))
|
|
$where[] = ['wx_openid', '=', $data['wx_openid']];
|
|
//微信小程序openid
|
|
if (!empty($data['weapp_openid']))
|
|
$where[] = ['weapp_openid', '=', $data['weapp_openid']];
|
|
// 微信unionid
|
|
if (!empty($data['wx_unionid']))
|
|
$where[] = ['wx_unionid', '=', $data['wx_unionid']];
|
|
if (!empty($data['username|mobile']))
|
|
$where[] = ['username|mobile', '=', $data['username|mobile']];
|
|
if (empty($where)) {
|
|
$where[] = ['member_id', '=', -1];
|
|
}
|
|
return $this->model->where($where)->findOrEmpty();
|
|
}
|
|
|
|
/**
|
|
* 通过对象修改会员信息
|
|
* @param $member
|
|
* @param $data
|
|
* @return void
|
|
*/
|
|
public function editByFind($member, $data)
|
|
{
|
|
return $member->save($data);
|
|
}
|
|
|
|
/**
|
|
* 修改字段
|
|
* @param string $field
|
|
* @param $data
|
|
* @return null
|
|
*/
|
|
public function modify(string $field, $data)
|
|
{
|
|
return (new CoreMemberService())->modify($this->member_id, $field, $data);
|
|
}
|
|
|
|
public function getQrcode()
|
|
{
|
|
// 生成会员二维码
|
|
$qrcode_dir = 'upload/member/temp';
|
|
if (!is_dir($qrcode_dir)) mkdir($qrcode_dir, intval('0755', 8), true);
|
|
$id = "member-" . $this->member_id;
|
|
$qrcode_path = "{$qrcode_dir}/order_qrcode_{$this->member_id}.png";
|
|
\core\util\QRcode::png($id, $qrcode_path, 'L', 16, 1);
|
|
|
|
// 生成会员条形码
|
|
$barcode_path = (new Barcode(14, $id))->generateBarcode($qrcode_dir, 2);
|
|
$detail = [];
|
|
$detail['verify_code_qrcode'] = image_to_base64($qrcode_path, true);
|
|
$detail['verify_code_barcode'] = image_to_base64($barcode_path);
|
|
return $detail;
|
|
}
|
|
|
|
/**
|
|
* 初始化会员数据
|
|
*/
|
|
public function initMemberData()
|
|
{
|
|
if ($this->member_id) {
|
|
event("MemberLoginAfter", ['member_id' => $this->member_id]);
|
|
}
|
|
}
|
|
|
|
public function get_campuses_list()
|
|
{
|
|
$campus = new Campus();
|
|
$list = $campus->select()->toArray();
|
|
return $list;
|
|
|
|
}
|
|
|
|
/**
|
|
* 日志记录工具方法
|
|
* @param string $level 日志级别
|
|
* @param string $message 日志信息
|
|
* @return void
|
|
*/
|
|
private function log($level, $message) {
|
|
Log::$level('MemberService: ' . $message);
|
|
}
|
|
|
|
public function list_call_up($resource_id)
|
|
{
|
|
$communication = new CommunicationRecords();
|
|
// 添加日志记录以便调试
|
|
$this->log('debug', "list_call_up请求参数: resource_id={$resource_id}");
|
|
|
|
try {
|
|
// 检查resource_id是否有效
|
|
if (empty($resource_id)) {
|
|
$this->log('warning', "list_call_up: resource_id为空");
|
|
return [];
|
|
}
|
|
|
|
// 查询前打印SQL查询条件
|
|
$sqlDebug = "SELECT * FROM school_communication_records WHERE resource_id = '{$resource_id}' ORDER BY communication_time DESC";
|
|
$this->log('debug', "list_call_up对应SQL: {$sqlDebug}");
|
|
|
|
// 执行查询
|
|
$result = $communication->where('resource_id', $resource_id)
|
|
->order('communication_time DESC')
|
|
->select()->toArray();
|
|
|
|
// 如果没有结果,尝试使用原生 SQL 查询检查记录存在性
|
|
if (empty($result)) {
|
|
$this->log('debug', "list_call_up: 主要查询没有结果,尝试直接查询表");
|
|
$rawResult = Db::query("SELECT COUNT(*) as count FROM school_communication_records WHERE resource_id = '{$resource_id}'");
|
|
$count = $rawResult[0]['count'] ?? 0;
|
|
$this->log('debug', "list_call_up: 原生SQL查询结果数量: {$count}");
|
|
|
|
// 如果原生查询有结果但模型查询没结果,尝试直接使用原生查询
|
|
if ($count > 0) {
|
|
$this->log('debug', "list_call_up: 检测到数据存在,使用原生查询获取");
|
|
$result = Db::query("SELECT * FROM school_communication_records WHERE resource_id = '{$resource_id}' ORDER BY communication_time DESC");
|
|
}
|
|
}
|
|
|
|
$this->log('debug', "list_call_up查询结果数量: " . count($result));
|
|
return $result;
|
|
} catch (\Exception $e) {
|
|
$this->log('error', "list_call_up查询异常: " . $e->getMessage());
|
|
return [];
|
|
}
|
|
}
|
|
|
|
public function update_call_up($resource_id, $remarks)
|
|
{
|
|
$campus = new CommunicationRecords();
|
|
return $campus->where('resource_id', $resource_id)->update(['remarks' => $remarks]);
|
|
}
|
|
|
|
public function jl_index(){
|
|
|
|
$schedules = new CourseSchedule();
|
|
$person_course_schedule = new PersonCourseSchedule();
|
|
$Assignment = new Assignment();
|
|
$service_logs = new ServiceLogs();
|
|
$course_list = $schedules
|
|
->alias("a")
|
|
->join(['school_venue' => 'b'],'a.venue_id = b.id','left')
|
|
->join(['school_course' => 'c'],'a.course_id = c.id','left')
|
|
->where([
|
|
['a.status','<>','completed'],
|
|
['a.course_date', 'between', [date('Y-m-d', strtotime('-6 days')), date('Y-m-d')]],
|
|
])
|
|
->where("a.coach_id = {$this->member_id} OR education_id = {$this->member_id} OR find_in_set('{$this->member_id}', a.assistant_ids) ")
|
|
->field("a.id,a.status,c.course_name,a.course_date,a.time_slot,b.venue_name as address,a.student_ids")
|
|
->order("time_slot desc")
|
|
->limit(3)
|
|
->select();
|
|
|
|
if($course_list){
|
|
$course_list = $course_list->toArray();
|
|
foreach ($course_list as $k=>$v){
|
|
$course_list[$k]['students_count'] = $person_course_schedule->where(['schedule_id' => $v['id']])->count();
|
|
$course_list[$k]['sign_count'] = $person_course_schedule->where(['schedule_id' => $v['id'],'status' => 2])->count();
|
|
}
|
|
}
|
|
|
|
//作业列表
|
|
$task_list = $Assignment
|
|
->alias("a")
|
|
->join(['school_class' => 'b'],"a.class_id = b.id","left")
|
|
->join(['school_course' => 'c'],"a.course_id = c.id","left")
|
|
->field("a.id,a.create_time,b.class_name,c.course_name")
|
|
->where([
|
|
'a.personnel_id' => $this->member_id,
|
|
'a.status' => 3
|
|
])
|
|
->limit("5")
|
|
->select();
|
|
|
|
|
|
$service_list = $service_logs
|
|
->alias("a")
|
|
->join(['school_service' => 'b'],"a.service_id = b.id","left")
|
|
->field("a.id,b.service_name,b.description,a.created_at,a.status")
|
|
->where(['staff_id' => $this->member_id])
|
|
->order("a.created_at desc")
|
|
->limit("5")
|
|
->select();
|
|
|
|
return ['course_list' => $course_list,'task_list' => $task_list,'service_list' => $service_list];
|
|
}
|
|
|
|
|
|
public function get_assignments_list(){
|
|
$Assignment = new Assignment();
|
|
$search_model = $Assignment
|
|
->alias("a")
|
|
->join(['school_class' => 'b'],"a.class_id = b.id","left")
|
|
->join(['school_course' => 'c'],"a.course_id = c.id","left")
|
|
->field("a.id,a.create_time,b.class_name,c.course_name,a.status")
|
|
->where([
|
|
'a.personnel_id' => $this->member_id
|
|
])->order("a.create_time desc");
|
|
|
|
$list = $this->pageQuery($search_model, function ($item){
|
|
|
|
});
|
|
|
|
return $list;
|
|
}
|
|
|
|
|
|
|
|
public function assignments_info($data){
|
|
$Assignment = new Assignment();
|
|
|
|
$info = $Assignment
|
|
->alias("a")
|
|
->join(['school_personnel' => 'b'],'a.personnel_id = b.id','left')
|
|
->where(['a.id' => $data['id']])
|
|
->field("a.*,b.name as coach_name,b.head_img as coach_pic")
|
|
->find();
|
|
return $info ? $info->toArray() : [];
|
|
}
|
|
|
|
public function service_detail($data){
|
|
$service_logs = new ServiceLogs();
|
|
$info = $service_logs->alias("a")
|
|
->join(['school_customer_resources' => 'b'],'a.resource_id = b.id',"left")
|
|
->join(['school_course' => 'c'],'a.course_id = c.id',"left")
|
|
->join(['school_service' => 'd'],'a.service_id = d.id',"left")
|
|
->join(['school_personnel' => 'e'],'a.staff_id = e.id',"left")
|
|
->join(['school_campus' => 'f'],'b.campus = f.id',"left")
|
|
->where(['a.id' => $data['id']])
|
|
->field("
|
|
a.id,b.name as resource_id,c.course_name as course_id,d.service_name as service_id,a.service_remark,a.status,
|
|
e.name as staff_id,a.score,a.feedback,a.feedback_time,a.created_at,a.updated_at,f.campus_name as campus,
|
|
b.source_channel,b.source
|
|
")
|
|
->find();
|
|
|
|
$info['source'] = get_dict_value('source',$info['source']);
|
|
$info['channel'] = get_dict_value('SourceChannel',$info['source_channel']);
|
|
|
|
return $info ? $info->toArray() : [];
|
|
}
|
|
|
|
|
|
public function service_list(){
|
|
$service_logs = new ServiceLogs();
|
|
$search_model = $service_logs
|
|
->alias("a")
|
|
->join(['school_service' => 'd'],'a.service_id = d.id',"left")
|
|
->where([
|
|
'a.staff_id' => $this->member_id
|
|
])
|
|
->field("a.*,d.service_name,d.description")
|
|
->order("a.created_at desc");
|
|
|
|
$list = $this->pageQuery($search_model, function ($item){
|
|
|
|
});
|
|
|
|
return $list;
|
|
}
|
|
|
|
//教练下全部学员
|
|
public function student_list($data)
|
|
{
|
|
// 添加调试日志
|
|
Log::debug('MemberService/student_list - 接收参数: ' . json_encode($data));
|
|
|
|
// 创建查询构建器
|
|
$student_courses = new StudentCourses();
|
|
$query = $student_courses
|
|
->alias("a")
|
|
->join(['school_student' => 'b'],"a.student_id = b.id","left")
|
|
->join(['school_campus' => 'c'],'b.campus_id = c.id',"left")
|
|
->join(['school_customer_resources' => 'e'],'e.id = b.user_id',"left")
|
|
->join(['school_member' => 'f'],'f.member_id = e.member_id',"left")
|
|
->join(['school_resource_sharing' => 'g'],'g.resource_id = e.id',"left")
|
|
->where("a.main_coach_id = {$this->member_id} OR a.education_id = {$this->member_id} OR find_in_set('{$this->member_id}', a.assistant_ids) ");
|
|
|
|
// 基础条件:到期时间筛选
|
|
if(isset($data['type']) && $data['type'] == "daoqi"){
|
|
$query->where('a.end_date', 'between', [date('Y-m-d', strtotime('-6 days')), date('Y-m-d')]);
|
|
}
|
|
|
|
// 处理课时数量查询 (gift_hours + total_hours - use_total_hours - use_gift_hours = lessonCount)
|
|
if (!empty($data['lessonCount'])) {
|
|
$query->whereRaw("(a.gift_hours + a.total_hours - a.use_total_hours - a.use_gift_hours) = {$data['lessonCount']}");
|
|
}
|
|
|
|
// 处理课程ID查询
|
|
if (!empty($data['courseId']) && $data['courseId'] !== 'null') {
|
|
$query->where('a.course_id', '=', $data['courseId']);
|
|
}
|
|
|
|
// 处理姓名查询(模糊匹配)
|
|
if (!empty($data['name'])) {
|
|
Log::debug('MemberService/student_list - 添加姓名查询条件: ' . $data['name']);
|
|
$namePattern = '%' . $data['name'] . '%';
|
|
Log::debug('MemberService/student_list - 姓名匹配模式: ' . $namePattern);
|
|
$query->where('e.name', 'like', $namePattern);
|
|
}
|
|
|
|
// 处理手机号查询(模糊匹配)
|
|
if (!empty($data['phone'])) {
|
|
Log::debug('MemberService/student_list - 添加手机号查询条件: ' . $data['phone']);
|
|
$phonePattern = '%' . $data['phone'] . '%';
|
|
Log::debug('MemberService/student_list - 手机号匹配模式: ' . $phonePattern);
|
|
$query->where('e.phone_number', 'like', $phonePattern);
|
|
}
|
|
|
|
// 处理请假次数查询
|
|
if (!empty($data['leaveCount'])) {
|
|
$person_course_schedule = new PersonCourseSchedule();
|
|
$leave_resource_ids = $person_course_schedule
|
|
->field('resources_id')
|
|
->where(['status' => 2]) // 请假状态
|
|
->group('resources_id')
|
|
->having("COUNT(*) = {$data['leaveCount']}")
|
|
->column('resources_id');
|
|
|
|
if (empty($leave_resource_ids)) {
|
|
// 如果没有满足请假次数的资源,返回空结果
|
|
Log::debug('MemberService/student_list - 没有满足请假次数的资源,返回空结果');
|
|
return [];
|
|
}
|
|
|
|
$query->where('e.id', 'in', $leave_resource_ids);
|
|
}
|
|
|
|
// 处理班级ID查询
|
|
if (!empty($data['classId']) && $data['classId'] !== 'null') {
|
|
$class_resources_rel = new ClassResourcesRel();
|
|
$class_resource_ids = $class_resources_rel
|
|
->where(['class_id' => $data['classId']])
|
|
->column('resource_id');
|
|
|
|
if (empty($class_resource_ids)) {
|
|
// 如果班级下没有资源,返回空结果
|
|
Log::debug('MemberService/student_list - 班级下没有资源,返回空结果');
|
|
return [];
|
|
}
|
|
|
|
$query->where('e.id', 'in', $class_resource_ids);
|
|
}
|
|
|
|
// 记录生成的SQL(仅用于调试)
|
|
Log::debug('MemberService/student_list - SQL: ' . $query->buildSql());
|
|
|
|
$list = $query->field("
|
|
b.id,e.name,c.campus_name as campus,
|
|
a.total_hours,a.gift_hours,a.use_total_hours,a.use_gift_hours,a.end_date,f.headimg as avatar,g.id as resource_sharing_id,
|
|
e.phone_number
|
|
")
|
|
->select();
|
|
|
|
$result = $list ? $list->toArray() : [];
|
|
Log::debug('MemberService/student_list - 查询结果数量: ' . count($result));
|
|
|
|
return $result;
|
|
}
|
|
|
|
public function sktj(){
|
|
$course_schedule = new CourseSchedule();
|
|
$student_courses = new StudentCourses();
|
|
$class_resources_rel = new ClassResourcesRel();
|
|
$attendance = new Attendance();
|
|
$year = date('Y');
|
|
$currentMonth = date('n');
|
|
$results = [];
|
|
|
|
for ($m = $currentMonth; $m >= 1; $m--) {
|
|
$start = date("Y-m-01", strtotime("$year-$m"));
|
|
$end = date("Y-m-t", strtotime("$year-$m"));
|
|
|
|
$count = $course_schedule
|
|
->where("coach_id = {$this->member_id} OR education_id = {$this->member_id} OR find_in_set('{$this->member_id}', assistant_ids) ")
|
|
->where('course_date', 'between', [$start, $end])
|
|
->count();
|
|
|
|
|
|
$list = $student_courses
|
|
->where("main_coach_id = {$this->member_id} OR education_id = {$this->member_id} OR find_in_set('{$this->member_id}', assistant_ids) ")
|
|
->where('start_date', 'between', [$start, $end])
|
|
->select();
|
|
|
|
$yfzxy = count($list);
|
|
$class_id = [];
|
|
foreach($list as $k=>$v){
|
|
$class_id[] = $class_resources_rel->where(['resource_id' => $v['resource_id']])->value("class_id");
|
|
}
|
|
|
|
$class_id = array_unique($class_id);
|
|
|
|
$dk_count = $attendance->where(['staff_id' => $this->member_id])->where('attendance_date', 'between', [$start, $end])->count();
|
|
|
|
|
|
if ($count > 0) {
|
|
$rate = round($dk_count / $count * 100, 2); // 保留两位小数
|
|
} else {
|
|
$rate = 0;
|
|
}
|
|
|
|
|
|
$results[] = ['month_date' => "$year-$m",'ysks' => $count,'yfzxy' => $yfzxy,'zsbj' => count($class_id),'ydkl' => $rate];
|
|
|
|
|
|
}
|
|
|
|
return $results;
|
|
}
|
|
|
|
|
|
public function contract_sign(array $data){
|
|
$contract_sign = new ContractSign();
|
|
$signService = (new \app\service\core\contract_sign\ContractSign());
|
|
|
|
$info = $contract_sign
|
|
->alias("a")
|
|
->join(['school_contract' => 'b'],'a.contract_id = b.id',"left")
|
|
->where(['a.id' => $data['contract_sign_id']])
|
|
->field("a.*,b.placeholder")
|
|
->find();
|
|
|
|
|
|
$file_name = 'upload/'.date("YmdHis").time().'.docx';
|
|
$outputPath = root_path() . '/public/'.$file_name;
|
|
|
|
$signService->setSign(
|
|
root_path().'/public/'.$info['sign_file'],
|
|
$outputPath,
|
|
$data['pic_file'],
|
|
$info['placeholder']
|
|
);
|
|
|
|
$contract_sign->where(['id' => $data['contract_sign_id']])->update([
|
|
'sign_file' => $file_name,
|
|
'status' => 2,
|
|
'sign_time' => date('Y-m-d H:i:s')
|
|
]);
|
|
|
|
return true;
|
|
}
|
|
|
|
public function get_classes_list()
|
|
{
|
|
$data['classes'] = ClassGrade::where('status',1)
|
|
->when($this->campus_id, function ($query) {
|
|
$query->where('campus_id', $this->campus_id);
|
|
})
|
|
->select();
|
|
$data['course'] = Course::select();
|
|
return $data;
|
|
}
|
|
|
|
|
|
}
|
|
|