8 changed files with 793 additions and 9 deletions
@ -0,0 +1,95 @@ |
|||||
|
<?php |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | Niucloud-admin 企业快速开发的多应用管理平台 |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网址:https://www.niucloud.com |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | niucloud团队 版权所有 开源版本可自由商用 |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | Author: Niucloud Team |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\adminapi\controller\service_logs; |
||||
|
|
||||
|
use app\service\admin\service_logs\ServiceLogsDistributionService; |
||||
|
use core\base\BaseAdminController; |
||||
|
|
||||
|
/** |
||||
|
* 服务记录分发管理控制器 |
||||
|
* Class ServiceLogsDistribution |
||||
|
* @package app\adminapi\controller\service_logs |
||||
|
*/ |
||||
|
class ServiceLogsDistribution extends BaseAdminController |
||||
|
{ |
||||
|
/** |
||||
|
* 手动执行分发任务 |
||||
|
* @return \think\Response |
||||
|
*/ |
||||
|
public function executeDistribution() |
||||
|
{ |
||||
|
$result = (new ServiceLogsDistributionService())->executeDistribution(); |
||||
|
return success($result); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取分发统计信息 |
||||
|
* @return \think\Response |
||||
|
*/ |
||||
|
public function getDistributionStats() |
||||
|
{ |
||||
|
$result = (new ServiceLogsDistributionService())->getDistributionStats(); |
||||
|
return success($result); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取待分发的服务记录列表 |
||||
|
* @return \think\Response |
||||
|
*/ |
||||
|
public function getPendingDistributionList() |
||||
|
{ |
||||
|
$data = $this->request->params([ |
||||
|
["distribution_status", ""], |
||||
|
["date_range", ""] |
||||
|
]); |
||||
|
|
||||
|
$where = []; |
||||
|
if (!empty($data['distribution_status'])) { |
||||
|
$where['distribution_status'] = $data['distribution_status']; |
||||
|
} |
||||
|
if (!empty($data['date_range'])) { |
||||
|
$where['date_range'] = $data['date_range']; |
||||
|
} |
||||
|
|
||||
|
$result = (new ServiceLogsDistributionService())->getPendingDistributionList($where); |
||||
|
return success($result); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 重置分发状态 |
||||
|
* @return \think\Response |
||||
|
*/ |
||||
|
public function resetDistributionStatus() |
||||
|
{ |
||||
|
$data = $this->request->params([ |
||||
|
["ids", []], |
||||
|
["type", "both"] |
||||
|
]); |
||||
|
|
||||
|
if (empty($data['ids'])) { |
||||
|
return error('请选择要重置的记录'); |
||||
|
} |
||||
|
|
||||
|
$result = (new ServiceLogsDistributionService())->resetDistributionStatus($data['ids'], $data['type']); |
||||
|
return success($result); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取教务和教练人员列表 |
||||
|
* @return \think\Response |
||||
|
*/ |
||||
|
public function getStaffList() |
||||
|
{ |
||||
|
$result = (new ServiceLogsDistributionService())->getStaffList(); |
||||
|
return success($result); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,45 @@ |
|||||
|
<?php |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | Niucloud-admin 企业快速开发的多应用管理平台 |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网址:https://www.niucloud.com |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | niucloud团队 版权所有 开源版本可自由商用 |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | Author: Niucloud Team |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
return [ |
||||
|
'service_log_academic_notice' => [ |
||||
|
'name' => '服务记录教务通知', |
||||
|
'key' => 'service_log_academic_notice', |
||||
|
'sms' => [ |
||||
|
'content' => '尊敬的{staff_name},有新的服务记录需要您查看。服务名称:{service_name},评分:{score}分,创建时间:{created_at}。' |
||||
|
], |
||||
|
'wechat' => [ |
||||
|
'first' => '您有新的服务记录需要查看', |
||||
|
'remark' => '请及时处理相关事务' |
||||
|
], |
||||
|
'weapp' => [ |
||||
|
'title' => '服务记录通知', |
||||
|
'content' => '有新的服务记录需要您查看' |
||||
|
], |
||||
|
'async' => true |
||||
|
], |
||||
|
'service_log_coach_notice' => [ |
||||
|
'name' => '服务记录教练通知', |
||||
|
'key' => 'service_log_coach_notice', |
||||
|
'sms' => [ |
||||
|
'content' => '尊敬的{staff_name}教练,您有一项服务记录已完成。服务名称:{service_name},学员评分:{score}分,学员反馈:{feedback},创建时间:{created_at}。' |
||||
|
], |
||||
|
'wechat' => [ |
||||
|
'first' => '您的服务记录已完成', |
||||
|
'remark' => '请查看学员反馈和评分' |
||||
|
], |
||||
|
'weapp' => [ |
||||
|
'title' => '服务记录完成通知', |
||||
|
'content' => '您的服务记录已完成,请查看详情' |
||||
|
], |
||||
|
'async' => true |
||||
|
] |
||||
|
]; |
||||
@ -0,0 +1,203 @@ |
|||||
|
<?php |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | Niucloud-admin 企业快速开发的多应用管理平台 |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网址:https://www.niucloud.com |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | niucloud团队 版权所有 开源版本可自由商用 |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | Author: Niucloud Team |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\job\schedule; |
||||
|
|
||||
|
use app\model\service_logs\ServiceLogs; |
||||
|
use app\model\personnel\Personnel; |
||||
|
use app\service\core\notice\NoticeService; |
||||
|
use core\base\BaseJob; |
||||
|
use think\facade\Log; |
||||
|
|
||||
|
/** |
||||
|
* 服务记录分发定时任务 |
||||
|
* 用于给教务和教练分发服务记录通知 |
||||
|
*/ |
||||
|
class ServiceLogsDistribution extends BaseJob |
||||
|
{ |
||||
|
/** |
||||
|
* 执行任务 |
||||
|
* @return bool |
||||
|
*/ |
||||
|
public function doJob() |
||||
|
{ |
||||
|
Log::write('服务记录分发任务开始 ' . date('Y-m-d H:i:s')); |
||||
|
|
||||
|
try { |
||||
|
$this->distributeToAcademicAffairs(); |
||||
|
$this->distributeToCoaches(); |
||||
|
Log::write('服务记录分发任务完成 ' . date('Y-m-d H:i:s')); |
||||
|
} catch (\Exception $e) { |
||||
|
Log::write('服务记录分发任务异常: ' . $e->getMessage()); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 给教务分发服务记录 |
||||
|
*/ |
||||
|
private function distributeToAcademicAffairs() |
||||
|
{ |
||||
|
// 获取需要分发的服务记录(最近24小时内完成的记录) |
||||
|
$yesterday = date('Y-m-d H:i:s', strtotime('-1 day')); |
||||
|
$serviceLogs = ServiceLogs::where('status', 1) // 已完成状态 |
||||
|
->where('created_at', '>=', $yesterday) |
||||
|
->where('is_distributed_to_academic', 0) // 未分发给教务 |
||||
|
->with(['service', 'staff']) |
||||
|
->select(); |
||||
|
|
||||
|
if ($serviceLogs->isEmpty()) { |
||||
|
Log::write('没有需要分发给教务的服务记录'); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
// 获取教务人员列表 |
||||
|
$academicStaff = Personnel::where('status', Personnel::STATUS_NORMAL) |
||||
|
->where('position', 'like', '%教务%') |
||||
|
->select(); |
||||
|
|
||||
|
if ($academicStaff->isEmpty()) { |
||||
|
Log::write('未找到教务人员'); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
$distributionCount = 0; |
||||
|
foreach ($serviceLogs as $serviceLog) { |
||||
|
foreach ($academicStaff as $staff) { |
||||
|
// 发送通知给教务 |
||||
|
$this->sendServiceLogNotice($staff, $serviceLog, 'academic'); |
||||
|
$distributionCount++; |
||||
|
} |
||||
|
|
||||
|
// 标记为已分发给教务 |
||||
|
$serviceLog->is_distributed_to_academic = 1; |
||||
|
$serviceLog->distribution_time = time(); |
||||
|
$serviceLog->save(); |
||||
|
Log::write("已分发给教务,服务记录ID: {$serviceLog->id}"); |
||||
|
} |
||||
|
|
||||
|
Log::write("成功分发给教务 {$distributionCount} 条服务记录通知"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 给教练分发服务记录 |
||||
|
*/ |
||||
|
private function distributeToCoaches() |
||||
|
{ |
||||
|
// 获取需要分发的服务记录(最近24小时内完成的记录) |
||||
|
$yesterday = date('Y-m-d H:i:s', strtotime('-1 day')); |
||||
|
$serviceLogs = ServiceLogs::where('status', 1) // 已完成状态 |
||||
|
->where('created_at', '>=', $yesterday) |
||||
|
->where('is_distributed_to_coach', 0) // 未分发给教练 |
||||
|
->with(['service', 'staff']) |
||||
|
->select(); |
||||
|
|
||||
|
if ($serviceLogs->isEmpty()) { |
||||
|
Log::write('没有需要分发给教练的服务记录'); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
// 获取教练人员列表 |
||||
|
$coaches = Personnel::where('status', Personnel::STATUS_NORMAL) |
||||
|
->where('position', 'like', '%教练%') |
||||
|
->select(); |
||||
|
|
||||
|
if ($coaches->isEmpty()) { |
||||
|
Log::write('未找到教练人员'); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
$distributionCount = 0; |
||||
|
foreach ($serviceLogs as $serviceLog) { |
||||
|
// 找到对应的教练(根据服务记录中的staff_id) |
||||
|
$coach = $coaches->where('id', $serviceLog->staff_id)->first(); |
||||
|
if ($coach) { |
||||
|
// 发送通知给教练 |
||||
|
$this->sendServiceLogNotice($coach, $serviceLog, 'coach'); |
||||
|
$distributionCount++; |
||||
|
} |
||||
|
|
||||
|
// 标记为已分发给教练 |
||||
|
$serviceLog->is_distributed_to_coach = 1; |
||||
|
$serviceLog->distribution_time = time(); |
||||
|
$serviceLog->save(); |
||||
|
Log::write("已分发给教练,服务记录ID: {$serviceLog->id}"); |
||||
|
} |
||||
|
|
||||
|
Log::write("成功分发给教练 {$distributionCount} 条服务记录通知"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 发送服务记录通知 |
||||
|
* @param Personnel $staff 接收人员 |
||||
|
* @param ServiceLogs $serviceLog 服务记录 |
||||
|
* @param string $type 通知类型 (academic|coach) |
||||
|
*/ |
||||
|
private function sendServiceLogNotice($staff, $serviceLog, $type) |
||||
|
{ |
||||
|
try { |
||||
|
// 准备通知数据 |
||||
|
$noticeData = [ |
||||
|
'staff_name' => $staff->name, |
||||
|
'service_name' => $serviceLog->service->service_name ?? '未知服务', |
||||
|
'service_remark' => $serviceLog->service_remark ?? '', |
||||
|
'score' => $serviceLog->score ?? 0, |
||||
|
'feedback' => $serviceLog->feedback ?? '', |
||||
|
'created_at' => date('Y-m-d H:i:s', $serviceLog->created_at), |
||||
|
'type' => $type |
||||
|
]; |
||||
|
|
||||
|
// 根据类型选择不同的通知模板 |
||||
|
$noticeKey = $type === 'academic' ? 'service_log_academic_notice' : 'service_log_coach_notice'; |
||||
|
|
||||
|
// 发送通知 |
||||
|
NoticeService::send($noticeKey, $noticeData); |
||||
|
|
||||
|
Log::write("成功发送服务记录通知给 {$staff->name},服务记录ID: {$serviceLog->id}"); |
||||
|
|
||||
|
} catch (\Exception $e) { |
||||
|
Log::write("发送服务记录通知失败: {$e->getMessage()}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取分发统计信息 |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function getDistributionStats() |
||||
|
{ |
||||
|
$yesterday = date('Y-m-d H:i:s', strtotime('-1 day')); |
||||
|
|
||||
|
$stats = [ |
||||
|
'total_completed' => ServiceLogs::where('status', 1) |
||||
|
->where('created_at', '>=', $yesterday) |
||||
|
->count(), |
||||
|
'distributed_to_academic' => ServiceLogs::where('status', 1) |
||||
|
->where('created_at', '>=', $yesterday) |
||||
|
->where('is_distributed_to_academic', 1) |
||||
|
->count(), |
||||
|
'distributed_to_coach' => ServiceLogs::where('status', 1) |
||||
|
->where('created_at', '>=', $yesterday) |
||||
|
->where('is_distributed_to_coach', 1) |
||||
|
->count(), |
||||
|
'academic_staff_count' => Personnel::where('status', Personnel::STATUS_NORMAL) |
||||
|
->where('position', 'like', '%教务%') |
||||
|
->count(), |
||||
|
'coach_count' => Personnel::where('status', Personnel::STATUS_NORMAL) |
||||
|
->where('position', 'like', '%教练%') |
||||
|
->count(), |
||||
|
]; |
||||
|
|
||||
|
return $stats; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,184 @@ |
|||||
|
<?php |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | Niucloud-admin 企业快速开发的多应用管理平台 |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网址:https://www.niucloud.com |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | niucloud团队 版权所有 开源版本可自由商用 |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | Author: Niucloud Team |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\service\admin\service_logs; |
||||
|
|
||||
|
use app\job\schedule\ServiceLogsDistribution; |
||||
|
use app\model\service_logs\ServiceLogs; |
||||
|
use app\model\personnel\Personnel; |
||||
|
use core\base\BaseAdminService; |
||||
|
use think\facade\Log; |
||||
|
|
||||
|
/** |
||||
|
* 服务记录分发管理服务层 |
||||
|
* Class ServiceLogsDistributionService |
||||
|
* @package app\service\admin\service_logs |
||||
|
*/ |
||||
|
class ServiceLogsDistributionService extends BaseAdminService |
||||
|
{ |
||||
|
public function __construct() |
||||
|
{ |
||||
|
parent::__construct(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 手动执行分发任务 |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function executeDistribution() |
||||
|
{ |
||||
|
try { |
||||
|
$job = new ServiceLogsDistribution(); |
||||
|
$result = $job->doJob(); |
||||
|
|
||||
|
if ($result) { |
||||
|
return ['code' => 1, 'msg' => '分发任务执行成功']; |
||||
|
} else { |
||||
|
return ['code' => 0, 'msg' => '分发任务执行失败']; |
||||
|
} |
||||
|
} catch (\Exception $e) { |
||||
|
Log::write('手动执行分发任务异常: ' . $e->getMessage()); |
||||
|
return ['code' => 0, 'msg' => '分发任务执行异常:' . $e->getMessage()]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取分发统计信息 |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function getDistributionStats() |
||||
|
{ |
||||
|
try { |
||||
|
$job = new ServiceLogsDistribution(); |
||||
|
$stats = $job->getDistributionStats(); |
||||
|
|
||||
|
return [ |
||||
|
'code' => 1, |
||||
|
'data' => $stats, |
||||
|
'msg' => '获取统计信息成功' |
||||
|
]; |
||||
|
} catch (\Exception $e) { |
||||
|
Log::write('获取分发统计信息异常: ' . $e->getMessage()); |
||||
|
return ['code' => 0, 'msg' => '获取统计信息失败:' . $e->getMessage()]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取待分发的服务记录列表 |
||||
|
* @param array $where |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function getPendingDistributionList(array $where = []) |
||||
|
{ |
||||
|
$field = 'id,service_id,staff_id,status,service_remark,feedback,score,created_at,updated_at,is_distributed_to_academic,is_distributed_to_coach,distribution_time'; |
||||
|
|
||||
|
$search_model = ServiceLogs::alias("a") |
||||
|
->join(['school_service' => 'b'], 'a.service_id = b.id', 'left') |
||||
|
->join(['school_personnel' => 'c'], 'a.staff_id = c.id', 'left') |
||||
|
->where('a.status', 1) // 已完成状态 |
||||
|
->field("a.{$field},b.service_name,c.name as staff_name") |
||||
|
->order('a.created_at desc'); |
||||
|
|
||||
|
// 添加筛选条件 |
||||
|
if (isset($where['distribution_status'])) { |
||||
|
switch ($where['distribution_status']) { |
||||
|
case 'pending_academic': |
||||
|
$search_model->where('a.is_distributed_to_academic', 0); |
||||
|
break; |
||||
|
case 'pending_coach': |
||||
|
$search_model->where('a.is_distributed_to_coach', 0); |
||||
|
break; |
||||
|
case 'distributed': |
||||
|
$search_model->where('a.is_distributed_to_academic', 1) |
||||
|
->where('a.is_distributed_to_coach', 1); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (isset($where['date_range']) && !empty($where['date_range'])) { |
||||
|
$search_model->whereTime('a.created_at', $where['date_range']); |
||||
|
} |
||||
|
|
||||
|
$list = $this->pageQuery($search_model); |
||||
|
|
||||
|
return $list; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 重置分发状态 |
||||
|
* @param array $ids 服务记录ID数组 |
||||
|
* @param string $type 重置类型 (academic|coach|both) |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function resetDistributionStatus(array $ids, string $type = 'both') |
||||
|
{ |
||||
|
try { |
||||
|
$updateData = []; |
||||
|
|
||||
|
if ($type === 'academic' || $type === 'both') { |
||||
|
$updateData['is_distributed_to_academic'] = 0; |
||||
|
} |
||||
|
|
||||
|
if ($type === 'coach' || $type === 'both') { |
||||
|
$updateData['is_distributed_to_coach'] = 0; |
||||
|
} |
||||
|
|
||||
|
if ($type === 'both') { |
||||
|
$updateData['distribution_time'] = 0; |
||||
|
} |
||||
|
|
||||
|
$result = ServiceLogs::whereIn('id', $ids)->update($updateData); |
||||
|
|
||||
|
if ($result) { |
||||
|
Log::write("重置分发状态成功,记录ID: " . implode(',', $ids) . ",类型: {$type}"); |
||||
|
return ['code' => 1, 'msg' => '重置分发状态成功']; |
||||
|
} else { |
||||
|
return ['code' => 0, 'msg' => '重置分发状态失败']; |
||||
|
} |
||||
|
} catch (\Exception $e) { |
||||
|
Log::write('重置分发状态异常: ' . $e->getMessage()); |
||||
|
return ['code' => 0, 'msg' => '重置分发状态异常:' . $e->getMessage()]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取教务和教练人员列表 |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function getStaffList() |
||||
|
{ |
||||
|
try { |
||||
|
$academicStaff = Personnel::where('status', Personnel::STATUS_NORMAL) |
||||
|
->where('position', 'like', '%教务%') |
||||
|
->field('id,name,position,phone') |
||||
|
->select() |
||||
|
->toArray(); |
||||
|
|
||||
|
$coaches = Personnel::where('status', Personnel::STATUS_NORMAL) |
||||
|
->where('position', 'like', '%教练%') |
||||
|
->field('id,name,position,phone') |
||||
|
->select() |
||||
|
->toArray(); |
||||
|
|
||||
|
return [ |
||||
|
'code' => 1, |
||||
|
'data' => [ |
||||
|
'academic_staff' => $academicStaff, |
||||
|
'coaches' => $coaches |
||||
|
], |
||||
|
'msg' => '获取人员列表成功' |
||||
|
]; |
||||
|
} catch (\Exception $e) { |
||||
|
Log::write('获取人员列表异常: ' . $e->getMessage()); |
||||
|
return ['code' => 0, 'msg' => '获取人员列表失败:' . $e->getMessage()]; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,54 @@ |
|||||
|
<?php |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | Niucloud-admin 企业快速开发的多应用管理平台 |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | 官方网址:https://www.niucloud.com |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | niucloud团队 版权所有 开源版本可自由商用 |
||||
|
// +---------------------------------------------------------------------- |
||||
|
// | Author: Niucloud Team |
||||
|
// +---------------------------------------------------------------------- |
||||
|
|
||||
|
namespace app\upgrade\v151; |
||||
|
|
||||
|
use core\base\BaseUpgrade; |
||||
|
|
||||
|
/** |
||||
|
* 升级脚本 |
||||
|
* Class Upgrade |
||||
|
* @package app\upgrade\v151 |
||||
|
*/ |
||||
|
class Upgrade extends BaseUpgrade |
||||
|
{ |
||||
|
/** |
||||
|
* 升级 |
||||
|
* @return bool |
||||
|
*/ |
||||
|
public function upgrade() |
||||
|
{ |
||||
|
try { |
||||
|
// 执行SQL升级 |
||||
|
$this->executeSql(); |
||||
|
|
||||
|
// 记录升级日志 |
||||
|
$this->addUpgradeLog('v151', '服务记录分发功能升级完成'); |
||||
|
|
||||
|
return true; |
||||
|
} catch (\Exception $e) { |
||||
|
$this->addUpgradeLog('v151', '升级失败:' . $e->getMessage()); |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 执行SQL升级 |
||||
|
*/ |
||||
|
private function executeSql() |
||||
|
{ |
||||
|
$sqlFile = __DIR__ . '/upgrade.sql'; |
||||
|
if (file_exists($sqlFile)) { |
||||
|
$sql = file_get_contents($sqlFile); |
||||
|
$this->execute($sql); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
-- 为服务记录表添加分发状态字段 |
||||
|
ALTER TABLE `service_logs` |
||||
|
ADD COLUMN `is_distributed_to_academic` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否已分发给教务 0未分发 1已分发' AFTER `feedback`, |
||||
|
ADD COLUMN `is_distributed_to_coach` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否已分发给教练 0未分发 1已分发' AFTER `is_distributed_to_academic`, |
||||
|
ADD COLUMN `distribution_time` int(11) NOT NULL DEFAULT 0 COMMENT '分发时间' AFTER `is_distributed_to_coach`; |
||||
|
|
||||
|
-- 为人员表添加职位字段(如果不存在) |
||||
|
ALTER TABLE `personnel` |
||||
|
ADD COLUMN `position` varchar(100) NOT NULL DEFAULT '' COMMENT '职位' AFTER `name`; |
||||
@ -0,0 +1,165 @@ |
|||||
|
# 服务记录分发功能说明 |
||||
|
|
||||
|
## 功能概述 |
||||
|
|
||||
|
服务记录分发功能是一个定时任务系统,用于自动将已完成的服务记录分发给教务人员和教练,确保相关人员能够及时了解服务情况。 |
||||
|
|
||||
|
## 功能特性 |
||||
|
|
||||
|
### 1. 自动分发 |
||||
|
- 定时检查最近24小时内完成的服务记录 |
||||
|
- 自动识别教务人员和教练 |
||||
|
- 根据人员角色发送相应的通知 |
||||
|
|
||||
|
### 2. 分发规则 |
||||
|
- **教务人员**:接收所有已完成的服务记录通知 |
||||
|
- **教练**:只接收自己负责的服务记录通知 |
||||
|
|
||||
|
### 3. 通知方式 |
||||
|
- 支持短信通知 |
||||
|
- 支持微信通知 |
||||
|
- 支持小程序通知 |
||||
|
|
||||
|
## 文件结构 |
||||
|
|
||||
|
``` |
||||
|
app/ |
||||
|
├── job/schedule/ |
||||
|
│ └── ServiceLogsDistribution.php # 定时任务类 |
||||
|
├── service/admin/service_logs/ |
||||
|
│ └── ServiceLogsDistributionService.php # 分发管理服务 |
||||
|
├── adminapi/controller/service_logs/ |
||||
|
│ └── ServiceLogsDistribution.php # 分发管理控制器 |
||||
|
├── dict/notice/ |
||||
|
│ └── service_logs_notice.php # 通知模板配置 |
||||
|
└── upgrade/v151/ |
||||
|
├── upgrade.php # 升级脚本 |
||||
|
└── upgrade.sql # 数据库升级SQL |
||||
|
``` |
||||
|
|
||||
|
## 数据库变更 |
||||
|
|
||||
|
### 服务记录表 (service_logs) |
||||
|
新增字段: |
||||
|
- `is_distributed_to_academic` (tinyint): 是否已分发给教务 |
||||
|
- `is_distributed_to_coach` (tinyint): 是否已分发给教练 |
||||
|
- `distribution_time` (int): 分发时间 |
||||
|
|
||||
|
### 人员表 (personnel) |
||||
|
新增字段: |
||||
|
- `position` (varchar): 职位信息 |
||||
|
|
||||
|
## API接口 |
||||
|
|
||||
|
### 1. 手动执行分发任务 |
||||
|
``` |
||||
|
POST /adminapi/service_logs/distribution/execute |
||||
|
``` |
||||
|
|
||||
|
### 2. 获取分发统计信息 |
||||
|
``` |
||||
|
GET /adminapi/service_logs/distribution/stats |
||||
|
``` |
||||
|
|
||||
|
### 3. 获取待分发的服务记录列表 |
||||
|
``` |
||||
|
GET /adminapi/service_logs/distribution/pending |
||||
|
参数: |
||||
|
- distribution_status: 分发状态筛选 |
||||
|
- date_range: 日期范围筛选 |
||||
|
``` |
||||
|
|
||||
|
### 4. 重置分发状态 |
||||
|
``` |
||||
|
POST /adminapi/service_logs/distribution/reset |
||||
|
参数: |
||||
|
- ids: 服务记录ID数组 |
||||
|
- type: 重置类型 (academic|coach|both) |
||||
|
``` |
||||
|
|
||||
|
### 5. 获取教务和教练人员列表 |
||||
|
``` |
||||
|
GET /adminapi/service_logs/distribution/staff |
||||
|
``` |
||||
|
|
||||
|
## 使用方法 |
||||
|
|
||||
|
### 1. 安装升级 |
||||
|
执行数据库升级脚本: |
||||
|
```sql |
||||
|
-- 执行 app/upgrade/v151/upgrade.sql 中的SQL语句 |
||||
|
``` |
||||
|
|
||||
|
### 2. 配置定时任务 |
||||
|
在系统定时任务中添加: |
||||
|
```php |
||||
|
// 任务类 |
||||
|
app\job\schedule\ServiceLogsDistribution |
||||
|
|
||||
|
// 执行频率:每小时执行一次 |
||||
|
0 * * * * |
||||
|
``` |
||||
|
|
||||
|
### 3. 配置通知模板 |
||||
|
在后台管理系统中配置通知模板: |
||||
|
- 服务记录教务通知 (service_log_academic_notice) |
||||
|
- 服务记录教练通知 (service_log_coach_notice) |
||||
|
|
||||
|
### 4. 设置人员职位 |
||||
|
确保人员表中的职位字段正确设置: |
||||
|
- 教务人员:职位包含"教务" |
||||
|
- 教练:职位包含"教练" |
||||
|
|
||||
|
## 通知模板变量 |
||||
|
|
||||
|
### 教务通知模板变量 |
||||
|
- `{staff_name}`: 教务人员姓名 |
||||
|
- `{service_name}`: 服务名称 |
||||
|
- `{score}`: 评分 |
||||
|
- `{created_at}`: 创建时间 |
||||
|
|
||||
|
### 教练通知模板变量 |
||||
|
- `{staff_name}`: 教练姓名 |
||||
|
- `{service_name}`: 服务名称 |
||||
|
- `{score}`: 学员评分 |
||||
|
- `{feedback}`: 学员反馈 |
||||
|
- `{created_at}`: 创建时间 |
||||
|
|
||||
|
## 日志记录 |
||||
|
|
||||
|
系统会自动记录以下日志: |
||||
|
- 分发任务开始和完成时间 |
||||
|
- 分发成功的记录数量 |
||||
|
- 发送通知的成功和失败情况 |
||||
|
- 异常错误信息 |
||||
|
|
||||
|
## 注意事项 |
||||
|
|
||||
|
1. **数据库升级**:首次使用前必须执行数据库升级脚本 |
||||
|
2. **人员配置**:确保人员表中的职位信息正确设置 |
||||
|
3. **通知配置**:需要在后台配置相应的通知模板 |
||||
|
4. **定时任务**:建议设置为每小时执行一次 |
||||
|
5. **权限控制**:API接口需要相应的权限才能访问 |
||||
|
|
||||
|
## 故障排除 |
||||
|
|
||||
|
### 常见问题 |
||||
|
|
||||
|
1. **没有找到教务/教练人员** |
||||
|
- 检查人员表中的职位字段是否正确设置 |
||||
|
- 确认人员状态是否为正常状态 |
||||
|
|
||||
|
2. **通知发送失败** |
||||
|
- 检查通知模板配置 |
||||
|
- 确认短信/微信配置是否正确 |
||||
|
|
||||
|
3. **分发状态不更新** |
||||
|
- 检查数据库字段是否存在 |
||||
|
- 确认数据库权限是否正确 |
||||
|
|
||||
|
### 调试方法 |
||||
|
|
||||
|
1. 查看系统日志文件 |
||||
|
2. 使用手动执行接口测试 |
||||
|
3. 检查数据库中的分发状态字段 |
||||
|
4. 验证通知模板配置 |
||||
Loading…
Reference in new issue