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.

397 lines
16 KiB

6 months ago
<?php
namespace App\Http\Controllers\Admin;
use App\Exports\BaseExport;
use App\Helpers\ResponseCode;
use App\Models\AppointmentType;
use App\Models\CustomForm;
4 months ago
use App\Models\Dialogue;
4 months ago
use App\Models\Message;
6 months ago
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="需要输出的关联关系数组包括teachercourseSettingscoursePeriods"),
* @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->get()->toArray();
$export_fields = $all['export_fields'] ?? [];
// 导出文件名字
$tableName = $this->model->getTable();
$filename = (new CustomForm())->getTableComment($tableName);
return Excel::download(new BaseExport($export_fields, $list, $tableName), $filename . 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="邮箱"),
5 months ago
* @OA\Parameter(name="status", in="query", @OA\Schema(type="integer"), required=false, description="状态0待审核1通过2拒绝3退回修改4永久隐藏"),
6 months ago
* @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();
}
6 months ago
/**
* @OA\Get(
* path="/api/admin/supply-demand/chart",
* tags={"供需信息管理"},
* summary="交互统计",
* description="",
4 months ago
* @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="结束日期"),
4 months ago
* @OA\Parameter(name="type", in="query", @OA\Schema(type="string"), required=true, description="type类型"),
4 months ago
* @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="页码"),
6 months ago
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="暂无"
* )
* )
*/
public function chart()
{
4 months ago
$now = date('Y-m-d');
$startDate = request('start_date', $now);
$endDate = request('end_date', $now);
$type = request('type');
6 months ago
4 months ago
// 计算上期时间段(与当前时间段长度相同)
$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);
4 months ago
// 当期供需发布分页
4 months ago
$list = SupplyDemand::with(['user', 'dialogues' => function ($query) {
4 months ago
$query->with(['user', 'toUser', 'messages' => function ($q) {
$q->orderBy('created_at', 'desc');
}])->limit(2)->orderBy('created_at', 'desc');
4 months ago
}])->where(function ($query) use ($type) {
4 months ago
if ($type) {
$query->where('type', $type);
}
})->whereBetween('created_at', [$startDate, $endDate])
->paginate($all['page_size'] ?? 20);
4 months ago
return $this->success([
4 months ago
'list' => $list,
4 months ago
'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
];
6 months ago
}
6 months ago
4 months ago
/**
* @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) {
4 months ago
$query->where('user_id', $all['to_user_id'])->where('to_user_id', $all['user_id']);
4 months ago
})->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'));
}
6 months ago
}