163 Commits

Author SHA1 Message Date
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
9db66b7429 七牛云引入字体 2025-12-03 17:56:08 +08:00
c91895f57f 删除备份文件 2025-12-03 17:03:57 +08:00
42d9efdc02 移动端尺寸字体调整 2025-12-03 15:30:19 +08:00
e16b8b6b41 字体切换 2025-12-02 16:33:24 +08:00
8e4befc0ea Merge branch 'font' into dev 2025-12-02 16:12:06 +08:00
1a43ad30fb 移动端 2025-12-02 16:11:12 +08:00
1cdd0536b9 Merge branch 'font' 2025-12-01 15:46:23 +08:00
c28b945858 font 2025-12-01 15:33:55 +08:00
9cc6dc3cd9 Merge branch 'dev' 2025-11-28 16:23:35 +08:00
9845883d8e refactor: 专题 - 电力品线 2025-11-28 16:23:21 +08:00
4d25f6fec8 Merge branch 'dev' 2025-11-28 15:46:00 +08:00
5d44c45c13 footer 2025-11-28 15:45:20 +08:00
2764ce3b86 Merge branch 'dev' 2025-11-28 15:36:31 +08:00
7f472b0351 refactor: 专题 - 电力品线 2025-11-28 15:36:12 +08:00
7cb270b313 Merge branch 'dev' 2025-11-28 15:23:45 +08:00
14df140847 refactor: 专题 - 电力品线 2025-11-28 15:23:29 +08:00
86ffcb99ac Merge branch 'dev' 2025-11-28 14:51:46 +08:00
13e58c33a2 refactor: 专题 - 电力品线 2025-11-28 14:51:30 +08:00
c476193002 Merge branch 'dev' 2025-11-28 14:43:34 +08:00
88e307a10e feat: 添加电力品线专题url 2025-11-28 14:43:17 +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
ca3c00f396 电力 2025-11-28 14:18:19 +08:00
c8d5661856 尺寸调整 2025-11-27 18:38:58 +08:00
288c86ffbc 修复bug 2025-11-27 09:42:18 +08:00
ccc551dcba refactor: 专题 - 电力品线 修改 2025-11-26 17:46:09 +08:00
b6e8aa7880 refactor: 专题 - 电力品线 mobile 修改 2025-11-26 17:29:45 +08:00
cc2bb999c0 refactor: 删除gitea webhook文件 2025-11-25 17:45:32 +08:00
e7009c8a49 refactor: migration文件添加banner简称相关 2025-11-25 17:43:09 +08:00
2a8f88637c refactor: .gitignore 2025-11-25 17:38:57 +08:00
1fc6f9067c refactor: 专题 - 电力品线 2025-11-25 17:36:09 +08:00
ffa6f29af8 refactor: 专题 - 电力品线mobile端 2025-11-25 16:15:42 +08:00
476a238d27 refactor: 专题 - 电力品线pc端 2025-11-25 14:56:57 +08:00
18862c584f refactor: banner加入"banner简称"问题修改 2025-11-25 14:05:01 +08:00
ee9174e801 refactor: .gitignore 2025-11-25 14:01:08 +08:00
4c13d31cb9 feat: banner添加/编辑时加入“banner简称”字段 2025-11-25 14:00:06 +08:00
3ed8e1f8fc refactor: 主题 - 电力品线 2025-11-25 13:48:59 +08:00
1c998a4be1 feat: 添加dev-ci.yaml 2025-11-24 15:43:38 +08:00
c3c67c9e59 feat: 专题 - 电力品线首页 2025-11-20 14:29:30 +08:00
ef5d2c6ab9 refactor: 修改.gitignore 2025-11-20 11:00:35 +08:00
80678c23e2 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-09-19 15:22:25 +08:00
53e56b4649 1 2025-09-19 15:22:22 +08:00
ouzhiqiang
75977040f1 修改分类 2025-09-19 15:14:55 +08:00
ouzhiqiang
cf5a1280ee 修改分类 2025-09-19 14:59:45 +08:00
ouzhiqiang
30d99619b2 修改分类 2025-09-19 14:48:10 +08:00
ouzhiqiang
7e877920ee 修改分类 2025-09-19 14:47:05 +08:00
ouzhiqiang
04ede65c93 修改分类 2025-09-19 14:36:08 +08:00
ouzhiqiang
7524a9d572 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-09-19 14:32:27 +08:00
ouzhiqiang
9b5cf2147d 修改分类 2025-09-19 14:31:56 +08:00
9d898b1be3 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-09-19 14:13:56 +08:00
834114261c 1 2025-09-19 14:13:53 +08:00
ouzhiqiang
2dc787bbfd 修改分类 2025-09-19 11:37:41 +08:00
ouzhiqiang
5d61b4995f 修改分类 2025-09-19 11:22:25 +08:00
ouzhiqiang
6800332b5b 修改分类 2025-09-19 11:17:49 +08:00
ouzhiqiang
1c1d075f5e 修改分类 2025-09-19 11:09:29 +08:00
ouzhiqiang
34821fd0bc 修改分类 2025-09-19 10:41:41 +08:00
ouzhiqiang
3492d55707 修改分类 2025-09-19 10:36:26 +08:00
ouzhiqiang
5b901fe43c 修改分类 2025-09-19 10:29:25 +08:00
ouzhiqiang
e6d299df83 修改分类 2025-09-19 10:23:02 +08:00
ouzhiqiang
5d5a338b55 修改分类 2025-09-19 10:04:47 +08:00
ouzhiqiang
4cd2f4ad26 修改分类 2025-09-19 09:53:40 +08:00
ouzhiqiang
14f899bf62 修改分类 2025-09-19 09:51:29 +08:00
ouzhiqiang
f82888c8e3 Merge branch 'ozq-dev' into dev 2025-09-18 17:50:21 +08:00
ouzhiqiang
43c61a1ab5 修改分类 2025-09-18 17:50:05 +08:00
ouzhiqiang
4f2edf5d30 Merge branch 'ozq-dev' into dev 2025-09-18 17:47:43 +08:00
ouzhiqiang
4ca59e81e3 修改分类 2025-09-18 17:47:22 +08:00
ouzhiqiang
9cd7b4f508 Merge branch 'ozq-dev' into dev 2025-09-18 17:23:25 +08:00
ouzhiqiang
e02ad39620 修改分类 2025-09-18 17:23:07 +08:00
ouzhiqiang
0ce0c0a27a Merge branch 'ozq-dev' into dev 2025-09-18 17:16:43 +08:00
ouzhiqiang
db72a5643c 修改分类 2025-09-18 17:16:24 +08:00
ouzhiqiang
60fb6a5336 Merge branch 'ozq-dev' into dev 2025-09-18 17:13:22 +08:00
ouzhiqiang
987e98279a 修改分类 2025-09-18 17:13:04 +08:00
ouzhiqiang
9b926f1bf8 Merge branch 'ozq-dev' into dev 2025-09-18 17:04:44 +08:00
ouzhiqiang
810b581d87 修改分类 2025-09-18 17:04:29 +08:00
ouzhiqiang
6bbc7c55c9 Merge branch 'ozq-dev' into dev 2025-09-18 17:01:25 +08:00
ouzhiqiang
36de45c2e8 修改分类 2025-09-18 17:01:08 +08:00
ouzhiqiang
fd7e136c3a Merge branch 'ozq-dev' into dev 2025-09-18 16:56:01 +08:00
ouzhiqiang
c9987373a4 修改分类 2025-09-18 16:55:47 +08:00
ouzhiqiang
5386610bf9 Merge branch 'ozq-dev' into dev 2025-09-18 16:53:26 +08:00
ouzhiqiang
f1696a88d2 修改分类 2025-09-18 16:53:06 +08:00
ouzhiqiang
7e96a0e538 Merge branch 'ozq-dev' into dev 2025-09-18 16:49:16 +08:00
ouzhiqiang
1f1cc6145d 修改分类 2025-09-18 16:48:45 +08:00
ouzhiqiang
610377172a Merge branch 'ozq-dev' into dev 2025-09-18 16:11:52 +08:00
ouzhiqiang
0d5593e173 修改分类 2025-09-18 16:11:36 +08:00
ouzhiqiang
6dbeb59b36 Merge branch 'ozq-dev' into dev 2025-09-18 16:08:29 +08:00
ouzhiqiang
e54fccca65 修改分类 2025-09-18 16:08:05 +08:00
ouzhiqiang
1a92627ab9 Merge branch 'ozq-dev' into dev 2025-09-18 16:01:20 +08:00
ouzhiqiang
88a7f06499 修改分类 2025-09-18 16:00:49 +08:00
ouzhiqiang
d6e58c78d4 Merge branch 'ozq-dev' into dev 2025-09-18 15:39:28 +08:00
ouzhiqiang
46e78cff08 修改分类 2025-09-18 15:38:59 +08:00
ouzhiqiang
48c589babf Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-09-18 15:26:19 +08:00
ouzhiqiang
72f974c083 修改分类 2025-09-18 15:25:29 +08:00
9def4960c4 1 2025-09-18 11:59:32 +08:00
622f9f1665 1 2025-09-18 11:57:52 +08:00
db7c34f4ad 分类补充 2025-09-18 11:56:48 +08:00
f79dbc1121 移动端帮助中心三级菜单 2025-09-18 11:52:52 +08:00
f3de8b4a26 帮助中心文档三级菜单 2025-09-18 11:21:50 +08:00
85ccecb5bf Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-09-18 11:15:12 +08:00
fa60ec4fcb feat: 添加open api client管理命令 2025-09-17 17:48:27 +08:00
cb128a32a8 Merge branch 'dev' 2025-08-26 14:53:55 +08:00
705566b376 refactor: 去掉多余目录 2025-08-26 14:53:38 +08:00
0b13ec05dc fix: 修复“检测文件地址并根据情况转换为文件系统地址”url为null情况报错问题 2025-08-26 14:53:17 +08:00
7f765f40ee Merge branch 'dev' 2025-08-08 09:18:33 +08:00
2a9c3332f7 fix: 修复产品目录分类树数据问题 2025-08-08 09:18:13 +08:00
12822ccb6b Merge branch 'dev' 2025-08-07 17:08:12 +08:00
4872574eb0 fix: admapi - 产品目录同步分类更新时bug修复 2025-08-07 17:07:52 +08:00
fa893d6b53 Merge branch 'dev' 2025-08-07 11:38:17 +08:00
f9445b6f49 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-08-07 11:37:49 +08:00
fea5f233a9 style:底部样式修改 2025-08-07 11:36:56 +08:00
e2b65856d2 Merge branch 'dev' 2025-08-07 10:20:10 +08:00
3733ce720d fix: mobile - 底部“联系我们”取值问题 2025-08-07 10:19:45 +08:00
0b82dbbf5f Merge branch 'dev' 2025-08-07 10:18:06 +08:00
74d70fe815 fix: mobile - 底部“联系我们”取值问题 2025-08-07 10:17:24 +08:00
0f2dc12752 Merge branch 'dev' 2025-08-07 10:12:04 +08:00
499e86f52b fix: mobile - 底部“联系我们”取值问题 2025-08-07 10:03:50 +08:00
b24987fbd2 Merge branch 'dev' 2025-08-06 15:35:50 +08:00
19aecea497 perf openapi 图片地址拼接 2025-08-06 15:35:35 +08:00
9060ed8274 Merge branch 'dev' 2025-08-06 12:45:49 +08:00
54d15595ce fix: 后台 - 修改各导出图片等文件地址拼接问题 2025-08-06 11:56:53 +08:00
101c1ae807 fix: 后台 产品导出数据问题 2025-08-06 11:40:44 +08:00
ed7f274c6e fix: 后台 产品导出数据问题 2025-08-06 11:40:09 +08:00
1288ffd51b fix: mobile下视频分类地址错误 2025-07-31 10:55:26 +08:00
62e43375ab fix: 获取文件系统磁盘未判断“//”情况 2025-07-31 09:03:49 +08:00
9f01db7d54 fix: 首页“场景介绍”无法点击 2025-07-31 09:03:48 +08:00
ac06090792 1 2025-07-30 17:08:22 +08:00
6e6e4ac47c 1 2025-07-30 17:07:37 +08:00
8ccc4b0cd5 1 2025-07-30 16:48:54 +08:00
55cd7f2b62 1 2025-07-30 16:47:15 +08:00
43e1ae0422 1 2025-07-30 16:44:32 +08:00
7fcb78dde0 1 2025-07-30 16:40:36 +08:00
6872a13141 Merge branch 'dev' 2025-07-30 16:33:15 +08:00
234658f443 style:产品详情 2025-07-30 16:13:37 +08:00
9f9a384075 .ql-editor 2025-07-30 15:43:42 +08:00
047d7979ff .ql-editor 2025-07-30 15:42:52 +08:00
3544c08005 style:产品详情样式 2025-07-30 15:35:16 +08:00
2ff6d274d9 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-30 15:25:01 +08:00
d31d2359c6 style:详情样式 2025-07-30 15:24:58 +08:00
6f9c89da7b fix: 字段长度限制 2025-07-30 11:13:17 +08:00
9c6659830c fix: 字段长度限制 2025-07-30 11:12:13 +08:00
4c906723df Merge branch 'dev' 2025-07-29 17:52:13 +08:00
d93aa62fbf refactor: 修改后台banner的“链接地址”长度限制为510 2025-07-29 17:51:56 +08:00
f216ba82b4 Merge branch 'dev' 2025-07-29 16:48:16 +08:00
bcd537ef25 Merge branch 'dev' 2025-07-29 16:47:31 +08:00
589a099cdd 1 2025-07-29 14:16:51 +08:00
e13b30bbb2 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-29 14:14:29 +08:00
eb924d42d4 视频宽度限制 2025-07-29 14:14:27 +08:00
9378efe401 文章视频限制 2025-07-29 14:13:34 +08:00
84dd8ea84b fix: migrations/seeds 2025-07-29 14:08:30 +08:00
4c2441b1b6 fix: 产品详情-分类路径bug 2025-07-29 12:00:22 +08:00
db8e0803c1 文章详情样式调整 2025-07-28 14:50:26 +08:00
72b8230d5a Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-28 14:34:41 +08:00
5a8f32e0f8 style:宽度调整 2025-07-28 14:25:01 +08:00
517c2e954b chore: composer.json 2025-07-28 11:13:56 +08:00
eee40e6010 perf: migrations/seeds 2025-07-28 10:33:44 +08:00
a7882da734 perf: 七牛云存储 2025-07-28 10:16:03 +08:00
64ea309b30 refactor: .gitignore 2025-07-25 18:00:14 +08:00
708fee0490 refactor: 七牛云上传 2025-07-25 17:57:31 +08:00
5623c4160e 文章详情样式调整 2025-07-25 13:47:37 +08:00
139 changed files with 5933 additions and 798 deletions

View File

@@ -26,6 +26,13 @@ TTL=3600
REFRESH_TTL=20160
SECRET=b43e6276644ed60e65c50d1b324ba10b
# 七牛云存储配置
[QINIU_CLOUD]
BUCKET = orico-official-website
BASE_URL = //ow.static.f2b211.com
ACCESS_KEY = dOsTum4a5qvhPTBbZRPX0pIOU7PZWRX7htKjztms
SECRET_KEY = KFxsGbnErkALFfeGdMa8QWTdodJbamMX0iznLe-q
# 后台不需要登录的接口
[ADMIN_AUTH]
WHITE_LIST[] = v1/user/login
@@ -47,6 +54,13 @@ REFRESH_TOKEN_LIFETIME = 1209600; # 刷新令牌有效期
RESOURCE_IMAGES_DOMAIN = http://local.orico.com; # 图片资源服务器地址
RESOURCE_VIDEOS_DOMAIN = http://local.orico.com; # 视频资源服务器地址
# 七牛云存储配置
[QINUI]
BUCKET = orico
BASE_URL = http://local.orico.com
ACCESS_KEY = 1234567890
SECRET_KEY = 1234567890
# 前台视图模板规则配置
[INDEX_VIEW_TPL]
# 视图目录

View File

@@ -0,0 +1,26 @@
name: Gitea Actions Official-website
run-name: Deploy to ${{ inputs.deploy_target }} by @${{ gitea.actor }}
on:
push:
branches:
- dev
jobs:
deploy-dev:
runs-on: ubuntu-latest
steps:
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SERVER_SSH_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ secrets.SERVER_HOST }} >> ~/.ssh/known_hosts
- name: Deploy application
run: |
ssh ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }} << 'EOF'
set -e
cd /www/wwwroot/dev.ow.f2b211.com
# 拉取最新代码
git pull --rebase
EOF

9
.gitignore vendored
View File

@@ -7,9 +7,18 @@ Thumbs.db
.env.dev
.env.local
.env.prod
.htaccess
.user.ini
404.html
index.html
public/dist*
public/opendoc
public/logo.png
public/.well-known
/.idea
/.vscode
/.zed
/vendor
/.settings
/.buildpath

24
.zed/settings.json Normal file
View File

@@ -0,0 +1,24 @@
// Folder-specific settings
//
// For a full list of overridable settings, and general information on folder-specific settings,
// see the documentation: https://zed.dev/docs/configuring-zed#settings-files
{
"languages": {
"PHP": {
"language_servers": ["intelephense","!phpactor"]
}
},
"lsp": {
"intelephense": {
"initialization_options": {
"stubs": [
"wordpress",
"laravel",
"symfony",
"codeigniter",
"thinkphp"
]
}
}
}
}

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

@@ -99,6 +99,7 @@ class ReceiveProductSync
}
$category = ProductCategoryModel::language($lang_id)->tcoId($tco_category['id'])->find();
if (!empty($category)) {
$tco_parent = ProductTcoCategoryModel::language($lang_id)->tcoId($tco_category['tco_pid'])->find();
if (!empty($tco_parent)) {
$parent = ProductCategoryModel::language($lang_id)->tcoId($tco_parent['id'])->find();
@@ -109,10 +110,11 @@ class ReceiveProductSync
$category['path'] = $parent['path'] . $parent['pid'];
$category['level'] = $parent['level'] + 1;
}
if (!$category->save($category)) {
if (!$category->save()) {
throw new \Exception('产品分类更新失败');
}
}
}
Db::commit();
} catch (\Throwable $th) {

View File

@@ -228,7 +228,7 @@ class Article
private function getExportArticleData()
{
$server = request()->server();
$image_host = $server['REQUEST_SCHEME'] . "://" . $server['SERVER_NAME'] . config('filesystem.disks.public.url') . '/';
$image_host = $server['REQUEST_SCHEME'] . "://" . $server['SERVER_NAME'] . '/';
$param = request()->param(['title', 'category_id', 'release_time']);
$data = ArticleModel::field([
'*',
@@ -253,7 +253,7 @@ class Article
])
->bindAttr('category', ['category_name' => 'name'])
->each(function ($item) use($image_host) {
$item->image = !empty($item->image) ? $image_host . $item->image : '';
$item->image = !empty($item->image) ? url_join($image_host, $item->image) : '';
return $item;
});

View File

@@ -101,6 +101,8 @@ class BannerItem
'rel_prod_cate_id',
'title',
'title_txt_color',
'short_title',
'short_title_txt_color',
'desc',
'desc_txt_color',
'type',
@@ -156,6 +158,8 @@ class BannerItem
'rel_prod_cate_id',
'title',
'title_txt_color',
'short_title',
'short_title_txt_color',
'desc',
'desc_txt_color',
'type',
@@ -240,6 +244,7 @@ class BannerItem
'banner_name' => '分类名称',
'title' => '横幅名称',
'title_txt_color' => '横幅名称字体颜色',
'short_title' => '横幅简称',
'desc' => '描述',
'desc_txt_color' => '描述字体颜色',
'type' => '前台显示类型',
@@ -262,17 +267,16 @@ class BannerItem
// 获取导出数据
private function getBannerExportData()
{
$param = request()->param([
'title',
'banner_id',
'created_at'
]);
$server = request()->server();
$image_host = $server['REQUEST_SCHEME'] . "://" . $server['SERVER_NAME'] . '/';
$param = request()->param(['title', 'banner_id', 'created_at']);
return SysBannerItemModel::alias('item')
->field([
'item.id',
'banner.name' => 'banner_name',
'item.title',
'item.title_txt_color',
'item.short_title',
'item.desc',
'item.desc_txt_color',
'item.type',
@@ -311,7 +315,13 @@ class BannerItem
}
})
->order(['item.sort' => 'asc', 'item.id' => 'desc'])
->select();
->select()
->each(function($item) use($image_host) {
$item->image = !empty($item->image) ? url_join($image_host, $item->image) : '';
$item->extra_image = !empty($item->extra_image) ? url_join($image_host, $item->extra_image) : '';
$item->video = !empty($item->video) ? url_join($image_host, $item->video) : '';
return $item;
});
}
// 删除

View File

@@ -346,7 +346,7 @@ class Product
private function getExportProductData()
{
$server = request()->server();
$image_host = $server['REQUEST_SCHEME'] . "://" . $server['SERVER_NAME'] . config('filesystem.disks.public.url') . '/';
$image_host = $server['REQUEST_SCHEME'] . "://" . $server['SERVER_NAME'] . '/';
$param = request()->param([
'name',
'spu',
@@ -360,10 +360,10 @@ class Product
'spu',
'name',
'short_name',
'CONCAT("' . $image_host . '", `cover_image`)' => 'cover_image',
'cover_image',
'desc',
'CONCAT("' . $image_host . '", `video_img`)' => 'video_img',
'CONCAT("' . $image_host . '", `video_url`)' => 'video_url',
'video_img',
'video_url',
'CASE WHEN is_new = 1 THEN "是" ELSE "否" END' => 'is_new',
'CASE WHEN is_hot = 1 THEN "是" ELSE "否" END' => 'is_hot',
'CASE WHEN is_sale = 1 THEN "是" ELSE "否" END' => 'is_sale',
@@ -390,7 +390,18 @@ class Product
->order(['id' => 'asc'])
->select()
->bindAttr('category', ['category_name' => 'name'])
->hidden(['category_id', 'category']);
->hidden(['category_id', 'category'])
->each(function($item) use($image_host) {
if (!empty($item["cover_image"])) {
$item["cover_image"] = url_join($image_host, $item["cover_image"]);
}
if (!empty($item["video_img"])) {
$item["video_img"] = url_join($image_host, $item["video_img"]);
}
if (!empty($item["video_url"])) {
$item["video_url"] = url_join($image_host, $item["video_url"]);
}
});
if (!$products->isEmpty()) {
// 产品参数

View File

@@ -16,8 +16,9 @@ class ProductTcoCategory
$param = request()->param(['name']);
$categorys = ProductTcoCategoryModel::field([
'tco_id' => 'id',
'tco_pid' => 'pid',
'id',
'tco_id',
'tco_pid',
'name',
])
->withSearch(['name'], [
@@ -25,10 +26,10 @@ class ProductTcoCategory
])
->language(request()->lang_id)
->enabled()
->order(['id' => 'asc'])
->order(['tco_id' => 'asc'])
->select()
->toArray();
return success('获取成功', array_to_tree($categorys, 0, 'pid', false));
return success('获取成功', array_to_tree($categorys, 0, 'tco_pid', false, true, 'tco_id'));
}
}

View File

@@ -342,6 +342,18 @@ class System
'url' => (string)url('/index/topic/nas/download')
]
]
],
[
'id' => 8,
'name' => '电力品线专题',
'url' => '',
'children' => [
[
'id' => 81,
'name' => '首页',
'url' => (string)url('/index/topic/power_prodline/index')
],
]
]
];
}

View File

@@ -9,6 +9,7 @@ use app\admin\model\v1\SysAttachmentUploadRecordModel;
use Intervention\Image\ImageManager;
use Intervention\Image\Typography\FontFactory;
use think\facade\Filesystem;
use filesystem\Qiniu;
/**
* 文件上传控制器
@@ -153,8 +154,8 @@ class Upload
$image_model = new SysImageUploadRecordModel();
$image_model->language_id = request()->lang_id;
$image_model->module = $param['module'];
$image_model->image_path = $filename;
$image_model->image_thumb = $thumb_filename;
$image_model->image_path = $storage . '/' . $filename;
$image_model->image_thumb = $storage . '/' . $thumb_filename;
$image_model->file_size = $file_size;
$image_model->file_type = $mime_type;
$image_model->file_md5 = $filemd5;
@@ -165,8 +166,8 @@ class Upload
}
return success('操作成功', [
'path' => $storage . '/' . $image_model->image_path,
'thumb_path' => $storage . '/' . $image_model->image_thumb,
'path' => $image_model->image_path,
'thumb_path' => $image_model->image_thumb,
'filemd5' => $image_model->file_md5,
'filesha1' => $image_model->file_sha1
]);
@@ -226,6 +227,7 @@ class Upload
'filename_keep' => (int)data_get($options, 'filename_keep.value', 0) == 1,
'filemd5_unique' => (int)data_get($options, 'filemd5_unique.value', 0) == 1,
'filetype_to' => data_get($options, 'filetype_to.value', 'original'),
'save_to' => data_get($options, 'save_to.value', 'local'),
];
}
/**
@@ -345,20 +347,35 @@ class Upload
// 获取视频上传配置
list(
'filename_keep' => $filename_keep,
'filemd5_unique' => $filemd5_unique
'filemd5_unique' => $filemd5_unique,
'save_to' => $save_to,
) = $this->getUploadOptions('upload_video');
// 是否需要根据文件MD5值检查文件是否已存在
$video = $filemd5_unique ? SysVideoUploadRecordModel::md5($filemd5)->find() : null;
if (is_null($video)) {
// 保存位置配置 key
$disk = 'video';
// 检查是否需要保留原文件名
$name_rule = fn() => $filename_keep ? $this->filenameGenerator($file) : null;
$filename = Filesystem::disk('video')->putFile($param['module'], $file, $name_rule());
// 保存到七牛云
if ($save_to == 'qiniu_cloud') {
$disk = 'video_qiniu';
$storage = config('filesystem.disks.video_qiniu.path_prefix');
}
$filename = Filesystem::disk($disk)->putFile($param['module'], $file, $name_rule());
// 组装视频路径
$video_path = $storage . '/' . $filename;
if ($save_to == 'qiniu_cloud') {
$video_path = Filesystem::disk($disk)->url($filename);
}
// 保存视频
$video = new SysVideoUploadRecordModel();
$video->language_id = request()->lang_id;
$video->module = $param['module'];
$video->video_path = $filename;
$video->video_path = $video_path;
$video->file_size = $file->getSize();
$video->file_type = $file->getOriginalMime();
$video->file_md5 = $filemd5;
@@ -369,7 +386,7 @@ class Upload
}
return success('上传成功', [
'path' => $storage . '/' . $video->video_path,
'path' => $video->video_path,
'file_md5' => $video->file_md5,
'file_sha1' => $video->file_sha1
]);
@@ -399,25 +416,42 @@ class Upload
return error($validate->getError());
}
$storage = config('filesystem.disks.public.url');
$filemd5 = $file->md5();
$filesha1 = $file->sha1();
// 获取附件上传配置
list(
'filename_keep' => $filename_keep,
'filemd5_unique' => $filemd5_unique
'filemd5_unique' => $filemd5_unique,
'save_to' => $save_to
) = $this->getUploadOptions('upload_attachment');
// 是否需要根据文件MD5值检查文件是否已存在
$attachment = $filemd5_unique ? SysAttachmentUploadRecordModel::md5($filemd5)->find() : null;
if (is_null($attachment)) {
// 保存位置配置 key
$disk = 'public';
// 检查是否需要保留原文件名
$name_rule = fn() => $filename_keep ? $this->filenameGenerator($file) : null;
$filename = Filesystem::disk('public')->putFile('attachments', $file, $name_rule());
// 保存视频
// 保存到七牛云
if ($save_to == 'qiniu_cloud') {
$disk = 'public_qiniu';
$storage = config('filesystem.disks.public_qiniu.path_prefix');
}
$filename = Filesystem::disk($disk)->putFile('attachments', $file, $name_rule());
// 组装附件路径
$attachment_path = $storage . '/' . $filename;
if ($save_to == 'qiniu_cloud') {
$attachment_path = Filesystem::disk($disk)->url($filename);
}
// 保存附件
$attachment = new SysAttachmentUploadRecordModel();
$attachment->language_id = request()->lang_id;
$attachment->attachment_path = $filename;
$attachment->attachment_path = $attachment_path;
$attachment->file_size = $file->getSize();
$attachment->file_type = $file->getOriginalMime();
$attachment->file_md5 = $filemd5;
@@ -427,9 +461,8 @@ class Upload
}
}
$storage = config('filesystem.disks.public.url');
return success('上传成功', [
'path' => $storage . '/' . $attachment->attachment_path,
'path' => $attachment->attachment_path,
'file_md5' => $attachment->file_md5,
'file_sha1' => $attachment->file_sha1
]);

View File

@@ -209,9 +209,6 @@ class Video
]);
$domain = request()->domain();
$image_path = Config::get('filesystem.disks.image.url');
$video_path = Config::get('filesystem.disks.video.url');
return VideoModel::withoutField([
'language_id',
'updated_at',
@@ -230,13 +227,9 @@ class Video
->select()
->bindAttr('category', ['category_name' => 'name'])
->hidden(['category_id', 'category'])
->each(function ($item) use($domain, $image_path, $video_path) {
if (!empty($item->image)) {
$item->image = $domain . $image_path . '/' . $item->image;
}
if (!empty($item->video)) {
$item->video = $domain . $video_path . '/' . $item->video;
}
->each(function ($item) use($domain) {
$item->image = !empty($item->image) ? url_join($domain, $item->image) : '';
$item->video = !empty($item->video) ? url_join($domain, $item->video) : '';
$item->recommend = $item->recommend == 1 ? '是' : '否';
$item->status = $item->status == 1 ? '启用' : '禁用';
return $item;

View File

@@ -25,7 +25,7 @@ class SysBannerItemValidate extends Validate
'extra_image' => 'max:255',
'video' => 'max:255',
'link_to' => 'requireIf:type,image|max:64|in:article,article_category,product,product_category,system_page,custom',
'link' => 'max:255',
'link' => 'max:510',
'sort' => 'integer',
'status' => 'in:-1,1'
];
@@ -54,7 +54,7 @@ class SysBannerItemValidate extends Validate
'link_to.requireIf' => '链接类型不能为空',
'link_to.max' => '链接类型最多不能超过64个字符',
'link_to.in' => '链接类型必须是article,article_category,product,product_category,system_page,custom中之一',
'link.max' => '链接最多不能超过255个字符',
'link.max' => '链接最多不能超过512个字符',
'sort.integer' => '排序值必须是整数',
'status.in' => '状态必须是-1或1'
];

View File

@@ -17,7 +17,7 @@ class VideoValidate extends Validate
'id' => 'require|integer',
'language_id' => 'require|integer',
'category_id' => 'require|integer',
'name' => 'require|max:64',
'name' => 'require|max:128',
'desc' => 'max:512',
'image' => 'max:125',
'video' => 'max:125',
@@ -43,7 +43,7 @@ class VideoValidate extends Validate
'category_id.require' => '分类不能为空',
'category_id.integer' => '分类参数类型错误',
'name.require' => '名称不能为空',
'name.max' => '名称不能超过64个字符',
'name.max' => '名称不能超过128个字符',
'desc.max' => '描述不能超过512个字符',
'image.max' => '图片不能超过125个字符',
'video.max' => '视频不能超过125个字符',

View File

@@ -0,0 +1,42 @@
<?php
declare (strict_types = 1);
namespace app\command\OpenApiMgr;
use oauth\OAuthStorage;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
class AddClient extends Command
{
protected function configure()
{
// 指令配置
$this->setName('OpenApiMgr:AddClient')
->addArgument('salt', Argument::OPTIONAL, "开放API的client_secret密钥的盐值")
->setDescription('开放API的client管理');
}
protected function execute(Input $input, Output $output)
{
$salt = $input->getArgument('salt');
$salt = empty($salt) ? null : trim($salt);
// 指令输出
$oauth = new OAuthStorage($salt);
$client_id = random_str(13, 'all', 0);
$client_secret = random_str(32, 'all', 0);
$ok = $oauth->addClient($client_id, $client_secret, null);
if (!$ok) {
$output->writeln("添加失败");
return;
}
$output->writeln("添加成功:\nClientID: {$client_id}\nClientSecret: {$client_secret}\n");
}
}

View File

@@ -80,7 +80,7 @@ if (!function_exists('array_to_tree')) {
* @param bool $keep_pid 是否保留pid
* @return array
*/
function array_to_tree(array $data, int $pid, string $with = 'pid', int|bool $level = 1, bool $keep_pid = true)
function array_to_tree(array $data, int $pid, string $with = 'pid', int|bool $level = 1, bool $keep_pid = true, $with_ref = 'id')
{
$ret = [];
foreach ($data as $item) {
@@ -93,7 +93,7 @@ if (!function_exists('array_to_tree')) {
if ($keep_pid === false) {
unset($item[$with]);
}
$children = array_to_tree($data, $item['id'], $with, $lv, $keep_pid);
$children = array_to_tree($data, $item[$with_ref], $with, $lv, $keep_pid, $with_ref);
if ($children) {
$item['children'] = $children;
}
@@ -145,3 +145,90 @@ if (!function_exists('thumb')) {
return mb_substr($url, 0, $idx, 'utf-8') . '_thumb' . mb_substr($url, $idx, $len - $idx, 'utf-8');
}
}
if (!function_exists('get_filesystem_url')) {
/**
* 获取文件系统的访问 URL
* @param string $url 文件地址
* @param string $disk 磁盘配置 key
* @return string
*/
function get_filesystem_url(string|null $url, string $disk): string
{
if (is_null($url)) {
return '';
}
if (\think\helper\Str::startsWith($url, ['http://', 'https://', '//'])) {
return $url;
}
if (empty($disk)) {
return '';
}
return \think\facade\Filesystem::disk($disk)->url($url);
}
}
if (!function_exists('url_filesystem_detect')) {
/**
* 检测文件地址并根据情况转换为文件系统地址
* @param string $url 文件地址
* @return string
*/
function url_filesystem_detect(string|null $url): string
{
if (is_null($url)) {
return '';
}
$idx = strrpos($url, '.');
if ($idx === false) {
return $url;
}
$disks = [
'public_qiniu' => '_' . base64_encode('public_qiniu'),
'video_qiniu' => '_' . base64_encode('video_qiniu')
];
foreach ($disks as $disk => $marker) {
if (str_ends_with(mb_substr($url, 0, $idx), $marker)) {
return get_filesystem_url($url, $disk);
}
}
return $url;
}
}
if (!function_exists('url_join')) {
/**
* 合并URL
* @param string $url 基础URL
* @param string $path 路径
* @param bool $remove_slash 是否移除首尾的斜杠
* @return string
*/
function url_join(string $url, string $path, bool $remove_slash = true): string
{
if (empty($url)) {
return $path;
}
if (empty($path)) {
return $url;
}
if (\think\helper\Str::startsWith($path, ['http://', 'https://', '//'])) {
return $path;
}
if ($remove_slash) {
if (str_ends_with($url, '/') && str_starts_with($path, '/')) {
return $url . substr($path, 1);
}
if (!str_ends_with($url, '/') && !str_starts_with($path, '/')) {
return $url . '/' . $path;
}
}
return $url . $path;
}
}

View File

@@ -21,6 +21,8 @@ class SysBannerItemBaseModel extends BaseModel
'banner_id' => 'int',
'title' => 'string',
'title_txt_color' => 'string',
'short_title' => 'string',
'short_title_txt_color' => 'string',
'desc' => 'string',
'desc_txt_color' => 'string',
'type' => 'string',

View File

@@ -26,8 +26,6 @@ class Attachment extends Common
'size/d' => 12,
]);
// 获取附件分类
$categorys = AttachmentCategoryModel::field([
'id',
@@ -61,6 +59,16 @@ class Attachment extends Common
'id' => $param['id']??null
]
]);
if (!$attachements->isEmpty()) {
$attachements->each(function($item) {
if (is_array($item->attach)) {
$item->attach = array_map(function($v) {
$v['file_path'] = url_filesystem_detect($v['file_path']);
return $v;
}, $item->attach);
}
});
}
View::assign('attachements', $attachements);
View::assign('page', $attachements->render());
@@ -124,6 +132,9 @@ class Attachment extends Common
]);
if (!$videos->isEmpty()) {
$videos->each(function($item) {
$item->video = url_filesystem_detect($item->video);
});
$videos->setCollection($videos->getCollection()->chunk(2));
}
View::assign('videos', $videos);

View File

@@ -192,6 +192,8 @@ class TopicNas extends Common
{
// 获取文章分类及文章数据
$parent = ArticleCategoryModel::uniqueLabel('CATEGORY_681182e0a4529')->language($this->lang_id)->value('id');
$parent_two = ArticleCategoryModel::parent($parent)->language($this->lang_id)->column('id');//二级分类id
array_push($parent_two,$parent);
$article_categorys = ArticleCategoryModel::with(['article' => function($query) {
$query->field(['id', 'title', 'category_id'])
->order(['sort' => 'asc', 'id' => 'desc'])
@@ -199,15 +201,48 @@ class TopicNas extends Common
}])
->field([
'id',
'pid',
'name',
'icon'
])
->language($this->lang_id)
->parent($parent)
// ->parent($parent)
->parentChild($parent_two)
->isShow(true)
->order(['sort' => 'asc', 'id' => 'desc'])
->select();
View::assign('article_categorys', $article_categorys);
//查询三级分类
$article_categorys_new = [];
$article_categorys_two = [];
// dump($article_categorys->toArray());exit;
if (!$article_categorys->isEmpty()) {
foreach ($article_categorys->toArray() as $kk=>$vv) {
if ( $parent == $vv['pid'] ) {
array_push($article_categorys_new,$vv);
} else {
$article_categorys_two[$vv['pid']][] = $vv;
}
}
if ( !empty($article_categorys_two) ) {
foreach ($article_categorys_new as &$vvv) {
$articles = $vvv['article'];
if ( isset($article_categorys_two[$vvv['id']]) ) {
foreach ($article_categorys_two[$vvv['id']] as $v) {
foreach ($v['article'] as $av) {
if ( count($articles) < 3 ) {
array_push($articles,$av);
}
}
}
}
$vvv['article'] = $articles;
}
}
}
View::assign('article_categorys', $article_categorys_new);
// View::assign('article_categorys', $article_categorys);
$contacts = [];
// 获取banner数据
@@ -246,20 +281,46 @@ class TopicNas extends Common
// 获取文章分类及文章数据
$parent = ArticleCategoryModel::uniqueLabel('CATEGORY_681182e0a4529')->language($this->lang_id)->value('id');
$parent_two = ArticleCategoryModel::parent($parent)->language($this->lang_id)->column('id');//二级分类id
array_push($parent_two,$parent);
$article_categorys = ArticleCategoryModel::with(['article' => function ($query) {
$query->field(['id', 'title', 'category_id'])->order(['sort' => 'asc', 'id' => 'desc']);
}])
->field([
'id',
'pid',
'name',
'icon'
])
->language($this->lang_id)
->parent($parent)
// ->parent($parent)
->parentChild($parent_two)
->isShow(true)
->order(['sort' => 'asc', 'id' => 'desc'])
->select();
View::assign('article_categorys', $article_categorys);
// dump($article_categorys->toArray());exit;
//查询三级分类
$article_categorys_new = [];
$article_categorys_two = [];
if (!$article_categorys->isEmpty()) {
foreach ($article_categorys->toArray() as $kk=>$vv) {
if ( $parent == $vv['pid'] ) {
$vv['child'] = '';
array_push($article_categorys_new,$vv);
} else {
$article_categorys_two[$vv['pid']][] = $vv;
}
}
if ( !empty($article_categorys_two) ) {
foreach ($article_categorys_new as &$vvv) {
$vvv['child'] = isset($article_categorys_two[$vvv['id']])?$article_categorys_two[$vvv['id']]:'';
}
}
}
// dump($article_categorys_new);exit;
// dump($article_categorys_two);exit;
View::assign('article_categorys', $article_categorys_new);
return View::fetch('help_detail');
}
@@ -317,8 +378,18 @@ class TopicNas extends Common
->language($this->lang_id)
->where('category_id', 'IN', array_column($categorys, 'id'))
->select();
//查询上级id
$parent_two = ArticleCategoryModel::parentColumn(array_column($categorys, 'id'))->language($this->lang_id)->column('pid','id');//二级分类id
$articles_data = $articles->toArray();
foreach ($articles_data as &$v) {
$v['pid'] = 0;
if ( $parent_two[$v['category_id']] !== $parent ) {
$v['pid'] = $v['category_id'];
$v['category_id'] = $parent_two[$v['category_id']];
}
}
return success('success', $articles->toArray());
return success('success', $articles_data);
}
/**

View File

@@ -0,0 +1,127 @@
<?php
declare(strict_types=1);
namespace app\index\controller;
use app\index\model\SysBannerModel;
use think\facade\View;
use think\Request;
/**
* 专题 - 电力品线控制器
*/
class TopicPowerProdline extends Common
{
/**
* 重写控制器初始化
*/
public function initialize()
{
// 获取国家/语言列表
$languages = $this->getLanguages();
// 输出国家/语言列表
if (get_platform() == 'mobile') {
View::assign('header_languages', $languages);
}
// 获取当前语言
$current_language = $this->getCurrentLanguage($languages);
if (!empty($current_language)) {
$this->lang_id = $current_language['id'];
}
// 获取产品分类
$categorys = $this->getProductCategory($this->lang_id);
// 输出产品分类
View::assign('header_categorys', $categorys);
// 获取系统配置
$configs = $this->getSysConfig($this->lang_id, ['basic', 'contact', 'media']);
$this->basic_config = $configs['basic'];
// 输出系统配置
View::assign('basic_config', $configs['basic']);
View::assign('contact_config', $configs['contact']);
View::assign('media_config', $configs['media']);
// 获取底部导航
$footer_navigation = $this->getNavigation('NAV_67f60be43df8d', $this->lang_id);
// 输出底部导航
View::assign('footer_navigation', $footer_navigation);
}
/**
* 专题 - 电力品线首页
*/
public function index()
{
$banners = SysBannerModel::with([
'items' => function ($query) {
$query->withoutField(['sort', 'created_at', 'updated_at', 'deleted_at'])
->order(['sort' => 'asc', 'id' => 'desc'])
->enabled(true);
}
])
->atPlatform(request()->from)
->uniqueLabel([
'BANNER_691e729f2428d',
'BANNER_691e732e4ad69',
'BANNER_691e752d2bbe2',
'BANNER_691e75561c4d3',
'BANNER_691e75ec9391c',
'BANNER_691e7616545bf',
'BANNER_691e763fc08f4',
'BANNER_691e765a27eba',
'BANNER_691e76b6af393',
])
->language($this->lang_id)
->enabled(true)
->order(['sort' => 'asc', 'id' => 'desc'])
->select();
$data = [];
if (!$banners->isEmpty()) {
$banners_map = [];
foreach ($banners as $banner) {
$banners_map[$banner->unique_label] = $banner;
}
// 焦点轮播图
$focus_image = data_get($banners_map, 'BANNER_691e729f2428d')?->items->toArray();
if (!empty($focus_image)) $data['focus_image'] = $focus_image;
// 分类
$category = data_get($banners_map, 'BANNER_691e732e4ad69')?->items->toArray();
if (!empty($category)) $data['category'] = $category;
// 为什么选择奥睿科相关数据
$why_choose = data_get($banners_map, 'BANNER_691e752d2bbe2')?->items->toArray();
if (!empty($why_choose)) $data['why_choose'] = $why_choose;
// 差旅充
$travel_charger = data_get($banners_map, 'BANNER_691e75561c4d3')?->items->toArray();
if (!empty($travel_charger)) $data['travel_charger'] = $travel_charger;
// 家居充
$home_charger = data_get($banners_map, 'BANNER_691e75ec9391c')?->items->toArray();
if (!empty($home_charger)) $data['home_charger'] = $home_charger;
// 桌面充
$desktop_charger = data_get($banners_map, 'BANNER_691e7616545bf')?->items->toArray();
if (!empty($desktop_charger)) $data['desktop_charger'] = $desktop_charger;
// 墙充
$wall_charger = data_get($banners_map, 'BANNER_691e763fc08f4')?->items->toArray();
if (!empty($wall_charger)) $data['wall_charger'] = $wall_charger;
// 转换器
$converter = data_get($banners_map, 'BANNER_691e765a27eba')?->items->toArray();
if (!empty($converter)) $data['converter'] = $converter;
// 底部介绍
$footer_info = data_get($banners_map, 'BANNER_691e76b6af393')?->items->toArray();
if (!empty($footer_info)) $data['footer_info'] = $footer_info;
}
View::assign('data', $data);
return View::fetch('index');
}
}

View File

@@ -46,6 +46,27 @@ class ArticleCategoryModel extends ArticleCategoryBaseModel
$query->where('pid', '=', $parent);
}
// 所属上级分类范围查询
public function scopeParentChild($query, $parent)
{
if (is_array($parent)) {
$query->where('pid', 'IN', $parent);
return;
}
$query->where('pid', '=', $parent);
}
// 所属上级分类查询
public function scopeParentColumn($query, $parent)
{
if (is_array($parent)) {
$query->where('id', 'IN', $parent);
return;
}
$query->where('id', '=', $parent);
}
// 所属子分类范围查询
public function scopeChild($query, $id, $merge_self = false)
{

View File

@@ -105,6 +105,12 @@ Route::group('topic', function () {
// 专题-Nas软件下载页
Route::get('download', 'TopicNas/download');
});
// 专题 - 电力品线
Route::group("power_prodline", function() {
// 专题 - 电力品线首页
Route::get('index', 'TopicPowerProdline/index');
});
});
// 数据迁移

View File

@@ -14,7 +14,7 @@
<div class="tabs">
{notempty name="video_categorys"}
{volist name="video_categorys" id="va"}
<a href="{:url('attachment/index', ['id' => $va.id])}"><div class="tabit active">{$va.name}</div></a>
<a href="{:url('attachment/video', ['id' => $va.id])}"><div class="tabit active">{$va.name}</div></a>
{/volist}
{/notempty}
</div>

View File

@@ -22,7 +22,11 @@
<a class="href_01">{:lang_i18n('首页')}</a>
{volist name="product_categorys" id="ca"}
<span class="icon-arrow arrow_address"></span>
{eq name="ca.pid" value="0"}
<a class="href_02" href="{:url('product/category', ['id' => $ca.id])}">{$ca.name}</a>
{else /}
<a class="href_02" href="{:url('product/subcategory', ['id' => $ca.id])}">{$ca.name}</a>
{/eq}
{/volist}
</div>
</div>

View File

@@ -29,12 +29,13 @@
{/notempty}
<li>
<h3>{:lang_i18n('联系方式')}</h3>
{notempty name="contact_config.website_email"}
<p>{$contact_config.website_email.title} {$contact_config.website_email.value}</p>
{/notempty}
{notempty name="contact_config.website_hotline_office_hours"}
<p>{$contact_config.website_hotline_office_hours.title} {$contact_config.website_hotline_office_hours.value}</p>
{/notempty}
{if condition="!empty($contact_config)"}
{volist name="contact_config" id="vo"}
{if condition="$vo.type != 'image'"}
<p>{$vo.value}</p>
{/if}
{/volist}
{/if}
</li>
</ul>
</div>

View File

@@ -57,6 +57,8 @@
<div class="nars-hlpdt-ml">
{notempty name="article_categorys"}
<div class="nav-tree">
{volist name="article_categorys" id="ac" key="idx"}
<div class="categoryhelp">
<div class="categoryhelp-title">
@@ -67,6 +69,24 @@
<span>{$ac.name}</span>
</div>
<ul class="sub-list" {if condition='$ac.id == $Request.get.cid' }style="display: block;" {/if}>
{volist name="ac.child" id="ad"}
<li class="two-mues">
<a href="#" class="two-a">
<div><img src="__IMAGES__/nars-jt.png"
class="arrow {if condition='$ad.id == $Request.get.pid'}rotate{/if}">
</div>
<span>{$ad.name}</span>
</a>
<ul class="thress-mues" {if condition='$ad.id == $Request.get.pid' }style="display: block;" {/if}>
{volist name="ad.article" id="ae"}
<li>
<a href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id ,'pid' => $ad.id, 'id' => $ae.id])}"
style="margin-left:18%;padding: 0.4rem;">{$ae.title}</a>
</li>
{/volist}
</ul>
</li>
{/volist}
{volist name="ac.article" id="ar"}
<li>
<a href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id , 'id' => $ar.id])}"
@@ -78,6 +98,9 @@
</ul>
</div>
{/volist}
</div>
{/notempty}
</div>
@@ -128,6 +151,17 @@
$(this).next('.sub-list').slideToggle();
$(this).find('.arrow').toggleClass('rotate');
});
//分类二三级交互
$('.two-a').click(function(e) {
e.preventDefault();
e.stopPropagation(); // 阻止事件冒泡
// 切换当前二级菜单的箭头方向
$(this).find('.arrow').toggleClass('rotate');
// 切换对应的三级菜单显示/隐藏
$(this).siblings('.thress-mues').slideToggle();
});
// 点击顶部搜索图标-点击取消关闭
$('#ssico').click(function () {
$('.nhlpapp-pagescate').hide();

View File

@@ -0,0 +1,765 @@
{extend name="public/base" /}
{block name="style"}
<!-- 将rem适配JS移到这里确保优先执行 -->
<script type="text/javascript">
(function (doc, win) {
var docEl = doc.documentElement;
var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
function setRootFontSize() {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
var fontSize = clientWidth / 7.5; // 750px/7.5=100px375px/7.5=50px
// 直接修改内联样式,优先级最高
docEl.setAttribute('style', 'font-size: ' + fontSize + 'px !important;');
}
setRootFontSize();
win.addEventListener(resizeEvt, setRootFontSize);
doc.addEventListener('DOMContentLoaded', setRootFontSize);
})(document, window);
</script>
<link rel="stylesheet" href="__CSS__/topic_power_prodline/index.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/swiper.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/nav.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/advantage.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/moren.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/mask.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/product.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/product_list.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/product_card.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/footer.css">
{/block}
{block name="header"}
<!-- 重置header头为空 -->
{/block}
{block name="main"}
<a class="header" href="/">
<div class="header-img">
<img src="__IMAGES__/logo.png" alt="">
</div>
</a>
<!-- 轮播核心容器 -->
<div class="swiper-container auto-swiper-container" >
{notempty name="data.focus_image"}
<div class="swiper-wrapper">
{volist name="data.focus_image" id="fo"}
<a class="swiper-slide auto-swiper-slide" href="{$fo.link}">
<img src="{$fo.image}" alt="{$fo.title}" />
</a>
{/volist}
</div>
<div class="swiper-pagination"></div>
{/notempty}
</div>
<!-- 分类 -->
{notempty name="data.category"}
<div class="nav-box">
{volist name="data.category" id="ca"}
<a class="nav-item" href="{$ca.link}">
<img src="{$ca.image}" alt="{$ca.title}">
<p {:style(['color'=>$ca.title_txt_color])}>{$ca.title}</p>
</a>
{/volist}
</div>
{/notempty}
<!-- 500万 -->
{notempty name="data.why_choose"}
<div class="advantage-section">
{assign name="why_choose_title" value=":array_shift($data.why_choose)" /}
<h2 class="advantage-section__title">{$why_choose_title.title|default=''|raw}</h2>
<div class="advantage-section__list">
{volist name="data.why_choose" id="ch"}
<div class="advantage-card-wrap">
<div class="advantage-card" data-target="design">
<img src="{$ch.image}" alt="{$ch.title}:{$ch.short_title}" class="advantage-card__img">
<div class="advantage-card__content">
<!-- 标题+箭头容器:水平+垂直双居中,内部文字左、箭头右 -->
<div class="advantage-card__heading-wrap">
<div class="advantage-card__heading" {:style(['color'=>$ch.title_txt_color])}>{$ch.title}</div>
<img src="__IMAGES__/jiant.png" alt="" class="card-arrow">
</div>
<div class="advantage-card__description" {:style(['color'=>$ch.short_title_txt_color])}>{$ch.short_title}</div>
<div style="display:none;" class="mack-conten-text">{$ch.desc|raw}</div>
</div>
</div>
</div>
{/volist}
</div>
</div>
{/notempty}
<!-- 产品差旅充 -->
{notempty name="data.travel_charger"}
<div class="product-box">
{assign name="tc_title" value=":array_shift($data.travel_charger)" /}
<div class="product-title">
<h2 class="product-title-h2">{$tc_title.title|default=''}</h2>
<p class="product-title-p">{$tc_title.short_title|default=''}</p>
</div>
<div class="product-container" >
{assign name="tc_first_section_lf" value=":array_shift($data.travel_charger)" /}
{notempty name="tc_first_section_lf"}
<a class="product-left" href="{$tc_first_section_lf.link}">
<img src="{$tc_first_section_lf.image}" alt="{$tc_first_section_lf.title}" class="product-img">
<!-- 公共类+定位类:尺寸统一,定位不同 -->
<div class="product-img-hover top55">
<img src="{$tc_first_section_lf.extra_image}" alt="{$tc_first_section_lf.short_title}" class="img1">
</div>
</a>
{/notempty}
{assign name="tc_first_section_lr" value=":array_shift($data.travel_charger)" /}
{notempty name="tc_first_section_lr"}
<div class="product-right">
<img src="{$tc_first_section_lr.image}" alt="{$tc_first_section_lr.title}" class="right-content right-img">
<video src="{$tc_first_section_lr.video}" class="right-content right-video" muted loop playsinline>
您的浏览器不支持HTML5视频播放请升级浏览器
</video>
<button class="video-play-btn">
<span class="play-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<path d="M9 7L16 12L9 17V7Z" fill="white" />
</svg>
</span>
<!-- 暂停图标(默认隐藏) -->
<span class="pause-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<rect x="8" y="7" width="3" height="10" fill="white" />
<rect x="13" y="7" width="3" height="10" fill="white" />
</svg>
</span>
</button>
</div>
{/notempty}
</div>
{assign name="tc_second_section" value=":array_splice($data.travel_charger, 0, 4)" /}
{notempty name="tc_second_section"}
<div class="product-card-box">
<div class="product-card-container">
{volist name="tc_second_section" id="tss"}
<a class="product-card-wrap" href="{$tss.link}">
<div class="product-card" >
<div class="product-card-img">
<img src="{$tss.image}" alt="{$tss.title}">
</div>
<div class="product-card-text">
<div class="product-card-title" {:style(['color'=>$tss.title_txt_color])}>{$tss.title}</div>
<div class="product-card-desc" {:style(['color'=>$tss.short_title_txt_color])}>{$tss.short_title}</div>
</div>
<div class="product-card-link">
<img src="__IMAGES__/ljgd.png" alt="查看更多">
</div>
</div>
</a>
{/volist}
</div>
</div>
{assign name="tc_three_section" value=":array_shift($data.travel_charger)" /}
{notempty name="tc_three_section"}
<a href="{$tc_three_section.link}" class="more">
<div class="more-img">
{$tc_three_section.title}
</div>
</a>
{/notempty}
{/notempty}
</div>
{/notempty}
<!-- 产品 家居充-->
{notempty name="data.home_charger"}
<div class="product-box">
{assign name="hc_title" value=":array_shift($data.home_charger)" /}
<div class="product-title">
<h2 class="product-title-h2">{$hc_title.title|default=''}</h2>
<p class="product-title-p">{$hc_title.short_title|default=''}</p>
</div>
<div class="product-container">
{assign name="hc_first_section_lf" value=":array_shift($data.home_charger)" /}
{notempty name="hc_first_section_lf"}
<a class="product-left" href="{$hc_first_section_lf.link}">
<img src="{$hc_first_section_lf.image}" alt="{$hc_first_section_lf.title}" class="product-img">
<!-- 公共类+定位类:尺寸统一,定位不同 -->
<div class="product-img-hover">
<img src="{$hc_first_section_lf.extra_image}" alt="{$hc_first_section_lf.short_title}" class="img2">
</div>
</a>
{/notempty}
{assign name="hc_first_section_lr" value=":array_shift($data.home_charger)" /}
{notempty name="hc_first_section_lr"}
<div class="product-right">
<img src="{$hc_first_section_lr.image}" alt="{$hc_first_section_lr.title}" class="right-content right-img">
<video src="{$hc_first_section_lr.video}" class="right-content right-video" muted loop playsinline >
您的浏览器不支持HTML5视频播放请升级浏览器
</video>
<button class="video-play-btn">
<span class="play-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<path d="M9 7L16 12L9 17V7Z" fill="white" />
</svg>
</span>
<!-- 暂停图标(默认隐藏) -->
<span class="pause-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<rect x="8" y="7" width="3" height="10" fill="white" />
<rect x="13" y="7" width="3" height="10" fill="white" />
</svg>
</span>
</button>
</div>
{/notempty}
</div>
{assign name="hc_second_section" value=":array_splice($data.home_charger, 0, 4)" /}
{notempty name="hc_second_section"}
<div class="product-card-box">
<div class="product-card-container">
{volist name="hc_second_section" id="hcs"}
<a class="product-card-wrap" href="{$hcs.link}">
<div class="product-card" href="#">
<div class="product-card-img">
<img src="{$hcs.image}" alt="{$hcs.short_title}">
</div>
<div class="product-card-text">
<div class="product-card-title">{$hcs.title}</div>
<div class="product-card-desc">{$hcs.short_title}</div>
</div>
<div class="product-card-link">
<img src="__IMAGES__/ljgd.png" alt="查看更多">
</div>
</div>
</a>
{/volist}
</div>
</div>
{/notempty}
{assign name="hc_three_section" value=":array_shift($data.home_charger)" /}
{notempty name="hc_three_section"}
<a href="{$hc_three_section.link}" class="more">
<div class="more-img">
{$hc_three_section.title}
</div>
</a>
{/notempty}
</div>
{/notempty}
<!-- 产品 桌面充(悬浮图上右超出)底部列表样式不一样(左文右图) -->
<div class="product-box">
{assign name="dc_title" value=":array_shift($data.desktop_charger)" /}
<div class="product-title">
<h2 class="product-title-h2">{$dc_title.title|default=''}</h2>
<p class="product-title-p">{$dc_title.short_title|default=''}</p>
</div>
<div class="product-container">
{assign name="dc_first_section_lf" value=":array_shift($data.desktop_charger)" /}
{notempty name="dc_first_section_lf"}
<a class="product-left" href="{$dc_first_section_lf.link}">
<img src="{$dc_first_section_lf.image}" alt="{$dc_first_section_lf.short_title}" class="product-img">
<!-- 公共类+定位类:尺寸和第一个完全一致,仅定位不同 -->
<div class="product-img-hover right" >
<img src="{$dc_first_section_lf.extra_image}" alt="{$dc_first_section_lf.short_title}" class="img3">
</div>
</a>
{/notempty}
{assign name="dc_first_section_lr" value=":array_shift($data.desktop_charger)" /}
{notempty name="dc_first_section_lr"}
<div class="product-right">
<img src="{$dc_first_section_lr.image}"
alt="使用场景" class="right-content right-img">
<!--muted loop playsinline controls-->
<video
src="{$dc_first_section_lr.video}"
class="right-content right-video" muted loop playsinline >
您的浏览器不支持HTML5视频播放请升级浏览器
</video>
<button class="video-play-btn">
<span class="play-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<path d="M9 7L16 12L9 17V7Z" fill="white" />
</svg>
</span>
<!-- 暂停图标(默认隐藏) -->
<span class="pause-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<rect x="8" y="7" width="3" height="10" fill="white" />
<rect x="13" y="7" width="3" height="10" fill="white" />
</svg>
</span>
</button>
</div>
{/notempty}
</div>
{assign name="dc_second_section" value=":array_splice($data.desktop_charger, 0, 2)" /}
{notempty name="dc_second_section"}
<div class="product-card-box">
<div class="product-card-container">
{volist name="dc_second_section" id="dcs"}
<a class="product-card-wrap" href="{$dcs.link}">
<div class="product-card" href="#">
<div class="product-card-img">
<img src="{$dcs.image}" alt="{$dcs.short_title}">
</div>
<div class="product-card-text">
<div class="product-card-title">{$dcs.title}</div>
<div class="product-card-desc">{$dcs.short_title}</div>
</div>
<div class="product-card-link">
<img src="__IMAGES__/ljgd.png" alt="查看更多">
</div>
</div>
</a>
{/volist}
</div>
</div>
{/notempty}
{assign name="dc_three_section" value=":array_shift($data.desktop_charger)" /}
{notempty name="dc_three_section"}
<a href="{$dc_three_section.link}" class="more">
<div class="more-img">
{$dc_three_section.title}
</div>
</a>
{/notempty}
</div>
<!-- 墙插 -->
{notempty name="data.wall_charger"}
<div class="product-box">
{assign name="wc_title" value=":array_shift($data.wall_charger)" /}
<div class="product-title">
<h2 class="product-title-h2">{$wc_title.title|default=''}</h2>
<p class="product-title-p">{$wc_title.short_title|default=''}</p>
</div>
<div class="product-container">
{assign name="wc_first_section_lf" value=":array_shift($data.wall_charger)" /}
{notempty name="wc_first_section_lf"}
<a class="product-left" href="{$wc_first_section_lf.link}">
<img src="{$wc_first_section_lf.image}" alt="{$wc_first_section_lf.title}" class="product-img">
<!-- 公共类+定位类:尺寸统一,定位不同 -->
<div class="product-img-hover top70">
<img src="{$wc_first_section_lf.extra_image}" alt="{$wc_first_section_lf.title}" class="img4">
</div>
</a>
{/notempty}
{assign name="wc_first_section_lr" value=":array_shift($data.wall_charger)" /}
{notempty name="wc_first_section_lr"}
<div class="product-right">
<img src="{$wc_first_section_lr.image}" alt="{$wc_first_section_lr.title}" class="right-content right-img">
<video src="{$wc_first_section_lr.video}" class="right-content right-video" muted loop playsinline>
您的浏览器不支持HTML5视频播放请升级浏览器
</video>
<button class="video-play-btn">
<span class="play-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<path d="M9 7L16 12L9 17V7Z" fill="white" />
</svg>
</span>
<!-- 暂停图标(默认隐藏) -->
<span class="pause-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<rect x="8" y="7" width="3" height="10" fill="white" />
<rect x="13" y="7" width="3" height="10" fill="white" />
</svg>
</span>
</button>
</div>
{/notempty}
</div>
{assign name="wc_more_section" value=":array_shift($data.wall_charger)" /}
{notempty name="wc_more_section"}
<a href="{$wc_more_section.link}" class="more">
<div class="more-img">
{$wc_more_section.title}
</div>
</a>
{/notempty}
</div>
{/notempty}
{notempty name="data.converter"}
<!-- 转换器 -->
<div class="product-box">
{assign name="ct_title" value=":array_shift($data.converter)" /}
<div class="product-title">
<h2 class="product-title-h2">{$ct_title.title|default=''}</h2>
<p class="product-title-p">{$ct_title.short_title|default=''}</p>
</div>
{assign name="ct_more_section" value=":array_pop($data.converter)" /}
{assign name="ct_chunk_section" value=":array_chunk($data.converter, 2)" /}
{assign name="ct_chunk_section_len" value=":count($ct_chunk_section)" /}
{volist name="ct_chunk_section" id="cts" key="k"}
<div class="product-container">
{assign name="cts_lf" value=":array_shift($cts)" /}
{notempty name="cts_lf"}
<a class="product-left" href="{$cts_lf.link}">
<img src="{$cts_lf.image}" alt="{$cts_lf.title}" class="product-img">
<!-- 公共类+定位类:尺寸统一,定位不同 -->
<!--style="display:flex;justify-content: center;"-->
<div class="product-img-hover top40" >
<!-- style="width:70%"-->
<img src="{$cts_lf.extra_image}" alt="{$cts_lf.title}" class="img5">
</div>
</a>
{/notempty}
{assign name="cts_lr" value=":array_shift($cts)" /}
{notempty name="cts_lr"}
<div class="product-right">
<img src="{$cts_lr.image}" alt="{$cts_lr.title}" class="right-content right-img">
<video src="{$cts_lr.video}" class="right-content right-video" muted loop playsinline>
您的浏览器不支持HTML5视频播放请升级浏览器
</video>
<!-- 播放图标 -->
<button class="video-play-btn">
<span class="play-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<path d="M9 7L16 12L9 17V7Z" fill="white" />
</svg>
</span>
<!-- 暂停图标(默认隐藏) -->
<span class="pause-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<rect x="8" y="7" width="3" height="10" fill="white" />
<rect x="13" y="7" width="3" height="10" fill="white" />
</svg>
</span>
</button>
</div>
{/notempty}
</div>
{neq name="k" value="$ct_chunk_section_len"}
<div class="line"></div>
{/neq}
{/volist}
{notempty name="ct_more_section"}
<a href="{$ct_more_section.link}" class="more">
<div class="more-img">
{$ct_more_section.title}
</div>
</a>
{/notempty}
</div>
{/notempty}
{notempty name="data.footer_info"}
<!-- 底部 -->
<div class="prodline-footer-box">
<div class="prodline-footer-box-img">
<img src="{$data.footer_info.0.image}" alt="">
</div>
</div>
{/notempty}
<!-- 蒙版 -->
<div class="mask" id="mask">
<div class="mask-content" >
<span class="close-btn">&times;</span>
<div class="mask-scroll-content"></div>
</div>
</div>
{/block}
{block name="script"}
<script type="text/javascript">
let swiper=null;
const advantageItems = document.querySelectorAll('.advantage-card');
let scrollTop = 0; // 保存页面滚动位置
let closeBtnHtml = null; // 关闭按钮元素(全局变量,避免重复创建)
const mask = document.getElementById('mask');
const maskContent = document.querySelector('.mask-content');
const maskScrollContent = document.querySelector('.mask-scroll-content'); // 滚动容器(关键!)
const closeBtn = document.querySelector('.close-btn')
// 初始化:确保 maskScrollContent 存在于 maskContent 中(避免被清空)
if (!maskScrollContent) {
// 如果页面没有 mask-scroll-content动态创建确保结构稳定
const scrollContent = document.createElement('div');
scrollContent.className = 'mask-scroll-content';
maskContent.appendChild(scrollContent);
}
function createCloseBtn() {
if (closeBtnHtml) {
closeBtnHtml.remove();
}
closeBtnHtml = document.createElement('span');
closeBtnHtml.className = 'close-btn';
closeBtnHtml.innerHTML = '&times;';
closeBtnHtml.addEventListener('click', hideMask);
// 挂载到 maskContent而非 scrollContent避免被滚动影响位置
maskContent.prepend(closeBtnHtml);
}
function showMask(contentHtml) {
// 保存页面滚动位置
scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
// 关键:将内容填充到 scrollContent 中(而非直接替换 maskContent
maskScrollContent.innerHTML = contentHtml;
createCloseBtn();
// 显示蒙版
mask.style.display = 'flex';
// 禁止滚动(复用你的逻辑)
document.documentElement.classList.add('no-scroll');
document.body.classList.add('no-scroll');
document.body.style.top = `-${scrollTop}px`;
// 额外:打开蒙版时就重置滚动位置(避免残留上次滚动状态)
maskScrollContent.scrollTop = 0;
}
function hideMask() {
// 关键步骤 1先重置 scrollContent 的滚动位置(此时元素还未被销毁)
maskScrollContent.scrollTop = 0;
// 关键步骤 2清空 scrollContent 的内容(而非 maskContent
maskScrollContent.innerHTML = "";
// 隐藏蒙版
mask.style.display = 'none';
// 恢复滚动(复用你的逻辑)
document.documentElement.classList.remove('no-scroll');
document.body.classList.remove('no-scroll');
document.body.style.top = '';
// 还原页面滚动位置
window.scrollTo(0, scrollTop);
// 移除关闭按钮(可选,避免残留)
if (closeBtnHtml) {
closeBtnHtml.remove();
closeBtnHtml = null;
}
}
// 点击卡片显示详情
advantageItems.forEach((item) => {
item.addEventListener('click', (e) => {
// 获取当前点击卡片内的.mack-conten-text元素
const currentMackContent = e.currentTarget.querySelector('.mack-conten-text');
if (currentMackContent) {
// 关键修改获取该元素的子内容innerHTML 本身就是内部HTML不含当前元素标签
// 若想更彻底,可遍历子节点拼接内容(兼容特殊场景)
let contentHtml = '';
Array.from(currentMackContent.childNodes).forEach(child => {
// 只保留元素节点和文本节点(过滤空节点)
if (child.nodeType === 1 || child.nodeType === 3) {
contentHtml += child.outerHTML || child.textContent;
}
});
// 显示蒙版并传入纯净的子内容
showMask(contentHtml);
}
});
});
// 关闭按钮事件
closeBtn.addEventListener('click', hideMask);
// 点击蒙版背景关闭(可选)
mask.addEventListener('click', (e) => {
if (e.target === mask) hideMask();
});
// ESC 键关闭(可选)
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && mask.style.display === 'flex') hideMask();
});
// 关键:拦截蒙版的 touchmove 事件,阻止滚动穿透(移动端核心)
mask.addEventListener(
'touchmove',
(e) => {
// 只有点击蒙版背景(不是内容区域)才阻止滚动
if (e.target === mask) {
e.preventDefault(); // 阻止默认触摸滚动行为
e.stopPropagation(); // 阻止事件冒泡
}
},
{ passive: false }
); // passive: false 必须,否则 preventDefault 无效
document.addEventListener('DOMContentLoaded', () => {
// 初始化所有视频容器
function initVideoContainers() {
const productRights = document.querySelectorAll('.product-right');
// 支持的视频格式
const supportedVideoFormats = ['.mp4', '.webm', '.ogg', '.mov', '.avi', '.mkv', '.flv', '.wmv'];
productRights.forEach((container, index) => {
const video = container.querySelector('.right-video');
const btn = container.querySelector('.video-play-btn');
const img = container.querySelector('.right-img');
if (!video || !btn || !img) return;
const videoSrc = video.src.trim()
console.log(videoSrc,'=videoSrc=')
// 修复:正确检测有效视频地址
// 排除空字符串、null、undefined
const hasValidVideo = !!videoSrc && videoSrc.trim() !== '' && videoSrc !== 'undefined' && videoSrc !== 'null';
// 验证视频格式是否有效
const isValidFormat = supportedVideoFormats.some(format =>
videoSrc.toLowerCase().endsWith(format) ||
(videoSrc.includes('?') && videoSrc.toLowerCase().split('?')[0].endsWith(format))
);
// 初始化状态:无视频或格式无效则保持图片显示,永不切换
if (!hasValidVideo || !isValidFormat) {
img.style.display = 'block';
video.style.display = 'none';
btn.style.display = 'none';
// 绑定空方法,防止调用报错
video.switchMedia = function() {};
console.log(`容器${index}:无有效视频(src="${videoSrc}"),保持图片显示`);
return;
}
// 有有效视频的情况
console.log(`容器${index}:有有效视频(src="${videoSrc}"),初始化播放逻辑`);
// 初始状态
video.style.display = 'none';
video.pause();
img.style.display = 'block';
btn.style.display = 'none';
btn.style.opacity = '0';
// 同步状态函数
function syncMediaState() {
if (img.style.display === 'block') {
btn.style.display = 'none';
btn.style.opacity = '0';
} else {
btn.style.display = 'block';
btn.style.opacity = '1';
btn.classList.toggle('paused', !video.paused && !video.ended);
}
}
// 按钮点击事件
btn.addEventListener('click', () => {
if (video.paused) {
video.play().catch(() => syncMediaState());
} else {
video.pause();
}
syncMediaState();
});
// 视频事件监听
['play', 'pause', 'ended', 'playing', 'waiting'].forEach(event => {
video.addEventListener(event, syncMediaState);
});
// 滚动切换函数
video.switchMedia = function(showVideo) {
// 只处理有有效视频的情况
if (showVideo) {
img.style.display = 'none';
video.style.display = 'block';
video.play().catch(() => {
console.log(`容器${index}:自动播放失败,需要用户交互`);
syncMediaState();
});
} else {
video.pause();
img.style.display = 'block';
video.style.display = 'none';
}
syncMediaState();
};
// 初始同步
syncMediaState();
});
}
// 滚动监听 - 优化版
function setupScrollWatcher() {
let ticking = false;
function updateVideoVisibility() {
const productRights = document.querySelectorAll('.product-right');
productRights.forEach(container => {
const video = container.querySelector('.right-video');
if (!video || !video.switchMedia) return;
// 检查是否在视口中
const rect = container.getBoundingClientRect();
const viewHeight = window.innerHeight || document.documentElement.clientHeight;
const isInView = rect.top < viewHeight * 0.7 && rect.bottom > viewHeight * 0.3;
// 只对有有效视频的元素调用switchMedia
video.switchMedia(isInView);
});
ticking = false;
}
// 使用requestAnimationFrame优化性能
window.addEventListener('scroll', () => {
if (!ticking) {
requestAnimationFrame(updateVideoVisibility);
ticking = true;
}
});
}
// 初始化
initVideoContainers();
setupScrollWatcher();
// 初始检查一次
setTimeout(() => {
const event = new Event('scroll');
window.dispatchEvent(event);
}, 300);
});
window.onload = function () {
if (typeof Swiper === 'undefined') {
console.error('Swiper加载失败请刷新页面重试');
return;
}
swiper = new Swiper('.auto-swiper-container', {
autoplay: {
delay: 3000, // 3秒切换
disableOnInteraction: false,
},
loop: false,
slidesPerView: 1,
spaceBetween: 0,
// 启用分页指示标(核心配置)
pagination: {
el: '.swiper-pagination', // 对应 HTML 中的指示标容器
clickable: true, // 允许点击指示标切换
// dynamicBullets: true, // 动态指示标(当前激活放大)
//dynamicMainBullets: 3, // 动态模式显示3个核心指示标
},
navigation: false,
scrollbar: false,
on: {
resize: function () {
this.update();
},
},
});
window.addEventListener('resize', function () {
swiper.update();
});
// 初始化时触发滚动事件,确保状态正确
window.dispatchEvent(new Event('scroll'));
};
</script>
{/block}

View File

@@ -24,7 +24,9 @@
<p>{$detail.release_time|date_format_i18n}</p>
</div>
<!-- 文本渲染-->
<div class="blog_content">{$detail.content|raw}</div>
<div class="ql-container">
<div class="blog_content ql-editor">{$detail.content|raw}</div>
</div>
</div>
<!-- 评论只显示前面五条--->
{notempty name="comments"}

View File

@@ -117,8 +117,8 @@
<p class="subtitle" {notempty name="scene.desc_txt_color" }style="color:{$scene.desc_txt_color};" {/notempty}>
{$scene.desc|raw}</p>
<a class="sceneMore" href="{$scene.link}">{:lang_i18n('了解更多')} ></a> -->
</a>
<div style="background-image: url('{$scene.image}');" class="sceneimg"></div>
</a>
</div>
{/volist}
</div>

View File

@@ -22,7 +22,11 @@
<a class="pathname" href="/">{:lang_i18n('首页')}</a>
{volist name="product_categorys" id="ca"}
<div class="arrow"></div>
{eq name="ca.pid" value="0"}
<a class="pathname" href="{:url('product/category', ['id' => $ca.id])}">{$ca.name}</a>
{else /}
<a class="pathname" href="{:url('product/subcategory', ['id' => $ca.id])}">{$ca.name}</a>
{/eq}
{/volist}
</div>
<!-- 产品主图切换和参数详情-->
@@ -129,10 +133,12 @@
{/notempty}
</div>
<!-- 富文本渲染-->
<div class="products_des" id="detail">
<div class="ql-container">
<div class="products_des ql-editor" id="detail">
{$product.detail|default=''|raw}
</div>
</div>
</div>
<!-- 关联产品 -->
{notempty name="product_related"}
<div class="glcpmain" id="related">

View File

@@ -32,7 +32,7 @@
</div>
<div class="nhlp-tx-list">
{volist name="vo.article" id="va" key="index"}
<a class="txrow" href="{:url('/index/topic/nas/help_detail', ['cid' => $vo.id, 'id' => $va.id])}">
<a class="txrow" href="{:url('/index/topic/nas/help_detail', ['pid' => $va.category_id,'cid' => $vo.id, 'id' => $va.id])}">
<div class="nhlp-point"></div>
<span class="nhlpsp">{$va.title}</span>
<span class="narhelpgoimg">
@@ -41,7 +41,7 @@
</a>
{/volist}
{if condition="count($vo.article) >= 3"}
<a class="ckgdbt" href="{:url('/index/topic/nas/help_detail', ['cid' => $vo.id, 'id' => isset($vo.article[0])?$vo.article[0]['id']:0])}">
<a class="ckgdbt" href="{:url('/index/topic/nas/help_detail', ['cid' => $vo.id, 'id' => isset($vo.article[0])?$vo.article[0]['id']:0,'pid' => isset($vo.article[0])?$vo.article[0]['category_id']:0])}">
{:lang_i18n('查看更多')} >
</a>
{/if}

View File

@@ -32,28 +32,42 @@
<div class="nars-hlpdt-ml">
{notempty name="article_categorys"}
<div class="nav-tree">
<!-- start 三级菜单 -->
{volist name="article_categorys" id="ac"}
<div class="category">
<!-- 一级 -->
<div class="category-title">
<div class="arrow {if condition='$ac.id == $Request.get.cid'}rotate{/if}">
<img src="__IMAGES__/nas-jt.png" class="arrow {if condition='$ac.id == $Request.get.cid'}rotate{/if}" />
</div>
<div class="arrow {if condition='$ac.id == $Request.get.cid'}rotate{/if}"><img src="__IMAGES__/nas-jt.png" class="arrow {if condition='$ac.id == $Request.get.cid'}rotate{/if}" /></div>
<span>{$ac.name}</span>
</div>
<!-- 二级-->
<ul class="sub-list" {if condition='$ac.id == $Request.get.cid' }style="display: block;" {/if}>
{volist name="ac.article" id="ar"}
<li>
<a
href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id, 'id' => $ar.id])}"
{eq name="ar.id" value="$Request.get.id"}class="active"{/eq}
>
{$ar.title}
{volist name="ac.child" id="ad"}
<li class="two-mues">
<a href="#" class="two-a">
<div class="arrow {if condition='$ad.id == $Request.get.pid'}rotate{/if}"><img src="__IMAGES__/nas-jt.png" class="arrow {if condition='$ad.id == $Request.get.pid'}rotate{/if}" /></div>
<span>{$ad.name}</span>
</a>
<ul class="thress-mues" {if condition='$ad.id == $Request.get.pid' }style="display: block;" {/if}>
{volist name="ad.article" id="ae"}
<li style="margin-left: 30px;"><a href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id,'pid' => $ad.id, 'id' => $ae.id])}" style="padding-top: 6px;" {eq
name="ae.id" value="$Request.get.id" }class="active" {/eq}>{$ae.title}</a></li>
{/volist}
</ul>
<!-- 三级-->
</li>
{/volist}
{volist name="ac.article" id="ar"}
<li><a href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id, 'id' => $ar.id])}" style="padding-top: 6px;" {eq
name="ar.id" value="$Request.get.id" }class="active" {/eq}>{$ar.title}</a></li>
{/volist}
</ul>
</div>
{/volist}
<!-- end 三级菜单 -->
</div>
{/notempty}
</div>
@@ -75,10 +89,22 @@
{block name="script"}
<script type="text/javascript">
$(document).ready(function () {
// 一级菜单点击事件
$('.category-title').click(function () {
$(this).next('.sub-list').slideToggle();
$(this).find('.arrow').toggleClass('rotate');
});
// 二级菜单点击事件
$('.two-a').click(function(e) {
e.preventDefault();
e.stopPropagation(); // 阻止事件冒泡
// 切换当前二级菜单的箭头方向
$(this).find('.arrow').toggleClass('rotate');
// 切换对应的三级菜单显示/隐藏
$(this).siblings('.thress-mues').slideToggle();
});
// 搜索
$(document).on('click', function (e) {
var target = $(e.target);
@@ -109,7 +135,7 @@
html = '<ul>'
$.each(r.data, function (k, v) {
html +=
'<li><a href="{:url(\'/index/topic/nas/help_detail\')}?cid=' + v.category_id + '&id=' + v.id + '">' + v.title + '</a></li>'
'<li><a href="{:url(\'/index/topic/nas/help_detail\')}?cid=' + v.category_id + '&id=' + v.id + '&pid=' + v.pid + '">' + v.title + '</a></li>'
})
html += '</ul>'
}

View File

@@ -0,0 +1,581 @@
{extend name="public/nas_base" /}
{block name="style"}
<link rel="stylesheet" href="__CSS__/topic_power_prodline/index.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/swiper.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/nav.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/advantage.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/mask.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/product.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/product_list.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/product_card.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/footer.css">
{/block}
{block name="header"}
<!-- 重置header头为空 -->
{/block}
{block name="main"}
<a class="header" href="/">
<div class="header-img">
<img src="__IMAGES__/logo.png" alt="">
</div>
</a>
<!-- 轮播核心容器 -->
<div class="swiper-container auto-swiper-container" >
{notempty name="data.focus_image"}
<div class="swiper-wrapper">
{volist name="data.focus_image" id="fo"}
<a class="swiper-slide auto-swiper-slide" href="{$fo.link}">
<img src="{$fo.image}" alt="{$fo.title}" />
</a>
{/volist}
</div>
<div class="swiper-pagination"></div>
{/notempty}
</div>
<!-- 分类 -->
{notempty name="data.category"}
<div class="nav-box">
{volist name="data.category" id="ca"}
<a class="nav-item" href="{$ca.link}">
<img src="{$ca.image}" alt="{$ca.title}">
<p {:style(['color'=>$ca.title_txt_color])}>{$ca.title}</p>
</a>
{/volist}
</div>
{/notempty}
<!-- 500万 -->
{notempty name="data.why_choose"}
<div class="advantage-section">
{assign name="why_choose_title" value=":array_shift($data.why_choose)" /}
<h2 class="advantage-section__title">{$why_choose_title.title|default=''|raw}</h2>
<div class="advantage-section__list">
{volist name="data.why_choose" id="ch"}
<div class="advantage-card-wrap">
<div class="advantage-card" data-target="design">
<img src="{$ch.image}" alt="{$ch.title}:{$ch.short_title}" class="advantage-card__img">
<div class="advantage-card__content">
<!-- 标题+箭头容器:水平+垂直双居中,内部文字左、箭头右 -->
<div class="advantage-card__heading-wrap">
<div class="advantage-card__heading" {:style(['color'=>$ch.title_txt_color])}>{$ch.title}</div>
<img src="__IMAGES__/jiant.png" alt="" class="card-arrow">
</div>
<div class="advantage-card__description" {:style(['color'=>$ch.short_title_txt_color])}>{$ch.short_title}</div>
<div style="display:none;" class="mack-conten-text">{$ch.desc|raw}</div>
</div>
</div>
</div>
{/volist}
</div>
</div>
{/notempty}
<!-- 产品差旅充 -->
{notempty name="data.travel_charger"}
<div class="product-box">
{assign name="tc_title" value=":array_shift($data.travel_charger)" /}
<div class="product-title">
<h2 class="product-title-h2">{$tc_title.title|default=''}</h2>
<p class="product-title-p">{$tc_title.short_title|default=''}</p>
</div>
<div class="product-container" >
{assign name="tc_first_section_lf" value=":array_shift($data.travel_charger)" /}
{notempty name="tc_first_section_lf"}
<a class="product-left" href="{$tc_first_section_lf.link}">
<img src="{$tc_first_section_lf.image}" alt="{$tc_first_section_lf.title}" class="product-img">
<!-- 公共类+定位类:尺寸统一,定位不同 -->
<div class="product-img-hover product-img-1">
<img src="{$tc_first_section_lf.extra_image}" alt="{$tc_first_section_lf.short_title}">
</div>
</a>
{/notempty}
{assign name="tc_first_section_lr" value=":array_shift($data.travel_charger)" /}
{notempty name="tc_first_section_lr"}
<div class="product-right">
<img src="{$tc_first_section_lr.image}" alt="{$tc_first_section_lr.title}" class="right-content right-img">
<video src="{$tc_first_section_lr.video}" class="right-content right-video" muted loop playsinline controls>
您的浏览器不支持HTML5视频播放请升级浏览器
</video>
</div>
{/notempty}
</div>
{assign name="tc_second_section" value=":array_splice($data.travel_charger, 0, 4)" /}
{notempty name="tc_second_section"}
<div class="product-card-box">
<div class="product-card-container">
{volist name="tc_second_section" id="tss"}
<a class="product-card-wrap" href="{$tss.link}">
<div class="product-card" >
<div class="product-card-img">
<img src="{$tss.image}" alt="{$tss.title}">
</div>
<div class="product-card-text">
<div class="product-card-title" {:style(['color'=>$tss.title_txt_color])}>{$tss.title}</div>
<div class="product-card-desc" {:style(['color'=>$tss.short_title_txt_color])}>{$tss.short_title}</div>
</div>
<div class="product-card-link">
<img src="__IMAGES__/ljgd.png" alt="查看更多">
</div>
</div>
</a>
{/volist}
</div>
</div>
{assign name="tc_three_section" value=":array_shift($data.travel_charger)" /}
{notempty name="tc_three_section"}
<a href="{$tc_three_section.link}" class="more">
<div class="more-img">
{$tc_three_section.title}
</div>
</a>
{/notempty}
{/notempty}
</div>
{/notempty}
<!-- 产品 家居充-->
{notempty name="data.home_charger"}
<div class="product-box">
{assign name="hc_title" value=":array_shift($data.home_charger)" /}
<div class="product-title">
<h2 class="product-title-h2">{$hc_title.title|default=''}</h2>
<p class="product-title-p">{$hc_title.short_title|default=''}</p>
</div>
<div class="product-container">
{assign name="hc_first_section_lf" value=":array_shift($data.home_charger)" /}
{notempty name="hc_first_section_lf"}
<a class="product-left" href="{$hc_first_section_lf.link}">
<img src="{$hc_first_section_lf.image}" alt="{$hc_first_section_lf.title}" class="product-img">
<!-- 公共类+定位类:尺寸统一,定位不同 -->
<div class="product-img-hover product-img-1">
<img src="{$hc_first_section_lf.extra_image}" alt="{$hc_first_section_lf.short_title}">
</div>
</a>
{/notempty}
{assign name="hc_first_section_lr" value=":array_shift($data.home_charger)" /}
{notempty name="hc_first_section_lr"}
<div class="product-right">
<img src="{$hc_first_section_lr.image}" alt="{$hc_first_section_lr.title}" class="right-content right-img">
<video src="{$hc_first_section_lr.video}" class="right-content right-video" muted loop playsinline controls>
您的浏览器不支持HTML5视频播放请升级浏览器
</video>
</div>
{/notempty}
</div>
{assign name="hc_second_section" value=":array_splice($data.home_charger, 0, 4)" /}
{notempty name="hc_second_section"}
<div class="product-card-box">
<div class="product-card-container">
{volist name="hc_second_section" id="hcs"}
<a class="product-card-wrap" href="{$hcs.link}">
<div class="product-card" href="#">
<div class="product-card-img">
<img src="{$hcs.image}" alt="{$hcs.short_title}">
</div>
<div class="product-card-text">
<div class="product-card-title">{$hcs.title}</div>
<div class="product-card-desc">{$hcs.short_title}</div>
</div>
<div class="product-card-link">
<img src="__IMAGES__/ljgd.png" alt="查看更多">
</div>
</div>
</a>
{/volist}
</div>
</div>
{/notempty}
{assign name="hc_three_section" value=":array_shift($data.home_charger)" /}
{notempty name="hc_three_section"}
<a href="{$hc_three_section.link}" class="more">
<div class="more-img">
{$hc_three_section.title}
</div>
</a>
{/notempty}
</div>
{/notempty}
<!-- 产品 桌面充(悬浮图上右超出)底部列表样式不一样(左文右图) -->
<div class="product-box">
{assign name="dc_title" value=":array_shift($data.desktop_charger)" /}
<div class="product-title">
<h2 class="product-title-h2">{$dc_title.title|default=''}</h2>
<p class="product-title-p">{$dc_title.short_title|default=''}</p>
</div>
<div class="product-container">
{assign name="dc_first_section_lf" value=":array_shift($data.desktop_charger)" /}
{notempty name="dc_first_section_lf"}
<a class="product-left" href="{$dc_first_section_lf.link}">
<img src="{$dc_first_section_lf.image}" alt="{$dc_first_section_lf.short_title}" class="product-img">
<!-- 公共类+定位类:尺寸和第一个完全一致,仅定位不同 -->
<div class="product-img-hover product-img-2" >
<img src="{$dc_first_section_lf.extra_image}" alt="{$dc_first_section_lf.short_title}">
</div>
</a>
{/notempty}
{assign name="dc_first_section_lr" value=":array_shift($data.desktop_charger)" /}
{notempty name="dc_first_section_lr"}
<div class="product-right">
<img src="{$dc_first_section_lr.image}"
alt="使用场景" class="right-content right-img">
<!--muted loop playsinline controls-->
<video
src="{$dc_first_section_lr.video}"
class="right-content right-video" muted loop playsinline controls>
您的浏览器不支持HTML5视频播放请升级浏览器
</video>
</div>
{/notempty}
</div>
{assign name="dc_second_section" value=":array_splice($data.desktop_charger, 0, 2)" /}
{notempty name="dc_second_section"}
<div class="product-card-box">
<div class="product-card-container2">
{volist name="dc_second_section" id="dcs"}
<a class="product-card2" href="{$dcs.link}">
<div class="product-text2">
<!-- 新增内部容器,确保所有内容左对齐一致性 -->
<div class="product-text-content2">
<div class="product-card-title2">{$dcs.title}</div> <!-- 测试超出一行省略 -->
<div class="product-card-desc2">{$dcs.short_title}</div> <!-- 测试超出2行省略 -->
<div class="product-card-link2">
<img src="__IMAGES__/ljgd.png" alt="了解更多">
</div>
</div>
</div>
<div class="product-card-img2">
<img src="{$dcs.image}" alt="{$dcs.title}">
</div>
</a>
{/volist}
</div>
</div>
{/notempty}
{assign name="dc_three_section" value=":array_shift($data.desktop_charger)" /}
{notempty name="dc_three_section"}
<a href="{$dc_three_section.link}" class="more">
<div class="more-img">
{$dc_three_section.title}
</div>
</a>
{/notempty}
</div>
<!-- 墙插 -->
{notempty name="data.wall_charger"}
<div class="product-box">
{assign name="wc_title" value=":array_shift($data.wall_charger)" /}
<div class="product-title">
<h2 class="product-title-h2">{$wc_title.title|default=''}</h2>
<p class="product-title-p">{$wc_title.short_title|default=''}</p>
</div>
<div class="product-container">
{assign name="wc_first_section_lf" value=":array_shift($data.wall_charger)" /}
{notempty name="wc_first_section_lf"}
<a class="product-left" href="{$wc_first_section_lf.link}">
<img src="{$wc_first_section_lf.image}" alt="{$wc_first_section_lf.title}" class="product-img">
<!-- 公共类+定位类:尺寸统一,定位不同 -->
<div class="product-img-hover product-img-1">
<img src="{$wc_first_section_lf.extra_image}" alt="{$wc_first_section_lf.title}">
</div>
</a>
{/notempty}
{assign name="wc_first_section_lr" value=":array_shift($data.wall_charger)" /}
{notempty name="wc_first_section_lr"}
<div class="product-right">
<img src="{$wc_first_section_lr.image}" alt="{$wc_first_section_lr.title}" class="right-content right-img">
<video src="{$wc_first_section_lr.video}" class="right-content right-video" muted loop playsinline controls>
您的浏览器不支持HTML5视频播放请升级浏览器
</video>
</div>
{/notempty}
</div>
{assign name="wc_more_section" value=":array_shift($data.wall_charger)" /}
{notempty name="wc_more_section"}
<a href="{$wc_more_section.link}" class="more">
<div class="more-img">
{$wc_more_section.title}
</div>
</a>
{/notempty}
</div>
{/notempty}
{notempty name="data.converter"}
<!-- 转换器 -->
<div class="product-box">
{assign name="ct_title" value=":array_shift($data.converter)" /}
<div class="product-title">
<h2 class="product-title-h2">{$ct_title.title|default=''}</h2>
<p class="product-title-p">{$ct_title.short_title|default=''}</p>
</div>
{assign name="ct_more_section" value=":array_pop($data.converter)" /}
{assign name="ct_chunk_section" value=":array_chunk($data.converter, 2)" /}
{assign name="ct_chunk_section_len" value=":count($ct_chunk_section)" /}
{volist name="ct_chunk_section" id="cts" key="k"}
<div class="product-container">
{assign name="cts_lf" value=":array_shift($cts)" /}
{notempty name="cts_lf"}
<a class="product-left" href="{$cts_lf.link}">
<img src="{$cts_lf.image}" alt="{$cts_lf.title}" class="product-img">
<!-- 公共类+定位类:尺寸统一,定位不同 -->
<!--style="display:flex;justify-content: center;"-->
<div class="product-img-hover product-img-1" >
<!-- style="width:70%"-->
<img src="{$cts_lf.extra_image}" alt="{$cts_lf.title}">
</div>
</a>
{/notempty}
{assign name="cts_lr" value=":array_shift($cts)" /}
{notempty name="cts_lr"}
<div class="product-right">
<img src="{$cts_lr.image}" alt="{$cts_lr.title}" class="right-content right-img">
<video src="{$cts_lr.video}" class="right-content right-video" muted loop playsinline controls>
您的浏览器不支持HTML5视频播放请升级浏览器
</video>
</div>
{/notempty}
</div>
{neq name="k" value="$ct_chunk_section_len"}
<div class="line"></div>
{/neq}
{/volist}
{notempty name="ct_more_section"}
<a href="{$ct_more_section.link}" class="more" style="padding: clamp(1.5rem, 3vw, 3rem) 0">
<div class="more-img">
{$ct_more_section.title}
</div>
</a>
{/notempty}
</div>
{/notempty}
{notempty name="data.footer_info"}
<!-- 底部 -->
<div class="prodline-footer-box">
<div class="prodline-footer-box-img">
<img src="{$data.footer_info.0.image}" alt="">
</div>
</div>
{/notempty}
<!-- 蒙版 -->
<div class="mask" id="mask">
<div class="mask-content" >
<span class="close-btn">&times;</span>
<div class="mask-scroll-content"></div>
</div>
</div>
{/block}
{block name="script"}
<script type="text/javascript">
let swiper=null;
const advantageItems = document.querySelectorAll('.advantage-card');
let scrollTop = 0; // 保存页面滚动位置
let closeBtnHtml = null; // 关闭按钮元素(全局变量,避免重复创建)
const mask = document.getElementById('mask');
const maskContent = document.querySelector('.mask-content');
const maskScrollContent = document.querySelector('.mask-scroll-content'); // 滚动容器(关键!)
const closeBtn = document.querySelector('.close-btn')
// 初始化:确保 maskScrollContent 存在于 maskContent 中(避免被清空)
if (!maskScrollContent) {
// 如果页面没有 mask-scroll-content动态创建确保结构稳定
const scrollContent = document.createElement('div');
scrollContent.className = 'mask-scroll-content';
maskContent.appendChild(scrollContent);
}
function createCloseBtn() {
if (closeBtnHtml) {
closeBtnHtml.remove();
}
closeBtnHtml = document.createElement('span');
closeBtnHtml.className = 'close-btn';
closeBtnHtml.innerHTML = '&times;';
closeBtnHtml.addEventListener('click', hideMask);
// 挂载到 maskContent而非 scrollContent避免被滚动影响位置
maskContent.prepend(closeBtnHtml);
}
function showMask(contentHtml) {
// 保存页面滚动位置
scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
// 关键:将内容填充到 scrollContent 中(而非直接替换 maskContent
maskScrollContent.innerHTML = contentHtml;
createCloseBtn();
// 显示蒙版
mask.style.display = 'flex';
// 禁止滚动(复用你的逻辑)
document.documentElement.classList.add('no-scroll');
document.body.classList.add('no-scroll');
document.body.style.top = `-${scrollTop}px`;
// 额外:打开蒙版时就重置滚动位置(避免残留上次滚动状态)
maskScrollContent.scrollTop = 0;
}
function hideMask() {
// 关键步骤 1先重置 scrollContent 的滚动位置(此时元素还未被销毁)
maskScrollContent.scrollTop = 0;
// 关键步骤 2清空 scrollContent 的内容(而非 maskContent
maskScrollContent.innerHTML = "";
// 隐藏蒙版
mask.style.display = 'none';
// 恢复滚动(复用你的逻辑)
document.documentElement.classList.remove('no-scroll');
document.body.classList.remove('no-scroll');
document.body.style.top = '';
// 还原页面滚动位置
window.scrollTo(0, scrollTop);
// 移除关闭按钮(可选,避免残留)
if (closeBtnHtml) {
closeBtnHtml.remove();
closeBtnHtml = null;
}
}
// 点击卡片显示详情
advantageItems.forEach((item) => {
item.addEventListener('click', (e) => {
// 获取当前点击卡片内的.mack-conten-text元素
const currentMackContent = e.currentTarget.querySelector('.mack-conten-text');
if (currentMackContent) {
// 关键修改获取该元素的子内容innerHTML 本身就是内部HTML不含当前元素标签
// 若想更彻底,可遍历子节点拼接内容(兼容特殊场景)
let contentHtml = '';
Array.from(currentMackContent.childNodes).forEach(child => {
// 只保留元素节点和文本节点(过滤空节点)
if (child.nodeType === 1 || child.nodeType === 3) {
contentHtml += child.outerHTML || child.textContent;
}
});
// 显示蒙版并传入纯净的子内容
showMask(contentHtml);
}
});
});
// 关闭按钮事件
closeBtn.addEventListener('click', hideMask);
// 点击蒙版背景关闭(可选)
mask.addEventListener('click', (e) => {
if (e.target === mask) hideMask();
});
// ESC 键关闭(可选)
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && mask.style.display === 'flex') hideMask();
});
// 关键:拦截蒙版的 touchmove 事件,阻止滚动穿透(移动端核心)
mask.addEventListener(
'touchmove',
(e) => {
// 只有点击蒙版背景(不是内容区域)才阻止滚动
if (e.target === mask) {
e.preventDefault(); // 阻止默认触摸滚动行为
e.stopPropagation(); // 阻止事件冒泡
}
},
{ passive: false }
); // passive: false 必须,否则 preventDefault 无效
const allVideos = document.querySelectorAll('.right-video');
// 停止所有视频播放
function stopAllVideos() {
allVideos.forEach((video) => {
video.pause();
video.style.display = 'none';
// 显示对应图片
const img = video.parentElement.querySelector('.right-img');
if (img) img.style.display = 'block';
});
}
// 滚动切换图片/视频(核心逻辑)
window.addEventListener('scroll', function () {
const productRights = document.querySelectorAll('.product-right');
let activeVideo = null;
// 找出当前在视口中的视频容器
productRights.forEach((rightContainer) => {
const img = rightContainer.querySelector('.right-img');
const video = rightContainer.querySelector('.right-video');
const videoSrc = video.src.trim()
if (!img || !video) return;
if(!videoSrc) return;
const rect = rightContainer.getBoundingClientRect();
// 视口判断容器进入视口50%以上视为活跃
const isInView =
rect.top < window.innerHeight * 0.7 &&
rect.bottom > window.innerHeight * 0.3;
if (isInView) {
activeVideo = video;
}
});
// 处理活跃视频
if (activeVideo) {
stopAllVideos(); // 先停止其他视频
const img = activeVideo.parentElement.querySelector('.right-img');
img.style.display = 'none';
activeVideo.style.display = 'block';
// 自动播放(兼容原生控制栏,用户手动暂停后不会强制播放)
if (activeVideo.paused) {
activeVideo.play().catch((err) => {
console.log('视频播放失败(浏览器限制):', err);
// 播放失败时回退到图片
activeVideo.style.display = 'none';
img.style.display = 'block';
});
}
} else {
stopAllVideos(); // 无活跃视频时停止所有播放
}
});
window.onload = function () {
if (typeof Swiper === 'undefined') {
console.error('Swiper加载失败请刷新页面重试');
return;
}
swiper = new Swiper('.auto-swiper-container', {
autoplay: {
delay: 3000, // 3秒切换
disableOnInteraction: false,
},
loop: false,
slidesPerView: 1,
spaceBetween: 0,
// 启用分页指示标(核心配置)
pagination: {
el: '.swiper-pagination', // 对应 HTML 中的指示标容器
clickable: true, // 允许点击指示标切换
// dynamicBullets: true, // 动态指示标(当前激活放大)
//dynamicMainBullets: 3, // 动态模式显示3个核心指示标
},
navigation: false,
scrollbar: false,
on: {
resize: function () {
this.update();
},
},
});
window.addEventListener('resize', function () {
swiper.update();
});
// 初始化时触发滚动事件,确保状态正确
window.dispatchEvent(new Event('scroll'));
};
</script>
{/block}

View File

@@ -18,7 +18,7 @@ if (!function_exists('image_domain_concat')) {
return $path;
}
return rtrim($domain, '/') . '/' . ltrim($path, '/');
return url_join($domain, $path);
}
}
@@ -39,7 +39,7 @@ if (!function_exists('video_domain_concat')) {
return $path;
}
return rtrim($domain, '/') . '/' . ltrim($path, '/');
return url_join($domain, $path);
}
}

View File

@@ -21,9 +21,9 @@
],
"require": {
"php": ">=8.0.0",
"topthink/framework": "^8.0",
"topthink/framework": "8.1.2",
"topthink/think-orm": "v3.0.34",
"topthink/think-filesystem": "^2.0",
"topthink/think-filesystem": "^3.0",
"topthink/think-multi-app": "^1.1",
"topthink/think-migration": "^3.1",
"topthink/think-view": "^2.0",

View File

@@ -2,9 +2,12 @@
// +----------------------------------------------------------------------
// | 控制台配置
// +----------------------------------------------------------------------
return [
// 指令定义
'commands' => [
'data:migrate' => \app\command\DataMigration::class,
'openapi:addclient' => \app\command\OpenApiMgr\AddClient::class,
],
];

View File

@@ -39,6 +39,60 @@ return [
// 可见性
'visibility' => 'public',
],
'public_qiniu' => [
// 磁盘类型
'type' => \filesystem\driver\Qiniu::class,
// bucker 名称
'bucket' => env('QINIU_CLOUD.BUCKET', 'orico-official-website'),
// 访问密钥
'access_key' => env('QINIU_CLOUD.ACCESS_KEY', 'dOsTum4a5qvhPTBbZRPX0pIOU7PZWRX7htKjztms'),
// 密钥
'secret_key' => env('QINIU_CLOUD.SECRET_KEY', 'KFxsGbnErkALFfeGdMa8QWTdodJbamMX0iznLe-q'),
// 外部URL
'base_url' => env('QINIU_CLOUD.BASE_URL', '//szw73dlk3.hn-bkt.clouddn.com'),
// 路径
'path_prefix' => '/storage',
// 文件名称回调,可为文件名添加特定标志,以便可以在后续识别
'filename_generator' => function (\think\file\UploadedFile $file, callable $context_generator = null): callable {
return function() use ($file, $context_generator) {
// 为文件名称添加配置名,以为后续可能根据文件名识别文件所属存储配置信息
$marker = '_' . base64_encode('public_qiniu');
$filename = $context_generator ? $context_generator($file) : null;
if ($filename == null) {
return date('Ymd') . '/' . md5(microtime(true) . $file->getPathname()) . $marker;
}
return $filename . $marker;
};
},
],
'video_qiniu' => [
// 磁盘类型
'type' => \filesystem\driver\Qiniu::class,
// bucker 名称
'bucket' => env('QINIU_CLOUD.BUCKET', 'orico-official-website'),
// 访问密钥
'access_key' => env('QINIU_CLOUD.ACCESS_KEY', 'dOsTum4a5qvhPTBbZRPX0pIOU7PZWRX7htKjztms'),
// 密钥
'secret_key' => env('QINIU_CLOUD.SECRET_KEY', 'KFxsGbnErkALFfeGdMa8QWTdodJbamMX0iznLe-q'),
// 外部URL
'base_url' => env('QINIU_CLOUD.BASE_URL', '//szw73dlk3.hn-bkt.clouddn.com'),
// 路径
'path_prefix' => '/storage/videos',
// 文件名称回调,可为文件名添加特定标志,以便可以在后续识别
'filename_generator' => function (\think\file\UploadedFile $file, callable $context_generator = null): callable {
return function() use ($file, $context_generator) {
// 为文件名称添加配置名,以为后续可能根据文件名识别文件所属存储配置信息
$marker = '_' . base64_encode('video_qiniu');
$filename = $context_generator ? $context_generator() : null;
if ($filename == null) {
return date('Ymd') . '/' . md5(microtime(true) . $file->getPathname()) . $marker;
}
return $filename . $marker;
};
},
]
// 更多的磁盘配置信息
],
];

View File

@@ -31,7 +31,7 @@ class CreateVideo extends Migrator
$table = $this->table('video', ['engine' => 'MyISAM', 'comment' => '视频表']);
$table->addColumn('language_id', 'integer', ['signed' => false , 'null' => false, 'comment' => '语言ID'])
->addColumn('category_id', 'integer', ['signed' => false , 'null' => false, 'comment' => '分类ID'])
->addColumn('name', 'string', ['limit' => 64 , 'null' => false, 'comment' => '名称'])
->addColumn('name', 'string', ['limit' => 128 , 'null' => false, 'comment' => '名称'])
->addColumn('desc', 'string', ['limit' => 512, 'null' => true, 'default' => null, 'comment' => '描述信息'])
->addColumn('image', 'string', ['limit' => 125, 'null' => true, 'default' => null, 'comment' => '封面图片'])
->addColumn('video', 'string', ['limit' => 125, 'null' => true, 'default' => null, 'comment' => '视频地址'])

View File

@@ -32,6 +32,8 @@ class CreateSysBannerItem extends Migrator
$table->addColumn('banner_id', 'integer', ['null' => false, 'comment' => '所属Banner ID'])
->addColumn('title', 'string', ['limit' => 256, 'null' => false, 'comment' => '标题'])
->addColumn('title_txt_color', 'string', ['limit' => 7, 'null' => false, 'default' => '', 'comment' => '标题文本颜色'])
->addColumn('short_title', 'string', ['limit' => 255, 'null' => true, 'comment' => 'banner简称'])
->addColumn('short_title_txt_color', 'string', ['limit' => 7, 'null' => true, 'comment' => 'banner简称文本颜色'])
->addColumn('desc', MysqlAdapter::PHINX_TYPE_TEXT, ['null' => true, 'default' => null, 'comment' => '描述'])
->addColumn('desc_txt_color', 'string', ['limit' => 7, 'null' => false, 'default' => '', 'comment' => '描述文本颜色'])
->addColumn('type', 'string', ['limit' => 16, 'null' => false, 'comment' => '类型: image为图片, video为视频'])
@@ -39,7 +41,7 @@ class CreateSysBannerItem extends Migrator
->addColumn('extra_image', 'string', ['limit' => 255, 'null' => true, 'default' => null, 'comment' => '额外的图片'])
->addColumn('video', 'string', ['limit' => 255, 'null' => true, 'default' => null, 'comment' => '视频'])
->addColumn('link_to', 'string', ['limit' => 64, 'null' => true, 'default' => null, 'comment' => '链接到(类型): article:文章, article_category:文章分类, product:产品, product_category:产品分类, custom:自定义链接'])
->addColumn('link', 'string', ['limit' => 255, 'null' => true, 'default' => null, 'comment' => '链接'])
->addColumn('link', 'string', ['limit' => 510, 'null' => true, 'default' => null, 'comment' => '链接'])
->addColumn('sort', 'integer', ['limit' => 11, 'null' => false, 'default' => 0, 'comment' => '排序'])
->addColumn('status', 'boolean', ['limit' => 1, 'null' => false, 'default' => 1, 'comment' => '-1为禁用, 1为启用'])
->addColumn('created_at', 'timestamp', ['null' => false, 'default' =>'CURRENT_TIMESTAMP', 'comment' => '创建时间'])

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\nMontserrat\nMorocco\nMozambique\nMyanmar\nNamibia\nNauru\nNepal\nNetherlands Antilles\nNetherlands\nNew Caledonia\nNew Zealand\nNicaragua\nNiger\nNiue\nNorthern Mariana\nNorway\nOman\nPakistan\nPalau\nPalestine\nPanama\nPapua New Guinea\nParaguay\nPeru\nPhilippines\nPitcairn Islands\nPoland\nPortugal\nPuerto Rico\nQatar\nReunion\nRomania\nRussian Federation\nRwanda\nSaint Helena\nSaint Kitts-Nevis\nSaint Lucia\nSaint Vincent and the Grenadines\nSamoa\nSan Marino\nSao Tome and Principe\nSaudi Arabia\nSenegal\nSerbia\nSeychelles\nSierra Leone\nSingapore\nSlovakia\nSlovenia\nSolomon Islands\nSomalia\nSouth Africa\nSpain\nSri Lanka\nSudan\nSuriname\nSwaziland\nSweden\nSwitzerland\nSyria\nTajikistan\nTanzania\nThailand\nThe British Virgin Islands\nThe United States Virgin Islands\nTimor-Leste\nTogo\nTokelau\nTonga\nTrinidad and Tobago\nTunisia\nTurkey\nTurkmenistan\nTurks and Caicos Islands\nTuvalu\nUganda\nUkraine\nUnited Arab Emirates\nUnited Kingdom\nUnited States\nUruguay\nUzbekistan\nVanuatu\nVatican City\nVenezuela\nVietnam\nWallis and Futuna\nWestern Sahara\nYemen\nZambia\nZimbabwe", "extra" => "", "type" => "textarea", "sort" => 7, "remark" => "", "created_at" => "2025-04-27 11:10:22", "updated_at" => "2025-06-11 17:09:13", "deleted_at" => null],
["id" => 60, "group_id" => 4, "title" => "产品询盘可选国家", "name" => "optional_country_for_product_inquiry", "value" => "Afghanistan\nAlbania\nAlgeria\nAmerican Samoa\nAndorra\nAngola\nAnguilla\nAntigua and Barbuda\nArgentina\nArmenia\nAruba\nAustralia\nAustria\nAzerbaijan\nAzores\nBahamas\nBahrain\nBangladesh\nBarbados\nBelarus\nBelgium\nBelize\nBenin\nBermuda\nBhutan\nBolivia\nBosnia and Herzegovina\nBotswana\nBrazil\nBrunei\nBulgaria\nBurkina Faso\nBurundi\nCambodia\nCameroon\nCanada\nCanarias\nCape Verde\nCayman\nCentral African Republic\nChad\nChile\nChina\nColombia\nComoros\nCongo (Congo-Kinshasa)\nCongo\nCook Islands\nCosta Rica\nCote D'Ivoire\nCroatia\nCuba\nCyprus\nCzech\nDenmark\nDjibouti\nDominica\nDominican\nEcuador\nEgypt\nEl Salvador\nEquatorial Guinea\nEritrea\nEstonia\nEthiopia\nFiji\nFinland\nFrance\nFrench Guiana\nFrench Polynesia\nGabon\nGambia\nGeorgia\nGermany\nGhana\nGreece\nGreenland\nGrenada\nGuadeloupe\nGuam\nGuatemala\nGuinea\nGuinea-Bissau\nGuyana\nHaiti\nHonduras\nHungary\nIceland\nIndia\nIndonesia\nIran\nIraq\nIreland\nIsrael\nItaly\nJamaica\nJapan\nJordan\nKazakhstan\nKenya\nKiribati\nKorea (North)\nKorea (South)\nKuwait\nKyrgyzstan\nLaos\nLatvia\nLebanon\nLesotho\nLiberia\nLibya\nLiechtenstein\nLithuania\nLuxembourg\nMacedonia\nMadagascar\nMadeira\nMalawi\nMalaysia\nMaldives\nMali\nMalta\nMarshall Islands\nMartinique\nMauritania\nMauritius\nMexico\nMicronesia\nMoldova\nMonaco\nMongolia\nMontserrat\nMorocco\nMozambique\nMyanmar\nNamibia\nNauru\nNepal\nNetherlands Antilles\nNetherlands\nNew Caledonia\nNew Zealand\nNicaragua\nNiger\nNiue\nNorthern Mariana\nNorway\nOman\nPakistan\nPalau\nPalestine\nPanama\nPapua New Guinea\nParaguay\nPeru\nPhilippines\nPitcairn Islands\nPoland\nPortugal\nPuerto Rico\nQatar\nReunion\nRomania\nRussian Federation\nRwanda\nSaint Helena\nSaint Kitts-Nevis\nSaint Lucia\nSaint Vincent and the Grenadines\nSamoa\nSan Marino\nSao Tome and Principe\nSaudi Arabia\nSenegal\nSerbia\nSeychelles\nSierra Leone\nSingapore\nSlovakia\nSlovenia\nSolomon Islands\nSomalia\nSouth Africa\nSpain\nSri Lanka\nSudan\nSuriname\nSwaziland\nSweden\nSwitzerland\nSyria\nTajikistan\nTanzania\nThailand\nThe British Virgin Islands\nThe United States Virgin Islands\nTimor-Leste\nTogo\nTokelau\nTonga\nTrinidad and Tobago\nTunisia\nTurkey\nTurkmenistan\nTurks and Caicos Islands\nTuvalu\nUganda\nUkraine\nUnited Arab Emirates\nUnited Kingdom\nUnited States\nUruguay\nUzbekistan\nVanuatu\nVatican City\nVenezuela\nVietnam\nWallis and Futuna\nWestern Sahara\nYemen\nZambia\nZimbabwe", "extra" => null, "type" => "textarea", "sort" => 7, "remark" => null, "created_at" => "2025-04-27 11:23:25", "updated_at" => "2025-06-12 09:55:21", "deleted_at" => null],
["id" => 59, "group_id" => 1, "title" => "产品询盘可选国家", "name" => "optional_country_for_product_inquiry", "value" => "Afghanistan\nAlbania\nAlgeria\nAmerican Samoa\nAndorra\nAngola\nAnguilla\nAntigua and Barbuda\nArgentina\nArmenia\nAruba\nAustralia\nAustria\nAzerbaijan\nAzores\nBahamas\nBahrain\nBangladesh\nBarbados\nBelarus\nBelgium\nBelize\nBenin\nBermuda\nBhutan\nBolivia\nBosnia and Herzegovina\nBotswana\nBrazil\nBrunei\nBulgaria\nBurkina Faso\nBurundi\nCambodia\nCameroon\nCanada\nCanarias\nCape Verde\nCayman\nCentral African Republic\nChad\nChile\nChina\nColombia\nComoros\nCongo (Congo-Kinshasa)\nCongo\nCook Islands\nCosta Rica\nCote D'Ivoire\nCroatia\nCuba\nCyprus\nCzech\nDenmark\nDjibouti\nDominica\nDominican\nEcuador\nEgypt\nEl Salvador\nEquatorial Guinea\nEritrea\nEstonia\nEthiopia\nFiji\nFinland\nFrance\nFrench Guiana\nFrench Polynesia\nGabon\nGambia\nGeorgia\nGermany\nGhana\nGreece\nGreenland\nGrenada\nGuadeloupe\nGuam\nGuatemala\nGuinea\nGuinea-Bissau\nGuyana\nHaiti\nHonduras\nHungary\nIceland\nIndia\nIndonesia\nIran\nIraq\nIreland\nIsrael\nItaly\nJamaica\nJapan\nJordan\nKazakhstan\nKenya\nKiribati\nKorea (North)\nKorea (South)\nKuwait\nKyrgyzstan\nLaos\nLatvia\nLebanon\nLesotho\nLiberia\nLibya\nLiechtenstein\nLithuania\nLuxembourg\nMacedonia\nMadagascar\nMadeira\nMalawi\nMalaysia\nMaldives\nMali\nMalta\nMarshall Islands\nMartinique\nMauritania\nMauritius\nMexico\nMicronesia\nMoldova\nMonaco\nMongolia\nMetropolis\nMorocco\nMozambique\nMyanmar\nNamibia\nNauru\nNepal\nNetherlands Antilles\nNetherlands\nNew Caledonia\nNew Zealand\nNicaragua\nNiger\nNiue\nNorthern Mariana\nNorway\nOman\nPakistan\nPalau\nPalestine\nPanama\nPapua New Guinea\nParaguay\nPeru\nPhilippines\nPitcairn Islands\nPoland\nPortugal\nPuerto Rico\nQatar\nReunion\nRomania\nRussian Federation\nRwanda\nSaint Helena\nSaint Kitts-Nevis\nSaint Lucia\nSaint Vincent and the Grenadines\nSamoa\nSan Marino\nSao Tome and Principe\nSaudi Arabia\nSenegal\nSerbia\nSeychelles\nSierra Leone\nSingapore\nSlovakia\nSlovenia\nSolomon Islands\nSomalia\nSouth Africa\nSpain\nSri Lanka\nSudan\nSuriname\nSwaziland\nSweden\nSwitzerland\nSyria\nTajikistan\nTanzania\nThailand\nThe British Virgin Islands\nThe United States Virgin Islands\nTimor-Leste\nTogo\nTokelau\nTonga\nTrinidad and Tobago\nTunisia\nTurkey\nTurkmenistan\nTurks and Caicos Islands\nTuvalu\nUganda\nUkraine\nUnited Arab Emirates\nUnited Kingdom\nUnited States\nUruguay\nUzbekistan\nVanuatu\nVatican City\nVenezuela\nVietnam\nWallis and Futuna\nWestern Sahara\nYemen\nZambia\nZimbabwe", "extra" => "", "type" => "textarea", "sort" => 7, "remark" => "", "created_at" => "2025-04-27 11:10:22", "updated_at" => "2025-06-11 17:09:13", "deleted_at" => null],
["id" => 60, "group_id" => 4, "title" => "产品询盘可选国家", "name" => "optional_country_for_product_inquiry", "value" => "Afghanistan\nAlbania\nAlgeria\nAmerican Samoa\nAndorra\nAngola\nAnguilla\nAntigua and Barbuda\nArgentina\nArmenia\nAruba\nAustralia\nAustria\nAzerbaijan\nAzores\nBahamas\nBahrain\nBangladesh\nBarbados\nBelarus\nBelgium\nBelize\nBenin\nBermuda\nBhutan\nBolivia\nBosnia and Herzegovina\nBotswana\nBrazil\nBrunei\nBulgaria\nBurkina Faso\nBurundi\nCambodia\nCameroon\nCanada\nCanarias\nCape Verde\nCayman\nCentral African Republic\nChad\nChile\nChina\nColombia\nComoros\nCongo (Congo-Kinshasa)\nCongo\nCook Islands\nCosta Rica\nCote D'Ivoire\nCroatia\nCuba\nCyprus\nCzech\nDenmark\nDjibouti\nDominica\nDominican\nEcuador\nEgypt\nEl Salvador\nEquatorial Guinea\nEritrea\nEstonia\nEthiopia\nFiji\nFinland\nFrance\nFrench Guiana\nFrench Polynesia\nGabon\nGambia\nGeorgia\nGermany\nGhana\nGreece\nGreenland\nGrenada\nGuadeloupe\nGuam\nGuatemala\nGuinea\nGuinea-Bissau\nGuyana\nHaiti\nHonduras\nHungary\nIceland\nIndia\nIndonesia\nIran\nIraq\nIreland\nIsrael\nItaly\nJamaica\nJapan\nJordan\nKazakhstan\nKenya\nKiribati\nKorea (North)\nKorea (South)\nKuwait\nKyrgyzstan\nLaos\nLatvia\nLebanon\nLesotho\nLiberia\nLibya\nLiechtenstein\nLithuania\nLuxembourg\nMacedonia\nMadagascar\nMadeira\nMalawi\nMalaysia\nMaldives\nMali\nMalta\nMarshall Islands\nMartinique\nMauritania\nMauritius\nMexico\nMicronesia\nMoldova\nMonaco\nMongolia\nMetropolis\nMorocco\nMozambique\nMyanmar\nNamibia\nNauru\nNepal\nNetherlands Antilles\nNetherlands\nNew Caledonia\nNew Zealand\nNicaragua\nNiger\nNiue\nNorthern Mariana\nNorway\nOman\nPakistan\nPalau\nPalestine\nPanama\nPapua New Guinea\nParaguay\nPeru\nPhilippines\nPitcairn Islands\nPoland\nPortugal\nPuerto Rico\nQatar\nReunion\nRomania\nRussian Federation\nRwanda\nSaint Helena\nSaint Kitts-Nevis\nSaint Lucia\nSaint Vincent and the Grenadines\nSamoa\nSan Marino\nSao Tome and Principe\nSaudi Arabia\nSenegal\nSerbia\nSeychelles\nSierra Leone\nSingapore\nSlovakia\nSlovenia\nSolomon Islands\nSomalia\nSouth Africa\nSpain\nSri Lanka\nSudan\nSuriname\nSwaziland\nSweden\nSwitzerland\nSyria\nTajikistan\nTanzania\nThailand\nThe British Virgin Islands\nThe United States Virgin Islands\nTimor-Leste\nTogo\nTokelau\nTonga\nTrinidad and Tobago\nTunisia\nTurkey\nTurkmenistan\nTurks and Caicos Islands\nTuvalu\nUganda\nUkraine\nUnited Arab Emirates\nUnited Kingdom\nUnited States\nUruguay\nUzbekistan\nVanuatu\nVatican City\nVenezuela\nVietnam\nWallis and Futuna\nWestern Sahara\nYemen\nZambia\nZimbabwe", "extra" => null, "type" => "textarea", "sort" => 7, "remark" => null, "created_at" => "2025-04-27 11:23:25", "updated_at" => "2025-06-12 09:55:21", "deleted_at" => null],
["id" => 61, "group_id" => 1, "title" => "导航位置店铺URL", "name" => "navigation_store_url", "value" => "https://oricotechs.com/", "extra" => null, "type" => "text", "sort" => 6, "remark" => null, "created_at" => "2025-05-13 17:45:46", "updated_at" => "2025-06-11 17:09:13", "deleted_at" => null],
["id" => 62, "group_id" => 4, "title" => "导航位置店铺URL", "name" => "navigation_store_url", "value" => "https://oricotechs.com/", "extra" => null, "type" => "text", "sort" => 6, "remark" => null, "created_at" => "2025-05-13 17:45:46", "updated_at" => "2025-06-12 09:55:21", "deleted_at" => null],
["id" => 63, "group_id" => 7, "title" => "邮箱", "name" => "website_email", "value" => "supports@orico.com.cn", "extra" => null, "type" => "text", "sort" => 1, "remark" => null, "created_at" => "2025-05-23 17:06:53", "updated_at" => "2025-06-11 17:09:13", "deleted_at" => null],
@@ -119,6 +119,10 @@ class SysConfigInit extends Seeder
["id" => 102, "group_id" => 13, "title" => "视频 - 唯一性保持", "name" => "upload_video.filemd5_unique", "value" => "1", "extra" => "0:否\n1:是", "type" => "radio", "sort" => 5, "remark" => "如果保持视频文件唯一,重复视频上传时将立即返回已存在的地址;如果不保持,则同模块同一天上传的文件根据原文件名覆盖。", "created_at" => "2025-06-12 11:24:24", "updated_at" => "2025-06-12 11:25:18", "deleted_at" => NULL],
["id" => 103, "group_id" => 13, "title" => "附件 - 保留原文件名", "name" => "upload_attachment.filename_keep", "value" => NULL, "extra" => "0:否\n1:是", "type" => "radio", "sort" => 6, "remark" => "默认为否", "created_at" => "2025-06-12 11:27:08", "updated_at" => "2025-06-12 11:27:08", "deleted_at" => NULL],
["id" => 104, "group_id" => 13, "title" => "附件 - 唯一性保持", "name" => "upload_attachment.filemd5_unique", "value" => "1", "extra" => "0:否\n1:是", "type" => "radio", "sort" => 7, "remark" => "如果保持附件文件唯一,重复附件上传时将立即返回已存在的地址;如果不保持,则同模块同一天上传的文件根据原文件名覆盖。", "created_at" => "2025-06-12 11:28:22", "updated_at" => "2025-06-12 11:28:22", "deleted_at" => NULL],
['id' => 105, 'group_id' => 13, 'title' => '视频 - 保存到', 'name' => 'upload_video.save_to', 'value' => 'qiniu_cloud', 'extra' => 'local:本地\nqiniu_cloud:七牛云', 'type' => 'radio', 'sort' => 6, 'remark' => '视频保存位置,默认为“本地” - [本地为本站点服务器;七牛云为七牛云对象存储,上传经这本站点服务器中转,上传耗时稍慢于“本地”]', 'created_at' => '2025-07-25 10:46:24', 'updated_at' => '2025-07-25 16:41:53', 'deleted_at' => NULL],
['id' => 106, 'group_id' => 13, 'title' => '附件 - 保存到', 'name' => 'upload_attachment.save_to', 'value' => 'local', 'extra' => 'local:本地\nqiniu_cloud:七牛云', 'type' => 'radio', 'sort' => 9, 'remark' => '附件保存位置,默认为“本地” - [本地为本站点服务器;七牛云为七牛云对象存储,上传经这本站点服务器中转,上传耗时稍慢于“本地”]', 'created_at' => '2025-07-25 10:51:34', 'updated_at' => '2025-07-25 16:41:53', 'deleted_at' => NULL],
['id' => 107, 'group_id' => 14, 'title' => '视频 - 保存到', 'name' => 'upload_video.save_to', 'value' => 'qiniu_cloud', 'extra' => 'local:本地\nqiniu_cloud:七牛云', 'type' => 'radio', 'sort' => 6, 'remark' => '视频保存位置,默认为“本地” - [本地为本站点服务器;七牛云为七牛云对象存储,上传经这本站点服务器中转,上传耗时稍慢于“本地”]', 'created_at' => '2025-07-25 10:46:24', 'updated_at' => '2025-07-25 16:41:53', 'deleted_at' => NULL],
['id' => 108, 'group_id' => 14, 'title' => '附件 - 保存到', 'name' => 'upload_attachment.save_to', 'value' => 'local', 'extra' => 'local:本地\nqiniu_cloud:七牛云', 'type' => 'radio', 'sort' => 9, 'remark' => '附件保存位置,默认为“本地” - [本地为本站点服务器;七牛云为七牛云对象存储,上传经这本站点服务器中转,上传耗时稍慢于“本地”]', 'created_at' => '2025-07-25 10:51:34', 'updated_at' => '2025-07-25 16:41:53', 'deleted_at' => NULL],
];
$table = $this->table('sys_config');

View File

@@ -0,0 +1,295 @@
<?php
namespace filesystem\adapter;
use League\Flysystem\Config;
use League\Flysystem\FilesystemAdapter;
use League\Flysystem\FileAttributes;
use League\Flysystem\UnableToCopyFile;
use League\Flysystem\UnableToDeleteFile;
use League\Flysystem\UnableToMoveFile;
use League\Flysystem\UnableToReadFile;
use League\Flysystem\UnableToRetrieveMetadata;
use League\Flysystem\UnableToSetVisibility;
use League\Flysystem\UnableToWriteFile;
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
use Qiniu\Storage\BucketManager;
class QiniuAdapter implements FilesystemAdapter
{
protected ?Auth $authMgr;
protected ?UploadManager $uploadMgr;
protected ?BucketManager $bucketMgr;
public function __construct(protected string $access_key, protected string $secret_key, protected string $bucket, protected string $base_url, protected string $path)
{
}
private function getAuthMgr(): Auth
{
return $this->authMgr ?? new Auth($this->access_key, $this->secret_key);
}
private function getUploadMgr(): UploadManager
{
return $this->uploadMgr ?? new UploadManager();
}
private function getBucketMgr(): BucketManager
{
return $this->bucketMgr ?? new BucketManager($this->authMgr);
}
private function getPathPrefix(): string
{
$path = ltrim($this->path, '\\/');
if ($path !== '' && !str_ends_with($path, '/')) {
$path = $path . '/';
}
return $path;
}
private function applyPathPrefix(string $path): string
{
$path = ltrim($path, '\\/');
return $this->getPathPrefix() . $path;
}
private static function parseUrl($url): array
{
$result = [];
// Build arrays of values we need to decode before parsing
$entities = [
'%21',
'%2A',
'%27',
'%28',
'%29',
'%3B',
'%3A',
'%40',
'%26',
'%3D',
'%24',
'%2C',
'%2F',
'%3F',
'%23',
'%5B',
'%5D',
'%5C'
];
$replacements = ['!', '*', "'", '(', ')', ';', ':', '@', '&', '=', '$', ',', '/', '?', '#', '[', ']', '/'];
// Create encoded URL with special URL characters decoded so it can be parsed
// All other characters will be encoded
$encodedURL = str_replace($entities, $replacements, urlencode($url));
// Parse the encoded URL
$encodedParts = parse_url($encodedURL);
// Now, decode each value of the resulting array
if ($encodedParts) {
foreach ($encodedParts as $key => $value) {
$result[$key] = urldecode(str_replace($replacements, $entities, $value));
}
}
return $result;
}
private function normalizeHost($domain): string
{
if (0 !== stripos($domain, 'https://') && 0 !== stripos($domain, 'http://')) {
$domain = "http://{$domain}";
}
return rtrim($domain, '/') . '/';
}
private function getUrl(string $path): string
{
$segments = $this->parseUrl($path);
$query = empty($segments['query']) ? '' : '?' . $segments['query'];
return $this->normalizeHost($this->base_url) . ltrim(implode('/', array_map('rawurlencode', explode('/', $segments['path']))), '/') . $query;
}
private function privateDownloadUrl(string $path, int $expires = 3600): string
{
return $this->getAuthMgr()->privateDownloadUrl($this->getUrl($path), $expires);
}
private function getMetadata($path): FileAttributes|array
{
$result = $this->getBucketMgr()->stat($this->bucket, $path);
$result[0]['key'] = $path;
return $this->normalizeFileInfo($result[0]);
}
private function normalizeFileInfo(array $stats): FileAttributes
{
return new FileAttributes(
$stats['key'],
$stats['fsize'] ?? null,
null,
isset($stats['putTime']) ? floor($stats['putTime'] / 10000000) : null,
$stats['mimeType'] ?? null
);
}
public function fileExists(string $path): bool
{
[, $error] = $this->getBucketMgr()->stat($this->bucket, $this->applyPathPrefix($path));
return is_null($error);
}
public function directoryExists(string $path): bool
{
return $this->fileExists($path);
}
public function write(string $path, string $contents, Config $config): void
{
$mime = $config->get('mime', 'application/octet-stream');
/**
* @var Error|null $error
*/
[, $error] = $this->getUploadMgr()->put(
$this->getAuthMgr()->uploadToken($this->bucket),
$this->applyPathPrefix($path),
$contents,
null,
$mime,
$path
);
if ($error) {
throw UnableToWriteFile::atLocation($path, $error->message());
}
}
public function writeStream(string $path, $resource, Config $config): void
{
$data = '';
while (!feof($resource)) {
$data .= fread($resource, 1024);
}
$this->write($path, $data, $config);
}
public function read(string $path): string
{
try {
$result = file_get_contents($this->privateDownloadUrl($path));
} catch (\Exception $th) {
throw UnableToReadFile::fromLocation($path);
}
if (false === $result) {
throw UnableToReadFile::fromLocation($path);
}
return $result;
}
public function readStream(string $path)
{
if (ini_get('allow_url_fopen')) {
if ($result = fopen($this->privateDownloadUrl($path), 'r')) {
return $result;
}
}
throw UnableToReadFile::fromLocation($path);
}
public function delete(string $path): void
{
[, $error] = $this->getBucketMgr()->delete($this->bucket, $this->applyPathPrefix($path));
if (!is_null($error)) {
throw UnableToDeleteFile::atLocation($path);
}
}
public function deleteDirectory(string $path): void
{
$this->delete($path);
}
public function createDirectory(string $path, Config $config): void
{
}
public function setVisibility(string $path, string $visibility): void
{
throw UnableToSetVisibility::atLocation($path);
}
public function visibility(string $path): FileAttributes
{
throw UnableToRetrieveMetadata::visibility($path);
}
public function mimeType(string $path): FileAttributes
{
$meta = $this->getMetadata($path);
if ($meta->mimeType() === null) {
throw UnableToRetrieveMetadata::mimeType($path);
}
return $meta;
}
public function lastModified(string $path): FileAttributes
{
$meta = $this->getMetadata($path);
if ($meta->lastModified() === null) {
throw UnableToRetrieveMetadata::lastModified($path);
}
return $meta;
}
public function fileSize(string $path): FileAttributes
{
$meta = $this->getMetadata($path);
if ($meta->fileSize() === null) {
throw UnableToRetrieveMetadata::fileSize($path);
}
return $meta;
}
public function listContents(string $path, bool $deep): iterable
{
$result = $this->getBucketMgr()->listFiles($this->bucket, $path);
foreach ($result[0]['items'] ?? [] as $files) {
yield $this->normalizeFileInfo($files);
}
}
public function move(string $source, string $destination, Config $config): void
{
[, $error] = $this->getBucketMgr()->rename($this->bucket, $source, $destination);
if (!is_null($error)) {
throw UnableToMoveFile::fromLocationTo($source, $destination);
}
}
public function copy(string $source, string $destination, Config $config): void
{
[, $error] = $this->getBucketMgr()->copy($this->bucket, $source, $this->bucket, $destination);
if (!is_null($error)) {
throw UnableToCopyFile::fromLocationTo($source, $destination);
}
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace filesystem\driver;
use Closure;
use filesystem\adapter\QiniuAdapter;
use League\Flysystem\FilesystemAdapter;
class Qiniu extends \think\filesystem\Driver
{
protected function createAdapter(): FilesystemAdapter
{
return new QiniuAdapter(
$this->config['access_key'],
$this->config['secret_key'],
$this->config['bucket'],
$this->config['base_url'],
$this->config['path_prefix']
);
}
/**
* 保存文件
* @param string $path 路径
* @param \think\File $file 文件
* @param null|string|\Closure $rule 文件名规则
* @param array $options 参数
* @return bool|string
*/
public function putFile(string $path, \think\File $file, $rule = null, array $options = [])
{
if (!empty($this->config['filename_generator']) && $this->config['filename_generator'] instanceof Closure) {
$rule = $this->config['filename_generator']($file, $rule);
}
return $this->putFileAs($path, $file, $file->hashName($rule), $options);
}
public function url(string $path): string
{
if (str_starts_with($path, 'http://') || str_starts_with($path, 'https://')) {
return $path;
}
if (!str_starts_with($path, $this->config['path_prefix'])) {
$path = $this->config['path_prefix'] . '/' . $path;
}
return $this->concatPathToUrl($this->config['base_url'], $path);
}
public function path(string $path): string
{
if (!str_starts_with($path, $this->config['path_prefix'])) {
$path = $this->config['path_prefix'] . '/' . $path;
}
return $path;
}
}

View File

@@ -1,157 +0,0 @@
<?php
namespace uploader;
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
use Qiniu\Storage\BucketManager;
class QiniuUploader
{
private $bucket = 'orico-opd';
private $accessKey = 'dOsTum4a5qvhPTBbZRPX0pIOU7PZWRX7htKjztms';
private $secretKey = 'KFxsGbnErkALFfeGdMa8QWTdodJbamMX0iznLe-q';
private $rule = [
'fileSize' => 1024 * 1024 * 5, // 默认最大上传5M
'fileExt' => 'jpeg,jpg,png', // 默认上传文件后缀
'fileMime' => 'image/jpeg,image/png,image/gif' // 默认上传文件mime
];
private $dir = true;
private $originalName = false;
private $pathPrefix = '';
private $fileNamePrefix = 'orico';
static public $domain = 'http://opdfile.f2b211.com/';
public function __construct($conf = [])
{
if (!empty($conf['bucket'])) {
$this->bucket = $conf['bucket'];
}
if (!empty($conf['accessKey'])) {
$this->accessKey = $conf['accessKey'];
}
if (!empty($conf['secretKey'])) {
$this->secretKey = $conf['secretKey'];
}
if (!empty($conf['pathPrefix'])) {
$this->pathPrefix = trim($conf['pathPrefix'], '/');
}
}
/**
* 生成随机字符串
*/
private function random($length, $type = "string", $convert = "0")
{
$conf = [
'number' => '0123456789',
'string' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
'all' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789='
];
$string = $conf[$type];
if (!$string) {
$string = $conf['string'];
}
$strlen = strlen($string) - 1;
$char = '';
for ($i = 0; $i < $length; $i++) {
$char .= $string[mt_rand(0, $strlen)];
}
if ($convert > 0) {
$res = strtoupper($char);
} elseif ($convert == 0) {
$res = $char;
} elseif ($convert < 0) {
$res = strtolower($char);
}
return $res;
}
/**
* 组装文件名
*/
private function buildFileName()
{
return $this->fileNamePrefix . time() . substr(time(), -5) . substr(microtime(), 2, 3) . $this->random(8);
}
/**
* 上传验证规则
*/
public function validate($rule)
{
$this->rule = $rule;
}
/**
* 上传文件到七牛云
*/
public function uploadFile($name)
{
// 构建鉴权对象
$auth = new Auth($this->accessKey, $this->secretKey);
// 生成上传 Token
$token = $auth->uploadToken($this->bucket);
// 初始化 UploadManager 对象并进行文件的上传。
$uploadMgr = new UploadManager();
$file = request()->file($name);
$aspectRatio = [];
if (!empty($this->rule['aspectRatio'])) {
$aspectRatio = $this->rule['aspectRatio'];
unset($this->rule['aspectRatio']);
}
$validate = validate([$name => $this->rule]);
if (!$validate->check([$name => $file])) {
throw new \Exception($validate->getError());
}
$fileName = $file->getOriginalName(); // 文件原名
if (!$this->originalName) {
$fileName = $this->buildFileName() . '.' . $file->extension();
if (!$this->dir && !empty($this->pathPrefix)) {
$fileName = $this->pathPrefix . '/' . $fileName;
}
}
if ($this->dir) {
$fileName = date('Y') . '/' . date('m') . '/' . date('d') . '/' . $fileName;
if (!empty($this->pathPrefix)) {
$fileName = $this->pathPrefix . '/' . $fileName;
}
}
$filePath = $file->getPathname(); // 临时路径
if (!empty($aspectRatio)) { // 验证图片宽高
list($width, $height, $type, $attr) = getimagesize($file);
if ($width != $aspectRatio['width'] || $height != $aspectRatio['height']) {
throw new \Exception('图片宽高不符合');
}
}
$fileType = $file->getOriginalMime();
list($ret, $err) = $uploadMgr->putFile($token, $fileName, $filePath, null, $fileType, false);
if ($err !== null) {
throw new \Exception($err);
} else {
return ['hash' => $ret['hash'], 'filename' => $ret['key'], 'remote_url' => self::$domain . $ret['key']];
}
}
/**
* 上传文件到七牛云
*/
public function deleteFile($name)
{
// 构建鉴权对象
$auth = new Auth($this->accessKey, $this->secretKey);
// 初始化 BucketManager 对象并进行文件的删除。
$bucketManager = new BucketManager($auth);
$ret = $bucketManager->delete($this->bucket, $name);
return $ret;
}
}

View File

@@ -1,54 +0,0 @@
<?php
try {
$secret_key = 'Aa-1221';
// check for POST request
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
throw new \Exception('FAILED - not POST - '. $_SERVER['REQUEST_METHOD']);
}
// get content type
$content_type = isset($_SERVER['CONTENT_TYPE']) ? strtolower(trim($_SERVER['CONTENT_TYPE'])) : '';
if ($content_type != 'application/json') {
throw new \Exception('FAILED - not application/json - '. $content_type);
}
// get payload
$payload = trim(file_get_contents("php://input"));
if (empty($payload)) {
throw new \Exception('FAILED - no payload');
}
// get header signature
$header_signature = isset($_SERVER['HTTP_X_GITEA_SIGNATURE']) ? $_SERVER['HTTP_X_GITEA_SIGNATURE'] : '';
if (empty($header_signature)) {
throw new \Exception('FAILED - header signature missing');
}
// calculate payload signature
$payload_signature = hash_hmac('sha256', $payload, $secret_key, false);
// check payload signature against header signature
if ($header_signature !== $payload_signature) {
throw new \Exception('FAILED - payload signature');
}
// convert json to array
$decoded = json_decode($payload, true);
// check for json decode errors
if (json_last_error() !== JSON_ERROR_NONE) {
throw new \Exception('FAILED - json decode - '. json_last_error());
}
exec('git pull origin dev --rebase 2>&1', $result);
var_export($result);exit;
} catch (\Throwable $th) {
var_export($th->getMessage());
}

View File

@@ -1,2 +0,0 @@
*
!.gitignore

View File

@@ -23,7 +23,7 @@
.iotbt1 {
font-size: 18px;
font-family: Montserrat-Bold, Montserrat;
font-family: HarmonyOS-Bold, HarmonyOS;
padding-bottom: 24px;
padding-top: 40px;
font-weight: 700;
@@ -60,7 +60,7 @@
.iotbtp1 {
font-size: 14px;
font-family: Montserrat-Bold, Montserrat;
font-family: HarmonyOS-Bold, HarmonyOS;
font-weight: bold;
padding-bottom: 11px;
word-break: break-word;
@@ -69,7 +69,7 @@
.iotbts1 {
text-align: center;
font-size: 12px;
font-family: Montserrat-Medium, Montserrat;
font-family: HarmonyOS-Medium, HarmonyOS;
color: #9e9e9f;
word-break: break-word;
}
@@ -140,7 +140,7 @@
font-size: 14px;
padding-top: 12px;
text-align: center;
font-family: Montserrat-Medium, Montserrat;
font-family: HarmonyOS-Medium, HarmonyOS;
overflow-wrap: break-word;
word-break: break-word;
}
@@ -152,7 +152,7 @@
.sfbt1 {
text-align: center;
font-size: 18px;
font-family: Montserrat-Bold, Montserrat;
font-family: HarmonyOS-Bold, HarmonyOS;
font-weight: bold;
padding-bottom: 24px;
padding-top: 24px;
@@ -183,7 +183,7 @@
.cit {
width: 100%;
font-size: 14px;
font-family: Montserrat-Regular, Montserrat;
font-family: HarmonyOS-Regular, HarmonyOS;
color: #000;
display: flex;
flex-direction: row;
@@ -237,7 +237,7 @@
.wcu_s1 {
color: #000;
font: 16px;
font-family: Montserrat-Medium, Montserrat;
font-family: HarmonyOS-Medium, HarmonyOS;
font-weight: 500;
padding: 20px 24px;
}

View File

@@ -598,7 +598,7 @@
margin: auto;
font-size: 1rem;
color: #707070;
font-family: "Montserrat-Medium";
font-family: "HarmonyOS-Medium";
}
.oricoCnLc .gallery-thumbs .swiper-slide-thumb-active {
@@ -632,14 +632,14 @@
.oricoCnLc .info h5 {
font-size: #000;
font-size: 1rem;
font-family: "Montserrat-Bold";
font-family: "HarmonyOS-Bold";
padding: 2rem 2rem 0 1rem;
margin: 0;
}
.oricoCnLc .info p {
color: #707070;
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
padding: 1rem;
}
@@ -651,7 +651,7 @@
.oricoCnLc .m_ach-b .title {
font-size: 1.125rem;
font-family: "Montserrat-Bold";
font-family: "HarmonyOS-Bold";
width: 98%;
margin: auto;
position: relative;
@@ -660,7 +660,7 @@
.oricoCnLc .m_ach-b .chtitle {
font-size: 1.125rem;
font-family: "Montserrat-Bold";
font-family: "HarmonyOS-Bold";
width: 98%;
margin: auto;
position: relative;
@@ -677,7 +677,7 @@
.oricoCnLc .m_ch-title {
font-size: 1rem;
font-family: "Montserrat-Bold";
font-family: "HarmonyOS-Bold";
width: 98%;
margin: 1rem auto 0;
padding: 1rem 0 0;
@@ -690,7 +690,7 @@
font-size: 0.875;
line-height: 1.5rem;
color: #707070;
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
width: 98%;
margin: 1rem auto;
padding: 0;

View File

@@ -156,7 +156,7 @@
border-radius: 8px;
height: 48px;
box-shadow: none;
font-family: Montserrat-Regular, Montserrat;
font-family: HarmonyOS-Regular, HarmonyOS;
}
.oricoEGapp-articledetail .content .share_box .comment .comment_form>div input {

View File

@@ -33,7 +33,7 @@
border-radius: 1rem;
background-color: #fff;
color: #6b6c6e;
font-family: "Montserrat-Medium";
font-family: "HarmonyOS-Medium";
font-size: 0.875rem;
display: inline-block;
margin-bottom: 0.5rem;

View File

@@ -16,7 +16,7 @@
font-size: 18px;
color: #004bfa;
text-align: left;
font-family: Montserrat-Bold, Montserrat;
font-family: HarmonyOS-Bold, HarmonyOS;
font-weight: 700;
margin-top: 0;
margin-bottom: 12px;
@@ -27,7 +27,7 @@
color: #707070;
text-align: center;
text-align: left;
font-family: Montserrat-Medium, Montserrat;
font-family: HarmonyOS-Medium, HarmonyOS;
font-weight: 500;
}
@@ -83,7 +83,7 @@
.itlable {
font-size: 12.5px;
font-family: Montserrat-Medium, Montserrat;
font-family: HarmonyOS-Medium, HarmonyOS;
color: #000000;
font-weight: bold;
padding-bottom: 5px;
@@ -106,7 +106,7 @@
height: 48px;
border: none;
box-shadow: none;
font-family: Montserrat-Regular, Montserrat;
font-family: HarmonyOS-Regular, HarmonyOS;
}
.itselectopen {
@@ -130,12 +130,12 @@
padding: 15px;
background: #f2f2f2;
border-radius: 8px;
font-family: Montserrat-Regular, Montserrat;
font-family: HarmonyOS-Regular, HarmonyOS;
}
.bttj {
font-size: 14px;
font-family: Montserrat-Bold, Montserrat;
font-family: HarmonyOS-Bold, HarmonyOS;
font-weight: bold;
/* width: 212px; */
/* height: 48px; */
@@ -173,7 +173,7 @@
.iotbt1 {
font-size: 18px;
font-family: Montserrat-Bold, Montserrat;
font-family: HarmonyOS-Bold, HarmonyOS;
padding-bottom: 24px;
padding-top: 40px;
font-weight: 700;
@@ -210,7 +210,7 @@
.iotbtp1 {
font-size: 14px;
font-family: Montserrat-Bold, Montserrat;
font-family: HarmonyOS-Bold, HarmonyOS;
font-weight: bold;
padding-bottom: 11px;
word-break: break-word;
@@ -219,7 +219,7 @@
.iotbts1 {
text-align: center;
font-size: 12px;
font-family: Montserrat-Medium, Montserrat;
font-family: HarmonyOS-Medium, HarmonyOS;
color: #9e9e9f;
word-break: break-word;
}
@@ -290,7 +290,7 @@
font-size: 14px;
padding-top: 12px;
text-align: center;
font-family: Montserrat-Medium, Montserrat;
font-family: HarmonyOS-Medium, HarmonyOS;
overflow-wrap: break-word;
word-break: break-word;
}
@@ -302,7 +302,7 @@
.sfbt1 {
text-align: center;
font-size: 18px;
font-family: Montserrat-Bold, Montserrat;
font-family: HarmonyOS-Bold, HarmonyOS;
font-weight: bold;
padding-bottom: 24px;
padding-top: 24px;
@@ -333,7 +333,7 @@
.cit {
width: 100%;
font-size: 14px;
font-family: Montserrat-Regular, Montserrat;
font-family: HarmonyOS-Regular, HarmonyOS;
color: #000;
display: flex;
flex-direction: row;
@@ -388,7 +388,7 @@
.wcu_s1 {
color: #000;
font-size: 16px;
font-family: Montserrat-Medium, Montserrat;
font-family: HarmonyOS-Medium, HarmonyOS;
font-weight: 500;
padding: 20px 24px;
}

View File

@@ -16,7 +16,7 @@
font-size: 18px;
color: #004bfa;
text-align: left;
font-family: Montserrat-Bold, Montserrat;
font-family: HarmonyOS-Bold, HarmonyOS;
font-weight: 700;
margin-top: 0;
margin-bottom: 12px;
@@ -27,7 +27,7 @@
color: #707070;
text-align: center;
text-align: left;
font-family: Montserrat-Medium, Montserrat;
font-family: HarmonyOS-Medium, HarmonyOS;
font-weight: 500;
}
@@ -83,7 +83,7 @@
.itlable {
font-size: 12.5px;
font-family: Montserrat-Medium, Montserrat;
font-family: HarmonyOS-Medium, HarmonyOS;
color: #000000;
font-weight: bold;
padding-bottom: 5px;
@@ -106,7 +106,7 @@
height: 48px;
border: none;
box-shadow: none;
font-family: Montserrat-Regular, Montserrat;
font-family: HarmonyOS-Regular, HarmonyOS;
}
.itselectopen {
@@ -130,13 +130,13 @@
padding: 15px;
background: #f2f2f2;
border-radius: 8px;
font-family: Montserrat-Regular, Montserrat;
font-family: HarmonyOS-Regular, HarmonyOS;
border: 0;
}
.bttj {
font-size: 14px;
font-family: Montserrat-Bold, Montserrat;
font-family: HarmonyOS-Bold, HarmonyOS;
font-weight: bold;
/* width: 212px; */
padding: 15px 60px;
@@ -173,7 +173,7 @@
.iotbt1 {
font-size: 18px;
font-family: Montserrat-Bold, Montserrat;
font-family: HarmonyOS-Bold, HarmonyOS;
padding-bottom: 24px;
padding-top: 40px;
font-weight: 700;
@@ -210,7 +210,7 @@
.iotbtp1 {
font-size: 14px;
font-family: Montserrat-Bold, Montserrat;
font-family: HarmonyOS-Bold, HarmonyOS;
font-weight: bold;
padding-bottom: 11px;
word-break: break-word;
@@ -219,7 +219,7 @@
.iotbts1 {
text-align: center;
font-size: 12px;
font-family: Montserrat-Medium, Montserrat;
font-family: HarmonyOS-Medium, HarmonyOS;
color: #9e9e9f;
word-break: break-word;
}
@@ -290,7 +290,7 @@
font-size: 14px;
padding-top: 12px;
text-align: center;
font-family: Montserrat-Medium, Montserrat;
font-family: HarmonyOS-Medium, HarmonyOS;
overflow-wrap: break-word;
word-break: break-word;
}
@@ -302,7 +302,7 @@
.sfbt1 {
text-align: center;
font-size: 18px;
font-family: Montserrat-Bold, Montserrat;
font-family: HarmonyOS-Bold, HarmonyOS;
font-weight: bold;
padding-bottom: 24px;
padding-top: 24px;
@@ -333,7 +333,7 @@
.cit {
width: 100%;
font-size: 14px;
font-family: Montserrat-Regular, Montserrat;
font-family: HarmonyOS-Regular, HarmonyOS;
color: #000;
display: flex;
flex-direction: row;
@@ -387,7 +387,7 @@
.wcu_s1 {
color: #000;
font: 16px;
font-family: Montserrat-Medium, Montserrat;
font-family: HarmonyOS-Medium, HarmonyOS;
font-weight: 500;
padding: 20px 24px;
}

View File

@@ -7,7 +7,7 @@
margin-top: 3.3rem;
}
.oricoEGapp-Contact .banner_title {
font-family: "Montserrat-Bold";
font-family: "HarmonyOS-Bold";
font-size: 1.5rem;
position: absolute;
top: 50%;
@@ -24,7 +24,7 @@
color: #000;
}
.oricoEGapp-Contact .title {
font-family: "Montserrat-Bold";
font-family: "HarmonyOS-Bold";
font-size: 1rem;
}
.oricoEGapp-Contact .info {
@@ -43,12 +43,12 @@
height: 3rem;
}
.oricoEGapp-Contact .info .right .des {
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
font-size: 0.875rem;
line-height: 1.25rem;
}
.oricoEGapp-Contact .info_title {
font-family: "Montserrat-Bold";
font-family: "HarmonyOS-Bold";
font-size: 0.875rem;
line-height: 1.25rem;
margin-bottom: 0.22rem;
@@ -61,7 +61,7 @@
}
.oricoEGapp-Contact .question .title {
margin-top: 0.5rem;
font-family: "Montserrat-Bold";
font-family: "HarmonyOS-Bold";
font-size: 0.875rem;
line-height: 1.25rem;
}
@@ -86,7 +86,7 @@
.oricoEGapp-Contact .send {
display: block;
background-color: #004bfa;
font-family: "Montserrat-Bold";
font-family: "HarmonyOS-Bold";
font-size: 0.875rem;
padding: 0.75rem 1.5rem;
color: #fff;
@@ -98,7 +98,7 @@
color: #ee2f53;
}
.oricoEGapp-Contact .contact_b {
font-family: "Montserrat-SemiBold";
font-family: "HarmonyOS-SemiBold";
font-size: 1rem;
padding-top: 1.125rem;
padding-bottom: 1.125rem;
@@ -119,42 +119,42 @@
.oricoEGapp-Contact input::-webkit-input-placeholder {
color: #9e9e9f;
font-size: 0.875rem;
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
}
.oricoEGapp-Contact input:-moz-placeholder {
color: #9e9e9f;
font-size: 0.875rem;
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
}
.oricoEGapp-Contact input::-moz-placeholder {
color: #9e9e9f;
font-size: 0.875rem;
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
}
.oricoEGapp-Contact input:-ms-input-placeholder {
color: #9e9e9f;
font-size: 0.875rem;
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
}
.oricoEGapp-Contact textarea::-webkit-input-placeholder {
color: #9e9e9f;
font-size: 0.875rem;
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
}
.oricoEGapp-Contact textarea:-moz-placeholder {
color: #9e9e9f;
font-size: 0.875rem;
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
}
.oricoEGapp-Contact textarea::-moz-placeholder {
color: #9e9e9f;
font-size: 0.875rem;
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
}
.oricoEGapp-Contact textarea:-ms-input-placeholder {
color: #9e9e9f;
font-size: 0.875rem;
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
}
.oricoEGapp-Contact .narskfPage {
width: 100%;

View File

@@ -7,7 +7,7 @@
margin-top: 3.3rem;
}
.oricoEGapp-Contact .banner_title {
font-family: "Montserrat-Bold";
font-family: "HarmonyOS-Bold";
font-size: 1.5rem;
position: absolute;
top: 50%;
@@ -24,7 +24,7 @@
color: #000;
}
.oricoEGapp-Contact .title {
font-family: "Montserrat-Bold";
font-family: "HarmonyOS-Bold";
font-size: 1rem;
}
.oricoEGapp-Contact .info {
@@ -46,12 +46,12 @@
width: 88% !important;
}
.oricoEGapp-Contact .info .right .des {
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
font-size: 0.875rem;
line-height: 1.25rem;
}
.oricoEGapp-Contact .info_title {
font-family: "Montserrat-Bold";
font-family: "HarmonyOS-Bold";
font-size: 0.875rem;
line-height: 1.25rem;
margin-bottom: 0.22rem;
@@ -64,7 +64,7 @@
}
.oricoEGapp-Contact .question .title {
margin-top: 0.5rem;
font-family: "Montserrat-Bold";
font-family: "HarmonyOS-Bold";
font-size: 0.875rem;
line-height: 1.25rem;
}
@@ -89,7 +89,7 @@
.oricoEGapp-Contact .send {
display: block;
background-color: #004bfa;
font-family: "Montserrat-Bold";
font-family: "HarmonyOS-Bold";
font-size: 0.875rem;
padding: 0.75rem 1.5rem;
color: #fff;
@@ -101,7 +101,7 @@
color: #ee2f53;
}
.oricoEGapp-Contact .contact_b {
font-family: "Montserrat-SemiBold";
font-family: "HarmonyOS-SemiBold";
font-size: 1rem;
padding-top: 1.125rem;
padding-bottom: 1.125rem;
@@ -122,40 +122,40 @@
.oricoEGapp-Contact input::-webkit-input-placeholder {
color: #9e9e9f;
font-size: 0.875rem;
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
}
.oricoEGapp-Contact input:-moz-placeholder {
color: #9e9e9f;
font-size: 0.875rem;
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
}
.oricoEGapp-Contact input::-moz-placeholder {
color: #9e9e9f;
font-size: 0.875rem;
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
}
.oricoEGapp-Contact input:-ms-input-placeholder {
color: #9e9e9f;
font-size: 0.875rem;
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
}
.oricoEGapp-Contact textarea::-webkit-input-placeholder {
color: #9e9e9f;
font-size: 0.875rem;
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
}
.oricoEGapp-Contact textarea:-moz-placeholder {
color: #9e9e9f;
font-size: 0.875rem;
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
}
.oricoEGapp-Contact textarea::-moz-placeholder {
color: #9e9e9f;
font-size: 0.875rem;
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
}
.oricoEGapp-Contact textarea:-ms-input-placeholder {
color: #9e9e9f;
font-size: 0.875rem;
font-family: "Montserrat-Regular";
font-family: "HarmonyOS-Regular";
}

View File

@@ -1,7 +1,7 @@
@font-face {
font-family: 'icomoon';
src: url('../fonts/icomoon/icomoon.eot?11cuay');
src: url('../fonts/icomoon/icomoon.eot?11cuay#iefix') format('embedded-opentype'), url('../fonts/icomoon/icomoon.ttf?11cuay') format('truetype'),
src: url('../fonts/icomoon/icomoon.eot?11cuay#iefix') format('embedded-opentype'), url('../fonts/icomoon/icomoon.ttf?11cuay') format('opentype'),
url('../fonts/icomoon/icomoon.woff?11cuay') format('woff'), url('../fonts/icomoon/icomoon.svg?11cuay#icomoon') format('svg');
font-weight: normal;
font-style: normal;
@@ -54,7 +54,7 @@
font-family: 'colleciton';
src: url('../fonts/icomoon/colleciton/icomoon.eot?11cuay');
src: url('../fonts/icomoon/colleciton/icomoon.eot?11cuay#iefix') format('embedded-opentype'),
url('../fonts/icomoon/colleciton/icomoon.ttf?11cuay') format('truetype'), url('../fonts/icomoon/colleciton/icomoon.woff?11cuay') format('woff'),
url('../fonts/icomoon/colleciton/icomoon.ttf?11cuay') format('opentype'), url('../fonts/icomoon/colleciton/icomoon.woff?11cuay') format('woff'),
url('../fonts/icomoon/colleciton/icomoon.svg?11cuay#icomoon') format('svg');
font-weight: normal;
font-style: normal;
@@ -83,7 +83,7 @@
@font-face {
font-family: 'icomoon';
src: url('../fonts/icomoon/icomoona.eot?c46hgi');
src: url('../fonts/icomoon/icomoona.eot?c46hgi#iefix') format('embedded-opentype'), url('../fonts/icomoon/icomoona.ttf?c46hgi') format('truetype'),
src: url('../fonts/icomoon/icomoona.eot?c46hgi#iefix') format('embedded-opentype'), url('../fonts/icomoon/icomoona.ttf?c46hgi') format('opentype'),
url('../fonts/icomoon/icomoona.woff?c46hgi') format('woff'), url('../fonts/icomoon/icomoona.svg?c46hgi#icomoon') format('svg');
font-weight: normal;
font-style: normal;

View File

@@ -1,7 +1,7 @@
@font-face {
font-family: 'icomoon';
src: url('../fonts/icomoon/icomoon.eot?ujw7hy');
src: url('../fonts/icomoon/icomoon.eot?ujw7hy#iefix') format('embedded-opentype'), url('../fonts/icomoon/icomoon.ttf?ujw7hy') format('truetype'),
src: url('../fonts/icomoon/icomoon.eot?ujw7hy#iefix') format('embedded-opentype'), url('../fonts/icomoon/icomoon.ttf?ujw7hy') format('opentype'),
url('../fonts/icomoon/icomoon.woff?ujw7hy') format('woff'), url('../fonts/icomoon/icomoon.svg?ujw7hy#icomoon') format('svg');
font-weight: normal;
font-style: normal;
@@ -114,7 +114,7 @@
font-family: 'icomoon01';
src: url('fonts-20190124/icomoon.eot?ll2528');
src: url('fonts-20190124/icomoon.eot?ll2528#iefix') format('embedded-opentype'),
url('fonts-20190124/icomoon.ttf?ll2528') format('truetype'), url('fonts-20190124/icomoon.woff?ll2528') format('woff'),
url('fonts-20190124/icomoon.ttf?ll2528') format('opentype'), url('fonts-20190124/icomoon.woff?ll2528') format('woff'),
url('fonts-20190124/icomoon.svg?ll2528#icomoon') format('svg');
font-weight: normal;
font-style: normal;
@@ -161,7 +161,7 @@
@font-face {
font-family: 'icomoon02';
src: url('fonts/other/icomoon.eot?ujw7hy');
src: url('fonts/other/icomoon.eot?ujw7hy#iefix') format('embedded-opentype'), url('fonts/other/icomoon.ttf?ujw7hy') format('truetype'),
src: url('fonts/other/icomoon.eot?ujw7hy#iefix') format('embedded-opentype'), url('fonts/other/icomoon.ttf?ujw7hy') format('opentype'),
url('fonts/other/icomoon.woff?ujw7hy') format('woff'), url('fonts/other/icomoon.svg?ujw7hy#icomoon') format('svg');
font-weight: normal;
font-style: normal;
@@ -189,7 +189,7 @@
font-family: 'icomoon05';
src: url('fonts-20220322/icomoon.eot?cdcz43');
src: url('fonts-20220322/icomoon.eot?cdcz43#iefix') format('embedded-opentype'),
url('fonts-20220322/icomoon.ttf?cdcz43') format('truetype'), url('fonts-20220322/icomoon.woff?cdcz43') format('woff'),
url('fonts-20220322/icomoon.ttf?cdcz43') format('opentype'), url('fonts-20220322/icomoon.woff?cdcz43') format('woff'),
url('fonts-20220322/icomoon.svg?cdcz43#icomoon') format('svg');
font-weight: normal;
font-style: normal;

View File

@@ -29,7 +29,7 @@
display: none;
}
.oircoEgapp-head .top-menu .it-ct {
font-family: "Montserrat-SemiBold";
font-family: "HarmonyOS-SemiBold";
font-weight: bold;
}
.oircoEgapp-head .top-menu .it-ct .it-1 {

View File

@@ -1,20 +1,20 @@
@font-face {
font-family: "Montserrat";
src: url("../fonts/Montserrat-Regular.ttf") format("truetype");
font-family: "HarmonyOS";
src: url("../fonts/HarmonyOS-Regular.otf") format("opentype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "Montserrat-Bold";
src: url("../fonts/Montserrat-Bold.ttf") format("truetype");
font-family: "HarmonyOS-Bold";
src: url("../fonts/HarmonyOS-Bold.otf") format("opentype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "Montserrat-Medium";
src: url("../fonts/Montserrat-Medium.ttf") format("truetype");
font-family: "HarmonyOS-Medium";
src: url("../fonts/HarmonyOS-Medium.otf") format("opentype");
font-weight: normal;
font-style: normal;
}
@@ -22,7 +22,7 @@
* {
margin: 0;
padding: 0;
/* font-family: 'Montserrat'; */
/* font-family: 'HarmonyOS'; */
-ms-overflow-style: none;
/* IE 和 Edge */
scrollbar-width: none;
@@ -88,7 +88,7 @@ a {
}
body {
font-family: 'Montserrat-SemiBold';
font-family: 'HarmonyOS-SemiBold';
}
/* 分页样式 */
@@ -161,7 +161,9 @@ body {
.ql-editor>* {
cursor: text
}
.ql-editor video{
max-width: 100% !important;
}
.ql-editor p,.ql-editor ol,.ql-editor ul,.ql-editor pre,.ql-editor blockquote,.ql-editor h1,.ql-editor h2,.ql-editor h3,.ql-editor h4,.ql-editor h5,.ql-editor h6 {
margin: 0;
padding: 0;

View File

@@ -1,29 +1,30 @@
@font-face {
font-family: "Montserrat";
src: url("../fonts/Montserrat-Regular.ttf") format("truetype");
font-family: "HarmonyOS";
src: url("//ow.static.f2b211.com/static/fonts/HarmonyOS_Sans_SC_Regular.woff2") format("woff2");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "Montserrat-Bold";
src: url("../fonts/Montserrat-Bold.ttf") format("truetype");
font-family: "HarmonyOS-Bold";
src: url("//ow.static.f2b211.com/static/fonts/HarmonyOS_Sans_SC_Bold.woff2") format("woff2");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "Montserrat-Medium";
src: url("../fonts/Montserrat-Medium.ttf") format("truetype");
font-family: "HarmonyOS-Medium";
src: url("//ow.static.f2b211.com/static/fonts/HarmonyOS_Sans_SC_Medium.woff2") format("woff2");
font-weight: normal;
font-style: normal;
}
/* HarmonyOS-SemiBold1 */
@font-face {
font-family: "Montserrat-SemiBold";
src: url("../fonts/Montserrat-SemiBold.ttf") format("truetype");
font-family: "HarmonyOS-SemiBold";
src: url("//ow.static.f2b211.com/static/fonts/HarmonyOS_Sans_SC_Bold.woff2") format("woff2");
font-weight: normal;
font-style: normal;
}
body {
font-family: 'Montserrat-SemiBold';
font-family: 'HarmonyOS-SemiBold';
margin: auto;
background-color: #f5f5f5;
max-width: 750px;
@@ -591,7 +592,7 @@ button.swiper-pagination-bullet {
.Innew-text .title {
font-size: 2.5rem;
padding-bottom: 1rem;
font-family: 'Montserrat-Bold';
font-family: 'HarmonyOS-Bold';
}
.Inpro-text {
padding: 2rem 0 0.8rem;
@@ -600,7 +601,7 @@ button.swiper-pagination-bullet {
.Inpro-text .title {
font-size: 1.5rem;
padding-bottom: 1rem;
font-family: 'Montserrat-Bold';
font-family: 'HarmonyOS-Bold';
}
.Innew-text .more {
@@ -635,7 +636,7 @@ video img {
font-size: 1.2rem;
max-height: 3rem;
overflow: hidden;
font-family: 'Montserrat-Bold';
font-family: 'HarmonyOS-Bold';
}
.inprotext .t-f16 {
font-size: 1rem;
@@ -957,12 +958,12 @@ video img {
margin: auto;
line-height: 2rem;
padding: 0 3rem;
font-family: 'Montserrat-Bold';
font-family: 'HarmonyOS-Bold';
}
.ban-t {
padding: 0.5rem 3rem;
font-size: 1.125rem;
font-family: 'Montserrat-Regular';
font-family: 'HarmonyOS-Regular';
}
.btn-more {
background: transparent;
@@ -979,7 +980,7 @@ video img {
margin: auto;
font-size: 1rem;
font-weight: 600;
font-family: 'Montserrat-Bold';
font-family: 'HarmonyOS-Bold';
}
/*类别*/
.category {
@@ -1095,11 +1096,11 @@ video img {
padding: 0.2rem 0;
text-align: center;
margin: 0;
font-family: 'Montserrat-Bold';
font-family: 'HarmonyOS-Bold';
}
.num-bg li p {
font-size: 0.8rem;
font-family: 'Montserrat-Regular';
font-family: 'HarmonyOS-Regular';
}
/*标题*/
.Tech-text {
@@ -1115,7 +1116,7 @@ video img {
.Tech-text p {
padding: 1rem 0;
font-size: 0.875rem;
font-family: 'Montserrat-Medium';
font-family: 'HarmonyOS-Medium';
}
.pos-text {
@@ -1125,7 +1126,7 @@ video img {
color: #fff;
font-size: 0.825rem;
margin: 0 auto;
font-family: 'Montserrat-Bold';
font-family: 'HarmonyOS-Bold';
height: 2rem;
overflow: hidden;
text-overflow: ellipsis;
@@ -1157,7 +1158,7 @@ video img {
font-size: 0.9rem;
padding: 1rem 0;
line-height: 1.3em;
font-family: 'Montserrat-Bold';
font-family: 'HarmonyOS-Bold';
word-break: break-all;
}
.faq span {
@@ -1172,7 +1173,7 @@ video img {
font-size: 0.875rem;
line-height: 1.75em;
color: #666;
font-family: 'Montserrat-Medium';
font-family: 'HarmonyOS-Medium';
}
.faq i {
position: absolute;
@@ -1209,7 +1210,7 @@ video img {
word-wrap: break-word;
overflow: hidden;
height: 1.5rem;
font-family: 'Montserrat-Medium';
font-family: 'HarmonyOS-Medium';
font-weight: 400;
word-break: break-all;
}
@@ -1217,7 +1218,7 @@ video img {
font-size: 1.125rem;
color: #7f7f7f;
padding-bottom: 1rem;
font-family: 'Montserrat-Medium';
font-family: 'HarmonyOS-Medium';
font-weight: 400;
}
/*foot */
@@ -1249,7 +1250,7 @@ video img {
}
.foot-in h3 {
font-size: 1.25rem;
font-family: 'Montserrat-Bold';
font-family: 'HarmonyOS-Bold';
font-weight: 100;
}
.logo-input {
@@ -1278,7 +1279,7 @@ video img {
margin-left: 1rem;
}
.foot-cate li {
width: 50%;
min-width: 50%;
display: inline-block;
float: left;
color: #fff;
@@ -1292,7 +1293,7 @@ video img {
.foot-cate li p {
font-size: 0.7rem;
line-height: 2.5rem;
font-family: 'Montserrat-Medium';
font-family: 'HarmonyOS-Medium';
word-wrap: break-word;
}
.foot-wei {
@@ -1327,7 +1328,7 @@ video img {
width: 100%;
height: 1.2rem;
cursor: pointer;
font-family: 'Montserrat-Medium';
font-family: 'HarmonyOS-Medium';
}
/*下拉*/
.m_footer .left {
@@ -1375,7 +1376,7 @@ video img {
text-align: center;
font-size: 12px;
padding-bottom: 0.5rem;
font-family: 'Montserrat-Medium';
font-family: 'HarmonyOS-Medium';
}
/*下拉*/
.mask-up {
@@ -1985,7 +1986,7 @@ video img {
}
.swiper-slide a {
color: #000;
font-family: 'Montserrat-SemiBold';
font-family: 'HarmonyOS-SemiBold';
}
.swiper-slide img {
max-width: 100%;
@@ -2342,6 +2343,59 @@ video img {
margin-bottom: 1.3rem;
}
.products_des {
width: 100%;
margin-bottom: 50px;
}
.products_des img {
width: 100%;
}
.de_t_n {
font-size: 1.5em;
color: #333;
}
.detail_title {
text-align: center;
padding: 2% 0;
}
.detail_title p {
line-height: 2em;
}
.detail_con_a {
margin: auto;
overflow: hidden;
}
.lj_detail_text,
.lj_detail_texts {
font-size: 0.875em;
}
.lj_detail_text p {
line-height: 1.6em;
padding: 0.5% 0;
}
/*seo-pro*/
.seo-pro h3 {
font-size: 1.5em;
text-align: center;
color: #333;
margin: 2% 0 1%;
line-height: 1.2;
font-weight: 400;
}
.seo-pro p {
text-align: center;
margin: 0 0 11px;
}
.seo-pro a {
color: #333;
text-decoration: none;
}
.sa_blue,
.sa_blue a,
.seo-pro a:hover {
color: #009fdf;
}
/*两列*/
.list_two {
width: 100%;
@@ -2438,7 +2492,7 @@ video img {
margin-right: 0px;
line-height: 40px;
font-weight: 600;
font-family: Montserrat !important;
font-family: HarmonyOS !important;
color: #666;
text-align: left;
}
@@ -3426,26 +3480,26 @@ video img {
font-size: 1.5rem;
width: 90%;
margin: 4rem auto 0;
font-family: 'Montserrat-Bold';
font-family: 'HarmonyOS-Bold';
}
.timedesin {
font-size: 0.875rem;
padding: 0.5rem 1rem;
line-height: 1.3rem;
width: 90%;
font-family: 'Montserrat-Medium';
font-family: 'HarmonyOS-Medium';
}
.timeblue {
color: #004bfa;
font-size: 1.125rem;
font-family: 'Montserrat-Medium';
font-family: 'HarmonyOS-Medium';
}
.timeblue img {
vertical-align: middle;
}
.timeblue a {
color: #004bfa;
font-family: 'Montserrat-Medium';
font-family: 'HarmonyOS-Medium';
}
/*视频*/
.video-youtu {
@@ -3505,7 +3559,7 @@ video img {
}
.vision-title {
font-size: 1rem;
font-family: 'Montserrat-Bold';
font-family: 'HarmonyOS-Bold';
width: 98%;
margin: 1rem auto 0;
}
@@ -3513,7 +3567,7 @@ video img {
font-size: 0.875;
line-height: 1.5rem;
color: #707070;
font-family: 'Montserrat-Regular';
font-family: 'HarmonyOS-Regular';
width: 98%;
margin: 1rem auto;
}
@@ -3531,7 +3585,7 @@ video img {
}
.brand_title {
font-size: 1.125rem;
font-family: 'Montserrat-Bold';
font-family: 'HarmonyOS-Bold';
width: 98%;
margin: 1rem auto 0;
position: relative;
@@ -3549,7 +3603,7 @@ video img {
font-size: 0.875;
line-height: 1.5rem;
color: #000000;
font-family: 'Montserrat-Regular';
font-family: 'HarmonyOS-Regular';
width: 98%;
margin: 1rem auto;
}
@@ -3602,7 +3656,7 @@ video::-webkit-media-controls-current-time-display {
}
.m_ach .title {
font-size: 1.125rem;
font-family: 'Montserrat-Bold';
font-family: 'HarmonyOS-Bold';
width: 98%;
margin: 1rem auto 0;
position: relative;
@@ -3627,7 +3681,7 @@ video::-webkit-media-controls-current-time-display {
}
.m_ach .list-num li p {
color: #707070;
font-family: 'Montserrat-Regular';
font-family: 'HarmonyOS-Regular';
}
/*新闻评测*/
.news-vertu {
@@ -3923,7 +3977,7 @@ video::-webkit-media-controls-current-time-display {
border-radius: 8px;
height: 48px;
box-shadow: none;
font-family: Montserrat-Regular, Montserrat;
font-family: HarmonyOS-Regular, HarmonyOS;
}
.comment_area {
width: 100% !important;

View File

@@ -220,3 +220,31 @@
color: #1f2635;
border-bottom: 1px solid #1f2635;
}
/*9.18 添加三级样式*/
.narshelpCenterdetail-app .nhlpapp-pagescate .nars-hlpdt-ml .sub-list .two-mues {
position: relative;
}
.narshelpCenterdetail-app .nhlpapp-pagescate .nars-hlpdt-ml .sub-list .two-mues .two-a {
position: relative;
padding-top: 6px;
display: flex;
font-size: 0.95rem !important;
flex-direction: row;
}
.narshelpCenterdetail-app .nhlpapp-pagescate .nars-hlpdt-ml .sub-list .two-mues .two-a:hover {
border-bottom: none;
}
.narshelpCenterdetail-app .nhlpapp-pagescate .nars-hlpdt-ml .sub-list .thress-mues {
display: none;
}
.narshelpCenterdetail-app .nhlpapp-pagescate .nars-hlpdt-ml .sub-list .thress-mues a {
padding-top: 0.375rem;
padding-left: 1.875rem;
}

View File

@@ -0,0 +1,143 @@
/* 核心模块固定90%宽度PC端优化移动端边距 */
.advantage-section {
width: 93.5%;
margin: 0 auto;
padding-top:0.99rem;
position: relative;
z-index: 1;
height: auto !important;
min-height: auto !important;
margin-bottom: 0.51rem;
}
/* 标题容器:恢复原有居中样式 */
.advantage-section__title {
font-size: 0.46rem;
font-weight: 700;
text-align: center;
color: #101010;
margin:0 auto;
margin-bottom: 0.51rem;
width: 80%;
}
/* 列表容器改为wrap换行实现2+3布局间距设为0.08rem8px */
.advantage-section__list {
display: flex;
justify-content: flex-start; /* 左对齐排列 */
align-items: flex-start;
gap: 0.08rem; /* 列间距设计稿8px=0.08rem */
row-gap: 0.08rem; /* 行间距设计稿8px=0.08rem */
width: 100% !important;
flex-wrap: wrap; /* 允许换行 */
overflow: visible !important;
padding: 0 !important;
height: auto !important;
min-height: 1px !important;
position: relative !important;
}
/* 卡片包裹容器:动态宽度控制 */
.advantage-card-wrap {
display: block !important;
height: auto !important;
min-height: 1px !important;
}
/* 第一行2个卡片宽度=(100% - 1个间距)/2 */
.advantage-card-wrap:nth-child(1),
.advantage-card-wrap:nth-child(2) {
width: calc((100% - 0.08rem) / 2) !important;
}
/* 第二行3个卡片宽度=(100% - 2个间距)/3 */
.advantage-card-wrap:nth-child(3),
.advantage-card-wrap:nth-child(4),
.advantage-card-wrap:nth-child(5) {
width: calc((100% - 2 * 0.08rem) / 3) !important;
}
/* 卡片核心:宽度继承父容器,高度自适应 */
.advantage-card {
width: 100% !important;
overflow: hidden;
box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease;
cursor: pointer;
background: #fff;
position: relative;
z-index: 1;
height: auto !important;
display: flex;
flex-direction: column;
border-radius: 0.1rem 0.1rem 0 0 !important;
}
/* 图片容器保持1:1比例 */
.advantage-card__img {
width: 100%;
aspect-ratio: 1 / 1; /* 1:1比例 */
object-fit: cover;
background-color: #f9f9f9;
display: block;
flex-shrink: 0;
}
/* 文字区域保持内边距和布局内部间距也调整为0.08rem */
.advantage-card__content {
width: 100%;
padding: 0.4rem 0.23rem 0.31rem 0.2rem; /* 上下内边距 */
gap: 0.08rem; /* 内部元素间距设计稿8px=0.08rem */
}
/* 标题容器间距设为0.08rem8px */
.advantage-card__heading-wrap {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.08rem; /* 设计稿8px=0.08rem */
width: 100%;
}
/* 卡片标题:字体大小调整 */
.advantage-card__heading {
font-size: 0.34rem;
font-weight: 600;
color: #101010;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; /* 强制不换行 */
overflow: hidden; /* 超出隐藏 */
text-overflow: ellipsis; /* 显示省略号 */
}
/* 描述文字样式 */
.advantage-card__description {
font-size: 0.24rem;
color:#666666;
margin-top: 0.08rem; /* 与标题间距设计稿8px=0.08rem */
white-space: nowrap; /* 强制不换行 */
overflow: hidden; /* 超出隐藏 */
text-overflow: ellipsis; /* 显示省略号 */
}
/* 箭头大小 */
.card-arrow {
transition: transform 0.3s ease;
display: inline-flex;
align-items: center;
justify-content: center;
width: 0.33rem;
height: 0.33rem;
}
/* 卡片hover效果 */
/* .advantage-card:hover {
transform: scale(1.03);
} */
/* 箭头hover位移 */
.advantage-card:hover .card-arrow {
transform: translateX(0.03rem);
}

View File

@@ -0,0 +1,11 @@
.prodline-footer-box{
width: 100%;
/* padding: 3rem 0; */
}
.prodline-footer-box-img {
width: 93.5%;
margin: 0 auto;
}
.prodline-footer-box-img img {
width: 100%;
}

View File

@@ -0,0 +1,165 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* 1. 根字体适配限制最小根字体为14px从源头避免文字过小 */
/* html {
font-size: 16px;
} */
/* 平板端768px~1023px15px→16px过渡最小15px */
@media (max-width: 1024px) and (min-width: 768px) {
/* html {
font-size: calc(15px + (16 - 15) * (100vw - 768px) / (1023 - 768));
} */
html body {
margin: 0 !important;
padding: 0 !important;
width:100vw !important;
max-width: 100vw !important;
}
}
/* 移动端320px~767px固定14px不随屏幕缩小而变小避免文字<12px */
@media (max-width: 767px) {
/* html {
font-size: 14px;
} */
html body {
margin: 0 !important;
padding: 0 !important;
width:100vw !important;
max-width: 100vw !important;
}
}
/* 超小屏≤320px仍固定14px彻底杜绝文字过小 */
@media (max-width: 320px) {
/* html {
font-size: 14px;
} */
html body {
margin: 0 !important;
padding: 0 !important;
width:100vw !important;
max-width: 100vw !important;
}
}
body {
background: rgb(242, 243, 245);
/* margin:0 !important; */
}
a {
text-decoration: none;
display: block;
}
.header {
width: 100%;
background: #fff;
height: 60px;
display: flex;
align-items: center;
}
.header-img {
margin: 0 auto;
width: 90%;
display: flex;
align-items: center;
}
/* 强制设置根元素font-size优先级最高!important确保覆盖所有冲突 */
html {
font-size: inherit !important; /* 继承内联样式的50px而非浏览器默认值 */
-webkit-text-size-adjust: none !important; /* 禁止iOS自动调整字体大小 */
}
.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.7rem;
padding-right: 0.2rem;
padding-top: 0;
}
.oircoEgapp-foot .m_footer .right {
max-width: 50%;
}

View File

@@ -0,0 +1,79 @@
/* 蒙版样式 - 新增触摸事件禁止 */
.mask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
display: none;
justify-content: center;
align-items: center;
z-index: 9999;
overflow: hidden; /* 阻止蒙版自身滚动 */
touch-action: none; /* 禁止触摸行为 */
pointer-events: auto; /* 确保蒙版能接收事件 */
}
/* 蒙版内容容器 - 新增触摸事件传递控制 */
.mask-content {
width: 80%;
height: 100%;
background: rgb(242, 243, 245);
border-radius: 12px;
overflow: hidden; /* 内容容器不滚动 */
position: relative;
animation: popIn 0.3s ease;
max-height: 90vh;
display: flex;
flex-direction: column;
pointer-events: auto; /* 确保内容区域能正常交互 */
}
/* 滚动内容容器 - 保持不变 */
.mask-scroll-content {
flex: 1;
overflow-y: auto;
padding: 20px;
-webkit-overflow-scrolling: touch; /* 移动端顺滑滚动 */
}
/* 升级:同时禁止 html 和 body 滚动(关键兼容) */
.no-scroll {
overflow: hidden !important;
position: fixed !important;
width: 100% !important;
height: 100% !important;
}
/* 其他原有样式保持不变 */
@keyframes popIn {
from {
transform: scale(0.8);
opacity: 0;
}
to {
transform: scale(1);
opacity: 1;
}
}
.close-btn {
position: absolute;
top: 20px;
right: 20px;
width: 40px;
height: 40px;
background-color: rgba(0, 0, 0, 0.3);
border-radius: 50%;
color: #fff;
font-size: 20px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
transition: background-color 0.3s ease;
z-index: 10;
}
.close-btn:hover {
background-color: #ff4d4f;
}

View File

@@ -0,0 +1,27 @@
.more {
width: 93.5%;
margin: 0 auto;
display: flex;
justify-content: center;
padding-top: 0.33rem;
}
.more:nth-child(5) {
padding-top: 0.33rem;
padding-bottom: 0.79rem;
}
.more-img {
background: #000;
color: #fff;
font-size: 0.21rem;
width: 1.54rem;
height: 0.5rem;
display: flex;
justify-content: center;
align-items: center;
border-radius: 0.5rem;
}
.line {
width: 100%;
height:0.14rem;
}

View File

@@ -0,0 +1,43 @@
/* 设计稿750px → 1rem=100px所有尺寸按设计稿÷100换算 */
.nav-box {
display: flex;
justify-content: space-around;
width: 93.5%;
margin: 0 auto;
background-color: #fff;
border-radius: 3.125rem; /* 设计稿312.5px */
box-shadow: 0 0.125rem 0.9375rem rgba(0, 0, 0, 0.05); /* 设计稿12.5px/93.75px */
position: relative;
z-index: 1;
overflow: visible;
padding: 0 0.42rem; /* 设计稿42px左右内边距取中间值 */
/* min-height: fit-content; */
/* height:0.86rem; */
box-sizing: border-box;
padding-bottom: 0.2rem;
}
.nav-item {
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
flex: 1;
margin-top: -0.5rem;
text-align: center;
align-self: flex-start;
}
.nav-item img {
width: 0.94rem; /* 设计稿80px示例图片尺寸可按实际调整 */
height: 0.94rem;
margin-bottom: 0.15rem; /* 设计稿10px图片与文字间距 */
}
.nav-item p {
font-size: 0.22rem; /* 设计稿16px文字大小 */
margin: 0;
}

View File

@@ -0,0 +1,149 @@
/* 设计稿750px → 1rem=100px所有尺寸按设计稿÷100换算 */
.product-box {
background: #fff;
padding-top: 0.93rem;
}
.product-title {
width: 93.5%;
margin: 0 auto;
padding-bottom: 0.83rem;
}
.product-title-h2 {
font-size: 0.46rem;
}
.product-title-p {
font-size: 0.24rem;
color: #646464;
margin-top: 0.21rem;
}
/* 容器布局:改为上下结构(右侧在上,左侧在下) */
.product-container {
display: flex;
flex-direction: column-reverse;
gap: 0.1rem; /* 上下间距 */
margin: 0 auto;
width: 93.5%;
align-items: stretch; /* 宽度铺满 */
}
/* 右侧容器:移到上方 */
.product-right {
flex: none; /* 取消flex比例自适应高度 */
position: relative;
border-radius: 0.1rem;
overflow: hidden;
width: 100%;
background-color: #f5f5f5;
min-height: 1.94rem;
aspect-ratio: 16/9;
}
/* 左侧容器:移到下方 */
.product-left {
flex: none; /* 取消flex比例自适应高度 */
position: relative;
width: 100%;
}
.product-img {
width: 100%;
height: auto;
border-radius: 0.1rem;
display: block;
}
/* 第二个产品:悬浮图位置调整(适配下方布局) */
.product-img-2 {
top: auto; /* 取消顶部定位 */
bottom: -0.8rem; /* 底部超出 */
transform: none;
width: 1.08rem;
position: absolute;
right: 0;
}
.right-content {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
transition: opacity 0.3s ease;
}
.right-video {
display: none;
}
.video-play-btn {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: none;
border: none;
cursor: pointer;
opacity: 0;
transition: opacity 0.3s ease;
z-index: 2;
display: none;
}
.play-icon {
display: inline-block;
}
.pause-icon {
display: none;
}
.video-play-btn.paused .play-icon {
display: none;
}
.video-play-btn.paused .pause-icon {
display: inline-block;
}
.right-video[playing] ~ .video-play-btn,
.product-right:hover .video-play-btn {
opacity: 1;
display: block;
}
/* 悬浮图容器:适配下方布局 */
.product-img-hover {
width: auto;
position: absolute;
right: 0;
bottom: 0;
z-index: 33;
}
.right {
right: -0.3rem;
}
/* 图片尺寸统一用rem */
.img1, .img2, .img3, .img4, .img5 {
width: 3.56rem;
max-width: 3.56rem;
}
.img1 {
max-width: 2.76rem;
}
.img2 {
max-width: 2.7rem;
}
.img3 {
max-width: 2.84rem;
}
.img4 {
max-width: 2.5rem;
}
.img5 {
max-width: 2.68rem;
}

View File

@@ -0,0 +1,206 @@
.product-card-container2 {
display: flex;
flex-wrap: nowrap;
gap: 10px;
align-items: stretch;
}
/* 产品卡片样式 */
.product-card2 {
box-sizing: border-box;
background: rgb(242, 243, 245);
border-radius: 8px;
cursor: pointer;
flex: 1 1 50%;
/* 一行2个 */
min-width: 180px;
/* 保证图片显示 */
/* max-width: calc(50% - 10px); */
/* 适配gap */
height: 240px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
display: flex;
text-decoration: none;
transition: transform 0.3s ease, box-shadow 0.3s ease;
overflow: hidden;
}
/* 核心修改:文字区域相对于父盒子居中,内部内容左对齐 */
.product-text2 {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
/* 文字区域整体水平居中相对于product-card1 */
justify-content: center;
/* 文字区域整体垂直居中相对于product-card1 */
text-align: left;
/* 内部文字左对齐 */
min-width: 70px;
box-sizing: border-box;
width: 100%;
}
/* 内部内容容器:统一承载标题、描述、链接,确保左对齐一致性 */
.product-text-content2 {
width: 100%;
/* 继承product-text的宽度确保左对齐范围完整 */
max-width: 280px;
/* 新增限制最大宽度避免PC端父容器过宽时内容排版松散 */
}
/* 标题:超出一行显示省略号(左对齐) */
.product-card-title2 {
font-size: clamp(16px, 2vw, 19px);
font-weight: 600;
color: #333;
margin-bottom: 5px;
letter-spacing: 0.2px;
/* 超出一行省略号核心样式 */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
/* 基于内部容器左对齐,省略号生效 */
}
/* 描述超出2行显示省略号左对齐 */
.product-card-desc2 {
font-size: clamp(12px, 1.8vw, 14px);
color: #656565;
margin-bottom: 15px;
letter-spacing: 0.1px;
/* 超出2行显示省略号核心样式 */
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
white-space: normal;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
/* 基于内部容器左对齐 */
line-height: 1.4;
/* 优化行高2行高度适中 */
}
/* 图片容器:确保移动端显示 */
.product-card-img2 {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
min-width: 70px;
/* 强制保留图片区域,避免被挤压 */
}
.product-card-img2 img {
width: 100%;
height: auto;
max-height: 144px;
min-height: 80px;
object-fit: contain;
/* 保持图片比例完整,不拉伸 */
}
/* 链接图标:左对齐(基于内部容器) */
.product-card-link2 {
width: 100%;
display: flex;
justify-content: flex-start;
/* 图标左对齐 */
}
.product-card-link2 img {
width: clamp(60px, 4vw, 76px);
margin: 0;
/* 清除居中margin */
}
/* hover效果 */
.product-card2:hover {
transform: scale(1.03);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.12);
}
/* 媒体查询平板端768px ~ 1023px */
@media (max-width: 1023px) and (min-width: 768px) {
.product-card2 {
height: 224px;
min-width: 170px;
}
.product-text2 {
padding-left: 20px;
}
.product-card-img2 img {
max-height: 128px;
}
}
/* 媒体查询移动端≤767px */
@media (max-width: 767px) {
.product-card-box2 {
margin-top: 19px;
}
.product-card2 {
padding: 0 8px;
}
.product-card-container2 {
gap: 8px;
}
.product-card2 {
height: 208px;
min-width: 160px;
}
.product-card-img2 img {
max-height: 120px;
min-height: 72px;
}
}
/* 媒体查询小屏手机≤375px */
@media (max-width: 375px) {
.product-card2 {
height: 192px;
min-width: 140px;
}
/* 强制文字最小12px保证可读性 */
.product-card-title2,
.product-card-desc2 {
font-size: 12px;
}
.product-card-img2 img {
max-height: 104px;
min-height: 64px;
}
.product-card2 {
padding: 0 5px;
}
.product-card-link2 img {
width: 40px;
/* 固定图标尺寸,节省空间 */
}
}
/* 媒体查询超小屏手机≤320px */
@media (max-width: 320px) {
.product-card2 {
min-width: 120px;
}
.product-text2 {
padding: 0 5px;
}
.product-card-img2 {
min-width: 60px;
/* 缩小图片区域最小宽度,平衡文字空间 */
}
}

View File

@@ -0,0 +1,124 @@
/* 设计稿750px → 1rem=100px所有尺寸按设计稿÷100换算 */
/* 容器布局:通用基础样式 */
.product-card-box {
width: 93.5%;
margin: 0.12rem auto 0;
padding: 0;
}
.product-card-container {
width: 100%;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
overflow: visible !important;
height: auto !important;
gap: 0.12rem; /* 间距调整为0.12rem */
justify-content: space-between; /* 两端对齐,确保铺满 */
align-items: flex-start;
}
/* 卡片包裹容器强制一行2个并铺满 */
.product-card-wrap {
display: block !important;
width: calc(50% - 0.06rem) !important; /* 50%宽度 - 间距的一半0.12rem/2=0.06rem */
height: auto !important;
margin: 0 !important; /* 移除额外margin */
}
/* 卡片核心:通用样式 */
.product-card {
background: rgb(242, 243, 245);
cursor: pointer;
width: 100% !important;
flex: none;
box-shadow: 0 0.1125rem 0.4rem rgba(0, 0, 0, 0.05);
margin: 0 !important;
box-shadow: 0 0.05rem 0.15rem rgba(0, 0, 0, 0.08); /* 包裹容器阴影 */
display: flex;
flex-direction: column;
height: auto !important;
transition: transform 0.3s ease;
border-radius: 0.07rem;
}
/* 卡片hover效果通用 */
.product-card:hover {
transform: scale(1.02);
}
/* 图片容器:通用样式 */
.product-card-img {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
flex: 0 0 auto;
aspect-ratio: 3 / 2.8;
overflow: hidden;
}
/* 产品图片:通用样式 */
.product-card img {
width: 100%;
height: 100%;
object-fit: contain;
object-position: center;
}
/* 文字容器:通用样式(居中对齐) */
.product-card-text {
flex: 1 1 auto;
display: flex;
flex-direction: column;
justify-content: center;
height: auto !important;
align-items: center;
text-align: center;
}
/* 标题样式:通用 */
.product-card-title {
font-size: 0.3rem;
font-weight: 600;
color: #333;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
height: auto !important;
margin-bottom: 0.21rem;
}
/* 描述样式通用2行截断 */
.product-card-desc {
font-size: 0.24rem;
color: #656565;
word-break: break-word;
height: auto !important;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
line-height: 1.4;
}
/* 链接图标容器:通用样式(居中) */
.product-card-link {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
flex: 0 0 auto;
padding: 0.35rem 0 0.4rem;
height: auto !important;
text-align: center;
}
/* 链接图标:通用样式 */
.product-card-link img {
width: 1.54rem;
height: auto;
object-fit: contain;
}

View File

@@ -0,0 +1,75 @@
.swiper-container {
padding: 0 !important;
}
/* 轮播容器 - 核心:基于视口高度自适应 */
.auto-swiper-container {
width: 100%;
/* 关键:高度 = 视口高度的百分比可调整如60vh=屏幕高度60% */
margin-bottom:1.5rem;
/* max-height: 900px; */
min-height: 300px;
position: relative;
margin-top:60px;
}
/* 轮播项 - 填充容器高度 */
.auto-swiper-slide {
width: 100%;
/*height: 100%;*/
display: flex;
align-items: center;
justify-content: center;
}
/* 图片自适应核心:填充屏幕比例高度,保持比例 */
.auto-swiper-slide img {
width: 100%;
height: 100%;
object-fit: contain; /* 替换 cover 为 contain完整显示图片 */
display: block;
}
/* 轮播容器保持相对定位 */
.auto-swiper-container {
position: relative;
width: 100%;
}
/* 轮播容器保持相对定位 */
.auto-swiper-container {
position: relative;
width: 100%;
}
/* 指示标容器:居中排列 */
.swiper-pagination {
position: absolute;
bottom: 10%; /* 距离底部的距离,可调整 */
left: 50%;
transform: translateX(-50%);
/* width:100%;
display: flex; */
/* justify-content: center; */
z-index: 10;
}
/* 激活状态:白色长条 */
.swiper-pagination-bullet-active {
background:#fff !important;
}
/* 未激活状态:黑色透明圆点(可调整透明度) */
.swiper-pagination-bullet {
display: inline-block;
width: 16px !important;
height: 16px !important;
border-radius: 8px;
/*background: #555;*/
margin: 0 5px;
/*opacity: 0.8;*/
border: 1px solid #fff;
/*cursor: pointer;*/
}

BIN
public/static/index/mobile/fonts/HarmonyOS_Sans_SC_Black.ttf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/static/index/mobile/fonts/HarmonyOS_Sans_SC_Bold.ttf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/static/index/mobile/fonts/HarmonyOS_Sans_SC_Light.ttf (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/static/index/mobile/fonts/HarmonyOS_Sans_SC_Thin.ttf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/static/index/mobile/fonts/Metropolis-Black.otf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/static/index/mobile/fonts/Metropolis-BlackItalic.otf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/static/index/mobile/fonts/Metropolis-Bold.otf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/static/index/mobile/fonts/Metropolis-BoldItalic.otf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/static/index/mobile/fonts/Metropolis-ExtraBold.otf (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
public/static/index/mobile/fonts/Metropolis-ExtraLight.otf (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
public/static/index/mobile/fonts/Metropolis-Light.otf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/static/index/mobile/fonts/Metropolis-LightItalic.otf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/static/index/mobile/fonts/Metropolis-Medium.otf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/static/index/mobile/fonts/Metropolis-MediumItalic.otf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/static/index/mobile/fonts/Metropolis-Regular.otf (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
public/static/index/mobile/fonts/Metropolis-SemiBold.otf (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
public/static/index/mobile/fonts/Metropolis-Thin.otf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/static/index/mobile/fonts/Metropolis-ThinItalic.otf (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

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: Montserrat-Bold, Montserrat;
font-family: Metropolis-Bold, Metropolis;
margin-top: 2rem;
width: 90%;
margin-left: 5%;
@@ -75,7 +75,7 @@
width: 80%;
font-size: 0.875rem;
color: #707070;
font-family: Montserrat-Medium, Montserrat;
font-family: Metropolis-Medium, Metropolis;
margin-top: 1.375rem;
margin-left: 10%;
}
@@ -93,7 +93,7 @@
line-height: 2em;
margin-bottom: 2%;
font-weight: 600;
font-family: Montserrat-Bold, Montserrat;
font-family: Metropolis-Bold, Metropolis;
}
.orico_Page_productxc .productxcMain .culture_vision .swt-Container {
width: 80%;
@@ -138,14 +138,14 @@
color: #101010;
line-height: 2em;
margin-bottom: 2%;
font-family: Montserrat-Bold, Montserrat;
font-family: Metropolis-Bold, Metropolis;
margin-right: 10%;
}
.orico_Page_productxc .productxcMain .culture_vision .swt-Container .swt-Table .Table-Row .right .des {
font-size: 16px;
color: #737373;
line-height: 1.6rem;
font-family: Montserrat-Medium, Montserrat;
font-family: Metropolis-Medium, Metropolis;
}
.orico_Page_productxc .productxcMain .culture_vision .swt-Container .swt-Table .Table-Row .Table-Cell {
display: table-cell;
@@ -159,7 +159,7 @@
font-size: 1rem;
color: #737373;
line-height: 1.6rem;
font-family: Montserrat-Medium, Montserrat;
font-family: Metropolis-Medium, Metropolis;
}
.orico_Page_productxc .productxcMain .culture_vision .swt-Container .culture_vision_02 .des,
.orico_Page_productxc .productxcMain .culture_vision .swt-Container .culture_vision_02 .subtitle {

View File

@@ -30,7 +30,7 @@
}
.orico_Page_introduction .introductionMain .iotbpage .iotb_bgw .iotbt1 {
font-size: 32px;
font-family: Montserrat-Bold, Montserrat;
font-family: Metropolis-Bold, Metropolis;
padding-bottom: 65px;
padding-top: 88px;
font-weight: 700;
@@ -57,14 +57,14 @@
}
.orico_Page_introduction .introductionMain .iotbpage .iotb_bgw .iotb_part1 .iotb_p1_item .iotbtp1 {
font-size: 18px;
font-family: Montserrat-Bold, Montserrat;
font-family: Metropolis-Bold, Metropolis;
font-weight: bold;
padding-bottom: 18px;
}
.orico_Page_introduction .introductionMain .iotbpage .iotb_bgw .iotb_part1 .iotb_p1_item .iotbts1 {
text-align: center;
font-size: 16px;
font-family: Montserrat-Medium, Montserrat;
font-family: Metropolis-Medium, Metropolis;
color: #9e9e9f;
}
.orico_Page_introduction .introductionMain .iotb_part2 {
@@ -78,7 +78,7 @@
}
.orico_Page_introduction .introductionMain .iotb_part2 .iotbt1 {
font-size: 32px;
font-family: Montserrat-Bold, Montserrat;
font-family: Metropolis-Bold, Metropolis;
padding-bottom: 65px;
padding-top: 88px;
font-weight: 700;

View File

@@ -30,7 +30,7 @@
height: 11.25rem;
line-height: 11.25rem;
font-size: 2rem;
font-family: Montserrat-Bold, Montserrat;
font-family: Metropolis-Bold, Metropolis;
font-weight: bold;
color: #000000;
text-align: center;
@@ -52,7 +52,7 @@
.orico_Page_achievement .achievementMain .achInfo .achNums .achive_shuju .title1 {
margin-top: 2.5rem;
font-size: 2rem;
font-family: Montserrat-Bold, Montserrat;
font-family: Metropolis-Bold, Metropolis;
font-weight: bold;
color: #000000;
}
@@ -62,7 +62,7 @@
.orico_Page_achievement .achievementMain .achInfo .achNums .achive_shuju .subtitle1 {
margin-top: 1rem;
font-size: 1.125rem;
font-family: Montserrat-Regular, Montserrat;
font-family: Metropolis-Regular, Metropolis;
font-weight: 400;
color: #707070;
}
@@ -71,7 +71,7 @@
height: auto;
position: relative;
background: #f2f2f2;
font-family: Montserrat;
font-family: Metropolis;
padding-bottom: 10%;
}
.orico_Page_achievement .achievementMain .achTimes .timecontent {
@@ -83,7 +83,7 @@
height: 11.25rem;
line-height: 11.25rem;
font-size: 2rem;
font-family: Montserrat-Bold, Montserrat;
font-family: Metropolis-Bold, Metropolis;
font-weight: bold;
color: #000000;
text-align: center;
@@ -142,7 +142,7 @@
background: url(/static/index/pc/images/greyyuandian.png) 3px 3px no-repeat;
height: 2.375rem;
font-size: 1.25rem;
font-family: Montserrat-Bold, Montserrat;
font-family: Metropolis-Bold, Metropolis;
font-weight: bold;
color: #000000;
line-height: 1.875rem;
@@ -153,7 +153,7 @@
.orico_Page_achievement .achievementMain .achTimes .timecontent .timelist .timeline-con .con_event_list .event_list div li {
display: inline-block;
width: 94%;
font-family: Montserrat-Medium, Montserrat;
font-family: Metropolis-Medium, Metropolis;
line-height: 1.5625rem;
font-size: 1rem;
font-weight: 500;
@@ -181,7 +181,7 @@
height: 11.25rem;
line-height: 11.25rem;
font-size: 2rem;
font-family: Montserrat-Bold, Montserrat;
font-family: Metropolis-Bold, Metropolis;
font-weight: bold;
color: #000000;
text-align: center;
@@ -211,7 +211,7 @@
margin-left: 4.0625rem;
margin-top: 2.5rem;
font-size: 1.75rem;
font-family: Montserrat-Bold, Montserrat;
font-family: Metropolis-Bold, Metropolis;
font-weight: bold;
color: #000000;
line-height: 1.625rem;
@@ -220,7 +220,7 @@
margin-left: 65px;
width: 80%;
font-size: 16px;
font-family: Montserrat-Medium, Montserrat;
font-family: Metropolis-Medium, Metropolis;
font-weight: 500;
color: #707070;
line-height: 26px;

View File

@@ -52,10 +52,10 @@
font-weight: 600;
color: #000000;
line-height: 20px;
font-family: Montserrat-Bold, Montserrat;
font-family: Metropolis-Bold, Metropolis;
}
.orico_Page_brand .brandMain .our_brand_con .our_brand_bg .vtext .Table-Cell p {
font-family: Montserrat-Medium, Montserrat;
font-family: Metropolis-Medium, Metropolis;
font-size: 14px;
color: #707070;
line-height: 22px;
@@ -100,17 +100,17 @@
margin-top: 2.5rem;
}
.orico_Page_brand .brandMain .dis_bril_bg .dis_bril_con .title p {
font-family: Montserrat-Bold, Montserrat;
font-family: Metropolis-Bold, Metropolis;
}
.orico_Page_brand .brandMain .dis_bril_bg .dis_bril_con .subtitle {
width: 80%;
font-size: 0.875rem;
color: #707070;
font-family: Montserrat-Medium, Montserrat;
font-family: Metropolis-Medium, Metropolis;
margin-top: 2.5rem;
margin-left: 10%;
}
.orico_Page_brand .brandMain .dis_bril_bg .dis_bril_con .subtitle p {
font-family: Montserrat-Medium;
font-family: Metropolis-Medium;
line-height: 22px;
}

Some files were not shown because too many files have changed in this diff Show More