This commit is contained in:
wushumin
2026-05-11 15:28:27 +08:00
commit edd1a02157
302 changed files with 67193 additions and 0 deletions

View 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");
}
}