Skip to content

Commit fdd20fe

Browse files
committed
feat: release 6.9.0
1 parent c434475 commit fdd20fe

File tree

175 files changed

+1931
-974
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

175 files changed

+1931
-974
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,20 @@ AdminMenu::register(function () {
285285
- [https://modstart.com/forum](https://modstart.com/forum)
286286

287287

288+
## ⭐️ 贡献代码
289+
290+
系统接受 Github 和 Gitee 的 Pull Request,欢迎提交代码。
291+
292+
文件 `/vendor/modstart/modstart` 底层代码修改,可以提交 PR 到以下仓库,该仓库会在每次发版自动合入所有系统。
293+
294+
- `Github` [https://github.com/modstart-lib/modstart](https://github.com/modstart-lib/modstart)
295+
- `Gitee` [https://gitee.com/modstart-lib/modstart](https://gitee.com/modstart-lib/modstart)
296+
297+
如果是非底层代码修改,可具体提交 PR 到以下仓库
298+
299+
- `Github` [https://github.com/modstart/ModStartCMS](https://github.com/modstart/ModStartCMS)
300+
- `Gitee` [https://gitee.com/modstart/ModStartCMS](https://gitee.com/modstart/ModStartCMS)
301+
288302
## ✉️ 使用交流
289303

290304
### QQ交流群

module/AdminManager/Asset/entry/upgrade.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

module/AdminManager/resources/asset/src/pages/Upgrade.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@
179179
class="tw-bg-white tw-rounded-sm tw-mb-2 tw-box tw-px-5 tw-py-3 tw-mb-3 tw-flex tw-items-center tw-zoom-in">
180180
<div class="tw-w-10 tw-h-10 tw-flex-none tw-image-fit tw-rounded-full tw-overflow-hidden">
181181
<div class="circle tw-border tw-border-gray-200 tw-border-solid tw-shadow ub-cover-1-1"
182-
:style="{backgroundImage:`url(${memberUser.avatar||'/asset/image/avatar.png'})`}"></div>
182+
:style="{backgroundImage:`url(${memberUser.avatar||'/asset/image/avatar.svg'})`}"></div>
183183
</div>
184184
<div class="tw-ml-4 tw-mr-auto">
185185
<div class="tw-font-medium">{{memberUser.username || ''}}</div>

module/Member/Admin/Controller/ConfigController.php

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,41 @@ public function setting(AdminConfigBuilder $builder)
1414
{
1515
$captchaType = array_merge(['' => '默认'], CaptchaProvider::nameTitleMap());
1616
$builder->pageTitle('功能设置');
17-
$builder->layoutPanel('登录注册', function ($builder) use ($captchaType) {
17+
$builder->layoutPanel('登录', function ($builder) use ($captchaType) {
1818
/** @var HasFields $builder */
1919
$builder->switch('loginCaptchaEnable', '启用登录验证码')
2020
->when('=', true, function (Form $form) use ($captchaType) {
21-
$form->select('loginCaptchaProvider', '登录验证码类型')->options($captchaType);
21+
$form->select('loginCaptchaProvider', '登录验证码类型')->options($captchaType)
22+
->help('用于 用户名密码登录(/login)、手机快捷登录(/login_phone) 的人机验证');
2223
});
2324
$builder->switch('Member_LoginPhoneEnable', '启用手机快捷登录')
2425
->when('=', true, function (Form $form) {
25-
$form->text('Member_LoginPhoneNameSuggest', '快捷注册用户名前缀')
26+
$form->text('Member_LoginPhoneNameSuggest', '手机快捷登录用户名')
2627
->defaultValue('用户')
2728
->help(join('', [
28-
'<p>默认为"用户",用户注册后自动设置用户名和昵称为 "用户xxxx"。可以使用占位符,如"用户{Phone}"表示注册后自动设置为"用户+手机号"。</p>',
29-
'<p>{Phone}用户手机 {Phone4}手机后4位 {Uid}用户ID,如冲突将会自动追加随机字符串</p>'
29+
'<p>默认为"用户",用户注册后自动设置用户名和昵称为 "用户xxxx"。</p>',
30+
'<p>可使用占位符,如"用户{Phone}"表示注册后自动设置为"用户+手机号",用户名如遇冲突将会自动追加随机字符串。</p>',
31+
'<p>其他占位符:{Phone}用户手机、{Phone4}手机后4位、{Uid}用户ID</p>',
3032
]));
31-
$form->switch('Member_LoginPhoneAutoRegister', '登录时自动注册')
32-
->help('开启后,用户使用手机号登录时,如果用户不存在则自动注册');
33-
});
33+
$form->switch('Member_LoginPhoneAutoRegister', '手机快捷登录自动注册')
34+
->help('开启后,手机快捷登录遇用户不存在则自动注册,关闭表示手机号不存在不能登录');
35+
})
36+
->help('开启手机快捷登录(/login_phone)');
3437
$builder->select('Member_LoginDefault', '默认登录方式')->options([
35-
'default' => '用户名密码登录',
36-
'phone' => '手机快捷登录',
38+
'default' => '用户名密码登录 /login',
39+
'phone' => '手机快捷登录 /login_phone',
3740
]);
41+
42+
});
43+
$builder->layoutPanel('注册', function ($builder) use ($captchaType) {
44+
/** @var HasFields $builder */
45+
$builder->select('Member_RegisterCaptchaProvider', '注册验证码类型')->options($captchaType)
46+
->help('用于 普通注册(/register)、手机快捷注册(/register_phone) 的人机验证');
3847
$builder->switch('registerDisable', '禁用注册')
3948
->when('!=', true, function ($builder) {
40-
$builder->switch('registerEmailEnable', '启用邮箱注册');
41-
$builder->switch('registerPhoneEnable', '启用手机注册');
42-
$builder->switch('Member_RegisterPhoneEnable', '启用手机快捷注册');
49+
$builder->switch('registerEmailEnable', '注册时填写邮箱');
50+
$builder->switch('registerPhoneEnable', '注册时填写手机');
51+
$builder->switch('Member_RegisterPhoneEnable', '启用手机快捷注册')->help('开启后用户可通过手机验证码快捷注册(/register_phone)');
4352
$builder->select('Member_RegisterDefault', '默认注册方式')->options([
4453
'default' => '用户名密码注册',
4554
'phone' => '手机快捷注册',
@@ -49,32 +58,32 @@ public function setting(AdminConfigBuilder $builder)
4958
$builder->switch('registerOauthEnable', '允许以授权方式注册');
5059
});
5160
if (modstart_module_enabled('MemberOauth')) {
52-
$builder->switch('Member_OauthBindPhoneEnable', '授权登录绑定手机');
53-
$builder->switch('Member_OauthBindEmailEnable', '授权登录绑定邮箱');
61+
$builder->switch('Member_OauthBindPhoneEnable', '授权登录需绑定手机');
62+
$builder->switch('Member_OauthBindEmailEnable', '授权登录需绑定邮箱');
5463
}
5564
$builder->number('Member_UsernameMinLength', '用户名最小长度')->defaultValue(3);
56-
$builder->button('', '保存')->forSubmit();
65+
5766
});
58-
$builder->layoutPanel('账号安全', function ($builder) {
59-
$builder->switch('Member_ProfileEmailEnable', '开启邮箱绑定');
60-
$builder->switch('Member_ProfilePhoneEnable', '开启手机绑定');
67+
$builder->layoutPanel('找回密码', function ($builder) {
6168
$builder->switch('retrieveDisable', '禁用找回密码')
6269
->when('!=', true, function ($builder) {
6370
$builder->switch('retrievePhoneEnable', '启用手机找回密码');
6471
$builder->switch('retrieveEmailEnable', '启用邮箱找回密码');
6572
});
66-
$builder->button('', '保存')->forSubmit();
6773
});
68-
$builder->layoutPanel('安全设置', function ($builder) {
74+
$builder->layoutPanel('账号安全', function ($builder) {
75+
$builder->switch('Member_ProfileEmailEnable', '开启邮箱绑定')->help('启用后用户中心增加邮箱绑定页面');
76+
$builder->switch('Member_ProfilePhoneEnable', '开启手机绑定')->help('启用后用户中心增加手机绑定页面');
6977
$builder->switch('Member_LoginRedirectCheckEnable', '登录后跳转安全验证')
7078
->when('=', true, function (Form $form) {
7179
$form->textarea('Member_LoginRedirectWhiteList', '白名单')->placeholder('请输入域名白名单,每行一个,如:www.example.com');
7280
});
7381
$builder->switch('Member_DeleteEnable', '启用自助注销账号')
74-
->help('用户注销账号后,用户名会重置为随机字符串,已绑定的手机、邮箱均会解绑');
75-
$builder->button('', '保存')->forSubmit();
82+
->help('开启后,用户中心可自主申请注销账号。用户注销账号后,用户名会重置为随机字符串,已绑定的手机、邮箱均会解绑');
83+
7684
});
7785
$builder->formClass('wide');
86+
$builder->contentFixedBottomContentSave();
7887
$builder->disableBoxWrap(true);
7988
$builder->showReset(false)->showSubmit(false);
8089
return $builder->perform();

module/Member/Admin/Controller/MemberController.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ protected function crud(AdminCRUDBuilder $builder)
5858
$builder->id('id', 'ID');
5959
MemberAdminList::callGridField($builder);
6060
$builder->display('avatar', '头像')->hookRendering(function (AbstractField $field, $item, $index) {
61-
$avatarSmall = AssetsUtil::fixOrDefault($item->avatar, 'asset/image/avatar.png');
62-
$avatarBig = AssetsUtil::fixOrDefault($item->avatarBig, 'asset/image/avatar.png');
61+
$avatarSmall = AssetsUtil::fixOrDefault($item->avatar, 'asset/image/avatar.svg');
62+
$avatarBig = AssetsUtil::fixOrDefault($item->avatarBig, 'asset/image/avatar.svg');
6363
return AutoRenderedFieldValue::make("<a href='$avatarBig' class='tw-inline-block' data-image-preview>
6464
<img src='$avatarSmall' class='tw-rounded-full tw-w-8 tw-h-8 tw-shadow'></a>");
6565
});
@@ -221,6 +221,7 @@ public function edit(AdminDialogPage $page)
221221
}
222222
$form = Form::make('');
223223
$form->layoutPanel('基础', function (Form $form) {
224+
$form->display('id', '用户ID')->addable(true);
224225
$form->text('username', '用户名');
225226
$form->text('phone', '手机');
226227
$form->text('email', '邮箱');
@@ -233,7 +234,7 @@ public function edit(AdminDialogPage $page)
233234
}
234235
if (ModuleManager::getModuleConfigBoolean('Member', 'vipEnable', false)) {
235236
$form->radio('vipId', 'VIP')->options(MemberVipUtil::mapTitle())->required();
236-
$form->date('vipExpire', 'VIP过期');
237+
$form->date('vipExpire', 'VIP过期')->help('VIP过期留空表示永久');
237238
}
238239
});
239240
$form->item($memberUser)->fillFields();
@@ -285,7 +286,7 @@ public function search()
285286
return [
286287
'value' => intval($item['id']),
287288
'name' => htmlspecialchars(MemberUtil::viewName($item)),
288-
'avatar' => AssetsUtil::fixOrDefault($item['avatar'], 'asset/image/avatar.png'),
289+
'avatar' => AssetsUtil::fixOrDefault($item['avatar'], 'asset/image/avatar.svg'),
289290
];
290291
}, $paginateData['records']);
291292
return Response::jsonSuccessData($records);

module/Member/Admin/Controller/MemberVipSetController.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@ protected function crud(AdminCRUDBuilder $builder)
3535
$builder->image('icon', '图标');
3636
$builder->currency('price', '价格')->required();
3737
$builder->number('vipDays', '时间')->required()->help('单位为天,365表示1年');
38-
foreach (MemberVipBiz::all() as $biz) {
39-
$biz->vipField($builder);
40-
}
4138
$builder->text('desc', '简要说明')->required();
4239
$builder->richHtml('content', '详细说明')->required();
4340
if (ModuleManager::getModuleConfigBoolean('Member', 'creditEnable', false)) {
@@ -46,6 +43,11 @@ protected function crud(AdminCRUDBuilder $builder)
4643
$form->number('creditPresentValue', '赠送积分数量');
4744
})->optionsYesNo()->listable(false);
4845
}
46+
foreach (MemberVipBiz::all() as $biz) {
47+
$builder->layoutPanel($biz->title(), function ($builder) use ($biz) {
48+
$biz->vipField($builder);
49+
});
50+
}
4951
$builder->display('created_at', L('Created At'))->listable(false);
5052
$builder->display('updated_at', L('Updated At'))->listable(false);
5153
})

module/Member/Api/Controller/AuthController.php

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
use Module\Member\Provider\RegisterProcessor\AbstractMemberRegisterProcessorProvider;
2323
use Module\Member\Provider\RegisterProcessor\MemberRegisterProcessorProvider;
2424
use Module\Member\Util\MemberUtil;
25+
use Module\Member\Util\SecurityUtil;
2526
use Module\Vendor\Email\MailSendJob;
26-
use Module\Vendor\Provider\Captcha\CaptchaProvider;
2727
use Module\Vendor\Session\SessionUtil;
2828
use Module\Vendor\Sms\SmsUtil;
2929
use Module\Vendor\Support\ResponseCodes;
@@ -231,11 +231,11 @@ public function oauthBind($oauthType = null)
231231
if (!Session::get('oauthBindCaptchaPass', false)) {
232232
if (!CaptchaFacade::check($captcha)) {
233233
SessionUtil::atomicProduce('oauthBindCaptchaPassCount', 1);
234-
return Response::generate(-1, '图片验证失败');
234+
return Response::generate(-1, '请重新进行安全验证');
235235
}
236236
}
237237
if (!SessionUtil::atomicConsume('oauthBindCaptchaPassCount')) {
238-
return Response::generate(-1, '请重新输入图片验证码');
238+
return Response::generate(-1, '请进行安全验证');
239239
}
240240
if (modstart_config('Member_OauthBindPhoneEnable')) {
241241
if (empty($phone)) {
@@ -612,11 +612,11 @@ public function login()
612612
}
613613

614614
if (modstart_config('loginCaptchaEnable', false)) {
615-
$captchaProvider = modstart_config('loginCaptchaProvider', null);
615+
$captchaProvider = SecurityUtil::loginCaptchaProvider();
616616
if ($captchaProvider) {
617-
$ret = CaptchaProvider::get($captchaProvider)->validate();
617+
$ret = $captchaProvider->validate();
618618
if (Response::isError($ret)) {
619-
return $ret;
619+
return Response::generate(-1, $ret['msg']);
620620
}
621621
} else {
622622
if (!CaptchaFacade::check($input->getTrimString('captcha'))) {
@@ -750,9 +750,17 @@ public function loginPhoneVerify()
750750
return Response::generate(-1, '手机为空或格式不正确');
751751
}
752752

753-
$captcha = $input->getTrimString('captcha');
754-
if (!CaptchaFacade::check($captcha)) {
755-
return Response::generate(-1, '图片验证码错误');
753+
$provider = SecurityUtil::loginCaptchaProvider();
754+
if ($provider) {
755+
$ret = $provider->validate();
756+
if (Response::isError($ret)) {
757+
return $ret;
758+
}
759+
} else {
760+
$captcha = $input->getTrimString('captcha');
761+
if (!CaptchaFacade::check($captcha)) {
762+
return Response::generate(-1, '图片验证码错误');
763+
}
756764
}
757765

758766
$memberUser = MemberUtil::getByPhone($phone);
@@ -926,11 +934,11 @@ public function register()
926934
if (!Session::get('registerCaptchaPass', false)) {
927935
if (!CaptchaFacade::check($captcha)) {
928936
SessionUtil::atomicProduce('registerCaptchaPassCount', 1);
929-
return Response::generate(-1, '图片验证失败');
937+
return Response::generate(-1, '请重新进行安全验证');
930938
}
931939
}
932940
if (!SessionUtil::atomicConsume('registerCaptchaPassCount')) {
933-
return Response::generate(-1, '请重新输入图片验证码');
941+
return Response::generate(-1, '请进行安全验证');
934942
}
935943

936944
if (modstart_config('registerPhoneEnable')) {
@@ -1024,10 +1032,10 @@ public function registerEmailVerify()
10241032
}
10251033

10261034
if (!Session::get('registerCaptchaPass', false)) {
1027-
return Response::generate(-1, '请先验证图片验证码');
1035+
return Response::generate(-1, '请先进行安全验证');
10281036
}
10291037
if (!SessionUtil::atomicConsume('registerCaptchaPassCount')) {
1030-
return Response::generate(-1, '请重新输入图片验证码');
1038+
return Response::generate(-1, '请进行安全验证');
10311039
}
10321040

10331041
$memberUser = MemberUtil::getByEmail($email);
@@ -1074,10 +1082,10 @@ public function registerPhoneVerify()
10741082
}
10751083

10761084
if (!Session::get('registerCaptchaPass', false)) {
1077-
return Response::generate(-1, '请先验证图片验证码');
1085+
return Response::generate(-1, '请先进行安全验证');
10781086
}
10791087
if (!SessionUtil::atomicConsume('registerCaptchaPassCount')) {
1080-
return Response::generate(-1, '请重新输入图片验证码');
1088+
return Response::generate(-1, '请进行安全验证');
10811089
}
10821090

10831091
$memberUser = MemberUtil::getByPhone($phone);
@@ -1113,11 +1121,19 @@ public function registerPhoneVerify()
11131121
*/
11141122
public function registerCaptchaVerify()
11151123
{
1116-
$input = InputPackage::buildFromInput();
1117-
$captcha = $input->getTrimString('captcha');
1118-
if (!CaptchaFacade::check($captcha)) {
1119-
SessionUtil::atomicRemove('registerCaptchaPassCount');
1120-
return Response::generate(ResponseCodes::CAPTCHA_ERROR, '验证码错误');
1124+
$provider = SecurityUtil::registerCaptchaProvider();
1125+
if ($provider) {
1126+
$ret = $provider->validate();
1127+
if (Response::isError($ret)) {
1128+
return $ret;
1129+
}
1130+
} else {
1131+
$input = InputPackage::buildFromInput();
1132+
$captcha = $input->getTrimString('captcha');
1133+
if (!CaptchaFacade::check($captcha)) {
1134+
SessionUtil::atomicRemove('registerCaptchaPassCount');
1135+
return Response::generate(ResponseCodes::CAPTCHA_ERROR, '验证码错误');
1136+
}
11211137
}
11221138
Session::put('registerCaptchaPass', true);
11231139
$registerCaptchaPassCount = 1;
@@ -1183,10 +1199,10 @@ public function oauthBindEmailVerify()
11831199
}
11841200

11851201
if (!Session::get('oauthBindCaptchaPass', false)) {
1186-
return Response::generate(-1, '请先验证图片验证码');
1202+
return Response::generate(-1, '请先进行安全验证');
11871203
}
11881204
if (!SessionUtil::atomicConsume('oauthBindCaptchaPassCount')) {
1189-
return Response::generate(-1, '请重新输入图片验证码');
1205+
return Response::generate(-1, '请进行安全验证');
11901206
}
11911207

11921208
$memberUser = MemberUtil::getByEmail($email);
@@ -1230,10 +1246,10 @@ public function oauthBindPhoneVerify()
12301246
}
12311247

12321248
if (!Session::get('oauthBindCaptchaPass', false)) {
1233-
return Response::generate(-1, '请先验证图片验证码');
1249+
return Response::generate(-1, '请先进行安全验证');
12341250
}
12351251
if (!SessionUtil::atomicConsume('oauthBindCaptchaPassCount')) {
1236-
return Response::generate(-1, '请重新输入图片验证码');
1252+
return Response::generate(-1, '请进行安全验证');
12371253
}
12381254

12391255
$memberUser = MemberUtil::getByPhone($phone);
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
4+
namespace Module\Member\Api\Controller;
5+
6+
7+
use Illuminate\Routing\Controller;
8+
use ModStart\Core\Input\Response;
9+
use Module\Member\Auth\MemberUser;
10+
use Module\Member\Support\MemberLoginCheck;
11+
use Module\MemberCert\Util\MemberCertUtil;
12+
13+
class MemberController extends Controller implements MemberLoginCheck
14+
{
15+
public function current()
16+
{
17+
$data = [];
18+
$data['_certType'] = null;
19+
if (modstart_module_enabled('MemberCert')) {
20+
$data['_certType'] = MemberCertUtil::getCertType(MemberUser::id());
21+
}
22+
return Response::generateSuccessData($data);
23+
}
24+
}

0 commit comments

Comments
 (0)