Store the customized Shopro mall so it can be kept on the remote.
Co-authored-by: Cursor <cursoragent@cursor.com>
这个提交包含在:
1
addons/sdtheme/.addonrc
普通文件
1
addons/sdtheme/.addonrc
普通文件
@@ -0,0 +1 @@
|
||||
{"files":["public\/assets\/addons\/sdtheme\/simple_sdkjcc.less","public\/assets\/addons\/sdtheme\/simple.css"],"license":"regular","licenseto":"26425","licensekey":"E1jBsJz6Sdq9lGrX uEDSWoBYupcUg6k9gcnWGA==","domains":["14996.com"],"licensecodes":[],"validations":["82dcffa78fca7d832197ff1e1d536e2a"]}
|
||||
139
addons/sdtheme/Sdtheme.php
普通文件
139
addons/sdtheme/Sdtheme.php
普通文件
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
namespace addons\sdtheme;
|
||||
|
||||
use app\common\library\Menu;
|
||||
use think\Addons;
|
||||
use think\Request;
|
||||
use think\Config;
|
||||
|
||||
/**
|
||||
* 插件
|
||||
*/
|
||||
class Sdtheme extends Addons
|
||||
{
|
||||
|
||||
/**
|
||||
* 应用初始化钩子 - 修改跳转提示页模板配置
|
||||
*/
|
||||
public function appInit()
|
||||
{
|
||||
$addonPath = ADDON_PATH . 'sdtheme' . DS;
|
||||
|
||||
// 跳转提示页样式开关
|
||||
if ($this->getConfig()['error_page_jump']) {
|
||||
Config::set('dispatch_success_tmpl', $addonPath . 'view' . DS . 'tpl' . DS . 'dispatch_jump.tpl');
|
||||
Config::set('dispatch_error_tmpl', $addonPath . 'view' . DS . 'tpl' . DS . 'dispatch_jump.tpl');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML替换
|
||||
*/
|
||||
public function viewFilter(&$content)
|
||||
{
|
||||
$request = Request::instance();
|
||||
$module = strtolower($request->module());
|
||||
$controller = strtolower($request->controller());
|
||||
$action = strtolower($request->action());
|
||||
|
||||
if ($module == 'admin') {
|
||||
|
||||
// 如果没有定义主题就用 sdtheme-white
|
||||
if ($controller == 'index' && $action == 'index') {
|
||||
if (!config('fastadmin.adminskin') && !cookie('adminskin')) {
|
||||
$content = preg_replace(
|
||||
'/(<body[^>]*class=")([^"]*)(")/',
|
||||
'$1$2 sdtheme-white $3',
|
||||
$content
|
||||
);
|
||||
}
|
||||
|
||||
// 右侧菜单栏增加主题
|
||||
$newItem = '<li><a href="javascript:;" data-skin="" class="clearfix full-opacity-hover"><div><span style="width: 20%; height: 27px; background: #FFFFFF;"></span><span style="width: 80%; height: 27px; background: #f4f5f7;"></span></div></a><p class="text-center no-margin">sdtheme</p></li>';
|
||||
$content = preg_replace(
|
||||
'/(<ul[^>]*class="list-unstyled clearfix skin-list"[^>]*>)/',
|
||||
'$1' . $newItem,
|
||||
$content
|
||||
);
|
||||
}
|
||||
|
||||
if (!($controller == 'index' && $action == 'login')) {
|
||||
$version = config('site.version');
|
||||
$cdnurl = config('site.cdnurl');
|
||||
$html = "<link href='{$cdnurl}/assets/addons/sdtheme/simple.css?v={$version}' rel='stylesheet'>";
|
||||
|
||||
$content = preg_replace(
|
||||
'/<!--\[if lt IE 9\]>(.*?)<!\[endif\]-->/is',
|
||||
$html,
|
||||
$content
|
||||
);
|
||||
|
||||
$content = preg_replace(
|
||||
'/(<body[^>]*class=")([^"]*)(")/',
|
||||
'$1$2 sdtheme-body $3',
|
||||
$content
|
||||
);
|
||||
|
||||
$content = preg_replace(
|
||||
'/(<[^>]+class="[^"]*)\btable-bordered\b([^>]*>)/',
|
||||
'$1 table-bordered fixed-table-fast-contaner $2',
|
||||
$content
|
||||
);
|
||||
|
||||
$content = preg_replace(
|
||||
'/(<form[^>]*id="add-form"[^>]*class="[^"]*)/',
|
||||
'$1 form-valiator ',
|
||||
$content
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件安装方法
|
||||
* @return bool
|
||||
*/
|
||||
public function install()
|
||||
{
|
||||
$menu=[];
|
||||
$config_file= ADDON_PATH ."sdtheme" . DS.'config'.DS. "menu.php";
|
||||
if (is_file($config_file)) {
|
||||
$menu = include $config_file;
|
||||
}
|
||||
if($menu){
|
||||
Menu::create($menu);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件卸载方法
|
||||
* @return bool
|
||||
*/
|
||||
public function uninstall()
|
||||
{
|
||||
$info=get_addon_info('sdtheme');
|
||||
Menu::delete(isset($info['first_menu'])?$info['first_menu']:'sdtheme');
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件启用方法
|
||||
*/
|
||||
public function enable()
|
||||
{
|
||||
$info=get_addon_info('sdtheme');
|
||||
Menu::enable(isset($info['first_menu'])?$info['first_menu']:'sdtheme');
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件禁用方法
|
||||
*/
|
||||
public function disable()
|
||||
{
|
||||
$info=get_addon_info('sdtheme');
|
||||
Menu::disable(isset($info['first_menu'])?$info['first_menu']:'sdtheme');
|
||||
}
|
||||
}
|
||||
18
addons/sdtheme/bootstrap.js
vendored
普通文件
18
addons/sdtheme/bootstrap.js
vendored
普通文件
@@ -0,0 +1,18 @@
|
||||
/*require.config({
|
||||
paths: {
|
||||
},
|
||||
shim: {
|
||||
}
|
||||
});*/
|
||||
|
||||
|
||||
require([], function (undefined) {
|
||||
// 后台切换主题,先直接刷新
|
||||
if (Config.modulename == 'admin' && Config.controllername == 'index' && Config.actionname == 'index') {
|
||||
$('.skin-list .clearfix.full-opacity-hover').on('click', function () {
|
||||
setTimeout(() => {
|
||||
location.reload();
|
||||
}, 100)
|
||||
})
|
||||
}
|
||||
});
|
||||
16
addons/sdtheme/config.php
普通文件
16
addons/sdtheme/config.php
普通文件
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
return array (
|
||||
0 =>
|
||||
array (
|
||||
'name' => 'error_page_jump',
|
||||
'type' => 'radio',
|
||||
'title' => '跳转提示页样式',
|
||||
'value' => '1',
|
||||
'content' =>
|
||||
array (
|
||||
1 => '新样式',
|
||||
0 => '原样式',
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
return array (
|
||||
'table_name' => '',
|
||||
'self_path' => '',
|
||||
'update_data' => '',
|
||||
);
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
* 菜单配置文件
|
||||
*/
|
||||
|
||||
return array (
|
||||
);
|
||||
11
addons/sdtheme/info.ini
普通文件
11
addons/sdtheme/info.ini
普通文件
@@ -0,0 +1,11 @@
|
||||
name = sdtheme
|
||||
title = 简约后台主题插件
|
||||
intro = 后台页面新的主题风格,简约现代化风格主题
|
||||
author = 风雨
|
||||
website =
|
||||
version = 1.1.0
|
||||
state = 1
|
||||
url = /addons/sdtheme
|
||||
first_menu = sdtheme
|
||||
license = regular
|
||||
licenseto = 26425
|
||||
@@ -0,0 +1,223 @@
|
||||
{__NOLAYOUT__}<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>{:__('Warning')}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<link rel="shortcut icon" href="__CDN__/assets/img/favicon.ico" />
|
||||
<style type="text/css">
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
|
||||
background-size: 200% 200%;
|
||||
animation: gradientBG 15s ease infinite;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
body {
|
||||
padding: 20px;
|
||||
}
|
||||
@keyframes gradientBG {
|
||||
0% { background-position: 0% 50%; }
|
||||
50% { background-position: 100% 50%; }
|
||||
100% { background-position: 0% 50%; }
|
||||
}
|
||||
.box {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 24px;
|
||||
box-shadow: 0 25px 80px rgba(0,0,0,0.25), 0 0 0 1px rgba(255,255,255,0.2) inset;
|
||||
width: 100%;
|
||||
max-width: 440px;
|
||||
padding: 52px 44px;
|
||||
text-align: center;
|
||||
backdrop-filter: blur(20px);
|
||||
animation: slideUp 0.5s ease-out;
|
||||
}
|
||||
@keyframes slideUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
.icon {
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
margin: 0 auto 28px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 40px;
|
||||
font-weight: bold;
|
||||
animation: scaleIn 0.5s ease-out 0.2s both;
|
||||
}
|
||||
@keyframes scaleIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.5);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
.icon-success {
|
||||
background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%);
|
||||
color: #155724;
|
||||
box-shadow: 0 8px 24px rgba(21, 87, 36, 0.2);
|
||||
}
|
||||
.icon-error {
|
||||
background: linear-gradient(135deg, #f8d7da 0%, #f5c6cb 100%);
|
||||
color: #721c24;
|
||||
box-shadow: 0 8px 24px rgba(114, 18, 36, 0.2);
|
||||
}
|
||||
.icon-info {
|
||||
background: linear-gradient(135deg, #d1ecf1 0%, #bee5eb 100%);
|
||||
color: #0c5460;
|
||||
box-shadow: 0 8px 24px rgba(12, 84, 96, 0.2);
|
||||
}
|
||||
.msg {
|
||||
font-size: 19px;
|
||||
color: #2d3748;
|
||||
margin-bottom: 20px;
|
||||
line-height: 1.6;
|
||||
word-break: break-all;
|
||||
font-weight: 500;
|
||||
}
|
||||
.timer {
|
||||
font-size: 14px;
|
||||
color: #718096;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.timer b {
|
||||
color: #667eea;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
min-width: 18px;
|
||||
display: inline-block;
|
||||
}
|
||||
.progress-bar {
|
||||
height: 4px;
|
||||
background: #e2e8f0;
|
||||
border-radius: 2px;
|
||||
margin-bottom: 32px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.progress-bar i {
|
||||
display: block;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
|
||||
border-radius: 2px;
|
||||
transition: width 1s linear;
|
||||
}
|
||||
.btns {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
}
|
||||
.btns a {
|
||||
flex: 1;
|
||||
display: block;
|
||||
padding: 15px 0;
|
||||
border-radius: 12px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.btns a::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
|
||||
transition: left 0.5s;
|
||||
}
|
||||
.btns a:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
.btn-back {
|
||||
background: #edf2f7;
|
||||
color: #4a5568;
|
||||
}
|
||||
.btn-back:hover {
|
||||
background: #e2e8f0;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 20px rgba(0,0,0,0.1);
|
||||
}
|
||||
.btn-jump {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
|
||||
}
|
||||
.btn-jump:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 12px 28px rgba(102, 126, 234, 0.5);
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.box { padding: 40px 28px; border-radius: 20px; }
|
||||
.btns { flex-direction: column; }
|
||||
.icon { width: 80px; height: 80px; font-size: 34px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
{php}$iconClass = $code == 1 ? 'icon-success' : ($code == 0 ? 'icon-error' : 'icon-info');{/php}
|
||||
<div class="box">
|
||||
<div class="icon {$iconClass|htmlentities}">
|
||||
{if $code == 1}✓{elseif $code == 0}✕{else}ℹ{/if}
|
||||
</div>
|
||||
<div class="msg">{$msg|htmlentities}</div>
|
||||
{if $url}
|
||||
<div class="timer">
|
||||
{:__('This page will be re-directed in %s seconds', '<b id="wait">' . htmlentities($wait) . '</b>')}
|
||||
</div>
|
||||
<div class="progress-bar">
|
||||
<i id="progress" style="width: 100%"></i>
|
||||
</div>
|
||||
<div class="btns">
|
||||
<a href="__PUBLIC__" class="btn-back">{:__('Go back')}</a>
|
||||
<a id="href" href="{$url|htmlentities}" class="btn-jump">{:__('Jump now')}</a>
|
||||
</div>
|
||||
{else}
|
||||
<div class="btns">
|
||||
<a href="__PUBLIC__" class="btn-jump" style="width: 100%">{:__('Go back')}</a>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{if $url}
|
||||
<script>
|
||||
(function () {
|
||||
var wait = document.getElementById('wait'),
|
||||
href = document.getElementById('href').href,
|
||||
progress = document.getElementById('progress'),
|
||||
total = parseInt(wait.innerHTML),
|
||||
curr = total;
|
||||
var interval = setInterval(function () {
|
||||
curr--;
|
||||
wait.innerHTML = curr;
|
||||
progress.style.width = (curr / total * 100) + '%';
|
||||
if (curr <= 0) {
|
||||
clearInterval(interval);
|
||||
location.href = href;
|
||||
}
|
||||
}, 1000);
|
||||
})();
|
||||
</script>
|
||||
{/if}
|
||||
</body>
|
||||
</html>
|
||||
在新工单中引用
屏蔽一个用户