Compare commits
210 Commits
66da36a907
...
font
| Author | SHA1 | Date | |
|---|---|---|---|
| de87a4b237 | |||
| 32ab01bfb8 | |||
| 30f4f0761a | |||
| df2ccc288c | |||
| d5acd5a025 | |||
| 39cd6137b3 | |||
| 8f03cb8f99 | |||
| 5a1d69a836 | |||
| de0f1f34ce | |||
| 6af605bc6f | |||
| 362a7f5a65 | |||
| dafeb04f65 | |||
| 7b5cac6874 | |||
| 4942e5d78e | |||
| b35f1f9ed4 | |||
| 7a987cd672 | |||
| 7c87ea07ed | |||
| 45aaa0c35e | |||
| 23aed15ada | |||
| 325fab3d27 | |||
| 5c1f4a0a73 | |||
| fa4dcf313a | |||
| 1c098304f9 | |||
| c72cfa2e43 | |||
| fec6dca03d | |||
| fdb673d174 | |||
| 6daac314dd | |||
|
|
9d8e22d270 | ||
|
|
f154f3ddf6 | ||
|
|
2073a27ef7 | ||
|
|
e301fc7e94 | ||
|
|
f9251d944e | ||
|
|
1e6187801d | ||
|
|
346dcebba3 | ||
| ab7b23e5d1 | |||
| 325221bd67 | |||
|
|
721e91dc31 | ||
|
|
12e51c6f46 | ||
|
|
8ba9006173 | ||
|
|
a7d413871b | ||
|
|
ce6a882c17 | ||
|
|
7e7cfeacbc | ||
|
|
e1961d2a83 | ||
|
|
d313617e2b | ||
|
|
f0c82c848f | ||
|
|
f606dc64a5 | ||
|
|
39dc3c4e1a | ||
|
|
52b265f36e | ||
|
|
5f9fb74696 | ||
|
|
b251c78b2f | ||
|
|
2e1c83d46d | ||
|
|
0265cb0629 | ||
|
|
68d66b2925 | ||
|
|
601403bf3e | ||
|
|
bbe2197b38 | ||
|
|
ee955a3674 | ||
|
|
e45df84312 | ||
|
|
4e0891da97 | ||
|
|
f9b895732e | ||
|
|
e72ecd55f4 | ||
|
|
558b418d18 | ||
|
|
78cbc5de6e | ||
|
|
f7b610df72 | ||
|
|
b1522a365b | ||
|
|
48906ec9cd | ||
|
|
b57cb8dfd6 | ||
|
|
7d70c55557 | ||
|
|
4fdda8435d | ||
|
|
7a96809bfe | ||
|
|
62b3e2798f | ||
|
|
bfeac736ea | ||
|
|
74ea50b7e4 | ||
|
|
8a617c06e9 | ||
|
|
efa8acaf12 | ||
|
|
d3ff726e90 | ||
|
|
7880c18e85 | ||
|
|
e80ba5ac7d | ||
| 20b5fd901b | |||
| e38c00f59c | |||
| a18706f7d4 | |||
| 4ff2ee4a76 | |||
| 2ca708fd4a | |||
| 29761f551d | |||
| fdb75e4888 | |||
| 5fde7159e0 | |||
| 6068efa03f | |||
| 738b293ea2 | |||
| a1be105c31 | |||
| 03374856e4 | |||
| f07741ff19 | |||
| c64450d74c | |||
| e462b38ff9 | |||
| b96021d21d | |||
| 12d6fdc3a6 | |||
| cd3f651a2a | |||
| 1e4b416cac | |||
| e38446f3fd | |||
| 06b9d42ae4 | |||
| 99d78069d5 | |||
| 342a3754aa | |||
| 51e9c8ced1 | |||
| b13d481e1e | |||
| da8f204167 | |||
| c1979da1af | |||
| 1802f57906 | |||
| 3fa3b8fb63 | |||
| fb2b1455bc | |||
| cc497b2ebc | |||
| 2b450a2e9c | |||
| e266e89a97 | |||
| 2a94a7ecec | |||
| 9137335ce3 | |||
| b8946f223a | |||
| 3a8440c2b9 | |||
| c2bba7fb56 | |||
| 052570fefa | |||
| 09b1f9f14c | |||
| 37825f88ba | |||
| 1c7434b591 | |||
| 585da730ea | |||
| 2ecc51d8a9 | |||
| ad7148ccfc | |||
| 1e00db6c97 | |||
| 5ed692a672 | |||
| 5f7156470e | |||
| 3aafcd3f3b | |||
| 9b339d6364 | |||
| 09f9bfd301 | |||
| 910a07ea47 | |||
| c27d529b82 | |||
| b6724c0361 | |||
| d4fa15f671 | |||
| 60229ae058 | |||
| 6cf27d8b9c | |||
| 6ba7181e3f | |||
| 4334c2db66 | |||
| d7e93567d9 | |||
| e19ba6a315 | |||
| a8e7ad2430 | |||
| 55c8762255 | |||
| 43a4f5f706 | |||
| c6cff2e97d | |||
| 5d53c26c5c | |||
| 857bb4ad21 | |||
| b3dfb8655b | |||
| 10c1f86708 | |||
| 62a67bf7a0 | |||
| 4dc4932ac7 | |||
| b99c07ef4a | |||
| f8dc645048 | |||
| 051b4ed7e7 | |||
| 142e29f131 | |||
| 7f58f1ff83 | |||
| 5650ccfb87 | |||
| 439c9073b8 | |||
| f78f164326 | |||
| 5fb2abe818 | |||
| 1f3b646495 | |||
| a1ea5c6752 | |||
| beb86140a6 | |||
| 0d442fb63a | |||
| af139f6bf4 | |||
| 1d79ea5186 | |||
| de02e59b0e | |||
| f4fa5afcfa | |||
| 2c40c95794 | |||
| 70534f2a97 | |||
| 4515939fcf | |||
| b16971e6f1 | |||
| 3840206e7c | |||
| ef1f786417 | |||
| 745671bd33 | |||
| a13ea053e3 | |||
| 0725cd779f | |||
| 47caddad60 | |||
| 5db4263f67 | |||
| 9887bd1045 | |||
| 768e1ed786 | |||
| f211f58068 | |||
| e7e7386054 | |||
| 9c7f2d394b | |||
| a1f1716f5c | |||
| 250f78593a | |||
| 2c0b8161a5 | |||
| 83fa83e00d | |||
| 176b25b631 | |||
| 4b2566b762 | |||
| a25f87de9f | |||
| ec6fa7fe77 | |||
| 0ba299ee05 | |||
| d06002d95c | |||
| 1758fb8995 | |||
| 52259d573c | |||
| a680391d86 | |||
| 0e0ed64b38 | |||
| 5221b43c01 | |||
| a373ee7163 | |||
| 07692a2a29 | |||
| 3c7bdd8ac9 | |||
| db3b704d89 | |||
| 6e3e0d59db | |||
| f8884aa736 | |||
| 8e62d95864 | |||
| 7bf88fd578 | |||
| a4330c1216 | |||
| 6c80dbabeb | |||
| e0009fb8fa | |||
| 702e874e08 | |||
| 7e486e463c | |||
| df482bbcdd |
36
.example.env
36
.example.env
@@ -26,6 +26,13 @@ TTL=3600
|
||||
REFRESH_TTL=20160
|
||||
SECRET=b43e6276644ed60e65c50d1b324ba10b
|
||||
|
||||
# 七牛云存储配置
|
||||
[QINIU_CLOUD]
|
||||
BUCKET = orico-official-website
|
||||
BASE_URL = //ow.static.f2b211.com
|
||||
ACCESS_KEY = dOsTum4a5qvhPTBbZRPX0pIOU7PZWRX7htKjztms
|
||||
SECRET_KEY = KFxsGbnErkALFfeGdMa8QWTdodJbamMX0iznLe-q
|
||||
|
||||
# 后台不需要登录的接口
|
||||
[ADMIN_AUTH]
|
||||
WHITE_LIST[] = v1/user/login
|
||||
@@ -47,8 +54,15 @@ REFRESH_TOKEN_LIFETIME = 1209600; # 刷新令牌有效期
|
||||
RESOURCE_IMAGES_DOMAIN = http://local.orico.com; # 图片资源服务器地址
|
||||
RESOURCE_VIDEOS_DOMAIN = http://local.orico.com; # 视频资源服务器地址
|
||||
|
||||
# 视图模板规则配置
|
||||
[VIEW_TPL]
|
||||
# 七牛云存储配置
|
||||
[QINUI]
|
||||
BUCKET = orico
|
||||
BASE_URL = http://local.orico.com
|
||||
ACCESS_KEY = 1234567890
|
||||
SECRET_KEY = 1234567890
|
||||
|
||||
# 前台视图模板规则配置
|
||||
[INDEX_VIEW_TPL]
|
||||
# 视图目录
|
||||
# query 规则:URL参数 mtpl=1 表示移动端访问
|
||||
# 例如:http://xxxx.com?mtpl=1
|
||||
@@ -63,4 +77,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
|
||||
|
||||
26
.gitea/workflows/dev-ci.yaml
Normal file
26
.gitea/workflows/dev-ci.yaml
Normal file
@@ -0,0 +1,26 @@
|
||||
name: Gitea Actions Official-website
|
||||
run-name: Deploy to ${{ inputs.deploy_target }} by @${{ gitea.actor }}
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
|
||||
jobs:
|
||||
deploy-dev:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Setup SSH
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo "${{ secrets.SERVER_SSH_KEY }}" > ~/.ssh/id_rsa
|
||||
chmod 600 ~/.ssh/id_rsa
|
||||
ssh-keyscan -H ${{ secrets.SERVER_HOST }} >> ~/.ssh/known_hosts
|
||||
- name: Deploy application
|
||||
run: |
|
||||
ssh ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }} << 'EOF'
|
||||
set -e
|
||||
cd /www/wwwroot/dev.ow.f2b211.com
|
||||
|
||||
# 拉取最新代码
|
||||
git pull --rebase
|
||||
EOF
|
||||
11
.gitignore
vendored
11
.gitignore
vendored
@@ -7,10 +7,19 @@ Thumbs.db
|
||||
.env.dev
|
||||
.env.local
|
||||
.env.prod
|
||||
.htaccess
|
||||
.user.ini
|
||||
404.html
|
||||
index.html
|
||||
|
||||
public/dist*
|
||||
public/opendoc
|
||||
public/logo.png
|
||||
public/.well-known
|
||||
/.idea
|
||||
/.vscode
|
||||
/.zed
|
||||
/vendor
|
||||
/.settings
|
||||
/.buildpath
|
||||
/.project
|
||||
/.project
|
||||
|
||||
24
.zed/settings.json
Normal file
24
.zed/settings.json
Normal file
@@ -0,0 +1,24 @@
|
||||
// Folder-specific settings
|
||||
//
|
||||
// For a full list of overridable settings, and general information on folder-specific settings,
|
||||
// see the documentation: https://zed.dev/docs/configuring-zed#settings-files
|
||||
{
|
||||
"languages": {
|
||||
"PHP": {
|
||||
"language_servers": ["intelephense","!phpactor"]
|
||||
}
|
||||
},
|
||||
"lsp": {
|
||||
"intelephense": {
|
||||
"initialization_options": {
|
||||
"stubs": [
|
||||
"wordpress",
|
||||
"laravel",
|
||||
"symfony",
|
||||
"codeigniter",
|
||||
"thinkphp"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,18 +99,20 @@ class ReceiveProductSync
|
||||
}
|
||||
|
||||
$category = ProductCategoryModel::language($lang_id)->tcoId($tco_category['id'])->find();
|
||||
$tco_parent = ProductTcoCategoryModel::language($lang_id)->tcoId($tco_category['tco_pid'])->find();
|
||||
if (!empty($tco_parent)) {
|
||||
$parent = ProductCategoryModel::language($lang_id)->tcoId($tco_parent['id'])->find();
|
||||
if ($parent->isEmpty()) {
|
||||
throw new \Exception('产品分类父级不存在');
|
||||
if (!empty($category)) {
|
||||
$tco_parent = ProductTcoCategoryModel::language($lang_id)->tcoId($tco_category['tco_pid'])->find();
|
||||
if (!empty($tco_parent)) {
|
||||
$parent = ProductCategoryModel::language($lang_id)->tcoId($tco_parent['id'])->find();
|
||||
if ($parent->isEmpty()) {
|
||||
throw new \Exception('产品分类父级不存在');
|
||||
}
|
||||
$category['pid'] = $parent['id'];
|
||||
$category['path'] = $parent['path'] . $parent['pid'];
|
||||
$category['level'] = $parent['level'] + 1;
|
||||
}
|
||||
if (!$category->save()) {
|
||||
throw new \Exception('产品分类更新失败');
|
||||
}
|
||||
$category['pid'] = $parent['id'];
|
||||
$category['path'] = $parent['path'] . $parent['pid'];
|
||||
$category['level'] = $parent['level'] + 1;
|
||||
}
|
||||
if (!$category->save($category)) {
|
||||
throw new \Exception('产品分类更新失败');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ class Article
|
||||
private function getExportArticleData()
|
||||
{
|
||||
$server = request()->server();
|
||||
$image_host = $server['REQUEST_SCHEME'] . "://" . $server['SERVER_NAME'] . config('filesystem.disks.public.url') . '/';
|
||||
$image_host = $server['REQUEST_SCHEME'] . "://" . $server['SERVER_NAME'] . '/';
|
||||
$param = request()->param(['title', 'category_id', 'release_time']);
|
||||
$data = ArticleModel::field([
|
||||
'*',
|
||||
@@ -253,7 +253,7 @@ class Article
|
||||
])
|
||||
->bindAttr('category', ['category_name' => 'name'])
|
||||
->each(function ($item) use($image_host) {
|
||||
$item->image = !empty($item->image) ? $image_host . $item->image : '';
|
||||
$item->image = !empty($item->image) ? url_join($image_host, $item->image) : '';
|
||||
return $item;
|
||||
});
|
||||
|
||||
|
||||
@@ -101,6 +101,8 @@ class BannerItem
|
||||
'rel_prod_cate_id',
|
||||
'title',
|
||||
'title_txt_color',
|
||||
'short_title',
|
||||
'short_title_txt_color',
|
||||
'desc',
|
||||
'desc_txt_color',
|
||||
'type',
|
||||
@@ -156,6 +158,8 @@ class BannerItem
|
||||
'rel_prod_cate_id',
|
||||
'title',
|
||||
'title_txt_color',
|
||||
'short_title',
|
||||
'short_title_txt_color',
|
||||
'desc',
|
||||
'desc_txt_color',
|
||||
'type',
|
||||
@@ -208,7 +212,7 @@ class BannerItem
|
||||
Log::error(sprintf('%s:%s %s', $th->getFile(), $th->getLine(), $th->getMessage()));
|
||||
return error('操作失败');
|
||||
}
|
||||
|
||||
|
||||
return success('操作成功');
|
||||
}
|
||||
|
||||
@@ -240,6 +244,7 @@ class BannerItem
|
||||
'banner_name' => '分类名称',
|
||||
'title' => '横幅名称',
|
||||
'title_txt_color' => '横幅名称字体颜色',
|
||||
'short_title' => '横幅简称',
|
||||
'desc' => '描述',
|
||||
'desc_txt_color' => '描述字体颜色',
|
||||
'type' => '前台显示类型',
|
||||
@@ -262,17 +267,16 @@ class BannerItem
|
||||
// 获取导出数据
|
||||
private function getBannerExportData()
|
||||
{
|
||||
$param = request()->param([
|
||||
'title',
|
||||
'banner_id',
|
||||
'created_at'
|
||||
]);
|
||||
$server = request()->server();
|
||||
$image_host = $server['REQUEST_SCHEME'] . "://" . $server['SERVER_NAME'] . '/';
|
||||
$param = request()->param(['title', 'banner_id', 'created_at']);
|
||||
return SysBannerItemModel::alias('item')
|
||||
->field([
|
||||
'item.id',
|
||||
'banner.name' => 'banner_name',
|
||||
'item.title',
|
||||
'item.title_txt_color',
|
||||
'item.short_title',
|
||||
'item.desc',
|
||||
'item.desc_txt_color',
|
||||
'item.type',
|
||||
@@ -311,7 +315,13 @@ class BannerItem
|
||||
}
|
||||
})
|
||||
->order(['item.sort' => 'asc', 'item.id' => 'desc'])
|
||||
->select();
|
||||
->select()
|
||||
->each(function($item) use($image_host) {
|
||||
$item->image = !empty($item->image) ? url_join($image_host, $item->image) : '';
|
||||
$item->extra_image = !empty($item->extra_image) ? url_join($image_host, $item->extra_image) : '';
|
||||
$item->video = !empty($item->video) ? url_join($image_host, $item->video) : '';
|
||||
return $item;
|
||||
});
|
||||
}
|
||||
|
||||
// 删除
|
||||
|
||||
@@ -346,7 +346,7 @@ class Product
|
||||
private function getExportProductData()
|
||||
{
|
||||
$server = request()->server();
|
||||
$image_host = $server['REQUEST_SCHEME'] . "://" . $server['SERVER_NAME'] . config('filesystem.disks.public.url') . '/';
|
||||
$image_host = $server['REQUEST_SCHEME'] . "://" . $server['SERVER_NAME'] . '/';
|
||||
$param = request()->param([
|
||||
'name',
|
||||
'spu',
|
||||
@@ -360,10 +360,10 @@ class Product
|
||||
'spu',
|
||||
'name',
|
||||
'short_name',
|
||||
'CONCAT("' . $image_host . '", `cover_image`)' => 'cover_image',
|
||||
'cover_image',
|
||||
'desc',
|
||||
'CONCAT("' . $image_host . '", `video_img`)' => 'video_img',
|
||||
'CONCAT("' . $image_host . '", `video_url`)' => 'video_url',
|
||||
'video_img',
|
||||
'video_url',
|
||||
'CASE WHEN is_new = 1 THEN "是" ELSE "否" END' => 'is_new',
|
||||
'CASE WHEN is_hot = 1 THEN "是" ELSE "否" END' => 'is_hot',
|
||||
'CASE WHEN is_sale = 1 THEN "是" ELSE "否" END' => 'is_sale',
|
||||
@@ -390,7 +390,18 @@ class Product
|
||||
->order(['id' => 'asc'])
|
||||
->select()
|
||||
->bindAttr('category', ['category_name' => 'name'])
|
||||
->hidden(['category_id', 'category']);
|
||||
->hidden(['category_id', 'category'])
|
||||
->each(function($item) use($image_host) {
|
||||
if (!empty($item["cover_image"])) {
|
||||
$item["cover_image"] = url_join($image_host, $item["cover_image"]);
|
||||
}
|
||||
if (!empty($item["video_img"])) {
|
||||
$item["video_img"] = url_join($image_host, $item["video_img"]);
|
||||
}
|
||||
if (!empty($item["video_url"])) {
|
||||
$item["video_url"] = url_join($image_host, $item["video_url"]);
|
||||
}
|
||||
});
|
||||
|
||||
if (!$products->isEmpty()) {
|
||||
// 产品参数
|
||||
|
||||
@@ -16,8 +16,9 @@ class ProductTcoCategory
|
||||
$param = request()->param(['name']);
|
||||
|
||||
$categorys = ProductTcoCategoryModel::field([
|
||||
'tco_id' => 'id',
|
||||
'tco_pid' => 'pid',
|
||||
'id',
|
||||
'tco_id',
|
||||
'tco_pid',
|
||||
'name',
|
||||
])
|
||||
->withSearch(['name'], [
|
||||
@@ -25,10 +26,10 @@ class ProductTcoCategory
|
||||
])
|
||||
->language(request()->lang_id)
|
||||
->enabled()
|
||||
->order(['id' => 'asc'])
|
||||
->order(['tco_id' => 'asc'])
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
return success('获取成功', array_to_tree($categorys, 0, 'pid', false));
|
||||
return success('获取成功', array_to_tree($categorys, 0, 'tco_pid', false, true, 'tco_id'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,6 +342,18 @@ class System
|
||||
'url' => (string)url('/index/topic/nas/download')
|
||||
]
|
||||
]
|
||||
],
|
||||
[
|
||||
'id' => 8,
|
||||
'name' => '电力品线专题',
|
||||
'url' => '',
|
||||
'children' => [
|
||||
[
|
||||
'id' => 81,
|
||||
'name' => '首页',
|
||||
'url' => (string)url('/index/topic/power_prodline/index')
|
||||
],
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ use app\admin\model\v1\SysAttachmentUploadRecordModel;
|
||||
use Intervention\Image\ImageManager;
|
||||
use Intervention\Image\Typography\FontFactory;
|
||||
use think\facade\Filesystem;
|
||||
use filesystem\Qiniu;
|
||||
|
||||
/**
|
||||
* 文件上传控制器
|
||||
@@ -71,7 +72,7 @@ class Upload
|
||||
// 转换为webp格式
|
||||
$webp = $image->toWebp(75);
|
||||
$root = config('filesystem.disks.image.root');
|
||||
$filename = $param['module'] . '/' . ($name_rule() ?? date('Ymd') . '/' . md5((string)time()) . '.webp');
|
||||
$filename = $param['module'] . '/' . ($name_rule() ? $name_rule()() : date('Ymd') . '/' . md5((string)time() . random_str(8))) . '.webp';
|
||||
$webp->save($this->checkPath($root . '/' . $filename));
|
||||
// 获取webp文件大小
|
||||
$file_size = $webp->size();
|
||||
@@ -153,8 +154,8 @@ class Upload
|
||||
$image_model = new SysImageUploadRecordModel();
|
||||
$image_model->language_id = request()->lang_id;
|
||||
$image_model->module = $param['module'];
|
||||
$image_model->image_path = $filename;
|
||||
$image_model->image_thumb = $thumb_filename;
|
||||
$image_model->image_path = $storage . '/' . $filename;
|
||||
$image_model->image_thumb = $storage . '/' . $thumb_filename;
|
||||
$image_model->file_size = $file_size;
|
||||
$image_model->file_type = $mime_type;
|
||||
$image_model->file_md5 = $filemd5;
|
||||
@@ -165,8 +166,8 @@ class Upload
|
||||
}
|
||||
|
||||
return success('操作成功', [
|
||||
'path' => $storage . '/' . $image_model->image_path,
|
||||
'thumb_path' => $storage . '/' . $image_model->image_thumb,
|
||||
'path' => $image_model->image_path,
|
||||
'thumb_path' => $image_model->image_thumb,
|
||||
'filemd5' => $image_model->file_md5,
|
||||
'filesha1' => $image_model->file_sha1
|
||||
]);
|
||||
@@ -226,6 +227,7 @@ class Upload
|
||||
'filename_keep' => (int)data_get($options, 'filename_keep.value', 0) == 1,
|
||||
'filemd5_unique' => (int)data_get($options, 'filemd5_unique.value', 0) == 1,
|
||||
'filetype_to' => data_get($options, 'filetype_to.value', 'original'),
|
||||
'save_to' => data_get($options, 'save_to.value', 'local'),
|
||||
];
|
||||
}
|
||||
/**
|
||||
@@ -345,20 +347,35 @@ class Upload
|
||||
// 获取视频上传配置
|
||||
list(
|
||||
'filename_keep' => $filename_keep,
|
||||
'filemd5_unique' => $filemd5_unique
|
||||
'filemd5_unique' => $filemd5_unique,
|
||||
'save_to' => $save_to,
|
||||
) = $this->getUploadOptions('upload_video');
|
||||
// 是否需要根据文件MD5值检查文件是否已存在
|
||||
$video = $filemd5_unique ? SysVideoUploadRecordModel::md5($filemd5)->find() : null;
|
||||
if (is_null($video)) {
|
||||
// 保存位置配置 key
|
||||
$disk = 'video';
|
||||
// 检查是否需要保留原文件名
|
||||
$name_rule = fn() => $filename_keep ? $this->filenameGenerator($file) : null;
|
||||
$filename = Filesystem::disk('video')->putFile($param['module'], $file, $name_rule());
|
||||
|
||||
// 保存到七牛云
|
||||
if ($save_to == 'qiniu_cloud') {
|
||||
$disk = 'video_qiniu';
|
||||
$storage = config('filesystem.disks.video_qiniu.path_prefix');
|
||||
}
|
||||
$filename = Filesystem::disk($disk)->putFile($param['module'], $file, $name_rule());
|
||||
|
||||
// 组装视频路径
|
||||
$video_path = $storage . '/' . $filename;
|
||||
if ($save_to == 'qiniu_cloud') {
|
||||
$video_path = Filesystem::disk($disk)->url($filename);
|
||||
}
|
||||
|
||||
// 保存视频
|
||||
$video = new SysVideoUploadRecordModel();
|
||||
$video->language_id = request()->lang_id;
|
||||
$video->module = $param['module'];
|
||||
$video->video_path = $filename;
|
||||
$video->video_path = $video_path;
|
||||
$video->file_size = $file->getSize();
|
||||
$video->file_type = $file->getOriginalMime();
|
||||
$video->file_md5 = $filemd5;
|
||||
@@ -369,7 +386,7 @@ class Upload
|
||||
}
|
||||
|
||||
return success('上传成功', [
|
||||
'path' => $storage . '/' . $video->video_path,
|
||||
'path' => $video->video_path,
|
||||
'file_md5' => $video->file_md5,
|
||||
'file_sha1' => $video->file_sha1
|
||||
]);
|
||||
@@ -399,25 +416,42 @@ class Upload
|
||||
return error($validate->getError());
|
||||
}
|
||||
|
||||
$storage = config('filesystem.disks.public.url');
|
||||
|
||||
$filemd5 = $file->md5();
|
||||
$filesha1 = $file->sha1();
|
||||
|
||||
// 获取附件上传配置
|
||||
list(
|
||||
'filename_keep' => $filename_keep,
|
||||
'filemd5_unique' => $filemd5_unique
|
||||
'filemd5_unique' => $filemd5_unique,
|
||||
'save_to' => $save_to
|
||||
) = $this->getUploadOptions('upload_attachment');
|
||||
// 是否需要根据文件MD5值检查文件是否已存在
|
||||
$attachment = $filemd5_unique ? SysAttachmentUploadRecordModel::md5($filemd5)->find() : null;
|
||||
if (is_null($attachment)) {
|
||||
// 保存位置配置 key
|
||||
$disk = 'public';
|
||||
// 检查是否需要保留原文件名
|
||||
$name_rule = fn() => $filename_keep ? $this->filenameGenerator($file) : null;
|
||||
$filename = Filesystem::disk('public')->putFile('attachments', $file, $name_rule());
|
||||
|
||||
// 保存视频
|
||||
// 保存到七牛云
|
||||
if ($save_to == 'qiniu_cloud') {
|
||||
$disk = 'public_qiniu';
|
||||
$storage = config('filesystem.disks.public_qiniu.path_prefix');
|
||||
}
|
||||
$filename = Filesystem::disk($disk)->putFile('attachments', $file, $name_rule());
|
||||
|
||||
// 组装附件路径
|
||||
$attachment_path = $storage . '/' . $filename;
|
||||
if ($save_to == 'qiniu_cloud') {
|
||||
$attachment_path = Filesystem::disk($disk)->url($filename);
|
||||
}
|
||||
|
||||
// 保存附件
|
||||
$attachment = new SysAttachmentUploadRecordModel();
|
||||
$attachment->language_id = request()->lang_id;
|
||||
$attachment->attachment_path = $filename;
|
||||
$attachment->attachment_path = $attachment_path;
|
||||
$attachment->file_size = $file->getSize();
|
||||
$attachment->file_type = $file->getOriginalMime();
|
||||
$attachment->file_md5 = $filemd5;
|
||||
@@ -427,9 +461,8 @@ class Upload
|
||||
}
|
||||
}
|
||||
|
||||
$storage = config('filesystem.disks.public.url');
|
||||
return success('上传成功', [
|
||||
'path' => $storage . '/' . $attachment->attachment_path,
|
||||
'path' => $attachment->attachment_path,
|
||||
'file_md5' => $attachment->file_md5,
|
||||
'file_sha1' => $attachment->file_sha1
|
||||
]);
|
||||
|
||||
@@ -209,9 +209,6 @@ class Video
|
||||
]);
|
||||
|
||||
$domain = request()->domain();
|
||||
$image_path = Config::get('filesystem.disks.image.url');
|
||||
$video_path = Config::get('filesystem.disks.video.url');
|
||||
|
||||
return VideoModel::withoutField([
|
||||
'language_id',
|
||||
'updated_at',
|
||||
@@ -230,13 +227,9 @@ class Video
|
||||
->select()
|
||||
->bindAttr('category', ['category_name' => 'name'])
|
||||
->hidden(['category_id', 'category'])
|
||||
->each(function ($item) use($domain, $image_path, $video_path) {
|
||||
if (!empty($item->image)) {
|
||||
$item->image = $domain . $image_path . '/' . $item->image;
|
||||
}
|
||||
if (!empty($item->video)) {
|
||||
$item->video = $domain . $video_path . '/' . $item->video;
|
||||
}
|
||||
->each(function ($item) use($domain) {
|
||||
$item->image = !empty($item->image) ? url_join($domain, $item->image) : '';
|
||||
$item->video = !empty($item->video) ? url_join($domain, $item->video) : '';
|
||||
$item->recommend = $item->recommend == 1 ? '是' : '否';
|
||||
$item->status = $item->status == 1 ? '启用' : '禁用';
|
||||
return $item;
|
||||
|
||||
@@ -15,7 +15,7 @@ class SysBannerItemValidate extends Validate
|
||||
*/
|
||||
protected $rule = [
|
||||
'id' => 'require|integer',
|
||||
'banner_id' => 'require|integer',
|
||||
'banner_id' => 'require|integer|gt:0',
|
||||
'title' => 'require|max:256',
|
||||
'title_txt_color' => 'max:7',
|
||||
'desc' => 'max:1024',
|
||||
@@ -25,7 +25,7 @@ class SysBannerItemValidate extends Validate
|
||||
'extra_image' => 'max:255',
|
||||
'video' => 'max:255',
|
||||
'link_to' => 'requireIf:type,image|max:64|in:article,article_category,product,product_category,system_page,custom',
|
||||
'link' => 'max:255',
|
||||
'link' => 'max:510',
|
||||
'sort' => 'integer',
|
||||
'status' => 'in:-1,1'
|
||||
];
|
||||
@@ -41,6 +41,7 @@ class SysBannerItemValidate extends Validate
|
||||
'id.integer' => 'ID必须是整数',
|
||||
'banner_id.require' => '横幅项分类不能为空',
|
||||
'banner_id.integer' => '横幅项分类必须是整数',
|
||||
'banner_id.gt' => '该横幅分类不可选',
|
||||
'title.require' => '名称不能为空',
|
||||
'title.max' => '名称最多不能超过256个字符',
|
||||
'title_txt_color.max' => '名称字体颜色最多不能超过7个字符',
|
||||
@@ -53,7 +54,7 @@ class SysBannerItemValidate extends Validate
|
||||
'link_to.requireIf' => '链接类型不能为空',
|
||||
'link_to.max' => '链接类型最多不能超过64个字符',
|
||||
'link_to.in' => '链接类型必须是article,article_category,product,product_category,system_page,custom中之一',
|
||||
'link.max' => '链接最多不能超过255个字符',
|
||||
'link.max' => '链接最多不能超过512个字符',
|
||||
'sort.integer' => '排序值必须是整数',
|
||||
'status.in' => '状态必须是-1或1'
|
||||
];
|
||||
|
||||
@@ -17,7 +17,7 @@ class VideoValidate extends Validate
|
||||
'id' => 'require|integer',
|
||||
'language_id' => 'require|integer',
|
||||
'category_id' => 'require|integer',
|
||||
'name' => 'require|max:64',
|
||||
'name' => 'require|max:128',
|
||||
'desc' => 'max:512',
|
||||
'image' => 'max:125',
|
||||
'video' => 'max:125',
|
||||
@@ -43,7 +43,7 @@ class VideoValidate extends Validate
|
||||
'category_id.require' => '分类不能为空',
|
||||
'category_id.integer' => '分类参数类型错误',
|
||||
'name.require' => '名称不能为空',
|
||||
'name.max' => '名称不能超过64个字符',
|
||||
'name.max' => '名称不能超过128个字符',
|
||||
'desc.max' => '描述不能超过512个字符',
|
||||
'image.max' => '图片不能超过125个字符',
|
||||
'video.max' => '视频不能超过125个字符',
|
||||
|
||||
42
app/command/OpenApiMgr/AddClient.php
Normal file
42
app/command/OpenApiMgr/AddClient.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\command\OpenApiMgr;
|
||||
|
||||
use oauth\OAuthStorage;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\input\Argument;
|
||||
use think\console\input\Option;
|
||||
use think\console\Output;
|
||||
|
||||
class AddClient extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
// 指令配置
|
||||
$this->setName('OpenApiMgr:AddClient')
|
||||
->addArgument('salt', Argument::OPTIONAL, "开放API的client_secret密钥的盐值")
|
||||
->setDescription('开放API的client管理');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$salt = $input->getArgument('salt');
|
||||
$salt = empty($salt) ? null : trim($salt);
|
||||
|
||||
// 指令输出
|
||||
$oauth = new OAuthStorage($salt);
|
||||
|
||||
$client_id = random_str(13, 'all', 0);
|
||||
$client_secret = random_str(32, 'all', 0);
|
||||
|
||||
$ok = $oauth->addClient($client_id, $client_secret, null);
|
||||
if (!$ok) {
|
||||
$output->writeln("添加失败");
|
||||
return;
|
||||
}
|
||||
|
||||
$output->writeln("添加成功:\nClientID: {$client_id}\nClientSecret: {$client_secret}\n");
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,7 @@ if (!function_exists('array_to_tree')) {
|
||||
* @param bool $keep_pid 是否保留pid
|
||||
* @return array
|
||||
*/
|
||||
function array_to_tree(array $data, int $pid, string $with = 'pid', int|bool $level = 1, bool $keep_pid = true)
|
||||
function array_to_tree(array $data, int $pid, string $with = 'pid', int|bool $level = 1, bool $keep_pid = true, $with_ref = 'id')
|
||||
{
|
||||
$ret = [];
|
||||
foreach ($data as $item) {
|
||||
@@ -93,7 +93,7 @@ if (!function_exists('array_to_tree')) {
|
||||
if ($keep_pid === false) {
|
||||
unset($item[$with]);
|
||||
}
|
||||
$children = array_to_tree($data, $item['id'], $with, $lv, $keep_pid);
|
||||
$children = array_to_tree($data, $item[$with_ref], $with, $lv, $keep_pid, $with_ref);
|
||||
if ($children) {
|
||||
$item['children'] = $children;
|
||||
}
|
||||
@@ -144,4 +144,91 @@ if (!function_exists('thumb')) {
|
||||
|
||||
return mb_substr($url, 0, $idx, 'utf-8') . '_thumb' . mb_substr($url, $idx, $len - $idx, 'utf-8');
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('get_filesystem_url')) {
|
||||
/**
|
||||
* 获取文件系统的访问 URL
|
||||
* @param string $url 文件地址
|
||||
* @param string $disk 磁盘配置 key
|
||||
* @return string
|
||||
*/
|
||||
function get_filesystem_url(string|null $url, string $disk): string
|
||||
{
|
||||
if (is_null($url)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (\think\helper\Str::startsWith($url, ['http://', 'https://', '//'])) {
|
||||
return $url;
|
||||
}
|
||||
if (empty($disk)) {
|
||||
return '';
|
||||
}
|
||||
return \think\facade\Filesystem::disk($disk)->url($url);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('url_filesystem_detect')) {
|
||||
/**
|
||||
* 检测文件地址并根据情况转换为文件系统地址
|
||||
* @param string $url 文件地址
|
||||
* @return string
|
||||
*/
|
||||
function url_filesystem_detect(string|null $url): string
|
||||
{
|
||||
if (is_null($url)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$idx = strrpos($url, '.');
|
||||
if ($idx === false) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
$disks = [
|
||||
'public_qiniu' => '_' . base64_encode('public_qiniu'),
|
||||
'video_qiniu' => '_' . base64_encode('video_qiniu')
|
||||
];
|
||||
foreach ($disks as $disk => $marker) {
|
||||
if (str_ends_with(mb_substr($url, 0, $idx), $marker)) {
|
||||
return get_filesystem_url($url, $disk);
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('url_join')) {
|
||||
/**
|
||||
* 合并URL
|
||||
* @param string $url 基础URL
|
||||
* @param string $path 路径
|
||||
* @param bool $remove_slash 是否移除首尾的斜杠
|
||||
* @return string
|
||||
*/
|
||||
function url_join(string $url, string $path, bool $remove_slash = true): string
|
||||
{
|
||||
if (empty($url)) {
|
||||
return $path;
|
||||
}
|
||||
if (empty($path)) {
|
||||
return $url;
|
||||
}
|
||||
if (\think\helper\Str::startsWith($path, ['http://', 'https://', '//'])) {
|
||||
return $path;
|
||||
}
|
||||
|
||||
if ($remove_slash) {
|
||||
if (str_ends_with($url, '/') && str_starts_with($path, '/')) {
|
||||
return $url . substr($path, 1);
|
||||
}
|
||||
if (!str_ends_with($url, '/') && !str_starts_with($path, '/')) {
|
||||
return $url . '/' . $path;
|
||||
}
|
||||
}
|
||||
|
||||
return $url . $path;
|
||||
}
|
||||
}
|
||||
@@ -17,22 +17,24 @@ class SysBannerItemBaseModel extends BaseModel
|
||||
|
||||
// 字段信息
|
||||
protected $schema = [
|
||||
'id' => 'int',
|
||||
'banner_id' => 'int',
|
||||
'title' => 'string',
|
||||
'title_txt_color' => 'string',
|
||||
'desc' => 'string',
|
||||
'desc_txt_color' => 'string',
|
||||
'type' => 'string',
|
||||
'image' => 'string',
|
||||
'extra_image' => 'string',
|
||||
'video' => 'string',
|
||||
'link_to' => 'string',
|
||||
'link' => 'string',
|
||||
'sort' => 'int',
|
||||
'status' => 'int',
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime'
|
||||
'id' => 'int',
|
||||
'banner_id' => 'int',
|
||||
'title' => 'string',
|
||||
'title_txt_color' => 'string',
|
||||
'short_title' => 'string',
|
||||
'short_title_txt_color' => 'string',
|
||||
'desc' => 'string',
|
||||
'desc_txt_color' => 'string',
|
||||
'type' => 'string',
|
||||
'image' => 'string',
|
||||
'extra_image' => 'string',
|
||||
'video' => 'string',
|
||||
'link_to' => 'string',
|
||||
'link' => 'string',
|
||||
'sort' => 'int',
|
||||
'status' => 'int',
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime'
|
||||
];
|
||||
}
|
||||
|
||||
@@ -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') {
|
||||
|
||||
@@ -21,9 +21,9 @@ class Attachment extends Common
|
||||
{
|
||||
$param = request()->param([
|
||||
'id',
|
||||
'keyword',
|
||||
'page/d' => 1,
|
||||
'size/d' => 12,
|
||||
'keyword' => '',
|
||||
'page/d' => 1,
|
||||
'size/d' => 12,
|
||||
]);
|
||||
|
||||
// 获取附件分类
|
||||
@@ -48,9 +48,9 @@ class Attachment extends Common
|
||||
'support_platform',
|
||||
'attach',
|
||||
])
|
||||
->withSearch(['name'], ['name' => $param['keyword']??null])
|
||||
->withSearch(['name'], ['name' => !empty($param['keyword']) ? trim($param['keyword']) : null])
|
||||
->language($this->lang_id)
|
||||
->category($param['id']??null)
|
||||
->category(!empty($param['id']) ? $param['id'] : $categorys[0]['id']??null)
|
||||
->order(['sort' => 'asc', 'id' => 'desc'])
|
||||
->paginate([
|
||||
'list_rows' => $param['size'],
|
||||
@@ -59,6 +59,16 @@ class Attachment extends Common
|
||||
'id' => $param['id']??null
|
||||
]
|
||||
]);
|
||||
if (!$attachements->isEmpty()) {
|
||||
$attachements->each(function($item) {
|
||||
if (is_array($item->attach)) {
|
||||
$item->attach = array_map(function($v) {
|
||||
$v['file_path'] = url_filesystem_detect($v['file_path']);
|
||||
return $v;
|
||||
}, $item->attach);
|
||||
}
|
||||
});
|
||||
}
|
||||
View::assign('attachements', $attachements);
|
||||
View::assign('page', $attachements->render());
|
||||
|
||||
@@ -109,9 +119,9 @@ class Attachment extends Common
|
||||
'video',
|
||||
'link'
|
||||
])
|
||||
->withSearch(['name'], ['name' => $param['keyword']??null])
|
||||
->withSearch(['name'], ['name' => !empty($param['keyword']) ? trim($param['keyword']) : null])
|
||||
->language($this->lang_id)
|
||||
->category($param['id']??$video_categorys[0]['id']??null)
|
||||
->category(!empty($param['id']) ? $param['id'] : $video_categorys[0]['id']??null)
|
||||
->order(['sort' => 'asc', 'id' => 'desc'])
|
||||
->paginate([
|
||||
'list_rows' => $param['size'],
|
||||
@@ -122,6 +132,9 @@ class Attachment extends Common
|
||||
]);
|
||||
|
||||
if (!$videos->isEmpty()) {
|
||||
$videos->each(function($item) {
|
||||
$item->video = url_filesystem_detect($item->video);
|
||||
});
|
||||
$videos->setCollection($videos->getCollection()->chunk(2));
|
||||
}
|
||||
View::assign('videos', $videos);
|
||||
|
||||
@@ -277,7 +277,7 @@ class Product extends Common
|
||||
'page/d' => 1,
|
||||
'size/d' => 10
|
||||
]);
|
||||
$keywords = $param['keywords'] ?? '';
|
||||
$keywords = !empty($param['keywords']) ? trim($param['keywords']) : '';
|
||||
|
||||
// 关键词搜索
|
||||
$products = ProductModel::field([
|
||||
|
||||
@@ -192,6 +192,8 @@ class TopicNas extends Common
|
||||
{
|
||||
// 获取文章分类及文章数据
|
||||
$parent = ArticleCategoryModel::uniqueLabel('CATEGORY_681182e0a4529')->language($this->lang_id)->value('id');
|
||||
$parent_two = ArticleCategoryModel::parent($parent)->language($this->lang_id)->column('id');//二级分类id
|
||||
array_push($parent_two,$parent);
|
||||
$article_categorys = ArticleCategoryModel::with(['article' => function($query) {
|
||||
$query->field(['id', 'title', 'category_id'])
|
||||
->order(['sort' => 'asc', 'id' => 'desc'])
|
||||
@@ -199,14 +201,48 @@ class TopicNas extends Common
|
||||
}])
|
||||
->field([
|
||||
'id',
|
||||
'pid',
|
||||
'name',
|
||||
'icon'
|
||||
])
|
||||
->language($this->lang_id)
|
||||
->parent($parent)
|
||||
// ->parent($parent)
|
||||
->parentChild($parent_two)
|
||||
->isShow(true)
|
||||
->order(['sort' => 'asc', 'id' => 'desc'])
|
||||
->select();
|
||||
View::assign('article_categorys', $article_categorys);
|
||||
//查询三级分类
|
||||
$article_categorys_new = [];
|
||||
$article_categorys_two = [];
|
||||
// dump($article_categorys->toArray());exit;
|
||||
if (!$article_categorys->isEmpty()) {
|
||||
foreach ($article_categorys->toArray() as $kk=>$vv) {
|
||||
if ( $parent == $vv['pid'] ) {
|
||||
array_push($article_categorys_new,$vv);
|
||||
} else {
|
||||
$article_categorys_two[$vv['pid']][] = $vv;
|
||||
}
|
||||
}
|
||||
if ( !empty($article_categorys_two) ) {
|
||||
foreach ($article_categorys_new as &$vvv) {
|
||||
$articles = $vvv['article'];
|
||||
if ( isset($article_categorys_two[$vvv['id']]) ) {
|
||||
foreach ($article_categorys_two[$vvv['id']] as $v) {
|
||||
foreach ($v['article'] as $av) {
|
||||
if ( count($articles) < 3 ) {
|
||||
array_push($articles,$av);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$vvv['article'] = $articles;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
View::assign('article_categorys', $article_categorys_new);
|
||||
// View::assign('article_categorys', $article_categorys);
|
||||
|
||||
$contacts = [];
|
||||
// 获取banner数据
|
||||
@@ -245,19 +281,46 @@ class TopicNas extends Common
|
||||
|
||||
// 获取文章分类及文章数据
|
||||
$parent = ArticleCategoryModel::uniqueLabel('CATEGORY_681182e0a4529')->language($this->lang_id)->value('id');
|
||||
$parent_two = ArticleCategoryModel::parent($parent)->language($this->lang_id)->column('id');//二级分类id
|
||||
array_push($parent_two,$parent);
|
||||
$article_categorys = ArticleCategoryModel::with(['article' => function ($query) {
|
||||
$query->field(['id', 'title', 'category_id'])->order(['sort' => 'asc', 'id' => 'desc']);
|
||||
}])
|
||||
->field([
|
||||
'id',
|
||||
'pid',
|
||||
'name',
|
||||
'icon'
|
||||
])
|
||||
->language($this->lang_id)
|
||||
->parent($parent)
|
||||
// ->parent($parent)
|
||||
->parentChild($parent_two)
|
||||
->isShow(true)
|
||||
->order(['sort' => 'asc', 'id' => 'desc'])
|
||||
->select();
|
||||
View::assign('article_categorys', $article_categorys);
|
||||
// dump($article_categorys->toArray());exit;
|
||||
//查询三级分类
|
||||
$article_categorys_new = [];
|
||||
$article_categorys_two = [];
|
||||
if (!$article_categorys->isEmpty()) {
|
||||
foreach ($article_categorys->toArray() as $kk=>$vv) {
|
||||
if ( $parent == $vv['pid'] ) {
|
||||
$vv['child'] = '';
|
||||
array_push($article_categorys_new,$vv);
|
||||
} else {
|
||||
$article_categorys_two[$vv['pid']][] = $vv;
|
||||
}
|
||||
}
|
||||
if ( !empty($article_categorys_two) ) {
|
||||
foreach ($article_categorys_new as &$vvv) {
|
||||
$vvv['child'] = isset($article_categorys_two[$vvv['id']])?$article_categorys_two[$vvv['id']]:'';
|
||||
}
|
||||
}
|
||||
}
|
||||
// dump($article_categorys_new);exit;
|
||||
// dump($article_categorys_two);exit;
|
||||
|
||||
View::assign('article_categorys', $article_categorys_new);
|
||||
|
||||
return View::fetch('help_detail');
|
||||
}
|
||||
@@ -315,8 +378,18 @@ class TopicNas extends Common
|
||||
->language($this->lang_id)
|
||||
->where('category_id', 'IN', array_column($categorys, 'id'))
|
||||
->select();
|
||||
//查询上级id
|
||||
$parent_two = ArticleCategoryModel::parentColumn(array_column($categorys, 'id'))->language($this->lang_id)->column('pid','id');//二级分类id
|
||||
$articles_data = $articles->toArray();
|
||||
foreach ($articles_data as &$v) {
|
||||
$v['pid'] = 0;
|
||||
if ( $parent_two[$v['category_id']] !== $parent ) {
|
||||
$v['pid'] = $v['category_id'];
|
||||
$v['category_id'] = $parent_two[$v['category_id']];
|
||||
}
|
||||
}
|
||||
|
||||
return success('success', $articles->toArray());
|
||||
return success('success', $articles_data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
127
app/index/controller/TopicPowerProdline.php
Normal file
127
app/index/controller/TopicPowerProdline.php
Normal file
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\index\controller;
|
||||
|
||||
use app\index\model\SysBannerModel;
|
||||
use think\facade\View;
|
||||
use think\Request;
|
||||
|
||||
/**
|
||||
* 专题 - 电力品线控制器
|
||||
*/
|
||||
class TopicPowerProdline extends Common
|
||||
{
|
||||
/**
|
||||
* 重写控制器初始化
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
// 获取国家/语言列表
|
||||
$languages = $this->getLanguages();
|
||||
// 输出国家/语言列表
|
||||
if (get_platform() == 'mobile') {
|
||||
View::assign('header_languages', $languages);
|
||||
}
|
||||
|
||||
// 获取当前语言
|
||||
$current_language = $this->getCurrentLanguage($languages);
|
||||
if (!empty($current_language)) {
|
||||
$this->lang_id = $current_language['id'];
|
||||
}
|
||||
|
||||
// 获取产品分类
|
||||
$categorys = $this->getProductCategory($this->lang_id);
|
||||
// 输出产品分类
|
||||
View::assign('header_categorys', $categorys);
|
||||
|
||||
// 获取系统配置
|
||||
$configs = $this->getSysConfig($this->lang_id, ['basic', 'contact', 'media']);
|
||||
$this->basic_config = $configs['basic'];
|
||||
// 输出系统配置
|
||||
View::assign('basic_config', $configs['basic']);
|
||||
View::assign('contact_config', $configs['contact']);
|
||||
View::assign('media_config', $configs['media']);
|
||||
|
||||
// 获取底部导航
|
||||
$footer_navigation = $this->getNavigation('NAV_67f60be43df8d', $this->lang_id);
|
||||
// 输出底部导航
|
||||
View::assign('footer_navigation', $footer_navigation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 专题 - 电力品线首页
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$banners = SysBannerModel::with([
|
||||
'items' => function ($query) {
|
||||
$query->withoutField(['sort', 'created_at', 'updated_at', 'deleted_at'])
|
||||
->order(['sort' => 'asc', 'id' => 'desc'])
|
||||
->enabled(true);
|
||||
}
|
||||
])
|
||||
->atPlatform(request()->from)
|
||||
->uniqueLabel([
|
||||
'BANNER_691e729f2428d',
|
||||
'BANNER_691e732e4ad69',
|
||||
'BANNER_691e752d2bbe2',
|
||||
'BANNER_691e75561c4d3',
|
||||
'BANNER_691e75ec9391c',
|
||||
'BANNER_691e7616545bf',
|
||||
'BANNER_691e763fc08f4',
|
||||
'BANNER_691e765a27eba',
|
||||
'BANNER_691e76b6af393',
|
||||
])
|
||||
->language($this->lang_id)
|
||||
->enabled(true)
|
||||
->order(['sort' => 'asc', 'id' => 'desc'])
|
||||
->select();
|
||||
|
||||
$data = [];
|
||||
if (!$banners->isEmpty()) {
|
||||
$banners_map = [];
|
||||
foreach ($banners as $banner) {
|
||||
$banners_map[$banner->unique_label] = $banner;
|
||||
}
|
||||
// 焦点轮播图
|
||||
$focus_image = data_get($banners_map, 'BANNER_691e729f2428d')?->items->toArray();
|
||||
if (!empty($focus_image)) $data['focus_image'] = $focus_image;
|
||||
|
||||
// 分类
|
||||
$category = data_get($banners_map, 'BANNER_691e732e4ad69')?->items->toArray();
|
||||
if (!empty($category)) $data['category'] = $category;
|
||||
|
||||
// 为什么选择奥睿科相关数据
|
||||
$why_choose = data_get($banners_map, 'BANNER_691e752d2bbe2')?->items->toArray();
|
||||
if (!empty($why_choose)) $data['why_choose'] = $why_choose;
|
||||
|
||||
// 差旅充
|
||||
$travel_charger = data_get($banners_map, 'BANNER_691e75561c4d3')?->items->toArray();
|
||||
if (!empty($travel_charger)) $data['travel_charger'] = $travel_charger;
|
||||
|
||||
// 家居充
|
||||
$home_charger = data_get($banners_map, 'BANNER_691e75ec9391c')?->items->toArray();
|
||||
if (!empty($home_charger)) $data['home_charger'] = $home_charger;
|
||||
|
||||
// 桌面充
|
||||
$desktop_charger = data_get($banners_map, 'BANNER_691e7616545bf')?->items->toArray();
|
||||
if (!empty($desktop_charger)) $data['desktop_charger'] = $desktop_charger;
|
||||
|
||||
// 墙充
|
||||
$wall_charger = data_get($banners_map, 'BANNER_691e763fc08f4')?->items->toArray();
|
||||
if (!empty($wall_charger)) $data['wall_charger'] = $wall_charger;
|
||||
|
||||
// 转换器
|
||||
$converter = data_get($banners_map, 'BANNER_691e765a27eba')?->items->toArray();
|
||||
if (!empty($converter)) $data['converter'] = $converter;
|
||||
|
||||
// 底部介绍
|
||||
$footer_info = data_get($banners_map, 'BANNER_691e76b6af393')?->items->toArray();
|
||||
if (!empty($footer_info)) $data['footer_info'] = $footer_info;
|
||||
}
|
||||
View::assign('data', $data);
|
||||
|
||||
return View::fetch('index');
|
||||
}
|
||||
}
|
||||
@@ -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()] ?? '';
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,27 @@ class ArticleCategoryModel extends ArticleCategoryBaseModel
|
||||
$query->where('pid', '=', $parent);
|
||||
}
|
||||
|
||||
// 所属上级分类范围查询
|
||||
public function scopeParentChild($query, $parent)
|
||||
{
|
||||
if (is_array($parent)) {
|
||||
$query->where('pid', 'IN', $parent);
|
||||
return;
|
||||
}
|
||||
$query->where('pid', '=', $parent);
|
||||
}
|
||||
|
||||
// 所属上级分类查询
|
||||
public function scopeParentColumn($query, $parent)
|
||||
{
|
||||
if (is_array($parent)) {
|
||||
$query->where('id', 'IN', $parent);
|
||||
return;
|
||||
}
|
||||
$query->where('id', '=', $parent);
|
||||
}
|
||||
|
||||
|
||||
// 所属子分类范围查询
|
||||
public function scopeChild($query, $id, $merge_self = false)
|
||||
{
|
||||
|
||||
@@ -105,6 +105,12 @@ Route::group('topic', function () {
|
||||
// 专题-Nas软件下载页
|
||||
Route::get('download', 'TopicNas/download');
|
||||
});
|
||||
|
||||
// 专题 - 电力品线
|
||||
Route::group("power_prodline", function() {
|
||||
// 专题 - 电力品线首页
|
||||
Route::get('index', 'TopicPowerProdline/index');
|
||||
});
|
||||
});
|
||||
|
||||
// 数据迁移
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<div class="tabs">
|
||||
{notempty name="video_categorys"}
|
||||
{volist name="video_categorys" id="va"}
|
||||
<a href="{:url('attachment/index', ['id' => $va.id])}"><div class="tabit active">{$va.name}</div></a>
|
||||
<a href="{:url('attachment/video', ['id' => $va.id])}"><div class="tabit active">{$va.name}</div></a>
|
||||
{/volist}
|
||||
{/notempty}
|
||||
</div>
|
||||
|
||||
@@ -22,7 +22,11 @@
|
||||
<a class="href_01">{:lang_i18n('首页')}</a>
|
||||
{volist name="product_categorys" id="ca"}
|
||||
<span class="icon-arrow arrow_address"></span>
|
||||
{eq name="ca.pid" value="0"}
|
||||
<a class="href_02" href="{:url('product/category', ['id' => $ca.id])}">{$ca.name}</a>
|
||||
{else /}
|
||||
<a class="href_02" href="{:url('product/subcategory', ['id' => $ca.id])}">{$ca.name}</a>
|
||||
{/eq}
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -29,12 +29,13 @@
|
||||
{/notempty}
|
||||
<li>
|
||||
<h3>{:lang_i18n('联系方式')}</h3>
|
||||
{notempty name="contact_config.website_email"}
|
||||
<p>{$contact_config.website_email.title}: {$contact_config.website_email.value}</p>
|
||||
{/notempty}
|
||||
{notempty name="contact_config.website_hotline_office_hours"}
|
||||
<p>{$contact_config.website_hotline_office_hours.title}: {$contact_config.website_hotline_office_hours.value}</p>
|
||||
{/notempty}
|
||||
{if condition="!empty($contact_config)"}
|
||||
{volist name="contact_config" id="vo"}
|
||||
{if condition="$vo.type != 'image'"}
|
||||
<p>{$vo.value}</p>
|
||||
{/if}
|
||||
{/volist}
|
||||
{/if}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -22,18 +22,18 @@
|
||||
<div class="headtop">
|
||||
{eq name=":cookie('think_lang')" value="zh-cn"}
|
||||
<a href="{:url('/index/topic/nas/index')}">
|
||||
{else/}
|
||||
<a>
|
||||
{/eq}
|
||||
<img src="__IMAGES__/logo.png" class="logoicoimg">
|
||||
</a>
|
||||
<div style="display: flex;">
|
||||
<img src="__IMAGES__/fenlei.png" class="ssicoimg" id="flico">
|
||||
<img src="__IMAGES__/sousuo.png" class="ssicoimg" id="ssico" style="margin-right:32px">
|
||||
</div>
|
||||
{else/}
|
||||
<a>
|
||||
{/eq}
|
||||
<img src="__IMAGES__/logo.png" class="logoicoimg">
|
||||
</a>
|
||||
<div style="display: flex;">
|
||||
<img src="__IMAGES__/fenlei.png" class="ssicoimg" id="flico">
|
||||
<img src="__IMAGES__/sousuo.png" class="ssicoimg" id="ssico" style="margin-right:32px">
|
||||
</div>
|
||||
</div>
|
||||
<!-- 文章内容 -->
|
||||
<div class="ql-container">
|
||||
<div class="ql-container">
|
||||
<div id="rendered-content" class="nhlp-app-content ql-editor">
|
||||
{$article.content|raw|default=''}
|
||||
</div>
|
||||
@@ -42,7 +42,8 @@
|
||||
<div class="nhlpapp-search">
|
||||
<div class="nhlpappshtop">
|
||||
<div class="nhlpapp-shdiv">
|
||||
<input class="nhlp-ipt" id="search-input" placeholder="{:lang_i18n('请输入搜索关键字,如安装赛博云空间,影视库')}" autocomplete="off">
|
||||
<input class="nhlp-ipt" id="search-input" placeholder="{:lang_i18n('请输入搜索关键字,如安装赛博云空间,影视库')}"
|
||||
autocomplete="off">
|
||||
<img src="__IMAGES__/ssapp.png" class="searchimg">
|
||||
</div>
|
||||
<span class="closetx">{:lang_i18n('取消')}</span>
|
||||
@@ -52,22 +53,44 @@
|
||||
<div class="dropdown" id="dropdown"></div>
|
||||
</div>
|
||||
<!-- 分类文章目录 -->
|
||||
<div class="nhlpapp-pagescate" {:style(['display' => $Request.get.view == 'more' ? 'block' : 'none'])}>
|
||||
<div class="nhlpapp-pagescate" {:style(['display'=> $Request.get.view == 'more' ? 'block' : 'none'])}>
|
||||
<div class="nars-hlpdt-ml">
|
||||
{notempty name="article_categorys"}
|
||||
<div class="nav-tree">
|
||||
|
||||
|
||||
{volist name="article_categorys" id="ac" key="idx"}
|
||||
<div class="categoryhelp">
|
||||
<div class="categoryhelp-title">
|
||||
<div>
|
||||
<img src="__IMAGES__/nars-jt.png" class="arrow {if condition='$ac.id == $Request.get.cid'}rotate{/if}">
|
||||
<img src="__IMAGES__/nars-jt.png"
|
||||
class="arrow {if condition='$ac.id == $Request.get.cid'}rotate{/if}">
|
||||
</div>
|
||||
<span>{$ac.name}</span>
|
||||
</div>
|
||||
<ul class="sub-list" {if condition='$ac.id == $Request.get.cid'}style="display: block;"{/if}>
|
||||
<ul class="sub-list" {if condition='$ac.id == $Request.get.cid' }style="display: block;" {/if}>
|
||||
{volist name="ac.child" id="ad"}
|
||||
<li class="two-mues">
|
||||
<a href="#" class="two-a">
|
||||
<div><img src="__IMAGES__/nars-jt.png"
|
||||
class="arrow {if condition='$ad.id == $Request.get.pid'}rotate{/if}">
|
||||
</div>
|
||||
<span>{$ad.name}</span>
|
||||
</a>
|
||||
<ul class="thress-mues" {if condition='$ad.id == $Request.get.pid' }style="display: block;" {/if}>
|
||||
{volist name="ad.article" id="ae"}
|
||||
<li>
|
||||
<a href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id ,'pid' => $ad.id, 'id' => $ae.id])}"
|
||||
style="margin-left:18%;padding: 0.4rem;">{$ae.title}</a>
|
||||
</li>
|
||||
{/volist}
|
||||
</ul>
|
||||
</li>
|
||||
{/volist}
|
||||
{volist name="ac.article" id="ar"}
|
||||
<li>
|
||||
<a href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id , 'id' => $ar.id])}" style="padding-top: 6px;">
|
||||
<a href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id , 'id' => $ar.id])}"
|
||||
style="padding-top: 6px;">
|
||||
{$ar.title}
|
||||
</a>
|
||||
</li>
|
||||
@@ -75,11 +98,14 @@
|
||||
</ul>
|
||||
</div>
|
||||
{/volist}
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
<!-- 顶部国家选择-->
|
||||
<!-- 顶部国家选择-->
|
||||
<div class="top-country">
|
||||
<div class="mask"></div>
|
||||
<div class="action-sheet">
|
||||
@@ -125,6 +151,17 @@
|
||||
$(this).next('.sub-list').slideToggle();
|
||||
$(this).find('.arrow').toggleClass('rotate');
|
||||
});
|
||||
//分类二三级交互
|
||||
$('.two-a').click(function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation(); // 阻止事件冒泡
|
||||
|
||||
// 切换当前二级菜单的箭头方向
|
||||
$(this).find('.arrow').toggleClass('rotate');
|
||||
|
||||
// 切换对应的三级菜单显示/隐藏
|
||||
$(this).siblings('.thress-mues').slideToggle();
|
||||
});
|
||||
// 点击顶部搜索图标-点击取消关闭
|
||||
$('#ssico').click(function () {
|
||||
$('.nhlpapp-pagescate').hide();
|
||||
@@ -134,10 +171,10 @@
|
||||
$('.nhlpapp-search').hide();
|
||||
});
|
||||
// 顶部国家选择
|
||||
$('.top-country-toggle').click(function(){
|
||||
$('.top-country-toggle').click(function () {
|
||||
$(".mask,.action-sheet").show();
|
||||
})
|
||||
$('.top-country .close-icon').click(function(){
|
||||
$('.top-country .close-icon').click(function () {
|
||||
$(".mask,.action-sheet").hide();
|
||||
})
|
||||
// 搜索
|
||||
@@ -172,6 +209,27 @@
|
||||
})
|
||||
}, 300);
|
||||
});
|
||||
// 英文截断处理
|
||||
// 目标容器:富文本内容所在的元素
|
||||
const contentContainer = $('#rendered-content');
|
||||
|
||||
// 遍历所有包含文本内容的标签(p、h1-h6、strong等)
|
||||
contentContainer.find('*').each(function () {
|
||||
const $element = $(this);
|
||||
const htmlContent = $element.html();
|
||||
|
||||
// 条件1:排除内容仅为一个 的标签(如<p> </p>)
|
||||
if (htmlContent.trim() === ' ') {
|
||||
return; // 不处理,继续下一个元素
|
||||
}
|
||||
|
||||
// 条件2:检查是否包含 且有实际文本内容
|
||||
if (htmlContent.includes(' ')) {
|
||||
// 将所有 替换为普通空格(有效占位符,支持单词完整换行)
|
||||
const newContent = htmlContent.replace(/ /g, ' ');
|
||||
$element.html(newContent);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{/block}
|
||||
740
app/index/view/mobile/topic_power_prodline/index.html
Normal file
740
app/index/view/mobile/topic_power_prodline/index.html
Normal file
@@ -0,0 +1,740 @@
|
||||
{extend name="public/base" /}
|
||||
{block name="style"}
|
||||
<link rel="stylesheet" href="__CSS__/topic_power_prodline/index.css">
|
||||
<link rel="stylesheet" href="__CSS__/topic_power_prodline/swiper.css">
|
||||
<link rel="stylesheet" href="__CSS__/topic_power_prodline/nav.css">
|
||||
<link rel="stylesheet" href="__CSS__/topic_power_prodline/advantage.css">
|
||||
<link rel="stylesheet" href="__CSS__/topic_power_prodline/mask.css">
|
||||
<link rel="stylesheet" href="__CSS__/topic_power_prodline/product.css">
|
||||
<link rel="stylesheet" href="__CSS__/topic_power_prodline/product_list.css">
|
||||
<link rel="stylesheet" href="__CSS__/topic_power_prodline/product_card.css">
|
||||
<link rel="stylesheet" href="__CSS__/topic_power_prodline/footer.css">
|
||||
{/block}
|
||||
{block name="header"}
|
||||
<!-- 重置header头为空 -->
|
||||
{/block}
|
||||
{block name="main"}
|
||||
<a class="header" href="/">
|
||||
<div class="header-img">
|
||||
<img src="__IMAGES__/logo.png" alt="">
|
||||
</div>
|
||||
</a>
|
||||
<!-- 轮播核心容器 -->
|
||||
<div class="swiper-container auto-swiper-container" >
|
||||
{notempty name="data.focus_image"}
|
||||
<div class="swiper-wrapper">
|
||||
{volist name="data.focus_image" id="fo"}
|
||||
<a class="swiper-slide auto-swiper-slide" href="{$fo.link}">
|
||||
<img src="{$fo.image}" alt="{$fo.title}" />
|
||||
</a>
|
||||
{/volist}
|
||||
</div>
|
||||
<div class="swiper-pagination"></div>
|
||||
{/notempty}
|
||||
</div>
|
||||
<!-- 分类 -->
|
||||
{notempty name="data.category"}
|
||||
<div class="nav-box">
|
||||
{volist name="data.category" id="ca"}
|
||||
<a class="nav-item" href="{$ca.link}">
|
||||
<img src="{$ca.image}" alt="{$ca.title}">
|
||||
<p {:style(['color'=>$ca.title_txt_color])}>{$ca.title}</p>
|
||||
</a>
|
||||
{/volist}
|
||||
</div>
|
||||
{/notempty}
|
||||
<!-- 500万 -->
|
||||
{notempty name="data.why_choose"}
|
||||
<div class="advantage-section">
|
||||
{assign name="why_choose_title" value=":array_shift($data.why_choose)" /}
|
||||
<h2 class="advantage-section__title">{$why_choose_title.title|default=''|raw}</h2>
|
||||
<div class="advantage-section__list">
|
||||
{volist name="data.why_choose" id="ch"}
|
||||
<div class="advantage-card-wrap">
|
||||
<div class="advantage-card" data-target="design">
|
||||
<img src="{$ch.image}" alt="{$ch.title}:{$ch.short_title}" class="advantage-card__img">
|
||||
<div class="advantage-card__content">
|
||||
<!-- 标题+箭头容器:水平+垂直双居中,内部文字左、箭头右 -->
|
||||
<div class="advantage-card__heading-wrap">
|
||||
<div class="advantage-card__heading" {:style(['color'=>$ch.title_txt_color])}>{$ch.title}</div>
|
||||
<img src="__IMAGES__/jiant.png" alt="" class="card-arrow">
|
||||
</div>
|
||||
<div class="advantage-card__description" {:style(['color'=>$ch.short_title_txt_color])}>{$ch.short_title}</div>
|
||||
<div style="display:none;" class="mack-conten-text">{$ch.desc|raw}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
{/notempty}
|
||||
<!-- 产品差旅充 -->
|
||||
{notempty name="data.travel_charger"}
|
||||
<div class="product-box">
|
||||
{assign name="tc_title" value=":array_shift($data.travel_charger)" /}
|
||||
<div class="product-title">
|
||||
<h2 class="product-title-h2">{$tc_title.title|default=''}</h2>
|
||||
<p class="product-title-p">{$tc_title.short_title|default=''}</p>
|
||||
</div>
|
||||
<div class="product-container" >
|
||||
{assign name="tc_first_section_lf" value=":array_shift($data.travel_charger)" /}
|
||||
{notempty name="tc_first_section_lf"}
|
||||
<a class="product-left" href="{$tc_first_section_lf.link}">
|
||||
<img src="{$tc_first_section_lf.image}" alt="{$tc_first_section_lf.title}" class="product-img">
|
||||
<!-- 公共类+定位类:尺寸统一,定位不同 -->
|
||||
<div class="product-img-hover product-img-1">
|
||||
<img src="{$tc_first_section_lf.extra_image}" alt="{$tc_first_section_lf.short_title}">
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
{assign name="tc_first_section_lr" value=":array_shift($data.travel_charger)" /}
|
||||
{notempty name="tc_first_section_lr"}
|
||||
<div class="product-right">
|
||||
<img src="{$tc_first_section_lr.image}" alt="{$tc_first_section_lr.title}" class="right-content right-img">
|
||||
<video src="{$tc_first_section_lr.video}" class="right-content right-video" muted loop playsinline>
|
||||
您的浏览器不支持HTML5视频播放,请升级浏览器
|
||||
</video>
|
||||
<button class="video-play-btn">
|
||||
<span class="play-icon">
|
||||
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
|
||||
<path d="M9 7L16 12L9 17V7Z" fill="white" />
|
||||
</svg>
|
||||
</span>
|
||||
<!-- 暂停图标(默认隐藏) -->
|
||||
<span class="pause-icon">
|
||||
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
|
||||
<rect x="8" y="7" width="3" height="10" fill="white" />
|
||||
<rect x="13" y="7" width="3" height="10" fill="white" />
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
{/notempty}
|
||||
</div>
|
||||
{assign name="tc_second_section" value=":array_splice($data.travel_charger, 0, 4)" /}
|
||||
{notempty name="tc_second_section"}
|
||||
<div class="product-card-box">
|
||||
<div class="product-card-container">
|
||||
{volist name="tc_second_section" id="tss"}
|
||||
<a class="product-card-wrap" href="{$tss.link}">
|
||||
<div class="product-card" >
|
||||
<div class="product-card-img">
|
||||
<img src="{$tss.image}" alt="{$tss.title}">
|
||||
</div>
|
||||
<div class="product-card-text">
|
||||
<div class="product-card-title" {:style(['color'=>$tss.title_txt_color])}>{$tss.title}</div>
|
||||
<div class="product-card-desc" {:style(['color'=>$tss.short_title_txt_color])}>{$tss.short_title}</div>
|
||||
</div>
|
||||
<div class="product-card-link">
|
||||
<img src="__IMAGES__/ljgd.png" alt="查看更多">
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
{assign name="tc_three_section" value=":array_shift($data.travel_charger)" /}
|
||||
{notempty name="tc_three_section"}
|
||||
<a href="{$tc_three_section.link}" class="more">
|
||||
<div class="more-img">
|
||||
{$tc_three_section.title}
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
{/notempty}
|
||||
</div>
|
||||
{/notempty}
|
||||
<!-- 产品 家居充-->
|
||||
{notempty name="data.home_charger"}
|
||||
<div class="product-box">
|
||||
{assign name="hc_title" value=":array_shift($data.home_charger)" /}
|
||||
<div class="product-title">
|
||||
<h2 class="product-title-h2">{$hc_title.title|default=''}</h2>
|
||||
<p class="product-title-p">{$hc_title.short_title|default=''}</p>
|
||||
</div>
|
||||
<div class="product-container">
|
||||
{assign name="hc_first_section_lf" value=":array_shift($data.home_charger)" /}
|
||||
{notempty name="hc_first_section_lf"}
|
||||
<a class="product-left" href="{$hc_first_section_lf.link}">
|
||||
<img src="{$hc_first_section_lf.image}" alt="{$hc_first_section_lf.title}" class="product-img">
|
||||
<!-- 公共类+定位类:尺寸统一,定位不同 -->
|
||||
<div class="product-img-hover product-img-1">
|
||||
<img src="{$hc_first_section_lf.extra_image}" alt="{$hc_first_section_lf.short_title}">
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
{assign name="hc_first_section_lr" value=":array_shift($data.home_charger)" /}
|
||||
{notempty name="hc_first_section_lr"}
|
||||
<div class="product-right">
|
||||
<img src="{$hc_first_section_lr.image}" alt="{$hc_first_section_lr.title}" class="right-content right-img">
|
||||
<video src="{$hc_first_section_lr.video}" class="right-content right-video" muted loop playsinline >
|
||||
您的浏览器不支持HTML5视频播放,请升级浏览器
|
||||
</video>
|
||||
<button class="video-play-btn">
|
||||
<span class="play-icon">
|
||||
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
|
||||
<path d="M9 7L16 12L9 17V7Z" fill="white" />
|
||||
</svg>
|
||||
</span>
|
||||
<!-- 暂停图标(默认隐藏) -->
|
||||
<span class="pause-icon">
|
||||
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
|
||||
<rect x="8" y="7" width="3" height="10" fill="white" />
|
||||
<rect x="13" y="7" width="3" height="10" fill="white" />
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
{/notempty}
|
||||
</div>
|
||||
{assign name="hc_second_section" value=":array_splice($data.home_charger, 0, 4)" /}
|
||||
{notempty name="hc_second_section"}
|
||||
<div class="product-card-box">
|
||||
<div class="product-card-container">
|
||||
{volist name="hc_second_section" id="hcs"}
|
||||
<a class="product-card-wrap" href="{$hcs.link}">
|
||||
<div class="product-card" href="#">
|
||||
<div class="product-card-img">
|
||||
<img src="{$hcs.image}" alt="{$hcs.short_title}">
|
||||
</div>
|
||||
<div class="product-card-text">
|
||||
<div class="product-card-title">{$hcs.title}</div>
|
||||
<div class="product-card-desc">{$hcs.short_title}</div>
|
||||
</div>
|
||||
<div class="product-card-link">
|
||||
<img src="__IMAGES__/ljgd.png" alt="查看更多">
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
{/notempty}
|
||||
{assign name="hc_three_section" value=":array_shift($data.home_charger)" /}
|
||||
{notempty name="hc_three_section"}
|
||||
<a href="{$hc_three_section.link}" class="more">
|
||||
<div class="more-img">
|
||||
{$hc_three_section.title}
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
</div>
|
||||
{/notempty}
|
||||
<!-- 产品 桌面充(悬浮图上右超出)底部列表样式不一样(左文右图) -->
|
||||
<div class="product-box">
|
||||
{assign name="dc_title" value=":array_shift($data.desktop_charger)" /}
|
||||
<div class="product-title">
|
||||
<h2 class="product-title-h2">{$dc_title.title|default=''}</h2>
|
||||
<p class="product-title-p">{$dc_title.short_title|default=''}</p>
|
||||
</div>
|
||||
<div class="product-container">
|
||||
{assign name="dc_first_section_lf" value=":array_shift($data.desktop_charger)" /}
|
||||
{notempty name="dc_first_section_lf"}
|
||||
<a class="product-left" href="{$dc_first_section_lf.link}">
|
||||
<img src="{$dc_first_section_lf.image}" alt="{$dc_first_section_lf.short_title}" class="product-img">
|
||||
<!-- 公共类+定位类:尺寸和第一个完全一致,仅定位不同 -->
|
||||
<div class="product-img-hover product-img-2" >
|
||||
<img src="{$dc_first_section_lf.extra_image}" alt="{$dc_first_section_lf.short_title}">
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
{assign name="dc_first_section_lr" value=":array_shift($data.desktop_charger)" /}
|
||||
{notempty name="dc_first_section_lr"}
|
||||
<div class="product-right">
|
||||
<img src="{$dc_first_section_lr.image}"
|
||||
alt="使用场景" class="right-content right-img">
|
||||
<!--muted loop playsinline controls-->
|
||||
<video
|
||||
src="{$dc_first_section_lr.video}"
|
||||
class="right-content right-video" muted loop playsinline >
|
||||
您的浏览器不支持HTML5视频播放,请升级浏览器
|
||||
</video>
|
||||
<button class="video-play-btn">
|
||||
<span class="play-icon">
|
||||
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
|
||||
<path d="M9 7L16 12L9 17V7Z" fill="white" />
|
||||
</svg>
|
||||
</span>
|
||||
<!-- 暂停图标(默认隐藏) -->
|
||||
<span class="pause-icon">
|
||||
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
|
||||
<rect x="8" y="7" width="3" height="10" fill="white" />
|
||||
<rect x="13" y="7" width="3" height="10" fill="white" />
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
{/notempty}
|
||||
</div>
|
||||
{assign name="dc_second_section" value=":array_splice($data.desktop_charger, 0, 2)" /}
|
||||
{notempty name="dc_second_section"}
|
||||
<div class="product-card-box">
|
||||
<div class="product-card-container2">
|
||||
{volist name="dc_second_section" id="dcs"}
|
||||
<a class="product-card2" href="{$dcs.link}">
|
||||
<div class="product-text2">
|
||||
<!-- 新增内部容器,确保所有内容左对齐一致性 -->
|
||||
<div class="product-text-content2">
|
||||
<div class="product-card-title2">{$dcs.title}</div> <!-- 测试超出一行省略 -->
|
||||
<div class="product-card-desc2">{$dcs.short_title}</div> <!-- 测试超出2行省略 -->
|
||||
<div class="product-card-link2">
|
||||
<img src="__IMAGES__/ljgd.png" alt="了解更多">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="product-card-img2">
|
||||
<img src="{$dcs.image}" alt="{$dcs.title}">
|
||||
</div>
|
||||
</a>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
{/notempty}
|
||||
{assign name="dc_three_section" value=":array_shift($data.desktop_charger)" /}
|
||||
{notempty name="dc_three_section"}
|
||||
<a href="{$dc_three_section.link}" class="more">
|
||||
<div class="more-img">
|
||||
{$dc_three_section.title}
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
</div>
|
||||
<!-- 墙插 -->
|
||||
{notempty name="data.wall_charger"}
|
||||
<div class="product-box">
|
||||
{assign name="wc_title" value=":array_shift($data.wall_charger)" /}
|
||||
<div class="product-title">
|
||||
<h2 class="product-title-h2">{$wc_title.title|default=''}</h2>
|
||||
<p class="product-title-p">{$wc_title.short_title|default=''}</p>
|
||||
</div>
|
||||
<div class="product-container">
|
||||
{assign name="wc_first_section_lf" value=":array_shift($data.wall_charger)" /}
|
||||
{notempty name="wc_first_section_lf"}
|
||||
<a class="product-left" href="{$wc_first_section_lf.link}">
|
||||
<img src="{$wc_first_section_lf.image}" alt="{$wc_first_section_lf.title}" class="product-img">
|
||||
<!-- 公共类+定位类:尺寸统一,定位不同 -->
|
||||
<div class="product-img-hover product-img-1">
|
||||
<img src="{$wc_first_section_lf.extra_image}" alt="{$wc_first_section_lf.title}">
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
{assign name="wc_first_section_lr" value=":array_shift($data.wall_charger)" /}
|
||||
{notempty name="wc_first_section_lr"}
|
||||
<div class="product-right">
|
||||
<img src="{$wc_first_section_lr.image}" alt="{$wc_first_section_lr.title}" class="right-content right-img">
|
||||
<video src="{$wc_first_section_lr.video}" class="right-content right-video" muted loop playsinline>
|
||||
您的浏览器不支持HTML5视频播放,请升级浏览器
|
||||
</video>
|
||||
<button class="video-play-btn">
|
||||
<span class="play-icon">
|
||||
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
|
||||
<path d="M9 7L16 12L9 17V7Z" fill="white" />
|
||||
</svg>
|
||||
</span>
|
||||
<!-- 暂停图标(默认隐藏) -->
|
||||
<span class="pause-icon">
|
||||
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
|
||||
<rect x="8" y="7" width="3" height="10" fill="white" />
|
||||
<rect x="13" y="7" width="3" height="10" fill="white" />
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
{/notempty}
|
||||
</div>
|
||||
{assign name="wc_more_section" value=":array_shift($data.wall_charger)" /}
|
||||
{notempty name="wc_more_section"}
|
||||
<a href="{$wc_more_section.link}" class="more">
|
||||
<div class="more-img">
|
||||
{$wc_more_section.title}
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
</div>
|
||||
{/notempty}
|
||||
{notempty name="data.converter"}
|
||||
<!-- 转换器 -->
|
||||
<div class="product-box">
|
||||
{assign name="ct_title" value=":array_shift($data.converter)" /}
|
||||
<div class="product-title">
|
||||
<h2 class="product-title-h2">{$ct_title.title|default=''}</h2>
|
||||
<p class="product-title-p">{$ct_title.short_title|default=''}</p>
|
||||
</div>
|
||||
{assign name="ct_more_section" value=":array_pop($data.converter)" /}
|
||||
{assign name="ct_chunk_section" value=":array_chunk($data.converter, 2)" /}
|
||||
{assign name="ct_chunk_section_len" value=":count($ct_chunk_section)" /}
|
||||
{volist name="ct_chunk_section" id="cts" key="k"}
|
||||
<div class="product-container">
|
||||
{assign name="cts_lf" value=":array_shift($cts)" /}
|
||||
{notempty name="cts_lf"}
|
||||
<a class="product-left" href="{$cts_lf.link}">
|
||||
<img src="{$cts_lf.image}" alt="{$cts_lf.title}" class="product-img">
|
||||
<!-- 公共类+定位类:尺寸统一,定位不同 -->
|
||||
<!--style="display:flex;justify-content: center;"-->
|
||||
<div class="product-img-hover product-img-1" >
|
||||
<!-- style="width:70%"-->
|
||||
<img src="{$cts_lf.extra_image}" alt="{$cts_lf.title}">
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
{assign name="cts_lr" value=":array_shift($cts)" /}
|
||||
{notempty name="cts_lr"}
|
||||
<div class="product-right">
|
||||
<img src="{$cts_lr.image}" alt="{$cts_lr.title}" class="right-content right-img">
|
||||
<video src="{$cts_lr.video}" class="right-content right-video" muted loop playsinline>
|
||||
您的浏览器不支持HTML5视频播放,请升级浏览器
|
||||
</video>
|
||||
<!-- 播放图标 -->
|
||||
<button class="video-play-btn">
|
||||
<span class="play-icon">
|
||||
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
|
||||
<path d="M9 7L16 12L9 17V7Z" fill="white" />
|
||||
</svg>
|
||||
</span>
|
||||
<!-- 暂停图标(默认隐藏) -->
|
||||
<span class="pause-icon">
|
||||
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
|
||||
<rect x="8" y="7" width="3" height="10" fill="white" />
|
||||
<rect x="13" y="7" width="3" height="10" fill="white" />
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
{/notempty}
|
||||
</div>
|
||||
{neq name="k" value="$ct_chunk_section_len"}
|
||||
<div class="line"></div>
|
||||
{/neq}
|
||||
{/volist}
|
||||
{notempty name="ct_more_section"}
|
||||
<a href="{$ct_more_section.link}" class="more">
|
||||
<div class="more-img">
|
||||
{$ct_more_section.title}
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
</div>
|
||||
{/notempty}
|
||||
{notempty name="data.footer_info"}
|
||||
<!-- 底部 -->
|
||||
<div class="prodline-footer-box">
|
||||
<div class="prodline-footer-box-img">
|
||||
<img src="{$data.footer_info.0.image}" alt="">
|
||||
</div>
|
||||
</div>
|
||||
{/notempty}
|
||||
<!-- 蒙版 -->
|
||||
<div class="mask" id="mask">
|
||||
<div class="mask-content" >
|
||||
<span class="close-btn">×</span>
|
||||
<div class="mask-scroll-content"></div>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
{block name="script"}
|
||||
<script type="text/javascript">
|
||||
let swiper=null;
|
||||
const advantageItems = document.querySelectorAll('.advantage-card');
|
||||
let scrollTop = 0; // 保存页面滚动位置
|
||||
let closeBtnHtml = null; // 关闭按钮元素(全局变量,避免重复创建)
|
||||
const mask = document.getElementById('mask');
|
||||
const maskContent = document.querySelector('.mask-content');
|
||||
const maskScrollContent = document.querySelector('.mask-scroll-content'); // 滚动容器(关键!)
|
||||
const closeBtn = document.querySelector('.close-btn')
|
||||
// 初始化:确保 maskScrollContent 存在于 maskContent 中(避免被清空)
|
||||
if (!maskScrollContent) {
|
||||
// 如果页面没有 mask-scroll-content,动态创建(确保结构稳定)
|
||||
const scrollContent = document.createElement('div');
|
||||
scrollContent.className = 'mask-scroll-content';
|
||||
maskContent.appendChild(scrollContent);
|
||||
}
|
||||
|
||||
function createCloseBtn() {
|
||||
if (closeBtnHtml) {
|
||||
closeBtnHtml.remove();
|
||||
}
|
||||
|
||||
closeBtnHtml = document.createElement('span');
|
||||
closeBtnHtml.className = 'close-btn';
|
||||
closeBtnHtml.innerHTML = '×';
|
||||
|
||||
closeBtnHtml.addEventListener('click', hideMask);
|
||||
|
||||
// 挂载到 maskContent(而非 scrollContent),避免被滚动影响位置
|
||||
maskContent.prepend(closeBtnHtml);
|
||||
}
|
||||
|
||||
function showMask(contentHtml) {
|
||||
// 保存页面滚动位置
|
||||
scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
|
||||
|
||||
// 关键:将内容填充到 scrollContent 中(而非直接替换 maskContent)
|
||||
maskScrollContent.innerHTML = contentHtml;
|
||||
createCloseBtn();
|
||||
|
||||
// 显示蒙版
|
||||
mask.style.display = 'flex';
|
||||
|
||||
// 禁止滚动(复用你的逻辑)
|
||||
document.documentElement.classList.add('no-scroll');
|
||||
document.body.classList.add('no-scroll');
|
||||
document.body.style.top = `-${scrollTop}px`;
|
||||
|
||||
// 额外:打开蒙版时就重置滚动位置(避免残留上次滚动状态)
|
||||
maskScrollContent.scrollTop = 0;
|
||||
}
|
||||
|
||||
function hideMask() {
|
||||
// 关键步骤 1:先重置 scrollContent 的滚动位置(此时元素还未被销毁)
|
||||
maskScrollContent.scrollTop = 0;
|
||||
|
||||
// 关键步骤 2:清空 scrollContent 的内容(而非 maskContent)
|
||||
maskScrollContent.innerHTML = "";
|
||||
|
||||
// 隐藏蒙版
|
||||
mask.style.display = 'none';
|
||||
|
||||
// 恢复滚动(复用你的逻辑)
|
||||
document.documentElement.classList.remove('no-scroll');
|
||||
document.body.classList.remove('no-scroll');
|
||||
document.body.style.top = '';
|
||||
|
||||
// 还原页面滚动位置
|
||||
window.scrollTo(0, scrollTop);
|
||||
|
||||
// 移除关闭按钮(可选,避免残留)
|
||||
if (closeBtnHtml) {
|
||||
closeBtnHtml.remove();
|
||||
closeBtnHtml = null;
|
||||
}
|
||||
}
|
||||
// 点击卡片显示详情
|
||||
advantageItems.forEach((item) => {
|
||||
item.addEventListener('click', (e) => {
|
||||
// 获取当前点击卡片内的.mack-conten-text元素
|
||||
const currentMackContent = e.currentTarget.querySelector('.mack-conten-text');
|
||||
if (currentMackContent) {
|
||||
// 关键修改:获取该元素的子内容(innerHTML 本身就是内部HTML,不含当前元素标签)
|
||||
// 若想更彻底,可遍历子节点拼接内容(兼容特殊场景)
|
||||
let contentHtml = '';
|
||||
Array.from(currentMackContent.childNodes).forEach(child => {
|
||||
// 只保留元素节点和文本节点(过滤空节点)
|
||||
if (child.nodeType === 1 || child.nodeType === 3) {
|
||||
contentHtml += child.outerHTML || child.textContent;
|
||||
}
|
||||
});
|
||||
// 显示蒙版并传入纯净的子内容
|
||||
showMask(contentHtml);
|
||||
}
|
||||
});
|
||||
});
|
||||
// 关闭按钮事件
|
||||
closeBtn.addEventListener('click', hideMask);
|
||||
// 点击蒙版背景关闭(可选)
|
||||
mask.addEventListener('click', (e) => {
|
||||
if (e.target === mask) hideMask();
|
||||
});
|
||||
|
||||
// ESC 键关闭(可选)
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape' && mask.style.display === 'flex') hideMask();
|
||||
});
|
||||
|
||||
// 关键:拦截蒙版的 touchmove 事件,阻止滚动穿透(移动端核心)
|
||||
mask.addEventListener(
|
||||
'touchmove',
|
||||
(e) => {
|
||||
// 只有点击蒙版背景(不是内容区域)才阻止滚动
|
||||
if (e.target === mask) {
|
||||
e.preventDefault(); // 阻止默认触摸滚动行为
|
||||
e.stopPropagation(); // 阻止事件冒泡
|
||||
}
|
||||
},
|
||||
{ passive: false }
|
||||
); // passive: false 必须,否则 preventDefault 无效
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// 初始化所有视频容器
|
||||
function initVideoContainers() {
|
||||
const productRights = document.querySelectorAll('.product-right');
|
||||
// 支持的视频格式
|
||||
const supportedVideoFormats = ['.mp4', '.webm', '.ogg', '.mov', '.avi', '.mkv', '.flv', '.wmv'];
|
||||
productRights.forEach((container, index) => {
|
||||
const video = container.querySelector('.right-video');
|
||||
const btn = container.querySelector('.video-play-btn');
|
||||
const img = container.querySelector('.right-img');
|
||||
if (!video || !btn || !img) return;
|
||||
const videoSrc = video.src.trim()
|
||||
console.log(videoSrc,'=videoSrc=')
|
||||
// 修复:正确检测有效视频地址
|
||||
// 排除空字符串、null、undefined
|
||||
const hasValidVideo = !!videoSrc && videoSrc.trim() !== '' && videoSrc !== 'undefined' && videoSrc !== 'null';
|
||||
|
||||
// 验证视频格式是否有效
|
||||
const isValidFormat = supportedVideoFormats.some(format =>
|
||||
videoSrc.toLowerCase().endsWith(format) ||
|
||||
(videoSrc.includes('?') && videoSrc.toLowerCase().split('?')[0].endsWith(format))
|
||||
);
|
||||
|
||||
// 初始化状态:无视频或格式无效则保持图片显示,永不切换
|
||||
if (!hasValidVideo || !isValidFormat) {
|
||||
img.style.display = 'block';
|
||||
video.style.display = 'none';
|
||||
btn.style.display = 'none';
|
||||
// 绑定空方法,防止调用报错
|
||||
video.switchMedia = function() {};
|
||||
console.log(`容器${index}:无有效视频(src="${videoSrc}"),保持图片显示`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 有有效视频的情况
|
||||
console.log(`容器${index}:有有效视频(src="${videoSrc}"),初始化播放逻辑`);
|
||||
|
||||
// 初始状态
|
||||
video.style.display = 'none';
|
||||
video.pause();
|
||||
img.style.display = 'block';
|
||||
btn.style.display = 'none';
|
||||
btn.style.opacity = '0';
|
||||
|
||||
// 同步状态函数
|
||||
function syncMediaState() {
|
||||
if (img.style.display === 'block') {
|
||||
btn.style.display = 'none';
|
||||
btn.style.opacity = '0';
|
||||
} else {
|
||||
btn.style.display = 'block';
|
||||
btn.style.opacity = '1';
|
||||
btn.classList.toggle('paused', !video.paused && !video.ended);
|
||||
}
|
||||
}
|
||||
|
||||
// 按钮点击事件
|
||||
btn.addEventListener('click', () => {
|
||||
if (video.paused) {
|
||||
video.play().catch(() => syncMediaState());
|
||||
} else {
|
||||
video.pause();
|
||||
}
|
||||
syncMediaState();
|
||||
});
|
||||
|
||||
// 视频事件监听
|
||||
['play', 'pause', 'ended', 'playing', 'waiting'].forEach(event => {
|
||||
video.addEventListener(event, syncMediaState);
|
||||
});
|
||||
|
||||
// 滚动切换函数
|
||||
video.switchMedia = function(showVideo) {
|
||||
// 只处理有有效视频的情况
|
||||
if (showVideo) {
|
||||
img.style.display = 'none';
|
||||
video.style.display = 'block';
|
||||
video.play().catch(() => {
|
||||
console.log(`容器${index}:自动播放失败,需要用户交互`);
|
||||
syncMediaState();
|
||||
});
|
||||
} else {
|
||||
video.pause();
|
||||
img.style.display = 'block';
|
||||
video.style.display = 'none';
|
||||
}
|
||||
syncMediaState();
|
||||
};
|
||||
|
||||
// 初始同步
|
||||
syncMediaState();
|
||||
});
|
||||
}
|
||||
|
||||
// 滚动监听 - 优化版
|
||||
function setupScrollWatcher() {
|
||||
let ticking = false;
|
||||
|
||||
function updateVideoVisibility() {
|
||||
const productRights = document.querySelectorAll('.product-right');
|
||||
|
||||
productRights.forEach(container => {
|
||||
const video = container.querySelector('.right-video');
|
||||
if (!video || !video.switchMedia) return;
|
||||
|
||||
// 检查是否在视口中
|
||||
const rect = container.getBoundingClientRect();
|
||||
const viewHeight = window.innerHeight || document.documentElement.clientHeight;
|
||||
const isInView = rect.top < viewHeight * 0.7 && rect.bottom > viewHeight * 0.3;
|
||||
|
||||
// 只对有有效视频的元素调用switchMedia
|
||||
video.switchMedia(isInView);
|
||||
});
|
||||
|
||||
ticking = false;
|
||||
}
|
||||
|
||||
// 使用requestAnimationFrame优化性能
|
||||
window.addEventListener('scroll', () => {
|
||||
if (!ticking) {
|
||||
requestAnimationFrame(updateVideoVisibility);
|
||||
ticking = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 初始化
|
||||
initVideoContainers();
|
||||
setupScrollWatcher();
|
||||
|
||||
// 初始检查一次
|
||||
setTimeout(() => {
|
||||
const event = new Event('scroll');
|
||||
window.dispatchEvent(event);
|
||||
}, 300);
|
||||
});
|
||||
|
||||
window.onload = function () {
|
||||
if (typeof Swiper === 'undefined') {
|
||||
console.error('Swiper加载失败,请刷新页面重试');
|
||||
return;
|
||||
}
|
||||
|
||||
swiper = new Swiper('.auto-swiper-container', {
|
||||
autoplay: {
|
||||
delay: 3000, // 3秒切换
|
||||
disableOnInteraction: false,
|
||||
},
|
||||
loop: false,
|
||||
slidesPerView: 1,
|
||||
spaceBetween: 0,
|
||||
// 启用分页指示标(核心配置)
|
||||
pagination: {
|
||||
el: '.swiper-pagination', // 对应 HTML 中的指示标容器
|
||||
clickable: true, // 允许点击指示标切换
|
||||
// dynamicBullets: true, // 动态指示标(当前激活放大)
|
||||
//dynamicMainBullets: 3, // 动态模式显示3个核心指示标
|
||||
},
|
||||
navigation: false,
|
||||
scrollbar: false,
|
||||
on: {
|
||||
resize: function () {
|
||||
this.update();
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
window.addEventListener('resize', function () {
|
||||
swiper.update();
|
||||
});
|
||||
|
||||
// 初始化时触发滚动事件,确保状态正确
|
||||
window.dispatchEvent(new Event('scroll'));
|
||||
};
|
||||
</script>
|
||||
{/block}
|
||||
@@ -5,7 +5,7 @@
|
||||
{block name="main"}
|
||||
<div class="orico_Page_achievement">
|
||||
<div class="achievementMain">
|
||||
<img src="__IMAGES__/Achievement.png" class="acvImg" />
|
||||
<img src="__IMAGES__/Achievement.webp" class="acvImg" />
|
||||
<div class="achInfo">
|
||||
<div class="title">{:lang_i18n('ORICO荣耀')}</div>
|
||||
{notempty name="achievement"}
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
<p>{$detail.release_time|date_format_i18n}</p>
|
||||
</div>
|
||||
<!-- 文本渲染-->
|
||||
<div class="blog_content">{$detail.content|raw}</div>
|
||||
<div class="ql-container">
|
||||
<div class="blog_content ql-editor">{$detail.content|raw}</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 评论只显示前面五条--->
|
||||
{notempty name="comments"}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<!-- 搜索 -->
|
||||
<form action="{:url('attachment/index')}" method="get">
|
||||
<div class="search_all">
|
||||
<input type="hidden" name="id" value="{$Request.get.id}" />
|
||||
<input type="hidden" name="id" value="{$Request.get.id??$categorys[0]['id']??''}" />
|
||||
<input type="text" name="keyword" placeholder="{:lang_i18n('搜索')}" />
|
||||
<button class="searchbtn" type="submit"><img src="__IMAGES__/search_blue.png" /></button>
|
||||
</div>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<!-- 搜索 -->
|
||||
<form action="{:url('attachment/video')}" method="get">
|
||||
<div class="search_all">
|
||||
<input type="hidden" name="id" value="{$Request.get.id}" />
|
||||
<input type="hidden" name="id" value="{$Request.get.id??$video_categorys[0]['id']??''}" />
|
||||
<input type="text" name="keyword" placeholder="{:lang_i18n('搜索')}" />
|
||||
<button class="searchbtn" type="submit"><img src="__IMAGES__/search_blue.png" /></button>
|
||||
</div>
|
||||
|
||||
@@ -117,8 +117,8 @@
|
||||
<p class="subtitle" {notempty name="scene.desc_txt_color" }style="color:{$scene.desc_txt_color};" {/notempty}>
|
||||
{$scene.desc|raw}</p>
|
||||
<a class="sceneMore" href="{$scene.link}">{:lang_i18n('了解更多')} ></a> -->
|
||||
<div style="background-image: url('{$scene.image}');" class="sceneimg"></div>
|
||||
</a>
|
||||
<div style="background-image: url('{$scene.image}');" class="sceneimg"></div>
|
||||
</div>
|
||||
{/volist}
|
||||
</div>
|
||||
@@ -129,10 +129,10 @@
|
||||
<span class="otsbtitle">{:lang_i18n('强大功能、简单使用')}</span>
|
||||
<div class="beforeafter ba-slider">
|
||||
<!-- 对比前的图片 -->
|
||||
<img src="__IMAGES__/indeximg1.jpg">
|
||||
<img src="__IMAGES__/indeximg1.webp">
|
||||
<div class="resize">
|
||||
<!-- 对比后的图片 -->
|
||||
<img src="__IMAGES__/indeximg2.jpg">
|
||||
<img src="__IMAGES__/indeximg2.webp">
|
||||
</div>
|
||||
<!-- 可拖动的分隔条 -->
|
||||
<span class="handle"></span>
|
||||
|
||||
@@ -22,7 +22,11 @@
|
||||
<a class="pathname" href="/">{:lang_i18n('首页')}</a>
|
||||
{volist name="product_categorys" id="ca"}
|
||||
<div class="arrow"></div>
|
||||
{eq name="ca.pid" value="0"}
|
||||
<a class="pathname" href="{:url('product/category', ['id' => $ca.id])}">{$ca.name}</a>
|
||||
{else /}
|
||||
<a class="pathname" href="{:url('product/subcategory', ['id' => $ca.id])}">{$ca.name}</a>
|
||||
{/eq}
|
||||
{/volist}
|
||||
</div>
|
||||
<!-- 产品主图切换和参数详情-->
|
||||
@@ -129,8 +133,10 @@
|
||||
{/notempty}
|
||||
</div>
|
||||
<!-- 富文本渲染-->
|
||||
<div class="products_des" id="detail">
|
||||
{$product.detail|default=''|raw}
|
||||
<div class="ql-container">
|
||||
<div class="products_des ql-editor" id="detail">
|
||||
{$product.detail|default=''|raw}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 关联产品 -->
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
{else/}
|
||||
<a href="javascript:void(0);" class="fline">
|
||||
{$vo.value}
|
||||
{/if}
|
||||
{/if}
|
||||
</a>
|
||||
</li>
|
||||
{/volist}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<div class="narshelpCenterPc">
|
||||
<!-- banner-搜索 -->
|
||||
<div class="pagetopbg">
|
||||
<img src="__IMAGES__/nas_help_banner.jpg" class="hpbgimg" />
|
||||
<img src="__IMAGES__/nas_help_banner.webp" class="hpbgimg" />
|
||||
<div class='nhlp-search'>
|
||||
<input class="nhlp-ipt" id="search-input" placeholder="{:lang_i18n('请输入搜索关键字,如安装赛博云空间,影视库')}" autocomplete="off" />
|
||||
<img src="__IMAGES__/nas_help_search.png" class="searchimg" />
|
||||
@@ -26,13 +26,13 @@
|
||||
<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>
|
||||
<div class="nhlp-tx-list">
|
||||
{volist name="vo.article" id="va" key="index"}
|
||||
<a class="txrow" href="{:url('/index/topic/nas/help_detail', ['cid' => $vo.id, 'id' => $va.id])}">
|
||||
<a class="txrow" href="{:url('/index/topic/nas/help_detail', ['pid' => $va.category_id,'cid' => $vo.id, 'id' => $va.id])}">
|
||||
<div class="nhlp-point"></div>
|
||||
<span class="nhlpsp">{$va.title}</span>
|
||||
<span class="narhelpgoimg">
|
||||
@@ -41,7 +41,7 @@
|
||||
</a>
|
||||
{/volist}
|
||||
{if condition="count($vo.article) >= 3"}
|
||||
<a class="ckgdbt" href="{:url('/index/topic/nas/help_detail', ['cid' => $vo.id, 'id' => isset($vo.article[0])?$vo.article[0]['id']:0])}">
|
||||
<a class="ckgdbt" href="{:url('/index/topic/nas/help_detail', ['cid' => $vo.id, 'id' => isset($vo.article[0])?$vo.article[0]['id']:0,'pid' => isset($vo.article[0])?$vo.article[0]['category_id']:0])}">
|
||||
{:lang_i18n('查看更多')} >
|
||||
</a>
|
||||
{/if}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
{extend name="public/nas_base" /}
|
||||
{block name="title"}
|
||||
{notempty name="article.seo_title"}<title>{$article.seo_title}</title>{else /}{__BLOCK__}{/notempty}
|
||||
{notempty name="article.seo_title"}<title>{$article.seo_title}</title>{else /}{__BLOCK__}{/notempty}
|
||||
{/block}
|
||||
{block name="seo"}
|
||||
{notempty name="article.seo_keywords"}
|
||||
<meta name="keywords" content="{$article.seo_keywords}" />
|
||||
<meta name="description" content="{$article.seo_desc}" />
|
||||
{else /}
|
||||
{__BLOCK__}
|
||||
{/notempty}
|
||||
{notempty name="article.seo_keywords"}
|
||||
<meta name="keywords" content="{$article.seo_keywords}" />
|
||||
<meta name="description" content="{$article.seo_desc}" />
|
||||
{else /}
|
||||
{__BLOCK__}
|
||||
{/notempty}
|
||||
{/block}
|
||||
{block name="style"}
|
||||
<link rel="stylesheet" href="__CSS__/topic_nas_help-detail.css"/>
|
||||
<link rel="stylesheet" href="__CSS__/topic_nas_help-detail.css" />
|
||||
{/block}
|
||||
{block name="main"}
|
||||
<div class="orico_Page_index">
|
||||
@@ -32,28 +32,42 @@
|
||||
<div class="nars-hlpdt-ml">
|
||||
{notempty name="article_categorys"}
|
||||
<div class="nav-tree">
|
||||
|
||||
<!-- start 三级菜单 -->
|
||||
{volist name="article_categorys" id="ac"}
|
||||
<div class="category">
|
||||
<!-- 一级 -->
|
||||
<div class="category-title">
|
||||
<div class="arrow {if condition='$ac.id == $Request.get.cid'}rotate{/if}">
|
||||
<img src="__IMAGES__/nas-jt.png" class="arrow {if condition='$ac.id == $Request.get.cid'}rotate{/if}" />
|
||||
</div>
|
||||
<div class="arrow {if condition='$ac.id == $Request.get.cid'}rotate{/if}"><img src="__IMAGES__/nas-jt.png" class="arrow {if condition='$ac.id == $Request.get.cid'}rotate{/if}" /></div>
|
||||
<span>{$ac.name}</span>
|
||||
</div>
|
||||
<ul class="sub-list" {if condition='$ac.id == $Request.get.cid'}style="display: block;"{/if}>
|
||||
{volist name="ac.article" id="ar"}
|
||||
<li>
|
||||
<a
|
||||
href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id, 'id' => $ar.id])}"
|
||||
{eq name="ar.id" value="$Request.get.id"}class="active"{/eq}
|
||||
>
|
||||
{$ar.title}
|
||||
<!-- 二级-->
|
||||
<ul class="sub-list" {if condition='$ac.id == $Request.get.cid' }style="display: block;" {/if}>
|
||||
{volist name="ac.child" id="ad"}
|
||||
<li class="two-mues">
|
||||
<a href="#" class="two-a">
|
||||
<div class="arrow {if condition='$ad.id == $Request.get.pid'}rotate{/if}"><img src="__IMAGES__/nas-jt.png" class="arrow {if condition='$ad.id == $Request.get.pid'}rotate{/if}" /></div>
|
||||
<span>{$ad.name}</span>
|
||||
</a>
|
||||
<ul class="thress-mues" {if condition='$ad.id == $Request.get.pid' }style="display: block;" {/if}>
|
||||
{volist name="ad.article" id="ae"}
|
||||
<li style="margin-left: 30px;"><a href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id,'pid' => $ad.id, 'id' => $ae.id])}" style="padding-top: 6px;" {eq
|
||||
name="ae.id" value="$Request.get.id" }class="active" {/eq}>{$ae.title}</a></li>
|
||||
{/volist}
|
||||
</ul>
|
||||
<!-- 三级-->
|
||||
</li>
|
||||
{/volist}
|
||||
{volist name="ac.article" id="ar"}
|
||||
<li><a href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id, 'id' => $ar.id])}" style="padding-top: 6px;" {eq
|
||||
name="ar.id" value="$Request.get.id" }class="active" {/eq}>{$ar.title}</a></li>
|
||||
{/volist}
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
{/volist}
|
||||
<!-- end 三级菜单 -->
|
||||
|
||||
</div>
|
||||
{/notempty}
|
||||
</div>
|
||||
@@ -75,10 +89,22 @@
|
||||
{block name="script"}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
// 一级菜单点击事件
|
||||
$('.category-title').click(function () {
|
||||
$(this).next('.sub-list').slideToggle();
|
||||
$(this).find('.arrow').toggleClass('rotate');
|
||||
});
|
||||
// 二级菜单点击事件
|
||||
$('.two-a').click(function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation(); // 阻止事件冒泡
|
||||
|
||||
// 切换当前二级菜单的箭头方向
|
||||
$(this).find('.arrow').toggleClass('rotate');
|
||||
|
||||
// 切换对应的三级菜单显示/隐藏
|
||||
$(this).siblings('.thress-mues').slideToggle();
|
||||
});
|
||||
// 搜索
|
||||
$(document).on('click', function (e) {
|
||||
var target = $(e.target);
|
||||
@@ -109,7 +135,7 @@
|
||||
html = '<ul>'
|
||||
$.each(r.data, function (k, v) {
|
||||
html +=
|
||||
'<li><a href="{:url(\'/index/topic/nas/help_detail\')}?cid=' + v.category_id + '&id=' + v.id + '">' + v.title + '</a></li>'
|
||||
'<li><a href="{:url(\'/index/topic/nas/help_detail\')}?cid=' + v.category_id + '&id=' + v.id + '&pid=' + v.pid + '">' + v.title + '</a></li>'
|
||||
})
|
||||
html += '</ul>'
|
||||
}
|
||||
@@ -121,21 +147,27 @@
|
||||
// 内容
|
||||
// 清空标题列表
|
||||
$("#title-list ul").empty();
|
||||
// 提取 h1 标题
|
||||
// 提取 h3 标题
|
||||
var h1Titles = $("#rendered-content").find("h3");
|
||||
h1Titles.each(function (index) {
|
||||
var title = $(this);
|
||||
var titleText = title.text();
|
||||
var titleId = "title-" + index;
|
||||
title.attr("id", titleId);
|
||||
var listItem = $("<li>");
|
||||
var link = $("<a>", {
|
||||
href: "#" + titleId,
|
||||
text: titleText
|
||||
// 只有当找到h3标题且内容不为空时才进行处理
|
||||
if (h1Titles.length > 0) {
|
||||
h1Titles.each(function (index) {
|
||||
var title = $(this);
|
||||
var titleText = title.text().trim(); // 使用trim()去除空白字符
|
||||
// 只有当标题文本不为空时才添加到列表
|
||||
if (titleText) {
|
||||
var titleId = "title-" + index;
|
||||
title.attr("id", titleId);
|
||||
var listItem = $("<li>");
|
||||
var link = $("<a>", {
|
||||
href: "#" + titleId,
|
||||
text: titleText
|
||||
});
|
||||
listItem.append(link);
|
||||
$("#title-list ul").append(listItem);
|
||||
}
|
||||
});
|
||||
listItem.append(link);
|
||||
$("#title-list ul").append(listItem);
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{/block}
|
||||
581
app/index/view/pc/topic_power_prodline/index.html
Normal file
581
app/index/view/pc/topic_power_prodline/index.html
Normal file
@@ -0,0 +1,581 @@
|
||||
{extend name="public/nas_base" /}
|
||||
{block name="style"}
|
||||
<link rel="stylesheet" href="__CSS__/topic_power_prodline/index.css">
|
||||
<link rel="stylesheet" href="__CSS__/topic_power_prodline/swiper.css">
|
||||
<link rel="stylesheet" href="__CSS__/topic_power_prodline/nav.css">
|
||||
<link rel="stylesheet" href="__CSS__/topic_power_prodline/advantage.css">
|
||||
<link rel="stylesheet" href="__CSS__/topic_power_prodline/mask.css">
|
||||
<link rel="stylesheet" href="__CSS__/topic_power_prodline/product.css">
|
||||
<link rel="stylesheet" href="__CSS__/topic_power_prodline/product_list.css">
|
||||
<link rel="stylesheet" href="__CSS__/topic_power_prodline/product_card.css">
|
||||
<link rel="stylesheet" href="__CSS__/topic_power_prodline/footer.css">
|
||||
{/block}
|
||||
{block name="header"}
|
||||
<!-- 重置header头为空 -->
|
||||
{/block}
|
||||
{block name="main"}
|
||||
<a class="header" href="/">
|
||||
<div class="header-img">
|
||||
<img src="__IMAGES__/logo.png" alt="">
|
||||
</div>
|
||||
</a>
|
||||
<!-- 轮播核心容器 -->
|
||||
<div class="swiper-container auto-swiper-container" >
|
||||
{notempty name="data.focus_image"}
|
||||
<div class="swiper-wrapper">
|
||||
{volist name="data.focus_image" id="fo"}
|
||||
<a class="swiper-slide auto-swiper-slide" href="{$fo.link}">
|
||||
<img src="{$fo.image}" alt="{$fo.title}" />
|
||||
</a>
|
||||
{/volist}
|
||||
</div>
|
||||
<div class="swiper-pagination"></div>
|
||||
{/notempty}
|
||||
</div>
|
||||
<!-- 分类 -->
|
||||
{notempty name="data.category"}
|
||||
<div class="nav-box">
|
||||
{volist name="data.category" id="ca"}
|
||||
<a class="nav-item" href="{$ca.link}">
|
||||
<img src="{$ca.image}" alt="{$ca.title}">
|
||||
<p {:style(['color'=>$ca.title_txt_color])}>{$ca.title}</p>
|
||||
</a>
|
||||
{/volist}
|
||||
</div>
|
||||
{/notempty}
|
||||
<!-- 500万 -->
|
||||
{notempty name="data.why_choose"}
|
||||
<div class="advantage-section">
|
||||
{assign name="why_choose_title" value=":array_shift($data.why_choose)" /}
|
||||
<h2 class="advantage-section__title">{$why_choose_title.title|default=''|raw}</h2>
|
||||
<div class="advantage-section__list">
|
||||
{volist name="data.why_choose" id="ch"}
|
||||
<div class="advantage-card-wrap">
|
||||
<div class="advantage-card" data-target="design">
|
||||
<img src="{$ch.image}" alt="{$ch.title}:{$ch.short_title}" class="advantage-card__img">
|
||||
<div class="advantage-card__content">
|
||||
<!-- 标题+箭头容器:水平+垂直双居中,内部文字左、箭头右 -->
|
||||
<div class="advantage-card__heading-wrap">
|
||||
<div class="advantage-card__heading" {:style(['color'=>$ch.title_txt_color])}>{$ch.title}</div>
|
||||
<img src="__IMAGES__/jiant.png" alt="" class="card-arrow">
|
||||
</div>
|
||||
<div class="advantage-card__description" {:style(['color'=>$ch.short_title_txt_color])}>{$ch.short_title}</div>
|
||||
<div style="display:none;" class="mack-conten-text">{$ch.desc|raw}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
{/notempty}
|
||||
<!-- 产品差旅充 -->
|
||||
{notempty name="data.travel_charger"}
|
||||
<div class="product-box">
|
||||
{assign name="tc_title" value=":array_shift($data.travel_charger)" /}
|
||||
<div class="product-title">
|
||||
<h2 class="product-title-h2">{$tc_title.title|default=''}</h2>
|
||||
<p class="product-title-p">{$tc_title.short_title|default=''}</p>
|
||||
</div>
|
||||
<div class="product-container" >
|
||||
{assign name="tc_first_section_lf" value=":array_shift($data.travel_charger)" /}
|
||||
{notempty name="tc_first_section_lf"}
|
||||
<a class="product-left" href="{$tc_first_section_lf.link}">
|
||||
<img src="{$tc_first_section_lf.image}" alt="{$tc_first_section_lf.title}" class="product-img">
|
||||
<!-- 公共类+定位类:尺寸统一,定位不同 -->
|
||||
<div class="product-img-hover product-img-1">
|
||||
<img src="{$tc_first_section_lf.extra_image}" alt="{$tc_first_section_lf.short_title}">
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
{assign name="tc_first_section_lr" value=":array_shift($data.travel_charger)" /}
|
||||
{notempty name="tc_first_section_lr"}
|
||||
<div class="product-right">
|
||||
<img src="{$tc_first_section_lr.image}" alt="{$tc_first_section_lr.title}" class="right-content right-img">
|
||||
<video src="{$tc_first_section_lr.video}" class="right-content right-video" muted loop playsinline controls>
|
||||
您的浏览器不支持HTML5视频播放,请升级浏览器
|
||||
</video>
|
||||
</div>
|
||||
{/notempty}
|
||||
</div>
|
||||
{assign name="tc_second_section" value=":array_splice($data.travel_charger, 0, 4)" /}
|
||||
{notempty name="tc_second_section"}
|
||||
<div class="product-card-box">
|
||||
<div class="product-card-container">
|
||||
{volist name="tc_second_section" id="tss"}
|
||||
<a class="product-card-wrap" href="{$tss.link}">
|
||||
<div class="product-card" >
|
||||
<div class="product-card-img">
|
||||
<img src="{$tss.image}" alt="{$tss.title}">
|
||||
</div>
|
||||
<div class="product-card-text">
|
||||
<div class="product-card-title" {:style(['color'=>$tss.title_txt_color])}>{$tss.title}</div>
|
||||
<div class="product-card-desc" {:style(['color'=>$tss.short_title_txt_color])}>{$tss.short_title}</div>
|
||||
</div>
|
||||
<div class="product-card-link">
|
||||
<img src="__IMAGES__/ljgd.png" alt="查看更多">
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
{assign name="tc_three_section" value=":array_shift($data.travel_charger)" /}
|
||||
{notempty name="tc_three_section"}
|
||||
<a href="{$tc_three_section.link}" class="more">
|
||||
<div class="more-img">
|
||||
{$tc_three_section.title}
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
{/notempty}
|
||||
</div>
|
||||
{/notempty}
|
||||
<!-- 产品 家居充-->
|
||||
{notempty name="data.home_charger"}
|
||||
<div class="product-box">
|
||||
{assign name="hc_title" value=":array_shift($data.home_charger)" /}
|
||||
<div class="product-title">
|
||||
<h2 class="product-title-h2">{$hc_title.title|default=''}</h2>
|
||||
<p class="product-title-p">{$hc_title.short_title|default=''}</p>
|
||||
</div>
|
||||
<div class="product-container">
|
||||
{assign name="hc_first_section_lf" value=":array_shift($data.home_charger)" /}
|
||||
{notempty name="hc_first_section_lf"}
|
||||
<a class="product-left" href="{$hc_first_section_lf.link}">
|
||||
<img src="{$hc_first_section_lf.image}" alt="{$hc_first_section_lf.title}" class="product-img">
|
||||
<!-- 公共类+定位类:尺寸统一,定位不同 -->
|
||||
<div class="product-img-hover product-img-1">
|
||||
<img src="{$hc_first_section_lf.extra_image}" alt="{$hc_first_section_lf.short_title}">
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
{assign name="hc_first_section_lr" value=":array_shift($data.home_charger)" /}
|
||||
{notempty name="hc_first_section_lr"}
|
||||
<div class="product-right">
|
||||
<img src="{$hc_first_section_lr.image}" alt="{$hc_first_section_lr.title}" class="right-content right-img">
|
||||
<video src="{$hc_first_section_lr.video}" class="right-content right-video" muted loop playsinline controls>
|
||||
您的浏览器不支持HTML5视频播放,请升级浏览器
|
||||
</video>
|
||||
</div>
|
||||
{/notempty}
|
||||
</div>
|
||||
{assign name="hc_second_section" value=":array_splice($data.home_charger, 0, 4)" /}
|
||||
{notempty name="hc_second_section"}
|
||||
<div class="product-card-box">
|
||||
<div class="product-card-container">
|
||||
{volist name="hc_second_section" id="hcs"}
|
||||
<a class="product-card-wrap" href="{$hcs.link}">
|
||||
<div class="product-card" href="#">
|
||||
<div class="product-card-img">
|
||||
<img src="{$hcs.image}" alt="{$hcs.short_title}">
|
||||
</div>
|
||||
<div class="product-card-text">
|
||||
<div class="product-card-title">{$hcs.title}</div>
|
||||
<div class="product-card-desc">{$hcs.short_title}</div>
|
||||
</div>
|
||||
<div class="product-card-link">
|
||||
<img src="__IMAGES__/ljgd.png" alt="查看更多">
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
{/notempty}
|
||||
{assign name="hc_three_section" value=":array_shift($data.home_charger)" /}
|
||||
{notempty name="hc_three_section"}
|
||||
<a href="{$hc_three_section.link}" class="more">
|
||||
<div class="more-img">
|
||||
{$hc_three_section.title}
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
</div>
|
||||
{/notempty}
|
||||
<!-- 产品 桌面充(悬浮图上右超出)底部列表样式不一样(左文右图) -->
|
||||
<div class="product-box">
|
||||
{assign name="dc_title" value=":array_shift($data.desktop_charger)" /}
|
||||
<div class="product-title">
|
||||
<h2 class="product-title-h2">{$dc_title.title|default=''}</h2>
|
||||
<p class="product-title-p">{$dc_title.short_title|default=''}</p>
|
||||
</div>
|
||||
<div class="product-container">
|
||||
{assign name="dc_first_section_lf" value=":array_shift($data.desktop_charger)" /}
|
||||
{notempty name="dc_first_section_lf"}
|
||||
<a class="product-left" href="{$dc_first_section_lf.link}">
|
||||
<img src="{$dc_first_section_lf.image}" alt="{$dc_first_section_lf.short_title}" class="product-img">
|
||||
<!-- 公共类+定位类:尺寸和第一个完全一致,仅定位不同 -->
|
||||
<div class="product-img-hover product-img-2" >
|
||||
<img src="{$dc_first_section_lf.extra_image}" alt="{$dc_first_section_lf.short_title}">
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
{assign name="dc_first_section_lr" value=":array_shift($data.desktop_charger)" /}
|
||||
{notempty name="dc_first_section_lr"}
|
||||
<div class="product-right">
|
||||
<img src="{$dc_first_section_lr.image}"
|
||||
alt="使用场景" class="right-content right-img">
|
||||
<!--muted loop playsinline controls-->
|
||||
<video
|
||||
src="{$dc_first_section_lr.video}"
|
||||
class="right-content right-video" muted loop playsinline controls>
|
||||
您的浏览器不支持HTML5视频播放,请升级浏览器
|
||||
</video>
|
||||
</div>
|
||||
{/notempty}
|
||||
|
||||
</div>
|
||||
{assign name="dc_second_section" value=":array_splice($data.desktop_charger, 0, 2)" /}
|
||||
{notempty name="dc_second_section"}
|
||||
<div class="product-card-box">
|
||||
<div class="product-card-container2">
|
||||
{volist name="dc_second_section" id="dcs"}
|
||||
<a class="product-card2" href="{$dcs.link}">
|
||||
<div class="product-text2">
|
||||
<!-- 新增内部容器,确保所有内容左对齐一致性 -->
|
||||
<div class="product-text-content2">
|
||||
<div class="product-card-title2">{$dcs.title}</div> <!-- 测试超出一行省略 -->
|
||||
<div class="product-card-desc2">{$dcs.short_title}</div> <!-- 测试超出2行省略 -->
|
||||
<div class="product-card-link2">
|
||||
<img src="__IMAGES__/ljgd.png" alt="了解更多">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="product-card-img2">
|
||||
<img src="{$dcs.image}" alt="{$dcs.title}">
|
||||
</div>
|
||||
</a>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
{/notempty}
|
||||
{assign name="dc_three_section" value=":array_shift($data.desktop_charger)" /}
|
||||
{notempty name="dc_three_section"}
|
||||
<a href="{$dc_three_section.link}" class="more">
|
||||
<div class="more-img">
|
||||
{$dc_three_section.title}
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
</div>
|
||||
<!-- 墙插 -->
|
||||
{notempty name="data.wall_charger"}
|
||||
<div class="product-box">
|
||||
{assign name="wc_title" value=":array_shift($data.wall_charger)" /}
|
||||
<div class="product-title">
|
||||
<h2 class="product-title-h2">{$wc_title.title|default=''}</h2>
|
||||
<p class="product-title-p">{$wc_title.short_title|default=''}</p>
|
||||
</div>
|
||||
<div class="product-container">
|
||||
{assign name="wc_first_section_lf" value=":array_shift($data.wall_charger)" /}
|
||||
{notempty name="wc_first_section_lf"}
|
||||
<a class="product-left" href="{$wc_first_section_lf.link}">
|
||||
<img src="{$wc_first_section_lf.image}" alt="{$wc_first_section_lf.title}" class="product-img">
|
||||
<!-- 公共类+定位类:尺寸统一,定位不同 -->
|
||||
<div class="product-img-hover product-img-1">
|
||||
<img src="{$wc_first_section_lf.extra_image}" alt="{$wc_first_section_lf.title}">
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
{assign name="wc_first_section_lr" value=":array_shift($data.wall_charger)" /}
|
||||
{notempty name="wc_first_section_lr"}
|
||||
<div class="product-right">
|
||||
<img src="{$wc_first_section_lr.image}" alt="{$wc_first_section_lr.title}" class="right-content right-img">
|
||||
<video src="{$wc_first_section_lr.video}" class="right-content right-video" muted loop playsinline controls>
|
||||
您的浏览器不支持HTML5视频播放,请升级浏览器
|
||||
</video>
|
||||
</div>
|
||||
{/notempty}
|
||||
</div>
|
||||
{assign name="wc_more_section" value=":array_shift($data.wall_charger)" /}
|
||||
{notempty name="wc_more_section"}
|
||||
<a href="{$wc_more_section.link}" class="more">
|
||||
<div class="more-img">
|
||||
{$wc_more_section.title}
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
</div>
|
||||
{/notempty}
|
||||
{notempty name="data.converter"}
|
||||
<!-- 转换器 -->
|
||||
<div class="product-box">
|
||||
{assign name="ct_title" value=":array_shift($data.converter)" /}
|
||||
<div class="product-title">
|
||||
<h2 class="product-title-h2">{$ct_title.title|default=''}</h2>
|
||||
<p class="product-title-p">{$ct_title.short_title|default=''}</p>
|
||||
</div>
|
||||
{assign name="ct_more_section" value=":array_pop($data.converter)" /}
|
||||
{assign name="ct_chunk_section" value=":array_chunk($data.converter, 2)" /}
|
||||
{assign name="ct_chunk_section_len" value=":count($ct_chunk_section)" /}
|
||||
{volist name="ct_chunk_section" id="cts" key="k"}
|
||||
<div class="product-container">
|
||||
{assign name="cts_lf" value=":array_shift($cts)" /}
|
||||
{notempty name="cts_lf"}
|
||||
<a class="product-left" href="{$cts_lf.link}">
|
||||
<img src="{$cts_lf.image}" alt="{$cts_lf.title}" class="product-img">
|
||||
<!-- 公共类+定位类:尺寸统一,定位不同 -->
|
||||
<!--style="display:flex;justify-content: center;"-->
|
||||
<div class="product-img-hover product-img-1" >
|
||||
<!-- style="width:70%"-->
|
||||
<img src="{$cts_lf.extra_image}" alt="{$cts_lf.title}">
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
{assign name="cts_lr" value=":array_shift($cts)" /}
|
||||
{notempty name="cts_lr"}
|
||||
<div class="product-right">
|
||||
<img src="{$cts_lr.image}" alt="{$cts_lr.title}" class="right-content right-img">
|
||||
<video src="{$cts_lr.video}" class="right-content right-video" muted loop playsinline controls>
|
||||
您的浏览器不支持HTML5视频播放,请升级浏览器
|
||||
</video>
|
||||
</div>
|
||||
{/notempty}
|
||||
</div>
|
||||
{neq name="k" value="$ct_chunk_section_len"}
|
||||
<div class="line"></div>
|
||||
{/neq}
|
||||
{/volist}
|
||||
{notempty name="ct_more_section"}
|
||||
<a href="{$ct_more_section.link}" class="more" style="padding: clamp(1.5rem, 3vw, 3rem) 0">
|
||||
<div class="more-img">
|
||||
{$ct_more_section.title}
|
||||
</div>
|
||||
</a>
|
||||
{/notempty}
|
||||
</div>
|
||||
{/notempty}
|
||||
{notempty name="data.footer_info"}
|
||||
<!-- 底部 -->
|
||||
<div class="prodline-footer-box">
|
||||
<div class="prodline-footer-box-img">
|
||||
<img src="{$data.footer_info.0.image}" alt="">
|
||||
</div>
|
||||
</div>
|
||||
{/notempty}
|
||||
<!-- 蒙版 -->
|
||||
<div class="mask" id="mask">
|
||||
<div class="mask-content" >
|
||||
<span class="close-btn">×</span>
|
||||
<div class="mask-scroll-content"></div>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
{block name="script"}
|
||||
<script type="text/javascript">
|
||||
let swiper=null;
|
||||
const advantageItems = document.querySelectorAll('.advantage-card');
|
||||
let scrollTop = 0; // 保存页面滚动位置
|
||||
let closeBtnHtml = null; // 关闭按钮元素(全局变量,避免重复创建)
|
||||
const mask = document.getElementById('mask');
|
||||
const maskContent = document.querySelector('.mask-content');
|
||||
const maskScrollContent = document.querySelector('.mask-scroll-content'); // 滚动容器(关键!)
|
||||
const closeBtn = document.querySelector('.close-btn')
|
||||
// 初始化:确保 maskScrollContent 存在于 maskContent 中(避免被清空)
|
||||
if (!maskScrollContent) {
|
||||
// 如果页面没有 mask-scroll-content,动态创建(确保结构稳定)
|
||||
const scrollContent = document.createElement('div');
|
||||
scrollContent.className = 'mask-scroll-content';
|
||||
maskContent.appendChild(scrollContent);
|
||||
}
|
||||
|
||||
|
||||
function createCloseBtn() {
|
||||
if (closeBtnHtml) {
|
||||
closeBtnHtml.remove();
|
||||
}
|
||||
|
||||
closeBtnHtml = document.createElement('span');
|
||||
closeBtnHtml.className = 'close-btn';
|
||||
closeBtnHtml.innerHTML = '×';
|
||||
|
||||
closeBtnHtml.addEventListener('click', hideMask);
|
||||
|
||||
// 挂载到 maskContent(而非 scrollContent),避免被滚动影响位置
|
||||
maskContent.prepend(closeBtnHtml);
|
||||
}
|
||||
|
||||
function showMask(contentHtml) {
|
||||
// 保存页面滚动位置
|
||||
scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
|
||||
|
||||
// 关键:将内容填充到 scrollContent 中(而非直接替换 maskContent)
|
||||
maskScrollContent.innerHTML = contentHtml;
|
||||
createCloseBtn();
|
||||
|
||||
// 显示蒙版
|
||||
mask.style.display = 'flex';
|
||||
|
||||
// 禁止滚动(复用你的逻辑)
|
||||
document.documentElement.classList.add('no-scroll');
|
||||
document.body.classList.add('no-scroll');
|
||||
document.body.style.top = `-${scrollTop}px`;
|
||||
|
||||
// 额外:打开蒙版时就重置滚动位置(避免残留上次滚动状态)
|
||||
maskScrollContent.scrollTop = 0;
|
||||
}
|
||||
|
||||
function hideMask() {
|
||||
// 关键步骤 1:先重置 scrollContent 的滚动位置(此时元素还未被销毁)
|
||||
maskScrollContent.scrollTop = 0;
|
||||
|
||||
// 关键步骤 2:清空 scrollContent 的内容(而非 maskContent)
|
||||
maskScrollContent.innerHTML = "";
|
||||
|
||||
// 隐藏蒙版
|
||||
mask.style.display = 'none';
|
||||
|
||||
// 恢复滚动(复用你的逻辑)
|
||||
document.documentElement.classList.remove('no-scroll');
|
||||
document.body.classList.remove('no-scroll');
|
||||
document.body.style.top = '';
|
||||
|
||||
// 还原页面滚动位置
|
||||
window.scrollTo(0, scrollTop);
|
||||
|
||||
// 移除关闭按钮(可选,避免残留)
|
||||
if (closeBtnHtml) {
|
||||
closeBtnHtml.remove();
|
||||
closeBtnHtml = null;
|
||||
}
|
||||
}
|
||||
// 点击卡片显示详情
|
||||
advantageItems.forEach((item) => {
|
||||
item.addEventListener('click', (e) => {
|
||||
// 获取当前点击卡片内的.mack-conten-text元素
|
||||
const currentMackContent = e.currentTarget.querySelector('.mack-conten-text');
|
||||
if (currentMackContent) {
|
||||
// 关键修改:获取该元素的子内容(innerHTML 本身就是内部HTML,不含当前元素标签)
|
||||
// 若想更彻底,可遍历子节点拼接内容(兼容特殊场景)
|
||||
let contentHtml = '';
|
||||
Array.from(currentMackContent.childNodes).forEach(child => {
|
||||
// 只保留元素节点和文本节点(过滤空节点)
|
||||
if (child.nodeType === 1 || child.nodeType === 3) {
|
||||
contentHtml += child.outerHTML || child.textContent;
|
||||
}
|
||||
});
|
||||
// 显示蒙版并传入纯净的子内容
|
||||
showMask(contentHtml);
|
||||
}
|
||||
});
|
||||
});
|
||||
// 关闭按钮事件
|
||||
closeBtn.addEventListener('click', hideMask);
|
||||
// 点击蒙版背景关闭(可选)
|
||||
mask.addEventListener('click', (e) => {
|
||||
if (e.target === mask) hideMask();
|
||||
});
|
||||
|
||||
// ESC 键关闭(可选)
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape' && mask.style.display === 'flex') hideMask();
|
||||
});
|
||||
|
||||
// 关键:拦截蒙版的 touchmove 事件,阻止滚动穿透(移动端核心)
|
||||
mask.addEventListener(
|
||||
'touchmove',
|
||||
(e) => {
|
||||
// 只有点击蒙版背景(不是内容区域)才阻止滚动
|
||||
if (e.target === mask) {
|
||||
e.preventDefault(); // 阻止默认触摸滚动行为
|
||||
e.stopPropagation(); // 阻止事件冒泡
|
||||
}
|
||||
},
|
||||
{ passive: false }
|
||||
); // passive: false 必须,否则 preventDefault 无效
|
||||
|
||||
const allVideos = document.querySelectorAll('.right-video');
|
||||
// 停止所有视频播放
|
||||
function stopAllVideos() {
|
||||
allVideos.forEach((video) => {
|
||||
video.pause();
|
||||
video.style.display = 'none';
|
||||
// 显示对应图片
|
||||
const img = video.parentElement.querySelector('.right-img');
|
||||
if (img) img.style.display = 'block';
|
||||
});
|
||||
}
|
||||
|
||||
// 滚动切换图片/视频(核心逻辑)
|
||||
window.addEventListener('scroll', function () {
|
||||
const productRights = document.querySelectorAll('.product-right');
|
||||
let activeVideo = null;
|
||||
// 找出当前在视口中的视频容器
|
||||
productRights.forEach((rightContainer) => {
|
||||
const img = rightContainer.querySelector('.right-img');
|
||||
const video = rightContainer.querySelector('.right-video');
|
||||
const videoSrc = video.src.trim()
|
||||
if (!img || !video) return;
|
||||
if(!videoSrc) return;
|
||||
const rect = rightContainer.getBoundingClientRect();
|
||||
// 视口判断:容器进入视口50%以上视为活跃
|
||||
const isInView =
|
||||
rect.top < window.innerHeight * 0.7 &&
|
||||
rect.bottom > window.innerHeight * 0.3;
|
||||
|
||||
if (isInView) {
|
||||
activeVideo = video;
|
||||
}
|
||||
});
|
||||
|
||||
// 处理活跃视频
|
||||
if (activeVideo) {
|
||||
stopAllVideos(); // 先停止其他视频
|
||||
const img = activeVideo.parentElement.querySelector('.right-img');
|
||||
img.style.display = 'none';
|
||||
activeVideo.style.display = 'block';
|
||||
|
||||
// 自动播放(兼容原生控制栏,用户手动暂停后不会强制播放)
|
||||
if (activeVideo.paused) {
|
||||
activeVideo.play().catch((err) => {
|
||||
console.log('视频播放失败(浏览器限制):', err);
|
||||
// 播放失败时回退到图片
|
||||
activeVideo.style.display = 'none';
|
||||
img.style.display = 'block';
|
||||
});
|
||||
}
|
||||
} else {
|
||||
stopAllVideos(); // 无活跃视频时停止所有播放
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
window.onload = function () {
|
||||
if (typeof Swiper === 'undefined') {
|
||||
console.error('Swiper加载失败,请刷新页面重试');
|
||||
return;
|
||||
}
|
||||
|
||||
swiper = new Swiper('.auto-swiper-container', {
|
||||
autoplay: {
|
||||
delay: 3000, // 3秒切换
|
||||
disableOnInteraction: false,
|
||||
},
|
||||
loop: false,
|
||||
slidesPerView: 1,
|
||||
spaceBetween: 0,
|
||||
// 启用分页指示标(核心配置)
|
||||
pagination: {
|
||||
el: '.swiper-pagination', // 对应 HTML 中的指示标容器
|
||||
clickable: true, // 允许点击指示标切换
|
||||
// dynamicBullets: true, // 动态指示标(当前激活放大)
|
||||
//dynamicMainBullets: 3, // 动态模式显示3个核心指示标
|
||||
},
|
||||
navigation: false,
|
||||
scrollbar: false,
|
||||
on: {
|
||||
resize: function () {
|
||||
this.update();
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
window.addEventListener('resize', function () {
|
||||
swiper.update();
|
||||
});
|
||||
|
||||
// 初始化时触发滚动事件,确保状态正确
|
||||
window.dispatchEvent(new Event('scroll'));
|
||||
};
|
||||
</script>
|
||||
{/block}
|
||||
@@ -18,7 +18,7 @@ if (!function_exists('image_domain_concat')) {
|
||||
return $path;
|
||||
}
|
||||
|
||||
return rtrim($domain, '/') . '/' . ltrim($path, '/');
|
||||
return url_join($domain, $path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ if (!function_exists('video_domain_concat')) {
|
||||
return $path;
|
||||
}
|
||||
|
||||
return rtrim($domain, '/') . '/' . ltrim($path, '/');
|
||||
return url_join($domain, $path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,11 @@ Route::group('v1', function() {
|
||||
->middleware(\app\openapi\middleware\Auth::class);
|
||||
})
|
||||
->middleware(\think\middleware\Throttle::class, [
|
||||
'visit_rate' => '5/m',
|
||||
'prefix' => 'throttle_',
|
||||
'visit_rate' => '5/m',
|
||||
'key' => function($throttle, $request) {
|
||||
return '__CONTROLLER__/__ACTION__/__IP__';
|
||||
},
|
||||
'visit_fail_response' => function (\think\middleware\Throttle $throttle, \think\Request $request, int $wait_seconds) {
|
||||
return \think\Response::create('您的操作过于频繁, 请在 ' . $wait_seconds . ' 秒后再试。')->code(429);
|
||||
},
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
],
|
||||
"require": {
|
||||
"php": ">=8.0.0",
|
||||
"topthink/framework": "^8.0",
|
||||
"topthink/framework": "8.1.2",
|
||||
"topthink/think-orm": "v3.0.34",
|
||||
"topthink/think-filesystem": "^2.0",
|
||||
"topthink/think-filesystem": "^3.0",
|
||||
"topthink/think-multi-app": "^1.1",
|
||||
"topthink/think-migration": "^3.1",
|
||||
"topthink/think-view": "^2.0",
|
||||
@@ -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",
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | 控制台配置
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
return [
|
||||
// 指令定义
|
||||
'commands' => [
|
||||
'data:migrate' => \app\command\DataMigration::class,
|
||||
'openapi:addclient' => \app\command\OpenApiMgr\AddClient::class,
|
||||
],
|
||||
];
|
||||
|
||||
@@ -39,6 +39,60 @@ return [
|
||||
// 可见性
|
||||
'visibility' => 'public',
|
||||
],
|
||||
'public_qiniu' => [
|
||||
// 磁盘类型
|
||||
'type' => \filesystem\driver\Qiniu::class,
|
||||
// bucker 名称
|
||||
'bucket' => env('QINIU_CLOUD.BUCKET', 'orico-official-website'),
|
||||
// 访问密钥
|
||||
'access_key' => env('QINIU_CLOUD.ACCESS_KEY', 'dOsTum4a5qvhPTBbZRPX0pIOU7PZWRX7htKjztms'),
|
||||
// 密钥
|
||||
'secret_key' => env('QINIU_CLOUD.SECRET_KEY', 'KFxsGbnErkALFfeGdMa8QWTdodJbamMX0iznLe-q'),
|
||||
// 外部URL
|
||||
'base_url' => env('QINIU_CLOUD.BASE_URL', '//szw73dlk3.hn-bkt.clouddn.com'),
|
||||
// 路径
|
||||
'path_prefix' => '/storage',
|
||||
// 文件名称回调,可为文件名添加特定标志,以便可以在后续识别
|
||||
'filename_generator' => function (\think\file\UploadedFile $file, callable $context_generator = null): callable {
|
||||
return function() use ($file, $context_generator) {
|
||||
// 为文件名称添加配置名,以为后续可能根据文件名识别文件所属存储配置信息
|
||||
$marker = '_' . base64_encode('public_qiniu');
|
||||
$filename = $context_generator ? $context_generator($file) : null;
|
||||
if ($filename == null) {
|
||||
return date('Ymd') . '/' . md5(microtime(true) . $file->getPathname()) . $marker;
|
||||
}
|
||||
|
||||
return $filename . $marker;
|
||||
};
|
||||
},
|
||||
],
|
||||
'video_qiniu' => [
|
||||
// 磁盘类型
|
||||
'type' => \filesystem\driver\Qiniu::class,
|
||||
// bucker 名称
|
||||
'bucket' => env('QINIU_CLOUD.BUCKET', 'orico-official-website'),
|
||||
// 访问密钥
|
||||
'access_key' => env('QINIU_CLOUD.ACCESS_KEY', 'dOsTum4a5qvhPTBbZRPX0pIOU7PZWRX7htKjztms'),
|
||||
// 密钥
|
||||
'secret_key' => env('QINIU_CLOUD.SECRET_KEY', 'KFxsGbnErkALFfeGdMa8QWTdodJbamMX0iznLe-q'),
|
||||
// 外部URL
|
||||
'base_url' => env('QINIU_CLOUD.BASE_URL', '//szw73dlk3.hn-bkt.clouddn.com'),
|
||||
// 路径
|
||||
'path_prefix' => '/storage/videos',
|
||||
// 文件名称回调,可为文件名添加特定标志,以便可以在后续识别
|
||||
'filename_generator' => function (\think\file\UploadedFile $file, callable $context_generator = null): callable {
|
||||
return function() use ($file, $context_generator) {
|
||||
// 为文件名称添加配置名,以为后续可能根据文件名识别文件所属存储配置信息
|
||||
$marker = '_' . base64_encode('video_qiniu');
|
||||
$filename = $context_generator ? $context_generator() : null;
|
||||
if ($filename == null) {
|
||||
return date('Ymd') . '/' . md5(microtime(true) . $file->getPathname()) . $marker;
|
||||
}
|
||||
|
||||
return $filename . $marker;
|
||||
};
|
||||
},
|
||||
]
|
||||
// 更多的磁盘配置信息
|
||||
],
|
||||
];
|
||||
|
||||
@@ -31,7 +31,7 @@ class CreateVideo extends Migrator
|
||||
$table = $this->table('video', ['engine' => 'MyISAM', 'comment' => '视频表']);
|
||||
$table->addColumn('language_id', 'integer', ['signed' => false , 'null' => false, 'comment' => '语言ID'])
|
||||
->addColumn('category_id', 'integer', ['signed' => false , 'null' => false, 'comment' => '分类ID'])
|
||||
->addColumn('name', 'string', ['limit' => 64 , 'null' => false, 'comment' => '名称'])
|
||||
->addColumn('name', 'string', ['limit' => 128 , 'null' => false, 'comment' => '名称'])
|
||||
->addColumn('desc', 'string', ['limit' => 512, 'null' => true, 'default' => null, 'comment' => '描述信息'])
|
||||
->addColumn('image', 'string', ['limit' => 125, 'null' => true, 'default' => null, 'comment' => '封面图片'])
|
||||
->addColumn('video', 'string', ['limit' => 125, 'null' => true, 'default' => null, 'comment' => '视频地址'])
|
||||
|
||||
@@ -32,6 +32,8 @@ class CreateSysBannerItem extends Migrator
|
||||
$table->addColumn('banner_id', 'integer', ['null' => false, 'comment' => '所属Banner ID'])
|
||||
->addColumn('title', 'string', ['limit' => 256, 'null' => false, 'comment' => '标题'])
|
||||
->addColumn('title_txt_color', 'string', ['limit' => 7, 'null' => false, 'default' => '', 'comment' => '标题文本颜色'])
|
||||
->addColumn('short_title', 'string', ['limit' => 255, 'null' => true, 'comment' => 'banner简称'])
|
||||
->addColumn('short_title_txt_color', 'string', ['limit' => 7, 'null' => true, 'comment' => 'banner简称文本颜色'])
|
||||
->addColumn('desc', MysqlAdapter::PHINX_TYPE_TEXT, ['null' => true, 'default' => null, 'comment' => '描述'])
|
||||
->addColumn('desc_txt_color', 'string', ['limit' => 7, 'null' => false, 'default' => '', 'comment' => '描述文本颜色'])
|
||||
->addColumn('type', 'string', ['limit' => 16, 'null' => false, 'comment' => '类型: image为图片, video为视频'])
|
||||
@@ -39,7 +41,7 @@ class CreateSysBannerItem extends Migrator
|
||||
->addColumn('extra_image', 'string', ['limit' => 255, 'null' => true, 'default' => null, 'comment' => '额外的图片'])
|
||||
->addColumn('video', 'string', ['limit' => 255, 'null' => true, 'default' => null, 'comment' => '视频'])
|
||||
->addColumn('link_to', 'string', ['limit' => 64, 'null' => true, 'default' => null, 'comment' => '链接到(类型): article:文章, article_category:文章分类, product:产品, product_category:产品分类, custom:自定义链接'])
|
||||
->addColumn('link', 'string', ['limit' => 255, 'null' => true, 'default' => null, 'comment' => '链接'])
|
||||
->addColumn('link', 'string', ['limit' => 510, 'null' => true, 'default' => null, 'comment' => '链接'])
|
||||
->addColumn('sort', 'integer', ['limit' => 11, 'null' => false, 'default' => 0, 'comment' => '排序'])
|
||||
->addColumn('status', 'boolean', ['limit' => 1, 'null' => false, 'default' => 1, 'comment' => '-1为禁用, 1为启用'])
|
||||
->addColumn('created_at', 'timestamp', ['null' => false, 'default' =>'CURRENT_TIMESTAMP', 'comment' => '创建时间'])
|
||||
|
||||
@@ -73,8 +73,8 @@ class SysConfigInit extends Seeder
|
||||
["id" => 56, "group_id" => 12, "title" => "Instagram URL新窗口打开", "name" => "article_share_to_instagram.is_blank", "value" => "1", "extra" => "1:是\n0:否", "type" => "radio", "sort" => 6, "remark" => "", "created_at" => "2025-04-23 17:49:12", "updated_at" => "2025-06-12 09:55:21", "deleted_at" => null],
|
||||
["id" => 57, "group_id" => 12, "title" => "Twitter URL新窗口打开", "name" => "article_share_to_twitter.is_blank", "value" => "1", "extra" => "1:是\n0:否", "type" => "radio", "sort" => 9, "remark" => "", "created_at" => "2025-04-23 17:49:12", "updated_at" => "2025-06-12 09:55:21", "deleted_at" => null],
|
||||
["id" => 58, "group_id" => 12, "title" => "Reddit URL新窗口打开", "name" => "article_share_to_reddit.is_blank", "value" => "1", "extra" => "1:是\n0:否", "type" => "radio", "sort" => 12, "remark" => "", "created_at" => "2025-04-23 17:49:12", "updated_at" => "2025-06-12 09:55:21", "deleted_at" => null],
|
||||
["id" => 59, "group_id" => 1, "title" => "产品询盘可选国家", "name" => "optional_country_for_product_inquiry", "value" => "Afghanistan\nAlbania\nAlgeria\nAmerican Samoa\nAndorra\nAngola\nAnguilla\nAntigua and Barbuda\nArgentina\nArmenia\nAruba\nAustralia\nAustria\nAzerbaijan\nAzores\nBahamas\nBahrain\nBangladesh\nBarbados\nBelarus\nBelgium\nBelize\nBenin\nBermuda\nBhutan\nBolivia\nBosnia and Herzegovina\nBotswana\nBrazil\nBrunei\nBulgaria\nBurkina Faso\nBurundi\nCambodia\nCameroon\nCanada\nCanarias\nCape Verde\nCayman\nCentral African Republic\nChad\nChile\nChina\nColombia\nComoros\nCongo (Congo-Kinshasa)\nCongo\nCook Islands\nCosta Rica\nCote D'Ivoire\nCroatia\nCuba\nCyprus\nCzech\nDenmark\nDjibouti\nDominica\nDominican\nEcuador\nEgypt\nEl Salvador\nEquatorial Guinea\nEritrea\nEstonia\nEthiopia\nFiji\nFinland\nFrance\nFrench Guiana\nFrench Polynesia\nGabon\nGambia\nGeorgia\nGermany\nGhana\nGreece\nGreenland\nGrenada\nGuadeloupe\nGuam\nGuatemala\nGuinea\nGuinea-Bissau\nGuyana\nHaiti\nHonduras\nHungary\nIceland\nIndia\nIndonesia\nIran\nIraq\nIreland\nIsrael\nItaly\nJamaica\nJapan\nJordan\nKazakhstan\nKenya\nKiribati\nKorea (North)\nKorea (South)\nKuwait\nKyrgyzstan\nLaos\nLatvia\nLebanon\nLesotho\nLiberia\nLibya\nLiechtenstein\nLithuania\nLuxembourg\nMacedonia\nMadagascar\nMadeira\nMalawi\nMalaysia\nMaldives\nMali\nMalta\nMarshall Islands\nMartinique\nMauritania\nMauritius\nMexico\nMicronesia\nMoldova\nMonaco\nMongolia\nMontserrat\nMorocco\nMozambique\nMyanmar\nNamibia\nNauru\nNepal\nNetherlands Antilles\nNetherlands\nNew Caledonia\nNew Zealand\nNicaragua\nNiger\nNiue\nNorthern Mariana\nNorway\nOman\nPakistan\nPalau\nPalestine\nPanama\nPapua New Guinea\nParaguay\nPeru\nPhilippines\nPitcairn Islands\nPoland\nPortugal\nPuerto Rico\nQatar\nReunion\nRomania\nRussian Federation\nRwanda\nSaint Helena\nSaint Kitts-Nevis\nSaint Lucia\nSaint Vincent and the Grenadines\nSamoa\nSan Marino\nSao Tome and Principe\nSaudi Arabia\nSenegal\nSerbia\nSeychelles\nSierra Leone\nSingapore\nSlovakia\nSlovenia\nSolomon Islands\nSomalia\nSouth Africa\nSpain\nSri Lanka\nSudan\nSuriname\nSwaziland\nSweden\nSwitzerland\nSyria\nTajikistan\nTanzania\nThailand\nThe British Virgin Islands\nThe United States Virgin Islands\nTimor-Leste\nTogo\nTokelau\nTonga\nTrinidad and Tobago\nTunisia\nTurkey\nTurkmenistan\nTurks and Caicos Islands\nTuvalu\nUganda\nUkraine\nUnited Arab Emirates\nUnited Kingdom\nUnited States\nUruguay\nUzbekistan\nVanuatu\nVatican City\nVenezuela\nVietnam\nWallis and Futuna\nWestern Sahara\nYemen\nZambia\nZimbabwe", "extra" => "", "type" => "textarea", "sort" => 7, "remark" => "", "created_at" => "2025-04-27 11:10:22", "updated_at" => "2025-06-11 17:09:13", "deleted_at" => null],
|
||||
["id" => 60, "group_id" => 4, "title" => "产品询盘可选国家", "name" => "optional_country_for_product_inquiry", "value" => "Afghanistan\nAlbania\nAlgeria\nAmerican Samoa\nAndorra\nAngola\nAnguilla\nAntigua and Barbuda\nArgentina\nArmenia\nAruba\nAustralia\nAustria\nAzerbaijan\nAzores\nBahamas\nBahrain\nBangladesh\nBarbados\nBelarus\nBelgium\nBelize\nBenin\nBermuda\nBhutan\nBolivia\nBosnia and Herzegovina\nBotswana\nBrazil\nBrunei\nBulgaria\nBurkina Faso\nBurundi\nCambodia\nCameroon\nCanada\nCanarias\nCape Verde\nCayman\nCentral African Republic\nChad\nChile\nChina\nColombia\nComoros\nCongo (Congo-Kinshasa)\nCongo\nCook Islands\nCosta Rica\nCote D'Ivoire\nCroatia\nCuba\nCyprus\nCzech\nDenmark\nDjibouti\nDominica\nDominican\nEcuador\nEgypt\nEl Salvador\nEquatorial Guinea\nEritrea\nEstonia\nEthiopia\nFiji\nFinland\nFrance\nFrench Guiana\nFrench Polynesia\nGabon\nGambia\nGeorgia\nGermany\nGhana\nGreece\nGreenland\nGrenada\nGuadeloupe\nGuam\nGuatemala\nGuinea\nGuinea-Bissau\nGuyana\nHaiti\nHonduras\nHungary\nIceland\nIndia\nIndonesia\nIran\nIraq\nIreland\nIsrael\nItaly\nJamaica\nJapan\nJordan\nKazakhstan\nKenya\nKiribati\nKorea (North)\nKorea (South)\nKuwait\nKyrgyzstan\nLaos\nLatvia\nLebanon\nLesotho\nLiberia\nLibya\nLiechtenstein\nLithuania\nLuxembourg\nMacedonia\nMadagascar\nMadeira\nMalawi\nMalaysia\nMaldives\nMali\nMalta\nMarshall Islands\nMartinique\nMauritania\nMauritius\nMexico\nMicronesia\nMoldova\nMonaco\nMongolia\nMontserrat\nMorocco\nMozambique\nMyanmar\nNamibia\nNauru\nNepal\nNetherlands Antilles\nNetherlands\nNew Caledonia\nNew Zealand\nNicaragua\nNiger\nNiue\nNorthern Mariana\nNorway\nOman\nPakistan\nPalau\nPalestine\nPanama\nPapua New Guinea\nParaguay\nPeru\nPhilippines\nPitcairn Islands\nPoland\nPortugal\nPuerto Rico\nQatar\nReunion\nRomania\nRussian Federation\nRwanda\nSaint Helena\nSaint Kitts-Nevis\nSaint Lucia\nSaint Vincent and the Grenadines\nSamoa\nSan Marino\nSao Tome and Principe\nSaudi Arabia\nSenegal\nSerbia\nSeychelles\nSierra Leone\nSingapore\nSlovakia\nSlovenia\nSolomon Islands\nSomalia\nSouth Africa\nSpain\nSri Lanka\nSudan\nSuriname\nSwaziland\nSweden\nSwitzerland\nSyria\nTajikistan\nTanzania\nThailand\nThe British Virgin Islands\nThe United States Virgin Islands\nTimor-Leste\nTogo\nTokelau\nTonga\nTrinidad and Tobago\nTunisia\nTurkey\nTurkmenistan\nTurks and Caicos Islands\nTuvalu\nUganda\nUkraine\nUnited Arab Emirates\nUnited Kingdom\nUnited States\nUruguay\nUzbekistan\nVanuatu\nVatican City\nVenezuela\nVietnam\nWallis and Futuna\nWestern Sahara\nYemen\nZambia\nZimbabwe", "extra" => null, "type" => "textarea", "sort" => 7, "remark" => null, "created_at" => "2025-04-27 11:23:25", "updated_at" => "2025-06-12 09:55:21", "deleted_at" => null],
|
||||
["id" => 59, "group_id" => 1, "title" => "产品询盘可选国家", "name" => "optional_country_for_product_inquiry", "value" => "Afghanistan\nAlbania\nAlgeria\nAmerican Samoa\nAndorra\nAngola\nAnguilla\nAntigua and Barbuda\nArgentina\nArmenia\nAruba\nAustralia\nAustria\nAzerbaijan\nAzores\nBahamas\nBahrain\nBangladesh\nBarbados\nBelarus\nBelgium\nBelize\nBenin\nBermuda\nBhutan\nBolivia\nBosnia and Herzegovina\nBotswana\nBrazil\nBrunei\nBulgaria\nBurkina Faso\nBurundi\nCambodia\nCameroon\nCanada\nCanarias\nCape Verde\nCayman\nCentral African Republic\nChad\nChile\nChina\nColombia\nComoros\nCongo (Congo-Kinshasa)\nCongo\nCook Islands\nCosta Rica\nCote D'Ivoire\nCroatia\nCuba\nCyprus\nCzech\nDenmark\nDjibouti\nDominica\nDominican\nEcuador\nEgypt\nEl Salvador\nEquatorial Guinea\nEritrea\nEstonia\nEthiopia\nFiji\nFinland\nFrance\nFrench Guiana\nFrench Polynesia\nGabon\nGambia\nGeorgia\nGermany\nGhana\nGreece\nGreenland\nGrenada\nGuadeloupe\nGuam\nGuatemala\nGuinea\nGuinea-Bissau\nGuyana\nHaiti\nHonduras\nHungary\nIceland\nIndia\nIndonesia\nIran\nIraq\nIreland\nIsrael\nItaly\nJamaica\nJapan\nJordan\nKazakhstan\nKenya\nKiribati\nKorea (North)\nKorea (South)\nKuwait\nKyrgyzstan\nLaos\nLatvia\nLebanon\nLesotho\nLiberia\nLibya\nLiechtenstein\nLithuania\nLuxembourg\nMacedonia\nMadagascar\nMadeira\nMalawi\nMalaysia\nMaldives\nMali\nMalta\nMarshall Islands\nMartinique\nMauritania\nMauritius\nMexico\nMicronesia\nMoldova\nMonaco\nMongolia\nMetropolis\nMorocco\nMozambique\nMyanmar\nNamibia\nNauru\nNepal\nNetherlands Antilles\nNetherlands\nNew Caledonia\nNew Zealand\nNicaragua\nNiger\nNiue\nNorthern Mariana\nNorway\nOman\nPakistan\nPalau\nPalestine\nPanama\nPapua New Guinea\nParaguay\nPeru\nPhilippines\nPitcairn Islands\nPoland\nPortugal\nPuerto Rico\nQatar\nReunion\nRomania\nRussian Federation\nRwanda\nSaint Helena\nSaint Kitts-Nevis\nSaint Lucia\nSaint Vincent and the Grenadines\nSamoa\nSan Marino\nSao Tome and Principe\nSaudi Arabia\nSenegal\nSerbia\nSeychelles\nSierra Leone\nSingapore\nSlovakia\nSlovenia\nSolomon Islands\nSomalia\nSouth Africa\nSpain\nSri Lanka\nSudan\nSuriname\nSwaziland\nSweden\nSwitzerland\nSyria\nTajikistan\nTanzania\nThailand\nThe British Virgin Islands\nThe United States Virgin Islands\nTimor-Leste\nTogo\nTokelau\nTonga\nTrinidad and Tobago\nTunisia\nTurkey\nTurkmenistan\nTurks and Caicos Islands\nTuvalu\nUganda\nUkraine\nUnited Arab Emirates\nUnited Kingdom\nUnited States\nUruguay\nUzbekistan\nVanuatu\nVatican City\nVenezuela\nVietnam\nWallis and Futuna\nWestern Sahara\nYemen\nZambia\nZimbabwe", "extra" => "", "type" => "textarea", "sort" => 7, "remark" => "", "created_at" => "2025-04-27 11:10:22", "updated_at" => "2025-06-11 17:09:13", "deleted_at" => null],
|
||||
["id" => 60, "group_id" => 4, "title" => "产品询盘可选国家", "name" => "optional_country_for_product_inquiry", "value" => "Afghanistan\nAlbania\nAlgeria\nAmerican Samoa\nAndorra\nAngola\nAnguilla\nAntigua and Barbuda\nArgentina\nArmenia\nAruba\nAustralia\nAustria\nAzerbaijan\nAzores\nBahamas\nBahrain\nBangladesh\nBarbados\nBelarus\nBelgium\nBelize\nBenin\nBermuda\nBhutan\nBolivia\nBosnia and Herzegovina\nBotswana\nBrazil\nBrunei\nBulgaria\nBurkina Faso\nBurundi\nCambodia\nCameroon\nCanada\nCanarias\nCape Verde\nCayman\nCentral African Republic\nChad\nChile\nChina\nColombia\nComoros\nCongo (Congo-Kinshasa)\nCongo\nCook Islands\nCosta Rica\nCote D'Ivoire\nCroatia\nCuba\nCyprus\nCzech\nDenmark\nDjibouti\nDominica\nDominican\nEcuador\nEgypt\nEl Salvador\nEquatorial Guinea\nEritrea\nEstonia\nEthiopia\nFiji\nFinland\nFrance\nFrench Guiana\nFrench Polynesia\nGabon\nGambia\nGeorgia\nGermany\nGhana\nGreece\nGreenland\nGrenada\nGuadeloupe\nGuam\nGuatemala\nGuinea\nGuinea-Bissau\nGuyana\nHaiti\nHonduras\nHungary\nIceland\nIndia\nIndonesia\nIran\nIraq\nIreland\nIsrael\nItaly\nJamaica\nJapan\nJordan\nKazakhstan\nKenya\nKiribati\nKorea (North)\nKorea (South)\nKuwait\nKyrgyzstan\nLaos\nLatvia\nLebanon\nLesotho\nLiberia\nLibya\nLiechtenstein\nLithuania\nLuxembourg\nMacedonia\nMadagascar\nMadeira\nMalawi\nMalaysia\nMaldives\nMali\nMalta\nMarshall Islands\nMartinique\nMauritania\nMauritius\nMexico\nMicronesia\nMoldova\nMonaco\nMongolia\nMetropolis\nMorocco\nMozambique\nMyanmar\nNamibia\nNauru\nNepal\nNetherlands Antilles\nNetherlands\nNew Caledonia\nNew Zealand\nNicaragua\nNiger\nNiue\nNorthern Mariana\nNorway\nOman\nPakistan\nPalau\nPalestine\nPanama\nPapua New Guinea\nParaguay\nPeru\nPhilippines\nPitcairn Islands\nPoland\nPortugal\nPuerto Rico\nQatar\nReunion\nRomania\nRussian Federation\nRwanda\nSaint Helena\nSaint Kitts-Nevis\nSaint Lucia\nSaint Vincent and the Grenadines\nSamoa\nSan Marino\nSao Tome and Principe\nSaudi Arabia\nSenegal\nSerbia\nSeychelles\nSierra Leone\nSingapore\nSlovakia\nSlovenia\nSolomon Islands\nSomalia\nSouth Africa\nSpain\nSri Lanka\nSudan\nSuriname\nSwaziland\nSweden\nSwitzerland\nSyria\nTajikistan\nTanzania\nThailand\nThe British Virgin Islands\nThe United States Virgin Islands\nTimor-Leste\nTogo\nTokelau\nTonga\nTrinidad and Tobago\nTunisia\nTurkey\nTurkmenistan\nTurks and Caicos Islands\nTuvalu\nUganda\nUkraine\nUnited Arab Emirates\nUnited Kingdom\nUnited States\nUruguay\nUzbekistan\nVanuatu\nVatican City\nVenezuela\nVietnam\nWallis and Futuna\nWestern Sahara\nYemen\nZambia\nZimbabwe", "extra" => null, "type" => "textarea", "sort" => 7, "remark" => null, "created_at" => "2025-04-27 11:23:25", "updated_at" => "2025-06-12 09:55:21", "deleted_at" => null],
|
||||
["id" => 61, "group_id" => 1, "title" => "导航位置店铺URL", "name" => "navigation_store_url", "value" => "https://oricotechs.com/", "extra" => null, "type" => "text", "sort" => 6, "remark" => null, "created_at" => "2025-05-13 17:45:46", "updated_at" => "2025-06-11 17:09:13", "deleted_at" => null],
|
||||
["id" => 62, "group_id" => 4, "title" => "导航位置店铺URL", "name" => "navigation_store_url", "value" => "https://oricotechs.com/", "extra" => null, "type" => "text", "sort" => 6, "remark" => null, "created_at" => "2025-05-13 17:45:46", "updated_at" => "2025-06-12 09:55:21", "deleted_at" => null],
|
||||
["id" => 63, "group_id" => 7, "title" => "邮箱", "name" => "website_email", "value" => "supports@orico.com.cn", "extra" => null, "type" => "text", "sort" => 1, "remark" => null, "created_at" => "2025-05-23 17:06:53", "updated_at" => "2025-06-11 17:09:13", "deleted_at" => null],
|
||||
@@ -119,6 +119,10 @@ class SysConfigInit extends Seeder
|
||||
["id" => 102, "group_id" => 13, "title" => "视频 - 唯一性保持", "name" => "upload_video.filemd5_unique", "value" => "1", "extra" => "0:否\n1:是", "type" => "radio", "sort" => 5, "remark" => "如果保持视频文件唯一,重复视频上传时将立即返回已存在的地址;如果不保持,则同模块同一天上传的文件根据原文件名覆盖。", "created_at" => "2025-06-12 11:24:24", "updated_at" => "2025-06-12 11:25:18", "deleted_at" => NULL],
|
||||
["id" => 103, "group_id" => 13, "title" => "附件 - 保留原文件名", "name" => "upload_attachment.filename_keep", "value" => NULL, "extra" => "0:否\n1:是", "type" => "radio", "sort" => 6, "remark" => "默认为否", "created_at" => "2025-06-12 11:27:08", "updated_at" => "2025-06-12 11:27:08", "deleted_at" => NULL],
|
||||
["id" => 104, "group_id" => 13, "title" => "附件 - 唯一性保持", "name" => "upload_attachment.filemd5_unique", "value" => "1", "extra" => "0:否\n1:是", "type" => "radio", "sort" => 7, "remark" => "如果保持附件文件唯一,重复附件上传时将立即返回已存在的地址;如果不保持,则同模块同一天上传的文件根据原文件名覆盖。", "created_at" => "2025-06-12 11:28:22", "updated_at" => "2025-06-12 11:28:22", "deleted_at" => NULL],
|
||||
['id' => 105, 'group_id' => 13, 'title' => '视频 - 保存到', 'name' => 'upload_video.save_to', 'value' => 'qiniu_cloud', 'extra' => 'local:本地\nqiniu_cloud:七牛云', 'type' => 'radio', 'sort' => 6, 'remark' => '视频保存位置,默认为“本地” - [本地为本站点服务器;七牛云为七牛云对象存储,上传经这本站点服务器中转,上传耗时稍慢于“本地”]', 'created_at' => '2025-07-25 10:46:24', 'updated_at' => '2025-07-25 16:41:53', 'deleted_at' => NULL],
|
||||
['id' => 106, 'group_id' => 13, 'title' => '附件 - 保存到', 'name' => 'upload_attachment.save_to', 'value' => 'local', 'extra' => 'local:本地\nqiniu_cloud:七牛云', 'type' => 'radio', 'sort' => 9, 'remark' => '附件保存位置,默认为“本地” - [本地为本站点服务器;七牛云为七牛云对象存储,上传经这本站点服务器中转,上传耗时稍慢于“本地”]', 'created_at' => '2025-07-25 10:51:34', 'updated_at' => '2025-07-25 16:41:53', 'deleted_at' => NULL],
|
||||
['id' => 107, 'group_id' => 14, 'title' => '视频 - 保存到', 'name' => 'upload_video.save_to', 'value' => 'qiniu_cloud', 'extra' => 'local:本地\nqiniu_cloud:七牛云', 'type' => 'radio', 'sort' => 6, 'remark' => '视频保存位置,默认为“本地” - [本地为本站点服务器;七牛云为七牛云对象存储,上传经这本站点服务器中转,上传耗时稍慢于“本地”]', 'created_at' => '2025-07-25 10:46:24', 'updated_at' => '2025-07-25 16:41:53', 'deleted_at' => NULL],
|
||||
['id' => 108, 'group_id' => 14, 'title' => '附件 - 保存到', 'name' => 'upload_attachment.save_to', 'value' => 'local', 'extra' => 'local:本地\nqiniu_cloud:七牛云', 'type' => 'radio', 'sort' => 9, 'remark' => '附件保存位置,默认为“本地” - [本地为本站点服务器;七牛云为七牛云对象存储,上传经这本站点服务器中转,上传耗时稍慢于“本地”]', 'created_at' => '2025-07-25 10:51:34', 'updated_at' => '2025-07-25 16:41:53', 'deleted_at' => NULL],
|
||||
];
|
||||
|
||||
$table = $this->table('sys_config');
|
||||
|
||||
295
extend/filesystem/adapter/QiniuAdapter.php
Normal file
295
extend/filesystem/adapter/QiniuAdapter.php
Normal file
@@ -0,0 +1,295 @@
|
||||
<?php
|
||||
namespace filesystem\adapter;
|
||||
|
||||
use League\Flysystem\Config;
|
||||
use League\Flysystem\FilesystemAdapter;
|
||||
use League\Flysystem\FileAttributes;
|
||||
use League\Flysystem\UnableToCopyFile;
|
||||
use League\Flysystem\UnableToDeleteFile;
|
||||
use League\Flysystem\UnableToMoveFile;
|
||||
use League\Flysystem\UnableToReadFile;
|
||||
use League\Flysystem\UnableToRetrieveMetadata;
|
||||
use League\Flysystem\UnableToSetVisibility;
|
||||
use League\Flysystem\UnableToWriteFile;
|
||||
use Qiniu\Auth;
|
||||
use Qiniu\Storage\UploadManager;
|
||||
use Qiniu\Storage\BucketManager;
|
||||
|
||||
class QiniuAdapter implements FilesystemAdapter
|
||||
{
|
||||
protected ?Auth $authMgr;
|
||||
protected ?UploadManager $uploadMgr;
|
||||
protected ?BucketManager $bucketMgr;
|
||||
|
||||
public function __construct(protected string $access_key, protected string $secret_key, protected string $bucket, protected string $base_url, protected string $path)
|
||||
{
|
||||
}
|
||||
|
||||
private function getAuthMgr(): Auth
|
||||
{
|
||||
return $this->authMgr ?? new Auth($this->access_key, $this->secret_key);
|
||||
}
|
||||
|
||||
private function getUploadMgr(): UploadManager
|
||||
{
|
||||
return $this->uploadMgr ?? new UploadManager();
|
||||
}
|
||||
|
||||
private function getBucketMgr(): BucketManager
|
||||
{
|
||||
return $this->bucketMgr ?? new BucketManager($this->authMgr);
|
||||
}
|
||||
|
||||
private function getPathPrefix(): string
|
||||
{
|
||||
$path = ltrim($this->path, '\\/');
|
||||
if ($path !== '' && !str_ends_with($path, '/')) {
|
||||
$path = $path . '/';
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
private function applyPathPrefix(string $path): string
|
||||
{
|
||||
$path = ltrim($path, '\\/');
|
||||
return $this->getPathPrefix() . $path;
|
||||
}
|
||||
|
||||
private static function parseUrl($url): array
|
||||
{
|
||||
$result = [];
|
||||
|
||||
// Build arrays of values we need to decode before parsing
|
||||
$entities = [
|
||||
'%21',
|
||||
'%2A',
|
||||
'%27',
|
||||
'%28',
|
||||
'%29',
|
||||
'%3B',
|
||||
'%3A',
|
||||
'%40',
|
||||
'%26',
|
||||
'%3D',
|
||||
'%24',
|
||||
'%2C',
|
||||
'%2F',
|
||||
'%3F',
|
||||
'%23',
|
||||
'%5B',
|
||||
'%5D',
|
||||
'%5C'
|
||||
];
|
||||
$replacements = ['!', '*', "'", '(', ')', ';', ':', '@', '&', '=', '$', ',', '/', '?', '#', '[', ']', '/'];
|
||||
|
||||
// Create encoded URL with special URL characters decoded so it can be parsed
|
||||
// All other characters will be encoded
|
||||
$encodedURL = str_replace($entities, $replacements, urlencode($url));
|
||||
|
||||
// Parse the encoded URL
|
||||
$encodedParts = parse_url($encodedURL);
|
||||
|
||||
// Now, decode each value of the resulting array
|
||||
if ($encodedParts) {
|
||||
foreach ($encodedParts as $key => $value) {
|
||||
$result[$key] = urldecode(str_replace($replacements, $entities, $value));
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function normalizeHost($domain): string
|
||||
{
|
||||
if (0 !== stripos($domain, 'https://') && 0 !== stripos($domain, 'http://')) {
|
||||
$domain = "http://{$domain}";
|
||||
}
|
||||
|
||||
return rtrim($domain, '/') . '/';
|
||||
}
|
||||
|
||||
private function getUrl(string $path): string
|
||||
{
|
||||
$segments = $this->parseUrl($path);
|
||||
$query = empty($segments['query']) ? '' : '?' . $segments['query'];
|
||||
|
||||
return $this->normalizeHost($this->base_url) . ltrim(implode('/', array_map('rawurlencode', explode('/', $segments['path']))), '/') . $query;
|
||||
}
|
||||
|
||||
private function privateDownloadUrl(string $path, int $expires = 3600): string
|
||||
{
|
||||
return $this->getAuthMgr()->privateDownloadUrl($this->getUrl($path), $expires);
|
||||
}
|
||||
|
||||
private function getMetadata($path): FileAttributes|array
|
||||
{
|
||||
$result = $this->getBucketMgr()->stat($this->bucket, $path);
|
||||
$result[0]['key'] = $path;
|
||||
|
||||
return $this->normalizeFileInfo($result[0]);
|
||||
}
|
||||
|
||||
private function normalizeFileInfo(array $stats): FileAttributes
|
||||
{
|
||||
return new FileAttributes(
|
||||
$stats['key'],
|
||||
$stats['fsize'] ?? null,
|
||||
null,
|
||||
isset($stats['putTime']) ? floor($stats['putTime'] / 10000000) : null,
|
||||
$stats['mimeType'] ?? null
|
||||
);
|
||||
}
|
||||
|
||||
public function fileExists(string $path): bool
|
||||
{
|
||||
[, $error] = $this->getBucketMgr()->stat($this->bucket, $this->applyPathPrefix($path));
|
||||
return is_null($error);
|
||||
}
|
||||
|
||||
public function directoryExists(string $path): bool
|
||||
{
|
||||
return $this->fileExists($path);
|
||||
}
|
||||
|
||||
public function write(string $path, string $contents, Config $config): void
|
||||
{
|
||||
$mime = $config->get('mime', 'application/octet-stream');
|
||||
|
||||
/**
|
||||
* @var Error|null $error
|
||||
*/
|
||||
[, $error] = $this->getUploadMgr()->put(
|
||||
$this->getAuthMgr()->uploadToken($this->bucket),
|
||||
$this->applyPathPrefix($path),
|
||||
$contents,
|
||||
null,
|
||||
$mime,
|
||||
$path
|
||||
);
|
||||
|
||||
if ($error) {
|
||||
throw UnableToWriteFile::atLocation($path, $error->message());
|
||||
}
|
||||
}
|
||||
|
||||
public function writeStream(string $path, $resource, Config $config): void
|
||||
{
|
||||
$data = '';
|
||||
|
||||
while (!feof($resource)) {
|
||||
$data .= fread($resource, 1024);
|
||||
}
|
||||
|
||||
$this->write($path, $data, $config);
|
||||
}
|
||||
|
||||
public function read(string $path): string
|
||||
{
|
||||
try {
|
||||
$result = file_get_contents($this->privateDownloadUrl($path));
|
||||
} catch (\Exception $th) {
|
||||
throw UnableToReadFile::fromLocation($path);
|
||||
}
|
||||
|
||||
if (false === $result) {
|
||||
throw UnableToReadFile::fromLocation($path);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function readStream(string $path)
|
||||
{
|
||||
if (ini_get('allow_url_fopen')) {
|
||||
if ($result = fopen($this->privateDownloadUrl($path), 'r')) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
throw UnableToReadFile::fromLocation($path);
|
||||
}
|
||||
|
||||
public function delete(string $path): void
|
||||
{
|
||||
[, $error] = $this->getBucketMgr()->delete($this->bucket, $this->applyPathPrefix($path));
|
||||
if (!is_null($error)) {
|
||||
throw UnableToDeleteFile::atLocation($path);
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteDirectory(string $path): void
|
||||
{
|
||||
$this->delete($path);
|
||||
}
|
||||
|
||||
public function createDirectory(string $path, Config $config): void
|
||||
{
|
||||
}
|
||||
|
||||
public function setVisibility(string $path, string $visibility): void
|
||||
{
|
||||
throw UnableToSetVisibility::atLocation($path);
|
||||
}
|
||||
|
||||
public function visibility(string $path): FileAttributes
|
||||
{
|
||||
throw UnableToRetrieveMetadata::visibility($path);
|
||||
}
|
||||
|
||||
public function mimeType(string $path): FileAttributes
|
||||
{
|
||||
$meta = $this->getMetadata($path);
|
||||
|
||||
if ($meta->mimeType() === null) {
|
||||
throw UnableToRetrieveMetadata::mimeType($path);
|
||||
}
|
||||
|
||||
return $meta;
|
||||
}
|
||||
|
||||
public function lastModified(string $path): FileAttributes
|
||||
{
|
||||
$meta = $this->getMetadata($path);
|
||||
|
||||
if ($meta->lastModified() === null) {
|
||||
throw UnableToRetrieveMetadata::lastModified($path);
|
||||
}
|
||||
return $meta;
|
||||
}
|
||||
|
||||
public function fileSize(string $path): FileAttributes
|
||||
{
|
||||
$meta = $this->getMetadata($path);
|
||||
|
||||
if ($meta->fileSize() === null) {
|
||||
throw UnableToRetrieveMetadata::fileSize($path);
|
||||
}
|
||||
return $meta;
|
||||
}
|
||||
|
||||
public function listContents(string $path, bool $deep): iterable
|
||||
{
|
||||
$result = $this->getBucketMgr()->listFiles($this->bucket, $path);
|
||||
|
||||
foreach ($result[0]['items'] ?? [] as $files) {
|
||||
yield $this->normalizeFileInfo($files);
|
||||
}
|
||||
}
|
||||
|
||||
public function move(string $source, string $destination, Config $config): void
|
||||
{
|
||||
[, $error] = $this->getBucketMgr()->rename($this->bucket, $source, $destination);
|
||||
if (!is_null($error)) {
|
||||
throw UnableToMoveFile::fromLocationTo($source, $destination);
|
||||
}
|
||||
}
|
||||
|
||||
public function copy(string $source, string $destination, Config $config): void
|
||||
{
|
||||
[, $error] = $this->getBucketMgr()->copy($this->bucket, $source, $this->bucket, $destination);
|
||||
if (!is_null($error)) {
|
||||
throw UnableToCopyFile::fromLocationTo($source, $destination);
|
||||
}
|
||||
}
|
||||
}
|
||||
56
extend/filesystem/driver/Qiniu.php
Normal file
56
extend/filesystem/driver/Qiniu.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
namespace filesystem\driver;
|
||||
|
||||
use Closure;
|
||||
use filesystem\adapter\QiniuAdapter;
|
||||
use League\Flysystem\FilesystemAdapter;
|
||||
|
||||
class Qiniu extends \think\filesystem\Driver
|
||||
{
|
||||
protected function createAdapter(): FilesystemAdapter
|
||||
{
|
||||
return new QiniuAdapter(
|
||||
$this->config['access_key'],
|
||||
$this->config['secret_key'],
|
||||
$this->config['bucket'],
|
||||
$this->config['base_url'],
|
||||
$this->config['path_prefix']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存文件
|
||||
* @param string $path 路径
|
||||
* @param \think\File $file 文件
|
||||
* @param null|string|\Closure $rule 文件名规则
|
||||
* @param array $options 参数
|
||||
* @return bool|string
|
||||
*/
|
||||
public function putFile(string $path, \think\File $file, $rule = null, array $options = [])
|
||||
{
|
||||
if (!empty($this->config['filename_generator']) && $this->config['filename_generator'] instanceof Closure) {
|
||||
$rule = $this->config['filename_generator']($file, $rule);
|
||||
}
|
||||
|
||||
return $this->putFileAs($path, $file, $file->hashName($rule), $options);
|
||||
}
|
||||
|
||||
public function url(string $path): string
|
||||
{
|
||||
if (str_starts_with($path, 'http://') || str_starts_with($path, 'https://')) {
|
||||
return $path;
|
||||
}
|
||||
if (!str_starts_with($path, $this->config['path_prefix'])) {
|
||||
$path = $this->config['path_prefix'] . '/' . $path;
|
||||
}
|
||||
return $this->concatPathToUrl($this->config['base_url'], $path);
|
||||
}
|
||||
|
||||
public function path(string $path): string
|
||||
{
|
||||
if (!str_starts_with($path, $this->config['path_prefix'])) {
|
||||
$path = $this->config['path_prefix'] . '/' . $path;
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
<?php
|
||||
|
||||
try {
|
||||
|
||||
$secret_key = 'Aa-1221';
|
||||
|
||||
// check for POST request
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
throw new \Exception('FAILED - not POST - '. $_SERVER['REQUEST_METHOD']);
|
||||
}
|
||||
|
||||
// get content type
|
||||
$content_type = isset($_SERVER['CONTENT_TYPE']) ? strtolower(trim($_SERVER['CONTENT_TYPE'])) : '';
|
||||
|
||||
if ($content_type != 'application/json') {
|
||||
throw new \Exception('FAILED - not application/json - '. $content_type);
|
||||
}
|
||||
|
||||
// get payload
|
||||
$payload = trim(file_get_contents("php://input"));
|
||||
|
||||
if (empty($payload)) {
|
||||
throw new \Exception('FAILED - no payload');
|
||||
}
|
||||
|
||||
// get header signature
|
||||
$header_signature = isset($_SERVER['HTTP_X_GITEA_SIGNATURE']) ? $_SERVER['HTTP_X_GITEA_SIGNATURE'] : '';
|
||||
|
||||
if (empty($header_signature)) {
|
||||
throw new \Exception('FAILED - header signature missing');
|
||||
}
|
||||
|
||||
// calculate payload signature
|
||||
$payload_signature = hash_hmac('sha256', $payload, $secret_key, false);
|
||||
|
||||
// check payload signature against header signature
|
||||
if ($header_signature !== $payload_signature) {
|
||||
throw new \Exception('FAILED - payload signature');
|
||||
}
|
||||
|
||||
// convert json to array
|
||||
$decoded = json_decode($payload, true);
|
||||
|
||||
// check for json decode errors
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
throw new \Exception('FAILED - json decode - '. json_last_error());
|
||||
}
|
||||
|
||||
exec('git pull origin dev --rebase 2>&1', $result);
|
||||
|
||||
var_export($result);exit;
|
||||
} catch (\Throwable $th) {
|
||||
var_export($th->getMessage());
|
||||
}
|
||||
2
public/migrate_temp_images/.gitignore
vendored
2
public/migrate_temp_images/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
*
|
||||
!.gitignore
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
.iotbt1 {
|
||||
font-size: 18px;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
padding-bottom: 24px;
|
||||
padding-top: 40px;
|
||||
font-weight: 700;
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
.iotbtp1 {
|
||||
font-size: 14px;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: bold;
|
||||
padding-bottom: 11px;
|
||||
word-break: break-word;
|
||||
@@ -69,7 +69,7 @@
|
||||
.iotbts1 {
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
color: #9e9e9f;
|
||||
word-break: break-word;
|
||||
}
|
||||
@@ -140,7 +140,7 @@
|
||||
font-size: 14px;
|
||||
padding-top: 12px;
|
||||
text-align: center;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
overflow-wrap: break-word;
|
||||
word-break: break-word;
|
||||
}
|
||||
@@ -152,7 +152,7 @@
|
||||
.sfbt1 {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: bold;
|
||||
padding-bottom: 24px;
|
||||
padding-top: 24px;
|
||||
@@ -183,7 +183,7 @@
|
||||
.cit {
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
font-family: Montserrat-Regular, Montserrat;
|
||||
font-family: Metropolis-Regular, Metropolis;
|
||||
color: #000;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -237,7 +237,7 @@
|
||||
.wcu_s1 {
|
||||
color: #000;
|
||||
font: 16px;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
font-weight: 500;
|
||||
padding: 20px 24px;
|
||||
}
|
||||
|
||||
@@ -598,7 +598,7 @@
|
||||
margin: auto;
|
||||
font-size: 1rem;
|
||||
color: #707070;
|
||||
font-family: "Montserrat-Medium";
|
||||
font-family: "Metropolis-Medium";
|
||||
}
|
||||
|
||||
.oricoCnLc .gallery-thumbs .swiper-slide-thumb-active {
|
||||
@@ -632,14 +632,14 @@
|
||||
.oricoCnLc .info h5 {
|
||||
font-size: #000;
|
||||
font-size: 1rem;
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
padding: 2rem 2rem 0 1rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.oricoCnLc .info p {
|
||||
color: #707070;
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
@@ -651,7 +651,7 @@
|
||||
|
||||
.oricoCnLc .m_ach-b .title {
|
||||
font-size: 1.125rem;
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
width: 98%;
|
||||
margin: auto;
|
||||
position: relative;
|
||||
@@ -660,7 +660,7 @@
|
||||
|
||||
.oricoCnLc .m_ach-b .chtitle {
|
||||
font-size: 1.125rem;
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
width: 98%;
|
||||
margin: auto;
|
||||
position: relative;
|
||||
@@ -677,7 +677,7 @@
|
||||
|
||||
.oricoCnLc .m_ch-title {
|
||||
font-size: 1rem;
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
width: 98%;
|
||||
margin: 1rem auto 0;
|
||||
padding: 1rem 0 0;
|
||||
@@ -690,7 +690,7 @@
|
||||
font-size: 0.875;
|
||||
line-height: 1.5rem;
|
||||
color: #707070;
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
width: 98%;
|
||||
margin: 1rem auto;
|
||||
padding: 0;
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
border-radius: 8px;
|
||||
height: 48px;
|
||||
box-shadow: none;
|
||||
font-family: Montserrat-Regular, Montserrat;
|
||||
font-family: Metropolis-Regular, Metropolis;
|
||||
}
|
||||
|
||||
.oricoEGapp-articledetail .content .share_box .comment .comment_form>div input {
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
border-radius: 1rem;
|
||||
background-color: #fff;
|
||||
color: #6b6c6e;
|
||||
font-family: "Montserrat-Medium";
|
||||
font-family: "Metropolis-Medium";
|
||||
font-size: 0.875rem;
|
||||
display: inline-block;
|
||||
margin-bottom: 0.5rem;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
font-size: 18px;
|
||||
color: #004bfa;
|
||||
text-align: left;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: 700;
|
||||
margin-top: 0;
|
||||
margin-bottom: 12px;
|
||||
@@ -27,7 +27,7 @@
|
||||
color: #707070;
|
||||
text-align: center;
|
||||
text-align: left;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
|
||||
.itlable {
|
||||
font-size: 12.5px;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
padding-bottom: 5px;
|
||||
@@ -106,7 +106,7 @@
|
||||
height: 48px;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
font-family: Montserrat-Regular, Montserrat;
|
||||
font-family: Metropolis-Regular, Metropolis;
|
||||
}
|
||||
|
||||
.itselectopen {
|
||||
@@ -130,12 +130,12 @@
|
||||
padding: 15px;
|
||||
background: #f2f2f2;
|
||||
border-radius: 8px;
|
||||
font-family: Montserrat-Regular, Montserrat;
|
||||
font-family: Metropolis-Regular, Metropolis;
|
||||
}
|
||||
|
||||
.bttj {
|
||||
font-size: 14px;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: bold;
|
||||
/* width: 212px; */
|
||||
/* height: 48px; */
|
||||
@@ -173,7 +173,7 @@
|
||||
|
||||
.iotbt1 {
|
||||
font-size: 18px;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
padding-bottom: 24px;
|
||||
padding-top: 40px;
|
||||
font-weight: 700;
|
||||
@@ -210,7 +210,7 @@
|
||||
|
||||
.iotbtp1 {
|
||||
font-size: 14px;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: bold;
|
||||
padding-bottom: 11px;
|
||||
word-break: break-word;
|
||||
@@ -219,7 +219,7 @@
|
||||
.iotbts1 {
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
color: #9e9e9f;
|
||||
word-break: break-word;
|
||||
}
|
||||
@@ -290,7 +290,7 @@
|
||||
font-size: 14px;
|
||||
padding-top: 12px;
|
||||
text-align: center;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
overflow-wrap: break-word;
|
||||
word-break: break-word;
|
||||
}
|
||||
@@ -302,7 +302,7 @@
|
||||
.sfbt1 {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: bold;
|
||||
padding-bottom: 24px;
|
||||
padding-top: 24px;
|
||||
@@ -333,7 +333,7 @@
|
||||
.cit {
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
font-family: Montserrat-Regular, Montserrat;
|
||||
font-family: Metropolis-Regular, Metropolis;
|
||||
color: #000;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -388,7 +388,7 @@
|
||||
.wcu_s1 {
|
||||
color: #000;
|
||||
font-size: 16px;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
font-weight: 500;
|
||||
padding: 20px 24px;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
font-size: 18px;
|
||||
color: #004bfa;
|
||||
text-align: left;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: 700;
|
||||
margin-top: 0;
|
||||
margin-bottom: 12px;
|
||||
@@ -27,7 +27,7 @@
|
||||
color: #707070;
|
||||
text-align: center;
|
||||
text-align: left;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
|
||||
.itlable {
|
||||
font-size: 12.5px;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
padding-bottom: 5px;
|
||||
@@ -106,7 +106,7 @@
|
||||
height: 48px;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
font-family: Montserrat-Regular, Montserrat;
|
||||
font-family: Metropolis-Regular, Metropolis;
|
||||
}
|
||||
|
||||
.itselectopen {
|
||||
@@ -130,13 +130,13 @@
|
||||
padding: 15px;
|
||||
background: #f2f2f2;
|
||||
border-radius: 8px;
|
||||
font-family: Montserrat-Regular, Montserrat;
|
||||
font-family: Metropolis-Regular, Metropolis;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.bttj {
|
||||
font-size: 14px;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: bold;
|
||||
/* width: 212px; */
|
||||
padding: 15px 60px;
|
||||
@@ -173,7 +173,7 @@
|
||||
|
||||
.iotbt1 {
|
||||
font-size: 18px;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
padding-bottom: 24px;
|
||||
padding-top: 40px;
|
||||
font-weight: 700;
|
||||
@@ -210,7 +210,7 @@
|
||||
|
||||
.iotbtp1 {
|
||||
font-size: 14px;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: bold;
|
||||
padding-bottom: 11px;
|
||||
word-break: break-word;
|
||||
@@ -219,7 +219,7 @@
|
||||
.iotbts1 {
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
color: #9e9e9f;
|
||||
word-break: break-word;
|
||||
}
|
||||
@@ -290,7 +290,7 @@
|
||||
font-size: 14px;
|
||||
padding-top: 12px;
|
||||
text-align: center;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
overflow-wrap: break-word;
|
||||
word-break: break-word;
|
||||
}
|
||||
@@ -302,7 +302,7 @@
|
||||
.sfbt1 {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: bold;
|
||||
padding-bottom: 24px;
|
||||
padding-top: 24px;
|
||||
@@ -333,7 +333,7 @@
|
||||
.cit {
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
font-family: Montserrat-Regular, Montserrat;
|
||||
font-family: Metropolis-Regular, Metropolis;
|
||||
color: #000;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -387,7 +387,7 @@
|
||||
.wcu_s1 {
|
||||
color: #000;
|
||||
font: 16px;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
font-weight: 500;
|
||||
padding: 20px 24px;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
margin-top: 3.3rem;
|
||||
}
|
||||
.oricoEGapp-Contact .banner_title {
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
font-size: 1.5rem;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
@@ -24,7 +24,7 @@
|
||||
color: #000;
|
||||
}
|
||||
.oricoEGapp-Contact .title {
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
font-size: 1rem;
|
||||
}
|
||||
.oricoEGapp-Contact .info {
|
||||
@@ -43,12 +43,12 @@
|
||||
height: 3rem;
|
||||
}
|
||||
.oricoEGapp-Contact .info .right .des {
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
}
|
||||
.oricoEGapp-Contact .info_title {
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
margin-bottom: 0.22rem;
|
||||
@@ -61,7 +61,7 @@
|
||||
}
|
||||
.oricoEGapp-Contact .question .title {
|
||||
margin-top: 0.5rem;
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
}
|
||||
@@ -86,7 +86,7 @@
|
||||
.oricoEGapp-Contact .send {
|
||||
display: block;
|
||||
background-color: #004bfa;
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
font-size: 0.875rem;
|
||||
padding: 0.75rem 1.5rem;
|
||||
color: #fff;
|
||||
@@ -98,7 +98,7 @@
|
||||
color: #ee2f53;
|
||||
}
|
||||
.oricoEGapp-Contact .contact_b {
|
||||
font-family: "Montserrat-SemiBold";
|
||||
font-family: "Metropolis-SemiBold";
|
||||
font-size: 1rem;
|
||||
padding-top: 1.125rem;
|
||||
padding-bottom: 1.125rem;
|
||||
@@ -119,42 +119,42 @@
|
||||
.oricoEGapp-Contact input::-webkit-input-placeholder {
|
||||
color: #9e9e9f;
|
||||
font-size: 0.875rem;
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
}
|
||||
.oricoEGapp-Contact input:-moz-placeholder {
|
||||
color: #9e9e9f;
|
||||
font-size: 0.875rem;
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
}
|
||||
.oricoEGapp-Contact input::-moz-placeholder {
|
||||
color: #9e9e9f;
|
||||
font-size: 0.875rem;
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
}
|
||||
.oricoEGapp-Contact input:-ms-input-placeholder {
|
||||
color: #9e9e9f;
|
||||
font-size: 0.875rem;
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
}
|
||||
.oricoEGapp-Contact textarea::-webkit-input-placeholder {
|
||||
color: #9e9e9f;
|
||||
font-size: 0.875rem;
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
}
|
||||
.oricoEGapp-Contact textarea:-moz-placeholder {
|
||||
color: #9e9e9f;
|
||||
font-size: 0.875rem;
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
}
|
||||
.oricoEGapp-Contact textarea::-moz-placeholder {
|
||||
color: #9e9e9f;
|
||||
font-size: 0.875rem;
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
}
|
||||
.oricoEGapp-Contact textarea:-ms-input-placeholder {
|
||||
color: #9e9e9f;
|
||||
font-size: 0.875rem;
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
}
|
||||
.oricoEGapp-Contact .narskfPage {
|
||||
width: 100%;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
margin-top: 3.3rem;
|
||||
}
|
||||
.oricoEGapp-Contact .banner_title {
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
font-size: 1.5rem;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
@@ -24,7 +24,7 @@
|
||||
color: #000;
|
||||
}
|
||||
.oricoEGapp-Contact .title {
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
font-size: 1rem;
|
||||
}
|
||||
.oricoEGapp-Contact .info {
|
||||
@@ -46,12 +46,12 @@
|
||||
width: 88% !important;
|
||||
}
|
||||
.oricoEGapp-Contact .info .right .des {
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
}
|
||||
.oricoEGapp-Contact .info_title {
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
margin-bottom: 0.22rem;
|
||||
@@ -64,7 +64,7 @@
|
||||
}
|
||||
.oricoEGapp-Contact .question .title {
|
||||
margin-top: 0.5rem;
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
}
|
||||
@@ -89,7 +89,7 @@
|
||||
.oricoEGapp-Contact .send {
|
||||
display: block;
|
||||
background-color: #004bfa;
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
font-size: 0.875rem;
|
||||
padding: 0.75rem 1.5rem;
|
||||
color: #fff;
|
||||
@@ -101,7 +101,7 @@
|
||||
color: #ee2f53;
|
||||
}
|
||||
.oricoEGapp-Contact .contact_b {
|
||||
font-family: "Montserrat-SemiBold";
|
||||
font-family: "Metropolis-SemiBold";
|
||||
font-size: 1rem;
|
||||
padding-top: 1.125rem;
|
||||
padding-bottom: 1.125rem;
|
||||
@@ -122,40 +122,40 @@
|
||||
.oricoEGapp-Contact input::-webkit-input-placeholder {
|
||||
color: #9e9e9f;
|
||||
font-size: 0.875rem;
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
}
|
||||
.oricoEGapp-Contact input:-moz-placeholder {
|
||||
color: #9e9e9f;
|
||||
font-size: 0.875rem;
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
}
|
||||
.oricoEGapp-Contact input::-moz-placeholder {
|
||||
color: #9e9e9f;
|
||||
font-size: 0.875rem;
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
}
|
||||
.oricoEGapp-Contact input:-ms-input-placeholder {
|
||||
color: #9e9e9f;
|
||||
font-size: 0.875rem;
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
}
|
||||
.oricoEGapp-Contact textarea::-webkit-input-placeholder {
|
||||
color: #9e9e9f;
|
||||
font-size: 0.875rem;
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
}
|
||||
.oricoEGapp-Contact textarea:-moz-placeholder {
|
||||
color: #9e9e9f;
|
||||
font-size: 0.875rem;
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
}
|
||||
.oricoEGapp-Contact textarea::-moz-placeholder {
|
||||
color: #9e9e9f;
|
||||
font-size: 0.875rem;
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
}
|
||||
.oricoEGapp-Contact textarea:-ms-input-placeholder {
|
||||
color: #9e9e9f;
|
||||
font-size: 0.875rem;
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@font-face {
|
||||
font-family: 'icomoon';
|
||||
src: url('../fonts/icomoon/icomoon.eot?11cuay');
|
||||
src: url('../fonts/icomoon/icomoon.eot?11cuay#iefix') format('embedded-opentype'), url('../fonts/icomoon/icomoon.ttf?11cuay') format('truetype'),
|
||||
src: url('../fonts/icomoon/icomoon.eot?11cuay#iefix') format('embedded-opentype'), url('../fonts/icomoon/icomoon.ttf?11cuay') format('opentype'),
|
||||
url('../fonts/icomoon/icomoon.woff?11cuay') format('woff'), url('../fonts/icomoon/icomoon.svg?11cuay#icomoon') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
@@ -54,7 +54,7 @@
|
||||
font-family: 'colleciton';
|
||||
src: url('../fonts/icomoon/colleciton/icomoon.eot?11cuay');
|
||||
src: url('../fonts/icomoon/colleciton/icomoon.eot?11cuay#iefix') format('embedded-opentype'),
|
||||
url('../fonts/icomoon/colleciton/icomoon.ttf?11cuay') format('truetype'), url('../fonts/icomoon/colleciton/icomoon.woff?11cuay') format('woff'),
|
||||
url('../fonts/icomoon/colleciton/icomoon.ttf?11cuay') format('opentype'), url('../fonts/icomoon/colleciton/icomoon.woff?11cuay') format('woff'),
|
||||
url('../fonts/icomoon/colleciton/icomoon.svg?11cuay#icomoon') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
@@ -83,7 +83,7 @@
|
||||
@font-face {
|
||||
font-family: 'icomoon';
|
||||
src: url('../fonts/icomoon/icomoona.eot?c46hgi');
|
||||
src: url('../fonts/icomoon/icomoona.eot?c46hgi#iefix') format('embedded-opentype'), url('../fonts/icomoon/icomoona.ttf?c46hgi') format('truetype'),
|
||||
src: url('../fonts/icomoon/icomoona.eot?c46hgi#iefix') format('embedded-opentype'), url('../fonts/icomoon/icomoona.ttf?c46hgi') format('opentype'),
|
||||
url('../fonts/icomoon/icomoona.woff?c46hgi') format('woff'), url('../fonts/icomoon/icomoona.svg?c46hgi#icomoon') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@font-face {
|
||||
font-family: 'icomoon';
|
||||
src: url('../fonts/icomoon/icomoon.eot?ujw7hy');
|
||||
src: url('../fonts/icomoon/icomoon.eot?ujw7hy#iefix') format('embedded-opentype'), url('../fonts/icomoon/icomoon.ttf?ujw7hy') format('truetype'),
|
||||
src: url('../fonts/icomoon/icomoon.eot?ujw7hy#iefix') format('embedded-opentype'), url('../fonts/icomoon/icomoon.ttf?ujw7hy') format('opentype'),
|
||||
url('../fonts/icomoon/icomoon.woff?ujw7hy') format('woff'), url('../fonts/icomoon/icomoon.svg?ujw7hy#icomoon') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
@@ -114,7 +114,7 @@
|
||||
font-family: 'icomoon01';
|
||||
src: url('fonts-20190124/icomoon.eot?ll2528');
|
||||
src: url('fonts-20190124/icomoon.eot?ll2528#iefix') format('embedded-opentype'),
|
||||
url('fonts-20190124/icomoon.ttf?ll2528') format('truetype'), url('fonts-20190124/icomoon.woff?ll2528') format('woff'),
|
||||
url('fonts-20190124/icomoon.ttf?ll2528') format('opentype'), url('fonts-20190124/icomoon.woff?ll2528') format('woff'),
|
||||
url('fonts-20190124/icomoon.svg?ll2528#icomoon') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
@@ -161,7 +161,7 @@
|
||||
@font-face {
|
||||
font-family: 'icomoon02';
|
||||
src: url('fonts/other/icomoon.eot?ujw7hy');
|
||||
src: url('fonts/other/icomoon.eot?ujw7hy#iefix') format('embedded-opentype'), url('fonts/other/icomoon.ttf?ujw7hy') format('truetype'),
|
||||
src: url('fonts/other/icomoon.eot?ujw7hy#iefix') format('embedded-opentype'), url('fonts/other/icomoon.ttf?ujw7hy') format('opentype'),
|
||||
url('fonts/other/icomoon.woff?ujw7hy') format('woff'), url('fonts/other/icomoon.svg?ujw7hy#icomoon') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
@@ -189,7 +189,7 @@
|
||||
font-family: 'icomoon05';
|
||||
src: url('fonts-20220322/icomoon.eot?cdcz43');
|
||||
src: url('fonts-20220322/icomoon.eot?cdcz43#iefix') format('embedded-opentype'),
|
||||
url('fonts-20220322/icomoon.ttf?cdcz43') format('truetype'), url('fonts-20220322/icomoon.woff?cdcz43') format('woff'),
|
||||
url('fonts-20220322/icomoon.ttf?cdcz43') format('opentype'), url('fonts-20220322/icomoon.woff?cdcz43') format('woff'),
|
||||
url('fonts-20220322/icomoon.svg?cdcz43#icomoon') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
display: none;
|
||||
}
|
||||
.oircoEgapp-head .top-menu .it-ct {
|
||||
font-family: "Montserrat-SemiBold";
|
||||
font-family: "Metropolis-SemiBold";
|
||||
font-weight: bold;
|
||||
}
|
||||
.oircoEgapp-head .top-menu .it-ct .it-1 {
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
@font-face {
|
||||
font-family: "Montserrat";
|
||||
src: url("../fonts/Montserrat-Regular.ttf") format("truetype");
|
||||
font-family: "Metropolis";
|
||||
src: url("../fonts/Metropolis-Regular.otf") format("opentype");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Montserrat-Bold";
|
||||
src: url("../fonts/Montserrat-Bold.ttf") format("truetype");
|
||||
font-family: "Metropolis-Bold";
|
||||
src: url("../fonts/Metropolis-Bold.ttf") format("opentype");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Montserrat-Medium";
|
||||
src: url("../fonts/Montserrat-Medium.ttf") format("truetype");
|
||||
font-family: "Metropolis-Medium";
|
||||
src: url("../fonts/Metropolis-Medium.ttf") format("opentype");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
/* font-family: 'Montserrat'; */
|
||||
/* font-family: 'Metropolis'; */
|
||||
-ms-overflow-style: none;
|
||||
/* IE 和 Edge */
|
||||
scrollbar-width: none;
|
||||
@@ -88,7 +88,7 @@ a {
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Montserrat-SemiBold';
|
||||
font-family: 'Metropolis-SemiBold';
|
||||
}
|
||||
|
||||
/* 分页样式 */
|
||||
@@ -114,7 +114,6 @@ body {
|
||||
background-color: #444444;
|
||||
color: #fff;
|
||||
}
|
||||
/*编辑器样式*/
|
||||
@charset "UTF-8";.ql-container {
|
||||
box-sizing: border-box;
|
||||
font-family: Helvetica,Arial,sans-serif;
|
||||
@@ -156,16 +155,15 @@ body {
|
||||
-moz-tab-size: 4;
|
||||
text-align: left;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word; /* 兼容旧浏览器 */
|
||||
overflow-wrap: break-word; /* 优先在空格处换行,避免单词拆分 */
|
||||
word-break: normal; /* 禁止强制拆分单词 */
|
||||
hyphens: auto; /* 可选:超长单词用连字符换行(更优雅) */
|
||||
word-wrap: break-word
|
||||
}
|
||||
|
||||
.ql-editor>* {
|
||||
cursor: text
|
||||
}
|
||||
|
||||
.ql-editor video{
|
||||
max-width: 100% !important;
|
||||
}
|
||||
.ql-editor p,.ql-editor ol,.ql-editor ul,.ql-editor pre,.ql-editor blockquote,.ql-editor h1,.ql-editor h2,.ql-editor h3,.ql-editor h4,.ql-editor h5,.ql-editor h6 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@@ -566,27 +564,15 @@ body {
|
||||
}
|
||||
|
||||
.ql-editor .ql-size-small {
|
||||
font-size: .75em;
|
||||
word-wrap: break-word; /* 兼容旧浏览器 */
|
||||
overflow-wrap: break-word; /* 优先在空格处换行,避免单词拆分 */
|
||||
word-break: normal; /* 禁止强制拆分单词 */
|
||||
hyphens: auto; /* 可选:超长单词用连字符换行(更优雅) */
|
||||
font-size: .75em
|
||||
}
|
||||
|
||||
.ql-editor .ql-size-large {
|
||||
font-size: 1.5em;
|
||||
word-wrap: break-word; /* 兼容旧浏览器 */
|
||||
overflow-wrap: break-word; /* 优先在空格处换行,避免单词拆分 */
|
||||
word-break: normal; /* 禁止强制拆分单词 */
|
||||
hyphens: auto; /* 可选:超长单词用连字符换行(更优雅) */
|
||||
font-size: 1.5em
|
||||
}
|
||||
|
||||
.ql-editor .ql-size-huge {
|
||||
font-size: 2.5em;
|
||||
word-wrap: break-word; /* 兼容旧浏览器 */
|
||||
overflow-wrap: break-word; /* 优先在空格处换行,避免单词拆分 */
|
||||
word-break: normal; /* 禁止强制拆分单词 */
|
||||
hyphens: auto; /* 可选:超长单词用连字符换行(更优雅) */
|
||||
font-size: 2.5em
|
||||
}
|
||||
|
||||
.ql-editor .ql-direction-rtl {
|
||||
@@ -1181,8 +1167,8 @@ body {
|
||||
}
|
||||
|
||||
.ql-editor {
|
||||
min-height: 600px;
|
||||
max-height: 600px;
|
||||
/* min-height: 600px;
|
||||
max-height: 600px; */
|
||||
overflow: auto
|
||||
}
|
||||
|
||||
@@ -1201,7 +1187,7 @@ body {
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label:before,.ql-snow .ql-picker.ql-size .ql-picker-item:before {
|
||||
content: "14px"
|
||||
content: "12px"
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=small]:before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]:before {
|
||||
@@ -1255,3 +1241,119 @@ body {
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=monospace]:before,.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=monospace]:before {
|
||||
content: "等宽字体"
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimSun]:before,.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimSun]:before {
|
||||
font-family: SimSun,sans-serif;
|
||||
content: "宋体"
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimHei]:before,.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimHei]:before {
|
||||
font-family: SimHei,sans-serif;
|
||||
content: "黑体"
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Microsoft-YaHei]:before,.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Microsoft-YaHei]:before {
|
||||
font-family: Microsoft YaHei,sans-serif;
|
||||
content: "微软雅黑"
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=KaiTi]:before,.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=KaiTi]:before {
|
||||
font-family: KaiTi,sans-serif;
|
||||
content: "楷体"
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=FangSong]:before,.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=FangSong]:before {
|
||||
font-family: FangSong,sans-serif;
|
||||
content: "仿宋"
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Arial]:before,.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Arial]:before {
|
||||
font-family: Arial,sans-serif;
|
||||
content: "Arial"
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Times-New-Roman]:before,.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Times-New-Roman]:before {
|
||||
font-family: Times New Roman,sans-serif;
|
||||
content: "Times New Roman"
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=sans-serif]:before,.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=sans-serif]:before {
|
||||
font-family: sans-serif;
|
||||
content: "sans-serif"
|
||||
}
|
||||
|
||||
.ql-font-SimSun {
|
||||
font-family: SimSun,sans-serif
|
||||
}
|
||||
|
||||
.ql-font-SimHei {
|
||||
font-family: SimHei,sans-serif
|
||||
}
|
||||
|
||||
.ql-font-Microsoft-YaHei {
|
||||
font-family: Microsoft YaHei,sans-serif
|
||||
}
|
||||
|
||||
.ql-font-KaiTi {
|
||||
font-family: KaiTi,sans-serif
|
||||
}
|
||||
|
||||
.ql-font-FangSong {
|
||||
font-family: FangSong,sans-serif
|
||||
}
|
||||
|
||||
.ql-font-Arial {
|
||||
font-family: Arial,sans-serif
|
||||
}
|
||||
|
||||
.ql-font-Times-New-Roman {
|
||||
font-family: Times New Roman,sans-serif
|
||||
}
|
||||
|
||||
.ql-font-sans-serif {
|
||||
font-family: sans-serif
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="12px"]:before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="12px"]:before {
|
||||
content: "12px"
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="14px"]:before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="14px"]:before {
|
||||
content: "14px"
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="16px"]:before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="16px"]:before {
|
||||
content: "16px"
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="18px"]:before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="18px"]:before {
|
||||
content: "18px"
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="20px"]:before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="20px"]:before {
|
||||
content: "20px"
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="22px"]:before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="22px"]:before {
|
||||
content: "22px"
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="24px"]:before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="24px"]:before {
|
||||
content: "24px"
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="26px"]:before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="26px"]:before {
|
||||
content: "26px"
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="28px"]:before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="28px"]:before {
|
||||
content: "28px"
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="30px"]:before,.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="30px"]:before {
|
||||
content: "30px"
|
||||
}
|
||||
|
||||
.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"
|
||||
}
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
@font-face {
|
||||
font-family: "Montserrat";
|
||||
src: url("../fonts/Montserrat-Regular.ttf") format("truetype");
|
||||
font-family: "Metropolis";
|
||||
src: url("../fonts/Metropolis-Regular.otf") format("opentype");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Montserrat-Bold";
|
||||
src: url("../fonts/Montserrat-Bold.ttf") format("truetype");
|
||||
font-family: "Metropolis-Bold";
|
||||
src: url("../fonts/Metropolis-Bold.otf") format("opentype");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Montserrat-Medium";
|
||||
src: url("../fonts/Montserrat-Medium.ttf") format("truetype");
|
||||
font-family: "Metropolis-Medium";
|
||||
src: url("../fonts/Metropolis-Medium.otf") format("opentype");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Montserrat-SemiBold";
|
||||
src: url("../fonts/Montserrat-SemiBold.ttf") format("truetype");
|
||||
font-family: "Metropolis-SemiBold";
|
||||
src: url("../fonts/Metropolis-SemiBold.otf") format("opentype");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
body {
|
||||
font-family: 'Montserrat-SemiBold';
|
||||
font-family: 'Metropolis-SemiBold';
|
||||
margin: auto;
|
||||
background-color: #f5f5f5;
|
||||
max-width: 750px;
|
||||
@@ -101,7 +101,7 @@ address {
|
||||
list-style: none;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
word-break: break-all;
|
||||
/* word-break: break-all; */
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
@@ -591,7 +591,7 @@ button.swiper-pagination-bullet {
|
||||
.Innew-text .title {
|
||||
font-size: 2.5rem;
|
||||
padding-bottom: 1rem;
|
||||
font-family: 'Montserrat-Bold';
|
||||
font-family: 'Metropolis-Bold';
|
||||
}
|
||||
.Inpro-text {
|
||||
padding: 2rem 0 0.8rem;
|
||||
@@ -600,7 +600,7 @@ button.swiper-pagination-bullet {
|
||||
.Inpro-text .title {
|
||||
font-size: 1.5rem;
|
||||
padding-bottom: 1rem;
|
||||
font-family: 'Montserrat-Bold';
|
||||
font-family: 'Metropolis-Bold';
|
||||
}
|
||||
|
||||
.Innew-text .more {
|
||||
@@ -635,7 +635,7 @@ video img {
|
||||
font-size: 1.2rem;
|
||||
max-height: 3rem;
|
||||
overflow: hidden;
|
||||
font-family: 'Montserrat-Bold';
|
||||
font-family: 'Metropolis-Bold';
|
||||
}
|
||||
.inprotext .t-f16 {
|
||||
font-size: 1rem;
|
||||
@@ -957,12 +957,12 @@ video img {
|
||||
margin: auto;
|
||||
line-height: 2rem;
|
||||
padding: 0 3rem;
|
||||
font-family: 'Montserrat-Bold';
|
||||
font-family: 'Metropolis-Bold';
|
||||
}
|
||||
.ban-t {
|
||||
padding: 0.5rem 3rem;
|
||||
font-size: 1.125rem;
|
||||
font-family: 'Montserrat-Regular';
|
||||
font-family: 'Metropolis-Regular';
|
||||
}
|
||||
.btn-more {
|
||||
background: transparent;
|
||||
@@ -979,7 +979,7 @@ video img {
|
||||
margin: auto;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
font-family: 'Montserrat-Bold';
|
||||
font-family: 'Metropolis-Bold';
|
||||
}
|
||||
/*类别*/
|
||||
.category {
|
||||
@@ -1095,11 +1095,11 @@ video img {
|
||||
padding: 0.2rem 0;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
font-family: 'Montserrat-Bold';
|
||||
font-family: 'Metropolis-Bold';
|
||||
}
|
||||
.num-bg li p {
|
||||
font-size: 0.8rem;
|
||||
font-family: 'Montserrat-Regular';
|
||||
font-family: 'Metropolis-Regular';
|
||||
}
|
||||
/*标题*/
|
||||
.Tech-text {
|
||||
@@ -1115,7 +1115,7 @@ video img {
|
||||
.Tech-text p {
|
||||
padding: 1rem 0;
|
||||
font-size: 0.875rem;
|
||||
font-family: 'Montserrat-Medium';
|
||||
font-family: 'Metropolis-Medium';
|
||||
}
|
||||
|
||||
.pos-text {
|
||||
@@ -1125,7 +1125,7 @@ video img {
|
||||
color: #fff;
|
||||
font-size: 0.825rem;
|
||||
margin: 0 auto;
|
||||
font-family: 'Montserrat-Bold';
|
||||
font-family: 'Metropolis-Bold';
|
||||
height: 2rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -1157,7 +1157,7 @@ video img {
|
||||
font-size: 0.9rem;
|
||||
padding: 1rem 0;
|
||||
line-height: 1.3em;
|
||||
font-family: 'Montserrat-Bold';
|
||||
font-family: 'Metropolis-Bold';
|
||||
word-break: break-all;
|
||||
}
|
||||
.faq span {
|
||||
@@ -1172,7 +1172,7 @@ video img {
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.75em;
|
||||
color: #666;
|
||||
font-family: 'Montserrat-Medium';
|
||||
font-family: 'Metropolis-Medium';
|
||||
}
|
||||
.faq i {
|
||||
position: absolute;
|
||||
@@ -1209,7 +1209,7 @@ video img {
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
height: 1.5rem;
|
||||
font-family: 'Montserrat-Medium';
|
||||
font-family: 'Metropolis-Medium';
|
||||
font-weight: 400;
|
||||
word-break: break-all;
|
||||
}
|
||||
@@ -1217,7 +1217,7 @@ video img {
|
||||
font-size: 1.125rem;
|
||||
color: #7f7f7f;
|
||||
padding-bottom: 1rem;
|
||||
font-family: 'Montserrat-Medium';
|
||||
font-family: 'Metropolis-Medium';
|
||||
font-weight: 400;
|
||||
}
|
||||
/*foot */
|
||||
@@ -1249,7 +1249,7 @@ video img {
|
||||
}
|
||||
.foot-in h3 {
|
||||
font-size: 1.25rem;
|
||||
font-family: 'Montserrat-Bold';
|
||||
font-family: 'Metropolis-Bold';
|
||||
font-weight: 100;
|
||||
}
|
||||
.logo-input {
|
||||
@@ -1278,7 +1278,7 @@ video img {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
.foot-cate li {
|
||||
width: 50%;
|
||||
min-width: 50%;
|
||||
display: inline-block;
|
||||
float: left;
|
||||
color: #fff;
|
||||
@@ -1292,7 +1292,7 @@ video img {
|
||||
.foot-cate li p {
|
||||
font-size: 0.7rem;
|
||||
line-height: 2.5rem;
|
||||
font-family: 'Montserrat-Medium';
|
||||
font-family: 'Metropolis-Medium';
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.foot-wei {
|
||||
@@ -1327,7 +1327,7 @@ video img {
|
||||
width: 100%;
|
||||
height: 1.2rem;
|
||||
cursor: pointer;
|
||||
font-family: 'Montserrat-Medium';
|
||||
font-family: 'Metropolis-Medium';
|
||||
}
|
||||
/*下拉*/
|
||||
.m_footer .left {
|
||||
@@ -1375,7 +1375,7 @@ video img {
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
padding-bottom: 0.5rem;
|
||||
font-family: 'Montserrat-Medium';
|
||||
font-family: 'Metropolis-Medium';
|
||||
}
|
||||
/*下拉*/
|
||||
.mask-up {
|
||||
@@ -1985,7 +1985,7 @@ video img {
|
||||
}
|
||||
.swiper-slide a {
|
||||
color: #000;
|
||||
font-family: 'Montserrat-SemiBold';
|
||||
font-family: 'Metropolis-SemiBold';
|
||||
}
|
||||
.swiper-slide img {
|
||||
max-width: 100%;
|
||||
@@ -2342,6 +2342,59 @@ video img {
|
||||
margin-bottom: 1.3rem;
|
||||
}
|
||||
|
||||
.products_des {
|
||||
width: 100%;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
.products_des img {
|
||||
width: 100%;
|
||||
}
|
||||
.de_t_n {
|
||||
font-size: 1.5em;
|
||||
color: #333;
|
||||
}
|
||||
.detail_title {
|
||||
text-align: center;
|
||||
padding: 2% 0;
|
||||
}
|
||||
.detail_title p {
|
||||
line-height: 2em;
|
||||
}
|
||||
.detail_con_a {
|
||||
margin: auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
.lj_detail_text,
|
||||
.lj_detail_texts {
|
||||
font-size: 0.875em;
|
||||
}
|
||||
.lj_detail_text p {
|
||||
line-height: 1.6em;
|
||||
padding: 0.5% 0;
|
||||
}
|
||||
/*seo-pro*/
|
||||
.seo-pro h3 {
|
||||
font-size: 1.5em;
|
||||
text-align: center;
|
||||
color: #333;
|
||||
margin: 2% 0 1%;
|
||||
line-height: 1.2;
|
||||
font-weight: 400;
|
||||
}
|
||||
.seo-pro p {
|
||||
text-align: center;
|
||||
margin: 0 0 11px;
|
||||
}
|
||||
.seo-pro a {
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
}
|
||||
.sa_blue,
|
||||
.sa_blue a,
|
||||
.seo-pro a:hover {
|
||||
color: #009fdf;
|
||||
}
|
||||
|
||||
/*两列*/
|
||||
.list_two {
|
||||
width: 100%;
|
||||
@@ -2438,7 +2491,7 @@ video img {
|
||||
margin-right: 0px;
|
||||
line-height: 40px;
|
||||
font-weight: 600;
|
||||
font-family: Montserrat !important;
|
||||
font-family: Metropolis !important;
|
||||
color: #666;
|
||||
text-align: left;
|
||||
}
|
||||
@@ -3426,26 +3479,26 @@ video img {
|
||||
font-size: 1.5rem;
|
||||
width: 90%;
|
||||
margin: 4rem auto 0;
|
||||
font-family: 'Montserrat-Bold';
|
||||
font-family: 'Metropolis-Bold';
|
||||
}
|
||||
.timedesin {
|
||||
font-size: 0.875rem;
|
||||
padding: 0.5rem 1rem;
|
||||
line-height: 1.3rem;
|
||||
width: 90%;
|
||||
font-family: 'Montserrat-Medium';
|
||||
font-family: 'Metropolis-Medium';
|
||||
}
|
||||
.timeblue {
|
||||
color: #004bfa;
|
||||
font-size: 1.125rem;
|
||||
font-family: 'Montserrat-Medium';
|
||||
font-family: 'Metropolis-Medium';
|
||||
}
|
||||
.timeblue img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.timeblue a {
|
||||
color: #004bfa;
|
||||
font-family: 'Montserrat-Medium';
|
||||
font-family: 'Metropolis-Medium';
|
||||
}
|
||||
/*视频*/
|
||||
.video-youtu {
|
||||
@@ -3505,7 +3558,7 @@ video img {
|
||||
}
|
||||
.vision-title {
|
||||
font-size: 1rem;
|
||||
font-family: 'Montserrat-Bold';
|
||||
font-family: 'Metropolis-Bold';
|
||||
width: 98%;
|
||||
margin: 1rem auto 0;
|
||||
}
|
||||
@@ -3513,7 +3566,7 @@ video img {
|
||||
font-size: 0.875;
|
||||
line-height: 1.5rem;
|
||||
color: #707070;
|
||||
font-family: 'Montserrat-Regular';
|
||||
font-family: 'Metropolis-Regular';
|
||||
width: 98%;
|
||||
margin: 1rem auto;
|
||||
}
|
||||
@@ -3531,7 +3584,7 @@ video img {
|
||||
}
|
||||
.brand_title {
|
||||
font-size: 1.125rem;
|
||||
font-family: 'Montserrat-Bold';
|
||||
font-family: 'Metropolis-Bold';
|
||||
width: 98%;
|
||||
margin: 1rem auto 0;
|
||||
position: relative;
|
||||
@@ -3549,7 +3602,7 @@ video img {
|
||||
font-size: 0.875;
|
||||
line-height: 1.5rem;
|
||||
color: #000000;
|
||||
font-family: 'Montserrat-Regular';
|
||||
font-family: 'Metropolis-Regular';
|
||||
width: 98%;
|
||||
margin: 1rem auto;
|
||||
}
|
||||
@@ -3602,7 +3655,7 @@ video::-webkit-media-controls-current-time-display {
|
||||
}
|
||||
.m_ach .title {
|
||||
font-size: 1.125rem;
|
||||
font-family: 'Montserrat-Bold';
|
||||
font-family: 'Metropolis-Bold';
|
||||
width: 98%;
|
||||
margin: 1rem auto 0;
|
||||
position: relative;
|
||||
@@ -3627,7 +3680,7 @@ video::-webkit-media-controls-current-time-display {
|
||||
}
|
||||
.m_ach .list-num li p {
|
||||
color: #707070;
|
||||
font-family: 'Montserrat-Regular';
|
||||
font-family: 'Metropolis-Regular';
|
||||
}
|
||||
/*新闻评测*/
|
||||
.news-vertu {
|
||||
@@ -3923,7 +3976,7 @@ video::-webkit-media-controls-current-time-display {
|
||||
border-radius: 8px;
|
||||
height: 48px;
|
||||
box-shadow: none;
|
||||
font-family: Montserrat-Regular, Montserrat;
|
||||
font-family: Metropolis-Regular, Metropolis;
|
||||
}
|
||||
.comment_area {
|
||||
width: 100% !important;
|
||||
|
||||
@@ -40,9 +40,12 @@
|
||||
}
|
||||
|
||||
.narshelpCenterdetail-app .nhlp-app-content {
|
||||
margin: 1.25rem;
|
||||
/* margin: 1rem; */
|
||||
height: 100%;
|
||||
margin-top: 9.2vh;
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
margin-top: 5rem;
|
||||
}
|
||||
|
||||
.narshelpCenterdetail-app #rendered-content img {
|
||||
@@ -216,4 +219,32 @@
|
||||
.narshelpCenterdetail-app .nhlpapp-pagescate .nars-hlpdt-ml .sub-list li a:hover {
|
||||
color: #1f2635;
|
||||
border-bottom: 1px solid #1f2635;
|
||||
}
|
||||
|
||||
/*9.18 添加三级样式*/
|
||||
|
||||
.narshelpCenterdetail-app .nhlpapp-pagescate .nars-hlpdt-ml .sub-list .two-mues {
|
||||
position: relative;
|
||||
|
||||
}
|
||||
|
||||
.narshelpCenterdetail-app .nhlpapp-pagescate .nars-hlpdt-ml .sub-list .two-mues .two-a {
|
||||
position: relative;
|
||||
padding-top: 6px;
|
||||
display: flex;
|
||||
font-size: 0.95rem !important;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.narshelpCenterdetail-app .nhlpapp-pagescate .nars-hlpdt-ml .sub-list .two-mues .two-a:hover {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.narshelpCenterdetail-app .nhlpapp-pagescate .nars-hlpdt-ml .sub-list .thress-mues {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.narshelpCenterdetail-app .nhlpapp-pagescate .nars-hlpdt-ml .sub-list .thress-mues a {
|
||||
padding-top: 0.375rem;
|
||||
padding-left: 1.875rem;
|
||||
}
|
||||
@@ -0,0 +1,320 @@
|
||||
/* 核心模块:固定90%宽度(PC端),优化移动端边距 */
|
||||
.advantage-section {
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
padding: 4rem 0 3rem 0;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
height: auto !important;
|
||||
min-height: auto !important;
|
||||
}
|
||||
|
||||
/* 标题容器:恢复原有居中样式 */
|
||||
.advantage-section__title {
|
||||
font-size: clamp(1.5rem, 3vw, 2rem);
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
color: #333;
|
||||
line-height: 1.2;
|
||||
margin-bottom: clamp(1.5rem, 2vw, 2.5rem);
|
||||
}
|
||||
|
||||
/* 列表容器:强制设置高度相关属性,确保内容正常显示 */
|
||||
.advantage-section__list {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
gap: clamp(0.1rem, 0.3vw, 0.8rem);
|
||||
width: 100% !important;
|
||||
flex-wrap: nowrap;
|
||||
overflow: visible !important; /* 改为visible确保内容显示 */
|
||||
padding: 0 !important;
|
||||
/* 强制设置高度相关属性 */
|
||||
height: auto !important;
|
||||
min-height: 1px !important; /* 确保容器至少有高度 */
|
||||
position: relative !important; /* 建立BFC */
|
||||
}
|
||||
|
||||
/* 卡片包裹容器:确保为块级元素并继承高度 */
|
||||
.advantage-card-wrap {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
height: auto !important;
|
||||
min-height: 1px !important;
|
||||
}
|
||||
|
||||
/* 卡片核心:高度自适应内容 */
|
||||
.advantage-card {
|
||||
flex: 0 0 calc((100% - 4 * clamp(0.1rem, 0.3vw, 0.8rem)) / 5);
|
||||
min-width: calc((100% - 4 * clamp(0.1rem, 0.3vw, 0.8rem)) / 5);
|
||||
max-width: calc((100% - 4 * clamp(0.1rem, 0.3vw, 0.8rem)) / 5);
|
||||
border-radius: 0.5rem;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.1);
|
||||
transition: transform 0.3s ease;
|
||||
cursor: pointer;
|
||||
background: #fff;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
height: auto !important; /* 高度自适应内容 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 图片容器:设置为1:1比例 */
|
||||
.advantage-card__img {
|
||||
width: 100%;
|
||||
aspect-ratio: 1 / 1; /* 1:1图片比例 */
|
||||
object-fit: cover;
|
||||
background-color: #f9f9f9;
|
||||
display: block;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* 文字区域:flex垂直分布,确保标题和描述都垂直居中 */
|
||||
.advantage-card__content {
|
||||
width: 100%;
|
||||
padding: clamp(0.3rem, 0.4vw, 0.75rem);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
/* 标题容器:水平居中+内部两端对齐,同时垂直居中 */
|
||||
.advantage-card__heading-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: clamp(0.3rem, 0.5vw, 0.5rem);
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
/* 卡片标题:居左显示 */
|
||||
.advantage-card__heading {
|
||||
font-size: clamp(0.85rem, 1.5vw, 1.4rem);
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
line-height: 1.3;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* 卡片标题右侧箭头:自适应大小,与标题协调 */
|
||||
.card-arrow {
|
||||
color: #409eff;
|
||||
transition: transform 0.3s ease;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
/* 箭头大小根据标题字体大小自适应 */
|
||||
width: clamp(1rem, 1.8vw, 1.5rem);
|
||||
height: clamp(1rem, 1.8vw, 1.5rem);
|
||||
font-size: clamp(0.7rem, 1.2vw, 1.1rem);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* 卡片hover时箭头动画 */
|
||||
.advantage-card:hover .card-arrow {
|
||||
transform: translateX(3px);
|
||||
}
|
||||
|
||||
/* 描述文字:水平+垂直居中,与标题容器对齐 */
|
||||
.advantage-card__description {
|
||||
font-size: clamp(0.6rem, 0.9vw, 0.9rem);
|
||||
color: #78787a;
|
||||
line-height: 1.2;
|
||||
white-space: normal;
|
||||
overflow: hidden;
|
||||
width: 80%;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
|
||||
}
|
||||
|
||||
/* 卡片hover效果 */
|
||||
.advantage-card:hover {
|
||||
transform: scale(1.03);
|
||||
}
|
||||
|
||||
/* 箭头容器:自适应尺寸 */
|
||||
.arrow {
|
||||
position: relative;
|
||||
/* 箭头尺寸跟随card-arrow自适应 */
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 箭头线条基础样式:自适应粗细 */
|
||||
.arrow::before,
|
||||
.arrow::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
background-color: #fff;
|
||||
border-radius: clamp(0.05rem, 0.1vw, 0.1rem);
|
||||
/* 线条粗细自适应 */
|
||||
height: clamp(0.08rem, 0.15vw, 0.12rem);
|
||||
}
|
||||
|
||||
/* 右箭头:自适应长度 */
|
||||
.arrow-right::before {
|
||||
width: clamp(0.3rem, 0.7vw, 0.55rem);
|
||||
top: 50%;
|
||||
left: 0;
|
||||
transform: translateY(-50%) rotate(45deg);
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.arrow-right::after {
|
||||
width: clamp(0.3rem, 0.7vw, 0.55rem);
|
||||
top: 50%;
|
||||
left: 0;
|
||||
transform: translateY(-50%) rotate(-45deg);
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
/* 左箭头:自适应长度 */
|
||||
.arrow-left::before {
|
||||
width: clamp(0.3rem, 0.7vw, 0.55rem);
|
||||
top: 50%;
|
||||
right: 0;
|
||||
transform: translateY(-50%) rotate(-45deg);
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.arrow-left::after {
|
||||
width: clamp(0.3rem, 0.7vw, 0.55rem);
|
||||
top: 50%;
|
||||
right: 0;
|
||||
transform: translateY(-50%) rotate(45deg);
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
/* iPad Pro适配:和移动端一样一行展示2个,最后一个隐藏,字体放大 */
|
||||
@media (max-width: 1024px) and (min-width: 768px) {
|
||||
.advantage-section__list {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
height: auto !important;
|
||||
overflow: hidden !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.advantage-card-wrap {
|
||||
width: calc(50% - 7.5px) !important;
|
||||
float: left !important;
|
||||
margin: 0 0 15px 0 !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
.advantage-card-wrap:nth-child(odd) {
|
||||
margin-right: 15px !important;
|
||||
}
|
||||
|
||||
.advantage-card {
|
||||
width: 100% !important;
|
||||
min-width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
flex: none !important;
|
||||
height: auto !important;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 只显示前4个卡片,最后一个隐藏 */
|
||||
.advantage-card-wrap:nth-child(n+5) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.advantage-card__content {
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
padding: clamp(1rem, 3vw, 1.5rem) 0;
|
||||
}
|
||||
|
||||
.advantage-card__img {
|
||||
aspect-ratio: 1 / 1;
|
||||
max-height: 330px;
|
||||
}
|
||||
|
||||
/* 平板端字体放大 */
|
||||
.advantage-card__heading {
|
||||
font-size: clamp(1.1rem, 2vw, 1.6rem);
|
||||
}
|
||||
|
||||
.advantage-card__description {
|
||||
font-size: clamp(0.85rem, 1.3vw, 1.1rem);
|
||||
|
||||
}
|
||||
|
||||
.card-arrow {
|
||||
width: clamp(1.2rem, 2vw, 1.7rem);
|
||||
height: clamp(1.2rem, 2vw, 1.7rem);
|
||||
font-size: clamp(0.9rem, 1.5vw, 1.3rem);
|
||||
}
|
||||
}
|
||||
|
||||
/* 移动端布局调整:彻底修复高度为0问题 */
|
||||
@media (max-width: 767px) {
|
||||
/* 使用block布局+浮动确保高度正常 */
|
||||
.advantage-section__list {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
height: auto !important;
|
||||
overflow: hidden !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* 卡片包裹容器:使用浮动实现一行2个 */
|
||||
.advantage-card-wrap {
|
||||
width: calc(50% - 7.5px) !important;
|
||||
float: left !important;
|
||||
margin: 0 0 15px 0 !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
/* 偶数个卡片添加右边距 */
|
||||
.advantage-card-wrap:nth-child(odd) {
|
||||
margin-right: 15px !important;
|
||||
}
|
||||
|
||||
/* 卡片尺寸调整 */
|
||||
.advantage-card {
|
||||
width: 100% !important;
|
||||
min-width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
flex: none !important;
|
||||
height: auto !important;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 只显示前4个卡片 */
|
||||
.advantage-card-wrap:nth-child(n+5) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.advantage-card__img {
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
|
||||
.advantage-card__content {
|
||||
flex-grow: 1;
|
||||
padding: clamp(1rem, 3vw, 1.5rem) 0; /* 平板端底部内边距稍大 */
|
||||
}
|
||||
}
|
||||
|
||||
/* 超小屏进一步优化 */
|
||||
@media (max-width: 374px) {
|
||||
.advantage-card-wrap {
|
||||
width: calc(50% - 5px) !important;
|
||||
}
|
||||
|
||||
.advantage-card-wrap:nth-child(odd) {
|
||||
margin-right: 10px !important;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
.prodline-footer-box{
|
||||
width: 100%;
|
||||
padding: 3rem 0;
|
||||
}
|
||||
.prodline-footer-box-img {
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.prodline-footer-box-img img {
|
||||
width: 100%;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 1. 根字体适配:限制最小根字体为14px,从源头避免文字过小 */
|
||||
html {
|
||||
/* PC端(≥1024px):1rem=16px(原尺寸) */
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* 平板端(768px~1023px):15px→16px(过渡,最小15px) */
|
||||
@media (max-width: 1023px) and (min-width: 768px) {
|
||||
html {
|
||||
font-size: calc(15px + (16 - 15) * (100vw - 768px) / (1023 - 768));
|
||||
}
|
||||
}
|
||||
|
||||
/* 移动端(320px~767px):固定14px(不随屏幕缩小而变小,避免文字<12px) */
|
||||
@media (max-width: 767px) {
|
||||
html {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 超小屏(≤320px):仍固定14px,彻底杜绝文字过小 */
|
||||
@media (max-width: 320px) {
|
||||
html {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
body {
|
||||
background: rgb(242, 243, 245);
|
||||
/* margin:0 !important; */
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
}
|
||||
.more {
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding-top: clamp(1.5rem, 3vw, 3rem);
|
||||
}
|
||||
.more-img {
|
||||
background: #000;
|
||||
color: #fff;
|
||||
font-size: clamp(0.6rem, 0.9vw, 0.9rem);
|
||||
border-radius: clamp(0.875rem, 1.5vw, 1.125rem);
|
||||
padding: clamp(0.1rem, 0.3vw, 0.2rem);
|
||||
width: 5rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
height: clamp(1.5rem, 3vw, 3rem);
|
||||
}
|
||||
.header {
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
height: 60px;
|
||||
}
|
||||
.header-img {
|
||||
margin: 0 auto;
|
||||
width: 90%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
79
public/static/index/mobile/css/topic_power_prodline/mask.css
Normal file
79
public/static/index/mobile/css/topic_power_prodline/mask.css
Normal file
@@ -0,0 +1,79 @@
|
||||
/* 蒙版样式 - 新增触摸事件禁止 */
|
||||
.mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
display: none;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 9999;
|
||||
overflow: hidden; /* 阻止蒙版自身滚动 */
|
||||
touch-action: none; /* 禁止触摸行为 */
|
||||
pointer-events: auto; /* 确保蒙版能接收事件 */
|
||||
}
|
||||
|
||||
/* 蒙版内容容器 - 新增触摸事件传递控制 */
|
||||
.mask-content {
|
||||
width: 80%;
|
||||
height: 100%;
|
||||
background: rgb(242, 243, 245);
|
||||
border-radius: 12px;
|
||||
overflow: hidden; /* 内容容器不滚动 */
|
||||
position: relative;
|
||||
animation: popIn 0.3s ease;
|
||||
max-height: 90vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
pointer-events: auto; /* 确保内容区域能正常交互 */
|
||||
}
|
||||
|
||||
/* 滚动内容容器 - 保持不变 */
|
||||
.mask-scroll-content {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 20px;
|
||||
-webkit-overflow-scrolling: touch; /* 移动端顺滑滚动 */
|
||||
}
|
||||
|
||||
/* 升级:同时禁止 html 和 body 滚动(关键兼容) */
|
||||
.no-scroll {
|
||||
overflow: hidden !important;
|
||||
position: fixed !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
/* 其他原有样式保持不变 */
|
||||
@keyframes popIn {
|
||||
from {
|
||||
transform: scale(0.8);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s ease;
|
||||
z-index: 10;
|
||||
}
|
||||
.close-btn:hover {
|
||||
background-color: #ff4d4f;
|
||||
}
|
||||
96
public/static/index/mobile/css/topic_power_prodline/nav.css
Normal file
96
public/static/index/mobile/css/topic_power_prodline/nav.css
Normal file
@@ -0,0 +1,96 @@
|
||||
.nav-box {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
width: 90%;
|
||||
/* 平板/PC端限制最大宽度 */
|
||||
margin: 0 auto;
|
||||
background-color: #fff;
|
||||
border-radius: 3.125rem;
|
||||
/* 50px→3.125rem */
|
||||
box-shadow: 0 0.125rem 0.9375rem rgba(0, 0, 0, 0.05);
|
||||
/* 2px→0.125rem,15px→0.9375rem */
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding: 0.625rem 0;
|
||||
/* 10px→0.625rem(原内边距不变) */
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.625rem;
|
||||
/* 10px→0.625rem */
|
||||
cursor: pointer;
|
||||
padding: 0.625rem 0 1.25rem;
|
||||
/* 10px→0.625rem,20px→1.25rem */
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
flex: 1;
|
||||
min-width: 3rem;
|
||||
/* 48px→3rem(适配14px根字体) */
|
||||
max-width: 5rem;
|
||||
/* 80px→5rem */
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.nav-item img {
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
/* 60px→3.75rem(16px基准),14px根字体下≈52.5px,仍清晰 */
|
||||
object-fit: contain;
|
||||
border-radius: 0.75rem;
|
||||
/* 12px→0.75rem */
|
||||
position: absolute;
|
||||
top: -3.125rem;
|
||||
/* -50px→-3.125rem(14px根字体下≈43.75px,超出效果不变) */
|
||||
transform: translateY(0.625rem);
|
||||
/* 10px→0.625rem */
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.nav-item:hover img {
|
||||
transform: translateY(0.3125rem);
|
||||
/* 5px→0.3125rem */
|
||||
}
|
||||
|
||||
.nav-item:active img {
|
||||
transform: translateY(0.4375rem);
|
||||
/* 7px→0.4375rem */
|
||||
box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
/* 关键:文字单独控制,确保最小12px */
|
||||
.nav-item p {
|
||||
margin: 0;
|
||||
/* PC端:15px→0.9375rem(16px根字体) */
|
||||
font-size: 0.9375rem;
|
||||
color: #37373e;
|
||||
font-weight: 500;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
top: 1.125rem;
|
||||
/* 18px→1.125rem */
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
padding: 0 0.125rem;
|
||||
}
|
||||
|
||||
/* 平板端文字:14px→0.9375rem(15px根字体下=14px) */
|
||||
@media (max-width: 1023px) and (min-width: 768px) {
|
||||
.nav-item p {
|
||||
font-size: 0.9375rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* 移动端文字:强制12px(用px兜底,避免rem计算后过小) */
|
||||
@media (max-width: 767px) {
|
||||
.nav-item p {
|
||||
font-size: 12px;
|
||||
/* 直接用px固定最小尺寸,优先级最高 */
|
||||
font-size: clamp(12px, 0.857rem, 0.9375rem);
|
||||
/* 增强版:最小12px,默认0.857rem(14px根字体下≈12px),最大0.9375rem */
|
||||
}
|
||||
}
|
||||
184
public/static/index/mobile/css/topic_power_prodline/product.css
Normal file
184
public/static/index/mobile/css/topic_power_prodline/product.css
Normal file
@@ -0,0 +1,184 @@
|
||||
.product-box {
|
||||
background: #fff;
|
||||
padding: clamp(1.5rem, 3vw, 3rem) 0;
|
||||
/* 产品块之间留间距 */
|
||||
}
|
||||
|
||||
.product-title {
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
padding-bottom: clamp(1.5rem, 3vw, 3rem);
|
||||
}
|
||||
|
||||
.product-title-h2 {
|
||||
font-size: clamp(1.5rem, 3vw, 2.25rem);
|
||||
/* padding-top: clamp(1.5rem, 3vw, 3rem); */
|
||||
}
|
||||
|
||||
.product-title-p {
|
||||
font-size: clamp(0.875rem, 1.5vw, 1.125rem);
|
||||
color: #646464;
|
||||
margin-top: clamp(0.5rem, 1vw, 0.75rem);
|
||||
}
|
||||
|
||||
/* 容器布局:两个产品通用 */
|
||||
.product-container {
|
||||
display: flex;
|
||||
gap: clamp(0.4rem, 1vw, 0.71rem);
|
||||
margin: 0 auto;
|
||||
width: 90%;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
/* 左侧容器:两个产品通用 */
|
||||
.product-left {
|
||||
flex: 1.8;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.product-img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border-radius: 10px;
|
||||
display: block;
|
||||
/* 取消图片底部空隙 */
|
||||
}
|
||||
|
||||
/* 悬浮图公共样式:两个产品尺寸完全一致(100%宽度) */
|
||||
.product-img-hover {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
|
||||
/* 两个产品悬浮图宽度相同 */
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.product-img-hover img {
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
/* 图片尺寸100%,无区别 */
|
||||
height: auto;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
/* 第一个产品:悬浮图居中上移(仅定位差异) */
|
||||
.product-img-1 {
|
||||
top: -10%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
/* 第二个产品:悬浮图上右超出(仅定位差异) */
|
||||
.product-img-2 {
|
||||
top: -10%;
|
||||
/* 上超出 */
|
||||
transform: none;
|
||||
width: 108%;
|
||||
/* 取消居中 */
|
||||
}
|
||||
|
||||
/* 右侧容器:两个产品通用 */
|
||||
.product-right {
|
||||
flex: 3.2;
|
||||
position: relative;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
background-color: #f5f5f5;
|
||||
align-self: stretch;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.right-content {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.right-video {
|
||||
display: none;
|
||||
}
|
||||
.video-play-btn {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
z-index: 2;
|
||||
display: none; /* 默认隐藏 */
|
||||
}
|
||||
|
||||
/* 播放图标默认显示,暂停图标默认隐藏 */
|
||||
.play-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
.pause-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* .paused类时切换图标 */
|
||||
.video-play-btn.paused .play-icon {
|
||||
display: none;
|
||||
}
|
||||
.video-play-btn.paused .pause-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* 视频显示时按钮可见 */
|
||||
.right-video[playing] ~ .video-play-btn,
|
||||
.product-right:hover .video-play-btn {
|
||||
opacity: 1;
|
||||
display: block;
|
||||
}
|
||||
/* PC端适配:仅微调定位参数,尺寸不变 */
|
||||
@media (min-width: 1024px) {
|
||||
.product-container {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.product-left {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
.product-right {
|
||||
flex: 5;
|
||||
}
|
||||
|
||||
/* 宽度保持一致,仅调定位偏移 */
|
||||
.product-img-1 {
|
||||
top: -11%;
|
||||
}
|
||||
|
||||
.product-img-2 {
|
||||
top: -12%;
|
||||
}
|
||||
}
|
||||
|
||||
/* 超小屏适配:尺寸不变,微调定位 */
|
||||
@media (max-width: 375px) {
|
||||
.product-left {
|
||||
flex: 1.5;
|
||||
}
|
||||
|
||||
.product-right {
|
||||
flex: 3.5;
|
||||
}
|
||||
|
||||
/* 宽度仍保持一致 */
|
||||
.product-img-1 {
|
||||
top: -6%;
|
||||
}
|
||||
|
||||
.product-img-2 {
|
||||
top: -8%;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
.product-card-container2 {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
gap: 10px;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
/* 产品卡片样式 */
|
||||
.product-card2 {
|
||||
box-sizing: border-box;
|
||||
background: rgb(242, 243, 245);
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
flex: 1 1 50%;
|
||||
/* 一行2个 */
|
||||
min-width: 180px;
|
||||
/* 保证图片显示 */
|
||||
/* max-width: calc(50% - 10px); */
|
||||
/* 适配gap */
|
||||
height: 240px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
|
||||
display: flex;
|
||||
text-decoration: none;
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 核心修改:文字区域相对于父盒子居中,内部内容左对齐 */
|
||||
.product-text2 {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
/* 文字区域整体水平居中(相对于product-card1) */
|
||||
justify-content: center;
|
||||
/* 文字区域整体垂直居中(相对于product-card1) */
|
||||
text-align: left;
|
||||
/* 内部文字左对齐 */
|
||||
min-width: 70px;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 内部内容容器:统一承载标题、描述、链接,确保左对齐一致性 */
|
||||
.product-text-content2 {
|
||||
width: 100%;
|
||||
/* 继承product-text的宽度,确保左对齐范围完整 */
|
||||
max-width: 280px;
|
||||
/* 新增:限制最大宽度,避免PC端父容器过宽时内容排版松散 */
|
||||
}
|
||||
|
||||
/* 标题:超出一行显示省略号(左对齐) */
|
||||
.product-card-title2 {
|
||||
font-size: clamp(12px, 2vw, 18px);
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 5px;
|
||||
letter-spacing: 0.2px;
|
||||
/* 超出一行省略号核心样式 */
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 100%;
|
||||
/* 基于内部容器左对齐,省略号生效 */
|
||||
}
|
||||
|
||||
/* 描述:超出2行显示省略号(左对齐) */
|
||||
.product-card-desc2 {
|
||||
font-size: clamp(12px, 1.8vw, 14px);
|
||||
color: #656565;
|
||||
margin-bottom: 15px;
|
||||
letter-spacing: 0.1px;
|
||||
/* 超出2行显示省略号核心样式 */
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
white-space: normal;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 100%;
|
||||
/* 基于内部容器左对齐 */
|
||||
line-height: 1.4;
|
||||
/* 优化行高,2行高度适中 */
|
||||
}
|
||||
|
||||
/* 图片容器:确保移动端显示 */
|
||||
.product-card-img2 {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-width: 70px;
|
||||
/* 强制保留图片区域,避免被挤压 */
|
||||
}
|
||||
|
||||
.product-card-img2 img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
max-height: 144px;
|
||||
min-height: 80px;
|
||||
object-fit: contain;
|
||||
/* 保持图片比例完整,不拉伸 */
|
||||
}
|
||||
|
||||
/* 链接图标:左对齐(基于内部容器) */
|
||||
.product-card-link2 {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
/* 图标左对齐 */
|
||||
}
|
||||
|
||||
.product-card-link2 img {
|
||||
width: clamp(60px, 4vw, 76px);
|
||||
margin: 0;
|
||||
/* 清除居中margin */
|
||||
}
|
||||
|
||||
/* hover效果 */
|
||||
.product-card2:hover {
|
||||
transform: scale(1.03);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
/* 媒体查询:平板端(768px ~ 1023px) */
|
||||
@media (max-width: 1023px) and (min-width: 768px) {
|
||||
.product-card2 {
|
||||
height: 224px;
|
||||
min-width: 170px;
|
||||
}
|
||||
.product-text2 {
|
||||
padding-left: 20px;
|
||||
}
|
||||
.product-card-img2 img {
|
||||
max-height: 128px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 媒体查询:移动端(≤767px) */
|
||||
@media (max-width: 767px) {
|
||||
.product-card-box2 {
|
||||
margin-top: 19px;
|
||||
}
|
||||
|
||||
.product-card2 {
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.product-card-container2 {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.product-card2 {
|
||||
height: 208px;
|
||||
min-width: 160px;
|
||||
}
|
||||
|
||||
.product-card-img2 img {
|
||||
max-height: 120px;
|
||||
min-height: 72px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 媒体查询:小屏手机(≤375px) */
|
||||
@media (max-width: 375px) {
|
||||
.product-card2 {
|
||||
height: 192px;
|
||||
min-width: 140px;
|
||||
}
|
||||
|
||||
/* 强制文字最小12px,保证可读性 */
|
||||
.product-card-title2,
|
||||
.product-card-desc2 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.product-card-img2 img {
|
||||
max-height: 104px;
|
||||
min-height: 64px;
|
||||
}
|
||||
|
||||
.product-card2 {
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.product-card-link2 img {
|
||||
width: 40px;
|
||||
/* 固定图标尺寸,节省空间 */
|
||||
}
|
||||
}
|
||||
|
||||
/* 媒体查询:超小屏手机(≤320px) */
|
||||
@media (max-width: 320px) {
|
||||
.product-card2 {
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
.product-text2 {
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.product-card-img2 {
|
||||
min-width: 60px;
|
||||
/* 缩小图片区域最小宽度,平衡文字空间 */
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
/* 容器布局:通用基础样式(仅宽度、外边距,不涉及高度) */
|
||||
.product-card-box {
|
||||
width: 90%;
|
||||
margin: clamp(1rem, 2vw, 1.5rem) auto 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.product-card-container {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
overflow: visible !important; /* 改为visible,显示所有内容 */
|
||||
padding: 0 clamp(0.2rem, 0.6vw, 0.3rem);
|
||||
height: auto !important; /* 高度自适应内容 */
|
||||
}
|
||||
|
||||
/* 卡片包裹容器:确保不独占一行 */
|
||||
.product-card-wrap {
|
||||
display: contents; /* 让包裹容器不影响布局 */
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* ######################################################################### */
|
||||
/* 移动端+平板样式(max-width: 1023px)- 后续修改仅改这里 */
|
||||
/* ######################################################################### */
|
||||
@media (max-width: 1023px) {
|
||||
/* 卡片容器:移动端+平板特有 - 改为wrap换行,一行2个,高度自适应 */
|
||||
.product-card-container {
|
||||
align-items: flex-start; /* 改为flex-start,避免拉伸 */
|
||||
flex-wrap: wrap !important; /* 强制开启换行 */
|
||||
justify-content: flex-start !important; /* 左对齐 */
|
||||
gap: clamp(0.5rem, 1vw, 1rem) !important; /* 设置间距 */
|
||||
padding: 0 clamp(0.2rem, 0.6vw, 0.3rem) clamp(1rem, 2vw, 1.5rem) !important;
|
||||
height: auto !important; /* 高度自适应内容 */
|
||||
}
|
||||
|
||||
/* 卡片包裹容器:移动端+平板适配 */
|
||||
.product-card-wrap {
|
||||
display: block !important;
|
||||
width: calc(50% - clamp(0.25rem, 0.5vw, 0.5rem)) !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
height: auto !important; /* 高度自适应 */
|
||||
}
|
||||
|
||||
/* 卡片核心:移动端+平板改为一行2个,高度自适应内容 */
|
||||
.product-card {
|
||||
background: rgb(242, 243, 245);
|
||||
border-radius: clamp(0.375rem, 1vw, 0.5rem);
|
||||
cursor: pointer;
|
||||
width: 100% !important; /* 卡片宽度100%,由包裹容器控制 */
|
||||
flex: none;
|
||||
box-shadow: 0 clamp(0.1rem, 0.2vw, 0.125rem)
|
||||
clamp(0.3rem, 0.8vw, 0.5rem) rgba(0, 0, 0, 0.05);
|
||||
margin: 0 !important; /* 移除margin,用gap控制间距 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: auto !important; /* 高度自适应内容 */
|
||||
}
|
||||
|
||||
/* 卡片hover效果:移动端+平板特有 */
|
||||
.product-card:hover {
|
||||
transform: scale(clamp(1.01, 1.02, 1.03));
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
/* 图片容器:移动端+平板固定占比 */
|
||||
.product-card-img {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
flex: 0 0 auto; /* 改为auto,高度自适应 */
|
||||
aspect-ratio: 3 / 2.8; /* 保持图片比例 */
|
||||
margin-bottom: clamp(0.4rem, 0.6vw, 0.5rem);
|
||||
overflow: hidden;
|
||||
border-radius: clamp(0.2rem, 0.4vw, 0.25rem);
|
||||
}
|
||||
|
||||
/* 产品图片:移动端+平板特有 */
|
||||
.product-card img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
object-position: center;
|
||||
}
|
||||
|
||||
/* 文字容器:移动端+平板高度自适应 */
|
||||
.product-card-text {
|
||||
flex: 1 1 auto; /* 改为flex:1,高度自适应内容 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding-left: clamp(0.8rem, 2vw, 1.5rem);
|
||||
padding-right: clamp(0.8rem, 2vw, 1.5rem);
|
||||
height: auto !important; /* 高度自适应 */
|
||||
}
|
||||
|
||||
/* 标题样式:移动端+平板特有,高度自适应 */
|
||||
.product-card-title {
|
||||
font-size: clamp(0.8rem, 1.3vw, 1.2rem);
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
height: auto !important; /* 移除固定高度 */
|
||||
margin-bottom: clamp(0.2rem, 0.4vw, 0.3rem); /* 添加间距 */
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* 描述样式:移动端+平板高度自适应 */
|
||||
.product-card-desc {
|
||||
font-size: clamp(0.7rem, 1.1vw, 0.9rem);
|
||||
color: #656565;
|
||||
word-break: break-word;
|
||||
height: auto !important; /* 移除固定高度 */
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
/* 链接图标容器:移动端+平板高度自适应,添加较小的底部内边距 */
|
||||
.product-card-link {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 0 0 auto; /* 改为auto,高度自适应 */
|
||||
padding: clamp(0.5rem, 1vw, 0.8rem); /* 减小上下内边距 */
|
||||
padding-bottom: clamp(1rem, 3vw, 1.5rem); /* 更小的底部内边距(约12px) */
|
||||
padding-left: clamp(0.8rem, 2vw, 1.5rem);
|
||||
height: auto !important; /* 高度自适应 */
|
||||
}
|
||||
|
||||
/* 链接图标:移动端+平板特有 */
|
||||
.product-card-link img {
|
||||
width: clamp(2.5rem, 5vw, 4.5rem);
|
||||
height: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
/* 平板端(768px-1023px)补充样式 */
|
||||
@media (min-width: 768px) and (max-width: 1023px) {
|
||||
.product-card-img {
|
||||
aspect-ratio: 3 / 2.8; /* 保持图片比例 */
|
||||
}
|
||||
|
||||
.product-card-link img {
|
||||
width: clamp(5rem, 4vw, 6rem);
|
||||
}
|
||||
|
||||
/* 平板端字体稍大 */
|
||||
.product-card-title {
|
||||
font-size: clamp(1rem, 1.5vw, 1.4rem);
|
||||
}
|
||||
|
||||
.product-card-desc {
|
||||
font-size: clamp(0.85rem, 1.2vw, 1rem);
|
||||
}
|
||||
|
||||
/* 平板端底部内边距稍大但仍较小 */
|
||||
.product-card-link {
|
||||
padding-bottom: clamp(1rem, 3vw, 1.5rem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ######################################################################### */
|
||||
/* PC端样式(单独配置,min-width: 1024px)- 后续修改仅改这里 */
|
||||
/* ######################################################################### */
|
||||
@media (min-width: 1024px) {
|
||||
/* 卡片容器:PC端特有,高度自适应内容 */
|
||||
.product-card-container {
|
||||
align-items: flex-start; /* 改为flex-start,避免拉伸 */
|
||||
height: auto !important; /* 高度自适应内容 */
|
||||
}
|
||||
|
||||
/* 卡片包裹容器:PC端适配 */
|
||||
.product-card-wrap {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
/* 卡片核心:PC端高度自适应内容 */
|
||||
.product-card {
|
||||
background: rgb(242, 243, 245);
|
||||
border-radius: clamp(0.375rem, 1vw, 0.5rem);
|
||||
cursor: pointer;
|
||||
width: calc(25% - clamp(0.3rem, 0.5vw, 0.36rem));
|
||||
flex: none;
|
||||
box-shadow: 0 clamp(0.1rem, 0.2vw, 0.125rem)
|
||||
clamp(0.3rem, 0.8vw, 0.5rem) rgba(0, 0, 0, 0.05);
|
||||
margin: 0 clamp(0.16rem, 0.24vw, 0.2rem);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: auto !important; /* 高度自适应内容 */
|
||||
}
|
||||
|
||||
/* 卡片hover效果:PC端特有 */
|
||||
.product-card:hover {
|
||||
transform: scale(clamp(1.01, 1.02, 1.03));
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
/* 图片容器:PC端高度自适应 */
|
||||
.product-card-img {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
flex: 0 0 auto; /* 改为auto,高度自适应 */
|
||||
aspect-ratio: 3 / 2.8; /* 保持图片比例 */
|
||||
margin-bottom: clamp(0.4rem, 0.6vw, 0.5rem);
|
||||
overflow: hidden;
|
||||
border-radius: clamp(0.2rem, 0.4vw, 0.25rem);
|
||||
}
|
||||
|
||||
/* 产品图片:PC端特有 */
|
||||
.product-card img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
object-position: center;
|
||||
}
|
||||
|
||||
/* 文字容器:PC端高度自适应 */
|
||||
.product-card-text {
|
||||
flex: 1 1 auto; /* 改为flex:1,高度自适应内容 */
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding-left: clamp(0.8rem, 2vw, 1.5rem);
|
||||
padding-right: clamp(0.8rem, 2vw, 1.5rem);
|
||||
display: flex; /* 确保flex布局 */
|
||||
height: auto !important; /* 高度自适应 */
|
||||
}
|
||||
|
||||
/* 标题样式:PC端特有,高度自适应 */
|
||||
.product-card-title {
|
||||
font-size: clamp(0.8rem, 1.3vw, 1.2rem);
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
height: auto !important; /* 高度自适应 */
|
||||
margin-bottom: clamp(0.2rem, 0.4vw, 0.3rem); /* 添加间距 */
|
||||
line-height: 1.2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 描述样式:PC端高度自适应 */
|
||||
.product-card-desc {
|
||||
font-size: clamp(0.7rem, 1.1vw, 0.9rem);
|
||||
color: #656565;
|
||||
word-break: break-word;
|
||||
height: auto !important; /* 高度自适应 */
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
/* 链接图标容器:PC端高度自适应,添加较小的底部内边距 */
|
||||
.product-card-link {
|
||||
width: 100%;
|
||||
display: flex; /* 确保flex布局 */
|
||||
align-items: center;
|
||||
flex: 0 0 auto; /* 改为auto,高度自适应 */
|
||||
padding-left: clamp(0.8rem, 2vw, 1.5rem);
|
||||
padding-bottom: clamp(1rem, 3vw, 1.5rem) ; /* 更小的底部内边距 */
|
||||
height: auto !important; /* 高度自适应 */
|
||||
}
|
||||
|
||||
/* 链接图标:PC端特有 */
|
||||
.product-card-link img {
|
||||
width: clamp(2.5rem, 5vw, 4.5rem);
|
||||
height: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
.swiper-container {
|
||||
padding: 0 !important;
|
||||
}
|
||||
/* 轮播容器 - 核心:基于视口高度自适应 */
|
||||
.auto-swiper-container {
|
||||
width: 100%;
|
||||
/* 关键:高度 = 视口高度的百分比(可调整,如60vh=屏幕高度60%) */
|
||||
margin-bottom: 5.625rem;
|
||||
max-height: 900px;
|
||||
min-height: 300px;
|
||||
position: relative;
|
||||
margin-top:60px;
|
||||
|
||||
}
|
||||
/* 轮播项 - 填充容器高度 */
|
||||
.auto-swiper-slide {
|
||||
width: 100%;
|
||||
/*height: 100%;*/
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
|
||||
/* 图片自适应核心:填充屏幕比例高度,保持比例 */
|
||||
.auto-swiper-slide img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain; /* 替换 cover 为 contain,完整显示图片 */
|
||||
display: block;
|
||||
|
||||
}
|
||||
|
||||
/* 轮播容器保持相对定位 */
|
||||
.auto-swiper-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 轮播容器保持相对定位 */
|
||||
.auto-swiper-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 指示标容器:居中排列 */
|
||||
.swiper-pagination {
|
||||
position: absolute;
|
||||
bottom: 10%; /* 距离底部的距离,可调整 */
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
/* width:100%;
|
||||
display: flex; */
|
||||
/* justify-content: center; */
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
/* 激活状态:白色长条 */
|
||||
.swiper-pagination-bullet-active {
|
||||
background:#fff !important;
|
||||
}
|
||||
|
||||
/* 未激活状态:黑色透明圆点(可调整透明度) */
|
||||
.swiper-pagination-bullet {
|
||||
display: inline-block;
|
||||
width: 16px !important;
|
||||
height: 16px !important;
|
||||
border-radius: 8px;
|
||||
/*background: #555;*/
|
||||
margin: 0 5px;
|
||||
/*opacity: 0.8;*/
|
||||
border: 1px solid #fff;
|
||||
/*cursor: pointer;*/
|
||||
}
|
||||
|
||||
BIN
public/static/index/mobile/fonts/Metropolis-Black.otf
Normal file
BIN
public/static/index/mobile/fonts/Metropolis-Black.otf
Normal file
Binary file not shown.
BIN
public/static/index/mobile/fonts/Metropolis-BlackItalic.otf
Normal file
BIN
public/static/index/mobile/fonts/Metropolis-BlackItalic.otf
Normal file
Binary file not shown.
BIN
public/static/index/mobile/fonts/Metropolis-Bold.otf
Normal file
BIN
public/static/index/mobile/fonts/Metropolis-Bold.otf
Normal file
Binary file not shown.
BIN
public/static/index/mobile/fonts/Metropolis-BoldItalic.otf
Normal file
BIN
public/static/index/mobile/fonts/Metropolis-BoldItalic.otf
Normal file
Binary file not shown.
BIN
public/static/index/mobile/fonts/Metropolis-ExtraBold.otf
Normal file
BIN
public/static/index/mobile/fonts/Metropolis-ExtraBold.otf
Normal file
Binary file not shown.
BIN
public/static/index/mobile/fonts/Metropolis-ExtraBoldItalic.otf
Normal file
BIN
public/static/index/mobile/fonts/Metropolis-ExtraBoldItalic.otf
Normal file
Binary file not shown.
BIN
public/static/index/mobile/fonts/Metropolis-ExtraLight.otf
Normal file
BIN
public/static/index/mobile/fonts/Metropolis-ExtraLight.otf
Normal file
Binary file not shown.
BIN
public/static/index/mobile/fonts/Metropolis-ExtraLightItalic.otf
Normal file
BIN
public/static/index/mobile/fonts/Metropolis-ExtraLightItalic.otf
Normal file
Binary file not shown.
BIN
public/static/index/mobile/fonts/Metropolis-Light.otf
Normal file
BIN
public/static/index/mobile/fonts/Metropolis-Light.otf
Normal file
Binary file not shown.
BIN
public/static/index/mobile/fonts/Metropolis-LightItalic.otf
Normal file
BIN
public/static/index/mobile/fonts/Metropolis-LightItalic.otf
Normal file
Binary file not shown.
BIN
public/static/index/mobile/fonts/Metropolis-Medium.otf
Normal file
BIN
public/static/index/mobile/fonts/Metropolis-Medium.otf
Normal file
Binary file not shown.
BIN
public/static/index/mobile/fonts/Metropolis-MediumItalic.otf
Normal file
BIN
public/static/index/mobile/fonts/Metropolis-MediumItalic.otf
Normal file
Binary file not shown.
BIN
public/static/index/mobile/fonts/Metropolis-Regular.otf
Normal file
BIN
public/static/index/mobile/fonts/Metropolis-Regular.otf
Normal file
Binary file not shown.
BIN
public/static/index/mobile/fonts/Metropolis-RegularItalic.otf
Normal file
BIN
public/static/index/mobile/fonts/Metropolis-RegularItalic.otf
Normal file
Binary file not shown.
BIN
public/static/index/mobile/fonts/Metropolis-SemiBold.otf
Normal file
BIN
public/static/index/mobile/fonts/Metropolis-SemiBold.otf
Normal file
Binary file not shown.
BIN
public/static/index/mobile/fonts/Metropolis-SemiBoldItalic.otf
Normal file
BIN
public/static/index/mobile/fonts/Metropolis-SemiBoldItalic.otf
Normal file
Binary file not shown.
BIN
public/static/index/mobile/fonts/Metropolis-Thin.otf
Normal file
BIN
public/static/index/mobile/fonts/Metropolis-Thin.otf
Normal file
Binary file not shown.
BIN
public/static/index/mobile/fonts/Metropolis-ThinItalic.otf
Normal file
BIN
public/static/index/mobile/fonts/Metropolis-ThinItalic.otf
Normal file
Binary file not shown.
BIN
public/static/index/mobile/images/jiant.png
Normal file
BIN
public/static/index/mobile/images/jiant.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 696 B |
BIN
public/static/index/mobile/images/ljgd.png
Normal file
BIN
public/static/index/mobile/images/ljgd.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
@@ -66,7 +66,7 @@
|
||||
.orico_Page_productxc .productxcMain .culture_top .culture_bril_con .culture_bril_div .title {
|
||||
font-size: 1.125rem;
|
||||
font-weight: 600;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
margin-top: 2rem;
|
||||
width: 90%;
|
||||
margin-left: 5%;
|
||||
@@ -75,7 +75,7 @@
|
||||
width: 80%;
|
||||
font-size: 0.875rem;
|
||||
color: #707070;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
margin-top: 1.375rem;
|
||||
margin-left: 10%;
|
||||
}
|
||||
@@ -93,7 +93,7 @@
|
||||
line-height: 2em;
|
||||
margin-bottom: 2%;
|
||||
font-weight: 600;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
}
|
||||
.orico_Page_productxc .productxcMain .culture_vision .swt-Container {
|
||||
width: 80%;
|
||||
@@ -138,14 +138,14 @@
|
||||
color: #101010;
|
||||
line-height: 2em;
|
||||
margin-bottom: 2%;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
margin-right: 10%;
|
||||
}
|
||||
.orico_Page_productxc .productxcMain .culture_vision .swt-Container .swt-Table .Table-Row .right .des {
|
||||
font-size: 16px;
|
||||
color: #737373;
|
||||
line-height: 1.6rem;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
}
|
||||
.orico_Page_productxc .productxcMain .culture_vision .swt-Container .swt-Table .Table-Row .Table-Cell {
|
||||
display: table-cell;
|
||||
@@ -159,7 +159,7 @@
|
||||
font-size: 1rem;
|
||||
color: #737373;
|
||||
line-height: 1.6rem;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
}
|
||||
.orico_Page_productxc .productxcMain .culture_vision .swt-Container .culture_vision_02 .des,
|
||||
.orico_Page_productxc .productxcMain .culture_vision .swt-Container .culture_vision_02 .subtitle {
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
}
|
||||
.orico_Page_introduction .introductionMain .iotbpage .iotb_bgw .iotbt1 {
|
||||
font-size: 32px;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
padding-bottom: 65px;
|
||||
padding-top: 88px;
|
||||
font-weight: 700;
|
||||
@@ -57,14 +57,14 @@
|
||||
}
|
||||
.orico_Page_introduction .introductionMain .iotbpage .iotb_bgw .iotb_part1 .iotb_p1_item .iotbtp1 {
|
||||
font-size: 18px;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: bold;
|
||||
padding-bottom: 18px;
|
||||
}
|
||||
.orico_Page_introduction .introductionMain .iotbpage .iotb_bgw .iotb_part1 .iotb_p1_item .iotbts1 {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
color: #9e9e9f;
|
||||
}
|
||||
.orico_Page_introduction .introductionMain .iotb_part2 {
|
||||
@@ -78,7 +78,7 @@
|
||||
}
|
||||
.orico_Page_introduction .introductionMain .iotb_part2 .iotbt1 {
|
||||
font-size: 32px;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
padding-bottom: 65px;
|
||||
padding-top: 88px;
|
||||
font-weight: 700;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
height: 11.25rem;
|
||||
line-height: 11.25rem;
|
||||
font-size: 2rem;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
@@ -52,7 +52,7 @@
|
||||
.orico_Page_achievement .achievementMain .achInfo .achNums .achive_shuju .title1 {
|
||||
margin-top: 2.5rem;
|
||||
font-size: 2rem;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
}
|
||||
@@ -62,7 +62,7 @@
|
||||
.orico_Page_achievement .achievementMain .achInfo .achNums .achive_shuju .subtitle1 {
|
||||
margin-top: 1rem;
|
||||
font-size: 1.125rem;
|
||||
font-family: Montserrat-Regular, Montserrat;
|
||||
font-family: Metropolis-Regular, Metropolis;
|
||||
font-weight: 400;
|
||||
color: #707070;
|
||||
}
|
||||
@@ -71,7 +71,7 @@
|
||||
height: auto;
|
||||
position: relative;
|
||||
background: #f2f2f2;
|
||||
font-family: Montserrat;
|
||||
font-family: Metropolis;
|
||||
padding-bottom: 10%;
|
||||
}
|
||||
.orico_Page_achievement .achievementMain .achTimes .timecontent {
|
||||
@@ -83,7 +83,7 @@
|
||||
height: 11.25rem;
|
||||
line-height: 11.25rem;
|
||||
font-size: 2rem;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
@@ -142,7 +142,7 @@
|
||||
background: url(/static/index/pc/images/greyyuandian.png) 3px 3px no-repeat;
|
||||
height: 2.375rem;
|
||||
font-size: 1.25rem;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
line-height: 1.875rem;
|
||||
@@ -153,7 +153,7 @@
|
||||
.orico_Page_achievement .achievementMain .achTimes .timecontent .timelist .timeline-con .con_event_list .event_list div li {
|
||||
display: inline-block;
|
||||
width: 94%;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
line-height: 1.5625rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
@@ -181,7 +181,7 @@
|
||||
height: 11.25rem;
|
||||
line-height: 11.25rem;
|
||||
font-size: 2rem;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
@@ -211,7 +211,7 @@
|
||||
margin-left: 4.0625rem;
|
||||
margin-top: 2.5rem;
|
||||
font-size: 1.75rem;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
line-height: 1.625rem;
|
||||
@@ -220,7 +220,7 @@
|
||||
margin-left: 65px;
|
||||
width: 80%;
|
||||
font-size: 16px;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
font-weight: 500;
|
||||
color: #707070;
|
||||
line-height: 26px;
|
||||
|
||||
@@ -52,10 +52,10 @@
|
||||
font-weight: 600;
|
||||
color: #000000;
|
||||
line-height: 20px;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
}
|
||||
.orico_Page_brand .brandMain .our_brand_con .our_brand_bg .vtext .Table-Cell p {
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
font-size: 14px;
|
||||
color: #707070;
|
||||
line-height: 22px;
|
||||
@@ -100,17 +100,17 @@
|
||||
margin-top: 2.5rem;
|
||||
}
|
||||
.orico_Page_brand .brandMain .dis_bril_bg .dis_bril_con .title p {
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
}
|
||||
.orico_Page_brand .brandMain .dis_bril_bg .dis_bril_con .subtitle {
|
||||
width: 80%;
|
||||
font-size: 0.875rem;
|
||||
color: #707070;
|
||||
font-family: Montserrat-Medium, Montserrat;
|
||||
font-family: Metropolis-Medium, Metropolis;
|
||||
margin-top: 2.5rem;
|
||||
margin-left: 10%;
|
||||
}
|
||||
.orico_Page_brand .brandMain .dis_bril_bg .dis_bril_con .subtitle p {
|
||||
font-family: Montserrat-Medium;
|
||||
font-family: Metropolis-Medium;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user