Files
2025-02-10 10:39:00 +08:00

503 lines
18 KiB
PHP
Raw Permalink 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\manager\controller;
use think\admin\Controller;
use think\admin\service\AdminService;
/**
* 包名管理
* @auth true # 表示需要验证权限
* @menu true # 表示可以生成菜单
*/
class Package extends Controller
{
/**
* 绑定数据表
* @var string
*/
protected $table = 'offer_package';
/**
* 检查包名权限
* @param int $packageId 包名ID
* @return bool
*/
protected function checkPackageAuth($packageId)
{
// 超级管理员直接放行
if (AdminService::instance()->isSuper()) {
return true;
}
// 检查用户是否有包名管理模块的权限
if (!AdminService::instance()->check('package/index')) {
return false;
}
// 检查具体包名权限
$userId = AdminService::instance()->getUserId();
$exists = $this->app->db->name('offer_package_auth')
->where(['package_id' => $packageId, 'user_id' => $userId])
->find();
return !empty($exists);
}
/**
* 获取当前用户可访问的包名ID列表
*/
protected function getAuthPackageIds()
{
// 超级管理员可以访问所有
if (AdminService::instance()->isSuper()) {
return [];
}
// 如果没有包名管理模块权限,则不能访问任何包名
if (!AdminService::instance()->check('package/index')) {
return [-1];
}
// 获取用户被授权的包名列表
$userId = AdminService::instance()->getUserId();
$packageIds = $this->app->db->name('offer_package_auth')
->where(['user_id' => $userId])
->column('package_id');
return $packageIds ?: [-1];
}
/**
* 包名列表
* @auth true # 需要验证权限
* @menu true # 菜单可见
*/
public function index()
{
if ($this->request->isPost()) {
try {
// 获取请求参数
$page = $this->request->post('page/d', 1);
$limit = $this->request->post('limit/d', 15);
$where = [];
// 包名搜索
if ($package_name = $this->request->post('package_name/s', '')) {
$where[] = ['package_name', 'like', "%{$package_name}%"];
}
// 应用名称搜索
if ($name = $this->request->post('name/s', '')) {
$where[] = ['name', 'like', "%{$name}%"];
}
// 状态筛选
if ($status = $this->request->post('status/s', '')) {
$where[] = ['status', '=', $status];
}
// 创建人搜索
if ($username = $this->request->post('username/s', '')) {
$where[] = ['username', 'like', "%{$username}%"];
}
// 时间范围处理
if ($add_time = $this->request->post('add_time/s', '')) {
$times = explode(' - ', $add_time);
if (count($times) == 2) {
$start_time = strtotime($times[0] . ' 00:00:00');
$end_time = strtotime($times[1] . ' 23:59:59');
$where[] = ['add_time', 'between', [$start_time, $end_time]];
}
}
// 查询数据
$query = $this->app->db->name('offer_package')->alias('p');
// 非超级管理员需要进行权限过滤
if (!AdminService::instance()->isSuper()) {
// 检查包名管理模块权限
if (!AdminService::instance()->check('package/index')) {
return json([
'code' => 0,
'msg' => '',
'count' => 0,
'data' => []
]);
}
$userId = AdminService::instance()->getUserId();
// 通过左连接查询有权限的包名
$query->leftJoin('offer_package_auth pa', 'p.id = pa.package_id')
->where('pa.user_id', $userId);
}
// 先获取总数
$total = $query->where($where)->count();
// 分页查询数据
$list = $query->where($where)
->field('p.*') // 只查询包名表的字段
->order('p.id desc')
->group('p.id') // 防止重复数据
->page($page, $limit)
->select()
->toArray();
return json([
'code' => 0,
'msg' => '',
'count' => $total,
'data' => $list
]);
} catch (\Exception $e) {
trace("获取包名列表异常:" . $e->getMessage());
return json([
'code' => 1,
'msg' => '获取数据失败,请稍后重试',
'count' => 0,
'data' => []
]);
}
}
$this->fetch();
}
/**
* 添加包名
* @auth true
* @menu true
*/
public function add()
{
if ($this->request->isPost()) {
// 开启事务
$this->app->db->startTrans();
try {
$data = $this->_vali([
'package_name.require' => '包名不能为空!',
'name.require' => '应用名称不能为空!',
'status.require' => '状态不能为空!',
'status.in:0,1' => '状态值不正确!'
]);
// 检查包名是否已存在
$exists = $this->app->db->name('offer_package')
->where(['package_name' => $data['package_name']])
->find();
if ($exists) {
$this->app->db->rollback();
return json(['code' => 0, 'info' => '包名已存在,请更换!']);
}
// 添加时间字段
$now = time();
$data['add_time'] = $now;
$data['update_time'] = $now;
$data['username'] = session('user.username') ?? '';
// 插入包名数据
$result = $this->app->db->name('offer_package')->insertGetId($data);
if ($result === false) {
$this->app->db->rollback();
return json(['code' => 0, 'info' => '添加失败,请重试!']);
}
// 非超级管理员需要添加权限记录
if (!AdminService::instance()->isSuper()) {
$authData = [
'package_id' => $result,
'user_id' => AdminService::instance()->getUserId(),
'create_at' => date('Y-m-d H:i:s')
];
$authResult = $this->app->db->name('offer_package_auth')->insert($authData);
if ($authResult === false) {
$this->app->db->rollback();
return json(['code' => 0, 'info' => '添加权限记录失败!']);
}
}
$this->app->db->commit();
sysoplog('积分墙列表', '添加成功');
return json(['code' => 1, 'info' => '添加成功!']);
} catch (\Exception $e) {
$this->app->db->rollback();
trace("添加包名异常:" . $e->getMessage());
return json(['code' => 0, 'info' => '系统异常,请稍后重试!']);
}
}
}
/**
* 编辑包名
* @auth true
* @menu true
*/
public function edit()
{
if ($this->request->isPost()) {
try {
$data = $this->_vali([
'id.require' => '记录ID不能为空',
'package_name.require' => '包名不能为空!',
'name.require' => '应用名称不能为空!',
'status.require' => '状态不能为空!',
'status.in:0,1' => '状态值不正确!'
]);
// 检查权限
if (!$this->checkPackageAuth($data['id'])) {
return json(['code' => 0, 'info' => '您没有操作此包名的权限!']);
}
// 检查包名是否已存在(排除当前记录)
$exists = $this->app->db->name('offer_package')
->where('package_name', $data['package_name'])
->where('id', '<>', $data['id'])
->find();
if ($exists) {
return json(['code' => 0, 'info' => '包名已存在,请更换!']);
}
// 更新时间
$data['update_time'] = time();
$data['username'] = session('user.username') ?? '';
$result = $this->app->db->name('offer_package')
->where(['id' => $data['id']])
->update($data);
if ($result === false) {
return json(['code' => 0, 'info' => '更新失败,请重试!']);
}
sysoplog('积分墙列表', '更新成功');
return json(['code' => 1, 'info' => '更新成功!']);
} catch (\Exception $e) {
trace("编辑包名异常:" . $e->getMessage());
return json(['code' => 0, 'info' => '系统异常,请稍后重试!']);
}
}
}
/**
* 删除包名
* @auth true
* @menu true
*/
public function remove()
{
if ($this->request->isPost()) {
// 开启事务
$this->app->db->startTrans();
try {
$id = $this->request->param('id');
if (empty($id)) {
return json(['code' => 0, 'info' => '参数错误,请刷新重试!']);
}
// 检查权限
if (!$this->checkPackageAuth($id)) {
return json(['code' => 0, 'info' => '您没有操作此包名的权限!']);
}
// 删除包名记录
$result = $this->app->db->name('offer_package')
->where(['id' => $id])
->delete();
if ($result === false) {
$this->app->db->rollback();
return json(['code' => 0, 'info' => '删除失败,请重试!']);
}
// 同步删除权限表中的相关记录
$this->app->db->name('offer_package_auth')
->where(['package_id' => $id])
->delete();
$this->app->db->commit();
sysoplog('积分墙列表', '删除成功');
return json(['code' => 1, 'info' => '删除成功!']);
} catch (\Exception $e) {
$this->app->db->rollback();
trace("删除包名异常:" . $e->getMessage());
return json(['code' => 0, 'info' => '系统异常,请稍后重试!']);
}
}
}
/**
* 切换状态
* @auth true
* @menu true
*/
public function state()
{
if ($this->request->isPost()) {
try {
$data = $this->_vali([
'id.require' => '记录ID不能为空',
'status.in:0,1' => '状态值不正确!'
]);
// 检查权限
if (!$this->checkPackageAuth($data['id'])) {
return json(['code' => 0, 'info' => '您没有操作此包名的权限!']);
}
// 检查记录是否存在
$exists = $this->app->db->name('offer_package')
->where(['id' => $data['id']])
->find();
if (empty($exists)) {
return json(['code' => 0, 'info' => '记录不存在!']);
}
// 更新状态
$updateData = [
'status' => $data['status'],
'update_time' => time(),
'username' => session('user.username') ?? ''
];
$result = $this->app->db->name('offer_package')
->where(['id' => $data['id']])
->update($updateData);
if ($result === false) {
return json(['code' => 0, 'info' => '状态更新失败,请重试!']);
}
sysoplog('积分墙列表', '状态更新成功');
return json(['code' => 1, 'info' => '状态更新成功!']);
} catch (\Exception $e) {
trace("状态切换异常:" . $e->getMessage() . "\n" . $e->getTraceAsString());
return json(['code' => 0, 'info' => '系统异常,请稍后重试!']);
}
}
}
/**
* 生成测试数据
* @auth true
*/
public function generateTestData()
{
try {
// 设置执行时间为无限制
set_time_limit(0);
ini_set('memory_limit', '1024M');
// 开启事务
$this->app->db->startTrans();
try {
$insertData = [];
$existPackages = [];
$total = 8000; // 总记录数
$batchSize = 500; // 每批插入数量
$startTime = time();
// 获取已存在的包名,避免重复
$exists = $this->app->db->name($this->table)
->column('package_name');
$existPackages = array_flip($exists);
// 预生成一些常用词,提高应用名称的真实性
$prefixes = ['Super', 'My', 'Fast', 'Smart', 'Easy', 'Pro', 'Best', 'Quick'];
$suffixes = ['Browser', 'Player', 'Cleaner', 'Manager', 'Tool', 'Helper', 'App', 'Game'];
$domains = ['com', 'net', 'org', 'app', 'tech', 'io'];
// 生成记录
for ($i = 0; $i < $total; $i++) {
// 生成唯一包名
do {
// 生成更真实的包名 xxx.xxx.xxx.xxx
$domain = $domains[array_rand($domains)];
$company = $this->generateRandomString(rand(3, 8));
$product = $this->generateRandomString(rand(3, 8));
$module = $this->generateRandomString(rand(3, 8));
$packageName = "{$domain}.{$company}.{$product}.{$module}";
} while (isset($existPackages[$packageName]));
$existPackages[$packageName] = 1;
// 生成更真实的应用名称
$prefix = $prefixes[array_rand($prefixes)];
$suffix = $suffixes[array_rand($suffixes)];
$appName = $prefix . ' ' . $suffix . ' ' . ($i + 1);
// 生成数据
$insertData[] = [
'package_name' => $packageName,
'name' => $appName,
'status' => rand(0, 1), // 随机状态
'add_time' => time() - rand(0, 86400 * 30), // 随机时间最近30天内
'update_time' => time(),
'username' => session('user.username') ?? 'system'
];
// 批量插入
if (count($insertData) >= $batchSize) {
$this->app->db->name($this->table)->insertAll($insertData);
$insertData = [];
// 输出进度
$progress = round(($i + 1) / $total * 100, 2);
trace("数据生成进度:{$progress}%");
}
}
// 插入剩余数据
if (!empty($insertData)) {
$this->app->db->name($this->table)->insertAll($insertData);
}
$endTime = time();
$timeUsed = $endTime - $startTime;
$this->app->db->commit();
return json([
'code' => 1,
'info' => "测试数据生成成功!共生成 {$total} 条记录,耗时 {$timeUsed}"
]);
} catch (\Exception $e) {
$this->app->db->rollback();
throw $e;
}
} catch (\Exception $e) {
trace("生成测试数据异常:" . $e->getMessage() . "\n" . $e->getTraceAsString());
return json(['code' => 0, 'info' => '系统异常:' . $e->getMessage()]);
}
}
/**
* 生成随机字符串
* @param int $length 长度
* @return string
*/
private function generateRandomString($length = 5)
{
// 添加数字,使包名更真实
$characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
$result = '';
// 第一个字符必须是字母
$result .= $characters[rand(0, 25)];
// 生成剩余字符
for ($i = 1; $i < $length; $i++) {
$result .= $characters[rand(0, strlen($characters) - 1)];
}
return $result;
}
}