• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In
Build has been canceled!

miaoxing / plugin / 3766633246

pending completion
3766633246

push

github

twinh
feat(plugin): `BasePage` 增加 `pageInit` 事件

0 of 1 new or added line in 1 file covered. (0.0%)

84 existing lines in 24 files now uncovered.

902 of 2275 relevant lines covered (39.65%)

19.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

63.38
/src/Service/User.php
1
<?php
2

3
namespace Miaoxing\Plugin\Service;
4

5
use Miaoxing\Plugin\Auth\BaseAuth;
6
use Miaoxing\Plugin\Auth\JwtAuth;
7
use Miaoxing\Plugin\ConfigTrait;
8

9
/**
10
 * 用户
11
 *
12
 * @property bool $enableRegister
13
 * @property string $disableRegisterTips
14
 * @property bool $enableLoginCaptcha
15
 * @property int $defaultGroupId
16
 * @property bool $enablePasswordRest
17
 * @property bool $enableMobileVerify
18
 * @property bool $enableLogin
19
 * @property string $disableLoginTips
20
 * @property string $bgImage
21
 * @property int $defaultTagId
22
 * @property int $agreementArticleId
23
 * @property bool $enableExport
24
 * @property bool $enableCreate
25
 * @property string $defaultAvatar
26
 * @property bool $enablePinCode
27
 * @mixin \EventMixin
28
 * @mixin \ReqMixin
29
 * @mixin \PasswordMixin
30
 */
31
class User extends UserModel
32
{
33
    use ConfigTrait {
34
        __get as getConfig;
35
    }
36

37
    /**
38
     * 当前用户是唯一的
39
     *
40
     * @var bool
41
     */
42
    protected static $createNewInstance = false;
43

44
    protected $configs = [
45
        'enablePinCode' => [
46
            'default' => false,
47
        ],
48
        'checkMobileUnique' => [
49
            'default' => false,
50
        ],
51
        'defaultAvatar' => [
52
            'default' => '',
53
        ],
54
        'enableLogin' => [
55
            'default' => true,
56
        ],
57
        'enableRegister' => [
58
            'default' => true,
59
        ],
60
        'disableRegisterTips' => [
61
            'default' => '注册功能未启用',
62
        ],
63
        'enableLoginCaptcha' => [
64
            'default' => false,
65
        ],
66
        'defaultGroupId' => [
67
            'default' => 0,
68
        ],
69
        'enablePasswordRest' => [
70
            'default' => false,
71
        ],
72
        'enableMobileVerify' => [
73
            'default' => false,
74
        ],
75
        'disableLoginTips' => [
76
            'default' => '登录功能未启用',
77
        ],
78
        'bgImage' => [
79
            'default' => '',
80
        ],
81
        'defaultTagId' => [],
82
        'agreementArticleId' => [],
83
        'enableExport' => [
84
            'default' => false,
85
        ],
86
        'enableCreate' => [
87
            'default' => false,
88
        ],
89
    ];
90

91
    /**
92
     * @var string
93
     */
94
    protected $authClass = JwtAuth::class;
95

96
    /**
97
     * @var BaseAuth|null
98
     */
99
    protected $auth;
100

101
    /**
102
     * NOTE: 暂时只有__set有效
103
     *
104
     * @param string $name
105
     * @param mixed $value
106
     * @return mixed
107
     */
108
    public function __set($name, $value = null)
109
    {
110
        // NOTE: 设置前需主动加载,否则状态变为loaded,不会再去加载
111
        $this->loadDbUser();
12✔
112

113
        return parent::__set($name, $value);
12✔
114
    }
115

116
    protected function toArray($returnFields = [], callable $prepend = null): array
117
    {
118
        $this->loadDbUser();
3✔
119

120
        return parent::toArray($returnFields, $prepend);
3✔
121
    }
122

123
    /**
124
     * {@inheritdoc}
125
     */
126
    protected function save(iterable $attributes = []): UserModel
127
    {
128
        // 确保是更新操作,同时有ID作为更新条件
129
        $this->new = false;
6✔
130
        $this['id'] = $this->getAuth()->getData()['id'];
6✔
131

132
        return parent::save($attributes);
6✔
133
    }
134

135
    /**
136
     * Record: 获取用户资料,优先从认证服务中获取
137
     *
138
     * {@inheritdoc}
139
     */
140
    public function &get($name, &$exists = null, $throwException = true)
141
    {
142
        // 未加载数据,已登录,认证服务中存在需要的key
143
        $data = $this->getAuth()->getData();
267✔
144
        if ($this->isNew() && isset($data[$name])) {
267✔
145
            $exists = true;
9✔
146
            return $data[$name];
9✔
147
        } else {
148
            $this->loadDbUser();
267✔
149

150
            return parent::get($name, $exists, $throwException);
267✔
151
        }
152
    }
153

154
    public function &__get($name)
155
    {
156
        $result = $this->getConfig($name);
267✔
157
        return $result;
267✔
158
    }
159

160
    /**
161
     * 从数据库中查找用户加载到当前记录中
162
     */
163
    protected function loadDbUser()
164
    {
165
        if (!$this->isNew() || !$this->isLogin()) {
267✔
166
            return;
267✔
167
        }
168

169
        $id = $this->get('id');
9✔
170
        $user = UserModel::new()
9✔
171
            ->setCacheKey($this->getModelCacheKey($id))
9✔
172
            ->findOrInit($id);
9✔
173

174
        $this->loadRecordData($user);
9✔
175
    }
3✔
176

177
    /**
178
     * 加载外部记录的数据
179
     *
180
     * @param UserModel $user
181
     */
182
    protected function loadRecordData(UserModel $user)
183
    {
184
        $this->setAttributesFromDb($user->convertToDbAttributes());
87✔
185
        $this->new = false;
87✔
186
    }
29✔
187

188
    /**
189
     * @return string|null
190
     * @svc
191
     */
192
    protected function id()
193
    {
194
        return $this->id;
18✔
195
    }
196

197
    /**
198
     * @return $this
199
     * @svc
200
     */
201
    protected function cur()
202
    {
203
        return $this;
18✔
204
    }
205

206
    /**
207
     * 判断用户是否登录
208
     *
209
     * @return bool
210
     * @svc
211
     */
212
    protected function isLogin()
213
    {
214
        return $this->getAuth()->isLogin();
15✔
215
    }
216

217
    /**
218
     * 检查用户是否登录
219
     *
220
     * @return Ret
221
     * @svc
222
     */
223
    protected function checkLogin()
224
    {
225
        return $this->getAuth()->checkLogin();
×
226
    }
227

228
    /**
229
     * 根据用户账号密码,登录用户
230
     *
231
     * @param mixed $data
232
     * @return Ret
233
     * @svc
234
     */
235
    protected function login($data)
236
    {
237
        // 1. 校验用户账号密码是否符合规则
238
        $validator = wei()->validate([
×
UNCOV
239
            'data' => $data,
×
240
            'rules' => [
241
                'username' => [
242
                    'required' => true,
243
                ],
244
                'password' => [
245
                    'required' => true,
246
                ],
247
            ],
248
            'names' => [
249
                'username' => '帐号',
250
                'password' => '密码',
251
            ],
252
        ]);
253

254
        if (!$validator->isValid()) {
×
255
            return err($validator->getFirstMessage());
×
256
        }
257

258
        // 2. 检查手机/邮箱/用户名是否存在
259
        $user = UserModel::new();
×
260
        switch (true) {
261
            case wei()->isMobileCn($data['username']):
×
262
                $column = 'mobile';
×
263
                $user->whereNotNULL('mobile_verified_at');
×
264
                break;
×
265

266
            case wei()->isEmail($data['username']):
×
267
                $column = 'email';
×
268
                break;
×
269

270
            default:
271
                $column = 'username';
×
272
        }
273

274
        $user = $user->findBy($column, $data['username']);
×
275

276
        if (!$user) {
×
277
            return err('用户名不存在或密码错误');
×
278
        }
279

280
        // 3. 检查用户是否有效
281
        if (!$user->isEnabled) {
×
282
            return err('用户未启用,无法登录');
×
283
        }
284

285
        // 4. 验证密码是否正确
286
        if (!$user->verifyPassword($data['password'])) {
×
287
            return err('用户不存在或密码错误');
×
288
        }
289

290
        // 5. 验证通过,登录用户
291
        return $this->loginByModel($user);
×
292
    }
293

294
    /**
295
     * 根据用户ID直接登录用户
296
     *
297
     * @param string|int $id
298
     * @return Ret
299
     * @svc
300
     */
301
    protected function loginById($id)
302
    {
303
        $user = wei()->userModel()->find($id);
63✔
304
        if (!$user) {
63✔
305
            return err('用户不存在');
×
306
        } else {
307
            return $this->loginByModel($user);
63✔
308
        }
309
    }
310

311
    /**
312
     * 根据条件查找或创建用户,并登录
313
     *
314
     * @param mixed $conditions
315
     * @param array $data
316
     * @return $this
317
     * @svc
318
     */
319
    protected function loginBy($conditions, $data = [])
320
    {
321
        $user = wei()->userModel()->findOrCreate($conditions, $data);
×
322
        $this->loginByModel($user);
×
323

324
        return $this;
×
325
    }
326

327
    /**
328
     * 根据用户对象登录用户
329
     *
330
     * @param UserModel $user
331
     * @return Ret
332
     * @svc
333
     */
334
    protected function loginByModel(UserModel $user)
335
    {
336
        $this->loadRecordData($user);
78✔
337

338
        $ret = $this->getAuth()->login($user);
78✔
339
        if ($ret->isSuc()) {
78✔
340
            $this->event->trigger('userLogin', [$user]);
78✔
341
        }
342

343
        return $ret;
78✔
344
    }
345

346
    /**
347
     * 销毁用户会话,退出登录
348
     *
349
     * @return Ret
350
     * @svc
351
     */
352
    protected function logout()
353
    {
354
        $this->event->trigger('beforeUserLogout', [$this]);
12✔
355

356
        $this->setAttributesFromDb([]);
12✔
357

358
        $this->getAuth()->logout();
12✔
359

360
        return suc();
12✔
361
    }
362

363
    /**
364
     * 当用户信息更改后,可以主动调用该方法,刷新会话中的数据
365
     *
366
     * @param UserModel $user
367
     * @return $this
368
     * @svc
369
     */
370
    protected function refresh(UserModel $user)
371
    {
372
        if ($user->id === ($this->getAuth()->getData()['id'] ?? null)) {
24✔
373
            $this->loginByModel($user);
9✔
374
        }
375

376
        return $this;
24✔
377
    }
378

379
    protected function getAuth()
380
    {
381
        if (!$this->auth) {
315✔
382
            $this->auth = new $this->authClass();
12✔
383
        }
384
        return $this->auth;
315✔
385
    }
386
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc