feat(hjf): H5路由修复、分销等级显示优化、个人中心等级徽章

H5 部署与路由:
- manifest.json: router.base 改为 "/" 适配 public/ 根目录部署
- nginx-crmeb.conf: 恢复与 feature/fsgx 一致的原始配置
- App.vue: PC端重定向路径改为动态推导,修复死循环加载问题
- static/html/pc.html: 动态推导 H5 根路径,适配本地/云端两种部署

H5登录:
- pages/users/login/index.vue: H5端获取验证码跳过安全验证(条件编译)

分销等级展示修复:
- AgentLevelServices: 新增 loadHjfUserListLevelMaps/pickHjfLevelRowForUserListDisplay
  统一等级名称解析逻辑,优先返回 HJF 官方名称;新增 getUpgradeTasksForLevel 封装
- UserServices/MemberLevelServices: 改用统一解析方法,修复 protected $dao 访问错误
- api/hjf/MemberController: 直接取 eb_agent_level.name,新增 agent_level 原始值返回
- admin/v1/hjf/MemberController: team() 改用封装方法替代直接访问 protected dao

个人中心等级徽章:
- pages/user/index.vue + member/index.vue: memberInfo 沿链路透传
- member/template1.vue: UID右侧显示HjfMemberBadge,直接读 userInfo.agent_level_name
  无需等待异步 memberInfo,agentLevelGrade 计算属性从名称推导颜色等级

商品列表修复:
- BaseController.php/Common.php: 恢复加密版,修复 CRMEB 授权检查失败导致的400错误
- StoreProduct model: 移除冲突的 model maker 回调

数据库:
- hjf_migration.sql: 完善会员等级体系迁移脚本
- eb_agent_level.sql: 新增等级初始数据脚本

Made-with: Cursor
This commit is contained in:
apple
2026-03-22 01:43:36 +08:00
parent 590eca8c22
commit 8592243d36
34 changed files with 1467 additions and 745 deletions

View File

@@ -5,18 +5,19 @@ namespace app\controller\admin\v1\hjf;
use app\controller\admin\AuthController;
use app\dao\user\UserDao;
use app\services\agent\AgentLevelServices;
use app\services\hjf\MemberLevelServices;
use app\services\system\SystemConfigServices;
use crmeb\services\SystemConfigService;
use think\annotation\Inject;
/**
* Admin · 会员管理接口
* Admin · 会员管理接口(改造复用版)
*
* GET /adminapi/hjf/member/list — 会员列表(分页,支持按等级筛选)
* PUT /adminapi/hjf/member/level/:uid — 手动调整会员等级
* GET /adminapi/hjf/member/config获取会员等级配置
* POST /adminapi/hjf/member/config 保存会员等级配置
* 复用 eb_agent_level 体系,使用 eb_user.agent_level 字段。
*
* GET /adminapi/hjf/member/list 会员列表
* PUT /adminapi/hjf/member/level/:uid手动调整会员等级
* GET /adminapi/hjf/member/config — 获取会员等级配置(从 eb_agent_level 读取)
* POST /adminapi/hjf/member/config — 保存会员等级配置(写入 eb_agent_level
*
* Class MemberController
* @package app\controller\admin\v1\hjf
@@ -29,6 +30,9 @@ class MemberController extends AuthController
#[Inject]
protected MemberLevelServices $levelServices;
#[Inject]
protected AgentLevelServices $agentLevelServices;
/**
* 会员列表(分页)
*/
@@ -47,25 +51,38 @@ class MemberController extends AuthController
if ($where['keyword'] !== '') {
$condition['uid|nickname|phone'] = ['like', '%' . $where['keyword'] . '%'];
}
if ($where['member_level'] !== '') {
$condition['member_level'] = (int)$where['member_level'];
$grade = (int)$where['member_level'];
if ($grade === 0) {
$condition['agent_level'] = 0;
} else {
$agentLevelId = $this->agentLevelServices->getLevelIdByGrade($grade);
$condition['agent_level'] = $agentLevelId ?: -1;
}
}
$count = $this->userDao->count($condition);
$list = $this->userDao->selectList(
$condition,
'uid,nickname,avatar,phone,member_level,frozen_points,available_points,now_money,spread_uid,add_time',
'uid,nickname,avatar,phone,agent_level,frozen_points,available_points,now_money,spread_uid,add_time',
$page,
$limit,
'uid',
'desc'
);
// 附加直推单数 & 伞下单数
$levelList = $this->agentLevelServices->dao->getList(['is_del' => 0, 'status' => 1]);
$levelMap = array_column($levelList, null, 'id');
foreach ($list as &$item) {
$item['direct_order_count'] = $this->levelServices->getDirectQueueOrderCount((int)$item['uid']);
$agentLevelId = (int)($item['agent_level'] ?? 0);
$levelInfo = $levelMap[$agentLevelId] ?? null;
$item['member_level'] = $levelInfo ? (int)$levelInfo['grade'] : 0;
$item['member_level_name'] = $levelInfo ? $levelInfo['name'] : '普通会员';
$item['direct_order_count'] = $this->levelServices->getDirectQueueOrderCount((int)$item['uid']);
$item['umbrella_order_count'] = $this->levelServices->getUmbrellaQueueOrderCount((int)$item['uid']);
$item['direct_spread_count'] = $this->levelServices->getDirectSpreadCount((int)$item['uid']);
$item['direct_spread_count'] = $this->levelServices->getDirectSpreadCount((int)$item['uid']);
}
unset($item);
@@ -74,17 +91,15 @@ class MemberController extends AuthController
/**
* 手动调整会员等级
*
* @param int $uid
*/
public function updateLevel(int $uid): mixed
{
$data = $this->request->getMore([
['member_level', 0],
]);
$newLevel = (int)$data['member_level'];
$grade = (int)$data['member_level'];
if ($newLevel < 0 || $newLevel > 4) {
if ($grade < 0 || $grade > 4) {
return $this->fail('等级范围 0-4');
}
@@ -93,78 +108,51 @@ class MemberController extends AuthController
return $this->fail('用户不存在');
}
$this->userDao->update($uid, ['member_level' => $newLevel], 'uid');
$this->levelServices->setUserLevel($uid, $grade);
return $this->success('更新成功');
}
/**
* 获取会员等级配置
* 获取会员等级配置(从 eb_agent_level 表读取)
*/
public function getConfig(): mixed
{
$keys = [
'hjf_level_direct_require_1',
'hjf_level_umbrella_require_2',
'hjf_level_umbrella_require_3',
'hjf_level_umbrella_require_4',
'hjf_reward_direct_1',
'hjf_reward_direct_2',
'hjf_reward_direct_3',
'hjf_reward_direct_4',
'hjf_reward_umbrella_1',
'hjf_reward_umbrella_2',
'hjf_reward_umbrella_3',
'hjf_reward_umbrella_4',
];
$levelList = $this->agentLevelServices->dao->getList(['is_del' => 0, 'status' => 1]);
$config = [];
$defaults = [
'hjf_level_direct_require_1' => 3,
'hjf_level_umbrella_require_2' => 30,
'hjf_level_umbrella_require_3' => 100,
'hjf_level_umbrella_require_4' => 1000,
'hjf_reward_direct_1' => 500,
'hjf_reward_direct_2' => 800,
'hjf_reward_direct_3' => 1000,
'hjf_reward_direct_4' => 1300,
'hjf_reward_umbrella_1' => 0,
'hjf_reward_umbrella_2' => 300,
'hjf_reward_umbrella_3' => 200,
'hjf_reward_umbrella_4' => 300,
];
foreach ($keys as $key) {
$config[$key] = SystemConfigService::get($key, $defaults[$key] ?? 0);
foreach ($levelList as $level) {
$config[] = [
'id' => $level['id'],
'name' => $level['name'],
'grade' => $level['grade'],
'direct_reward_points' => $level['direct_reward_points'] ?? 0,
'umbrella_reward_points' => $level['umbrella_reward_points'] ?? 0,
];
}
return $this->success($config);
}
/**
* 保存会员等级配置
* 保存会员等级配置(写入 eb_agent_level 表)
*/
public function saveConfig(SystemConfigServices $configServices): mixed
public function saveConfig(): mixed
{
$allowedKeys = [
'hjf_level_direct_require_1',
'hjf_level_umbrella_require_2',
'hjf_level_umbrella_require_3',
'hjf_level_umbrella_require_4',
'hjf_reward_direct_1',
'hjf_reward_direct_2',
'hjf_reward_direct_3',
'hjf_reward_direct_4',
'hjf_reward_umbrella_1',
'hjf_reward_umbrella_2',
'hjf_reward_umbrella_3',
'hjf_reward_umbrella_4',
];
$levels = $this->request->post('levels', []);
if (!is_array($levels)) {
return $this->fail('参数格式错误');
}
$data = $this->request->post();
foreach ($data as $key => $value) {
if (in_array($key, $allowedKeys, true)) {
$configServices->setConfig($key, (string)$value);
foreach ($levels as $item) {
if (empty($item['id'])) continue;
$updateData = [];
if (isset($item['direct_reward_points'])) {
$updateData['direct_reward_points'] = (int)$item['direct_reward_points'];
}
if (isset($item['umbrella_reward_points'])) {
$updateData['umbrella_reward_points'] = (int)$item['umbrella_reward_points'];
}
if ($updateData) {
$this->agentLevelServices->dao->update((int)$item['id'], $updateData);
}
}