manghe/app/api/controller/Index.php
2025-04-17 14:35:10 +08:00

381 lines
13 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
namespace app\api\controller;
use app\api\controller\Base;
use app\common\model\Advert;
use app\common\model\Danye;
use app\common\model\Goods;
use app\common\model\GoodsList;
use app\common\model\OrderList;
use app\common\model\User;
use app\common\model\Yushou;
use think\facade\Db;
use \think\Request;
use app\common\model\Order;
use app\common\model\ProfitMoney;
use PhpOffice\PhpSpreadsheet\Chart\Title;
class Index extends Base
{
//首页
public function index(Request $request)
{
#首页轮播图
$advert = Advert::field('imgurl,ttype,coupon_id,goods_id,url')->where(['type' => 1])->order('sort desc,id desc')->select();
foreach ($advert as &$advert_value) {
$advert_value['imgurl'] = imageUrl($advert_value['imgurl']);
}
$tuijian = Advert::field('imgurl,ttype,coupon_id,goods_id,url')->where(['type' => 5])->order('sort desc,id desc')->select();
foreach ($tuijian as &$advert_value) {
$advert_value['imgurl'] = imageUrl($advert_value['imgurl']);
}
#公告
$notice = Danye::field('title,content')->where(['id' => 3])->find();
$notice['content'] = contentUrl($notice['content']);
#客服
$rule = getConfig('base');
$other = [
'is_shou_tan' => $rule['is_shou_tan'],
'jump_appid' => $rule['jump_appid'],
'corpid' => $rule['corpid'],
'wx_link' => $rule['wx_link'],
'erweima' => imageUrl($rule['erweima']),
];
return $this->renderSuccess('请求成功', compact('advert', 'notice', 'other', 'tuijian'));
}
/**
* 预售日历
*/
public function yushourili()
{
$data = Yushou::field('id,title,imgurl,sale_time,goods_id')->order('sort desc,id desc')->limit(10)->select()->toArray();
foreach ($data as &$value) {
$goods = Goods::field('id')
->where('id', '=', $value['goods_id'])
->where('status', 'in', [1, 3])
->find();
if (!$goods) {
Yushou::field('goods_id')->where('id', '=', $value['id'])->update(['goods_id' => 0]);
$value['goods_id'] = 0;
}
$value['imgurl'] = imageUrl($value['imgurl']);
$value['month'] = date('m月', $value['sale_time']);
$value['day'] = date('d', $value['sale_time']);
}
return $this->renderSuccess("请求成功", $data);
}
/**
* 单页
*/
public function danye()
{
// 设置header
$type = \request()->param('type/d', 0);
$info = Danye::where(['id' => $type])->find();
$is_image_optimizer = 0;
if ($info) {
$content = contentUrl($info['content']);
$is_image_optimizer = $info['is_image_optimizer'];
// header('Access-Control-Allow-Headers: Content-Type');
} else {
$content = '';
}
// return $this->renderSuccess("请求成功", $content);
return json(['status' => 1, 'msg' => '请求成功', 'data' => $content, 'is_image_optimizer' => $is_image_optimizer]);
}
/**
* 单页
*/
public function getDanye()
{
$type = \request()->param('type/d', 0);
$info = Danye::where(['id' => $type])->find();
if ($info) {
$content = contentUrl($info['content']);
} else {
$content = '';
}
return $this->renderSuccess("请求成功", [
'content' => $content,
'title' => $info['title']
]);
}
/**
* 获取轮播图
* @return \think\response\Json
*/
public function getAdvert()
{
$type = request()->param('type_id/d', 1);
#首页轮播图
$advert = Advert::field('imgurl,ttype,coupon_id,goods_id,url')->where(['type' => $type])->order('sort desc,id desc')->select();
foreach ($advert as &$advert_value) {
$advert_value['imgurl'] = imageUrl($advert_value['imgurl']);
}
return $this->renderSuccess('请求成功', $advert);
}
public function record(Request $request)
{
$whe = [];
// $whe[] = ['order_type', '<', 5];
$whe[] = ['status', '=', 1];
$whe[] = ['price', '>', 0];
// 获取当前月份的第一天
$firstDayOfMonth = date('Y-m-01');
// 获取当前月份的最后一天
$lastDayOfMonth = date('Y-m-t');
;
$start_time = strtotime($firstDayOfMonth);
$end_time = strtotime($lastDayOfMonth);
// if ($start_time > $end_time) {
// $this->err('开始时间不能大于结束时间');
// }
$whe[] = ['addtime', 'BETWEEN', array($start_time, $end_time)];
$field = "id,user_id,sum(price) as price";
$list = Order::where($whe)
->field($field)
->group("user_id")
->order("price desc")
->paginate(['list_rows' => $this->page]);
$page = $list->render();
$data = [];
$data['list'] = $list->toArray()['data'];
foreach ($data['list'] as &$value) {
$user_info = User::field('nickname,headimg,mobile')->where('id', '=', $value['user_id'])->find();
$value['nickname'] = $user_info['nickname'];
$value['headimg'] = imageUrl($user_info['headimg']);
// if (!strpos($$value['headimg'], 'http:') && !strpos($$value['headimg'], 'https:')) {
// $value['headimg'] = imageUrl($value['headimg']);
// ;
// }
$value['mobile'] = $user_info['mobile'];
}
return $this->renderSuccess('请求成功', $data);
}
/**
* 邀请排行
*/
public function get_user_yaoqing()
{
//select * from ( SELECT pid,count(1) n FROM `user` where pid>0 group by pid ) t where n>1 order by n desc
$list = User::where('pid', '>', 0)
->field('pid, COUNT(1) as n') // 选取 pid 和 计数字段
->group('pid')
->having('n > 30') // `having` 需要使用 `as` 取别名
->order('n desc')
// ->limit(10) // 添加限制条数
->select();
$data = array();
$index = 1;
foreach ($list as $item) {
$pid = $item['pid'];
// $count = $item['n'];
// $item['user_id'] = $pid;
$user_info = User::field('nickname,headimg,mobile')->where('id', '=', $pid)->find();
if ($user_info != null) {
$data[] = [
'index' => $index,
'user_id' => $pid,
'invitenumber' => $item['n'],
'nickname' => $user_info['nickname'],
'headimg' => imageUrl($user_info['headimg'])
];
$index++;
}
}
return $this->renderSuccess('请求成功', $data);
}
public function generate_urllink()
{
$wxServer = new \app\common\server\Wx($this->app);
$user_base = $wxServer->generateUrlLink();
header("Location: " . $user_base);
exit();
// return $this->renderSuccess('请求成功', $user_base );
}
/**
* 生成带用户推广二维码的海报图片
* @return \think\response\Json|void
*/
public function generate_urllinks()
{
// 获取并验证用户ID
$userId = request()->param('userId/d', 0);
if ($userId <= 0) {
return $this->renderError('无效的用户ID');
}
// 检查用户是否存在
$user = User::find($userId);
if (!$user) {
return $this->renderError('用户不存在');
}
// 获取配置信息
$config = getConfig('base');
$posterPath = $config['poster_template'] ?? '/img_poster.jpg';
$cacheExpire = $config['poster_cache_expire'] ?? 86400; // 默认缓存1天
// 创建缓存目录结构用户ID分组避免单目录文件过多
$userGroup = floor($userId / 1000); // 每1000个用户一个目录
$cacheDir = runtime_path() . 'poster/' . $userGroup . '/';
if (!is_dir($cacheDir)) {
mkdir($cacheDir, 0755, true);
}
// 缓存文件名基于用户ID和模板文件的哈希
$templateFile = getcwd() . $posterPath;
$templateHash = md5_file($templateFile); // 使用文件内容哈希而不是修改时间
$cacheFile = $cacheDir . 'user_' . $userId . '_' . $templateHash . '.png';
// 清理该用户的旧缓存文件(保留当前有效的)
$this->cleanUserPosterCache($cacheDir, $userId, $templateHash);
// 定期清理过期缓存每100次请求执行一次避免频繁IO
if (mt_rand(1, 100) === 1) {
$this->cleanExpiredPosterCache($cacheExpire);
}
// 如果缓存存在且未过期,直接使用缓存
if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < $cacheExpire)) {
$imageData = file_get_contents($cacheFile);
} else {
// 生成URL链接
$wxServer = new \app\common\server\Wx($this->app);
$user_base = $wxServer->generateUrlLinks($userId);
// 生成海报
$autoload = new \app\common\server\autoload();
$imageData = $autoload->generatePosterWithQR($templateFile, $user_base);
// 保存到缓存
if ($imageData) {
file_put_contents($cacheFile, $imageData);
// 更新最后访问时间文件(用于清理判断)
touch($cacheFile);
}
}
// 检查是否需要直接输出图片
$outputImage = request()->param('output/d', 1);
if ($imageData && $outputImage) {
header('Content-Type: image/png');
header('Content-Length: ' . strlen($imageData));
echo $imageData;
exit();
} elseif ($imageData) {
// 生成可访问的URL使用相对路径更安全且灵活
$relativePath = 'runtime/poster/' . $userGroup . '/user_' . $userId . '_' . $templateHash . '.png';
return $this->renderSuccess('海报生成成功', [
'image_url' => request()->domain() . '/' . $relativePath
]);
} else {
// 生成失败,返回错误信息
return $this->renderError('海报生成失败');
}
}
/**
* 清理指定用户的旧海报缓存
* @param string $cacheDir 缓存目录
* @param int $userId 用户ID
* @param string $currentHash 当前模板哈希
*/
private function cleanUserPosterCache($cacheDir, $userId, $currentHash)
{
// 查找该用户的所有缓存文件
$pattern = $cacheDir . 'user_' . $userId . '_*.png';
$files = glob($pattern);
foreach ($files as $file) {
// 如果不是当前使用的缓存文件,则删除
if (strpos($file, 'user_' . $userId . '_' . $currentHash . '.png') === false) {
@unlink($file);
}
}
}
/**
* 清理所有过期的海报缓存
* @param int $expireTime 过期时间(秒)
*/
private function cleanExpiredPosterCache($expireTime)
{
// 获取缓存根目录
$rootCacheDir = runtime_path() . 'poster/';
if (!is_dir($rootCacheDir)) {
return;
}
// 当前时间
$now = time();
// 遍历所有用户组目录
$groupDirs = glob($rootCacheDir . '*/');
foreach ($groupDirs as $groupDir) {
// 获取组目录中的所有PNG文件
$files = glob($groupDir . '*.png');
foreach ($files as $file) {
// 如果文件过期(最后修改时间超过过期时间)
if ($now - filemtime($file) > $expireTime) {
@unlink($file);
}
}
// 如果目录为空,删除目录
$remainingFiles = glob($groupDir . '*');
if (empty($remainingFiles)) {
@rmdir($groupDir);
}
}
}
/**
* 获取排行榜数据
* 支持diamond(钻石排行榜)、integral(UU币排行榜)、dadajuan(达达卷排行榜)、invite(邀请新人排行榜)、loss(亏损补贴排行榜)
*
* @return \think\response\Json
*/
public function getRankList()
{
// 获取排行榜类型参数
$type = request()->param('type', '');
// 验证排行榜类型是否有效
$validTypes = ['diamond', 'integral', 'dadajuan', 'invite', 'loss'];
if (!in_array($type, $validTypes)) {
return $this->renderError('无效的排行榜类型');
}
// 设置分页参数
$page = request()->param('page/d', 1);
$limit = request()->param('limit/d', 10);
// 初始化排行榜服务类
$rankService = new \app\common\service\RankService();
$data = $rankService->getRankList($type, $page, $limit);
// 返回数据
return $this->renderSuccess('请求成功', $data);
}
}