social 后台编辑
wip wip wip 修改插件图标 add social controller. add social controller. add shop base url wip wip save social setting 优化购物车加载 后台第三方登录插件 完善第三方登录按钮 fixed social setting wip wip wip wip 完善第三方登录 fixed social redirect 优化后台 修复google 登录 fixed window opener Add 第三方登录类型 wip wip 完善多语言 修复第三方登录前台多语言
|
|
@ -133,5 +133,6 @@ class AdminServiceProvider extends ServiceProvider
|
|||
{
|
||||
View::share('languages', languages());
|
||||
View::share('admin_base_url', admin_route('home.index'));
|
||||
View::share('shop_base_url', shop_route('home.index'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,6 +162,14 @@ class Plugin implements Arrayable, \ArrayAccess
|
|||
return $this->enabled;
|
||||
}
|
||||
|
||||
public function getSetting($name = '')
|
||||
{
|
||||
if ($name) {
|
||||
return plugin_setting("{$this->code}.{$name}");
|
||||
}
|
||||
return plugin_setting($this->code);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取插件对应的设置字段, 并获取已存储在DB的字段值
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class CustomerRepo
|
|||
*/
|
||||
public static function create($customerData)
|
||||
{
|
||||
$customerData['password'] = Hash::make($customerData['password']);
|
||||
$customerData['password'] = Hash::make($customerData['password'] ?? '');
|
||||
return Customer::query()->create($customerData);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,10 @@ class LoginController extends Controller
|
|||
if (current_customer()) {
|
||||
return redirect(shop_route('account.index'));
|
||||
}
|
||||
return view('account/login');
|
||||
$loginData = [
|
||||
'social_buttons' => hook_filter('login.social.buttons', []),
|
||||
];
|
||||
return view('account/login', $loginData);
|
||||
}
|
||||
|
||||
public function store(LoginRequest $request)
|
||||
|
|
|
|||
|
|
@ -1,39 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* LoginController.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author TL <mengwb@guangda.work>
|
||||
* @created 2022-06-22 20:22:54
|
||||
* @modified 2022-06-22 20:22:54
|
||||
*/
|
||||
|
||||
namespace Beike\Shop\Http\Controllers;
|
||||
|
||||
use Beike\Models\Customer;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('login');
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$credentials = $request->validate([
|
||||
'email' => ['required', 'email'],
|
||||
'password' => ['required'],
|
||||
]);
|
||||
|
||||
if (auth(Customer::AUTH_GUARD)->attempt($credentials)) {
|
||||
return redirect(route('home'));
|
||||
}
|
||||
|
||||
return back()->withErrors([
|
||||
'email' => 'The provided credentials do not match our records.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -38,7 +38,7 @@ class PluginServiceProvider extends ServiceProvider
|
|||
*/
|
||||
public function boot()
|
||||
{
|
||||
if(!installed()) {
|
||||
if (!installed()) {
|
||||
return;
|
||||
}
|
||||
$manager = app('plugin');
|
||||
|
|
@ -48,6 +48,7 @@ class PluginServiceProvider extends ServiceProvider
|
|||
foreach ($plugins as $plugin) {
|
||||
$pluginCode = $plugin->getDirname();
|
||||
$this->bootPlugin($plugin);
|
||||
$this->loadMigrations($pluginCode);
|
||||
$this->loadRoutes($pluginCode);
|
||||
$this->loadTranslations($pluginCode);
|
||||
}
|
||||
|
|
@ -78,6 +79,20 @@ class PluginServiceProvider extends ServiceProvider
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* 加载插件数据库迁移脚本
|
||||
*
|
||||
* @param $pluginCode
|
||||
*/
|
||||
private function loadMigrations($pluginCode)
|
||||
{
|
||||
$migrationPath = "{$this->pluginBasePath}/{$pluginCode}/Migrations";
|
||||
if (is_dir($migrationPath)) {
|
||||
$this->loadMigrationsFrom("{$migrationPath}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 加载插件路由
|
||||
*
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@ class AccountService
|
|||
* 注册用户
|
||||
*
|
||||
* @param array $data // ['email', 'password']
|
||||
* @return Customer
|
||||
* @return mixed
|
||||
*/
|
||||
public static function register(array $data): Customer
|
||||
public static function register(array $data)
|
||||
{
|
||||
$data['customer_group_id'] = system_setting('base.default_customer_group_id', 0); // default_customer_group_id为默认客户组名称
|
||||
$data['status'] = !system_setting('base.approve_customer'); // approve_customer为是否需要审核客户
|
||||
|
|
@ -38,7 +38,7 @@ class AccountService
|
|||
if ($data['email'] ?? 0) {
|
||||
$data['name'] = substr($data['email'], 0, strrpos($data['email'], '@'));;
|
||||
}
|
||||
$data['avatar'] = '';
|
||||
$data['avatar'] = $data['avatar'] ?? '';
|
||||
|
||||
return CustomerRepo::create($data);
|
||||
}
|
||||
|
|
@ -49,7 +49,8 @@ class AccountService
|
|||
* @param $type
|
||||
* @return void
|
||||
*/
|
||||
public static function sendVerifyCodeForForgotten($email, $type) {
|
||||
public static function sendVerifyCodeForForgotten($email, $type)
|
||||
{
|
||||
$code = str_pad(mt_rand(10, 999999), 6, '0', STR_PAD_LEFT);
|
||||
|
||||
VerifyCodeRepo::deleteByAccount($email);
|
||||
|
|
@ -68,7 +69,7 @@ class AccountService
|
|||
* @param $code
|
||||
* @param $account
|
||||
* @param $password
|
||||
* @param $type $account类型,email代表$account为邮箱地址,telephone代表$account为手机号码
|
||||
* @param $type $account类型,email代表$account为邮箱地址,telephone代表$account为手机号码
|
||||
* @return void
|
||||
*/
|
||||
public static function verifyAndChangePassword($code, $account, $password, $type = 'email')
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
"jenssegers/agent": "^2.6",
|
||||
"laravel/framework": "^9.0",
|
||||
"laravel/tinker": "^2.7",
|
||||
"overtrue/socialite": "^4.5",
|
||||
"spatie/laravel-permission": "^5.5",
|
||||
"srmklive/paypal": "^3.0",
|
||||
"stripe/stripe-php": "^8.8",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"axios": "^0.21",
|
||||
"bootstrap": "^4.6.1",
|
||||
"bootstrap": "^5.2.1",
|
||||
"bootstrap-5.1.3": "npm:bootstrap@5.1.3",
|
||||
"browser-sync": "^2.27.10",
|
||||
"browser-sync-webpack-plugin": "^2.3.0",
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
*
|
||||
!FlatShipping
|
||||
!LatestProducts
|
||||
!Paypal
|
||||
!Stripe
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
这里是插件css, 请在blade里面使用以下代码引入
|
||||
<link rel="stylesheet" href="{{ asset('plugin/stripe/css/demo.css') }}">
|
||||
*/
|
||||
|
||||
#bk-stripe-app .form-wrap {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
After Width: | Height: | Size: 6.5 KiB |
|
|
@ -0,0 +1,4 @@
|
|||
/**
|
||||
* 这里是插件js, 请在blade里面使用以下代码引入
|
||||
* <script src="{{ asset('plugin/stripe/js/demo.js') }}"></script>
|
||||
*/
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
"description": "按订单总额收取固定运费",
|
||||
"type": "shipping",
|
||||
"version": "v1.0.0",
|
||||
"icon": "",
|
||||
"icon": "/image/logo.png",
|
||||
"author": {
|
||||
"name": "成都光大网络科技有限公司",
|
||||
"email": "yangjin@beikeshop.com"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
这里是插件css, 请在blade里面使用以下代码引入
|
||||
<link rel="stylesheet" href="{{ asset('plugin/stripe/css/demo.css') }}">
|
||||
*/
|
||||
|
||||
#bk-stripe-app .form-wrap {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
After Width: | Height: | Size: 7.8 KiB |
|
|
@ -0,0 +1,4 @@
|
|||
/**
|
||||
* 这里是插件js, 请在blade里面使用以下代码引入
|
||||
* <script src="{{ asset('plugin/stripe/js/demo.js') }}"></script>
|
||||
*/
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
"description": "首页菜单添加最新商品列表功能",
|
||||
"type": "view",
|
||||
"version": "v1.0.0",
|
||||
"icon": "",
|
||||
"icon": "/image/logo.png",
|
||||
"author": {
|
||||
"name": "成都光大网络科技有限公司",
|
||||
"email": "yangjin@beikeshop.com"
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
/**
|
||||
* Bootstrap.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-10-12 17:33:29
|
||||
* @modified 2022-10-12 17:33:29
|
||||
*/
|
||||
|
||||
namespace Plugin\Social;
|
||||
|
||||
|
||||
class Bootstrap
|
||||
{
|
||||
public function boot()
|
||||
{
|
||||
$this->addSocialData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加第三方登录方式
|
||||
*/
|
||||
private function addSocialData()
|
||||
{
|
||||
add_filter('login.social.buttons', function ($buttons) {
|
||||
$providers = plugin_setting('social.setting');
|
||||
if (empty($providers)) {
|
||||
return $buttons;
|
||||
}
|
||||
|
||||
foreach ($providers as $provider) {
|
||||
$buttons[] = view('Social::shop/social_button', ['provider' => $provider])->render();
|
||||
}
|
||||
return $buttons;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/**
|
||||
* SocialController.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-09-30 18:46:38
|
||||
* @modified 2022-09-30 18:46:38
|
||||
*/
|
||||
|
||||
namespace Plugin\Social\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Beike\Repositories\SettingRepo;
|
||||
use Beike\Admin\Http\Controllers\Controller;
|
||||
|
||||
class AdminSocialController extends Controller
|
||||
{
|
||||
/**
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function saveSetting(Request $request): array
|
||||
{
|
||||
$socialData = [
|
||||
'type' => 'plugin',
|
||||
'space' => 'social',
|
||||
'name' => 'setting',
|
||||
'value' => json_encode($request->all()),
|
||||
'json' => 1,
|
||||
];
|
||||
SettingRepo::createOrUpdate($socialData);
|
||||
return json_success('保存成功');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
/**
|
||||
* SocialController.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-09-30 18:46:38
|
||||
* @modified 2022-09-30 18:46:38
|
||||
*/
|
||||
|
||||
namespace Plugin\Social\Controllers;
|
||||
|
||||
use Beike\Models\Customer;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Overtrue\Socialite\Exceptions\Exception;
|
||||
use Overtrue\Socialite\SocialiteManager;
|
||||
use Beike\Admin\Http\Controllers\Controller;
|
||||
use Plugin\Social\Repositories\CustomerRepo;
|
||||
|
||||
class ShopSocialController extends Controller
|
||||
{
|
||||
private SocialiteManager $socialite;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$config = [];
|
||||
$providerSettings = plugin_setting('social.setting');
|
||||
foreach ($providerSettings as $providerSetting) {
|
||||
$provider = $providerSetting['provider'];
|
||||
if (empty($provider)) {
|
||||
continue;
|
||||
}
|
||||
$config[$provider] = [
|
||||
'client_id' => $providerSetting['key'],
|
||||
'client_secret' => $providerSetting['secret'],
|
||||
'redirect' => plugin_route('social.callback', $provider),
|
||||
];
|
||||
}
|
||||
$this->socialite = new SocialiteManager($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $provider
|
||||
* @return mixed
|
||||
*/
|
||||
public function redirect($provider)
|
||||
{
|
||||
$url = $this->socialite->create($provider)->redirect();
|
||||
return redirect($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $provider
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function callback($provider)
|
||||
{
|
||||
$code = request('code');
|
||||
$driver = $this->socialite->create($provider);
|
||||
|
||||
// For google, facebook, twitter in China.
|
||||
$driver->setGuzzleOptions([
|
||||
'proxy' => '127.0.0.1:7890'
|
||||
]);
|
||||
|
||||
$userData = $driver->userFromCode($code);
|
||||
$customer = CustomerRepo::createCustomer($provider, $userData);
|
||||
Auth::guard(Customer::AUTH_GUARD)->login($customer);
|
||||
return view('Social::shop/callback');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/**
|
||||
* providers.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-10-13 11:30:33
|
||||
* @modified 2022-10-13 11:30:33
|
||||
*/
|
||||
|
||||
return [
|
||||
'alipay' => 'Alipay',
|
||||
'azure' => 'Azure',
|
||||
'dingtalk' => 'Dingtalk',
|
||||
'douyin' => 'Douyin',
|
||||
'douban' => 'Douban',
|
||||
'facebook' => 'Facebook',
|
||||
'feishu' => 'Feishu',
|
||||
'figma' => 'Figma',
|
||||
'github' => 'Github',
|
||||
'gitee' => 'Gitee',
|
||||
'google' => 'Google',
|
||||
'line' => 'Line',
|
||||
'linkedin' => 'Linkedin',
|
||||
'open-wework' => 'Open-wework',
|
||||
'outlook' => 'Outlook',
|
||||
'qcloud' => 'Qcloud',
|
||||
'qq' => 'QQ',
|
||||
'taobao' => 'Taobao',
|
||||
'tapd' => 'Tapd',
|
||||
'wechat' => 'Wechat',
|
||||
'wework' => 'Wework',
|
||||
'weibo' => 'Weibo',
|
||||
];
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
/**
|
||||
* setting.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-08-11 15:26:18
|
||||
* @modified 2022-08-11 15:26:18
|
||||
*/
|
||||
|
||||
return [
|
||||
// Text
|
||||
'text_module' => 'Modules',
|
||||
'text_success' => 'Success: You have modified module OpenCart OmniAuth!',
|
||||
'text_copyright' => 'OpenCart.cn <a href="http://www.opencart.cn" target="_blank">OmniAuth</a> © %s',
|
||||
'text_omni_explain' => 'This plugin supports WeChat scan code, WeChat Official, QQ, Weibo, Facebook, Google, Twitter and others Social Network',
|
||||
'text_omni_explain_2' => 'To use a third-party login, you need to apply to the corresponding platform, and fill in the obtained ID and key to the corresponding input box.',
|
||||
'text_wechat_title' => 'WeChat scan code login application address',
|
||||
'text_wechat_info' => 'WeChat open platform',
|
||||
'text_qq_title' => 'QQ login application address',
|
||||
'text_qq_info' => 'QQ interconnection',
|
||||
'text_weibo_title' => 'Weibo login application address',
|
||||
'text_weibo_info' => 'Weibo open platform',
|
||||
'text_facebook_title' => 'Facebook login application address',
|
||||
'text_google_title' => 'Google login application address',
|
||||
'text_Twitter_title' => 'Twitter login application address',
|
||||
'text_help_msg' => 'help information',
|
||||
|
||||
// Entry
|
||||
'entry_status' => 'Status',
|
||||
'entry_bind' => 'Force Bind',
|
||||
'entry_debug' => 'Debug Mode',
|
||||
|
||||
'entry_provider' => 'Provider',
|
||||
'entry_key' => 'Client ID',
|
||||
'entry_secret' => 'Client Secret',
|
||||
'entry_scope' => 'Flags (optional)',
|
||||
'entry_callback' => 'Callback URL',
|
||||
'entry_sort_order' => 'Sort Order',
|
||||
|
||||
// Button
|
||||
'button_add_row' => 'Add Provider',
|
||||
|
||||
// Error
|
||||
'error_permission' => 'Warning: You do not have permission to modify module OpenCart OmniAuth!',
|
||||
|
||||
// Providers
|
||||
'wechat' => 'WeChat',
|
||||
'wechatofficial' => 'WeChatOfficial',
|
||||
'qq' => 'QQ',
|
||||
'weibo' => 'Weibo',
|
||||
'facebook' => 'Facebook',
|
||||
'google' => 'Google',
|
||||
'twitter' => 'Twitter',
|
||||
|
||||
'instagram' => 'Instagram',
|
||||
];
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/**
|
||||
* providers.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-10-13 11:30:33
|
||||
* @modified 2022-10-13 11:30:33
|
||||
*/
|
||||
|
||||
return [
|
||||
'alipay' => '支付宝',
|
||||
'azure' => 'Azure',
|
||||
'dingtalk' => '钉钉',
|
||||
'douyin' => '抖音',
|
||||
'douban' => '豆瓣',
|
||||
'facebook' => 'Facebook',
|
||||
'feishu' => '飞书',
|
||||
'figma' => 'Figma',
|
||||
'github' => 'GitHub',
|
||||
'gitee' => 'Gitee',
|
||||
'google' => 'Google',
|
||||
'line' => 'Line',
|
||||
'linkedin' => 'Linkedin',
|
||||
'open-wework' => 'open-wework',
|
||||
'outlook' => 'Outlook',
|
||||
'qcloud' => '腾讯云',
|
||||
'qq' => 'QQ',
|
||||
'taobao' => '淘宝',
|
||||
'tapd' => 'tapd',
|
||||
'wechat' => '微信',
|
||||
'wework' => '企业微信',
|
||||
'weibo' => '微博',
|
||||
];
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
/**
|
||||
* setting.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-08-11 15:26:18
|
||||
* @modified 2022-08-11 15:26:18
|
||||
*/
|
||||
|
||||
return [
|
||||
// Text
|
||||
'text_module' => '模块',
|
||||
'text_success' => '成功: 您成功修改第三方登录配置!',
|
||||
'text_copyright' => 'OpenCart.cn <a href="http://www.opencart.cn" target="_blank">获取帮助</a> © %s',
|
||||
'text_omni_explain' => '本模块支持微信扫码, 微信公众号, QQ, 微博,Facebook,Google,Twitter等第三方登录',
|
||||
'text_omni_explain_2' => '要使用第三方登录, 需要到对应平台申请开通, 并把获取到的 ID 和密钥填写到上面对应的输入框',
|
||||
'text_wechat_title' => '微信扫码登录申请地址',
|
||||
'text_wechat_info' => '微信开放平台',
|
||||
'text_qq_title' => 'QQ登录申请地址',
|
||||
'text_qq_info' => 'QQ互联',
|
||||
'text_weibo_title' => '微博登录申请地址',
|
||||
'text_weibo_info' => '微博开放平台',
|
||||
'text_facebook_title' => 'Facebook登录申请地址',
|
||||
'text_google_title' => 'Google登录申请地址',
|
||||
'text_Twitter_title' => 'Twitter登录申请地址',
|
||||
'text_help_msg' => '帮助信息',
|
||||
|
||||
// Entry
|
||||
'entry_status' => '状态',
|
||||
'entry_bind' => '强制绑定',
|
||||
'entry_debug' => '调试模式',
|
||||
|
||||
'entry_provider' => '类型',
|
||||
'entry_key' => 'Client ID',
|
||||
'entry_secret' => 'Client Secret',
|
||||
'entry_scope' => 'Flags (可选项)',
|
||||
'entry_callback' => '回调地址',
|
||||
'entry_sort_order' => '排序',
|
||||
|
||||
// Button
|
||||
'button_add_row' => '添加类型',
|
||||
|
||||
// Error
|
||||
'error_permission' => '警告: 您没有权限修改此配置!',
|
||||
];
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('customer_socials', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->integer('customer_id');
|
||||
$table->string('provider');
|
||||
$table->string('user_id');
|
||||
$table->string('union_id');
|
||||
$table->string('access_token');
|
||||
$table->text('extra');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('customer_socials');
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
/**
|
||||
* CustomerSocial.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-10-13 10:35:44
|
||||
* @modified 2022-10-13 10:35:44
|
||||
*/
|
||||
|
||||
namespace Plugin\Social\Models;
|
||||
|
||||
use Beike\Models\Customer;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class CustomerSocial extends Model
|
||||
{
|
||||
public $table = 'customer_socials';
|
||||
|
||||
public $fillable = [
|
||||
'customer_id', 'provider', 'user_id', 'union_id', 'access_token', 'extra'
|
||||
];
|
||||
|
||||
public function customer(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Customer::class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
/**
|
||||
* CustomerRepo.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-10-13 09:57:13
|
||||
* @modified 2022-10-13 09:57:13
|
||||
*/
|
||||
|
||||
namespace Plugin\Social\Repositories;
|
||||
|
||||
use Beike\Models\Customer;
|
||||
use Overtrue\Socialite\User;
|
||||
use Overtrue\Socialite\Providers;
|
||||
use Beike\Shop\Services\AccountService;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Plugin\Social\Models\CustomerSocial;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Overtrue\Socialite\Exceptions\Exception;
|
||||
|
||||
class CustomerRepo
|
||||
{
|
||||
/**
|
||||
* 允许的第三方服务
|
||||
*/
|
||||
private const PROVIDERS = [
|
||||
Providers\Alipay::NAME,
|
||||
Providers\Azure::NAME,
|
||||
Providers\DingTalk::NAME,
|
||||
Providers\DouYin::NAME,
|
||||
Providers\Douban::NAME,
|
||||
Providers\Facebook::NAME,
|
||||
Providers\FeiShu::NAME,
|
||||
Providers\Figma::NAME,
|
||||
Providers\GitHub::NAME,
|
||||
Providers\Gitee::NAME,
|
||||
Providers\Google::NAME,
|
||||
Providers\Line::NAME,
|
||||
Providers\Linkedin::NAME,
|
||||
Providers\OpenWeWork::NAME,
|
||||
Providers\Outlook::NAME,
|
||||
Providers\QCloud::NAME,
|
||||
Providers\QQ::NAME,
|
||||
Providers\Taobao::NAME,
|
||||
Providers\Tapd::NAME,
|
||||
Providers\WeChat::NAME,
|
||||
Providers\WeWork::NAME,
|
||||
Providers\Weibo::NAME,
|
||||
];
|
||||
|
||||
public static function allProviders(): array
|
||||
{
|
||||
$items = [];
|
||||
foreach (self::PROVIDERS as $provider) {
|
||||
$items[] = [
|
||||
'code' => $provider,
|
||||
'label' => trans("Social::providers.{$provider}")
|
||||
];
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建客户, 关联第三方用户数据
|
||||
*
|
||||
* @param $provider
|
||||
* @param User $userData
|
||||
* @return Customer
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function createCustomer($provider, User $userData): Customer
|
||||
{
|
||||
$social = self::getCustomerByProvider($provider, $userData->getId());
|
||||
$customer = $social->customer ?? null;
|
||||
if ($customer) {
|
||||
return $customer;
|
||||
}
|
||||
|
||||
$email = $userData->getEmail();
|
||||
$customer = Customer::query()->where('email', $email)->first();
|
||||
if (empty($customer)) {
|
||||
$customerData = [
|
||||
'from' => $provider,
|
||||
'email' => $userData->getEmail(),
|
||||
'name' => $userData->getNickname(),
|
||||
'avatar' => $userData->getAvatar(),
|
||||
];
|
||||
$customer = AccountService::register($customerData);
|
||||
}
|
||||
|
||||
self::createSocial($customer, $provider, $userData);
|
||||
return $customer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $customer
|
||||
* @param $provider
|
||||
* @param User $userData
|
||||
* @return Model|Builder
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function createSocial($customer, $provider, User $userData): Model|Builder
|
||||
{
|
||||
$social = self::getCustomerByProvider($provider, $userData->getId());
|
||||
if ($social) {
|
||||
return $social;
|
||||
}
|
||||
|
||||
$socialData = [
|
||||
'customer_id' => $customer->id,
|
||||
'provider' => $provider,
|
||||
'user_id' => $userData->getId(),
|
||||
'union_id' => '',
|
||||
'access_token' => $userData->getAccessToken(),
|
||||
'extra' => $userData->toJSON()
|
||||
];
|
||||
return CustomerSocial::query()->create($socialData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过 provider 和 user_id 获取已存在 social
|
||||
* @param $provider
|
||||
* @param $userId
|
||||
* @return Model|Builder|null
|
||||
*/
|
||||
private static function getCustomerByProvider($provider, $userId): Model|Builder|null
|
||||
{
|
||||
return CustomerSocial::query()
|
||||
->with(['customer'])
|
||||
->where('provider', $provider)
|
||||
->where('user_id', $userId)
|
||||
->first();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
/**
|
||||
* admin.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-08-04 16:17:53
|
||||
* @modified 2022-08-04 16:17:53
|
||||
*/
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Plugin\Social\Controllers\AdminSocialController;
|
||||
|
||||
Route::post('/social/setting', [AdminSocialController::class, 'saveSetting'])->name('plugin.social.setting');
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/**
|
||||
* shop.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-09-30 18:52:54
|
||||
* @modified 2022-09-30 18:52:54
|
||||
*/
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Plugin\Social\Controllers\ShopSocialController;
|
||||
|
||||
Route::get('/social/redirect/{provider}', [ShopSocialController::class, 'redirect'])->name('plugin.social.redirect');
|
||||
Route::get('/social/callbacks/{provider}', [ShopSocialController::class, 'callback'])->name('plugin.social.callback');
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
|
@ -2,24 +2,181 @@
|
|||
|
||||
@section('title', __('admin/plugin.plugins_show'))
|
||||
|
||||
@section('page-title-right')
|
||||
<button type="button" class="btn btn-primary save-btn" onclick="app.submit('form')">{{ __('common.save') }}</button>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="card">
|
||||
<div class="card mb-4" id="app">
|
||||
<div class="card-body">
|
||||
<h6 class="border-bottom pb-3 mb-4">{{ $plugin->name }}</h6>
|
||||
<div class="d-flex justify-content-between align-items-center border-bottom pb-3 mb-4">
|
||||
<h6 class="mb-0">{{ $plugin->name }}</h6>
|
||||
<button type="button" @click="addRow()" class="btn btn-sm btn-outline-primary">{{ __('common.add') }}</button>
|
||||
</div>
|
||||
|
||||
@if (session('success'))
|
||||
<x-admin-alert type="success" msg="{{ session('success') }}" class="mt-4"/>
|
||||
@endif
|
||||
<form class="needs-validation" novalidate action="{{ admin_route('plugins.update', [$plugin->code]) }}" method="POST">
|
||||
@csrf
|
||||
{{ method_field('put') }}
|
||||
|
||||
这里是social配置模板
|
||||
|
||||
<x-admin::form.row title="">
|
||||
<button type="submit" class="btn btn-primary btn-lg mt-4">{{ __('common.submit') }}</button>
|
||||
</x-admin::form.row>
|
||||
</form>
|
||||
<el-form ref="form" :model="form" class="form-wrap" :inline-message="true">
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 150px">{{ __('Social::setting.entry_provider') }}</th>
|
||||
<th>{{ __('Social::setting.entry_status') }}</th>
|
||||
<th>{{ __('Social::setting.entry_key') }}</th>
|
||||
<th>{{ __('Social::setting.entry_secret') }}</th>
|
||||
<th>{{ __('Social::setting.entry_callback') }}</th>
|
||||
<th style="width: 100px">{{ __('Social::setting.entry_sort_order') }}</th>
|
||||
<th class="text-end"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody v-if="form.social.length">
|
||||
<tr v-for="(item, index) in form.social" :key="index">
|
||||
<td>
|
||||
<el-form-item prop="provider" class="mb-0">
|
||||
<el-select size="small" v-model="item.provider" @change="(e) => {providerChange(e, index)}" placeholder="{{ __('Social::setting.provider') }}">
|
||||
<el-option
|
||||
v-for="item in source.providers"
|
||||
:key="item.code"
|
||||
:label="item.label"
|
||||
:value="item.code">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</td>
|
||||
<td>
|
||||
<el-form-item label="" prop="entry_status" class="mb-0">
|
||||
<el-switch v-model="item.status" :active-value="1" :inactive-value="0"></el-switch>
|
||||
</el-form-item>
|
||||
</td>
|
||||
<td>
|
||||
<el-form-item
|
||||
label="" :prop="`social[${index}].key`" class="mb-0"
|
||||
:rules="[
|
||||
{ required: true, message: '{{ __('common.error_required', ['name' => __('Social::setting.entry_key')]) }}', trigger: ['blur', 'change'] },]"
|
||||
>
|
||||
<el-input size="small" v-model="item.key" placeholder="{{ __('Social::setting.entry_key') }}"></el-input>
|
||||
</el-form-item>
|
||||
</td>
|
||||
<td>
|
||||
<el-form-item
|
||||
label="" :prop="`social[${index}].secret`" class="mb-0"
|
||||
:rules="[
|
||||
{ required: true, message: '{{ __('common.error_required', ['name' => __('Social::setting.entry_secret')]) }}', trigger: ['blur', 'change'] },]"
|
||||
>
|
||||
<el-input size="small" v-model="item.secret" placeholder="{{ __('Social::setting.entry_secret') }}"></el-input>
|
||||
</el-form-item>
|
||||
</td>
|
||||
<td>
|
||||
<el-form-item label="" class="mb-0">
|
||||
<div class="input-group">
|
||||
<input size="small" class="form-control" :value="callbackUrl(item.callback)" disabled placeholder="{{ __('Social::setting.entry_callback') }}"></input>
|
||||
<a href="javascript:void(0)" class="btn btn-outline-secondary opacity-75 copy-code" :data-clipboard-text="item.callback"><i class="bi bi-front"></i></a>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</td>
|
||||
<td>
|
||||
<el-form-item label="" prop="sort_order" class="mb-0">
|
||||
<el-input size="small" v-model="item.sort_order" placeholder="{{ __('Social::setting.entry_sort_order') }}"></el-input>
|
||||
</el-form-item>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<button type="button" @click="form.social.splice(index, 1)" class="btn btn-outline-danger btn-sm ml-1"><i class="bi bi-x-lg"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody v-else><td colspan="7"><x-admin-no-data /></td></tbody>
|
||||
</table>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h6 class="border-bottom pb-3 mb-4">{{ __('Social::setting.text_help_msg') }}</h6>
|
||||
<ol class="list-group list-group-numbered lh-lg text-secondary">
|
||||
<li>{{ __('Social::setting.text_omni_explain') }}</li>
|
||||
<li>{{ __('Social::setting.text_omni_explain_2') }}</li>
|
||||
<li>{{ __('Social::setting.text_wechat_title') }}
|
||||
<a target="_blank" href="https://open.weixin.qq.com/">{{ __('Social::setting.text_wechat_info') }}</a>
|
||||
</li>
|
||||
<li>{{ __('Social::setting.text_qq_title') }}
|
||||
<a target="_blank" href="https://connect.qq.com/">{{ __('Social::setting.text_qq_info') }}</a>
|
||||
</li>
|
||||
<li>{{ __('Social::setting.text_weibo_title') }}
|
||||
<a target="_blank" href="http://open.weibo.com/">{{ __('Social::setting.text_weibo_info') }}</a>
|
||||
</li>
|
||||
<li>{{ __('Social::setting.text_facebook_title') }}
|
||||
<a target="_blank" href="https://developers.facebook.com/">Facebook</a>
|
||||
</li>
|
||||
<li>{{ __('Social::setting.text_google_title') }}
|
||||
<a target="_blank" href="https://console.developers.google.com/projectcreate/">Google</a>
|
||||
</li>
|
||||
<li>{{ __('Social::setting.text_Twitter_title') }}
|
||||
<a target="_blank" href="https://apps.twitter.com/">Twitter</a>
|
||||
</li>
|
||||
.......
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.el-form-item__error--inline {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.el-form-item__content {
|
||||
line-height: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="{{ asset('vendor/clipboard/clipboard.min.js') }}"></script>
|
||||
<script>
|
||||
new ClipboardJS('.copy-code')
|
||||
let app = new Vue({
|
||||
el: '#app',
|
||||
|
||||
data: {
|
||||
form: {
|
||||
social: @json($plugin->getSetting('setting') ?? []),
|
||||
},
|
||||
|
||||
source: {
|
||||
providers: @json(Plugin\Social\Repositories\CustomerRepo::allProviders())
|
||||
},
|
||||
|
||||
rules: {
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
submit(form) {
|
||||
this.$refs[form].validate((valid) => {
|
||||
if (!valid) {
|
||||
this.$message.error('{{ __('common.error_form') }}');
|
||||
return;
|
||||
}
|
||||
|
||||
$http.post("{{ admin_route('plugin.social.setting') }}", this.form.social).then((res) => {
|
||||
layer.msg(res.message)
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
callbackUrl(code) {
|
||||
return `{{ shop_route('home.index') }}/${code}`;
|
||||
},
|
||||
|
||||
providerChange(e, index) {
|
||||
this.form.social[index].callback = 'plugin/social/callbacks/' + e
|
||||
},
|
||||
|
||||
addRow() {
|
||||
this.form.social.push({provider: this.source.providers[1].code, status: 1, key: '', secret: '', callback: `plugin/social/callbacks/${this.source.providers[1].code}`, sort_order: this.form.social.length})
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
<script>
|
||||
const url = "{{ shop_route('account.index') }}";
|
||||
if (window.opener === null) {
|
||||
window.location.href = url;
|
||||
} else {
|
||||
window.opener.location = url;
|
||||
window.close();
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<button type="button" class="btn border fw-bold w-100 mb-3" class="provider-btn" onclick="bk.openWin('{{ plugin_route('social.redirect', $provider['provider']) }}')">
|
||||
<img src="{{ plugin_resize('social' , '/image/' . $provider['provider'] . '.png') }}" class="img-fluid wh-20 me-2">
|
||||
{{ __("Social::providers.".$provider['provider']) }}
|
||||
</button>
|
||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 11 KiB |
|
|
@ -9,12 +9,6 @@
|
|||
*/
|
||||
|
||||
body.page-marketing {
|
||||
.col-xl-3 {
|
||||
@media (min-width: 1200px) {
|
||||
width: 20%;
|
||||
}
|
||||
}
|
||||
|
||||
.marketing-item {
|
||||
box-shadow: none;
|
||||
border: 1px solid #eee;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ $alert-padding-y: 0.5rem;
|
|||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #fff;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.form-switch {
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
|
||||
<div class="marketing-wrap" v-if="plugins.data.length">
|
||||
<div class="row">
|
||||
<div class="col-xl-3 col-md-4 col-6" v-for="plugin, index in plugins.data" :key="index">
|
||||
<div class="col-xxl-2 col-xl-3 col-md-4 col-6" v-for="plugin, index in plugins.data" :key="index">
|
||||
<div class="card mb-4 marketing-item">
|
||||
<div class="card-body">
|
||||
<div class="plugin-img mb-3"><a :href="'admin/marketing/' + plugin.code"><img :src="plugin.icon_big"
|
||||
|
|
|
|||
|
|
@ -72,10 +72,10 @@ $form-feedback-icon-valid-color: inherit;
|
|||
|
||||
// $dropdown-divider-bg: rgba(0, 0, 0, 0.1);
|
||||
@import './bootstrap-icons';
|
||||
@import 'node_modules/bootstrap-5.1.3/scss/bootstrap';
|
||||
@import 'node_modules/bootstrap/scss/bootstrap';
|
||||
|
||||
.btn-primary {
|
||||
color: #fff;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.container-fluid {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,23 @@ body.page-login, body.page-forgotten {
|
|||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.el-form-item__error--inline {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.forgotten-link {
|
||||
display: block;
|
||||
margin-top: -14px;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 18px;
|
||||
|
||||
.el-form-item__content {
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.login-item-header {
|
||||
background: #f8f9fa;
|
||||
border-bottom: none;
|
||||
|
|
@ -23,14 +40,66 @@ body.page-login, body.page-forgotten {
|
|||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
border: none;
|
||||
.login-wrap {
|
||||
@media (min-width: 768px) {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: none;
|
||||
@media (min-width: 768px) {
|
||||
width: 340px;
|
||||
margin: 0 60px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-iframe {
|
||||
margin-bottom: 30px;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
padding: 0;
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: none;
|
||||
@media (min-width: 768px) {
|
||||
margin: 0 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.social-wrap {
|
||||
.title {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
height: 1px;
|
||||
top: 47%;
|
||||
background: #e5e5e5;
|
||||
}
|
||||
|
||||
span {
|
||||
background-color: #fff;
|
||||
position: relative;
|
||||
padding: 0 5px;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
border-color: #ccc !important;
|
||||
&:hover {
|
||||
background-color: #eee;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* @link https://beikeshop.com
|
||||
* @Author pu shuo <pushuo@guangda.work>
|
||||
* @Date 2022-09-09 19:16:39
|
||||
* @LastEditTime 2022-09-16 20:56:53
|
||||
* @LastEditTime 2022-09-28 17:23:48
|
||||
*/
|
||||
|
||||
export default {
|
||||
|
|
@ -12,13 +12,15 @@ export default {
|
|||
* @return {*}
|
||||
*/
|
||||
getCarts() {
|
||||
$http.get('carts/mini', null, {hload: true}).then((res) => {
|
||||
$('#offcanvas-right-cart').html(res.data.html);
|
||||
if (!res.data.quantity) {
|
||||
$('.cart-badge-quantity').hide();
|
||||
} else {
|
||||
$('.cart-badge-quantity').show().html(res.data.quantity > 99 ? '99+' : res.data.quantity);
|
||||
}
|
||||
$(document).ready(() => {
|
||||
$http.get('carts/mini', null, {hload: true}).then((res) => {
|
||||
$('#offcanvas-right-cart').html(res.data.html);
|
||||
if (!res.data.quantity) {
|
||||
$('.cart-badge-quantity').hide();
|
||||
} else {
|
||||
$('.cart-badge-quantity').show().html(res.data.quantity > 99 ? '99+' : res.data.quantity);
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
|
|
@ -118,9 +120,18 @@ export default {
|
|||
type: 2,
|
||||
title: '',
|
||||
shadeClose: true,
|
||||
scrollbar: false,
|
||||
area: ['900px', '600px'],
|
||||
skin: 'login-pop-box',
|
||||
content: 'login?iframe=true' //iframe的url
|
||||
});
|
||||
},
|
||||
|
||||
openWin(url, name = '', iWidth = 700, iHeight = 500) {
|
||||
var iTop = (window.screen.height - 30 - iHeight) / 2;;
|
||||
var iLeft = (window.screen.width - 10 - iWidth) / 2;;
|
||||
window.open(url, name, 'height=' + iHeight + ',innerHeight=' + iHeight
|
||||
+ ',width=' + iWidth + ',innerWidth=' + iWidth + ',top=' + iTop + ',left=' + iLeft
|
||||
+ ',toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no');
|
||||
}
|
||||
}
|
||||
|
|
@ -16,69 +16,65 @@
|
|||
<div class="hero-content pb-5 text-center"><h1 class="hero-heading">{{ __('shop/login.index') }}</h1></div>
|
||||
@endif
|
||||
|
||||
<div class="justify-content-center row {{ !request('iframe') ? 'mb-5' : '' }}">
|
||||
<div class="col-lg-{{ request('iframe') ? '6' : '5' }} col-md-6 col-sm-12">
|
||||
<div class="card">
|
||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules">
|
||||
<div class="login-item-header card-header">
|
||||
<h6 class="text-uppercase mb-0">{{ __('shop/login.login') }}</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="lead">{{ __('shop/login.already') }}</p>
|
||||
{{-- <p class="text-muted">Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis
|
||||
egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit
|
||||
amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p> --}}
|
||||
<hr>
|
||||
|
||||
<el-form-item label="{{ __('shop/login.email') }}" prop="email">
|
||||
<el-input @keyup.enter.native="checkedBtnLogin('loginForm')" v-model="loginForm.email" placeholder="{{ __('shop/login.email_address') }}"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="{{ __('shop/login.password') }}" prop="password" class="mb-4">
|
||||
<el-input @keyup.enter.native="checkedBtnLogin('loginForm')" type="password" v-model="loginForm.password" placeholder="{{ __('shop/login.password') }}"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<a class="text-muted" href="{{ shop_route('forgotten.index') }}"><i class="bi bi-question-circle"></i> {{ __('shop/login.forget_password') }}</a>
|
||||
|
||||
<div class="mt-4 mb-3">
|
||||
<button type="button" @click="checkedBtnLogin('loginForm')" class="btn btn-outline-dark"><i class="bi bi-box-arrow-in-right"></i> {{ __('shop/login.login') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-{{ request('iframe') ? '6' : '5' }} col-md-6 col-sm-12">
|
||||
<div class="card">
|
||||
<div class="login-wrap">
|
||||
<div class="card">
|
||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" :inline-message="true">
|
||||
<div class="login-item-header card-header">
|
||||
<h6 class="text-uppercase mb-0">{{ __('shop/login.new') }}</h6>
|
||||
<h6 class="text-uppercase mb-0">{{ __('shop/login.login') }}</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="lead">{{ __('shop/login.not_already') }}</p>
|
||||
{{-- <p class="text-muted">With registration with us new world of fashion, fantastic discounts and much more opens to
|
||||
you! The whole process will not take you more than a minute!</p>
|
||||
<p class="text-muted">If you have any questions, please feel free to <a href="/contact">contact us</a>, our
|
||||
customer service center is working for you 24/7.</p> --}}
|
||||
<hr>
|
||||
<div class="card-body px-md-2">
|
||||
<el-form-item label="{{ __('shop/login.email') }}" prop="email">
|
||||
<el-input @keyup.enter.native="checkedBtnLogin('loginForm')" v-model="loginForm.email" placeholder="{{ __('shop/login.email_address') }}"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form ref="registerForm" :model="registerForm" :rules="registeRules">
|
||||
<el-form-item label="{{ __('shop/login.email') }}" prop="email">
|
||||
<el-input @keyup.enter.native="checkedBtnLogin('registerForm')" v-model="registerForm.email" placeholder="{{ __('shop/login.email_address') }}"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="{{ __('shop/login.password') }}" prop="password">
|
||||
<el-input @keyup.enter.native="checkedBtnLogin('loginForm')" type="password" v-model="loginForm.password" placeholder="{{ __('shop/login.password') }}"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="{{ __('shop/login.password') }}" prop="password">
|
||||
<el-input @keyup.enter.native="checkedBtnLogin('registerForm')" type="password" v-model="registerForm.password" placeholder="{{ __('shop/login.password') }}"></el-input>
|
||||
</el-form-item>
|
||||
<a class="text-muted forgotten-link" href="{{ shop_route('forgotten.index') }}"><i class="bi bi-question-circle"></i> {{ __('shop/login.forget_password') }}</a>
|
||||
|
||||
<el-form-item label="{{ __('shop/login.confirm_password') }}" prop="password_confirmation">
|
||||
<el-input @keyup.enter.native="checkedBtnLogin('registerForm')" type="password" v-model="registerForm.password_confirmation" placeholder="{{ __('shop/login.confirm_password') }}"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<div class="mt-5 mb-3">
|
||||
<button type="button" @click="checkedBtnLogin('registerForm')" class="btn btn-outline-dark"><i class="bi bi-person"></i> {{ __('shop/login.register') }}</button>
|
||||
</div>
|
||||
</el-form>
|
||||
<div class="mt-4 mb-3">
|
||||
<button type="button" @click="checkedBtnLogin('loginForm')" class="btn btn-dark btn-lg w-100 fw-bold"><i class="bi bi-box-arrow-in-right"></i> {{ __('shop/login.login') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</el-form>
|
||||
|
||||
@if($social_buttons)
|
||||
<div class="social-wrap px-2">
|
||||
<div class="title mb-4"><span>第三方登录</span></div>
|
||||
@foreach($social_buttons as $button)
|
||||
{!! $button !!}
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="d-flex">
|
||||
<div class="vr bg-secondary"></div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="login-item-header card-header">
|
||||
<h6 class="text-uppercase mb-0">{{ __('shop/login.new') }}</h6>
|
||||
</div>
|
||||
<div class="card-body px-md-2">
|
||||
<el-form ref="registerForm" :model="registerForm" :rules="registeRules">
|
||||
<el-form-item label="{{ __('shop/login.email') }}" prop="email">
|
||||
<el-input @keyup.enter.native="checkedBtnLogin('registerForm')" v-model="registerForm.email" placeholder="{{ __('shop/login.email_address') }}"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="{{ __('shop/login.password') }}" prop="password">
|
||||
<el-input @keyup.enter.native="checkedBtnLogin('registerForm')" type="password" v-model="registerForm.password" placeholder="{{ __('shop/login.password') }}"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="{{ __('shop/login.confirm_password') }}" prop="password_confirmation">
|
||||
<el-input @keyup.enter.native="checkedBtnLogin('registerForm')" type="password" v-model="registerForm.password_confirmation" placeholder="{{ __('shop/login.confirm_password') }}"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<div class="mt-5 mb-3">
|
||||
<button type="button" @click="checkedBtnLogin('registerForm')" class="btn btn-dark btn-lg w-100 fw-bold"><i class="bi bi-person"></i> {{ __('shop/login.register') }}</button>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -184,4 +180,4 @@
|
|||
}
|
||||
})
|
||||
</script>
|
||||
@endpush
|
||||
@endpush
|
||||
|
|
|
|||