feat: 完成v10.1.0版本大更新,新增密保系统、勋章、任务、排行榜等功能

### 变更详情
1. 新增密保问题系统,支持8种预置验证问题,多场景支持多验证方式
2. 新增勋章管理模块,包含勋章配置、用户勋章关联管理
3. 新增每日任务系统,支持任务配置和用户进度追踪
4. 新增赛季排行榜功能,支持周/月赛季排行与奖励结算
5. 新增信息流推荐权重配置管理
6. 重构服务路径分层,按设备/网络/数据分类管理服务
7. 优化Feed请求参数截断逻辑,避免URL过长
8. 新增等级工具类,统一处理等级颜色与称号展示
9. 新增屏幕共享共享信令Provider,复用传输服务实例
10. 新增Android/iOS分享适配与桌面小组件支持
11. 清理旧版测试脚本,新增部署维护脚本
12. 完善用户注销关联数据清理逻辑
This commit is contained in:
Developer
2026-05-15 07:02:56 +08:00
parent 228095f80a
commit fc6fd7be0e
264 changed files with 24783 additions and 6267 deletions

View File

@@ -0,0 +1,23 @@
<?php
namespace app\admin\controller;
use app\common\controller\Backend;
/**
* 勋章管理
* @icon fa fa-shield
* @time 2026-05-14
* @description 管理用户勋章配置、稀有度和获取条件
*/
class Badge extends Backend
{
protected $model = null;
protected $searchFields = 'id,name';
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\Badge;
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace app\admin\controller;
use app\common\controller\Backend;
/**
* 每日任务管理
* @icon fa fa-tasks
* @time 2026-05-14
* @description 管理每日任务定义、类型和奖励配置
*/
class DailyTask extends Backend
{
protected $model = null;
protected $searchFields = 'id,name';
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\DailyTask;
}
}

View File

@@ -11,15 +11,17 @@ namespace app\admin\controller;
use app\common\controller\Backend;
use think\Db;
use app\admin\model\FeedWeightConfig as FeedWeightConfigModel;
class FeedWeight extends Backend
{
protected $model = null;
protected $searchFields = 'id,feed_type';
public function _initialize()
{
parent::_initialize();
$this->model = Db::name('feed_weight_config');
$this->model = new FeedWeightConfigModel;
}
/**

View File

@@ -0,0 +1,39 @@
<?php
namespace app\admin\controller;
use app\common\controller\Backend;
/**
* 赛季管理
* @icon fa fa-trophy
* @time 2026-05-14
* @description 管理赛季定义、奖励配置、结算操作
*/
class RankSeason extends Backend
{
protected $model = null;
protected $searchFields = 'id,name';
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\RankSeason;
}
/**
* @name 手动结算赛季
*/
public function settle($ids = '')
{
$ids = $ids ? $ids : $this->request->param('ids');
if (!$ids) $this->error('参数错误');
$row = $this->model->get($ids);
if (!$row) $this->error('赛季不存在');
if ($row['status'] === 'settled') $this->error('赛季已结算');
$this->model->where('id', $ids)->update(['status' => 'settled', 'settle_time' => time(), 'updatetime' => time()]);
$this->success('结算成功');
}
}

View File

@@ -190,6 +190,9 @@ class Userdeletion extends Backend
'article_like',
'article_rating',
'feed_interaction',
'user_exp_log',
'user_badge',
'user_task',
];
foreach ($relatedTables as $table) {
@@ -205,6 +208,8 @@ class Userdeletion extends Backend
]);
} catch (\Exception $e) {}
try { Db::name('user_deletion')->where('user_id', $userId)->where('id', '<>', $record['id'])->delete(); } catch (\Exception $e) {}
Db::name('user')->where('id', $userId)->delete();
Db::name('user_deletion')->where('id', $record['id'])->update([

View File

@@ -0,0 +1,23 @@
<?php
namespace app\admin\controller\user;
use app\common\controller\Backend;
/**
* 排名记录
* @icon fa fa-list-ol
* @time 2026-05-14
* @description 查看赛季排名记录
*/
class RankRecord extends Backend
{
protected $model = null;
protected $searchFields = 'id';
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\RankRecord;
}
}

View File

@@ -4,6 +4,7 @@ namespace app\admin\controller\user;
use app\common\controller\Backend;
use app\common\library\Auth;
use think\Db;
/**
* 会员管理
@@ -114,7 +115,9 @@ class User extends Backend
}
/**
* 删除
* @name 删除用户
* @desc 批量删除用户及其关联数据(签到/收藏/笔记/积分日志/勋章/任务/EXP日志等)
* @update v12.0.0 修复批量删除+关联数据清理
*/
public function del($ids = "")
{
@@ -122,12 +125,40 @@ class User extends Backend
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
$row = $this->model->get($ids);
$this->modelValidate = true;
if (!$row) {
$this->error(__('No Results were found'));
if (!$ids) {
$this->error(__('Parameter %s can not be empty', 'ids'));
}
$idArr = array_filter(explode(',', $ids), 'is_numeric');
if (empty($idArr)) {
$this->error(__('Parameter %s can not be empty', 'ids'));
}
foreach ($idArr as $userId) {
Db::startTrans();
try {
$relatedTables = [
'user_token', 'user_device', 'user_signin', 'user_favorite',
'user_note', 'user_score_log', 'user_money_log', 'user_title_log',
'coin_log', 'article_like', 'article_rating', 'feed_interaction',
'user_exp_log', 'user_badge', 'user_task',
];
foreach ($relatedTables as $table) {
try { Db::name($table)->where('user_id', $userId)->delete(); } catch (\Exception $e) {}
}
try {
Db::name('article')->where('user_id', $userId)->update([
'deletetime' => time(),
'status' => 'rejected',
]);
} catch (\Exception $e) {}
try { Db::name('user_deletion')->where('user_id', $userId)->delete(); } catch (\Exception $e) {}
Db::name('user')->where('id', $userId)->delete();
Db::commit();
} catch (\Exception $e) {
Db::rollback();
$this->error('删除用户ID:' . $userId . '失败 - ' . $e->getMessage());
}
}
Auth::instance()->delete($row['id']);
$this->success();
}

View File

@@ -0,0 +1,70 @@
<?php
namespace app\admin\controller\user;
use app\common\controller\Backend;
/**
* 用户勋章管理
* @icon fa fa-id-badge
* @time 2026-05-14
* @description 管理用户勋章发放与收回,支持只读列表和手动操作
* @lastUpdate 初始创建
*/
class UserBadge extends Backend
{
protected $model = null;
protected $searchFields = 'user_id';
protected $relationSearch = true;
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\UserBadge;
}
public function index()
{
$this->relationSearch = true;
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax()) {
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$list = $this->model
->with(['user', 'badge'])
->where($where)
->order($sort, $order)
->paginate($limit);
foreach ($list as $row) {
$row->visible(['id', 'user_id', 'badge_id', 'is_displayed', 'unlocked_at', 'createtime']);
$row->visible(['user', 'badge']);
if ($row->user) $row->getRelation('user')->visible(['id', 'nickname']);
if ($row->badge) $row->getRelation('badge')->visible(['id', 'name', 'icon']);
}
$result = array("total" => $list->total(), "rows" => $list->items());
return json($result);
}
return $this->view->fetch();
}
public function add()
{
if ($this->request->isPost()) {
$params = $this->request->post('row/a');
if (!$params) $this->error(__('Invalid parameters'));
$userId = intval($params['user_id'] ?? 0);
$badgeId = intval($params['badge_id'] ?? 0);
if (!$userId || !$badgeId) $this->error('用户ID和勋章ID必填');
$exists = db('user_badge')->where('user_id', $userId)->where('badge_id', $badgeId)->find();
if ($exists) $this->error('该用户已拥有此勋章');
db('user_badge')->insert([
'user_id' => $userId,
'badge_id' => $badgeId,
'is_displayed' => 0,
'unlocked_at' => time(),
'createtime' => time(),
]);
$this->success();
}
return parent::add();
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace app\admin\controller\user;
use app\common\controller\Backend;
/**
* EXP经验值日志
* @icon fa fa-bolt
* @time 2026-05-14
* @description 查看用户EXP经验值变动记录
*/
class UserExpLog extends Backend
{
protected $model = null;
protected $searchFields = 'id';
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\UserExpLog;
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace app\admin\controller\user;
use app\common\controller\Backend;
/**
* 用户任务进度
* @icon fa fa-list-check
* @time 2026-05-14
* @description 查看用户每日任务完成进度
*/
class UserTask extends Backend
{
protected $model = null;
protected $searchFields = 'id';
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\UserTask;
}
}