Compare commits
141 Commits
d4fa15f671
...
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 | |||
| 60229ae058 | |||
| 6cf27d8b9c | |||
| 4334c2db66 | |||
| d7e93567d9 | |||
| e19ba6a315 | |||
| a8e7ad2430 | |||
| 55c8762255 | |||
| 43a4f5f706 | |||
| c6cff2e97d | |||
| 5d53c26c5c |
14
.example.env
14
.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,6 +54,13 @@ REFRESH_TOKEN_LIFETIME = 1209600; # 刷新令牌有效期
|
||||
RESOURCE_IMAGES_DOMAIN = http://local.orico.com; # 图片资源服务器地址
|
||||
RESOURCE_VIDEOS_DOMAIN = http://local.orico.com; # 视频资源服务器地址
|
||||
|
||||
# 七牛云存储配置
|
||||
[QINUI]
|
||||
BUCKET = orico
|
||||
BASE_URL = http://local.orico.com
|
||||
ACCESS_KEY = 1234567890
|
||||
SECRET_KEY = 1234567890
|
||||
|
||||
# 前台视图模板规则配置
|
||||
[INDEX_VIEW_TPL]
|
||||
# 视图目录
|
||||
|
||||
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
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -7,9 +7,18 @@ 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
|
||||
|
||||
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',
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* 文件上传控制器
|
||||
@@ -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;
|
||||
|
||||
@@ -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'
|
||||
];
|
||||
@@ -54,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;
|
||||
}
|
||||
@@ -145,3 +145,90 @@ 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'
|
||||
];
|
||||
}
|
||||
|
||||
@@ -26,8 +26,6 @@ class Attachment extends Common
|
||||
'size/d' => 12,
|
||||
]);
|
||||
|
||||
|
||||
|
||||
// 获取附件分类
|
||||
$categorys = AttachmentCategoryModel::field([
|
||||
'id',
|
||||
@@ -61,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());
|
||||
|
||||
@@ -124,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);
|
||||
|
||||
@@ -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,15 +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数据
|
||||
@@ -246,20 +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');
|
||||
}
|
||||
@@ -317,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');
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
<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">
|
||||
@@ -67,6 +69,24 @@
|
||||
<span>{$ac.name}</span>
|
||||
</div>
|
||||
<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])}"
|
||||
@@ -78,6 +98,9 @@
|
||||
</ul>
|
||||
</div>
|
||||
{/volist}
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
{/notempty}
|
||||
</div>
|
||||
@@ -128,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();
|
||||
|
||||
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}
|
||||
@@ -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>
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
</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>'
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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,157 +0,0 @@
|
||||
<?php
|
||||
namespace uploader;
|
||||
|
||||
use Qiniu\Auth;
|
||||
use Qiniu\Storage\UploadManager;
|
||||
use Qiniu\Storage\BucketManager;
|
||||
|
||||
class QiniuUploader
|
||||
{
|
||||
private $bucket = 'orico-opd';
|
||||
private $accessKey = 'dOsTum4a5qvhPTBbZRPX0pIOU7PZWRX7htKjztms';
|
||||
private $secretKey = 'KFxsGbnErkALFfeGdMa8QWTdodJbamMX0iznLe-q';
|
||||
|
||||
private $rule = [
|
||||
'fileSize' => 1024 * 1024 * 5, // 默认最大上传5M
|
||||
'fileExt' => 'jpeg,jpg,png', // 默认上传文件后缀
|
||||
'fileMime' => 'image/jpeg,image/png,image/gif' // 默认上传文件mime
|
||||
];
|
||||
|
||||
private $dir = true;
|
||||
private $originalName = false;
|
||||
private $pathPrefix = '';
|
||||
private $fileNamePrefix = 'orico';
|
||||
|
||||
static public $domain = 'http://opdfile.f2b211.com/';
|
||||
|
||||
public function __construct($conf = [])
|
||||
{
|
||||
if (!empty($conf['bucket'])) {
|
||||
$this->bucket = $conf['bucket'];
|
||||
}
|
||||
if (!empty($conf['accessKey'])) {
|
||||
$this->accessKey = $conf['accessKey'];
|
||||
}
|
||||
if (!empty($conf['secretKey'])) {
|
||||
$this->secretKey = $conf['secretKey'];
|
||||
}
|
||||
if (!empty($conf['pathPrefix'])) {
|
||||
$this->pathPrefix = trim($conf['pathPrefix'], '/');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成随机字符串
|
||||
*/
|
||||
private function random($length, $type = "string", $convert = "0")
|
||||
{
|
||||
$conf = [
|
||||
'number' => '0123456789',
|
||||
'string' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
'all' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789='
|
||||
];
|
||||
$string = $conf[$type];
|
||||
if (!$string) {
|
||||
$string = $conf['string'];
|
||||
}
|
||||
$strlen = strlen($string) - 1;
|
||||
$char = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$char .= $string[mt_rand(0, $strlen)];
|
||||
}
|
||||
if ($convert > 0) {
|
||||
$res = strtoupper($char);
|
||||
} elseif ($convert == 0) {
|
||||
$res = $char;
|
||||
} elseif ($convert < 0) {
|
||||
$res = strtolower($char);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装文件名
|
||||
*/
|
||||
private function buildFileName()
|
||||
{
|
||||
return $this->fileNamePrefix . time() . substr(time(), -5) . substr(microtime(), 2, 3) . $this->random(8);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传验证规则
|
||||
*/
|
||||
public function validate($rule)
|
||||
{
|
||||
$this->rule = $rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件到七牛云
|
||||
*/
|
||||
public function uploadFile($name)
|
||||
{
|
||||
// 构建鉴权对象
|
||||
$auth = new Auth($this->accessKey, $this->secretKey);
|
||||
|
||||
// 生成上传 Token
|
||||
$token = $auth->uploadToken($this->bucket);
|
||||
|
||||
// 初始化 UploadManager 对象并进行文件的上传。
|
||||
$uploadMgr = new UploadManager();
|
||||
|
||||
$file = request()->file($name);
|
||||
|
||||
$aspectRatio = [];
|
||||
if (!empty($this->rule['aspectRatio'])) {
|
||||
$aspectRatio = $this->rule['aspectRatio'];
|
||||
unset($this->rule['aspectRatio']);
|
||||
}
|
||||
$validate = validate([$name => $this->rule]);
|
||||
if (!$validate->check([$name => $file])) {
|
||||
throw new \Exception($validate->getError());
|
||||
}
|
||||
|
||||
$fileName = $file->getOriginalName(); // 文件原名
|
||||
if (!$this->originalName) {
|
||||
$fileName = $this->buildFileName() . '.' . $file->extension();
|
||||
if (!$this->dir && !empty($this->pathPrefix)) {
|
||||
$fileName = $this->pathPrefix . '/' . $fileName;
|
||||
}
|
||||
}
|
||||
if ($this->dir) {
|
||||
$fileName = date('Y') . '/' . date('m') . '/' . date('d') . '/' . $fileName;
|
||||
if (!empty($this->pathPrefix)) {
|
||||
$fileName = $this->pathPrefix . '/' . $fileName;
|
||||
}
|
||||
}
|
||||
$filePath = $file->getPathname(); // 临时路径
|
||||
if (!empty($aspectRatio)) { // 验证图片宽高
|
||||
list($width, $height, $type, $attr) = getimagesize($file);
|
||||
if ($width != $aspectRatio['width'] || $height != $aspectRatio['height']) {
|
||||
throw new \Exception('图片宽高不符合');
|
||||
}
|
||||
}
|
||||
$fileType = $file->getOriginalMime();
|
||||
list($ret, $err) = $uploadMgr->putFile($token, $fileName, $filePath, null, $fileType, false);
|
||||
|
||||
if ($err !== null) {
|
||||
throw new \Exception($err);
|
||||
} else {
|
||||
return ['hash' => $ret['hash'], 'filename' => $ret['key'], 'remote_url' => self::$domain . $ret['key']];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 上传文件到七牛云
|
||||
*/
|
||||
public function deleteFile($name)
|
||||
{
|
||||
// 构建鉴权对象
|
||||
$auth = new Auth($this->accessKey, $this->secretKey);
|
||||
// 初始化 BucketManager 对象并进行文件的删除。
|
||||
$bucketManager = new BucketManager($auth);
|
||||
$ret = $bucketManager->delete($this->bucket, $name);
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
@@ -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';
|
||||
}
|
||||
|
||||
/* 分页样式 */
|
||||
@@ -161,7 +161,9 @@ body {
|
||||
.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;
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
@@ -220,3 +220,31 @@
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@
|
||||
border-radius: 8px;
|
||||
height: 48px;
|
||||
box-shadow: none;
|
||||
font-family: Montserrat-Regular, Montserrat;
|
||||
font-family: Metropolis-Regular, Metropolis;
|
||||
}
|
||||
.orico_Page_articleDetail .articleDetailMain .atmright .repply form {
|
||||
width: auto;
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
height: 56px;
|
||||
line-height: 56px;
|
||||
margin-top: -28px;
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
}
|
||||
.orico_Page_download .downloadMain .contact_c {
|
||||
width: 82%;
|
||||
@@ -43,7 +43,7 @@
|
||||
border-radius: 1.5rem;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
font-family: "Montserrat-Medium";
|
||||
font-family: "Metropolis-Medium";
|
||||
color: #9e9e9f;
|
||||
z-index: 9;
|
||||
position: relative;
|
||||
@@ -86,7 +86,7 @@
|
||||
font-size: 1.125rem;
|
||||
padding-top: 1.5625rem;
|
||||
padding-bottom: 1.5625rem;
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
text-align: center;
|
||||
border-radius: 0.75rem;
|
||||
cursor: pointer;
|
||||
@@ -137,20 +137,20 @@
|
||||
}
|
||||
.orico_Page_download .downloadMain .contact_c .softlist .softit .title {
|
||||
font-size: 1.125rem;
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
color: #000;
|
||||
}
|
||||
.orico_Page_download .downloadMain .contact_c .softlist .softit .sub_title {
|
||||
font-size: 0.875rem;
|
||||
margin-top: 0.875rem;
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
color: #9e9e9f;
|
||||
}
|
||||
.orico_Page_download .downloadMain .contact_c .softlist .softit .des {
|
||||
line-height: 20px;
|
||||
margin-top: 8px;
|
||||
font-size: 16px;
|
||||
font-family: "Montserrat-Medium";
|
||||
font-family: "Metropolis-Medium";
|
||||
color: #000;
|
||||
}
|
||||
.orico_Page_download .downloadMain .contact_c .softlist .softit .l_button {
|
||||
@@ -158,7 +158,7 @@
|
||||
padding: 15px 40px;
|
||||
margin-top: 74px;
|
||||
display: inline-block;
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
color: #004bfa;
|
||||
background-color: rgba(0, 75, 250, 0.05);
|
||||
cursor: pointer;
|
||||
@@ -212,7 +212,7 @@
|
||||
font-size: 16px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
color: #000;
|
||||
}
|
||||
.orico_Page_download .downloadMain .contact_c .vidotabs .hd ul li a{
|
||||
@@ -257,7 +257,7 @@
|
||||
height: 114px;
|
||||
}
|
||||
.orico_Page_download .downloadMain .contact_c .vidotabs .bdconten .video_hotul dd .htit .htit1 {
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
color: #000;
|
||||
font-size: 16px;
|
||||
margin-top: 40px;
|
||||
@@ -266,7 +266,7 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
.orico_Page_download .downloadMain .contact_c .vidotabs .bdconten .video_hotul dd .htit .htit2 {
|
||||
font-family: "Montserrat-Regular";
|
||||
font-family: "Metropolis-Regular";
|
||||
color: #9e9e9f;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
}
|
||||
.orico_Page_bussiness .bussinessMain .bd_main .sfbt1 {
|
||||
font-size: 24px;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
padding-bottom: 55px;
|
||||
@@ -52,7 +52,7 @@
|
||||
}
|
||||
.orico_Page_bussiness .bussinessMain .bd_main .bd_ct .bd_from .theit .bditem .itlable {
|
||||
font-size: 14px;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
padding-bottom: 10px;
|
||||
@@ -74,7 +74,7 @@
|
||||
height: 48px;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
font-family: Montserrat-Regular, Montserrat;
|
||||
font-family: Metropolis-Regular, Metropolis;
|
||||
}
|
||||
.orico_Page_bussiness .bussinessMain .bd_main .bd_ct .bd_from .theit .bditem .form-control {
|
||||
display: block;
|
||||
@@ -97,7 +97,7 @@
|
||||
.orico_Page_bussiness .bussinessMain .bd_main .bd_ct .bd_from .theit .bditem .sfbchecks .sfbcheckboxlist .cit {
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
font-family: Montserrat-Regular, Montserrat;
|
||||
font-family: Metropolis-Regular, Metropolis;
|
||||
color: #000;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -119,11 +119,11 @@
|
||||
background: #f2f2f2;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-family: Montserrat-Regular, Montserrat;
|
||||
font-family: Metropolis-Regular, Metropolis;
|
||||
}
|
||||
.orico_Page_bussiness .bussinessMain .bd_main .bttj {
|
||||
font-size: 14px;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: bold;
|
||||
width: 212px;
|
||||
padding: 15px 15px;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
color: #004bfa;
|
||||
padding-bottom: 1rem;
|
||||
text-align: center;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: 700;
|
||||
}
|
||||
.orico_Page_distributor .distributorMain .s1 {
|
||||
@@ -72,7 +72,7 @@
|
||||
}
|
||||
.orico_Page_distributor .distributorMain .bd_from .theit .bditem .itlable {
|
||||
font-size: 0.875rem;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
padding-bottom: 0.625rem;
|
||||
@@ -99,7 +99,7 @@
|
||||
border-radius: 0.5rem;
|
||||
height: 3rem;
|
||||
box-shadow: none;
|
||||
font-family: Montserrat-Regular, Montserrat;
|
||||
font-family: Metropolis-Regular, Metropolis;
|
||||
}
|
||||
.orico_Page_distributor .distributorMain .ittextarea {
|
||||
height: 6.25rem;
|
||||
@@ -108,11 +108,11 @@
|
||||
border: none;
|
||||
border-radius: 0.5rem;
|
||||
resize: none;
|
||||
font-family: Montserrat-Regular, Montserrat;
|
||||
font-family: Metropolis-Regular, Metropolis;
|
||||
}
|
||||
.orico_Page_distributor .distributorMain .bttj {
|
||||
font-size: 0.875rem;
|
||||
font-family: Montserrat-Bold, Montserrat;
|
||||
font-family: Metropolis-Bold, Metropolis;
|
||||
font-weight: bold;
|
||||
width: 10rem;
|
||||
padding: 1.2rem 3.75rem;
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
color: #000;
|
||||
display: block;
|
||||
width: 100%;
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
.orico_Page_contact .contactMain .contact_c .all_contact .info .info_all {
|
||||
@@ -77,7 +77,7 @@
|
||||
}
|
||||
.orico_Page_contact .contactMain .contact_c .all_contact .info .info_all .list .sub_list .title {
|
||||
font-size: 0.875rem;
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
}
|
||||
.orico_Page_contact .contactMain .contact_c .all_contact .info .info_all .list .sub_list .des {
|
||||
font-size: 0.875rem;
|
||||
@@ -92,14 +92,14 @@
|
||||
color: #000;
|
||||
display: block;
|
||||
width: 100%;
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
}
|
||||
.orico_Page_contact .contactMain .contact_c .all_contact .question .question_form .list {
|
||||
margin-top: 1.5rem;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
.orico_Page_contact .contactMain .contact_c .all_contact .question .question_form .list .title {
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
font-size: 0.875rem;
|
||||
padding-bottom: 0.3125rem;
|
||||
}
|
||||
@@ -110,13 +110,13 @@
|
||||
background: #f2f2f2;
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
font-family: Montserrat-Regular, Montserrat;
|
||||
font-family: Metropolis-Regular, Metropolis;
|
||||
}
|
||||
.orico_Page_contact .contactMain .contact_c .all_contact .question .question_form .list .ittextarea {
|
||||
height: 100px;
|
||||
background: #f2f2f2;
|
||||
border: none;
|
||||
font-family: Montserrat-Regular, Montserrat;
|
||||
font-family: Metropolis-Regular, Metropolis;
|
||||
resize: none;
|
||||
}
|
||||
.orico_Page_contact .contactMain .contact_c .all_contact .question .question_form .list .form_input input,
|
||||
@@ -143,7 +143,7 @@
|
||||
font-size: 0.875rem;
|
||||
background-color: #004bfa;
|
||||
color: #fff;
|
||||
font-family: "Montserrat-Bold";
|
||||
font-family: "Metropolis-Bold";
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -157,7 +157,7 @@
|
||||
background-color: #fff;
|
||||
border-radius: 0.75rem;
|
||||
margin-top: 1.5rem;
|
||||
font-family: "Montserrat-SemiBold";
|
||||
font-family: "Metropolis-SemiBold";
|
||||
}
|
||||
.orico_Page_contact .contactMain .contact_c .become_dis .text_blue {
|
||||
color: #004bfa;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -572,7 +572,7 @@
|
||||
font-size: 1rem;
|
||||
text-align: left;
|
||||
width: 80%;
|
||||
font-family: Montserrat !important;
|
||||
font-family: Metropolis !important;
|
||||
color: #004bfa;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user