love_php/app/Http/Controllers/Server/Admin/ReportController.php
2026-04-02 09:20:51 +08:00

545 lines
24 KiB
PHP

<?php
namespace App\Http\Controllers\Server\Admin;
use App\Jobs\SyncReportTaskDatabase;
use App\Models\Live\Anchor;
use App\Models\Server\TouristOrder;
use App\Server\ReportFile;
use App\Utils\Http;
use GuzzleHttp\Client;
use GuzzleHttp\RequestOptions;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\ConsultAccount;
use App\Models\Consultation;
use App\Models\Course\Course;
use App\Models\MerchantShop;
use App\Models\Server\CommunityActivity;
use App\Models\Server\MerchantReport;
use App\Models\Server\MerchantUser;
use App\Models\Server\ReportAnswer;
use App\Models\Server\ReportQuestion;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
class ReportController extends Controller
{
//用户报告
// 添加报告问题
public function addReport(Request $request){
try {
$m_id = $request->account_id;
$type = $request->type;
$type_id = $request->type_id;
$result = $this->getModel($type,$type_id);
if(empty($result)) return $this->failure('服务不存在,无法添加');
if($result->merchant_id != $m_id) return $this->failure('当前服务不属于你,无法添加');
$title = $request->title;
if(empty($title)) return $this->failure('标题必填');
$input_type = $request->input_type ?? 'input';
$title_answer = $request->title_answer ? json_encode($request->title_answer) : null;
$exist = ReportQuestion::where(['type'=>$type,'type_id'=>$type_id,'title'=>$title,'input_type'=>$input_type,'title_answer'=>$title_answer])->first();
if(in_array($request->input_type,['radio','checkbox']) && empty($request->title_answer)){
return $this->failure('输入方式为单选或多选 必须设置相对应的选项');
}
if($exist) return $this->failure('已存在相同类型的标题');
ReportQuestion::create([
'm_id'=>$request->account_id,
'type'=>$type,
'type_id'=>$type_id,
'title'=>$title,
'input_type'=>$input_type,
'title_answer'=>$title_answer,
]);
return $this->success('ok');
} catch (\Exception $e) {
$this->getError($e);
return $this->failure();
}
}
//添加填写时间
public function addReportTime(Request $request){
try {
$m_id = $request->account_id;
$type = $request->type;
$type_id = $request->type_id;
$class = $request->class ?? 'one';
$show_hint = $request->show_hint ?1:0;
$positive_title = $request->positive_title ?? '';
$positive_pic_url = $request->positive_pic_url ??'';
$negative_title = $request->negative_title ?? '';
$negative_pic_url = $request->negative_pic_url ?? '';
$steady_title = $request->steady_title ?? '';
$steady_pic_url = $request->steady_pic_url ?? '';
$notification_type = $request->notification_type ?? 0;
$notification_time = $request->notification_time;
$share_title = $request->share_title;
$share_jump_page = $request->share_jump_page;
$share_pic = $request->share_pic;
$hint = json_encode([
'positive_title' =>$positive_title,
'positive_pic_url' =>$positive_pic_url,
'negative_title' =>$negative_title,
'negative_pic_url' =>$negative_pic_url,
'steady_title' =>$steady_title,
'steady_pic_url' =>$steady_pic_url,
]);
if(count($request->commitd_at) && count($request->commitd_at) != count(array_unique($request->commitd_at))){
return $this->failure('存在重复日期,确认后再保存');
}
$commitd_at = ($request->commitd_at && is_array($request->commitd_at) && !empty($request->commitd_at[0])) ? json_encode($request->commitd_at) : null;
$result = $this->getModel($type,$type_id);
if(empty($result)) return $this->failure('服务不存在,无法添加');
if($result->merchant_id != $m_id) return $this->failure('当前服务不属于你,无法添加');
$where = ['m_id'=>$request->account_id,'type'=>$request->type,'type_id'=>$type_id];
$report_time = [
'class'=>$class,
'commitd_at'=>$commitd_at,
'show_hint' => $show_hint,
'hint' => $hint,
'share_title' => $share_title,
'share_pic' => json_encode($share_pic),
'notification_type' => $notification_type,
'notification_time' => $notification_time,
'share_jump_page' => $share_jump_page,
];
MerchantReport::updateOrCreate($where, $report_time);
return $this->success('ok');
} catch (\Exception $e) {
$this->getError($e);
return $this->failure($e->getMessage());
}
}
public function getModel($type,$type_id){
if($type == 'activity' || $type == 'service') $type = 'community';
$result = null;
switch ($type) {
case 'community':
$result = CommunityActivity::find($type_id);
break;
case 'shop':
$result = MerchantShop::find($type_id);
break;
case 'course':
$result = Course::find($type_id);
break;
case 'consult':
$result = Consultation::find($type_id);
$result->merchant_id = ConsultAccount::where('id',$result->consult_account_id)->value('merchant_id');
break;
default:
return $result;
break;
}
return $result;
}
//报告问题列表
public function reportQuestions(Request $request){
try {
$type = $request->type;
$type_id = $request->type_id;
$result = $this->getModel($type,$type_id);
if(empty($result)) return $this->success('ok',$result);
$time = MerchantReport::where('m_id',$request->account_id)->where('type',$type)
->where('type_id',$type_id)
->first();
if($time && $time->commitd_at){
$commitd_at = json_decode($time->commitd_at,true);
sort($commitd_at);
$time->commitd_at = $commitd_at;
}
if($time && $time->hint){
$time->hint = json_decode($time->hint, true);
}
if($time && $time->share_pic){
$time->share_pic = json_decode($time->share_pic, true);
}
$questions = ReportQuestion::where('type',$type)->where('type_id',$type_id)->orderBy('id','asc')
->select('id','title','input_type','title_answer','created_at')
->paginate();
foreach ($questions as $key => $value) {
$value->title_answer = json_decode($value->title_answer);
}
return $this->success('ok',compact('time','questions'));
} catch (\Exception $e) {
$this->getError($e);
return $this->failure();
}
}
public function reportTaskQrcode(Request $request)
{
try {
//同步任务到第三方任务库
$type = $request->input('type');
$type_id = $request->input('type_id');
if (empty($type) || empty($type_id)) throw new \Exception("缺少参数type/type_id");
$task_no = MerchantReport::where('m_id', $request->account_id)->where('type', $type)->where('type_id', $type_id)->value('task_no');
if (empty($task_no)) {
$task_no = uniqid();
MerchantReport::where('m_id', $request->account_id)->where('type', $type)->where('type_id', $type_id)->update(['task_no'=>$task_no]);
}
$activity = CommunityActivity::where('id', $type_id)->first();
$m_report = MerchantReport::where('m_id', $request->account_id)->where('type', $type)->where('type_id', $type_id)->first();
$commitd_at = $m_report->commitd_at;
// if (empty($commitd_at)) return $this->failure("暂未设置报告填写时间");
$commitd_arr = $commitd_at?json_decode($commitd_at):[];
$quesiotns = ReportQuestion::where('m_id', $request->account_id)->where('type', $type)->where('type_id', $type_id)->get();
if (empty(count($quesiotns))) return $this->failure("暂未设置报告项目");
if (count($commitd_arr)) {
sort($commitd_arr);
$sync_date = '';
$last_commitd_at = '';
$group_no = 'g'.uniqid();
foreach ($commitd_arr as $commitd_at) {
if ($sync_date) {
$sync_date = date('Y-m-d', strtotime($last_commitd_at) + 24 * 3600);
$db_task_no = '';
}else{
$sync_date = $commitd_at;
$db_task_no = $task_no;
}
$last_commitd_at = $commitd_at;
$this->syncReportTaskDatabase($activity, $quesiotns,$m_report, $db_task_no,$commitd_at,$sync_date, $group_no);
}
}else {
$this->syncReportTaskDatabase($activity, $quesiotns, $m_report, $task_no);
}
$key = 'merchant:report:task:qrcode:'.$type.":".$type_id;
if (Cache::has($key)) {
$qrcode = Cache::get($key);
}else {
//领取任务二维码
$qrcode = $this->getTaskQrcode($task_no);
if ($qrcode) {
Cache::forever($key, $qrcode);
}
}
return $this->success('ok', compact('qrcode'));
}catch (\Exception $e) {
$this->getError($e);
return $this->failure();
}
}
public function getTaskQrcode($task_no)
{
$token = config('app.task_token');
$url = env("APP_TASK_URL")."/api/tp/tasks/bind/qrcode?task_no=".$task_no;
$client = new Client();
$header = [
'APPTOKEN' => $token,
'Content-Type' => 'application/json'
];
$options = [
RequestOptions::TIMEOUT => 3,
RequestOptions::HTTP_ERRORS => false,
RequestOptions::HEADERS => $header,
];
$response = $client->get($url, $options);
$content = $response->getBody();
$res = json_decode($content, true);
$qrcode = '';
if ($res && isset($res['code'])) {
if ($res['code']) {
throw new \Exception($res['message']);
}else {
$qrcode = $res['data']['qrcode'];
}
}
return $qrcode;
}
public function syncReportTaskDatabase($activity, $questions, $m_report, $task_no=null, $commitd_at=null, $sync_date=null, $group_no=null)
{
if ($m_report->share_jump_page == 'first') {
$url = 'https://love.ufutx.com/pu/#?merchant_id='.$activity->merchant_id;
} else {
$url = 'https://love.ufutx.com/pu/#/activityDetails/'.$activity->id.'?merchant_id='.$activity->merchant_id;
}
$url = urlencode($url);
$share_url = 'https://love.ufutx.com/api/official/live/wechat/FamilyAuth?merchant_id='.$activity->merchant_id.'&url='.$url;
$title = $activity->title;
$cate_name = '任务清单一';
$sub_tasks = [];
$callback = null;
$task_no = $task_no?:uniqid();
foreach ($questions as $question) {
$content_type = ['txt'=>1, 'img'=>1, 'file'=>1, 'video'=>1,'num'=>0, 'radio'=>0,'checkbox'=>0];
if ($question->input_type == 'numeric') {
$content_type['num'] = 1;
}elseif ($question->input_type == 'radio') {
$content_type['radio'] = 1;
}elseif ($question->input_type == 'checkbox') {
$content_type['checkbox'] = 1;
}
$sub_task_no = uniqid();
$task['title'] = $question->title;
$task['task_no'] = $sub_task_no;
$task['start_time'] = $commitd_at?:null;
$task['end_time'] = $commitd_at?date('Y-m-d 23:59:59', strtotime($commitd_at)):null;
$task['sync_date'] = $sync_date;
$task['content_type'] = $content_type;
$task['callback'] = $callback?$callback.$sub_task_no:null;
$task['options'] = json_decode($question->title_answer);
$task['group_no'] = $group_no;
$task['comment_num'] = 1;
$sub_tasks[] = $task;
}
$team = [];
$anchor = Anchor::where('m_id', $activity->merchant_id)->first();
if ($anchor) {
$team_no = $anchor->team_no;
if (empty($team_no)) {
$team_no = 'team_'.uniqid();
Anchor::where('m_id', $activity->merchant_id)->update(['team_no'=>$team_no]);
}
$team = ['team_no'=>$team_no,'name'=>$anchor->name, 'pic'=>$anchor->pic];
}
$data = [
'cate_name' => $cate_name,
'title' => $commitd_at.$title.'用户报告',
'task_no' => $task_no,
'group_no' => $group_no,
'sync_date' => $sync_date,
'comment_num'=>1,
'sub_task' => $sub_tasks,
'team'=> $team,
'share_url'=>$share_url,
'share_poster' => $m_report->share_pic,
'share_desc' => $m_report->share_title,
];
SyncReportTaskDatabase::dispatch($data)->onQueue('sync.report.task.db');
return $task_no;
}
//编辑问题
public function updateReport(Request $request){
try {
$question_id = $request->question_id;
$question = ReportQuestion::find($question_id);
if(empty($question)) return $this->failure('问题不存在');
if($request->title && $request->title != $question->title){
$question->title = $request->title;
}
if($request->input_type && $request->input_type != $question->input_type){
$question->input_type = $request->input_type;
if(in_array($request->input_type,['radio','checkbox']) && empty($request->title_answer)){
return $this->failure('输入方式为单选或多选 必须设置相对应的选项');
}
}
if($request->title_answer && json_encode($request->title_answer) != $question->title_answer){
$question->title_answer = json_encode($request->title_answer);
}
$question->save();
return $this->success('ok');
} catch (\Exception $e) {
$this->getError($e);
return $this->failure();
}
}
//删除用户报告问题
public function removeQuestion(Request $request){
try {
$m_id = $request->account_id;
$question_id = $request->question_id;
$question = ReportQuestion::where('id',$question_id)->first();
if(empty($question)) return $this->failure('当前问题不存在或已被他人删除');
$result = $this->getModel($question->type,$question->type_id);
if($result->merchant_id != $m_id) return $this->failure('当前服务不属于你,无法删除');
$question->delete();
return $this->success('ok');
} catch (\Exception $e) {
$this->getError($e);
return $this->failure();
}
}
// 用户报告提交列表
public function userReports(Request $request){
try {
$commitd_at = $request->commitd_at;
$commitd_at2 = $request->commitd_at. '00:00:00';
$keyword = trim($request->keyword);
$result = $this->getModel($request->type,$request->type_id);
if(empty($result)) return $this->success('ok',$result);
//所有问题
$question_ids = ReportQuestion::withTrashed()->where(['type'=>$request->type,'type_id'=>$request->type_id])->orderBy('id','asc')->pluck('id')->toArray();
//回答了问题的用户
$m_user_ids = ReportAnswer::whereIn('question_id',$question_ids);
if($commitd_at){
$m_user_ids = $m_user_ids->where('commitd_at',$commitd_at);
}
$m_user_ids = $m_user_ids->pluck('m_user_id')->toArray();
$users = MerchantUser::whereIn('id',$m_user_ids)->select('id','nickname','pic','mobile');
if($keyword){
$users = $users->where(function($sql) use($keyword){
$sql->where('nickname','like',"%$keyword%")
->orWhere('mobile','like',"%$keyword%");
});
}
$users = $users->paginate();
foreach ($users as $user) {
//这个用户提交答案个数
$commit_ids = ReportAnswer::where('m_user_id',$user->id)->whereIn('question_id',$question_ids)->pluck('question_id')->toArray();
//未提交 id
$result = array_diff($question_ids,$commit_ids);
$un_titles = ReportQuestion::withTrashed()->whereIn('id',$result)->pluck('title')->toArray();
$answer = [];
$i = 0;
foreach ($question_ids as $key => $question_id) {
$q = ReportQuestion::withTrashed()->where('id',$question_id)->first();
if(in_array($question_id,$commit_ids)){
$a = ReportAnswer::where('question_id',$question_id)->where('m_user_id',$user->id)->first();
$answer[$key]['title'] = $a->title;
$answer[$key]['answer'] = $a->answer;
$answer[$key]['pics'] = !empty($a->pics) ? json_decode($a->pics,true) : [];
}else{
$answer[$key]['title'] = $un_titles[$i];
$answer[$key]['answer'] = '';
$answer[$key]['pics'] = [];
$i++;
if($i >= count($un_titles)) continue;
}
$answer[$key]['input_type'] = $q->input_type;
if($q->input_type == 'checkbox' && isset($a) && isset($a->answer2)){
$answer[$key]['answer2'] = json_decode($a->answer2);
}elseif(isset($a)){
$answer[$key]['answer2'] = $a->answer2;
}else{
$answer[$key]['answer2'] = '';
}
}
$user->answer = $answer;
}
return $this->success('ok',$users);
} catch (\Exception $e) {
$this->getError($e);
return $this->failure();
}
}
//提交了报告了用户
public function commitUsers(Request $request){
$keyword = trim($request->keyword);
//所有问题
$question_ids = ReportQuestion::withTrashed()->where(['type'=>$request->type,'type_id'=>$request->type_id])->orderBy('id','asc')->pluck('id')->toArray();
//回答了问题的用户
$m_user_ids = ReportAnswer::whereIn('question_id',$question_ids)->orderBy('id','desc')->pluck('m_user_id')->toArray();
$users = MerchantUser::whereIn('id',$m_user_ids)->select('id','nickname','pic','mobile');
if($keyword){
$users = $users->where(function($sql) use($keyword){
$sql->where('nickname','like',"%$keyword%")
->orWhere('mobile','like',"%$keyword%");
});
}
$users = $users->paginate();
foreach ($users as $key => $value) {
//该用户的提交时间数组
$commitd_ats = ReportAnswer::where('m_user_id',$value->id)->whereIn('question_id',$question_ids)->groupBy('commitd_at')->pluck('commitd_at')->toArray();
$commitd_at = [];
foreach ($commitd_ats as $key => $at) {
$atm = date('Y-m-d',strtotime($at));
$commitd_at[]=$atm;
}
sort($commitd_at);
$value->commitd_at = $commitd_at;
//文件
$file = ReportFile::where('user_id', $value->id)->where('type', 'activity')->where('type_id', $request->type_id)->first();
$file_status = 0;
$file_url = '';
if ($file && empty($file->url)) {
$file_status = 1;
$file_url = $file->url;
}elseif ($file && $file->url) {
$file_status = 2;
$file_url = $file->url;
}
$value->file_url = $file_url;
$value->file_status = $file_status;
}
return $this->success('ok',$users);
}
public function reportFile(Request $request, $user_id)
{
try {
$type = $request->input('type');
$type_id = $request->input('type_id');
$order = TouristOrder::where('type', $type)->where('type_id', $type_id)->whereIn('pay_status', [1,4])->where('account_id', $user_id)->first();
if (empty($order)) throw new \Exception("生成文件失败,订单不存在");
ReportFile::updateOrCreate(['order_id'=>$order->id, 'user_id'=>$order->account_id, 'type'=>'activity', 'type_id'=>$order->type_id], ['url'=>'', 'file_type'=>'docx']);
\App\Jobs\ReportExport::dispatch($order)->onQueue('report.export');
return $this->success('ok');
} catch (\Exception $e) {
$this->getError($e);
return $this->failure();
}
}
//该用户提交的答案列表
public function userAnswers(Request $request){
$m_user_id = $request->m_user_id;
$commitd_at = $request->commitd_at;
$commitd_at2 = $request->commitd_at.' 00:00:00';
$result = $this->getModel($request->type,$request->type_id);
if(empty($result)) return $this->success('ok',$result);
//所有问题
$question_ids = ReportQuestion::where(['type'=>$request->type,'type_id'=>$request->type_id])->orderBy('id','asc')->pluck('id')->toArray();
//这个用户提交答案个数
$commit_ids = ReportAnswer::where('m_user_id',$m_user_id)->whereIn('question_id',$question_ids);
if($commitd_at){
$commit_ids = $commit_ids->where('commitd_at',$commitd_at2);
}
$commit_ids = $commit_ids->pluck('question_id')->toArray();//75
//未提交 id
$result = array_diff($question_ids,$commit_ids);//76 77
$un_titles = ReportQuestion::whereIn('id',$result)->pluck('title')->toArray();
$answer = [];
$i = 0;
foreach ($question_ids as $key => $question_id) {
$q = ReportQuestion::where('id',$question_id)->first();
$answer[$key]['input_type'] = $q->input_type;
if(in_array($question_id,$commit_ids)){
$a = ReportAnswer::where('question_id',$question_id)->where('m_user_id',$m_user_id);
if($request->commitd_at){
$a = $a->where('commitd_at',$commitd_at2);
}
$a = $a->first();
$answer[$key]['title'] = $a->title;
$answer[$key]['answer'] = $a->answer;
$answer[$key]['pics'] = !empty($a->pics) ? json_decode($a->pics,true) : [];
}else{
$answer[$key]['title'] = $un_titles[$i];
$answer[$key]['answer'] = '';
$answer[$key]['pics'] = [];
$i++;
}
if($q->input_type == 'checkbox' && isset($a) && isset($a->answer2)){
$answer[$key]['answer2'] = json_decode($a->answer2);
}elseif(isset($a)){
$answer[$key]['answer2'] = $a->answer2;
}else{
$answer[$key]['answer2'] = '';
}
unset($a);
// if($i >= count($un_titles)) continue;
}
return $this->success('ok',$answer);
}
}