first
This commit is contained in:
244
server-api/app/controller/admin/UsersController.php
Normal file
244
server-api/app/controller/admin/UsersController.php
Normal file
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
|
||||
namespace app\controller\admin;
|
||||
|
||||
use support\Request;
|
||||
use support\think\Db;
|
||||
|
||||
class UsersController
|
||||
{
|
||||
public function overview(Request $request)
|
||||
{
|
||||
$this->ensurePasswordColumn();
|
||||
return api_success([
|
||||
'cards' => [
|
||||
[
|
||||
'title' => '用户总量',
|
||||
'value' => (int)Db::name('users')->count(),
|
||||
'desc' => '当前数据库中的用户数量',
|
||||
],
|
||||
[
|
||||
'title' => '正常用户',
|
||||
'value' => (int)Db::name('users')->where('status', 'enabled')->count(),
|
||||
'desc' => '当前可正常使用系统的用户数量',
|
||||
],
|
||||
[
|
||||
'title' => '地址数量',
|
||||
'value' => (int)Db::name('user_addresses')->count(),
|
||||
'desc' => '用户维护的寄送与收货地址总数',
|
||||
],
|
||||
[
|
||||
'title' => '消息总量',
|
||||
'value' => (int)Db::name('user_messages')->count(),
|
||||
'desc' => '已发送给用户的站内消息数量',
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->ensurePasswordColumn();
|
||||
$keyword = trim((string)$request->input('keyword', ''));
|
||||
$status = trim((string)$request->input('status', ''));
|
||||
|
||||
$query = Db::name('users')
|
||||
->alias('u')
|
||||
->leftJoin('user_addresses a', 'a.user_id = u.id AND a.is_default = 1')
|
||||
->field([
|
||||
'u.id',
|
||||
'u.nickname',
|
||||
'u.mobile',
|
||||
'u.password',
|
||||
'u.status',
|
||||
'u.created_at',
|
||||
'u.updated_at',
|
||||
'a.province',
|
||||
'a.city',
|
||||
'a.district',
|
||||
'a.detail_address',
|
||||
])
|
||||
->order('u.id', 'desc');
|
||||
|
||||
if ($keyword !== '') {
|
||||
$query->where(function ($builder) use ($keyword) {
|
||||
$builder->whereLike('u.nickname', "%{$keyword}%")
|
||||
->whereOrLike('u.mobile', "%{$keyword}%");
|
||||
});
|
||||
}
|
||||
|
||||
if ($status !== '') {
|
||||
$query->where('u.status', $status);
|
||||
}
|
||||
|
||||
$rows = $query->select()->toArray();
|
||||
|
||||
$list = array_map(function (array $item) {
|
||||
$userId = (int)$item['id'];
|
||||
|
||||
return [
|
||||
'id' => $userId,
|
||||
'nickname' => $item['nickname'] ?: '未命名用户',
|
||||
'mobile' => $item['mobile'] ?: '',
|
||||
'status' => $item['status'],
|
||||
'status_text' => $this->userStatusText($item['status']),
|
||||
'password_set' => ((string)($item['password'] ?? '')) !== '',
|
||||
'default_address' => trim(sprintf(
|
||||
'%s%s%s%s',
|
||||
$item['province'] ?? '',
|
||||
$item['city'] ?? '',
|
||||
$item['district'] ?? '',
|
||||
$item['detail_address'] ?? ''
|
||||
)),
|
||||
'order_count' => (int)Db::name('orders')->where('user_id', $userId)->count(),
|
||||
'message_count' => (int)Db::name('user_messages')->where('user_id', $userId)->count(),
|
||||
'ticket_count' => (int)Db::name('tickets')->where('user_id', $userId)->count(),
|
||||
'created_at' => $item['created_at'],
|
||||
'updated_at' => $item['updated_at'],
|
||||
];
|
||||
}, $rows);
|
||||
|
||||
return api_success(['list' => $list]);
|
||||
}
|
||||
|
||||
public function detail(Request $request)
|
||||
{
|
||||
$this->ensurePasswordColumn();
|
||||
$id = (int)$request->input('id', 0);
|
||||
if ($id <= 0) {
|
||||
return api_error('用户 ID 不能为空', 422);
|
||||
}
|
||||
|
||||
$user = Db::name('users')->where('id', $id)->find();
|
||||
if (!$user) {
|
||||
return api_error('用户不存在', 404);
|
||||
}
|
||||
|
||||
$addresses = Db::name('user_addresses')
|
||||
->where('user_id', $id)
|
||||
->order('is_default', 'desc')
|
||||
->order('id', 'desc')
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$recentOrders = Db::name('orders')
|
||||
->where('user_id', $id)
|
||||
->order('id', 'desc')
|
||||
->limit(5)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$recentMessages = Db::name('user_messages')
|
||||
->where('user_id', $id)
|
||||
->order('id', 'desc')
|
||||
->limit(5)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
return api_success([
|
||||
'user_info' => [
|
||||
'id' => (int)$user['id'],
|
||||
'nickname' => $user['nickname'] ?: '未命名用户',
|
||||
'mobile' => $user['mobile'] ?: '',
|
||||
'status' => $user['status'],
|
||||
'status_text' => $this->userStatusText($user['status']),
|
||||
'password_set' => ((string)($user['password'] ?? '')) !== '',
|
||||
'created_at' => $user['created_at'],
|
||||
'updated_at' => $user['updated_at'],
|
||||
],
|
||||
'addresses' => array_map(fn (array $item) => [
|
||||
'consignee' => $item['consignee'],
|
||||
'mobile' => $item['mobile'],
|
||||
'full_address' => trim(sprintf('%s%s%s%s', $item['province'], $item['city'], $item['district'], $item['detail_address'])),
|
||||
'is_default' => (bool)$item['is_default'],
|
||||
], $addresses),
|
||||
'recent_orders' => array_map(fn (array $item) => [
|
||||
'order_no' => $item['order_no'],
|
||||
'display_status' => $item['display_status'],
|
||||
'pay_amount' => (float)$item['pay_amount'],
|
||||
'created_at' => $item['created_at'],
|
||||
], $recentOrders),
|
||||
'recent_messages' => array_map(fn (array $item) => [
|
||||
'title' => $item['title'],
|
||||
'content' => $item['content'],
|
||||
'is_read' => (bool)$item['is_read'],
|
||||
'created_at' => $item['created_at'],
|
||||
], $recentMessages),
|
||||
]);
|
||||
}
|
||||
|
||||
public function save(Request $request)
|
||||
{
|
||||
$this->ensurePasswordColumn();
|
||||
$id = (int)$request->input('id', 0);
|
||||
$nickname = trim((string)$request->input('nickname', ''));
|
||||
$mobile = trim((string)$request->input('mobile', ''));
|
||||
$status = trim((string)$request->input('status', 'enabled'));
|
||||
$password = trim((string)$request->input('password', ''));
|
||||
|
||||
if ($nickname === '' || $mobile === '') {
|
||||
return api_error('昵称和手机号不能为空', 422);
|
||||
}
|
||||
|
||||
$now = date('Y-m-d H:i:s');
|
||||
$payload = [
|
||||
'nickname' => $nickname,
|
||||
'mobile' => $mobile,
|
||||
'status' => $status !== '' ? $status : 'enabled',
|
||||
'updated_at' => $now,
|
||||
];
|
||||
if ($password !== '') {
|
||||
$payload['password'] = password_hash($password, PASSWORD_BCRYPT);
|
||||
}
|
||||
|
||||
if ($id > 0) {
|
||||
$user = Db::name('users')->where('id', $id)->find();
|
||||
if (!$user) {
|
||||
return api_error('用户不存在', 404);
|
||||
}
|
||||
|
||||
$exists = Db::name('users')
|
||||
->where('mobile', $mobile)
|
||||
->where('id', '<>', $id)
|
||||
->find();
|
||||
if ($exists) {
|
||||
return api_error('手机号已存在', 422);
|
||||
}
|
||||
|
||||
Db::name('users')->where('id', $id)->update($payload);
|
||||
return api_success(['id' => $id], '用户已更新');
|
||||
}
|
||||
|
||||
$exists = Db::name('users')->where('mobile', $mobile)->find();
|
||||
if ($exists) {
|
||||
return api_error('手机号已存在', 422);
|
||||
}
|
||||
|
||||
$payload['avatar'] = '';
|
||||
$payload['password'] = $payload['password'] ?? '';
|
||||
$payload['last_login_at'] = null;
|
||||
$payload['created_at'] = $now;
|
||||
$newId = (int)Db::name('users')->insertGetId($payload);
|
||||
|
||||
return api_success(['id' => $newId], '用户已创建');
|
||||
}
|
||||
|
||||
private function userStatusText(string $status): string
|
||||
{
|
||||
return match ($status) {
|
||||
'enabled' => '正常',
|
||||
'disabled' => '已停用',
|
||||
default => $status,
|
||||
};
|
||||
}
|
||||
|
||||
private function ensurePasswordColumn(): void
|
||||
{
|
||||
$column = Db::query("SHOW COLUMNS FROM users LIKE 'password'");
|
||||
if ($column) {
|
||||
return;
|
||||
}
|
||||
|
||||
Db::execute("ALTER TABLE users ADD COLUMN password VARCHAR(255) NOT NULL DEFAULT '' AFTER mobile");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user