gengx
This commit is contained in:
@@ -5,6 +5,7 @@ namespace app\controller\api;
|
||||
use app\model\AiModel;
|
||||
use app\model\Conversation as ConversationModel;
|
||||
use app\model\Department;
|
||||
use app\model\InvitationCode;
|
||||
use app\model\MembershipLevel;
|
||||
use app\model\Message;
|
||||
use app\model\Role;
|
||||
@@ -155,6 +156,7 @@ class Admin extends BaseApi
|
||||
->leftJoin('roles r', 'u.role_id = r.id')
|
||||
->leftJoin('departments d', 'u.department_id = d.id')
|
||||
->field('u.id,u.username,u.email,u.nickname,u.role,u.role_id,u.department_id,u.status,u.membership_level_id,u.created_at,u.last_login_at,ml.name as membership_name,r.name as role_name,r.slug as role_slug,d.name as department_name')
|
||||
->whereRaw('LEFT(u.username, 6) <> ?', ['guest_'])
|
||||
->order('u.id', 'desc');
|
||||
|
||||
AdminScopeService::applyUserScope($query, $this->authUser(), 'u');
|
||||
@@ -183,6 +185,9 @@ class Admin extends BaseApi
|
||||
if (strlen($username) < 3 || strlen($username) > 50) {
|
||||
return $this->error('用户名长度需 3-50 个字符');
|
||||
}
|
||||
if (str_starts_with(strtolower($username), 'guest_')) {
|
||||
return $this->error('guest_ 为系统访客账号保留前缀');
|
||||
}
|
||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
return $this->error('邮箱格式不正确');
|
||||
}
|
||||
@@ -249,6 +254,9 @@ class Admin extends BaseApi
|
||||
if (!$user) {
|
||||
return $this->error('用户不存在', 404);
|
||||
}
|
||||
if (str_starts_with($user->username, 'guest_')) {
|
||||
return $this->error('访客请在访客管理中操作', 422);
|
||||
}
|
||||
|
||||
$roleSlug = Role::where('id', $user->role_id)->value('slug');
|
||||
if ($roleSlug === 'super_admin') {
|
||||
@@ -322,6 +330,9 @@ class Admin extends BaseApi
|
||||
if (!$user) {
|
||||
return $this->error('用户不存在', 404);
|
||||
}
|
||||
if (str_starts_with($user->username, 'guest_')) {
|
||||
return $this->error('访客请在访客管理中操作', 422);
|
||||
}
|
||||
|
||||
User::where('id', $targetId)->update($data);
|
||||
|
||||
@@ -332,6 +343,77 @@ class Admin extends BaseApi
|
||||
return $this->success(null, '更新成功');
|
||||
}
|
||||
|
||||
public function guests()
|
||||
{
|
||||
$auth = $this->authUser();
|
||||
AdminScopeService::requireAny($auth, ['menu:guests']);
|
||||
|
||||
$page = max(1, (int) $this->request->get('page', 1));
|
||||
$limit = min(50, max(1, (int) $this->request->get('limit', 20)));
|
||||
$status = trim((string) $this->request->get('status', ''));
|
||||
$keyword = trim((string) $this->request->get('keyword', ''));
|
||||
|
||||
$query = User::alias('u')
|
||||
->whereRaw('LEFT(u.username, 6) = ?', ['guest_'])
|
||||
->field("u.id,u.username,u.nickname,u.status,u.created_at,u.last_login_at,
|
||||
(SELECT COUNT(*) FROM conversations c WHERE c.user_id = u.id AND c.deleted_at IS NULL) AS conversation_count,
|
||||
(SELECT COUNT(*) FROM messages msg INNER JOIN conversations c2 ON msg.conversation_id = c2.id WHERE c2.user_id = u.id) AS message_count")
|
||||
->order('u.last_login_at', 'desc')
|
||||
->order('u.id', 'desc');
|
||||
|
||||
AdminScopeService::applyUserScope($query, $auth, 'u');
|
||||
if (in_array($status, ['active', 'disabled'], true)) {
|
||||
$query->where('u.status', $status);
|
||||
}
|
||||
if ($keyword !== '') {
|
||||
$query->where('u.username', 'like', '%' . $keyword . '%');
|
||||
}
|
||||
|
||||
$total = (clone $query)->count();
|
||||
$list = $query->page($page, $limit)->select();
|
||||
|
||||
return $this->success(['list' => $list, 'total' => $total]);
|
||||
}
|
||||
|
||||
public function updateGuestStatus($id)
|
||||
{
|
||||
$auth = $this->authUser();
|
||||
AdminScopeService::requireAny($auth, ['btn:guest:status']);
|
||||
|
||||
$guest = User::find((int) $id);
|
||||
if (!$guest || !str_starts_with($guest->username, 'guest_')) {
|
||||
return $this->error('访客不存在', 404);
|
||||
}
|
||||
if (!AdminScopeService::canViewUser($auth, (int) $guest->id)) {
|
||||
return $this->error('无权操作该访客', 403);
|
||||
}
|
||||
|
||||
$status = trim((string) $this->request->put('status', ''));
|
||||
if (!in_array($status, ['active', 'disabled'], true)) {
|
||||
return $this->error('访客状态无效', 422);
|
||||
}
|
||||
|
||||
$guest->save(['status' => $status]);
|
||||
return $this->success(null, $status === 'active' ? '访客已启用' : '访客已禁用');
|
||||
}
|
||||
|
||||
public function deleteGuest($id)
|
||||
{
|
||||
$auth = $this->authUser();
|
||||
AdminScopeService::requireAny($auth, ['btn:guest:delete']);
|
||||
|
||||
$guest = User::find((int) $id);
|
||||
if (!$guest || !str_starts_with($guest->username, 'guest_')) {
|
||||
return $this->error('访客不存在', 404);
|
||||
}
|
||||
if (!AdminScopeService::canViewUser($auth, (int) $guest->id)) {
|
||||
return $this->error('无权操作该访客', 403);
|
||||
}
|
||||
|
||||
User::destroy((int) $guest->id);
|
||||
return $this->success(null, '访客记录已删除');
|
||||
}
|
||||
|
||||
public function conversations()
|
||||
{
|
||||
AdminScopeService::requireAny($this->authUser(), [
|
||||
@@ -557,6 +639,109 @@ class Admin extends BaseApi
|
||||
return $this->success($options);
|
||||
}
|
||||
|
||||
public function invitations()
|
||||
{
|
||||
AdminScopeService::requireAny($this->authUser(), [
|
||||
'menu:invitations',
|
||||
'btn:invitation:create',
|
||||
'btn:invitation:revoke',
|
||||
'can_manage_users',
|
||||
]);
|
||||
|
||||
$status = trim((string) $this->request->get('status', ''));
|
||||
$query = InvitationCode::alias('i')
|
||||
->leftJoin('departments d', 'i.department_id = d.id')
|
||||
->leftJoin('users creator', 'i.created_by = creator.id')
|
||||
->leftJoin('users used', 'i.used_by = used.id')
|
||||
->field('i.*,d.name as department_name,creator.username as creator_name,used.username as used_by_name')
|
||||
->order('i.created_at', 'desc')
|
||||
->order('i.id', 'desc');
|
||||
|
||||
if (in_array($status, ['active', 'used', 'revoked'], true)) {
|
||||
$query->where('i.status', $status);
|
||||
}
|
||||
|
||||
return $this->success($query->limit(500)->select());
|
||||
}
|
||||
|
||||
public function createInvitation()
|
||||
{
|
||||
$user = $this->authUser();
|
||||
AdminScopeService::requireAny($user, [
|
||||
'btn:invitation:create',
|
||||
'menu:invitations',
|
||||
'can_manage_users',
|
||||
]);
|
||||
|
||||
$input = $this->request->post();
|
||||
$departmentId = $input['department_id'] ?? null;
|
||||
if ($departmentId !== null && $departmentId !== '') {
|
||||
$departmentId = (int) $departmentId;
|
||||
if ($departmentId <= 0 || !Department::find($departmentId)) {
|
||||
return $this->error('所选部门不存在', 422);
|
||||
}
|
||||
} else {
|
||||
$departmentId = null;
|
||||
}
|
||||
|
||||
$expiresAt = trim((string) ($input['expires_at'] ?? ''));
|
||||
if ($expiresAt !== '') {
|
||||
$expiresAt = str_replace('T', ' ', $expiresAt);
|
||||
$expiresTimestamp = strtotime($expiresAt);
|
||||
if (!$expiresTimestamp || $expiresTimestamp <= time()) {
|
||||
return $this->error('过期时间必须晚于当前时间', 422);
|
||||
}
|
||||
$expiresAt = date('Y-m-d H:i:s', $expiresTimestamp);
|
||||
} else {
|
||||
$expiresAt = null;
|
||||
}
|
||||
|
||||
do {
|
||||
$code = 'INV-' . strtoupper(bin2hex(random_bytes(5)));
|
||||
} while (InvitationCode::where('code', $code)->find());
|
||||
|
||||
$invitation = InvitationCode::create([
|
||||
'code' => $code,
|
||||
'department_id' => $departmentId,
|
||||
'created_by' => (int) $user['id'],
|
||||
'status' => 'active',
|
||||
'expires_at' => $expiresAt,
|
||||
]);
|
||||
|
||||
return $this->success([
|
||||
'id' => (int) $invitation->id,
|
||||
'code' => $invitation->code,
|
||||
'department_id' => $departmentId,
|
||||
'department_name' => $departmentId ? Department::where('id', $departmentId)->value('name') : null,
|
||||
'status' => 'active',
|
||||
'expires_at' => $expiresAt,
|
||||
'created_at' => $invitation->created_at,
|
||||
], '邀请码已生成');
|
||||
}
|
||||
|
||||
public function revokeInvitation($id)
|
||||
{
|
||||
AdminScopeService::requireAny($this->authUser(), [
|
||||
'btn:invitation:revoke',
|
||||
'menu:invitations',
|
||||
'can_manage_users',
|
||||
]);
|
||||
|
||||
$invitation = InvitationCode::find((int) $id);
|
||||
if (!$invitation) {
|
||||
return $this->error('邀请码不存在', 404);
|
||||
}
|
||||
if ($invitation->status === 'used') {
|
||||
return $this->error('已使用的邀请码不能作废', 422);
|
||||
}
|
||||
if ($invitation->status === 'revoked') {
|
||||
return $this->success(null, '邀请码已作废');
|
||||
}
|
||||
|
||||
$invitation->save(['status' => 'revoked']);
|
||||
return $this->success(null, '邀请码已作废');
|
||||
}
|
||||
|
||||
public function createDepartment()
|
||||
{
|
||||
AdminScopeService::requireAny($this->authUser(), ['btn:dept:create', 'can_manage_departments']);
|
||||
|
||||
Reference in New Issue
Block a user