feat(fsgx): HJF queue merge, brokerage timing, cycle commission, points release

- Add HJF jobs, services, DAOs, models, admin/API controllers, release command
- Respect brokerage_timing (on_pay vs confirm); dispatch HjfOrderPayJob for queue goods
- Queue-only cycle commission and position index fix in StoreOrderCreateServices
- UserBill income types: frozen_points_brokerage, frozen_points_release
- Timer: fsgx_release_frozen_points -> PointsReleaseServices
- Agent tasks: no_assess filtering for direct/umbrella counts
- Migrations: queue_pool, points_release_log, fsgx_v1 checklist updates
- Admin/uniapp: crontab preset, membership level, user list, finance routes, docs

Made-with: Cursor
This commit is contained in:
apple
2026-03-24 11:59:09 +08:00
parent 434aa8c69d
commit 76ccb24679
59 changed files with 2902 additions and 237 deletions

View File

@@ -40,6 +40,133 @@ class AgentLevelServices extends BaseServices
#[Inject]
protected AgentLevelDao $dao;
/**
* HJF 官方会员等级名称(与数据库插入数据一致)
* 用于区分 CRMEB 默认「等级一/等级二…」与 HJF 创客/云店…
*/
public const HJF_OFFICIAL_LEVEL_NAMES = ['创客', '云店', '服务商', '分公司'];
/**
* 一次查询并返回用户列表展示所需等级索引(供 UserServices::index() 调用)
*
* @return array{byId: array<int,array>, byGradeAny: array<int,array>, byGradeOfficial: array<int,array>}
*/
public function loadHjfUserListLevelMaps(): array
{
$rows = $this->dao->getList(['is_del' => 0]);
return $this->buildHjfUserListLevelMaps($rows);
}
/**
* 从等级行列表构建用户列表展示用索引
*
* @param array $hjfLevelRows
* @return array{byId: array<int,array>, byGradeAny: array<int,array>, byGradeOfficial: array<int,array>}
*/
public function buildHjfUserListLevelMaps(array $hjfLevelRows): array
{
$byId = [];
$byGradeAny = [];
$byGradeOfficial = [];
$official = self::HJF_OFFICIAL_LEVEL_NAMES;
foreach ($hjfLevelRows as $hjfRow) {
$lid = (int)($hjfRow['id'] ?? 0);
if ($lid > 0) {
$byId[$lid] = $hjfRow;
}
$g = (int)($hjfRow['grade'] ?? 0);
if ($g > 0 && !isset($byGradeAny[$g])) {
$byGradeAny[$g] = $hjfRow;
}
$nm = (string)($hjfRow['name'] ?? '');
if ($g > 0 && in_array($nm, $official, true) && !isset($byGradeOfficial[$g])) {
$byGradeOfficial[$g] = $hjfRow;
}
}
return ['byId' => $byId, 'byGradeAny' => $byGradeAny, 'byGradeOfficial' => $byGradeOfficial];
}
/**
* 用户列表场景:解析应展示的等级行
* - agent_level 指向 CRMEB 默认行时,按 grade 改用 HJF 官方行
* - 旧 id 已软删或误把 grade 写入 agent_level 时,按 byGradeAny 回退
*
* @param int $agentLevelId 用户的 agent_level 字段值
* @param array $maps loadHjfUserListLevelMaps() 返回的索引
* @return array|null
*/
public function pickHjfLevelRowForUserListDisplay(int $agentLevelId, array $maps): ?array
{
if ($agentLevelId <= 0) {
return null;
}
$byId = $maps['byId'] ?? [];
$byGradeAny = $maps['byGradeAny'] ?? [];
$byGradeOfficial = $maps['byGradeOfficial'] ?? [];
$official = self::HJF_OFFICIAL_LEVEL_NAMES;
$row = $byId[$agentLevelId] ?? null;
if ($row === null) {
return $byGradeAny[$agentLevelId] ?? null;
}
$nm = (string)($row['name'] ?? '');
$g = (int)($row['grade'] ?? 0);
if ($g > 0 && !in_array($nm, $official, true) && isset($byGradeOfficial[$g])) {
return $byGradeOfficial[$g];
}
return $row;
}
/**
* 根据 grade 获取 agent_level ID用于筛选条件转换
*
* @param int $grade 等级数字 (1=创客, 2=云店, 3=服务商, 4=分公司)
* @return int agent_level ID找不到返回 0
*/
public function getLevelIdByGrade(int $grade): int
{
if ($grade <= 0) {
return 0;
}
return (int)$this->dao->value(['grade' => $grade, 'is_del' => 0, 'status' => 1], 'id') ?: 0;
}
/**
* 根据 agent_level ID 获取等级 gradeHJF 会员等级数字 0-4
*/
public function getGradeByLevelId(int $agentLevelId): int
{
if ($agentLevelId <= 0) {
return 0;
}
$levelInfo = $this->getLevelInfo($agentLevelId);
return (int)($levelInfo['grade'] ?? 0);
}
/**
* 根据 agent_level ID 获取直推奖励积分
*/
public function getDirectRewardPoints(int $agentLevelId): int
{
if ($agentLevelId <= 0) {
return 0;
}
$levelInfo = $this->getLevelInfo($agentLevelId);
return (int)($levelInfo['direct_reward_points'] ?? 0);
}
/**
* 根据 agent_level ID 获取伞下奖励积分
*/
public function getUmbrellaRewardPoints(int $agentLevelId): int
{
if ($agentLevelId <= 0) {
return 0;
}
$levelInfo = $this->getLevelInfo($agentLevelId);
return (int)($levelInfo['umbrella_reward_points'] ?? 0);
}
/**
* 获取某一个等级信息
* @param int $id