Compare commits
6 Commits
f8dc645048
...
857bb4ad21
| Author | SHA1 | Date | |
|---|---|---|---|
| 857bb4ad21 | |||
| b3dfb8655b | |||
| 10c1f86708 | |||
| 62a67bf7a0 | |||
| 4dc4932ac7 | |||
| b99c07ef4a |
22
.example.env
22
.example.env
@@ -47,8 +47,8 @@ REFRESH_TOKEN_LIFETIME = 1209600; # 刷新令牌有效期
|
||||
RESOURCE_IMAGES_DOMAIN = http://local.orico.com; # 图片资源服务器地址
|
||||
RESOURCE_VIDEOS_DOMAIN = http://local.orico.com; # 视频资源服务器地址
|
||||
|
||||
# 视图模板规则配置
|
||||
[VIEW_TPL]
|
||||
# 前台视图模板规则配置
|
||||
[INDEX_VIEW_TPL]
|
||||
# 视图目录
|
||||
# query 规则:URL参数 mtpl=1 表示移动端访问
|
||||
# 例如:http://xxxx.com?mtpl=1
|
||||
@@ -63,4 +63,20 @@ RULE_QUERY_VALUE = 1
|
||||
RULE_DOMAIN_SCHEME[] = http
|
||||
RULE_DOMAIN_SCHEME[] = https
|
||||
# domain 规则域名
|
||||
RULE_DOMAIN_HOST = mobile.orico.cn
|
||||
RULE_DOMAIN_HOST = mobile.orico.cn
|
||||
|
||||
# 前台语言检测配置
|
||||
[INDEX_LANG_DETECT]
|
||||
# 是否启用域名检测方式来检测语言
|
||||
DOMAIN_DETECT = true
|
||||
# 域名规则
|
||||
# 格式:域名=语言
|
||||
# 例如:mobile.orico.cn=zh-cn
|
||||
DOMAIN_RULE[] = orico.cn=zh-cn
|
||||
DOMAIN_RULE[] = orico.com.cn=zh-cn
|
||||
DOMAIN_RULE[] = www.orico.cn=zh-cn
|
||||
DOMAIN_RULE[] = www.orico.com.cn=zh-cn
|
||||
DOMAIN_RULE[] = ow.f2b211.com=zh-cn
|
||||
DOMAIN_RULE[] = orico.cc=en-us
|
||||
DOMAIN_RULE[] = www.orico.cc=en-us
|
||||
DOMAIN_RULE[] = ow.us.f2b211.com=en-us
|
||||
|
||||
@@ -194,14 +194,14 @@ if (!function_exists('get_platform')) {
|
||||
} else {
|
||||
// 在非移动端环境,根据配置规则判断是否要显示移动端
|
||||
$view_cfg = $view_cfg = [
|
||||
'rule' => env('VIEW_TPL.RULE', 'query'),
|
||||
'rule' => env('INDEX_VIEW_TPL.RULE', 'query'),
|
||||
'query' => [
|
||||
'name' => env('VIEW_TPL.RULE_QUERY_NAME', 'mtpl'),
|
||||
'value' => env('VIEW_TPL.RULE_QUERY_VALUE', '1'),
|
||||
'name' => env('INDEX_VIEW_TPL.RULE_QUERY_NAME', 'mtpl'),
|
||||
'value' => env('INDEX_VIEW_TPL.RULE_QUERY_VALUE', '1'),
|
||||
],
|
||||
'domain' => [
|
||||
'scheme' => env('VIEW_TPL.RULE_DOMAIN_SCHEME', ['http']),
|
||||
'host' => env('VIEW_TPL.RULE_DOMAIN_HOST'),
|
||||
'scheme' => env('INDEX_VIEW_TPL.RULE_DOMAIN_SCHEME', ['http']),
|
||||
'host' => env('INDEX_VIEW_TPL.RULE_DOMAIN_HOST'),
|
||||
],
|
||||
];
|
||||
if ($view_cfg['rule'] == 'query') {
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
// 这是系统自动生成的middleware定义文件
|
||||
return [
|
||||
// 启用多语言支持
|
||||
think\middleware\LoadLangPack::class,
|
||||
// think\middleware\LoadLangPack::class,
|
||||
app\index\middleware\LoadLangPack::class,
|
||||
// 确认请求来源
|
||||
app\index\middleware\ConfirmRequestFrom::class,
|
||||
];
|
||||
|
||||
39
app/index/middleware/LoadLangPack.php
Normal file
39
app/index/middleware/LoadLangPack.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\index\middleware;
|
||||
|
||||
use think\Request;
|
||||
|
||||
class LoadLangPack extends \think\middleware\LoadLangPack
|
||||
{
|
||||
// 重写检测语言方法
|
||||
protected function detect(Request $request): string
|
||||
{
|
||||
$domain_detect = env('INDEX_LANG_DETECT.DOMAIN_DETECT', false);
|
||||
if ($domain_detect) {
|
||||
$lang = $this->getLangSet($request, env('INDEX_LANG_DETECT.DOMAIN_RULE', []));
|
||||
if ($lang != '') {
|
||||
return $lang;
|
||||
}
|
||||
}
|
||||
|
||||
return parent::detect($request);
|
||||
}
|
||||
|
||||
// 根据请求及规则获取语言
|
||||
private function getLangSet(Request $request, array $rules): string
|
||||
{
|
||||
$map = [];
|
||||
foreach ($rules as $v) {
|
||||
$val = str_replace(',', ',', $v);
|
||||
$item = explode(',', $v);
|
||||
foreach ($item as $val) {
|
||||
$it = explode('=', $val);
|
||||
$map[$it[0]] = $it[1];
|
||||
}
|
||||
}
|
||||
|
||||
return $map[$request->host()] ?? '';
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@
|
||||
<h1 class="helph1">{:lang_i18n('使用教程')}</h1>
|
||||
<div class="nhlp-row">
|
||||
{volist name="article_categorys" id="vo" key="idx"}
|
||||
<div class="nhlpit {gt name='idx' value='6'}nhlpit-w{/gt}">
|
||||
<div class="nhlpit">
|
||||
<div class="nhlptl">
|
||||
<img src="{$vo.icon}" class="bhlpicoimg" />{$vo.name}
|
||||
</div>
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
"topthink/think-cors": "^1.0",
|
||||
"phpoffice/phpspreadsheet": "^3.8",
|
||||
"friendsofsymfony/oauth2-php": "^1.3",
|
||||
"mobiledetect/mobiledetectlib": "4.8.09"
|
||||
"mobiledetect/mobiledetectlib": "4.8.09",
|
||||
"qiniu/php-sdk": "^7.14"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/var-dumper": ">=4.2",
|
||||
|
||||
157
extend/uploader/Qiniu.php
Normal file
157
extend/uploader/Qiniu.php
Normal file
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
namespace uploader;
|
||||
|
||||
use Qiniu\Auth;
|
||||
use Qiniu\Storage\UploadManager;
|
||||
use Qiniu\Storage\BucketManager;
|
||||
|
||||
class QiniuUploader
|
||||
{
|
||||
private $bucket = 'orico-opd';
|
||||
private $accessKey = 'dOsTum4a5qvhPTBbZRPX0pIOU7PZWRX7htKjztms';
|
||||
private $secretKey = 'KFxsGbnErkALFfeGdMa8QWTdodJbamMX0iznLe-q';
|
||||
|
||||
private $rule = [
|
||||
'fileSize' => 1024 * 1024 * 5, // 默认最大上传5M
|
||||
'fileExt' => 'jpeg,jpg,png', // 默认上传文件后缀
|
||||
'fileMime' => 'image/jpeg,image/png,image/gif' // 默认上传文件mime
|
||||
];
|
||||
|
||||
private $dir = true;
|
||||
private $originalName = false;
|
||||
private $pathPrefix = '';
|
||||
private $fileNamePrefix = 'orico';
|
||||
|
||||
static public $domain = 'http://opdfile.f2b211.com/';
|
||||
|
||||
public function __construct($conf = [])
|
||||
{
|
||||
if (!empty($conf['bucket'])) {
|
||||
$this->bucket = $conf['bucket'];
|
||||
}
|
||||
if (!empty($conf['accessKey'])) {
|
||||
$this->accessKey = $conf['accessKey'];
|
||||
}
|
||||
if (!empty($conf['secretKey'])) {
|
||||
$this->secretKey = $conf['secretKey'];
|
||||
}
|
||||
if (!empty($conf['pathPrefix'])) {
|
||||
$this->pathPrefix = trim($conf['pathPrefix'], '/');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成随机字符串
|
||||
*/
|
||||
private function random($length, $type = "string", $convert = "0")
|
||||
{
|
||||
$conf = [
|
||||
'number' => '0123456789',
|
||||
'string' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
'all' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789='
|
||||
];
|
||||
$string = $conf[$type];
|
||||
if (!$string) {
|
||||
$string = $conf['string'];
|
||||
}
|
||||
$strlen = strlen($string) - 1;
|
||||
$char = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$char .= $string[mt_rand(0, $strlen)];
|
||||
}
|
||||
if ($convert > 0) {
|
||||
$res = strtoupper($char);
|
||||
} elseif ($convert == 0) {
|
||||
$res = $char;
|
||||
} elseif ($convert < 0) {
|
||||
$res = strtolower($char);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装文件名
|
||||
*/
|
||||
private function buildFileName()
|
||||
{
|
||||
return $this->fileNamePrefix . time() . substr(time(), -5) . substr(microtime(), 2, 3) . $this->random(8);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传验证规则
|
||||
*/
|
||||
public function validate($rule)
|
||||
{
|
||||
$this->rule = $rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件到七牛云
|
||||
*/
|
||||
public function uploadFile($name)
|
||||
{
|
||||
// 构建鉴权对象
|
||||
$auth = new Auth($this->accessKey, $this->secretKey);
|
||||
|
||||
// 生成上传 Token
|
||||
$token = $auth->uploadToken($this->bucket);
|
||||
|
||||
// 初始化 UploadManager 对象并进行文件的上传。
|
||||
$uploadMgr = new UploadManager();
|
||||
|
||||
$file = request()->file($name);
|
||||
|
||||
$aspectRatio = [];
|
||||
if (!empty($this->rule['aspectRatio'])) {
|
||||
$aspectRatio = $this->rule['aspectRatio'];
|
||||
unset($this->rule['aspectRatio']);
|
||||
}
|
||||
$validate = validate([$name => $this->rule]);
|
||||
if (!$validate->check([$name => $file])) {
|
||||
throw new \Exception($validate->getError());
|
||||
}
|
||||
|
||||
$fileName = $file->getOriginalName(); // 文件原名
|
||||
if (!$this->originalName) {
|
||||
$fileName = $this->buildFileName() . '.' . $file->extension();
|
||||
if (!$this->dir && !empty($this->pathPrefix)) {
|
||||
$fileName = $this->pathPrefix . '/' . $fileName;
|
||||
}
|
||||
}
|
||||
if ($this->dir) {
|
||||
$fileName = date('Y') . '/' . date('m') . '/' . date('d') . '/' . $fileName;
|
||||
if (!empty($this->pathPrefix)) {
|
||||
$fileName = $this->pathPrefix . '/' . $fileName;
|
||||
}
|
||||
}
|
||||
$filePath = $file->getPathname(); // 临时路径
|
||||
if (!empty($aspectRatio)) { // 验证图片宽高
|
||||
list($width, $height, $type, $attr) = getimagesize($file);
|
||||
if ($width != $aspectRatio['width'] || $height != $aspectRatio['height']) {
|
||||
throw new \Exception('图片宽高不符合');
|
||||
}
|
||||
}
|
||||
$fileType = $file->getOriginalMime();
|
||||
list($ret, $err) = $uploadMgr->putFile($token, $fileName, $filePath, null, $fileType, false);
|
||||
|
||||
if ($err !== null) {
|
||||
throw new \Exception($err);
|
||||
} else {
|
||||
return ['hash' => $ret['hash'], 'filename' => $ret['key'], 'remote_url' => self::$domain . $ret['key']];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 上传文件到七牛云
|
||||
*/
|
||||
public function deleteFile($name)
|
||||
{
|
||||
// 构建鉴权对象
|
||||
$auth = new Auth($this->accessKey, $this->secretKey);
|
||||
// 初始化 BucketManager 对象并进行文件的删除。
|
||||
$bucketManager = new BucketManager($auth);
|
||||
$ret = $bucketManager->delete($this->bucket, $name);
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
@@ -1455,3 +1455,91 @@ div{
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="32px"]:before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="32px"]:before {
|
||||
content: "32px"
|
||||
}
|
||||
|
||||
|
||||
/*tab切换样式*/
|
||||
/* 标签页样式 */
|
||||
.quill-tabs {
|
||||
margin: 15px 0;
|
||||
overflow: hidden;
|
||||
border: 1px solid #dddddd;
|
||||
border-radius: 4px;
|
||||
}
|
||||
/* 用伪元素添加图标(可替换为自己的图标) */
|
||||
.ql-tabs::before {
|
||||
font-size: 16px;
|
||||
content: "T";
|
||||
/* 用 emoji 或字体图标 */
|
||||
}
|
||||
.quill-tab-list {
|
||||
display: flex;
|
||||
background-color: #f8f9fa;
|
||||
border-bottom: 1px solid #dddddd;
|
||||
}
|
||||
.quill-tab-list .quill-tab-button {
|
||||
padding: 10px 15px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
border: none;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
.quill-tab-list .quill-tab-button.active {
|
||||
color: #007bff;
|
||||
background-color: white;
|
||||
border-bottom: 2px solid #007bff;
|
||||
}
|
||||
.quill-tab-list .quill-tab-edit-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
margin-left: auto;
|
||||
color: #606266;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
.quill-tab-list .quill-tab-edit-btn:hover {
|
||||
color: #007bff;
|
||||
}
|
||||
.quill-tab-button {
|
||||
padding: 10px 15px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
border: none;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
.quill-tab-button.active {
|
||||
color: #007bff;
|
||||
background-color: white;
|
||||
border-bottom: 2px solid #007bff;
|
||||
}
|
||||
.quill-tab-content-list {
|
||||
padding: 15px;
|
||||
}
|
||||
.quill-tab-content {
|
||||
display: none;
|
||||
}
|
||||
.quill-tab-content.active {
|
||||
display: block;
|
||||
}
|
||||
/* 标签页标题编辑样式 */
|
||||
.tab-title-edit {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.tab-title-edit .title-text {
|
||||
display: inline-block;
|
||||
min-width: 60px;
|
||||
padding: 0 4px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
.tab-title-edit .title-input {
|
||||
width: 100px;
|
||||
margin: -2px 0;
|
||||
/* 与标签对齐 */
|
||||
}
|
||||
Reference in New Issue
Block a user