|
|
<?php
|
|
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
|
|
use App\Exports\BaseExport;
|
|
|
use App\Exports\CommonExport;
|
|
|
use App\Helpers\ResponseCode;
|
|
|
use App\Models\AppointmentType;
|
|
|
use App\Models\CustomForm;
|
|
|
use App\Models\Dialogue;
|
|
|
use App\Models\Message;
|
|
|
use App\Models\SupplyDemand;
|
|
|
use App\Models\SupplyDemandType;
|
|
|
use Illuminate\Support\Facades\Validator;
|
|
|
use Maatwebsite\Excel\Facades\Excel;
|
|
|
|
|
|
class SupplyDemandController extends BaseController
|
|
|
{
|
|
|
|
|
|
/**
|
|
|
* 构造函数
|
|
|
*/
|
|
|
public function __construct()
|
|
|
{
|
|
|
parent::__construct(new SupplyDemand());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/api/admin/supply-demand/index",
|
|
|
* tags={"供需信息管理"},
|
|
|
* summary="列表",
|
|
|
* description="",
|
|
|
* @OA\Parameter(name="is_export", in="query", @OA\Schema(type="string"), required=false, description="是否导出0否1是"),
|
|
|
* @OA\Parameter(name="export_fields", in="query", @OA\Schema(type="string"), required=false, description="需要导出的字段数组"),
|
|
|
* @OA\Parameter(name="filter", in="query", @OA\Schema(type="string"), required=false, description="查询条件。数组"),
|
|
|
* @OA\Parameter(name="show_relation", in="query", @OA\Schema(type="string"), required=false, description="需要输出的关联关系数组,包括:teacher,courseSettings,coursePeriods"),
|
|
|
* @OA\Parameter(name="page_size", in="query", @OA\Schema(type="string"), required=false, description="每页显示的条数"),
|
|
|
* @OA\Parameter(name="page", in="query", @OA\Schema(type="string"), required=false, description="页码"),
|
|
|
* @OA\Parameter(name="sort_name", in="query", @OA\Schema(type="string"), required=false, description="排序字段名字"),
|
|
|
* @OA\Parameter(name="sort_type", in="query", @OA\Schema(type="string"), required=false, description="排序类型"),
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="暂无"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function index()
|
|
|
{
|
|
|
$all = request()->all();
|
|
|
$list = $this->model->with('user')->where(function ($query) use ($all) {
|
|
|
if (isset($all['filter']) && !empty($all['filter'])) {
|
|
|
foreach ($all['filter'] as $condition) {
|
|
|
$key = $condition['key'] ?? null;
|
|
|
$op = $condition['op'] ?? null;
|
|
|
$value = $condition['value'] ?? null;
|
|
|
if (!isset($key) || !isset($op) || !isset($value)) {
|
|
|
continue;
|
|
|
}
|
|
|
// 等于
|
|
|
if ($op == 'eq') {
|
|
|
$query->where($key, $value);
|
|
|
}
|
|
|
// 不等于
|
|
|
if ($op == 'neq') {
|
|
|
$query->where($key, '!=', $value);
|
|
|
}
|
|
|
// 大于
|
|
|
if ($op == 'gt') {
|
|
|
$query->where($key, '>', $value);
|
|
|
}
|
|
|
// 大于等于
|
|
|
if ($op == 'egt') {
|
|
|
$query->where($key, '>=', $value);
|
|
|
}
|
|
|
// 小于
|
|
|
if ($op == 'lt') {
|
|
|
$query->where($key, '<', $value);
|
|
|
}
|
|
|
// 小于等于
|
|
|
if ($op == 'elt') {
|
|
|
$query->where($key, '<=', $value);
|
|
|
}
|
|
|
// 模糊搜索
|
|
|
if ($op == 'like') {
|
|
|
$query->where($key, 'like', '%' . $value . '%');
|
|
|
}
|
|
|
// 否定模糊搜索
|
|
|
if ($op == 'notlike') {
|
|
|
$query->where($key, 'not like', '%' . $value . '%');
|
|
|
}
|
|
|
// 范围搜索
|
|
|
if ($op == 'range') {
|
|
|
list($from, $to) = explode(',', $value);
|
|
|
if (empty($from) || empty($to)) {
|
|
|
continue;
|
|
|
}
|
|
|
$query->whereBetween($key, [$from, $to]);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
})->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc');
|
|
|
if (isset($all['is_export']) && !empty($all['is_export'])) {
|
|
|
$list = $list->limit(5000)->get()->toArray();
|
|
|
return Excel::download(new CommonExport($list, $all['export_fields'] ?? ''), $all['file_name'] ?? '' . date('YmdHis') . '.xlsx');
|
|
|
} else {
|
|
|
// 输出
|
|
|
$list = $list->paginate($all['page_size'] ?? 20);
|
|
|
}
|
|
|
return $this->success($list);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/api/admin/supply-demand/show",
|
|
|
* tags={"供需信息管理"},
|
|
|
* summary="详情",
|
|
|
* description="",
|
|
|
* @OA\Parameter(name="id", in="query", @OA\Schema(type="string"), required=true, description="id"),
|
|
|
* @OA\Parameter(name="show_relation", in="query", @OA\Schema(type="string"), required=false, description="需要输出的关联关系数组,填写输出指定数据"),
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="暂无"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function show()
|
|
|
{
|
|
|
$all = \request()->all();
|
|
|
$messages = [
|
|
|
'id.required' => 'Id必填',
|
|
|
];
|
|
|
$validator = Validator::make($all, [
|
|
|
'id' => 'required'
|
|
|
], $messages);
|
|
|
if ($validator->fails()) {
|
|
|
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
|
|
|
}
|
|
|
$detail = $this->model->with('user')->find($all['id']);
|
|
|
return $this->success($detail);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Post(
|
|
|
* path="/api/admin/supply-demand/save",
|
|
|
* tags={"供需信息管理"},
|
|
|
* summary="更新或新增",
|
|
|
* @OA\Parameter(name="id", in="query", @OA\Schema(type="integer"), required=false, description="需求供应表ID(存在则更新,不存在则新增)"),
|
|
|
* @OA\Parameter(name="title", in="query", @OA\Schema(type="string"), required=false, description="标题"),
|
|
|
* @OA\Parameter(name="supply_demand_type_id", in="query", @OA\Schema(type="integer"), required=false, description="分类ID"),
|
|
|
* @OA\Parameter(name="content", in="query", @OA\Schema(type="string"), required=false, description="内容"),
|
|
|
* @OA\Parameter(name="tag", in="query", @OA\Schema(type="string"), required=false, description="标签"),
|
|
|
* @OA\Parameter(name="wechat", in="query", @OA\Schema(type="string"), required=false, description="微信号"),
|
|
|
* @OA\Parameter(name="mobile", in="query", @OA\Schema(type="string"), required=false, description="电话"),
|
|
|
* @OA\Parameter(name="email", in="query", @OA\Schema(type="string"), required=false, description="邮箱"),
|
|
|
* @OA\Parameter(name="status", in="query", @OA\Schema(type="integer"), required=false, description="状态0待审核1通过2拒绝3退回修改4永久隐藏"),
|
|
|
* @OA\Response(
|
|
|
* response=200,
|
|
|
* description="操作成功"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function save()
|
|
|
{
|
|
|
return parent::save();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/api/admin/supply-demand/destroy",
|
|
|
* tags={"供需信息管理"},
|
|
|
* summary="删除",
|
|
|
* description="",
|
|
|
* @OA\Parameter(name="id", in="query", @OA\Schema(type="string"), required=true, description="id"),
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="暂无"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function destroy()
|
|
|
{
|
|
|
return parent::destroy();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/api/admin/supply-demand/chart",
|
|
|
* tags={"供需信息管理"},
|
|
|
* summary="交互统计",
|
|
|
* description="",
|
|
|
* @OA\Parameter(name="start_date", in="query", @OA\Schema(type="string"), required=true, description="开始日期"),
|
|
|
* @OA\Parameter(name="end_date", in="query", @OA\Schema(type="string"), required=true, description="结束日期"),
|
|
|
* @OA\Parameter(name="type", in="query", @OA\Schema(type="string"), required=true, description="type类型"),
|
|
|
* @OA\Parameter(name="page_size", in="query", @OA\Schema(type="string"), required=false, description="每页显示的条数"),
|
|
|
* @OA\Parameter(name="page", in="query", @OA\Schema(type="string"), required=false, description="页码"),
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="暂无"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function chart()
|
|
|
{
|
|
|
$now = date('Y-m-d');
|
|
|
$startDate = request('start_date', $now);
|
|
|
$endDate = request('end_date', $now);
|
|
|
$type = request('type');
|
|
|
|
|
|
// 计算上期时间段(与当前时间段长度相同)
|
|
|
$daysDiff = (strtotime($endDate) - strtotime($startDate)) / (60 * 60 * 24) + 1;
|
|
|
$prevEndDate = date('Y-m-d', strtotime($startDate) - 1);
|
|
|
$prevStartDate = date('Y-m-d', strtotime($prevEndDate) - $daysDiff + 1);
|
|
|
|
|
|
// 当期供需发布数
|
|
|
$supplyDemand = SupplyDemand::where(function ($query) use ($type) {
|
|
|
if ($type) {
|
|
|
$query->where('type', $type);
|
|
|
}
|
|
|
})->whereBetween('created_at', [$startDate, $endDate])
|
|
|
->get();
|
|
|
$supplyDemandCount = $supplyDemand->count();
|
|
|
|
|
|
// 上期供需发布数
|
|
|
$prevSupplyDemandCount = SupplyDemand::where(function ($query) use ($type) {
|
|
|
if ($type) {
|
|
|
$query->where('type', $type);
|
|
|
}
|
|
|
})->whereBetween('created_at', [$prevStartDate, $prevEndDate])
|
|
|
->count();
|
|
|
|
|
|
// 当期私信数量
|
|
|
$messageCount = Message::whereIn('supply_demand_id', $supplyDemand->pluck('id'))->count();
|
|
|
|
|
|
// 上期私信数量
|
|
|
$prevSupplyDemand = SupplyDemand::where(function ($query) use ($type) {
|
|
|
if ($type) {
|
|
|
$query->where('type', $type);
|
|
|
}
|
|
|
})->whereBetween('created_at', [$prevStartDate, $prevEndDate])
|
|
|
->get();
|
|
|
$prevMessageCount = Message::whereIn('supply_demand_id', $prevSupplyDemand->pluck('id'))->count();
|
|
|
|
|
|
// 当期交互次数(同一个dialogue_id一来一回算一次交互)
|
|
|
$interactionCount = Message::whereBetween('created_at', [$startDate, $endDate])
|
|
|
->whereNotNull('dialogue_id')
|
|
|
->groupBy('dialogue_id')
|
|
|
->selectRaw('dialogue_id, COUNT(*) as message_count')
|
|
|
->having('message_count', '>=', 2)
|
|
|
->count();
|
|
|
|
|
|
// 上期交互次数
|
|
|
$prevInteractionCount = Message::whereBetween('created_at', [$prevStartDate, $prevEndDate])
|
|
|
->whereNotNull('dialogue_id')
|
|
|
->groupBy('dialogue_id')
|
|
|
->selectRaw('dialogue_id, COUNT(*) as message_count')
|
|
|
->having('message_count', '>=', 2)
|
|
|
->count();
|
|
|
|
|
|
// 计算增减比率
|
|
|
$supplyDemandGrowthRate = $this->calculateGrowthRate($supplyDemandCount, $prevSupplyDemandCount);
|
|
|
$messageGrowthRate = $this->calculateGrowthRate($messageCount, $prevMessageCount);
|
|
|
$interactionGrowthRate = $this->calculateGrowthRate($interactionCount, $prevInteractionCount);
|
|
|
|
|
|
// 当期供需发布分页
|
|
|
$list = SupplyDemand::with(['user', 'dialogues' => function ($query) {
|
|
|
$query->with(['user', 'toUser', 'messages' => function ($q) {
|
|
|
$q->orderBy('created_at', 'desc')->limit(10);
|
|
|
}])->limit(2)->orderBy('created_at', 'desc');
|
|
|
}])->where(function ($query) use ($type) {
|
|
|
if ($type) {
|
|
|
$query->where('type', $type);
|
|
|
}
|
|
|
})->whereBetween('created_at', [$startDate, $endDate])
|
|
|
->paginate($all['page_size'] ?? 20);
|
|
|
return $this->success([
|
|
|
'list' => $list,
|
|
|
'supply_demand_count' => $supplyDemandCount,
|
|
|
'prev_supply_demand_count' => $prevSupplyDemandCount,
|
|
|
'supply_demand_growth_rate' => $supplyDemandGrowthRate,
|
|
|
'message_count' => $messageCount,
|
|
|
'prev_message_count' => $prevMessageCount,
|
|
|
'message_growth_rate' => $messageGrowthRate,
|
|
|
'interaction_count' => $interactionCount,
|
|
|
'prev_interaction_count' => $prevInteractionCount,
|
|
|
'interaction_growth_rate' => $interactionGrowthRate,
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 计算增长率
|
|
|
* @param int $current 当前数值
|
|
|
* @param int $previous 上期数值
|
|
|
* @return array 包含增长率和增长状态
|
|
|
*/
|
|
|
private function calculateGrowthRate($current, $previous)
|
|
|
{
|
|
|
if ($previous == 0) {
|
|
|
if ($current > 0) {
|
|
|
return [
|
|
|
'rate' => 100,
|
|
|
'status' => 'increase',
|
|
|
'display' => '+100%'
|
|
|
];
|
|
|
} else {
|
|
|
return [
|
|
|
'rate' => 0,
|
|
|
'status' => 'stable',
|
|
|
'display' => '0%'
|
|
|
];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
$rate = round(($current - $previous) / $previous * 100, 2);
|
|
|
|
|
|
if ($rate > 0) {
|
|
|
$status = 'increase';
|
|
|
$display = '+' . $rate . '%';
|
|
|
} elseif ($rate < 0) {
|
|
|
$status = 'decrease';
|
|
|
$display = $rate . '%';
|
|
|
} else {
|
|
|
$status = 'stable';
|
|
|
$display = '0%';
|
|
|
}
|
|
|
|
|
|
return [
|
|
|
'rate' => $rate,
|
|
|
'status' => $status,
|
|
|
'display' => $display
|
|
|
];
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* @OA\Get(
|
|
|
* path="/api/admin/supply-demand/message-list",
|
|
|
* tags={"供需信息管理"},
|
|
|
* summary="消息列表",
|
|
|
* description="",
|
|
|
* @OA\Parameter(name="to_user_id", in="query", @OA\Schema(type="string"), required=true, description="接收人"),
|
|
|
* @OA\Parameter(name="user_id", in="query", @OA\Schema(type="string"), required=true, description="发起人"),
|
|
|
* @OA\Parameter(name="page_size", in="query", @OA\Schema(type="string"), required=false, description="每页显示的条数"),
|
|
|
* @OA\Parameter(name="page", in="query", @OA\Schema(type="string"), required=false, description="页码"),
|
|
|
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
|
|
|
* @OA\Response(
|
|
|
* response="200",
|
|
|
* description="暂无"
|
|
|
* )
|
|
|
* )
|
|
|
*/
|
|
|
public function messageList()
|
|
|
{
|
|
|
$all = \request()->all();
|
|
|
$messages = [
|
|
|
'to_user_id.required' => '接收人必填',
|
|
|
'user_id.required' => '接收人必填',
|
|
|
];
|
|
|
$validator = Validator::make($all, [
|
|
|
'user_id' => 'required',
|
|
|
'to_user_id' => 'required'
|
|
|
], $messages);
|
|
|
if ($validator->fails()) {
|
|
|
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
|
|
|
}
|
|
|
// 获取会话id
|
|
|
$dialogue = Dialogue::where(function ($query) use ($all) {
|
|
|
$query->where('user_id', $all['user_id'])->where('to_user_id', $all['to_user_id']);
|
|
|
})->orWhere(function ($query) use ($all) {
|
|
|
$query->where('user_id', $all['to_user_id'])->where('to_user_id', $all['user_id']);
|
|
|
})->first();
|
|
|
if (empty($dialogue)) {
|
|
|
return $this->fail([ResponseCode::ERROR_BUSINESS, '会话不存在']);
|
|
|
}
|
|
|
$message = Message::with([
|
|
|
'user' => function ($query) {
|
|
|
$query->select('id', 'nickname', 'name', 'headimgurl', 'username');
|
|
|
},
|
|
|
'toUser' => function ($query) {
|
|
|
$query->select('id', 'nickname', 'name', 'headimgurl', 'username');
|
|
|
}
|
|
|
])->where(function ($query) use ($dialogue) {
|
|
|
$query->where('dialogue_id', $dialogue->id);
|
|
|
})->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc')
|
|
|
->paginate($all['page_size'] ?? 20);
|
|
|
return $this->success(compact('message'));
|
|
|
}
|
|
|
|
|
|
}
|