15 Commits

Author SHA1 Message Date
2c85df4a98 Merge branch 'dev' 2025-12-05 09:36:52 +08:00
88a91f3136 删除注释 2025-12-04 10:27:05 +08:00
5fd603cbc6 底部样式 2025-12-04 10:25:06 +08:00
b92753c822 底部 2025-12-04 10:22:56 +08:00
ddd578eb08 Merge branch 'dev' 2025-12-03 17:56:52 +08:00
1cdd0536b9 Merge branch 'font' 2025-12-01 15:46:23 +08:00
9cc6dc3cd9 Merge branch 'dev' 2025-11-28 16:23:35 +08:00
4d25f6fec8 Merge branch 'dev' 2025-11-28 15:46:00 +08:00
2764ce3b86 Merge branch 'dev' 2025-11-28 15:36:31 +08:00
7cb270b313 Merge branch 'dev' 2025-11-28 15:23:45 +08:00
86ffcb99ac Merge branch 'dev' 2025-11-28 14:51:46 +08:00
c476193002 Merge branch 'dev' 2025-11-28 14:43:34 +08:00
5643faad94 Merge branch 'dev' 2025-11-28 14:36:46 +08:00
989f6c25a0 refactor: 修改..gitignore 2025-11-28 14:35:35 +08:00
2e5103b19a Initial commit 2025-11-28 14:33:22 +08:00
88 changed files with 315 additions and 8374 deletions

4
.gitignore vendored
View File

@@ -9,8 +9,8 @@ Thumbs.db
.env.prod
.htaccess
.user.ini
/404.html
/index.html
404.html
index.html
public/dist*
public/opendoc

208
LICENSE Normal file
View File

@@ -0,0 +1,208 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION,
AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution
as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, "control" means (i) the power, direct
or indirect, to cause the direction or management of such entity, whether
by contract or otherwise, or (ii) ownership of fifty percent (50%) or more
of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions
granted by this License.
"Source" form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
"Object" form shall mean any form resulting from mechanical transformation
or translation of a Source form, including but not limited to compiled object
code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form,
made available under the License, as indicated by a copyright notice that
is included in or attached to the work (an example is provided in the Appendix
below).
"Derivative Works" shall mean any work, whether in Source or Object form,
that is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative
Works shall not include works that remain separable from, or merely link (or
bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative
Works thereof, that is intentionally submitted to Licensor for inclusion in
the Work by the copyright owner or by an individual or Legal Entity authorized
to submit on behalf of the copyright owner. For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written communication
sent to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor
for the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently incorporated
within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this
License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable copyright license to reproduce, prepare
Derivative Works of, publicly display, publicly perform, sublicense, and distribute
the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License,
each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section) patent
license to make, have made, use, offer to sell, sell, import, and otherwise
transfer the Work, where such license applies only to those patent claims
licensable by such Contributor that are necessarily infringed by their Contribution(s)
alone or by combination of their Contribution(s) with the Work to which such
Contribution(s) was submitted. If You institute patent litigation against
any entity (including a cross-claim or counterclaim in a lawsuit) alleging
that the Work or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses granted to You
under this License for that Work shall terminate as of the date such litigation
is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or
Derivative Works thereof in any medium, with or without modifications, and
in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy
of this License; and
(b) You must cause any modified files to carry prominent notices stating that
You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source
form of the Work, excluding those notices that do not pertain to any part
of the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its distribution,
then any Derivative Works that You distribute must include a readable copy
of the attribution notices contained within such NOTICE file, excluding those
notices that do not pertain to any part of the Derivative Works, in at least
one of the following places: within a NOTICE text file distributed as part
of the Derivative Works; within the Source form or documentation, if provided
along with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works
that You distribute, alongside or as an addendum to the NOTICE text from the
Work, provided that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction,
or distribution of Your modifications, or for any such Derivative Works as
a whole, provided Your use, reproduction, and distribution of the Work otherwise
complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any
Contribution intentionally submitted for inclusion in the Work by You to the
Licensor shall be under the terms and conditions of this License, without
any additional terms or conditions. Notwithstanding the above, nothing herein
shall supersede or modify the terms of any separate license agreement you
may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names,
trademarks, service marks, or product names of the Licensor, except as required
for reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to
in writing, Licensor provides the Work (and each Contributor provides its
Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied, including, without limitation, any warranties
or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR
A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness
of using or redistributing the Work and assume any risks associated with Your
exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether
in tort (including negligence), contract, or otherwise, unless required by
applicable law (such as deliberate and grossly negligent acts) or agreed to
in writing, shall any Contributor be liable to You for damages, including
any direct, indirect, special, incidental, or consequential damages of any
character arising as a result of this License or out of the use or inability
to use the Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all other commercial
damages or losses), even if such Contributor has been advised of the possibility
of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work
or Derivative Works thereof, You may choose to offer, and charge a fee for,
acceptance of support, warranty, indemnity, or other liability obligations
and/or rights consistent with this License. However, in accepting such obligations,
You may act only on Your own behalf and on Your sole responsibility, not on
behalf of any other Contributor, and only if You agree to indemnify, defend,
and hold each Contributor harmless for any liability incurred by, or claims
asserted against, such Contributor by reason of your accepting any such warranty
or additional liability. END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "[]" replaced with your own identifying
information. (Don't include the brackets!) The text should be enclosed in
the appropriate comment syntax for the file format. We also recommend that
a file or class name and description of purpose be included on the same "printed
page" as the copyright notice for easier identification within third-party
archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -354,18 +354,6 @@ class System
'url' => (string)url('/index/topic/power_prodline/index')
],
]
],
[
'id' => 9,
'name' => '笔记本AI PC专题',
'url' => '',
'children' => [
[
'id' => 91,
'name' => '首页',
'url' => (string)url('/index/topic/laptop/index')
],
]
]
];
}

View File

@@ -32,8 +32,7 @@ class ProductCategoryModel extends ProductCategoryBaseModel
// 所属产品目录分类id查询
public function scopeTcoId($query, $value)
{
// $query->where('related_tco_category', '=', $value);
$query->whereRaw('FIND_IN_SET(:ref_id, related_tco_category)', ['ref_id' => $value]);
$query->where('related_tco_category', '=', $value);
}
/**

View File

@@ -23,7 +23,7 @@ class ProductCategoryValidate extends Validate
'name' => 'require|max:64',
'icon' => 'max:125',
'desc' => 'max:255',
'related_tco_category' => 'string|checkRelatedTcoCategory',
'related_tco_category' => 'integer',
'sort' => 'integer',
'level' => 'integer',
'is_show' => 'in:0,1',
@@ -39,26 +39,25 @@ class ProductCategoryValidate extends Validate
* @var array
*/
protected $message = [
'id.require' => 'ID不能为空',
'id.integer' => 'ID必须为整数',
'language_id.require' => '语言ID不能为空',
'language_id.integer' => '语言ID必须为整数',
'unique_id.require' => '唯一标识不能为空',
'pid.different' => '父级ID不能为自身',
'pid.checkPidNotBeChildren' => '父级ID不能为自身的子分类',
'pid.integer' => '父级ID必须为整数',
'name.require' => '名称不能为空',
'name.max' => '名称最多不能超过64个字符',
'icon.max' => '图标最多不能超过125个字符',
'desc.max' => '描述最多不能超过255个字符',
'related_tco_category.string' => '关联TCO分类格式错误',
'related_tco_category.checkRelatedTcoCategory' => '该TCO分类已绑定',
'sort.integer' => '排序格式错误',
'level.integer' => '级别格式错误',
'is_show.in' => '是否显示格式错误',
'seo_title.max' => 'SEO标题最多不能超过255个字符',
'seo_keywords.max' => 'SEO关键字最多不能超过255个字符',
'seo_desc.max' => 'SEO描述最多不能超过255个字符',
'id.require' => 'ID不能为空',
'id.integer' => 'ID必须为整数',
'language_id.require' => '语言ID不能为空',
'language_id.integer' => '语言ID必须为整数',
'unique_id.require' => '唯一标识不能为空',
'pid.different' => '父级ID不能为自身',
'pid.checkPidNotBeChildren' => '父级ID不能为自身的子分类',
'pid.integer' => '父级ID必须为整数',
'name.require' => '名称不能为空',
'name.max' => '名称最多不能超过64个字符',
'icon.max' => '图标最多不能超过125个字符',
'desc.max' => '描述最多不能超过255个字符',
'related_tco_category.integer' => '关联TCO分类格式错误',
'sort.integer' => '排序格式错误',
'level.integer' => '级别格式错误',
'is_show.in' => '是否显示格式错误',
'seo_title.max' => 'SEO标题最多不能超过255个字符',
'seo_keywords.max' => 'SEO关键字最多不能超过255个字符',
'seo_desc.max' => 'SEO描述最多不能超过255个字符',
];
// 验证pid
@@ -85,32 +84,4 @@ class ProductCategoryValidate extends Validate
{
return $this->remove('id', 'require|integer')->remove('pid', 'different|checkPidNotBeChildren');
}
// 验证related_tco_category
protected function checkRelatedTcoCategory($value, $rule, $data = [])
{
if (empty($value)) {
return true;
}
$val = ProductCategoryModel::where(function($query) use($value) {
$arr = explode(",", $value);
foreach ($arr as $v) {
$query->whereFindInSet('related_tco_category', $v, 'OR');
}
})->column('id');
if (!empty($val)) {
$size = count($val);
// 如果存在超过一个,直接验证失败
if ($size > 1) {
return false;
}
// 如果存在一个并存在的id不为自身验证失败考虑更新场景查到自身情况
if ($size == 1 && $val[0] != $data['id']) {
return false;
}
}
return true;
}
}

View File

@@ -18,7 +18,7 @@ class SysBannerItemValidate extends Validate
'banner_id' => 'require|integer|gt:0',
'title' => 'require|max:256',
'title_txt_color' => 'max:7',
'desc' => 'max:2048',
'desc' => 'max:1024',
'desc_txt_color' => 'max:7',
'type' => 'in:image,video',
'image' => 'max:255',
@@ -45,7 +45,7 @@ class SysBannerItemValidate extends Validate
'title.require' => '名称不能为空',
'title.max' => '名称最多不能超过256个字符',
'title_txt_color.max' => '名称字体颜色最多不能超过7个字符',
'desc.max' => '描述最多不能超过2048个字符',
'desc.max' => '描述最多不能超过1024个字符',
'desc_txt_color.max' => '描述字体颜色最多不能超过7个字符',
'type.in' => '显示类型必须是image或video',
'image.max' => '图片地址最多不能超过255个字符',

View File

@@ -107,13 +107,6 @@ abstract class Common extends BaseController
'status' => 1
])
->where('status', '=', 1)
->where(function($query) {
// 临时代码,移动端暂时不显示 "AI PC"
if (request()->from == 'mobile') {
$table_name = SysNavigationItemModel::getTable();
$query->whereNotIn($table_name . ".id", [78]);
}
})
->order(['sort' => 'asc', 'id' => 'asc'])
->select();
if ($nav->isEmpty()) {
@@ -217,7 +210,7 @@ abstract class Common extends BaseController
];
}
unset($current);
return $data;
}
}

View File

@@ -1,104 +0,0 @@
<?php
declare (strict_types = 1);
namespace app\index\controller;
use app\index\model\SysBannerModel;
use think\facade\View;
class TopicLaptop extends Common
{
/**
* 专题 - 笔记本电脑首页
*/
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_693a268c8aa5f', // 专题 - 笔记本首页 - 焦点图
'BANNER_693a26b1ad252', // 专题 - 笔记本首页 - 性能介绍
'BANNER_693a27b767c8c', // 专题 - 笔记本首页 - CPU介绍
'BANNER_693a28740b8a7', // 专题 - 笔记本首页 - 显卡介绍
'BANNER_693a28aa8412d', // 专题 - 笔记本首页 - 运行内存介绍
'BANNER_693a29009fa72', // 专题 - 笔记本首页 - 硬盘介绍
'BANNER_693a29263c609', // 专题 - 笔记本首页 - 散热系统介绍
'BANNER_693a2959958bc', // 专题 - 笔记本首页 - 行业App运行介绍
'BANNER_693a298342b38', // 专题 - 笔记本首页 - 柔光屏介绍
'BANNER_693a2ad31fbe8', // 专题 - 笔记本首页 - 色域介绍
'BANNER_693a2b0327ac3', // 专题 - 笔记本首页 - 防眩光介绍
'BANNER_693a2cc70c762', // 专题 - 笔记本首页 - 外形质感介绍
'BANNER_693a2d3113d14', // 专题 - 笔记本首页 - 网卡介绍
'BANNER_693a2d53ac247', // 专题 - 笔记本首页 - 电池续航介绍
'BANNER_693a2d7f5fa21', // 专题 - 笔记本首页 - 接口介绍
'BANNER_693a2f2114eb3', // 专题 - 笔记本首页 - 使用场景焦点图
'BANNER_693a2f92baaa3', // 专题 - 笔记本首页 - 摄像头/麦克风/安全介绍
'BANNER_693a2fad26f55', // 专题 - 笔记本首页 - 系统预装介绍
'BANNER_693a2ff4629bd', // 专题 - 笔记本首页 - 产品检测介绍
'BANNER_693a30e9e4572', // 专题 - 笔记本首页 - 网页脚注
])
->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;
}
// 焦点图轮播图
$data['top_focus_images'] = data_get($banners_map, 'BANNER_693a268c8aa5f')?->items->toArray();
// 性能介绍
$data['perf'] = data_get($banners_map, 'BANNER_693a26b1ad252')?->items->toArray();
// CPU介绍
$data['cpu'] = data_get($banners_map, 'BANNER_693a27b767c8c')?->items->toArray();
// 显卡介绍
$data['gpu'] = data_get($banners_map, 'BANNER_693a28740b8a7')?->items->toArray();
// 运行内存介绍
$data['ram'] = data_get($banners_map, 'BANNER_693a28aa8412d')?->items->first()?->toArray();
// 硬盘介绍
$data['hard_drive'] = data_get($banners_map, 'BANNER_693a29009fa72')?->items->toArray();
// 散热系统介绍
$data['cooling_system'] = data_get($banners_map, 'BANNER_693a29263c609')?->items->toArray();
// 行业App运行介绍
$data['apps'] = data_get($banners_map, 'BANNER_693a2959958bc')?->items->first()?->toArray();
// 柔光屏介绍
$data['screen_soft_light'] = data_get($banners_map, 'BANNER_693a298342b38')?->items->toArray();
// 色域介绍
$data['screen_color_gamut'] = data_get($banners_map, 'BANNER_693a2ad31fbe8')?->items->toArray();
// 防眩光介绍
$data['screen_anti_glare'] = data_get($banners_map, 'BANNER_693a2b0327ac3')?->items->toArray();
// 外形质感介绍
$data['exterior_texture'] = data_get($banners_map, 'BANNER_693a2cc70c762')?->items->toArray();
// 网卡介绍
$data['network_card'] = data_get($banners_map, 'BANNER_693a2d3113d14')?->items->toArray();
// 电池续航介绍
$data['battery_life'] = data_get($banners_map, 'BANNER_693a2d53ac247')?->items->toArray();
// 接口介绍
$data['interface'] = data_get($banners_map, 'BANNER_693a2d7f5fa21')?->items->toArray();
// 使用场景焦点图
$data['scene_focus_images'] = data_get($banners_map, 'BANNER_693a2f2114eb3')?->items->toArray();
// 摄像头/麦克风/安全介绍
$data['camare_microphone_security'] = data_get($banners_map, 'BANNER_693a2f92baaa3')?->items->toArray();
// 系统预装介绍
$data['unified_preinstall'] = data_get($banners_map, 'BANNER_693a2fad26f55')?->items->first()?->toArray();
// 产品检测介绍
$data['product_testing'] = data_get($banners_map, 'BANNER_693a2ff4629bd')?->items->toArray();
// 网页脚注
$data['webpage_footnotes'] = data_get($banners_map, 'BANNER_693a30e9e4572')?->items->first()?->toArray();
}
View::assign('data', $data);
return View::fetch('index');
}
}

View File

@@ -92,9 +92,9 @@ return [
],
'attachment/video' => [
'软件和驱动程序' => 'Software and Drivers',
'您的浏览器不支持 video 标签。' => 'Your browser does not support HTML5 video.',
'您的浏览器不支持 video 标签。' => 'Your browser does not support HTML5 video.',
],
// 联系我们批量购买页面
'contactus/bulkbuy' => [
'批量购买' => 'Bulk Buy',
@@ -219,21 +219,4 @@ return [
'联系我们' => 'Contact US',
'目录' => 'Content'
],
// 笔记本专题 - 首页
'topiclaptop/index' => [
'CineBench R23 多核跑分' => 'Outperforms Ryzen 5 & Intel i5',
'*此跑分为ORICO实验室测定所得请以实际使用为准' => '*Data measured by ORICO Lab. Actual performance may vary.',
'3DMARK Time Spy显卡得分' => 'Handles Office & Gaming with Ease',
'肯辛通锁孔' => 'Kensington <br/> Lock Slot',
'千兆网口' => 'Gigabit <br/> Ethernet',
'USB-A<br/>(5Gbps)' => 'USB-A <br/> (5Gbps)',
'3.5mm<br/>耳麦合一' => '3.5mm <br/> Combo Audio',
'TF口3.0' => 'TF 3.0 <br/> Card Slot',
'全功能<br/>USB-C' => 'All-in-One <br/> USB-C',
"接口大满贯" => "Full-Featured Ports",
"酷睿i5-12450H" => "Core i5-12450H",
"锐龙9 6900HX" => "Ryzen9 6900HX",
"标配多种接口会议室连接电脑、U盘传输文件、TF卡读取等全都轻松搞定" => "Versatile Ports for Easy Connectivity. Effortlessly link to pro",
],
];
];

View File

@@ -224,21 +224,4 @@ return [
'联系我们' => 'Contact US',
'目录' => 'Content'
],
// 笔记本专题 - 首页
'topiclaptop/index' => [
'CineBench R23 多核跑分' => 'Outperforms Ryzen 5 & Intel i5',
'*此跑分为ORICO实验室测定所得请以实际使用为准' => '*Data measured by ORICO Lab. Actual performance may vary.',
'3DMARK Time Spy显卡得分' => 'Handles Office & Gaming with Ease',
'肯辛通锁孔' => 'Kensington <br/> Lock Slot',
'千兆网口' => 'Gigabit <br/> Ethernet',
'USB-A<br/>(5Gbps)' => 'USB-A <br/> (5Gbps)',
'3.5mm<br/>耳麦合一' => '3.5mm <br/> Combo Audio',
'TF口3.0' => 'TF 3.0 <br/> Card Slot',
'全功能<br/>USB-C' => 'All-in-One <br/> USB-C',
"接口大满贯" => "Full-Featured Ports",
"酷睿i5-12450H" => "Core i5-12450H",
"锐龙9 6900HX" => "Ryzen9 6900HX",
"标配多种接口会议室连接电脑、U盘传输文件、TF卡读取等全都轻松搞定" => "Versatile Ports for Easy Connectivity. Effortlessly link to pro",
],
];
];

View File

@@ -107,16 +107,10 @@ Route::group('topic', function () {
});
// 专题 - 电力品线
Route::group('power_prodline', function() {
Route::group("power_prodline", function() {
// 专题 - 电力品线首页
Route::get('index', 'TopicPowerProdline/index');
});
// 专题 - 笔记本电脑
Route::group('laptop', function() {
// 专题 - 笔记本电脑首页
Route::get('index', 'TopicLaptop/index');
});
});
// 数据迁移

File diff suppressed because it is too large Load Diff

View File

@@ -284,4 +284,4 @@
$('#top-country').hide();
});
});
</script>
</script>

File diff suppressed because it is too large Load Diff

View File

@@ -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\nHarmonyOS\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\nHarmonyOS\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],

View File

@@ -1,45 +1,28 @@
@font-face {
font-family: "HarmonyOS";
src: url("//ow.static.f2b211.com/static/fonts/HarmonyOS_Sans_SC_Regular.ttf") format("opentype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "HarmonyOS-Regular";
src: url("//ow.static.f2b211.com/static/fonts/HarmonyOS_Sans_SC_Regular.ttf") format("opentype");
src: url("../fonts/HarmonyOS-Regular.otf") format("opentype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "HarmonyOS-Bold";
src: url("//ow.static.f2b211.com/static/fonts/HarmonyOS_Sans_SC_Bold.ttf") format("opentype");
src: url("../fonts/HarmonyOS-Bold.otf") format("opentype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "HarmonyOS-Medium";
src: url("//ow.static.f2b211.com/static/fonts/HarmonyOS_Sans_SC_Medium.ttf") format("opentype");
font-weight: normal;
font-style: normal;
}
/* HarmonyOS-SemiBold1 */
@font-face {
font-family: "HarmonyOS-SemiBold";
src: url("//ow.static.f2b211.com/static/fonts/HarmonyOS_Sans_SC_Bold.ttf") format("opentype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "HarmonyOS-Light";
src: url("//ow.static.f2b211.com/static/fonts/HarmonyOS_Sans_SC_Light.ttf") format("opentype");
src: url("../fonts/HarmonyOS-Medium.otf") format("opentype");
font-weight: normal;
font-style: normal;
}
* {
margin: 0;
padding: 0;
font-family: 'HarmonyOS';
/* font-family: 'HarmonyOS'; */
-ms-overflow-style: none;
/* IE 和 Edge */
scrollbar-width: none;

View File

@@ -1,40 +0,0 @@
.amd-box {
width: 100%;
position: relative;
max-width: 6.82rem;
margin: 0 auto;
margin-top: -0.86rem;
z-index: 1;
}
.amd-img-header,
.amd-img-main,
.amd-img-footer {
width: 100%;
max-width: 6.82rem;
}
.amd-img-main {
display: flex;
justify-content: space-between;
}
.amd-img-main-left,
.amd-img-main-right {
flex: 1;
max-width: 3.36rem;
display: block;
}
.amd-img-main-left img,
.amd-img-main-right img {
width: 3.36rem;
display: block;
margin-top: 0.1rem;
}
.amd-img-header img {
width: 6.82rem;
display: block;
}
.amd-img-footer img {
width: 6.82rem;
margin-top: 0.1rem;
display: block;
}

View File

@@ -1,50 +0,0 @@
.bly {
margin: 0 0.34rem;
aspect-ratio: 682/338;
/* max-height: 6.97rem; */
padding-top: 1.5rem;
}
.bly .ba-slider .handle:after {
position: absolute;
top: 50%;
/* 1. 缩小宽高从48px改为32px可根据需求再调比如28px/30px */
width: 0.32rem;
height: 0.32rem;
/* 2. 同步调整margin宽高的一半保证居中48px对应-24px32px对应-16px */
margin: -0.16rem 0 0 -0.16rem;
content: '';
display: flex;
align-items: center;
justify-content: center;
background: #fff
url('https://dev.ow.f2b211.com/static/index/pc/images/ba-arrow.png')
/* 3. 缩小背景箭头从22px改为16px匹配整体尺寸 */ center center /
0.16rem 0.16rem no-repeat;
border: 1px solid #fff;
border-radius: 50%;
transition: all 0.3s ease;
transform: scale(1);
z-index: 5;
box-shadow: none;
}
.bly .ba-slider .handle.ba-draggable:after {
transform: scale(0.8);
}
.bly-t {
font-size: 0.36rem;
color: #fff;
text-align: center;
width: 100%;
}
.bly-p {
font-size: 0.18rem;
color: #cbcfd8;
text-align: center;
width: 100%;
padding-top: 0.37rem;
padding-bottom: 0.56rem;
font-family: 'HarmonyOS-Light';
line-height: 1.5;
}

View File

@@ -1,49 +0,0 @@
.cpu {
margin-top: 1.5rem;
width: 100%;
aspect-ratio: 750/882;
position: relative;
}
.cpu-main {
width: 100%;
aspect-ratio: 750/882;
}
.cpu-texts-t {
color: #fff;
font-size: 0.36rem;
line-height: 1;
text-align: center;
padding-top: 0.19rem;
}
.cpu-texts-p {
color: #cbcfd8;
font-size: 0.18rem;
margin-top: 0.37rem;
line-height: 1;
text-align: center;
}
.cpu-footer {
position: absolute;
bottom: 0;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.cpu-footer-img {
display: flex;
gap: 0.1rem;
}
.cpu-footer img {
width: 100%;
max-width: 1.48rem;
display: block;
}
.cpu-footer-desc {
font-size: 0.16rem;
color: #cbcfd8;
text-align: center;
margin-top: 0.38rem;
margin-bottom: 0.51rem;
width: 100%;
}

View File

@@ -1,59 +0,0 @@
.endurance {
position: relative;
width: 100%;
margin-top: 1.78rem;
aspect-ratio: 750/778;
}
.endurance-texts {
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
position: absolute;
top: -0.4rem;
}
.endurance-t {
width: 100%;
font-size: 0.5rem;
color: #fff;
text-align: center;
}
.endurance-t span:nth-child(1) {
font-size: 0.4rem;
line-height: 1;
}
.endurance-t span:nth-child(2) {
font-size: 0.36rem;
margin-left: 0.11rem;
line-height: 1;
}
.endurance-p {
font-size: 0.18rem;
color: #cbcfd8;
text-align: center;
padding-top: 0.37rem;
font-family: 'HarmonyOS-Light';
}
.endurance-img {
width: 100%;
position: absolute;
bottom: 0.62rem;
display: flex;
justify-content: center;
gap: 0.1rem;
}
.endurance-img img {
width: 2.46rem;
display: block;
}
.endurance-footer-p {
color: #ffffff;
font-size: 0.18rem;
position: absolute;
bottom: 0;
text-align: center;
left: 50%;
transform: translateX(-50%);
width: 100%;
}

View File

@@ -1,136 +0,0 @@
.footer-imgs {
width: 6.8rem;
margin: 0 auto;
margin-top: 1.5rem;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.footer-imgs img {
width: 2.22rem;
}
.footer-imgs img:nth-child(4),
.footer-imgs img:nth-child(5),
.footer-imgs img:nth-child(6) {
margin-top: 0.09rem;
}
.footer-texts {
width: 6.8rem;
margin: 1.5rem 0.35rem;
/* font-size: 0.16rem; */
color: #cbcfd8;
/* white-space: normal; */
/* margin-top: 1.5rem;
margin-bottom: 1.5rem; */
box-sizing: border-box;
}
.footer-texts p {
width: 6.8rem;
font-size: 0.16rem;
padding-left: 0.05rem;
text-indent: -0.1rem;
line-height: 1.5;
margin-bottom: 0.1rem;
font-family: 'HarmonyOS-Light';
letter-spacing: 1px;
}
.footer-texts-en {
width: 6.8rem;
margin: 0 auto;
font-size: 0.16rem;
color: #cbcfd8;
white-space: normal;
}
.footer-texts-en p {
text-indent: clamp(-16px, -1vw, -0.22rem);
font-family: 'HarmonyOS-Light';
}
.oircoEgapp-foot .logo-white img {
margin: 0 auto;
}
.oircoEgapp-foot .m_footer {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.oircoEgapp-foot .m_footer .left,
.oircoEgapp-foot .foot-con {
display: flex;
flex-direction: row;
align-items: center;
}
.oircoEgapp-foot .m_footer .right {
max-width: 55%;
}
.oircoEgapp-foot .m_footer .left {
max-width: 40%;
justify-content: end;
margin-right: 4%;
}
.oircoEgapp-foot .foot-con span {
width: auto;
padding: 0 0.625rem;
}
.oircoEgapp-foot .foot-cate .clearfix li h3 {
margin-bottom: 10px;
}
.oircoEgapp-foot .foot-cate .clearfix li p,
.oircoEgapp-foot .foot-cate .clearfix li p a {
font-size: 12px;
}
.logo-white {
text-align: center;
padding: 1rem 0 0;
display: flex;
align-items: center;
}
.foot-cate {
padding: 0 0.16rem;
}
.foot-cate h3 {
font-size: 0.28rem;
}
.foot-cate li {
padding: 0.7rem 0;
min-height: 1.8rem;
}
.foot-cate li p {
line-height: 0.8rem;
}
.m_footer .right {
float: right;
width: 57%;
text-align: left;
}
.foot-con span {
font-size:0.28rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 1;
width: 100%;
height: auto;
cursor: pointer;
font-family: 'HarmonyOS-Medium';
}
.oircoEgapp-foot .foot-con span {
width: auto;
padding: 0 0.125rem;
}
.m_footer .left a{
display: flex;
align-items: center;
}
.m_footer .left img {
width: 0.55rem;
padding-right: 0.2rem;
padding-top: 0;
}
.oircoEgapp-foot .m_footer .right {
max-width: 50%;
}

View File

@@ -1,69 +0,0 @@
.fs {
width: 100%;
}
.fs-box {
width: 100%;
aspect-ratio: 16/9; /* 2560/1440=16/9核心比例约束 */
position: relative;
will-change: contents; /* 告诉浏览器该元素即将变化,提前优化 */
contain: layout paint; /* 限制重排重绘范围 */
}
.fs-img,
.fs-video {
backface-visibility: hidden; /* 开启硬件加速 */
transform: translateZ(0); /* 硬件加速 */
}
.fs-box img {
width: 100%;
}
.fs-box-img {
display: flex;
display: flex;
flex-wrap: wrap;
}
.fs-h-img {
width: 100%;
display: flex;
justify-content: center;
gap: 0.11rem;
}
.fs-h-img img {
width: 3.35rem;
}
.fs-b-img {
width: 100%;
display: flex;
justify-content: center;
margin-top: 0.1rem;
}
.fs-b-img img {
width: 6.81rem;
}
.fs-ts {
font-size: 0.18rem;
text-align: center;
color: #cbcfd8;
padding: 0.4rem 0;
}
.dl {
width: 100%;
padding-top: 1.01rem;
}
.dl-t {
color: #fff;
font-size: 0.36rem;
width: 100%;
text-align: center;
line-height: 1.5;
}
.dl-p {
color: #cbcfd8;
font-size: 0.18rem;
width: 100%;
text-align: center;
padding-top: 0.37rem;
/* padding-bottom: 0.37rem; */
line-height: 1.5;
font-family: 'HarmonyOS-Light';
}

View File

@@ -1,44 +0,0 @@
.gpu {
width: 100%;
position: relative;
box-sizing: border-box;
}
.gpu-texts {
color: #fff;
font-size: 0.36rem;
margin: 0 0.34rem;
}
.gpu-texts-t {
line-height: 1.5;
}
.gpu-texts-p {
font-size: 0.16rem;
color: #cbcfd8;
line-height: 1.5;
margin-top: 0.32rem;
}
.gpu-main-img {
width: 100%;
aspect-ratio: 750/780;
}
.gpu-amd-img {
width: 100%;
}
.gpu-amd-img img {
max-width: 2.26rem;
width: 100%;
margin-top: 2.39rem;
margin-left: 0.45rem;
}
.gpu-footer-imgs {
display: flex;
position: absolute;
bottom: 0.61rem;
gap: 0.1rem;
left: 50%;
transform: translateX(-50%);
}
.gpu-footer-imgs img {
max-width: 1.63rem;
}

View File

@@ -1,231 +0,0 @@
.oircoEgapp-head {
display: flex;
flex-direction: column;
width: 100%;
height: auto;
position: fixed;
top: 0;
z-index: 1000;
width: -webkit-fill-available;
}
.oircoEgapp-head .headtop {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 0 0.16rem;
height:60px;
background: #fff;
}
.oircoEgapp-head .headtop .headerlogimg {
width: 2.25rem !important;
height: auto !important;
display: block;
/* height: 2.25rem; */
}
.oircoEgapp-head .top-menu {
background-color: #fff;
overflow: hidden;
width: 100%;
color: #000;
display: none;
}
.oircoEgapp-head .top-menu .it-ct {
font-family: "HarmonyOS-SemiBold";
font-weight: bold;
}
.oircoEgapp-head .top-menu .it-ct .it-1 {
padding: 0.16rem 3.5% 0.2rem;
border-bottom: 1px solid #e5e5e5;
font-size: 14px;
position: relative;
}
.oircoEgapp-head .top-menu .it-ct .it-1-more {
display: flex;
flex-direction: row;
justify-content: space-between;
padding-bottom: 1.5%;
}
.oircoEgapp-head .top-menu .it-ct .it-1-more i {
font-weight: bold;
}
.oircoEgapp-head .top-menu .it-ct .it-1-2 {
padding-left: 0.16rem;
font-size: 13px;
line-height: 1.8;
font-weight: 100;
font-weight: bold;
display: none;
}
.oircoEgapp-head .top-menu .it-ct .it-1-2 a {
color: #666;
}
.cursor_p span {
font-size: 0.38rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 1;
width: 100%;
/* height: 1.2rem; */
padding-left: 0.2rem;
}
.cursor_p span:hover {
font-size: 0.38rem;
white-space: normal;
width: 100%;
overflow: inherit;
line-height: 1.5;
}
/* .cursor_p {
height: 0.38rem !important;
} */
.img-responsive {
display: flex !important;
justify-content: center !important;
align-items: center !important;
}
.img-responsive span {
display: flex !important;
align-items: center !important;
}
.action-sheet {
border-top-left-radius: 10px;
border-top-right-radius: 10px;
display: none;
background: #fff;
width: 100%;
position: fixed;
bottom: 0;
z-index: 11111;
left: 0;
}
.menu-name {
text-indent: 0.2rem;
font-size: 14px;
font-weight: 700;
color: #000;
}
.action-sheet ul li {
margin: 0 10px;
color: #333;
font-size: 12px;
text-align: left;
border-bottom: 1px solid #eee;
padding: 12px 14px;
}
.action-sheet ul li a {
color: #333;
display: flex;
flex-direction: row;
align-items: center;
}
.action-sheet ul li img {
margin-right: 14px;
}
.menu-title {
display: flex;
align-items: center;
margin: 0 10px;
justify-content: space-between;
background: #fff;
border-top-left-radius: 6px;
border-top-right-radius:6px;
padding: 5px 0;
}
.close-icon {
width: 24px;
display: flex;
align-items: center;
}
.close-icon img {
width: 24px !important;
}
.title-text {
padding-top: 0.24rem;
color: #333;
font-size: 14px;
}
.title-text p {
line-height: 2;
}
.title-text p a {
color: #989898;
}
.title-text p a:hover {
color: #989898;
}
.marsk-container {
background: rgba(0, 0, 0, 0.8);
display: none;
position: absolute;
position: fixed;
top: 0;
right: 0;
left: 0;
bottom: 0px;
z-index: 9999;
}
.marsk-container-detail {
background: rgba(0, 0, 0, 0.8);
display: none;
position: absolute;
position: fixed;
top: 0;
right: 0;
left: 0;
bottom: 0px;
z-index: 9999;
}
.search-in {
margin-top:0.8rem;
}
.search-in input {
width: 70% !important;
height: 0.8rem;
background: #ffffff;
border: 1px solid #d6d6d6;
opacity: 1;
border-radius: 20px;
padding: 0 14px;
font-size: 14px;
}
::-webkit-input-placeholder {
color: #989898;
}
.search-button {
border: none;
font-size: 14px;
color: #fff;
position: absolute;
right: 10px;
cursor: pointer;
background: #0060ff;
height:0.7rem;
border-radius: 20px;
padding: 0 14px;
width: 22%;
}
.search-in form{
display: flex;
flex-direction: row;
align-items: center;
}
.search-in .title-text p a{
font-size: 14px;
}
/*头部搜索弹窗*/
.popup-quick {
width: 86%;
background-color: #fff;
z-index: 9999;
box-shadow: 0px 2px 5px rgba(255, 255, 255, 0.2);
color: #333;
padding: 14px;
border-radius: 5px;
margin: 14px auto 0;
position: relative;
margin-top: 1rem;
}

View File

@@ -1,13 +0,0 @@
* {
margin: 0;
padding: 0;
}
html {
width: 100% !important;
overflow-x: hidden;
}
body {
width: 100%;
background: #000;
overflow-x: hidden;
}

View File

@@ -1,43 +0,0 @@
.ips {
position: relative;
}
.ips-t {
font-size: 0.36rem;
color: #fff;
line-height: 1.5;
margin-top: 1.5rem;
margin-left: 0.38rem;
margin-right: 0.38rem;
margin-bottom: 0.46rem;
}
.ips-bg {
aspect-ratio: 750/678;
position: relative;
}
.ips-bg p {
font-size: 0.18rem;
color: #cbcfd8;
line-height: 1.5;
margin-left: 0.38rem;
margin-right: 0.38rem;
position: absolute;
top: -0.3rem;
}
.ips-imgs {
width: 6.8rem;
flex-wrap: wrap;
gap: 0.1rem;
position: absolute;
left: 50%;
transform: translateX(-50%);
bottom: -3rem;
display: flex;
}
.ips-imgs img {
width: 3.35rem;
display: block;
}
/* .ips-imgs img:nth-child(3),
.ips-imgs img:nth-child(4) {
margin-top: 0.1rem;
} */

View File

@@ -1,29 +0,0 @@
.m2 {
width: 100%;
margin-top: 1.09rem;
}
.m2-bg {
position: relative;
width: 100%;
aspect-ratio: 750/846;
}
.m2-bg-t1 {
font-size: 0.36rem;
color: #fff;
width: 100%;
text-align: center;
line-height: 1.5;
padding-top: 1.3rem;
}
.m2-img-box {
position: absolute;
bottom: 0.66rem;
width: 100%;
display: flex;
justify-content: center;
gap: 0.11rem;
}
.m2-img-box img {
width: 2.22rem;
}

View File

@@ -1,34 +0,0 @@
.memory {
width: 100%;
}
.memory-t {
font-size: 0.36rem;
color: #fff;
width: 100%;
text-align: center;
padding-bottom: 0.37rem;
line-height: 1.5;
}
.memory-img {
width: 100%;
aspect-ratio: 750/727;
position: relative;
}
.memory-p {
width: 100%;
font-size: 0.18rem;
color: #cbcfd8;
text-align: center;
line-height: 1.5;
}
.memory-footer-img {
position: absolute;
left: 50%;
transform: translateX(-50%);
bottom: -0.74rem;
}
.memory-footer-img img {
width: 6.83rem;
display: block;
}

View File

@@ -1,129 +0,0 @@
.progress {
margin-left: 0.34rem;
margin-right: 0.34rem;
box-sizing: border-box;
}
/* .progress-section {
margin-left: 0.34rem;
margin-right: 0.34rem;
box-sizing: border-box;
} */
.progress-title {
font-size: 0.24rem;
color: #fff;
padding: 0.16rem 0 0.36rem 0;
font-family: 'HarmonyOS-Medium';
}
.progress-item .label {
display: flex;
justify-content: space-between;
align-items: baseline;
line-height: 1;
margin-top: 0.13rem;
margin-bottom: 0.36rem;
}
.progress-item .label .device-name {
flex: 1;
font-family: 'HarmonyOS-Medium';
margin-left: 0.04rem;
}
.progress-item .label .value {
text-align: right;
font-family: 'HarmonyOS-Medium';
margin-right: 0.04rem;
}
.colorLinearGradient {
background: linear-gradient(90deg, #7e51ff, #d5dfff);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.progress-item .label .value.m4-max {
color: #5e5ce6;
}
.progress-bar {
flex: 1;
height: 0.1rem;
max-height: 0.2rem;
min-height: 0.1rem;
border-radius: 0.1rem;
overflow: hidden;
position: relative;
/* 性能优化1开启硬件加速减少重绘 */
transform: translateZ(0);
will-change: transform;
}
.progress-fill {
height: 100%;
border-radius: 0.05rem;
transform: scaleX(0);
transform-origin: left center;
transition: transform 1.2s ease-out;
will-change: transform;
position: relative;
}
/* 保留你所有原始的进度条颜色类 */
.progress-fill.m4-max {
background: linear-gradient(40deg, #7e51ff, #e1d5ff);
}
.progress-fill.m2-max {
background: #bfc5d9;
}
@keyframes shimmer {
100% {
left: 150%;
}
}
.font20 {
font-size: 0.2rem !important;
}
.font18 {
font-size: 0.18rem !important;
}
.colorCBCFD8 {
color: #646778 !important;
}
.progress-p {
color: #cbcfd8;
font-size: 0.18rem;
margin-top: 0.51rem;
margin-bottom: 1.5rem;
text-align: center;
}
.progress-p1 {
color: #cbcfd8;
font-size: 0.18rem;
margin-top: 1.56rem;
text-align: center;
}
.w645 {
width: 6.45rem;
}
.w585 {
width: 5.85rem;
}
.w454 {
width: 4.54rem;
}
.w321 {
width: 3.21rem;
}
.w596 {
width: 5.96rem;
}
.w467 {
width: 4.67rem;
}

View File

@@ -1,25 +0,0 @@
/* .qb {
position: absolute;
top:3rem;
left: 50%;
transform: translateX(-50%);
} */
.qb-t {
width: 100%;
font-size: 0.36rem;
color: #fff;
text-align: center;
padding-top: 1.5rem;
}
.qb-p {
font-size: 0.18rem;
color: #cbcfd8;
text-align: center;
padding-top: 0.37rem;
padding-bottom: 0.34rem;
font-family: 'HarmonyOS-Light';
line-height: 1.5;
}
.qb-bg-img1 {
width: 6.9rem;
}

View File

@@ -1,28 +0,0 @@
.rgb-t {
font-size: 0.36rem;
color: #fff;
width: 100%;
text-align: center;
margin-top: 4.84rem;
margin-bottom: 0.37rem;
line-height: 1.5;
}
.rgb-bg {
aspect-ratio: 750/582;
}
.rgb-p {
font-size: 0.18rem;
color: #cbcfd8;
line-height: 1.5;
text-align: center;
}
.rgb-imgs {
display: flex;
gap: 0.1rem;
margin-top: 0.28rem;
justify-content: center;
}
.rgb-imgs img {
width: 2.17rem;
display: block;
}

View File

@@ -1,85 +0,0 @@
/* 轮播容器 - 核心:基于视口高度自适应 */
.auto-swiper-container {
width: 100%;
overflow: hidden;
position: relative;
z-index: 1;
}
/* 轮播项 - 填充容器高度 */
.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: cover; /* 优先填充容器,裁剪超出部分(无拉伸) */
/* object-fit: contain; 可选:完整显示图片,不裁剪(可能留黑边) */
display: block;
}
.swiper-container-texts {
position: absolute;
left: 50%;
top: 0.91rem;
transform: translateX(-50%);
z-index: 10;
width: 100%;
}
.swiper-container-texts-t {
font-size: 0.48rem;
text-align: center;
width: 100%;
line-height: 1;
}
.swiper-container-texts-p {
padding-top: 0.68rem;
font-size: 0.16rem;
/* text-align: center; */
width: 100%;
display: flex;
align-items: center;
letter-spacing: 1.3px;
justify-content: center;
}
.swiper-container-texts-p div {
font-family: 'HarmonyOS-Light';
}
.swiper-container-texts-line {
width: 1px;
height: 0.16rem;
background: #fff;
margin: 0 12px;
}
.swiper-container-texts-img {
width: 100%;
display: flex;
justify-content: center;
padding-top: 0.63rem;
cursor: pointer;
}
.swiper-container-texts-img a {
width: 100%;
max-width: 1.18rem;
}
.swiper-container-texts-img img {
width: 100%;
max-width: 1.18rem;
}
.swiper-slide-t {
font-size: 0.2rem;
text-align: center;
color: #fff;
}
.swiper-slide-p {
font-size: 0.16rem;
color: #cbcfd8;
text-align: center;
margin-top: 0.18rem;
}

View File

@@ -1,105 +0,0 @@
.tabs-container {
width: 6.03rem;
margin: 0 auto;
}
.tabs-header-box {
width: 100%;
display: flex;
justify-content: center;
margin-top: 0.48rem;
}
.tabs-header {
display: inline-flex;
/* 改为inline-flex宽度由子元素决定 */
position: relative;
border-bottom: 1px solid #cbcfd8;
margin: 0 auto;
width: 1.75rem;
display: flex;
}
.tab-item {
/* padding: 12px 24px; */
font-size: 0.18rem;
cursor: pointer;
transition: color 0.2s ease;
white-space: nowrap;
color: #cbcfd8;
flex: 1;
text-align: center;
}
.tab-item {
margin-bottom: 0.08rem;
}
.tab-indicator {
position: absolute;
bottom: 0;
height: 2px;
background-color: #fff;
transform: translateX(0);
width: 0.87rem;
transition: transform 0.3s cubic-bezier(0.25, 0.1, 0.25, 1),
width 0.3s cubic-bezier(0.25, 0.1, 0.25, 1);
will-change: transform, width;
backface-visibility: hidden;
perspective: 1000px;
}
.tab-content {
width: 6.03rem;
width: 6.03rem;
/* min-width: 1280px; */
margin: 0 auto;
}
.content-video {
max-width: 100%;
height: auto;
border-radius: 8px;
}
.tabs-p {
width: 100%;
font-size: 0.18rem;
color: #cbcfd8;
text-align: center;
margin-top: 0.48rem;
display: none;
}
.tabs-p.active {
display: block;
}
.tab-panel {
display: none;
}
.tab-panel-img {
background: #1c1c1e;
width: 5.77rem;
overflow: hidden;
display: flex;
justify-content: flex-end;
border-radius: 0.16rem;
}
.tab-panel-img img {
width: 5.77rem;
}
.tab-panel.active {
display: block;
}
.tab-t {
font-size: 0.36rem;
color: #cbcfd8;
width: 100%;
text-align: center;
margin-top: 1.5rem;
margin-bottom: 0.7rem;
display: none;
}
.tab-t.active {
display: block;
}
/* .tab-ts {
margin-top: 2.97rem;
margin-bottom: 1rem;
} */

View File

@@ -1,37 +0,0 @@
.wifi {
position: relative;
width: 100%;
aspect-ratio: 750/595;
margin-top: 3.45rem;
}
.wifi-texts {
position: absolute;
top: -2.3rem;
left: 0.42rem;
width: 100%;
}
.wifi-t {
width: 100%;
font-size: 0.36rem;
color: #fff;
line-height: 1.5;
}
.wifi-p {
font-size: 0.18rem;
color: #cbcfd8;
padding-top: 0.37rem;
line-height: 1.4;
font-family: 'HarmonyOS-Light';
}
.wifi-img {
width: 100%;
position: absolute;
bottom: -0.22rem;
display: flex;
justify-content: center;
gap: 0.1rem;
}
.wifi-img img {
width: 3.35rem;
display: block;
}

View File

@@ -1,9 +0,0 @@
.window {
width: 100%;
display: flex;
justify-content: center;
margin-top: 1.5rem;
}
.window img {
width: 6.8rem;
}

View File

@@ -1,58 +0,0 @@
.xn-container {
width: 6.8rem;
margin: 0 auto;
box-sizing: border-box;
}
/* 图片容器样式(核心) */
.xn-image-section {
overflow: hidden;
border-radius: 0.16rem;
background: #0d0c10;
border: 1px solid #3f3f45;
width: 6.8rem;
}
.zoom-image {
width: 100%;
height: auto;
display: block;
/* 调整transform过渡时间为2sopacity为1.5s,可按需修改 */
transition: transform 2s cubic-bezier(0.25, 0.1, 0.25, 1), opacity 1.5s ease;
transform: scale(0.8);
/* 初始缩放比例 */
opacity: 0.9;
/* 初始透明度(略暗,放大后变亮) */
}
/* 滚动触发后的放大状态 */
.zoom-image.active {
transform: scale(1.1);
/* 放大5%(官网常用比例,不夸张) */
opacity: 1;
}
.xn-t {
font-size: 0.36rem;
color: #fff;
text-align: center;
margin-top: 1.5rem;
margin-bottom: 0.6rem;
}
.xn-p {
padding-top: 0.6rem;
font-size: 0.16rem;
margin-left: 0.47rem;
}
.xn-p p {
width: 5.84rem;
color: #cbcfd8;
line-height: 1.5;
/* 核心:左内边距控制第二行缩进量 */
padding-left: 0.8rem;
/* 首行向左偏移,抵消左内边距,实现第二行缩进 */
text-indent: -0.8rem;
/* 确保p标签是块级且换行正常 */
display: block;
word-wrap: break-word;
}

View File

@@ -1,123 +0,0 @@
/* 图片容器100vw宽最小宽度1440px按图片原始比例2560:1857定高 */
.zoom-container {
width: 7.5rem;
height: 6.05rem;
position: relative;
}
/* 图片包裹层:与容器同尺寸,定位参考系,承接缩放变换 */
.img-wrapper {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
/* z-index: -10; */
}
/* 图片:按原始比例填充包裹层,不裁切,初始放大+过渡动画 */
.bg-img {
width: 7.5rem;
height: 6.05rem;
display: block;
transform: scale(1.5);
transition: transform 1.8s ease;
transform-origin: center center;
}
/* 图片缩小后的状态 */
.bg-img.zoom-out {
transform: scale(1);
}
/* 标注样式:关键修正 - 基于容器绝对定位,百分比参考图片原始比例 */
.annotation {
position: absolute;
color: #48494d;
font-size: calc(12px + 0.3vw);
opacity: 0;
transform: translateY(calc(10px + 0.5vw));
transition: opacity 0.8s ease, transform 0.8s ease;
pointer-events: none;
z-index: 10;
white-space: nowrap;
/* 关键:标注的定位参考系是容器(与图片同比例),而非缩放后的图片 */
top: 0;
left: 0;
/* 重置默认值依赖内联style的百分比定位 */
}
/* 标注显示状态 */
.annotation.anno-show {
opacity: 1;
transform: translateY(0);
}
.annotation span {
position: relative;
display: inline-block;
/* 确保文字居中对齐 */
text-align: center;
}
/* 标注线条样式:基于文字定位,适配缩放 */
.annotation span::before {
content: '';
position: absolute;
left: 50%;
transform: translateX(-50%);
width: 0.01rem;
height: 0;
bottom: calc(100% + 6px);
background-color: #48494d;
transition: height 0.8s ease;
transform-origin: bottom center;
}
/* 向上延伸的标注线条(给需要向上的.annotation加anno-up类 */
.annotation.anno-up span::before {
/* 把线条位置从文字下方,改成文字上方 */
bottom: auto;
top: 0.3rem; /* 定位到文字顶部外 */
/* 线条方向改为向上延伸 */
transform-origin: top center;
}
.annotation.anno-up1 span::before {
/* 把线条位置从文字下方,改成文字上方 */
bottom: auto;
top: 0.5rem; /* 定位到文字顶部外 */
/* 线条方向改为向上延伸 */
transform-origin: top center;
}
/* 标注显示时,设置线条最终高度 */
.annotation.anno-show span::before {
height: 0.57rem;
/* 最终高度vw单位 */
}
.zoom-t {
width: 100%;
text-align: center;
font-size: 0.36rem;
color: #fff;
padding-top: 1.5rem;
}
.zoom-p {
width: 100%;
text-align: center;
font-size: 0.18rem;
color: #cbcfd8;
position: absolute;
top: 0.37rem;
z-index: 10;
line-height: 1.5;
font-family: 'HarmonyOS-Light';
}
/* 标注延迟类 */
.anno-delay-1 {
transition-delay: 0.8s;
}
.anno-delay-1 span::before {
transition-delay: 0.8s;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

View File

@@ -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: HarmonyOS-Bold, HarmonyOS;
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: HarmonyOS-Medium, HarmonyOS;
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: HarmonyOS-Bold, HarmonyOS;
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: HarmonyOS-Bold, HarmonyOS;
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: HarmonyOS-Medium, HarmonyOS;
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: HarmonyOS-Medium, HarmonyOS;
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 {

View File

@@ -30,7 +30,7 @@
}
.orico_Page_introduction .introductionMain .iotbpage .iotb_bgw .iotbt1 {
font-size: 32px;
font-family: HarmonyOS-Bold, HarmonyOS;
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: HarmonyOS-Bold, HarmonyOS;
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: HarmonyOS-Medium, HarmonyOS;
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: HarmonyOS-Bold, HarmonyOS;
font-family: Metropolis-Bold, Metropolis;
padding-bottom: 65px;
padding-top: 88px;
font-weight: 700;

View File

@@ -30,7 +30,7 @@
height: 11.25rem;
line-height: 11.25rem;
font-size: 2rem;
font-family: HarmonyOS-Bold, HarmonyOS;
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: HarmonyOS-Bold, HarmonyOS;
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: HarmonyOS-Regular, HarmonyOS;
font-family: Metropolis-Regular, Metropolis;
font-weight: 400;
color: #707070;
}
@@ -71,7 +71,7 @@
height: auto;
position: relative;
background: #f2f2f2;
font-family: HarmonyOS;
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: HarmonyOS-Bold, HarmonyOS;
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: HarmonyOS-Bold, HarmonyOS;
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: HarmonyOS-Medium, HarmonyOS;
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: HarmonyOS-Bold, HarmonyOS;
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: HarmonyOS-Bold, HarmonyOS;
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: HarmonyOS-Medium, HarmonyOS;
font-family: Metropolis-Medium, Metropolis;
font-weight: 500;
color: #707070;
line-height: 26px;

View File

@@ -52,10 +52,10 @@
font-weight: 600;
color: #000000;
line-height: 20px;
font-family: HarmonyOS-Bold, HarmonyOS;
font-family: Metropolis-Bold, Metropolis;
}
.orico_Page_brand .brandMain .our_brand_con .our_brand_bg .vtext .Table-Cell p {
font-family: HarmonyOS-Medium, HarmonyOS;
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: HarmonyOS-Bold, HarmonyOS;
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: HarmonyOS-Medium, HarmonyOS;
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: HarmonyOS-Medium;
font-family: Metropolis-Medium;
line-height: 22px;
}

View File

@@ -153,7 +153,7 @@
border-radius: 8px;
height: 48px;
box-shadow: none;
font-family: HarmonyOS-Regular, HarmonyOS;
font-family: Metropolis-Regular, Metropolis;
}
.orico_Page_articleDetail .articleDetailMain .atmright .repply form {
width: auto;

View File

@@ -32,7 +32,7 @@
height: 56px;
line-height: 56px;
margin-top: -28px;
font-family: "HarmonyOS-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: "HarmonyOS-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: "HarmonyOS-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: "HarmonyOS-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: "HarmonyOS-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: "HarmonyOS-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: "HarmonyOS-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: "HarmonyOS-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: "HarmonyOS-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: "HarmonyOS-Regular";
font-family: "Metropolis-Regular";
color: #9e9e9f;
display: -webkit-box;
-webkit-box-orient: vertical;

View File

@@ -21,7 +21,7 @@
}
.orico_Page_bussiness .bussinessMain .bd_main .sfbt1 {
font-size: 24px;
font-family: HarmonyOS-Bold, HarmonyOS;
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: HarmonyOS-Bold, HarmonyOS;
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: HarmonyOS-Regular, HarmonyOS;
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: HarmonyOS-Regular, HarmonyOS;
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: HarmonyOS-Regular, HarmonyOS;
font-family: Metropolis-Regular, Metropolis;
}
.orico_Page_bussiness .bussinessMain .bd_main .bttj {
font-size: 14px;
font-family: HarmonyOS-Bold, HarmonyOS;
font-family: Metropolis-Bold, Metropolis;
font-weight: bold;
width: 212px;
padding: 15px 15px;

View File

@@ -25,7 +25,7 @@
color: #004bfa;
padding-bottom: 1rem;
text-align: center;
font-family: HarmonyOS-Bold, HarmonyOS;
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: HarmonyOS-Bold, HarmonyOS;
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: HarmonyOS-Regular, HarmonyOS;
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: HarmonyOS-Regular, HarmonyOS;
font-family: Metropolis-Regular, Metropolis;
}
.orico_Page_distributor .distributorMain .bttj {
font-size: 0.875rem;
font-family: HarmonyOS-Bold, HarmonyOS;
font-family: Metropolis-Bold, Metropolis;
font-weight: bold;
width: 10rem;
padding: 1.2rem 3.75rem;

View File

@@ -38,7 +38,7 @@
color: #000;
display: block;
width: 100%;
font-family: "HarmonyOS-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: "HarmonyOS-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: "HarmonyOS-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: "HarmonyOS-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: HarmonyOS-Regular, HarmonyOS;
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: HarmonyOS-Regular, HarmonyOS;
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: "HarmonyOS-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: "HarmonyOS-SemiBold";
font-family: "Metropolis-SemiBold";
}
.orico_Page_contact .contactMain .contact_c .become_dis .text_blue {
color: #004bfa;

View File

@@ -572,7 +572,7 @@
font-size: 1rem;
text-align: left;
width: 80%;
font-family: HarmonyOS !important;
font-family: Metropolis !important;
color: #004bfa;
}

View File

@@ -1,60 +1,24 @@
/* @font-face {
font-family: "HarmonyOS";
src: url("../fonts/HarmonyOS-Regular.otf") format("opentype");
@font-face {
font-family: "Metropolis";
src: url("../fonts/Metropolis-Regular.otf") format("opentype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "HarmonyOS-Bold";
src: url("../fonts/HarmonyOS-Bold.otf") format("opentype");
font-family: "Metropolis-Bold";
src: url("../fonts/Metropolis-Bold.otf") format("opentype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "HarmonyOS-Medium";
src: url("../fonts/HarmonyOS-Medium.otf") format("opentype");
font-family: "Metropolis-Medium";
src: url("../fonts/Metropolis-Medium.otf") format("opentype");
font-weight: normal;
font-style: normal;
} */
@font-face {
font-family: "HarmonyOS";
src: url("//ow.static.f2b211.com/static/fonts/HarmonyOS_Sans_SC_Regular.ttf") format("opentype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "HarmonyOS-Regular";
src: url("//ow.static.f2b211.com/static/fonts/HarmonyOS_Sans_SC_Regular.ttf") format("opentype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "HarmonyOS-Bold";
src: url("//ow.static.f2b211.com/static/fonts/HarmonyOS_Sans_SC_Bold.ttf") format("opentype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "HarmonyOS-Medium";
src: url("//ow.static.f2b211.com/static/fonts/HarmonyOS_Sans_SC_Medium.ttf") format("opentype");
font-weight: normal;
font-style: normal;
}
/* HarmonyOS-SemiBold1 */
@font-face {
font-family: "HarmonyOS-SemiBold";
src: url("//ow.static.f2b211.com/static/fonts/HarmonyOS_Sans_SC_Bold.ttf") format("opentype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "HarmonyOS-Light";
src: url("//ow.static.f2b211.com/static/fonts/HarmonyOS_Sans_SC_Light.ttf") format("opentype");
font-weight: normal;
font-style: normal;
}
::-webkit-scrollbar {
width: 0.625rem;
background: #d2eafb;
@@ -68,7 +32,7 @@
* {
margin: 0;
padding: 0;
font-family: 'HarmonyOS';
font-family: 'Metropolis';
}
*:hover {

View File

@@ -1,20 +0,0 @@
.dl {
width: 100%;
padding-top: 0.71rem;
}
.dl-t {
color: #fff;
font-size: 0.63rem;
width: 100%;
text-align: center;
}
.dl-p {
color: #cbcfd8;
font-size: clamp(16px, 1vw, 0.22rem);
width: 100%;
text-align: center;
padding-top: 0.43rem;
/* padding-bottom: 0.37rem; */
line-height: 1.8;
font-family: "HarmonyOS-Light";
}

View File

@@ -1,131 +0,0 @@
.amd-box {
width: auto;
background: #000;
/* overflow: hidden; */
max-width: 14.4rem;
/* min-width: 1280px; */
margin: 0 auto;
/* margin-top:-3.5rem; */
}
.amd-img-box {
max-width: 14.4rem;
/* 移除height:100%,避免继承高度导致比例失效 */
}
/* 动画基础样式(保留,仅微调) */
.amd-img-1,
.amd-img-2,
.amd-img-3,
.amd-img-4,
.amd-img-5,
.amd-img-6 {
max-width: 14.4rem;
}
.amd-img-2,
.amd-img-3,
.amd-img-4,
.amd-img-5,
.amd-img-6 {
margin-top:0.2rem;
}
.fade-in {
opacity: 1 !important;
transform: translateY(0) !important;
visibility: visible !important;
}
/* 原有图片样式(重点修改) */
.amd-img-1-1 {
width: 14.4rem;
display: block;
}
.amd-img-2 {
display: flex;
gap: 0.2rem;
}
/* 710:210比例的容器核心修改 */
.amd-img-2-1,
.amd-img-2-2 {
flex: 1;
width: 50%;
}
.amd-img-2-1 img,
.amd-img-2-2 img {
width: 7.11rem;
display: block;
}
.amd-img-3 {
display: flex;
height: auto;
gap: 0.2rem;
}
.amd-img-3-left,.amd-img-3-right {
flex: 1;
height: auto;
width: 50%;
}
.amd-img-3-right {
display: flex;
flex-direction: column;
justify-content: space-between
}
.amd-img-3-left img {
display: block;
width: 7.11rem;
}
/* 3-2-right710:210比例 */
.amd-img-3-1-right,.amd-img-3-2-right {
width: 100%;
}
.amd-img-3-1-right img,
.amd-img-3-2-right img {
width: 7.11rem;
height: 100%;
display: block;
}
/* 统一处理其他图片容器的比例 */
.amd-img-4 {
width: 14.4rem;
}
.amd-img-4 img {
width: 100%;
height: 100%;
display: block;
}
.amd-img-5 {
/* max-width: 1440px; */
width: 100%;
display: flex;
gap: 0.2rem;
}
.amd-img-5 img {
flex: 1;
width: 7.11rem;
display: block;
}
.amd-img-6 {
width: 14.4rem;
}
.amd-img-6 img {
width: 100%;
height: 100%;
display: block;
}

View File

@@ -1,150 +0,0 @@
.amd-box {
width: 100%;
background: #000;
overflow: hidden;
max-width: 1440px;
min-width: 1280px;
margin: 0 auto;
margin-top:-2rem;
}
.amd-img-box {
width: 100%;
/* 移除height:100%,避免继承高度导致比例失效 */
}
/* 动画基础样式(保留,仅微调) */
.amd-img-1,
.amd-img-2,
.amd-img-3,
.amd-img-4,
.amd-img-5,
.amd-img-6 {
width: 100%;
}
.amd-img-2,
.amd-img-3,
.amd-img-4,
.amd-img-5,
.amd-img-6 {
margin-top:0.15rem;
}
.fade-in {
opacity: 1 !important;
transform: translateY(0) !important;
visibility: visible !important;
}
/* 原有图片样式(重点修改) */
.amd-img-1-1 {
max-width: 14.4rem;
width: 100%;
/* 移除height:100%改用auto保持比例 */
height: auto;
/* aspect-ratio: 1440/429; */
display: block;
}
.amd-img-2 {
display: flex;
gap: 0.2rem;
}
/* 710:210比例的容器核心修改 */
.amd-img-2-1,
.amd-img-2-2 {
flex: 1;
width: 50%;
/* 固定宽高比710/210 ≈ 3.38反向则210/710≈29.58% */
/* aspect-ratio: 711/261; */
overflow: hidden; /* 裁剪超出部分(可选) */
}
.amd-img-2-1 img,
.amd-img-2-2 img {
width: 100%;
height: 100%;
display: block;
aspect-ratio: 711/261;
}
.amd-img-3 {
display: flex;
height: auto;
gap: 0.2rem;
}
.amd-img-3-left,.amd-img-3-right {
flex: 1;
height: auto;
width: 50%;
}
.amd-img-3-right {
display: flex;
flex-direction: column;
justify-content: space-between
}
.amd-img-3-left img {
display: block;
aspect-ratio: 711/541;
}
/* 3-2-right710:210比例 */
.amd-img-3-1-right,.amd-img-3-2-right {
width: 100%;
}
.amd-img-3-1-right img,
.amd-img-3-2-right img {
width: 100%;
height: 100%;
display: block;
aspect-ratio: 711/261;
}
/* 统一处理其他图片容器的比例 */
.amd-img-4 {
max-width: 1440px;
aspect-ratio: 1440/178; /* 按原始1440:178比例固定 */
}
.amd-img-4 img {
width: 100%;
height: 100%;
/* object-fit: cover; */
display: block;
}
.amd-img-5 {
max-width: 1440px;
display: flex;
gap: 0.2rem;
aspect-ratio: 1440/260; /* 1440:260比例 */
}
.amd-img-5 img {
flex: 1;
width: 50%;
height: 100%;
/* object-fit: cover; */
display: block;
}
.amd-img-6 {
max-width: 1440px;
aspect-ratio: 1440/260; /* 1440:260比例 */
overflow: hidden;
}
.amd-img-6 img {
width: 100%;
height: 100%;
/* object-fit: cover; */
display: block;
}

View File

@@ -1,49 +0,0 @@
.bly {
/* max-width: 1440px;
min-width: 1280px; */
max-width: 14.4rem;
margin: 0 auto;
aspect-ratio: 1437/679;
/* max-height: 6.97rem; */
padding-top:4.41rem;
}
.bly .ba-slider .handle:after {
position: absolute;
top: 50%;
width: 48px;
height: 48px;
margin: -24px 0 0 -24px;
content: '';
display: flex;
align-items: center;
justify-content: center;
background: #fff
url('https://dev.ow.f2b211.com/static/index/pc/images/ba-arrow.png')
center center / 22px 22px no-repeat;
border: 1px solid #fff;
border-radius: 50%;
transition: all 0.3s ease;
transform: scale(1);
z-index: 5;
box-shadow: none;
}
.bly .ba-slider .handle.ba-draggable:after {
transform: scale(0.8);
}
.bly-t {
font-size: 0.63rem;
color: #fff;
text-align: center;
width: 100%;
}
.bly-p {
font-size: clamp(16px, 1vw, 0.22rem);
color: #cbcfd8;
text-align: center;
width: 100%;
padding-top: 0.43rem;
padding-bottom: 1rem;
font-family: "HarmonyOS-Light";
}

View File

@@ -1,64 +0,0 @@
.bottom-img-box {
width: 100%;
/* min-width: 1280px; */
padding: 3rem 0;
}
.bottom-img {
/* width: 14.416rem; */
max-width: 14.4rem;
width: 14.4rem;
/* min-width:12.8rem; */
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin: 0 auto;
}
.bottom-img img {
width: 33%;
/* flex:1; */
height: auto;
}
.bottom-img img:nth-child(4) {
padding-top: 8px;
}
.bottom-img img:nth-child(5) {
padding-top: 8px;
}
.bottom-img img:nth-child(6) {
padding-top: 8px;
}
.bottom-text {
width: 100%;
margin-bottom: 4.3rem;
}
.bottom-p {
max-width: 14.4rem;
/* min-width: 1280px; */
margin:0 auto;
font-size:clamp(16px, 1vw, 0.22rem);
color:#cbcfd8;
white-space: normal;
}
.bottom-p p {
text-indent:clamp(-16px, -1vw, -0.22rem);
line-height: 1.8;
margin-bottom: 0.1rem;
font-family: "HarmonyOS-Light";
letter-spacing:1px;
}
.bottom-p1 {
max-width: 14.4rem;
/* min-width: 1280px; */
margin:0 auto;
font-size:clamp(16px, 1vw, 0.22rem);
color:#cbcfd8;
white-space: normal;
}
.bottom-p1 p{
text-indent:clamp(-16px, -1vw, -0.22rem);
/* line-height: 1.8; */
/* margin-bottom: 0.1rem; */
font-family: "HarmonyOS-Light";
/* letter-spacing:1px; */
}

View File

@@ -1,162 +0,0 @@
.orico_footer {
background: #000;
font-size: 16px; /* 1rem*16=16px */
}
.orico_footer .fotter {
margin: 0 auto;
overflow: hidden;
padding-bottom: 88px; /* 5.5rem*16=88px */
padding-top: 36px; /* 2.25rem*16=36px */
position: relative;
}
.orico_footer .fotter .footerico {
position: absolute;
height: 50px; /* 3.125rem*16=50px */
left: 8%;
top: 5%;
}
.orico_footer .fotter .footerMain {
min-width: 1024px;
max-width: 1200px; /* 75rem*16=1200px */
margin: 0 auto;
display: flex;
flex-direction: column;
}
.orico_footer .fotter .footerMain .foottxttop {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
}
.orico_footer .fotter .footerMain .foottxttop .foootCt {
/* gap: 1.5rem;
display: grid; */
display: flex;
flex-direction: column;
margin-bottom: 20px; /* 原px保留 */
}
.orico_footer .fotter .footerMain .foottxttop .foootCt .ftitle {
font-weight: 700;
color: #fff;
font-size: 20px; /* 1.25rem*16=20px */
margin-bottom: 30px; /* 原px保留 */
}
.orico_footer .fotter .footerMain .foottxttop .foootCt ul {
/* display: grid;
gap: 0.75rem; */
display: flex;
flex-direction: column;
}
.orico_footer .fotter .footerMain .foottxttop .foootCt ul li {
margin-bottom: 15px; /* 原px保留 */
}
.orico_footer .fotter .footerMain .foottxttop .foootCt ul .fline {
color: #fff;
opacity: 0.7;
transition: opacity 0.2s ease-in-out;
overflow-wrap: anywhere;
font-size: 16px; /* 兜底确保16px */
}
.orico_footer .fotter .footerMain .foottxtbottom {
padding-left: 14%;
display: grid;
padding-top: 4%;
}
.orico_footer .fotter .footerMain .foottxtbottom .ftopicos {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 1%;
gap: 32px; /* 2rem*16=32px */
}
.orico_footer .fotter .footerMain .foottxtbottom .ftopicos ul {
/* gap: 0.75rem 1.5rem; */
flex-wrap: wrap;
display: flex;
}
.orico_footer .fotter .footerMain .foottxtbottom .ftopicos ul a {
margin-right: 32px; /* 2rem*16=32px */
}
.orico_footer .fotter .footerMain .foottxtbottom .ftopicos ul img {
height: 30px; /* 原px保留 */
width: 30px; /* 原px保留 */
}
.orico_footer .fotter .footerMain .foottxtbottom .ftcopyright {
color: #b3b3b3;
font-size: 16px; /* 原0.875rem=14px → 提升至16px */
}
.orico_footer .fotter .footerMain .foottxtbottom .ftcopyright a {
color: #b3b3b3;
font-size: 16px; /* 兜底确保16px */
}
.orico_footer .fotter .footerMain .foottxtbottom .batext {
color: #fff;
font-size: 16px; /* 原14px → 提升至16px */
margin-top: 5px; /* 原px保留 */
}
.oricoCont {
width: 100%;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 56px 0; /* 3.5rem*16=56px */
background: transparent;
background: #f2f2f2;
}
.oricoCont .ctitem {
width: 45%;
display: flex;
flex-direction: column;
align-items: center;
}
.oricoCont .ctitem .ctimg {
max-width: 100px; /* 6.25rem*16=100px */
width: 60px; /* 3.75rem*16=60px */
height: 60px; /* 3.75rem*16=60px */
margin-top: 2%;
display: block;
margin-left: auto;
margin-right: auto;
}
.oricoCont .ctitem .cttitle {
font-size: 20px; /* 1.25rem*16=20px */
text-align: center;
font-weight: 600;
line-height: 40px; /* 2.5rem*16=40px */
}
.oricoCont .ctitem .ctdec {
font-size: 16px; /* 原0.875rem=14px → 提升至16px */
text-align: center;
line-height: 16px; /* 1rem*16=16px */
margin: auto;
}
.backtop {
position: fixed;
right: 20px; /* 1.25rem*16=20px */
padding: 10px 5px; /* 原px值保留 */
bottom: 10%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
color: #666;
font-size: 16px; /* 原0.75rem=12px → 提升至16px保障可读性 */
background: #fff;
cursor: pointer;
border: 1px solid rgb(241, 241, 241);
}
.backtop .ictop {
height: 18px; /* 1.125rem*16=18px */
width: 15px; /* 0.9375rem*16=15px */
margin-bottom: 4px; /* 0.25rem*16=4px */
}
@media screen and (max-width: 1777px) {
.footerico {
top: 65% !important;
bottom: 24%;
left: 50% !important;
}
}

View File

@@ -1,76 +0,0 @@
.fs {
min-width: 1280px;
}
.fs-box {
width: 100%;
aspect-ratio: 16/9; /* 2560/1440=16/9核心比例约束 */
position: relative;
will-change: contents; /* 告诉浏览器该元素即将变化,提前优化 */
contain: layout paint; /* 限制重排重绘范围 */
}
.fs-img, .fs-video {
backface-visibility: hidden; /* 开启硬件加速 */
transform: translateZ(0); /* 硬件加速 */
}
.fs-box img {
width: 100%;
}
.fs-box-img {
display: flex;
/* width: 100%;
position: absolute;
bottom: -60px; */
display: flex;
flex-wrap: wrap;
/* justify-content: center;
gap: 0.2rem; */
min-width: 1280px;
}
.fs-h-img {
width: 100%;
display: flex;
justify-content: center;
gap: 0.2rem;
/* margin-top: 0.2rem; */
min-width: 1280px;
}
.fs-h-img img {
max-width: 7.1rem;
}
.fs-b-img {
width: 100%;
display: flex;
justify-content: center;
margin-top: 0.2rem;
min-width: 1280px;
}
.fs-b-img img {
width: 100%;
max-width: 14.4rem;
}
.fs-ts {
font-size: clamp(16px, 1vw, 0.22rem);
text-align: center;
color:#cbcfd8;
padding:0.4rem 0;
}.dl {
width: 100%;
padding-top: 0.71rem;
}
.dl-t {
color: #fff;
font-size: 0.63rem;
width: 100%;
text-align: center;
}
.dl-p {
color: #cbcfd8;
font-size: clamp(16px, 1vw, 0.22rem);
width: 100%;
text-align: center;
padding-top: 0.43rem;
/* padding-bottom: 0.37rem; */
line-height: 1.8;
font-family: "HarmonyOS-Light";
}

View File

@@ -1,406 +0,0 @@
@charset "UTF-8";
/* 全局文字最小尺寸兜底 */
.header-PC {
width: 100%;
height: 60px;
background: #fff;
display: flex;
justify-content: center;
position: fixed;
top: 0;
z-index: 100;
}
.header-PC * {
min-font-size: 16px !important; /* 强制最小16px */
box-sizing: border-box;
}
.header-PC #header {
margin: 0 auto;
height: 60px; /* 0.6rem*100=60px */
max-width: var(--max-width);
/* position: fixed;
top: 0; */
display: flex;
flex-direction: row;
align-items: center;
z-index: 999;
background: white;
color: black;
width: 100%;
font-size: 16px; /* 基础字号16px */
}
.header-PC #header .nav1 {
position: relative;
width: 20%;
}
.header-PC #header .nav1 img {
width: 45%;
margin-left: 40%;
}
.header-PC #header .nav2 {
position: relative;
width: 60%;
}
.header-PC #header .nav2 .navItem {
font-size: 16px; /* 强制16px */
position: relative;
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
justify-content: center;
width: 12.5%;
height: 60px; /* 0.6rem*100=60px */
text-align: center;
float: left;
text-decoration: none;
transition: all 0.3s ease;
-webkit-transition: all 0.5s ease;
}
.header-PC #header .nav2 .navItem a {
padding-right: 5px; /* 0.05rem*100=5px */
padding-left: 20px; /* 0.2rem*100=20px */
text-decoration: none;
word-break: keep-all;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
word-wrap: break-word;
text-wrap: nowrap;
font-size: 16px; /* 确保16px */
}
.header-PC #header .nav2 .navItem .downimg {
height: 12px; /* 0.12rem*100=12px */
}
.header-PC #header .nav2 .navItem .navItemConten {
width: 100%;
z-index: 999;
background-color: #f2f2f2;
max-height: 660px; /* 6.6rem*100=660px */
box-shadow: 3px 5px 60px -20px #88909a; /* 0.03/0.05/0.6/-0.2rem 转px */
position: fixed;
border: 1px solid lightgray;
top: 60px; /* 0.6rem*100=60px */
transition: max-height 0.5s ease-out, opacity 0.5s ease-out;
left: 0;
display: none;
font-size: 16px; /* 基础字号16px */
}
.header-PC #header .nav2 .navItem .navItemConten .navItem_cyleft {
float: left;
text-align: center;
width: 20%;
max-height: 660px; /* 6.6rem*100=660px */
font-size: 16px; /* 强制16px */
}
.header-PC #header .nav2 .navItem .navItemConten .navItem_cyleft li {
cursor: pointer;
zoom: 1;
clear: both;
border: 1px solid transparent;
}
.header-PC #header .nav2 .navItem .navItemConten .navItem_cyleft li a {
line-height: 44px; /* 0.44rem*100=44px */
color: #656a6d;
font-size: 16px; /* 确保16px */
}
.header-PC #header .nav2 .navItem .navItemConten .navItem_cyleft li a:hover {
color: #004bfa;
}
.header-PC #header .nav2 .navItem .navItemConten .navItem_cyleft li.it_active {
border-color: #dddddd;
background-color: #ffffff;
}
.header-PC #header .nav2 .navItem .navItemConten .navItem_cyright {
max-height: 660px; /* 6.6rem*100=660px */
min-height: 460px; /* 4.6rem*100=460px */
overflow-y: auto;
border-left: 1px solid #dddddd;
font-weight: normal;
background-color: #fff;
margin: 0 auto;
box-shadow: -3px 0 0px #f3f3f3; /* -0.03rem*100=-3px */
text-align: left;
}
.header-PC #header .nav2 .navItem .navItemConten .navItem_cyright .nav_cyrightit dt {
font-size: 16px; /* 原0.14rem=14px → 提升至16px */
line-height: 16px; /* 0.16rem*100=16px */
margin-inline-start: 20px; /* 0.2rem*100=20px */
font-weight: 600;
border-bottom: 1px solid rgba(225, 225, 225, 0.5);
padding-bottom: 13px; /* 0.13rem*100=13px */
padding-top: 16px; /* 0.16rem*100=16px */
}
.header-PC #header .nav2 .navItem .navItemConten .navItem_cyright .nav_cyrightit dt img {
height: 16px; /* 0.16rem*100=16px */
max-width: 100%;
}
.header-PC #header .nav2 .navItem .navItemConten .navItem_cyright .nav_cyrightit dt a {
color: #333;
text-decoration: none;
word-break: keep-all;
overflow: hidden;
text-overflow: ellipsis;
word-wrap: break-word;
text-wrap: nowrap;
font-size: 16px; /* 确保16px */
}
.header-PC #header .nav2 .navItem .navItemConten .navItem_cyright .nav_cyrightit dd {
font-size: 16px; /* 原0.14rem=14px → 提升至16px */
line-height: 40px; /* 0.4rem*100=40px */
padding-top: 0vw;
font-weight: 100;
display: inline-block;
margin-right: 3%;
margin-inline-start: 40px; /* 0.4rem*100=40px */
}
.header-PC #header .nav2 .navItem .navItemConten .navItem_cyright .nav_cyrightit dd a {
font-size: 16px; /* 确保16px */
}
.header-PC #header .nav2 .navItem .navItemConten .navItem_cyright .nav_cyrightit dd a:hover {
color: #004bf9;
font-weight: 600;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-transition: all 0.2s linear;
}
.header-PC #header .nav2 .navItem .navItemConten.active {
max-height: 660px; /* 6.6rem*100=660px */
opacity: 1;
}
.header-PC #header .nav2 .navItem .navItemConten1 {
background-color: #fff;
color: black;
position: absolute;
top: 60px; /* 0.6rem*100=60px */
left: 20px; /* 0.2rem*100=20px */
width: auto;
height: auto;
z-index: 9999;
border-radius: 5px; /* 0.05rem*100=5px */
box-shadow: 0 0 1px 0 #88909a; /* 0.01rem*100=1px */
display: none;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 8px 0; /* 0.08rem*100=8px */
font-size: 16px; /* 基础字号16px */
}
.header-PC #header .nav2 .navItem .navItemConten1 li {
color: #fff;
float: left;
text-align: center;
line-height: 24px; /* 0.24rem*100=24px */
padding: 8px 32px; /* 0.08/0.32rem*100=8/32px */
display: list-item;
}
.header-PC #header .nav2 .navItem .navItemConten1 li a {
cursor: pointer;
padding-left: 0;
white-space: nowrap;
font-size: 16px; /* 确保16px */
}
.header-PC #header .nav2 .navItem > a.active,
.header-PC #header .nav2 .navItem .navItemConten1 li a:hover {
color: #004bfa;
}
.header-PC #header .nav3 {
position: relative;
width: 20%;
background-color: transparent;
display: flex;
align-items: center;
cursor: pointer;
font-size: 16px; /* 基础字号16px */
}
.header-PC #header .nav3 .searchimg {
margin-left: 10%;
}
.header-PC #header .nav3 .storetopbt {
background: #004cfa;
color: #fff;
padding: 0 15px; /* 0.15rem*100=15px */
border-radius: 20px; /* 0.2rem*100=20px */
height: 38px; /* 0.38rem*100=38px */
line-height: 40px; /* 0.4rem*100=40px */
margin-left: 15%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
font-size: 16px; /* 强制16px */
}
.header-PC #header .nav3 .storetopbt .storeImgico {
width: 20px; /* 0.2rem*100=20px */
margin-right: 8px; /* 0.08rem*100=8px */
}
.header-PC #header .nav3 .choesCountry {
position: relative;
margin-left: 15%;
display: flex;
}
.header-PC #header .nav3 .choesCountry .topCountry {
display: none;
width: 340px; /* 3.4rem*100=340px */
background-color: white;
/* position: fixed; */
position: absolute;
right: -150px;
top: 50px; /* 0.8rem*100=80px */
border-radius: 15px; /* 0.15rem*100=15px */
box-shadow: 2px 2px 10px 1px #88909a; /* 0.02/0.02/0.1/0.01rem 转px */
font-size: 16px; /* 基础字号16px */
}
.header-PC #header .nav3 .choesCountry .topCountry li {
width: 100%;
height: 50px; /* 0.5rem*100=50px */
line-height: 50px; /* 0.5rem*100=50px */
text-align: center;
display: flex;
}
.header-PC #header .nav3 .choesCountry .topCountry li .countryName {
width: 70%;
text-align: left;
margin-left: 10px; /* 0.1rem*100=10px */
font-size: 16px; /* 强制16px */
}
.header-PC #header .nav3 .choesCountry .topCountry li .cico {
width: 18%;
margin-left: 0;
}
.header-PC #header .nav3 .choesCountry .topCountry li .cico .countryimg {
margin-left: 0;
margin-left: 20px; /* 0.2rem*100=20px */
margin-top: 15px; /* 0.15rem*100=15px */
vertical-align: top;
}
.header-PC #header .nav3 .choesCountry .topCountry li.closec {
display: flex;
flex-direction: row;
justify-content: end;
height: 30px; /* 0.3rem*100=30px */
}
.header-PC #header .nav3 .choesCountry .topCountry .closecountrybt {
color: #aaa;
margin-top: -5px; /* 0.05rem*100=5px */
cursor: pointer;
height: 20px; /* 0.2rem*100=20px */
width: 20px; /* 0.2rem*100=20px */
margin-right: 10px; /* 0.1rem*100=10px */
font-size: 16px; /* 确保关闭按钮文字16px */
}
.header-PC .searchmodalMian {
position: fixed;
z-index: 999;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
z-index: 998;
display: none;
}
.header-PC .searchmodalMian .searchmodalct {
background-color: #fff;
padding: 20px; /* 0.2rem*100=20px */
border-radius: 20px; /* 0.2rem*100=20px */
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); /* 0.04/0.08rem 转px */
border: 1px solid rgba(0, 0, 0, 0.2);
position: fixed;
right: 2%;
width: 33%;
top: 80px; /* 0.8rem*100=80px */
height: 80%;
overflow-y: auto;
z-index: 998;
font-size: 16px; /* 基础字号16px */
}
.header-PC .searchmodalMian .searchmodalct .close-btn {
color: #aaa;
float: right;
font-size: 24px; /* 0.24rem*100=24px */
cursor: pointer;
}
.header-PC .searchmodalMian .searchmodalct #serrchinput {
margin-left: 10%;
margin-top: 5%;
width: 80%;
height: 44px; /* 0.44rem*100=44px */
border: 1px solid grey;
border-radius: 22px; /* 0.22rem*100=22px */
background-position: 95% 50%;
padding-left: 5%;
font-size: 16px; /* 输入框文字16px */
}
.header-PC .searchmodalMian .searchmodalct .searchhistory,
.header-PC .searchmodalMian .searchmodalct .popProduct {
margin-top: 5%;
margin-left: 10%;
width: 80%;
display: flex;
position: relative;
}
.header-PC .searchmodalMian .searchmodalct .searchhistory .h_title,
.header-PC .searchmodalMian .searchmodalct .popProduct .h_title {
position: absolute;
left: 0;
top: 1%;
font-size: 16px; /* 保持16px */
color: #989898;
}
.header-PC .searchmodalMian .searchmodalct .searchhistory ul,
.header-PC .searchmodalMian .searchmodalct .popProduct ul {
margin-top: 10%;
margin-left: 1%;
}
.header-PC .searchmodalMian .searchmodalct .popProduct .popmain{
width: 100%;
}
.header-PC .searchmodalMian .searchmodalct .searchhistory .popmain,
.header-PC .searchmodalMian .searchmodalct .popProduct .popmain {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.header-PC .searchmodalMian .searchmodalct .searchhistory .popmain .popitem,
.header-PC .searchmodalMian .searchmodalct .popProduct .popmain .popitem {
text-align: center;
margin-top: 7%;
margin-left: 1%;
display: flex;
flex-direction: column;
justify-content: center;
width: 30%;
align-items: center;
overflow: hidden;
}
.header-PC .searchmodalMian .searchmodalct .searchhistory .popmain .popitem .popimg,
.header-PC .searchmodalMian .searchmodalct .popProduct .popmain .popitem .popimg {
width: 115px; /* 1.15rem*100=115px */
height: 115px; /* 1.15rem*100=115px */
margin: 0 auto;
}
.header-PC .searchmodalMian .searchmodalct .searchhistory .popmain .popitem .productName,
.header-PC .searchmodalMian .searchmodalct .popProduct .popmain .popitem .productName {
font-weight: 600;
display: -webkit-box;
-webkit-line-clamp: 1;
text-overflow: ellipsis;
font-size: 16px; /* 原0.128rem=12.8px → 提升至16px */
margin-top: 10%;
}
.header-PC .searchmodalMian .searchmodalct .popProduct .popmain .popitem .productName
{
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: block;
font-size: 16px; /* 原14px → 提升至16px */
}
.header-PC .searchmodalMian .searchmodalct .popProduct .popmain .popitem .produc-dec{
font-size: 16px; /* 原10px → 提升至16px */
color: #000000;
margin-top: 1%;
}

View File

@@ -1,45 +0,0 @@
html {
width: 100%;
}
body {
/* width: 100vw;
height: 100vh; */
background: #000;
overflow-x: hidden;
scroll-behavior: smooth !important;
-webkit-overflow-scrolling: touch !important;
/* padding: 0 !important;
margin:0 !important; */
/* max-width:100% !important;
width: 100vw !important;
margin:0 auto; */
/* max-width:100vw !important */
/* margin:0 auto !important; */
}
/* 当视口宽度大于1920px时生效 */
@media screen and (min-width: 1920px) {
/* 这里写你的样式 */
body {
max-width:100% !important;
width: 100vw !important;
}
}
.opacity0 {
opacity: 0;
transform: translateY(0.5rem);
visibility: hidden;
/* margin-top: 20px; */
will-change: opacity, transform;
backface-visibility: hidden;
perspective: 1000px;
transition:
opacity 1.2s ease-in-out,
transform 1.2s ease-in-out,
visibility 1.2s ease-in-out;
}
/* 18-19号防卡顿延迟19号动画 */
/* [data-order="19"] {
transition: all 0.3s ease-out 0.2s !important;
} */

View File

@@ -1,91 +0,0 @@
.ips {
position: relative;
width: 100%;
aspect-ratio: 2560/1657; /* 2560/1440=16/9核心比例约束 */
/* background: url('../img/ips1.png');
background-repeat: no-repeat;
background-size: 100% auto; 宽度铺满,高度自动 */
min-width: 1280px;
/* margin-top: 2.69rem; */
}
.ips-text {
color: #cbcfd8;
/* width: 1440px; */
min-width: 1280px;
/* max-width: 1440px; */
/* margin-left: 6rem; */
width: 100%;
}
.ips-t {
color: #fff;
font-size: 0.63rem;
padding-top:3.9rem;
padding-left: 5.63rem;
}
.ips-p {
font-size: clamp(16px, 1vw, 0.22rem);
padding-top: 0.86rem;
padding-left: 5.63rem;
line-height: 1.8;
color:#cbcfd8;
font-family: "HarmonyOS-Light";
}
.ips-img {
display: flex;
flex-wrap: wrap; /* 允许换行 */
justify-content: space-between; /* 左对齐也可设为center居中 */
margin-left: 5.63rem;
width: 6.9rem;
padding-top: 2rem;
}
.ips-img img {
max-width: 2.2rem;
}
.ips-img img:nth-child(2) {
margin-left: 2.5rem;
}
.ips-img img:nth-child(4) {
margin-left: 2.5rem;
margin-top: 1.22rem;
}
.ips-img img:nth-child(3) {
margin-top: 1.22rem;
}
.ips-img1 {
display: flex;
flex-wrap: wrap; /* 允许换行 */
justify-content: space-between; /* 左对齐也可设为center居中 */
margin-left: 5.63rem;
width: 7.35rem;
padding-top: 2.03rem;
}
.ips-img1 img:nth-child(1) {
width: 100%;
max-width: 2.76rem;
/* aspect-ratio: 276/168; */
}
.ips-img1 img:nth-child(2) {
width: 100%;
max-width: 3.35rem;
max-height:1.3rem ;
/* aspect-ratio: 335/130; */
}
.ips-img1 img:nth-child(3) {
width: 100%;
max-width: 2.67rem;
max-height: 1.18rem;
/* aspect-ratio: 267/118; */
margin-top: 1.36rem;
}
.ips-img1 img:nth-child(4) {
width: 100%;
max-width: 3.39rem;
/* aspect-ratio: 339/122; */
margin-top: 1.36rem;
max-height: 1.22rem;
}

View File

@@ -1,128 +0,0 @@
/* 图片容器100vw宽最小宽度1440px按图片原始比例2560:1857定高 */
.zoom-container {
width: 100%;
min-width: 1440px;
overflow: hidden;
position: relative;
/* 固定比例:高度 = 宽度 * 1857/2560确保图片不裁切 */
aspect-ratio: 2560 / 1857;
height: auto; /* 替代原max计算用aspect-ratio保证比例 */
}
/* 图片包裹层:与容器同尺寸,定位参考系,承接缩放变换 */
.img-wrapper {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
z-index: -10;
}
/* 图片:按原始比例填充包裹层,不裁切,初始放大+过渡动画 */
.bg-img {
width: 100%;
height: 100%;
object-fit: contain; /* 改为contain确保图片完整显示不裁切 */
display: block;
transform: scale(1.5);
transition: transform 1.8s ease;
transform-origin: center center;
}
/* 图片缩小后的状态 */
.bg-img.zoom-out {
transform: scale(1);
}
/* 标注样式:关键修正 - 基于容器绝对定位,百分比参考图片原始比例 */
.annotation {
position: absolute;
color: #48494D;
font-size: calc(12px + 0.3vw);
opacity: 0;
transform: translateY(calc(10px + 0.5vw));
transition: opacity 0.8s ease, transform 0.8s ease;
pointer-events: none;
z-index: 10;
white-space: nowrap;
/* 关键:标注的定位参考系是容器(与图片同比例),而非缩放后的图片 */
top: 0;
left: 0;
/* 重置默认值依赖内联style的百分比定位 */
}
/* 标注显示状态 */
.annotation.anno-show {
opacity: 1;
transform: translateY(0);
}
.annotation span {
position: relative;
display: inline-block;
/* 确保文字居中对齐 */
text-align: center;
}
/* 标注线条样式:基于文字定位,适配缩放 */
.annotation span::before {
content: '';
position: absolute;
left: 50%;
transform: translateX(-50%);
width: 1px;
height: 0;
bottom: calc(100% + 6px);
background-color: #48494D;
transition: height 0.8s ease;
transform-origin: bottom center;
}
/* 标注显示时,设置线条最终高度 */
.annotation.anno-show span::before {
height:clamp(50px,3vw,0.6rem);
/* 最终高度vw单位 */
}
.zoom-text {
padding-top: 3rem;
padding-bottom: 2rem;
}
.zoom-text div{
width: 100%;
text-align: center;
font-size:0.63rem;
color:#fff
}
.zoom-text p{
width: 100%;
text-align: center;
font-size:clamp(16px,1vw,0.22rem);
color:#cbcfd8;
padding-top: 0.43rem;
font-family: "HarmonyOS-Light";
}
/* 响应式适配1280px以下固定尺寸 */
@media (max-width: 1280px) {
.zoom-container {
min-width: 1280px; /* 最小宽度适配 */
}
.annotation span::before {
bottom: calc(100% + 6px);
}
.annotation.anno-show span::before {
height: 38px; /* 固定高度 */
}
.annotation {
font-size: 14px; /* 固定字体大小,避免过小 */
}
}
/* 标注延迟类 */
.anno-delay-1 {
transition-delay: 0.8s;
}
.anno-delay-1 span::before {
transition-delay: 0.8s;
}

View File

@@ -1,163 +0,0 @@
/* .lb {
position: relative;
width: 100%;
height: 100%;
} */
/* 外层容器完全保留你的REM样式 */
.carousel-wrapper {
width: 100%;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
gap: 0;
padding: 0;
padding-top: 0.4rem;
position: relative;
box-sizing: border-box;
}
/* 轮播容器:核心 - REM控制最大宽度宽度100%自适应 */
.carousel-container {
width: 100%;
max-width: 14.4rem; /* 你的REM限制保留 */
overflow: hidden !important;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
flex-shrink: 0;
box-sizing: border-box !important;
transform: translateZ(0);
clip-path: inset(0 1px 0 0);
}
/* 轮播图片列表flex布局无固定宽度靠子元素撑满 */
.carousel-imgs {
display: flex;
transition: transform 0.5s ease-out; /* 顺滑过渡 */
will-change: transform; /* 性能优化 */
height: auto;
flex-wrap: nowrap; /* 禁止换行 */
margin: 0 !important;
padding: 0 !important;
}
/* 单张图片REM控制最大宽度宽度100%继承容器 */
.carousel-img {
width: 100%;
max-width: 14.4rem; /* 你的REM限制保留 */
flex-shrink: 0; /* 禁止收缩 */
object-fit: cover; /* 保持比例,不拉伸 */
height: auto; /* 高度自适应 */
display: block; /* 去除默认间隙 */
margin: 0 !important;
padding: 0 !important;
image-rendering: crisp-edges;
box-sizing: border-box;
}
/* 箭头样式完全保留你的REM样式 */
.carousel-arrow {
width: 0.77rem;
height: 0.77rem;
background: transparent;
border: none;
border-radius: 50%;
cursor: pointer;
z-index: 10;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
opacity: 0.85;
user-select: none;
flex-shrink: 0;
margin: 0 20px;
/* position: absolute;
top: 50%;
transform: translateY(-50%); */
}
.carousel-arrow img {
width: 100%;
height: 100%;
object-fit: contain;
border-radius: 50%;
}
.carousel-arrow:hover {
opacity: 1;
/* transform: translateY(-50%) scale(1.1); */
box-shadow: 0 6px 20px rgba(0, 120, 255, 0.4);
}
.arrow-left {
margin-right: 1rem;
/* left: 0; */
}
.arrow-right {
margin-left: 1rem;
/* right: 0; */
}
/* 文字区域完全保留你的REM样式 */
.carousel-texts {
box-sizing: border-box;
max-width: 14.4rem;
margin: 0 auto;
display: flex;
justify-content: space-between;
/* padding-top: 1rem; */
position: relative;
z-index: 10;
padding:1rem 0.28rem 0 0.52rem;
}
.carousel-text {
border-bottom: 3px solid transparent;
transition: all 0.3s ease;
cursor: pointer;
border-radius: 4px;
color:#48494D;
user-select: none;
}
.carousel-text.active {
transform: translateY(-3px);
color: #fff !important;
/* border-bottom-color: #fff; */
}
.carousel-text-t {
font-size: 0.32rem;
text-align: center;
}
.carousel-text-t1{
font-size: clamp(0.18rem, 1vw, 0.26rem); /* REM版clamp */
text-align: center;
}
.carousel-text-p1 {
font-size: clamp(0.16rem, 1vw, 0.22rem); /* REM版clamp */
padding-top: 0.28rem;
text-align: center;
font-family: "HarmonyOS-Light";
}
.carousel-text-p {
font-size: clamp(0.16rem, 1vw, 0.22rem); /* REM版clamp */
padding-top: 0.3rem;
text-align: center;
font-family: "HarmonyOS-Light";
}
/* 响应式适配小屏幕REM缩放 */
@media (max-width: 768px) {
.carousel-arrow {
width: 0.6rem;
height: 0.6rem;
margin: 0 0.1rem;
}
.arrow-left {
margin-right: 0.5rem;
}
.arrow-right {
margin-left: 0.5rem;
}
.carousel-text-t {
font-size: 0.28rem;
}
}

View File

@@ -1,40 +0,0 @@
.m2 {
width: 100%;
}
.m2-bg {
position: relative;
width: 100%;
aspect-ratio: 2560/1800; /* 2560/1440=16/9核心比例约束 */
/* background: url('../img/m2.png');
background-repeat: no-repeat;
background-size: 100% auto; 宽度铺满,高度自动 */
min-width: 1280px;
}
.m2-bg-t {
font-size: 0.63rem;
color: #fff;
width: 100%;
text-align: center;
padding-top: 1.78rem;
/* margin-top: 1.78rem; */
}
.m2-bg-t1 {
font-size: 0.36rem;
color: #fff;
width: 100%;
text-align: center;
padding-top: 1.78rem;
}
.m2-img-box {
position: absolute;
bottom: 2.19rem;
width: 100%;
display: flex;
justify-content: center;
gap: 0.2rem;
}
.m2-img-box img {
max-width: 4.66rem;
aspect-ratio: 466/249
}

View File

@@ -1,203 +0,0 @@
/* 你的原始基础样式保留,仅添加/修改性能相关属性 */
.container {
max-width: 14.4rem;
margin: 0 auto;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
}
.progress-section {
max-width: 14.4rem;
}
.progress-title {
font-size: 0.48rem;
color: #fff;
padding: 2.13rem 0 0.78rem 0;
font-family: "HarmonyOS-Medium";
}
.progress-item .label {
font-size: 0.4rem;
color: #cbcfd8;
margin-bottom: 0.08rem;
display: flex;
justify-content: space-between;
align-items: baseline;
line-height: 1;
margin-top: 0.3rem;
margin-bottom: 0.76rem;
}
.progress-item .label .device-name {
flex: 1;
font-family: "HarmonyOS-Medium";
}
.progress-item .label .baseline {
color: #cbcfd8;
font-size: 0.6rem;
}
.progress-item .label .value {
font-size: 0.4rem;
min-width: 0.8rem;
text-align: right;
margin-left: 0.16rem;
font-family: "HarmonyOS-Medium";
}
.colorLinearGradient {
background: linear-gradient(90deg, #7e51ff, #d5dfff);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.progress-item .label .value.m4-max {
color: #5e5ce6;
}
.progress-item .label .value.gray {
color: #86868b;
}
.progress-bar-container {
display: flex;
align-items: center;
gap: 0.16rem;
}
.progress-bar {
flex: 1;
height: 0.2rem;
max-height: 20px;
min-height: 10px;
border-radius: 10px;
overflow: hidden;
position: relative;
/* 性能优化1开启硬件加速减少重绘 */
transform: translateZ(0);
will-change: transform;
}
.progress-fill {
height: 100%;
border-radius: 0.05rem;
/* 性能优化2替换width动画为transform消除重排 */
transform: scaleX(0);
transform-origin: left center;
transition: transform 1.2s ease-out;
will-change: transform;
position: relative;
/* 移除原始的width: 0; */
}
/* 保留你所有原始的进度条颜色类 */
.progress-fill.m4-max {
background: linear-gradient(40deg, #7e51ff, #e1d5ff);
}
.progress-fill.m2-max {
background: #bfc5d9;
}
.progress-fill.m1-max {
background: #bfc5d9;
}
.progress-fill.baseline {
background: #bfc5d9;
}
/* 流光动效(保留你的注释,如需启用可直接解开) */
/* .progress-fill::after {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 50%;
height: 100%;
background: linear-gradient(
90deg,
transparent,
rgba(255, 255, 255, 0.3),
transparent
);
animation: shimmer 1.5s infinite;
} */
@keyframes shimmer {
100% {
left: 150%;
}
}
/* 基准说明(保留原始样式) */
.baseline-note {
margin-top: 0.3rem;
font-size: 0.13rem;
color: #86868b;
padding-top: 0.15rem;
border-top: 1px solid #e9e9eb;
}
.baseline-note sup {
font-size: 0.1rem;
vertical-align: top;
}
/* 保留你所有设计稿固定宽度类(完全不动) */
.w1440 {
width: 14.4rem;
}
.w1368 {
width: 13.68rem;
}
.w1243 {
width: 12.43rem;
}
.w964 {
width: 9.64rem;
}
.w681 {
width: 6.81rem;
}
.w1274 {
width: 12.74rem;
}
.w1000 {
width: 10rem;
}
.font32 {
font-size: 0.32rem !important;
}
.colorCBCFD8 {
color: #646778 !important;
}
.color8A8787 {
color: #646778 !important;
}
.progress-p {
color: #cbcfd8;
font-size: clamp(16px, 1vw, 0.22rem);
margin-top: 1.56rem;
margin-bottom: 2rem;
text-align: center;
}
.progress-p1 {
color: #cbcfd8;
font-size: clamp(16px, 1vw, 0.22rem);
margin-top: 1.56rem;
text-align: center;
}

View File

@@ -1,25 +0,0 @@
/* .qb {
position: absolute;
top:3rem;
left: 50%;
transform: translateX(-50%);
} */
.qb-t {
width: 100%;
font-size: 0.63rem;
color: #fff;
text-align: center;
padding-top: 3rem;
}
.qb-p {
font-size: clamp(16px, 1vw, 0.22rem);
color: #cbcfd8;
text-align: center;
padding-top: 0.43rem;
padding-bottom: 0.56rem;
font-family: "HarmonyOS-Light";
}
.qb-bg-img1 {
max-width: 16.43rem;
min-height: 13.31rem;
}

View File

@@ -1,79 +0,0 @@
.readon-box {
position: relative;
width: 100%;
aspect-ratio: 16/9; /* 2560/1440=16/9核心比例约束 */
background-repeat: no-repeat;
background-size: 100% auto; /* 宽度铺满,高度自动 */
margin-bottom: 2.63rem;
}
.readon-text {
/* max-width: 1440px;
min-width: 1280px; */
width: 14.4rem;
margin: 0 auto;
}
.readon-t {
color: #fff;
font-size: 0.68rem;
/* line-height: 1.4; */
/* padding-top: 1.01rem;
padding-bottom: 0.50rem; */
}
.readon-t div:nth-child(1) {
padding-top: 1.34rem;
padding-bottom: 0.41rem;
}
.readon-t div:nth-child(2),.readon-t div:nth-child(3){
font-size:0.63rem;
}
.readon-p {
color: #cbcfd8;
font-size: 0.64rem;
}
.readon-js {
color: #cbcfd8;
font-size: 0.27rem;
line-height: 1.8;
margin-top: 0.72rem;
font-family: "HarmonyOS-Light";
}
.readon-js1 {
color: #cbcfd8;
font-size: 0.22rem;
line-height: 1.8;
margin-top: 0.72rem;
font-family: "HarmonyOS-Light";
}
.readon-img,.readon-img1 {
width: 100%;
/* max-w
max-width: 1440px;
min-width: 1280px; */
margin-top:2.37rem;
}
.readon-img img {
width: 100%;
max-width: 3.78rem;
aspect-ratio: 378/218;
}
.readon-img1 img {
width: 100%;
max-width: 3.73rem;
/* aspect-ratio: 378/218; */
}
.readon-img-box {
width: 100%;
min-width: 1280px;
position: absolute;
margin: 0 auto;
bottom: -0.61rem;
display: flex;
justify-content: center;
gap: 0.2rem;
}
.readon-img-box img {
max-width: 3.45rem;
aspect-ratio:345/245;
}

View File

@@ -1,46 +0,0 @@
.rgb {
position: relative;
width: 100%;
aspect-ratio: 7680/2889; /* 2560/1440=16/9核心比例约束 */
/* background: url('../img/rgb.png');
background-repeat: no-repeat;
background-size: 100% auto; */
min-width: 1280px;
margin-top: 2.7rem;
}
.rgb-text {
position: absolute;
top: -1rem;
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
}
.rgb-t {
width: 100%;
font-size: 0.63rem;
color: #fff;
text-align: center;
}
.rgb-p {
font-size: clamp(16px, 1vw, 0.22rem);
color: #cbcfd8;
text-align: center;
padding-top: 0.43rem;
line-height: 1.8;
font-family: "HarmonyOS-Light";
}
.rgb-img {
width: 100%;
min-width: 1280px;
position: absolute;
bottom: -1.41rem;
display: flex;
justify-content: center;
gap: 0.2rem;
}
.rgb-img img {
max-width:4.66rem;
aspect-ratio: 466/261;
display: block;
}

View File

@@ -1,75 +0,0 @@
/* 轮播容器 - 核心:基于视口高度自适应 */
.auto-swiper-container {
width: 100%;
/* 关键:高度 = 视口高度的百分比可调整如60vh=屏幕高度60% */
/* height: 60vh; */
/* max-height: 800px;
min-height: 300px; */
overflow: hidden;
position: relative;
z-index: 1;
}
/* 轮播项 - 填充容器高度 */
.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: cover; /* 优先填充容器,裁剪超出部分(无拉伸) */
/* object-fit: contain; 可选:完整显示图片,不裁剪(可能留黑边) */
display: block;
}
.swiper-container-texts {
position: absolute;
left: 50%;
top:2.3rem;
transform: translateX(-50%);
z-index: 10;
}
.swiper-container-texts-t {
font-size: 0.9rem;
text-align: center;
width: 100%;
line-height: 1;
}
.swiper-container-texts-p {
padding-top: 0.43rem;
font-size: 0.28rem;
text-align: center;
width: 100%;
display: flex;
align-items: center;
letter-spacing: 1.3px;
}
.swiper-container-texts-p div {
font-family: "HarmonyOS-Light";
}
.swiper-container-texts-line {
width: 1px;
height: 0.16rem;
background: #fff;
margin: 0 12px;
}
.swiper-container-texts-img {
width: 100%;
display: flex;
justify-content: center;
padding-top: 0.63rem;
cursor: pointer;
}
.swiper-container-texts-img a {
width: 1.82rem;
}
.swiper-container-texts-img img {
width: 1.82rem;
}

View File

@@ -1,130 +0,0 @@
.tabs-container {
width: 100%;
/* color: #fff;
width: 1440px;
max-width: 1440px;
min-width: 1280px;
margin: 0 auto; */
margin-bottom: 2.98rem;
}
.tabs-header-box {
width: 100%;
display: flex;
justify-content: center;
margin-top: 1rem;
}
.tabs-header {
display: inline-flex;
/* 改为inline-flex宽度由子元素决定 */
position: relative;
border-bottom: 1px solid #cbcfd8;
margin: 0 auto;
width: 2.33rem;
display: flex;
}
.tab-item {
/* padding: 12px 24px; */
font-size: clamp(16px, 1vw, 0.22rem);
cursor: pointer;
transition: color 0.2s ease;
white-space: nowrap;
color: #cbcfd8;
flex: 1;
text-align: center;
}
.tab-item:nth-child(1) {
margin-bottom: 24px;
}
.tab-item:nth-child(2) {
margin-bottom: 24px;
}
.tab-indicator {
position: absolute;
bottom: 0;
height: 2px;
background-color: #fff;
transform: translateX(0);
width: 80px;
transition: transform 0.3s cubic-bezier(0.25, 0.1, 0.25, 1),
width 0.3s cubic-bezier(0.25, 0.1, 0.25, 1);
will-change: transform, width;
backface-visibility: hidden;
perspective: 1000px;
}
.tab-content {
width: 14.4rem;
max-width: 14.4rem;
/* min-width: 1280px; */
margin: 0 auto;
}
/* 新增样式 */
.content-image {
max-width: 100%;
height: auto;
border-radius: 8px;
}
.content-image img {
max-width: 14.4rem;
}
.content-video {
max-width: 100%;
height: auto;
border-radius: 8px;
}
.tabs-p {
width: 100%;
font-size: clamp(16px, 1vw, 0.22rem);
color: #cbcfd8;
text-align: center;
margin-top:0.7rem;
display: none;
}
.tabs-p.active {
display: block;
}
.tab-panel {
display: none;
}
.tab-panel-img {
background:#1c1c1e ;
width: 100%;
max-width: 14.4rem;
max-height: 7rem;
overflow: hidden;
display: flex;
justify-content: flex-end;
padding-top: 0.7rem;
border-radius: 0.16rem;
}
.tab-panel-img img {
width: 100%;
max-width: 13.7rem;
height: 100%;
}
.tab-panel.active {
display: block;
}
.tab-t {
font-size: 0.63rem;
color: #cbcfd8;
width: 100%;
text-align: center;
margin-top: 3rem;
margin-bottom: 0.7rem;
display: none;
}
.tab-t.active {
display: block;
}
/* .tab-ts {
margin-top: 2.97rem;
margin-bottom: 1rem;
} */

View File

@@ -1,74 +0,0 @@
.wift-bg {
position: relative;
width: 100%;
height: 100%;
aspect-ratio: 2560/1913;
/* 2560/1440=16/9核心比例约束 */
/* background: url('../img/w1.png');
background-repeat: no-repeat;
background-size: 100% auto; */
min-width: 1280px;
/* margin-bottom: 0.71rem; */
position: relative;
}
.wift-test {
position: absolute;
left:50%;
top:3rem;
transform: translateX(-50%);
}
.wift-bg-t {
font-size: 0.5rem;
color: #cbcfd8;
width: 100%;
text-align: center;
}
.wift-bg-p {
font-size: clamp(16px, 1vw, 0.22rem);
color: #cbcfd8;
width: 100%;
text-align: center;
padding-top: 0.43rem;
line-height: 1.8;
font-family: "HarmonyOS-Light";
}
.wift-bg-p1 {
font-size: clamp(16px, 1vw, 0.22rem);
color: #cbcfd8;
width: 100%;
text-align: center;
padding-top: 0.43rem;
line-height: 1.8;
font-family: "HarmonyOS-Light";
}
.wift-bg-img {
width: 100%;
display: flex;
justify-content: center;
position: absolute;
bottom: 1.46rem;
}
.wift-bg-img img {
width: 14.41rem;
}
.wift-t {
width: 100%;
color: #fff;
text-align: center;
/* margin-top: 2.95rem; */
/* padding-top: 2.95rem; */
font-size: 0.72rem;
}
.wift-t div:nth-child(1) {
font-size: 0.72rem;
line-height: 1;
padding-bottom: 0.33rem;
}
.wift-t div:nth-child(2) {
font-size: 0.63rem;
line-height: 1;
}

View File

@@ -1,46 +0,0 @@
.wift6 {
position: relative;
width: 100%;
aspect-ratio: 2560/1440; /* 2560/1440=16/9核心比例约束 */
/* background: url('../img/rgb.png');
background-repeat: no-repeat;
background-size: 100% auto; */
min-width: 1280px;
margin-top: 3.5rem;
}
.wift6-text {
position: absolute;
top: -0.3rem;
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
}
.wift6-t {
width: 100%;
font-size: 0.63rem;
color: #fff;
text-align: center;
}
.wift6-p {
font-size: clamp(16px, 1vw, 0.22rem);
color: #cbcfd8;
text-align: center;
padding-top: 0.43rem;
line-height: 1.8;
font-family: "HarmonyOS-Light";
}
.wift6-img {
width: 100%;
min-width: 1280px;
position: absolute;
bottom: -0.56rem;
display: flex;
justify-content: center;
gap: 0.4rem;
}
.wift6-img img {
max-width:7.15rem;
aspect-ratio: 715/309;
display: block;
}

View File

@@ -1,12 +0,0 @@
.windows {
max-width: 14.4rem;
/* min-width: 1280px; */
position: relative;
width: 100%;
aspect-ratio: 1440/1117; /* 2560/1440=16/9核心比例约束 */
/* background: url('../img/windows1.png');
background-repeat: no-repeat;
background-size: 100% auto; */
/* min-width: 1280px; */
margin: 0 auto;
}

View File

@@ -1,60 +0,0 @@
.xh {
position: relative;
width: 100%;
aspect-ratio: 5120/3316; /* 2560/1440=16/9核心比例约束 */
/* background: url('../img/rgb.png');
background-repeat: no-repeat;
background-size: 100% auto; */
min-width: 1280px;
margin-top: 3.56rem;
}
.xh-text {
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
/* padding-top: 0.8rem; */
}
.xh-t {
width: 100%;
font-size: 0.5rem;
color: #fff;
text-align: center;
}
.xh-t span:nth-child(1) {
font-size: 0.72rem;
}
.xh-t span:nth-child(2) {
font-size: 0.63rem;
margin-left: 0.13rem;
}
.xh-p {
font-size: clamp(16px, 1vw, 0.22rem);
color: #cbcfd8;
text-align: center;
padding-top: 0.43rem;
font-family: "HarmonyOS-Light";
}
.xh-img {
width: 100%;
min-width: 1280px;
position: absolute;
bottom: 1.8rem;
display: flex;
justify-content: center;
gap: 0.2rem;
}
.xh-img img {
max-width: 7.1rem;
aspect-ratio: 710/308;
display: block;
}
.xh-b-p {
color: #ffffff;
font-size: clamp(16px, 1vw, 0.22rem);
position: absolute;
bottom: 0;
text-align: center;
left: 50%;
transform: translateX(-50%);
}

View File

@@ -1,55 +0,0 @@
/* 页面容器(模拟官网宽屏布局) */
.xn-container {
/* min-width: 1280px; */
max-width: 14.4rem;
width: 100%;
margin: 0 auto;
}
/* 图片容器样式(核心) */
.xn-image-section {
overflow: hidden;
border-radius: 16px;
/* 官网图片圆角风格 */
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
max-width: 14.4rem;
/* min-width: 1280px; */
margin: 0 auto;
background: #0d0c10;
border:1px solid #3f3f45;
}
.zoom-image {
width: 100%;
height: auto;
display: block;
/* 调整transform过渡时间为2sopacity为1.5s,可按需修改 */
transition: transform 2s cubic-bezier(0.25, 0.1, 0.25, 1), opacity 1.5s ease;
transform: scale(0.8);
/* 初始缩放比例 */
opacity: 0.9;
/* 初始透明度(略暗,放大后变亮) */
}
/* 滚动触发后的放大状态 */
.zoom-image.active {
transform: scale(1.1);
/* 放大5%(官网常用比例,不夸张) */
opacity: 1;
}
.xn-t {
font-size:0.63rem;
color: #fff;
text-align: center;
margin-top: 3rem;
margin-bottom: 1.26rem;
}
.xn-p {
padding-top: 0.6rem;
}
.xn-p p {
font-size: clamp(16px, 1vw, 0.22rem);
color: #CBCFD8;
text-align: center;
line-height: 2.4;
}

View File

@@ -1,67 +0,0 @@
/* 容器高度完全跟随图片真实高度 */
.fullscreen-img-container {
position: relative;
width: 100%;
min-width: 1280px;
margin-top:1.5rem;
aspect-ratio: 16/9; /* 2560/1440=16/9核心比例约束 */
/* background: url('../img/yq1.png'); */
background-size: cover;
/* 去掉所有强制高度,高度=图片真实高度 */
}
/* 图片按真实比例显示,不拉伸/裁剪可选cover看需求 */
.fullscreen-img {
width: 100%;
height: auto;
display: block;
/* 如需填满容器保留cover如需显示完整图片改为contain */
object-fit: cover;
}
/* 文字:修复宽幅+居中生效(仅改定位行) */
.overlay-text {
/* 宽幅限制生效 */
width: 100%;
min-width: 1280px;
padding-top: 1.5rem;
}
.overlay-text div {
width: 100%;
font-size: 0.63rem;
color: #fff;
text-align: center;
line-height: 1;
font-size: 500;
}
.overlay-text p {
font-size: clamp(16px,1vw,0.22rem);
color: #cbcfd8;
text-align: center;
padding-top: 0.43rem;
font-family: "HarmonyOS-Light";
}
.float-cards {
display: flex;
width: 100%;
justify-content: center;
position: absolute;
bottom: -1.05rem;
gap: 0.2rem;
}
.float-cards img {
/* width: 2.96rem; */
/* width: 100%; */
max-width: 2.96rem;
aspect-ratio:296/215
}
.bottom-desc {
text-align: center;
color: #cbcfd8;
font-size: clamp(16px, 1vw, 0.22rem);
padding-top: 1.9rem;
width: 100%;
min-width: 1280px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -10,7 +10,6 @@ $(document).ready(function () {
// 初始化图片放大功能
initImageEnlarger();
console.log('触发')
});
/**
@@ -295,4 +294,4 @@ function initImageEnlarger() {
$enlargeImg.hide();
}
});
}
}

View File

@@ -1,186 +0,0 @@
# 图片迁移脚本快速开始指南
## 概述
这是一个通过SSH将本地图片迁移到远程服务器的Python脚本。支持保持相对路径结构自动创建目录批量处理图片文件。
## 环境要求
- Python 3.6+
- paramiko库 (SSH客户端库)
## 快速开始
### 1. 安装依赖
```bash
cd /var/www/html/orico-official-website/scripts
pip install -r requirements.txt
```
### 2. 创建配置文件
```bash
# 创建示例配置文件
python image_migrate.py --create-config config.json
```
编辑生成的 `config.json` 文件,填写目标服务器信息:
- 修改 `target.ssh` 部分的目标服务器地址、用户名、密码/密钥
- 设置 `source.base_dir` 为本地图片目录路径
### 3. 准备图片路径列表
创建 `images.txt` 文件,每行一个相对路径:
```txt
uploads/products/2024/01/product1.jpg
uploads/products/2024/01/product2.jpg
assets/images/logo.png
uploads/banners/main-banner.jpg
```
### 4. 执行迁移
```bash
python image_migrate.py --config config.json --input images.txt --verbose
```
## 配置文件示例(本地源)
```json
{
"source": {
"type": "local",
"base_dir": "/var/www/html/orico-official-website/public/uploads"
},
"target": {
"type": "ssh",
"base_dir": "/var/www/html/images",
"ssh": {
"host": "your-server.com",
"port": 22,
"username": "deploy",
"password": "your_password",
"key_file": "/path/to/private/key"
}
}
}
```
## 常用命令
### 基本迁移
```bash
python image_migrate.py --config config.json --input images.txt
```
### 详细输出模式
```bash
python image_migrate.py --config config.json --input images.txt --verbose
```
### 覆盖已存在的文件
```bash
python image_migrate.py --config config.json --input images.txt --overwrite
```
### 直接从命令行指定文件
```bash
python image_migrate.py --config config.json \
"uploads/test1.jpg" \
"uploads/test2.jpg" \
"assets/logo.png"
```
### 不使用配置文件,直接指定参数
```bash
python image_migrate.py \
--source-type local \
--source-dir /path/to/local/images \
--target-host server.example.com \
--target-user username \
--target-dir /remote/path/images \
--input images.txt \
--verbose
```
## 常见场景
### 场景1迁移网站上传目录
```bash
# 配置文件中的源目录设置为:
"source": {
"type": "local",
"base_dir": "/var/www/html/orico-official-website/public/uploads"
}
# 执行迁移
python image_migrate.py --config config.json --input uploads_list.txt
```
### 场景2从数据库导出路径并迁移
```bash
# 从数据库导出图片路径
mysql -u username -p database -e "SELECT image_path FROM products" --skip-column-names > products.txt
# 清理路径(如果需要)
sed -i 's/^\.\///' products.txt
# 迁移图片
python image_migrate.py --config config.json --input products.txt --verbose
```
### 场景3迁移整个目录结构
```bash
# 使用find命令生成所有图片文件列表
find /path/to/local/images -type f \( -name "*.jpg" -o -name "*.png" -o -name "*.gif" -o -name "*.webp" \) | sed 's|^/path/to/local/images/||' > all_images.txt
# 迁移所有图片
python image_migrate.py --config config.json --input all_images.txt
```
## 路径说明
- **相对路径**:相对于配置文件中指定的 `base_dir`
- **示例**:如果 `base_dir``/var/www/html/images`,相对路径 `uploads/test.jpg` 对应完整路径 `/var/www/html/images/uploads/test.jpg`
- **目标路径**:在目标服务器上保持相同的相对路径结构
## 故障排查
### 1. 连接失败
```bash
# 测试SSH连接
ssh -p 22 username@server.example.com
# 检查配置文件中的主机、端口、用户名是否正确
```
### 2. 文件不存在
```bash
# 检查本地文件是否存在
ls -la /var/www/html/orico-official-website/public/uploads/uploads/test.jpg
# 使用详细模式查看完整路径
python image_migrate.py --config config.json --input images.txt --verbose
```
### 3. 权限不足
```bash
# 检查本地文件读取权限
ls -la /path/to/local/images
# 检查目标目录写入权限通过SSH
ssh username@server.example.com "ls -la /remote/path/images"
```
## 注意事项
1. 建议使用SSH密钥认证而非密码更安全
2. 首次使用前,建议用少量文件测试
3. 大文件传输可能需要较长时间,建议分批处理
4. 使用 `--verbose` 参数可查看详细传输信息
5. 脚本会自动创建目标服务器上的目录结构
## 获取帮助
```bash
# 查看完整帮助
python image_migrate.py --help
# 查看详细使用说明
cat README.md
```
---
*快速开始指南更新日期2024年*
*脚本位置:/var/www/html/orico-official-website/scripts/*

View File

@@ -1,415 +0,0 @@
# 图片迁移脚本 (Image Migration Script)
从本地目录或SSH服务器迁移图片到远程SSH服务器保持相对路径结构一致。
## 功能特性
-**灵活的源支持**:支持本地目录(`local`)和SSH服务器(`ssh`)作为源
-**远程目标**通过SSH迁移到远程服务器
-**路径保持**:在目标服务器上保持相同的相对路径和文件名
-**配置灵活**:支持配置文件和命令行参数
-**目录自动创建**:递归创建目标目录结构
-**重复文件处理**:默认跳过已存在文件,支持覆盖选项
-**进度统计**:显示详细的传输进度和统计信息
-**错误处理**:完善的连接管理和错误处理
## 环境要求
- Python 3.6+
- paramiko 库用于SSH连接
## 快速开始
### 1. 安装依赖
```bash
cd /var/www/html/orico-official-website/scripts
pip install -r requirements.txt
```
### 2. 创建配置文件
```bash
# 创建示例配置文件
python image_migrate.py --create-config config.json
# 编辑配置文件,填写真实的服务器信息
vim config.json
```
### 3. 准备图片路径列表
创建一个文本文件(如 `images.txt`),每行一个相对路径:
```
uploads/products/2024/01/product1.jpg
uploads/products/2024/01/product2.jpg
assets/images/logo.png
```
### 4. 执行迁移
#### 从本地目录迁移到远程服务器(最常用)
```bash
# 使用配置文件迁移(源为本地目录)
python image_migrate.py --config config.json --input images.txt
# 或直接指定参数迁移(源为本地目录)
python image_migrate.py \
--source-type local --source-dir /path/to/local/images \
--target-host dst.example.com --target-user user2 --target-dir /home/user/images \
--input images.txt --verbose
```
#### 从SSH服务器迁移到另一个SSH服务器
```bash
# 使用配置文件迁移源为SSH服务器
python image_migrate.py --config config.json --input images.txt
# 或直接指定参数迁移源为SSH服务器
python image_migrate.py \
--source-type ssh --source-host src.example.com --source-user user1 --source-dir /var/www/images \
--target-host dst.example.com --target-user user2 --target-dir /home/user/images \
--input images.txt --verbose
```
## 配置文件格式
配置文件为JSON格式支持两种源类型配置
### 本地目录作为源(推荐)
```json
{
"source": {
"type": "local",
"base_dir": "/path/to/local/images"
},
"target": {
"type": "ssh",
"base_dir": "/var/www/html/images",
"ssh": {
"host": "target-server.example.com",
"port": 22,
"username": "username",
"password": "your_password_here",
"key_file": "/path/to/private/key"
}
}
}
```
### SSH服务器作为源
```json
{
"source": {
"type": "ssh",
"base_dir": "/var/www/html/images",
"ssh": {
"host": "source-server.example.com",
"port": 22,
"username": "username",
"password": "your_password_here",
"key_file": "/path/to/private/key"
}
},
"target": {
"type": "ssh",
"base_dir": "/var/www/html/images",
"ssh": {
"host": "target-server.example.com",
"port": 22,
"username": "username",
"password": "your_password_here",
"key_file": "/path/to/private/key"
}
}
}
```
**注意:**
- `type`:可以是 `"local"`(本地目录)或 `"ssh"`SSH服务器
- `base_dir`:图片的基础目录,图片的相对路径将相对于这个目录
- 对于SSH类型需要提供`ssh`配置部分
- `password``key_file` 二选一即可
- 目标服务器**必须**是SSH类型
## 命令行参数
### 主要选项
| 参数 | 说明 |
| ---------------------- | ---------------------- |
| `--config FILE` | 使用配置文件 |
| `--create-config FILE` | 创建示例配置文件 |
| `--input FILE` | 包含图片路径列表的文件 |
| `--verbose`, `-v` | 显示详细输出 |
| `--overwrite` | 覆盖已存在的文件 |
### 源服务器参数(可覆盖配置文件)
| 参数 | 说明 |
| ------------------------ | ------------------------------------------------------------ |
| `--source-type TYPE` | 源类型: `local`(本地目录) 或 `ssh`(SSH服务器),默认: `local` |
| `--source-dir DIR` | **必需** 源服务器图片基础目录 |
| `--source-host HOST` | 源服务器地址仅SSH类型需要 |
| `--source-port PORT` | 源服务器端口仅SSH类型默认: 22 |
| `--source-user USER` | 源服务器用户名仅SSH类型需要 |
| `--source-password PASS` | 源服务器密码仅SSH类型需要 |
| `--source-key FILE` | 源服务器私钥文件路径仅SSH类型需要 |
### 目标服务器参数(可覆盖配置文件)
| 参数 | 说明 |
| ------------------------ | ------------------------------------ |
| `--target-host HOST` | **必需** 目标服务器地址必须是SSH |
| `--target-port PORT` | 目标服务器端口(默认: 22 |
| `--target-user USER` | **必需** 目标服务器用户名 |
| `--target-password PASS` | 目标服务器密码 |
| `--target-key FILE` | 目标服务器私钥文件路径 |
| `--target-dir DIR` | **必需** 目标服务器图片基础目录 |
## 使用示例
### 示例1从本地目录迁移到远程服务器推荐
```bash
# 1. 创建配置文件
python image_migrate.py --create-config myconfig.json
# 2. 编辑配置文件
# 将 source.type 设置为 "local"
# 设置 source.base_dir 为本地目录路径
# 填写目标服务器的SSH信息
# 3. 创建图片路径文件
echo "uploads/test.jpg" > images.txt
echo "assets/logo.png" >> images.txt
# 4. 执行迁移
python image_migrate.py --config myconfig.json --input images.txt
```
### 示例2直接从命令行迁移本地图片
```bash
python image_migrate.py \
--source-type local \
--source-dir /home/user/my_website/images \
--target-host 192.168.1.200 \
--target-user deploy \
--target-key ~/.ssh/id_rsa \
--target-dir /var/www/html/images \
--input images.txt \
--verbose
```
### 示例3从SSH服务器迁移到另一个SSH服务器
```bash
python image_migrate.py \
--source-type ssh \
--source-host old-server.example.com \
--source-user admin \
--source-key ~/.ssh/id_rsa \
--source-dir /var/www/images \
--target-host new-server.example.com \
--target-user deploy \
--target-dir /home/deploy/images \
--input images.txt \
--overwrite
```
### 示例4直接从命令行指定图片路径
```bash
python image_migrate.py --config config.json \
"uploads/product1.jpg" \
"uploads/product2.jpg" \
"assets/logo.png"
```
### 示例5批量迁移数据库导出的图片路径
```bash
# 从数据库导出图片路径(假设每行一个路径)
mysql -e "SELECT image_path FROM products" --skip-column-names > products.txt
# 清理路径(如果需要)
sed -i 's/^\.\///' products.txt
# 迁移图片
python image_migrate.py --config config.json --input products.txt --verbose
```
## 图片路径格式
图片路径应为**相对路径**,相对于配置文件中指定的 `base_dir`
```
# 正确示例(相对路径)
uploads/products/2024/01/product1.jpg
assets/images/logo.png
# 错误示例(绝对路径)
/var/www/html/images/uploads/product1.jpg # 错误!应该使用相对路径
# 在目标服务器上,文件将保存为:
# 目标 base_dir + 相对路径
```
## 工作流程
1. **连接建立**连接到目标SSH服务器源为本地时不需要连接
2. **路径处理**:为每个图片构建完整源路径和目标路径
3. **目录创建**:在目标服务器上创建必要的目录结构
4. **文件检查**:检查源文件是否存在,目标文件是否已存在(跳过)
5. **文件传输**:通过本地临时文件传输(源→本地临时文件→目标)
6. **统计报告**:显示传输结果和统计信息
## 故障排除
### 常见问题
#### 1. 连接失败
```
错误: 连接失败: [Errno 111] Connection refused
```
- 检查目标服务器地址和端口
- 确认SSH服务正在运行
- 检查防火墙设置
#### 2. 认证失败
```
错误: Authentication failed.
```
- 确认用户名和密码正确
- 检查SSH密钥权限chmod 600 ~/.ssh/id_rsa
- 确认密钥已添加到目标服务器的 authorized_keys
#### 3. 源文件不存在
```
错误: 源文件不存在: /path/to/local/images/uploads/test.jpg
```
- 确认相对路径正确
- 确认源基础目录正确
- 使用 `--verbose` 查看完整路径
#### 4. 权限不足
```
错误: Permission denied
```
- 确认用户有读取源文件的权限(本地文件)
- 确认用户有写入目标目录的权限
#### 5. 目录创建失败
```
错误: 无法创建目标目录: /var/www/html/images/uploads
```
- 检查目标目录的写入权限
- 确认目标服务器磁盘空间充足
### 调试技巧
1. **使用详细模式**:添加 `--verbose` 参数查看详细信息
2. **测试连接**手动SSH连接测试目标服务器是否可达
3. **检查路径**:在源目录上确认文件存在
4. **查看日志**:脚本会显示详细的错误信息
## 性能优化
### 大文件传输
- 脚本使用流式传输,适用于大文件
- 临时文件存储在系统临时目录,传输完成后自动清理
### 批量传输
- 对于大量文件,建议分批处理
- 可以使用多个图片路径文件,分别执行迁移
### 网络优化
- 确保到目标服务器的网络连接稳定
- 考虑使用内网传输以提高速度
## 安全注意事项
1. **认证方式**建议使用SSH密钥认证而非密码
2. **权限控制**:配置文件建议设置权限 `chmod 600 config.json`
3. **最小权限**:使用具有最小必要权限的账户执行迁移
4. **本地文件安全**:确保本地目录不包含敏感信息
5. **临时文件清理**:脚本会自动清理临时传输文件
## 扩展和定制
### 修改脚本
- 可以在 `ImageMigrator` 类中添加额外的功能
- 支持断点续传、并行传输等高级功能
### 集成到工作流
- 可以与其他脚本结合使用
- 可以作为CI/CD流程的一部分
### 添加进度条
```python
# 可选:安装 tqdm 库
pip install tqdm
# 在脚本中添加进度条显示
```
## 文件结构
```
scripts/
├── image_migrate.py # 主脚本
├── image_migrate_backup.py # 原始版本备份
├── requirements.txt # Python依赖
├── README.md # 本文档
└── examples/ # 示例文件
├── config.example.json # 配置文件示例
└── images.example.txt # 图片路径示例
```
## 版本更新
### v2.0 更新
- ✅ 新增本地目录(`local`)作为源的支持
- ✅ 默认源类型改为`local`
- ✅ 简化配置文件结构
- ✅ 改进错误处理和临时文件管理
## 许可证
本脚本根据项目需要自由使用和修改。
## 支持
如有问题,请:
1. 检查本文档的故障排除部分
2. 使用 `--verbose` 参数获取详细信息
3. 确认服务器配置正确
---
**提示**:首次使用前,建议在测试服务器上进行小规模测试。

View File

@@ -1,24 +0,0 @@
{
"source": {
"type": "local",
"base_dir": "public/storage",
"ssh": {
"host": "source-server.example.com",
"port": 22,
"username": "username",
"password": "your_password_here",
"key_file": ""
}
},
"target": {
"type": "ssh",
"base_dir": "/www/wwwroot/orico-official-website/public/storage",
"ssh": {
"host": "47.91.149.172",
"port": 22,
"username": "root",
"password": "Orico666tx5d",
"key_file": ""
}
}
}

View File

@@ -1,24 +0,0 @@
{
"source": {
"type": "local",
"base_dir": "/var/www/html/orico-official-website/public/storage",
"ssh": {
"host": "source-server.example.com",
"port": 22,
"username": "username",
"password": "your_password_here",
"key_file": "/path/to/private/key"
}
},
"target": {
"type": "ssh",
"base_dir": "/www/wwwroot/orico-official-website/public/storage",
"ssh": {
"host": "47.91.149.172",
"port": 22,
"username": "root",
"password": "Orico666tx5d",
"key_file": ""
}
}
}

View File

@@ -1,12 +0,0 @@
# 图片路径示例文件
# 每行一个相对路径(相对于配置文件中指定的基础目录)
# 空行和以 # 开头的行会被忽略
# 路径使用正斜杠 /即使在Windows系统上
# 注意:这些路径都是相对路径
# 实际文件在源服务器上的完整路径是:源基础目录 + 相对路径
# 例如:如果源基础目录是 /var/www/html/images
# 那么 uploads/products/2024/01/product1.jpg 对应的完整路径是:
# /var/www/html/images/uploads/products/2024/01/product1.jpg
images/article/logo.png

View File

@@ -1,912 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
图片迁移脚本 - 通过SSH或本地目录迁移图片到远程服务器
保持相对路径结构一致
"""
import argparse
import json
import os
import shutil
import sys
import tempfile
import time
from typing import Any, Dict, List, Optional, Tuple
# paramiko 导入被延迟到实际需要时
paramiko: Any = None
def ensure_paramiko() -> None:
"""确保paramiko已导入如果未安装则报错"""
global paramiko
if paramiko is None:
try:
import paramiko as paramiko_module
paramiko = paramiko_module
except ImportError:
print("错误: 需要安装paramiko库")
print("请运行: pip install paramiko")
sys.exit(1)
class ServerConfig:
"""服务器配置支持SSH或本地目录"""
def __init__(
self,
config_type: str = "ssh", # "ssh" 或 "local"
host: str = "",
port: int = 22,
username: Optional[str] = None,
password: Optional[str] = None,
key_file: Optional[str] = None,
base_dir: Optional[str] = None,
):
"""
初始化服务器配置
Args:
config_type: 配置类型,'ssh' 表示SSH服务器'local' 表示本地目录
host: 服务器地址对于local类型可为None
port: 服务器端口仅SSH类型
username: 用户名仅SSH类型
password: 密码仅SSH类型
key_file: 私钥文件路径仅SSH类型
base_dir: 基础目录路径
"""
self.config_type = config_type
self.host = host
self.port = port
self.username = username
self.password = password
self.key_file = key_file
self.base_dir = base_dir.rstrip("/") if base_dir else ""
def to_dict(self) -> Dict:
"""转换为字典"""
return {
"type": self.config_type,
"host": self.host,
"port": self.port,
"username": self.username,
"password": self.password,
"key_file": self.key_file,
"base_dir": self.base_dir,
}
@classmethod
def from_dict(cls, data: Dict) -> "ServerConfig":
"""从字典创建"""
ssh_data = data.get("ssh", {})
return cls(
config_type=data.get("type", "ssh"),
host=ssh_data.get("host", "localhost"),
port=ssh_data.get("port", 22),
username=ssh_data.get("username", ""),
password=ssh_data.get("password", ""),
key_file=ssh_data.get("key_file", ""),
base_dir=data.get("base_dir", ""),
)
def is_local(self) -> bool:
"""是否是本地目录配置"""
return self.config_type == "local"
def __str__(self) -> str:
if self.is_local():
return f"LocalDirectory(base_dir={self.base_dir})"
else:
return f"SSHServer(host={self.host}:{self.port}, user={self.username}, base_dir={self.base_dir})"
class ImageMigrator:
"""图片迁移器"""
def __init__(
self,
source_config: ServerConfig,
target_config: ServerConfig,
verbose: bool = False,
overwrite: bool = False,
) -> None:
"""
初始化迁移器
Args:
source_config: 源服务器配置可以是本地目录或SSH服务器
target_config: 目标服务器配置必须为SSH服务器
verbose: 是否显示详细输出
overwrite: 是否覆盖已存在的文件
"""
self.source_config = source_config
self.target_config = target_config
self.verbose = verbose
self.overwrite = overwrite
# SSH客户端连接仅用于SSH类型的服务器
self.source_client: Any = None
self.target_client: Any = None
self.source_sftp: Any = None
self.target_sftp: Any = None
# 统计信息
self.stats = {
"total": 0,
"success": 0,
"failed": 0,
"skipped": 0,
"bytes_transferred": 0,
}
def connect(self) -> bool:
"""连接到服务器"""
try:
# 确保paramiko已导入
ensure_paramiko()
# 连接目标服务器必须为SSH
if self.target_config.is_local():
print("错误: 目标服务器必须为SSH服务器不能是本地目录")
return False
self.target_client = paramiko.SSHClient()
self.target_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
if self.verbose:
print(
f"连接到目标服务器: {self.target_config.host}:{self.target_config.port}"
)
if self.target_config.key_file:
key = paramiko.RSAKey.from_private_key_file(self.target_config.key_file)
self.target_client.connect(
hostname=self.target_config.host,
port=self.target_config.port,
username=self.target_config.username,
pkey=key,
)
else:
self.target_client.connect(
hostname=self.target_config.host,
port=self.target_config.port,
username=self.target_config.username,
password=self.target_config.password,
)
self.target_sftp = self.target_client.open_sftp()
# 检查SFTP服务器的工作目录
if self.verbose:
try:
cwd = self.target_sftp.getcwd()
print(f"DEBUG: 目标SFTP服务器当前工作目录: {cwd}")
except Exception as e:
print(f"DEBUG: 无法获取目标SFTP服务器工作目录: {e}")
# 连接源服务器如果是SSH类型
if not self.source_config.is_local():
self.source_client = paramiko.SSHClient()
self.source_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
if self.verbose:
print(
f"连接到源服务器: {self.source_config.host}:{self.source_config.port}"
)
if self.source_config.key_file:
key = paramiko.RSAKey.from_private_key_file(
self.source_config.key_file
)
self.source_client.connect(
hostname=self.source_config.host,
port=self.source_config.port,
username=self.source_config.username,
pkey=key,
)
else:
self.source_client.connect(
hostname=self.source_config.host,
port=self.source_config.port,
username=self.source_config.username,
password=self.source_config.password,
)
self.source_sftp = self.source_client.open_sftp()
if self.verbose:
source_type = (
"本地目录" if self.source_config.is_local() else "SSH服务器"
)
print(f"连接成功! 源: {source_type}, 目标: SSH服务器")
return True
except Exception as e:
print(f"连接失败: {e}")
self.close()
return False
def close(self) -> None:
"""关闭所有连接"""
if self.source_sftp:
self.source_sftp.close()
if self.source_client:
self.source_client.close()
if self.target_sftp:
self.target_sftp.close()
if self.target_client:
self.target_client.close()
if self.verbose:
print("连接已关闭")
def ensure_target_directory(self, remote_dir: str) -> bool:
"""确保目标目录存在(递归创建)"""
try:
if self.verbose:
print(f"DEBUG ensure_target_directory: 检查/创建目录: {remote_dir}")
# 确保路径以斜杠开头(绝对路径)
if not remote_dir.startswith("/"):
remote_dir = "/" + remote_dir
if self.verbose:
print(
f"DEBUG ensure_target_directory: 转换为绝对路径: {remote_dir}"
)
# 首先检查目录是否已经存在
try:
# 尝试列出目录内容
self.target_sftp.listdir(remote_dir)
if self.verbose:
print(f"DEBUG ensure_target_directory: 目录已存在: {remote_dir}")
return True
except (FileNotFoundError, IOError):
# 目录不存在,需要递归创建
if self.verbose:
print(
f"DEBUG ensure_target_directory: 目录不存在,开始递归创建: {remote_dir}"
)
# 分割路径为各个组件,保留空字符串以处理根目录
parts = [p for p in remote_dir.split("/") if p]
# 从根目录开始逐级创建
current_path = ""
for i, part in enumerate(parts):
# 构建当前路径(确保以斜杠开头)
if current_path:
current_path = f"{current_path}/{part}"
else:
current_path = f"/{part}"
# 检查当前路径是否存在
try:
self.target_sftp.listdir(current_path)
if self.verbose:
print(
f"DEBUG ensure_target_directory: 路径已存在: {current_path}"
)
except (FileNotFoundError, IOError):
# 当前路径不存在,尝试创建
if self.verbose:
print(
f"DEBUG ensure_target_directory: 创建目录: {current_path}"
)
try:
self.target_sftp.mkdir(current_path)
if self.verbose:
print(
f"DEBUG ensure_target_directory: 目录创建成功: {current_path}"
)
except Exception as mkdir_e:
# 如果创建失败,可能是权限问题或目录已存在
if self.verbose:
print(
f"DEBUG ensure_target_directory: 创建目录时出错 {current_path}: {mkdir_e}"
)
# 尝试检查目录是否真的不存在
try:
self.target_sftp.listdir(current_path)
if self.verbose:
print(
f"DEBUG ensure_target_directory: 目录实际上已存在: {current_path}"
)
except Exception as listdir_e:
# 目录确实不存在且创建失败
print(f"错误: 无法创建目录 {current_path}: {listdir_e}")
return False
# 最终确认目录是否创建成功
try:
self.target_sftp.listdir(remote_dir)
if self.verbose:
print(
f"DEBUG ensure_target_directory: 目录创建完成: {remote_dir}"
)
return True
except Exception as final_check_e:
if self.verbose:
print(
f"DEBUG ensure_target_directory: 最终检查失败 {remote_dir}: {final_check_e}"
)
return False
except Exception as e:
print(f"创建目录失败 {remote_dir}: {e}")
if self.verbose:
import traceback
traceback.print_exc()
return False
def get_source_file_info(self, source_path: str) -> Tuple[bool, Optional[int]]:
"""
获取源文件信息
Returns:
Tuple[exists: bool, size: Optional[int]]
"""
try:
if self.source_config.is_local():
# 本地文件
if self.verbose:
print(f"DEBUG: 检查本地文件路径: {source_path}")
print(f"DEBUG: 当前工作目录: {os.getcwd()}")
print(f"DEBUG: 绝对路径: {os.path.abspath(source_path)}")
print(f"DEBUG: 文件是否存在: {os.path.exists(source_path)}")
if os.path.exists(source_path):
if self.verbose:
print(f"DEBUG: 文件大小: {os.path.getsize(source_path)} bytes")
return True, os.path.getsize(source_path)
else:
if self.verbose:
print("DEBUG: 文件不存在!")
return False, 0
else:
# SSH远程文件
source_attr = self.source_sftp.stat(source_path)
return True, source_attr.st_size
except Exception as e:
if self.verbose:
print(f"DEBUG: 获取文件信息时出错: {e}")
return False, 0
def read_source_file(self, source_path: str, temp_path: str) -> bool:
"""
读取源文件到临时文件
Returns:
bool: 是否成功
"""
try:
if self.source_config.is_local():
# 从本地文件复制
if self.verbose:
print("DEBUG read_source_file: 开始复制文件")
print(f"DEBUG read_source_file: 源路径: {source_path}")
print(f"DEBUG read_source_file: 临时路径: {temp_path}")
print(
f"DEBUG read_source_file: 源文件是否存在: {os.path.exists(source_path)}"
)
print(
f"DEBUG read_source_file: 源文件绝对路径: {os.path.abspath(source_path)}"
)
shutil.copy2(source_path, temp_path)
if self.verbose:
print("DEBUG read_source_file: 复制完成")
print(
f"DEBUG read_source_file: 临时文件是否存在: {os.path.exists(temp_path)}"
)
if os.path.exists(temp_path):
print(
f"DEBUG read_source_file: 临时文件大小: {os.path.getsize(temp_path)} bytes"
)
return True
else:
# 从SSH服务器下载
self.source_sftp.get(source_path, temp_path)
return True
except Exception as e:
with open("fails.txt", "a", encoding="utf-8") as file:
file.write(f"{source_path}\n")
print(f"读取源文件失败 {source_path}: {e}")
import traceback
traceback.print_exc()
return False
def transfer_file(self, relative_path: str) -> bool:
"""
传输单个文件
Args:
relative_path: 相对路径(相对于基础目录)
Returns:
bool: 是否成功
"""
try:
# 构建完整路径
source_path = f"{self.source_config.base_dir}/{relative_path}"
target_path = f"{self.target_config.base_dir}/{relative_path}"
if self.verbose:
source_type = "本地" if self.source_config.is_local() else "远程"
print(f"传输: {relative_path}")
print(f" 源({source_type}): {source_path}")
print(f" 目标(远程): {target_path}")
# 检查源文件是否存在并获取大小
source_exists, file_size = self.get_source_file_info(source_path)
if not source_exists:
print(f"错误: 源文件不存在: {source_path}")
self.stats["failed"] += 1
return False
# 检查目标文件是否已存在根据overwrite选项处理
try:
self.target_sftp.stat(target_path)
if not self.overwrite:
if self.verbose:
print(f"跳过: 目标文件已存在: {target_path}")
self.stats["skipped"] += 1
return True
else:
if self.verbose:
print(f"覆盖: 目标文件已存在: {target_path}")
except FileNotFoundError:
if self.verbose:
print(f"DEBUG: 目标文件不存在,将创建新文件: {target_path}")
except Exception as e:
if self.verbose:
print(f"DEBUG: 检查目标文件时出错: {e}")
# 确保目标目录存在
target_dir = os.path.dirname(target_path)
if self.verbose:
print(f"DEBUG: 目标目录: {target_dir}")
print(f"DEBUG: 目标路径: {target_path}")
if target_dir and not self.ensure_target_directory(target_dir):
print(f"错误: 无法创建目标目录: {target_dir}")
self.stats["failed"] += 1
return False
# 传输文件
start_time = time.time()
temp_path = None
try:
# 创建临时文件
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
temp_path = temp_file.name
if self.verbose:
print(f"DEBUG: 创建临时文件: {temp_path}")
# 读取源文件到临时文件
if not self.read_source_file(source_path, temp_path):
self.stats["failed"] += 1
return False
# 上传到目标服务器
if self.verbose:
print(f"DEBUG: 开始上传到目标服务器: {temp_path} -> {target_path}")
print(f"DEBUG: 临时文件大小: {os.path.getsize(temp_path)} bytes")
print(f"DEBUG: 临时文件是否存在: {os.path.exists(temp_path)}")
# 尝试列出目标目录内容
try:
target_dir = os.path.dirname(target_path)
dir_list = self.target_sftp.listdir(target_dir)
print(f"DEBUG: 目标目录内容: {dir_list}")
except Exception as e:
print(f"DEBUG: 无法列出目标目录内容 {target_dir}: {e}")
# 尝试检查目录是否存在
try:
self.target_sftp.stat(target_dir)
print(f"DEBUG: 但目录stat成功: {target_dir}")
except Exception as stat_e:
print(f"DEBUG: 目录stat也失败: {stat_e}")
self.target_sftp.put(temp_path, target_path)
if self.verbose:
print("DEBUG: 上传完成")
except Exception as e:
if self.verbose:
print(f"DEBUG: 上传过程中出错: {e}")
import traceback
traceback.print_exc()
raise
finally:
# 清理临时文件
if temp_path and os.path.exists(temp_path):
try:
if self.verbose:
print(f"DEBUG: 清理临时文件: {temp_path}")
os.remove(temp_path)
except Exception as e:
if self.verbose:
print(f"DEBUG: 清理临时文件时出错: {e}")
# 记录统计
transfer_time = time.time() - start_time
speed = (file_size or 0) / transfer_time / 1024 if transfer_time > 0 else 0
if self.verbose:
print(
f" 完成: {file_size} bytes, 耗时: {transfer_time:.2f}s, 速度: {speed:.2f} KB/s"
)
self.stats["success"] += 1
self.stats["bytes_transferred"] += file_size or 0
return True
except Exception as e:
print(f"传输失败 {relative_path}: {e}")
if self.verbose:
import traceback
traceback.print_exc()
self.stats["failed"] += 1
return False
def migrate_images(self, image_paths: List[str]) -> Dict[str, int]:
"""
迁移图片列表
Args:
image_paths: 相对路径列表
Returns:
Dict: 统计信息
"""
if not self.connect():
return self.stats
try:
self.stats["total"] = len(image_paths)
source_type = "本地目录" if self.source_config.is_local() else "SSH服务器"
print(f"开始从{source_type}迁移 {len(image_paths)} 个图片到SSH服务器...")
for i, relative_path in enumerate(image_paths, 1):
# 清理路径
relative_path = relative_path.strip()
if not relative_path:
continue
# 显示进度
print(f"[{i}/{len(image_paths)}] {relative_path}", end="")
# 传输文件
success = self.transfer_file(relative_path)
if success:
print("")
else:
print("")
# 打印统计信息
print("\n" + "=" * 50)
print("迁移完成!")
print(f"总计: {self.stats['total']}")
print(f"成功: {self.stats['success']}")
print(f"失败: {self.stats['failed']}")
print(f"跳过: {self.stats['skipped']}")
print(f"传输字节: {self.stats['bytes_transferred']:,}")
return self.stats
finally:
self.close()
def load_config(config_file: str) -> Dict:
"""加载配置文件"""
try:
with open(config_file, "r", encoding="utf-8") as f:
config = json.load(f)
return config
except Exception as e:
print(f"加载配置文件失败 {config_file}: {e}")
return {}
def save_config(config_file: str, config: Dict):
"""保存配置文件"""
try:
with open(config_file, "w", encoding="utf-8") as f:
json.dump(config, f, indent=2, ensure_ascii=False)
print(f"配置文件已保存: {config_file}")
except Exception as e:
print(f"保存配置文件失败 {config_file}: {e}")
def create_example_config(config_file: str):
"""创建示例配置文件"""
example_config = {
"source": {
"type": "local", # 可以是 "local" 或 "ssh"
"base_dir": "/path/to/local/images",
# 如果是SSH类型需要以下配置
"ssh": {
"host": "source-server.example.com",
"port": 22,
"username": "username",
"password": "your_password_here",
"key_file": "/path/to/private/key",
},
},
"target": {
"type": "ssh", # 目标必须是SSH类型
"base_dir": "/var/www/html/images",
"ssh": {
"host": "target-server.example.com",
"port": 22,
"username": "username",
"password": "your_password_here",
"key_file": "/path/to/private/key",
},
},
}
save_config(config_file, example_config)
print("已创建示例配置文件")
print("注意: 源服务器可以是本地目录(local)或SSH服务器(ssh)")
print(" 目标服务器必须是SSH服务器(ssh)")
def read_image_paths(image_list_file: str) -> List[str]:
"""从文件读取图片路径列表"""
paths = []
try:
with open(image_list_file, "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if line and not line.startswith("#"):
paths.append(line)
print(f"从文件读取 {len(paths)} 个图片路径")
except Exception as e:
print(f"读取图片路径文件失败 {image_list_file}: {e}")
return paths
def main():
parser = argparse.ArgumentParser(
description="从本地目录或SSH服务器迁移图片到远程SSH服务器保持相对路径结构",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
示例:
# 使用配置文件迁移(源为本地目录)
python image_migrate.py --config config.json --input images.txt
# 使用配置文件迁移源为SSH服务器
# 配置文件中 source.type="ssh"
# 直接指定参数迁移(源为本地目录)
python image_migrate.py \\
--source-type local --source-dir /path/to/local/images \\
--target-host dst.example.com --target-user user2 --target-dir /home/user/images \\
--input images.txt
# 直接指定参数迁移源为SSH服务器
python image_migrate.py \\
--source-type ssh --source-host src.example.com --source-user user1 --source-dir /var/www/images \\
--target-host dst.example.com --target-user user2 --target-dir /home/user/images \\
--input images.txt
# 创建示例配置文件
python image_migrate.py --create-config config.json
# 从命令行直接指定图片路径
python image_migrate.py --config config.json images/product1.jpg images/product2.jpg
""",
)
# 配置文件选项
parser.add_argument("--config", help="配置文件路径")
parser.add_argument("--create-config", metavar="FILE", help="创建示例配置文件")
# 源服务器选项
parser.add_argument(
"--source-type",
choices=["local", "ssh"],
default="local",
help="源服务器类型: local(本地目录) 或 ssh(SSH服务器),默认: local",
)
parser.add_argument("--source-host", help="源服务器地址仅SSH类型需要")
parser.add_argument(
"--source-port",
type=int,
default=22,
help="源服务器端口仅SSH类型默认: 22",
)
parser.add_argument("--source-user", help="源服务器用户名仅SSH类型需要")
parser.add_argument("--source-password", help="源服务器密码仅SSH类型需要")
parser.add_argument("--source-key", help="源服务器私钥文件路径仅SSH类型需要")
parser.add_argument("--source-dir", help="源服务器图片基础目录")
# 目标服务器选项
parser.add_argument("--target-host", help="目标服务器地址")
parser.add_argument(
"--target-port", type=int, default=22, help="目标服务器端口(默认: 22"
)
parser.add_argument("--target-user", help="目标服务器用户名")
parser.add_argument("--target-password", help="目标服务器密码")
parser.add_argument("--target-key", help="目标服务器私钥文件路径")
parser.add_argument("--target-dir", help="目标服务器图片基础目录")
# 输入选项
parser.add_argument(
"--input", "-i", help="包含图片路径列表的文件(每行一个相对路径)"
)
parser.add_argument("--verbose", "-v", action="store_true", help="显示详细输出")
parser.add_argument("--overwrite", action="store_true", help="覆盖已存在的文件")
# 直接传递图片路径
parser.add_argument("image_paths", nargs="*", help="直接指定图片相对路径")
args = parser.parse_args()
# 创建示例配置文件
if args.create_config:
create_example_config(args.create_config)
return
# 检查必要参数(如果不是创建配置文件)
if not args.config and not (
args.source_dir and args.target_host and args.target_user and args.target_dir
):
print("错误: 必须提供配置文件或指定必要的服务器参数")
print("必要参数: --source-dir, --target-host, --target-user, --target-dir")
parser.print_help()
sys.exit(1)
# 加载配置
config = {}
if args.config:
config = load_config(args.config)
if not config:
print("错误: 无法加载配置文件")
sys.exit(1)
# 构建源服务器配置
source_config_data = config.get("source", {})
# 命令行参数覆盖配置文件
if args.source_type:
source_config_data["type"] = args.source_type
# 如果是SSH类型需要SSH配置
if args.source_type == "ssh" or source_config_data.get("type") == "ssh":
ssh_config = source_config_data.get("ssh", {})
if args.source_host:
ssh_config["host"] = args.source_host
if args.source_port:
ssh_config["port"] = args.source_port
if args.source_user:
ssh_config["username"] = args.source_user
if args.source_password:
ssh_config["password"] = args.source_password
if args.source_key:
ssh_config["key_file"] = args.source_key
source_config_data["ssh"] = ssh_config
# 检查必要的SSH参数
if not ssh_config.get("host"):
print("错误: 源服务器为SSH类型必须指定 --source-host")
sys.exit(1)
if not ssh_config.get("username"):
print("错误: 源服务器为SSH类型必须指定 --source-user")
sys.exit(1)
else:
# 本地类型不需要SSH配置
source_config_data.pop("ssh", None)
# 设置基础目录
if args.source_dir:
source_config_data["base_dir"] = args.source_dir
elif "base_dir" not in source_config_data:
print("错误: 必须指定源服务器图片基础目录 (--source-dir)")
sys.exit(1)
# 构建目标服务器配置
target_config_data = config.get("target", {})
target_config_data["type"] = "ssh" # 目标必须是SSH
ssh_config = target_config_data.get("ssh", {})
# 命令行参数覆盖配置文件
if args.target_host:
ssh_config["host"] = args.target_host
if args.target_port:
ssh_config["port"] = args.target_port
if args.target_user:
ssh_config["username"] = args.target_user
if args.target_password:
ssh_config["password"] = args.target_password
if args.target_key:
ssh_config["key_file"] = args.target_key
target_config_data["ssh"] = ssh_config
# 设置基础目录
if args.target_dir:
target_config_data["base_dir"] = args.target_dir
elif "base_dir" not in target_config_data:
print("错误: 必须指定目标服务器图片基础目录 (--target-dir)")
sys.exit(1)
# 检查必要的目标SSH参数
if not ssh_config.get("host"):
print("错误: 必须指定目标服务器地址 (--target-host)")
sys.exit(1)
if not ssh_config.get("username"):
print("错误: 必须指定目标服务器用户名 (--target-user)")
sys.exit(1)
# 创建服务器配置对象
try:
source_config = ServerConfig.from_dict(source_config_data)
target_config = ServerConfig.from_dict(target_config_data)
if args.verbose:
print(f"源服务器配置: {source_config}")
print(f"目标服务器配置: {target_config}")
except Exception as e:
print(f"创建服务器配置失败: {e}")
sys.exit(1)
# 获取图片路径列表
image_paths = []
# 从文件读取
if args.input:
file_paths = read_image_paths(args.input)
image_paths.extend(file_paths)
# 从命令行参数添加
if args.image_paths:
image_paths.extend(args.image_paths)
if not image_paths:
print("错误: 没有指定要迁移的图片路径")
print("请使用 --input 指定文件或直接在命令行提供路径")
sys.exit(1)
# 去重
image_paths = list(set(image_paths))
# 创建并运行迁移器
migrator = ImageMigrator(
source_config=source_config,
target_config=target_config,
verbose=args.verbose,
overwrite=args.overwrite,
)
# 执行迁移
stats = migrator.migrate_images(image_paths)
# 如果有失败,返回错误代码
if stats["failed"] > 0:
sys.exit(1)
if __name__ == "__main__":
main()

View File

@@ -1,2 +0,0 @@
images/banner/20251217/c16f15d090170b9cecaf6b88e02384f3_thumb.png
images/banner/20251217/c16f15d090170b9cecaf6b88e02384f3.png

View File

@@ -1,8 +0,0 @@
# Requirements for image migration script
paramiko>=2.12.0
# Optional: for better performance with large files
# Optional: for progress bars
# tqdm>=4.66.0
# Install with: pip install -r requirements.txt