239 Commits

Author SHA1 Message Date
de87a4b237 font 2025-12-01 15:33:55 +08:00
32ab01bfb8 refactor: 专题 - 电力品线
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 5s
2025-11-28 16:23:21 +08:00
30f4f0761a footer
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 5s
2025-11-28 15:45:20 +08:00
df2ccc288c refactor: 专题 - 电力品线
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 5s
2025-11-28 15:36:12 +08:00
d5acd5a025 refactor: 专题 - 电力品线
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 6s
2025-11-28 15:23:29 +08:00
39cd6137b3 refactor: 专题 - 电力品线
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 4s
2025-11-28 14:51:30 +08:00
8f03cb8f99 feat: 添加电力品线专题url
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 5s
2025-11-28 14:43:17 +08:00
5a1d69a836 电力
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 4s
2025-11-28 14:18:19 +08:00
de0f1f34ce 尺寸调整
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 4s
2025-11-27 18:38:58 +08:00
6af605bc6f 修复bug
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 5s
2025-11-27 09:42:18 +08:00
362a7f5a65 refactor: 专题 - 电力品线 修改
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 4s
2025-11-26 17:46:09 +08:00
dafeb04f65 refactor: 专题 - 电力品线 mobile 修改
Some checks failed
Gitea Actions Official-website / deploy-dev (push) Failing after 5s
2025-11-26 17:29:45 +08:00
7b5cac6874 refactor: 删除gitea webhook文件
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 4s
2025-11-25 17:45:32 +08:00
4942e5d78e refactor: migration文件添加banner简称相关
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 5s
2025-11-25 17:43:09 +08:00
b35f1f9ed4 refactor: .gitignore
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 2s
2025-11-25 17:38:57 +08:00
7a987cd672 refactor: 专题 - 电力品线
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 3s
2025-11-25 17:36:09 +08:00
7c87ea07ed refactor: 专题 - 电力品线mobile端
Some checks failed
Gitea Actions Official-website / deploy-dev (push) Failing after 3s
2025-11-25 16:15:42 +08:00
45aaa0c35e refactor: 专题 - 电力品线pc端
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 4s
2025-11-25 14:56:57 +08:00
23aed15ada refactor: banner加入"banner简称"问题修改
Some checks failed
Gitea Actions Official-website / deploy-dev (push) Failing after 7s
2025-11-25 14:05:01 +08:00
325fab3d27 refactor: .gitignore
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 5s
2025-11-25 14:01:08 +08:00
5c1f4a0a73 feat: banner添加/编辑时加入“banner简称”字段
Some checks failed
Gitea Actions Official-website / deploy-dev (push) Failing after 4s
2025-11-25 14:00:06 +08:00
fa4dcf313a refactor: 主题 - 电力品线
Some checks failed
Gitea Actions Official-website / deploy-dev (push) Failing after 4s
2025-11-25 13:48:59 +08:00
1c098304f9 feat: 添加dev-ci.yaml
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 5s
2025-11-24 15:43:38 +08:00
c72cfa2e43 feat: 专题 - 电力品线首页 2025-11-20 14:29:30 +08:00
fec6dca03d refactor: 修改.gitignore 2025-11-20 11:00:35 +08:00
fdb673d174 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-09-19 15:22:25 +08:00
6daac314dd 1 2025-09-19 15:22:22 +08:00
ouzhiqiang
9d8e22d270 修改分类 2025-09-19 15:14:55 +08:00
ouzhiqiang
f154f3ddf6 修改分类 2025-09-19 14:59:45 +08:00
ouzhiqiang
2073a27ef7 修改分类 2025-09-19 14:48:10 +08:00
ouzhiqiang
e301fc7e94 修改分类 2025-09-19 14:47:05 +08:00
ouzhiqiang
f9251d944e 修改分类 2025-09-19 14:36:08 +08:00
ouzhiqiang
1e6187801d Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-09-19 14:32:27 +08:00
ouzhiqiang
346dcebba3 修改分类 2025-09-19 14:31:56 +08:00
ab7b23e5d1 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-09-19 14:13:56 +08:00
325221bd67 1 2025-09-19 14:13:53 +08:00
ouzhiqiang
721e91dc31 修改分类 2025-09-19 11:37:41 +08:00
ouzhiqiang
12e51c6f46 修改分类 2025-09-19 11:22:25 +08:00
ouzhiqiang
8ba9006173 修改分类 2025-09-19 11:17:49 +08:00
ouzhiqiang
a7d413871b 修改分类 2025-09-19 11:09:29 +08:00
ouzhiqiang
ce6a882c17 修改分类 2025-09-19 10:41:41 +08:00
ouzhiqiang
7e7cfeacbc 修改分类 2025-09-19 10:36:26 +08:00
ouzhiqiang
e1961d2a83 修改分类 2025-09-19 10:29:25 +08:00
ouzhiqiang
d313617e2b 修改分类 2025-09-19 10:23:02 +08:00
ouzhiqiang
f0c82c848f 修改分类 2025-09-19 10:04:47 +08:00
ouzhiqiang
f606dc64a5 修改分类 2025-09-19 09:53:40 +08:00
ouzhiqiang
39dc3c4e1a 修改分类 2025-09-19 09:51:29 +08:00
ouzhiqiang
52b265f36e Merge branch 'ozq-dev' into dev 2025-09-18 17:50:21 +08:00
ouzhiqiang
5f9fb74696 修改分类 2025-09-18 17:50:05 +08:00
ouzhiqiang
b251c78b2f Merge branch 'ozq-dev' into dev 2025-09-18 17:47:43 +08:00
ouzhiqiang
2e1c83d46d 修改分类 2025-09-18 17:47:22 +08:00
ouzhiqiang
0265cb0629 Merge branch 'ozq-dev' into dev 2025-09-18 17:23:25 +08:00
ouzhiqiang
68d66b2925 修改分类 2025-09-18 17:23:07 +08:00
ouzhiqiang
601403bf3e Merge branch 'ozq-dev' into dev 2025-09-18 17:16:43 +08:00
ouzhiqiang
bbe2197b38 修改分类 2025-09-18 17:16:24 +08:00
ouzhiqiang
ee955a3674 Merge branch 'ozq-dev' into dev 2025-09-18 17:13:22 +08:00
ouzhiqiang
e45df84312 修改分类 2025-09-18 17:13:04 +08:00
ouzhiqiang
4e0891da97 Merge branch 'ozq-dev' into dev 2025-09-18 17:04:44 +08:00
ouzhiqiang
f9b895732e 修改分类 2025-09-18 17:04:29 +08:00
ouzhiqiang
e72ecd55f4 Merge branch 'ozq-dev' into dev 2025-09-18 17:01:25 +08:00
ouzhiqiang
558b418d18 修改分类 2025-09-18 17:01:08 +08:00
ouzhiqiang
78cbc5de6e Merge branch 'ozq-dev' into dev 2025-09-18 16:56:01 +08:00
ouzhiqiang
f7b610df72 修改分类 2025-09-18 16:55:47 +08:00
ouzhiqiang
b1522a365b Merge branch 'ozq-dev' into dev 2025-09-18 16:53:26 +08:00
ouzhiqiang
48906ec9cd 修改分类 2025-09-18 16:53:06 +08:00
ouzhiqiang
b57cb8dfd6 Merge branch 'ozq-dev' into dev 2025-09-18 16:49:16 +08:00
ouzhiqiang
7d70c55557 修改分类 2025-09-18 16:48:45 +08:00
ouzhiqiang
4fdda8435d Merge branch 'ozq-dev' into dev 2025-09-18 16:11:52 +08:00
ouzhiqiang
7a96809bfe 修改分类 2025-09-18 16:11:36 +08:00
ouzhiqiang
62b3e2798f Merge branch 'ozq-dev' into dev 2025-09-18 16:08:29 +08:00
ouzhiqiang
bfeac736ea 修改分类 2025-09-18 16:08:05 +08:00
ouzhiqiang
74ea50b7e4 Merge branch 'ozq-dev' into dev 2025-09-18 16:01:20 +08:00
ouzhiqiang
8a617c06e9 修改分类 2025-09-18 16:00:49 +08:00
ouzhiqiang
efa8acaf12 Merge branch 'ozq-dev' into dev 2025-09-18 15:39:28 +08:00
ouzhiqiang
d3ff726e90 修改分类 2025-09-18 15:38:59 +08:00
ouzhiqiang
7880c18e85 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-09-18 15:26:19 +08:00
ouzhiqiang
e80ba5ac7d 修改分类 2025-09-18 15:25:29 +08:00
20b5fd901b 1 2025-09-18 11:59:32 +08:00
e38c00f59c 1 2025-09-18 11:57:52 +08:00
a18706f7d4 分类补充 2025-09-18 11:56:48 +08:00
4ff2ee4a76 移动端帮助中心三级菜单 2025-09-18 11:52:52 +08:00
2ca708fd4a 帮助中心文档三级菜单 2025-09-18 11:21:50 +08:00
29761f551d Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-09-18 11:15:12 +08:00
fdb75e4888 feat: 添加open api client管理命令 2025-09-17 17:48:27 +08:00
5fde7159e0 Merge branch 'dev' 2025-08-26 14:53:55 +08:00
6068efa03f refactor: 去掉多余目录 2025-08-26 14:53:38 +08:00
738b293ea2 fix: 修复“检测文件地址并根据情况转换为文件系统地址”url为null情况报错问题 2025-08-26 14:53:17 +08:00
a1be105c31 Merge branch 'dev' 2025-08-08 09:18:33 +08:00
03374856e4 fix: 修复产品目录分类树数据问题 2025-08-08 09:18:13 +08:00
f07741ff19 Merge branch 'dev' 2025-08-07 17:08:12 +08:00
c64450d74c fix: admapi - 产品目录同步分类更新时bug修复 2025-08-07 17:07:52 +08:00
e462b38ff9 Merge branch 'dev' 2025-08-07 11:38:17 +08:00
b96021d21d Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-08-07 11:37:49 +08:00
12d6fdc3a6 style:底部样式修改 2025-08-07 11:36:56 +08:00
cd3f651a2a Merge branch 'dev' 2025-08-07 10:20:10 +08:00
1e4b416cac fix: mobile - 底部“联系我们”取值问题 2025-08-07 10:19:45 +08:00
e38446f3fd Merge branch 'dev' 2025-08-07 10:18:06 +08:00
06b9d42ae4 fix: mobile - 底部“联系我们”取值问题 2025-08-07 10:17:24 +08:00
99d78069d5 Merge branch 'dev' 2025-08-07 10:12:04 +08:00
342a3754aa fix: mobile - 底部“联系我们”取值问题 2025-08-07 10:03:50 +08:00
51e9c8ced1 Merge branch 'dev' 2025-08-06 15:35:50 +08:00
b13d481e1e perf openapi 图片地址拼接 2025-08-06 15:35:35 +08:00
da8f204167 Merge branch 'dev' 2025-08-06 12:45:49 +08:00
c1979da1af fix: 后台 - 修改各导出图片等文件地址拼接问题 2025-08-06 11:56:53 +08:00
1802f57906 fix: 后台 产品导出数据问题 2025-08-06 11:40:44 +08:00
3fa3b8fb63 fix: 后台 产品导出数据问题 2025-08-06 11:40:09 +08:00
fb2b1455bc fix: mobile下视频分类地址错误 2025-07-31 10:55:26 +08:00
cc497b2ebc fix: 获取文件系统磁盘未判断“//”情况 2025-07-31 09:03:49 +08:00
2b450a2e9c fix: 首页“场景介绍”无法点击 2025-07-31 09:03:48 +08:00
e266e89a97 1 2025-07-30 17:08:22 +08:00
2a94a7ecec 1 2025-07-30 17:07:37 +08:00
9137335ce3 1 2025-07-30 16:48:54 +08:00
b8946f223a 1 2025-07-30 16:47:15 +08:00
3a8440c2b9 1 2025-07-30 16:44:32 +08:00
c2bba7fb56 1 2025-07-30 16:40:36 +08:00
052570fefa Merge branch 'dev' 2025-07-30 16:33:15 +08:00
09b1f9f14c style:产品详情 2025-07-30 16:13:37 +08:00
37825f88ba .ql-editor 2025-07-30 15:43:42 +08:00
1c7434b591 .ql-editor 2025-07-30 15:42:52 +08:00
585da730ea style:产品详情样式 2025-07-30 15:35:16 +08:00
2ecc51d8a9 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-30 15:25:01 +08:00
ad7148ccfc style:详情样式 2025-07-30 15:24:58 +08:00
1e00db6c97 fix: 字段长度限制 2025-07-30 11:13:17 +08:00
5ed692a672 fix: 字段长度限制 2025-07-30 11:12:13 +08:00
5f7156470e Merge branch 'dev' 2025-07-29 17:52:13 +08:00
3aafcd3f3b refactor: 修改后台banner的“链接地址”长度限制为510 2025-07-29 17:51:56 +08:00
9b339d6364 Merge branch 'dev' 2025-07-29 16:48:16 +08:00
09f9bfd301 Merge branch 'dev' 2025-07-29 16:47:31 +08:00
910a07ea47 1 2025-07-29 14:16:51 +08:00
c27d529b82 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-29 14:14:29 +08:00
b6724c0361 视频宽度限制 2025-07-29 14:14:27 +08:00
d4fa15f671 文章视频限制 2025-07-29 14:13:34 +08:00
60229ae058 fix: migrations/seeds 2025-07-29 14:08:30 +08:00
6cf27d8b9c fix: 产品详情-分类路径bug 2025-07-29 12:00:22 +08:00
6ba7181e3f 文章详情样式调整 2025-07-28 14:50:26 +08:00
4334c2db66 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-28 14:34:41 +08:00
d7e93567d9 style:宽度调整 2025-07-28 14:25:01 +08:00
e19ba6a315 chore: composer.json 2025-07-28 11:13:56 +08:00
a8e7ad2430 perf: migrations/seeds 2025-07-28 10:33:44 +08:00
55c8762255 perf: 七牛云存储 2025-07-28 10:16:03 +08:00
43a4f5f706 refactor: .gitignore 2025-07-25 18:00:14 +08:00
c6cff2e97d refactor: 七牛云上传 2025-07-25 17:57:31 +08:00
5d53c26c5c 文章详情样式调整 2025-07-25 13:47:37 +08:00
857bb4ad21 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-24 10:00:18 +08:00
b3dfb8655b 1 2025-07-24 10:00:14 +08:00
10c1f86708 feat: 七牛云上传开发 2025-07-23 17:55:34 +08:00
62a67bf7a0 perf: 自定义语言检测中间件 2025-07-23 17:55:34 +08:00
4dc4932ac7 补充 2025-07-23 17:25:57 +08:00
b99c07ef4a .ql-editor 关于tab切换的样式同步 2025-07-23 17:20:11 +08:00
f8dc645048 样式修改 2025-07-22 16:48:22 +08:00
051b4ed7e7 Merge branch 'dev' 2025-07-21 17:32:36 +08:00
142e29f131 fix: pc 产品,附件,视频搜索去除首尾空格 2025-07-21 17:31:17 +08:00
7f58f1ff83 fix: pc 视频搜索 2025-07-21 16:55:06 +08:00
5650ccfb87 fix: pc 视频搜索 2025-07-21 16:54:43 +08:00
439c9073b8 Merge branch 'dev' 2025-07-19 10:48:27 +08:00
f78f164326 fix: 图片上传命名问题 2025-07-19 10:48:07 +08:00
5fb2abe818 Merge branch 'master' of https://gitea.f2b211.com/jsasg/orico-official-website 2025-07-18 15:19:02 +08:00
1f3b646495 1 2025-07-18 15:16:09 +08:00
a1ea5c6752 标题提取空过滤 样式修改 2025-07-18 15:15:13 +08:00
beb86140a6 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-18 14:42:10 +08:00
0d442fb63a Merge branch 'dev' 2025-07-18 14:40:20 +08:00
af139f6bf4 fix: nas 文章详情页分类排序问题 2025-07-18 14:40:02 +08:00
1d79ea5186 Merge branch 'master' of https://gitea.f2b211.com/jsasg/orico-official-website 2025-07-18 14:39:33 +08:00
de02e59b0e 1 2025-07-18 14:39:30 +08:00
f4fa5afcfa Merge branch 'dev' 2025-07-18 13:36:33 +08:00
2c40c95794 fix: 横幅分类不可小于0 2025-07-18 13:33:58 +08:00
70534f2a97 fix: nas帮助中心文件分类未排序 2025-07-18 12:36:20 +08:00
4515939fcf Achievement 2025-07-18 10:29:26 +08:00
b16971e6f1 nas_help_banner 格式修改 2025-07-18 10:16:58 +08:00
3840206e7c indeximg1 ,indeximg2压缩webp 2025-07-18 09:44:41 +08:00
ef1f786417 编辑器样式修改 2025-07-17 17:45:34 +08:00
745671bd33 1 2025-07-17 17:04:16 +08:00
a13ea053e3 1 2025-07-17 17:02:29 +08:00
0725cd779f 1 2025-07-17 17:01:17 +08:00
47caddad60 Merge branch 'master' of https://gitea.f2b211.com/jsasg/orico-official-website 2025-07-17 16:49:08 +08:00
5db4263f67 1 2025-07-17 16:49:03 +08:00
9887bd1045 Merge branch 'dev' 2025-07-17 16:43:24 +08:00
768e1ed786 perf: 优化openapi接口频率限制 2025-07-17 16:43:02 +08:00
f211f58068 1 2025-07-17 16:40:23 +08:00
e7e7386054 1 2025-07-17 16:35:38 +08:00
9c7f2d394b 1 2025-07-17 16:31:42 +08:00
a1f1716f5c 1还原 2025-07-17 16:27:14 +08:00
250f78593a 还原 2025-07-17 16:25:01 +08:00
2c0b8161a5 1 2025-07-17 16:22:28 +08:00
83fa83e00d 1 2025-07-17 16:18:57 +08:00
176b25b631 1 2025-07-17 16:11:01 +08:00
4b2566b762 ·1 2025-07-17 16:02:31 +08:00
a25f87de9f 1 2025-07-17 15:40:29 +08:00
ec6fa7fe77 1 2025-07-17 15:39:17 +08:00
0ba299ee05 1 2025-07-17 15:32:22 +08:00
d06002d95c 1 2025-07-17 15:30:43 +08:00
1758fb8995 格式化 2025-07-17 15:22:56 +08:00
52259d573c Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-17 15:20:55 +08:00
a680391d86 1 2025-07-17 15:19:56 +08:00
0e0ed64b38 1 2025-07-17 15:18:38 +08:00
5221b43c01 1 2025-07-17 15:13:01 +08:00
a373ee7163 1 2025-07-17 15:08:52 +08:00
07692a2a29 1 2025-07-17 12:00:46 +08:00
3c7bdd8ac9 Merge branch 'master' of https://gitea.f2b211.com/jsasg/orico-official-website 2025-07-17 11:49:33 +08:00
db3b704d89 1 2025-07-17 11:49:31 +08:00
6e3e0d59db fix: database/seeds 2025-07-17 11:44:00 +08:00
f8884aa736 1 2025-07-17 11:42:38 +08:00
8e62d95864 1 2025-07-17 11:30:52 +08:00
7bf88fd578 英文单词不换行 2025-07-17 10:48:37 +08:00
a4330c1216 1 2025-07-17 10:36:36 +08:00
6c80dbabeb 图片拉伸 2025-07-17 10:24:00 +08:00
e0009fb8fa .header-PC #header .nav3 .choesCountry 2025-07-17 10:19:09 +08:00
66da36a907 fix: database/seeds 2025-07-17 09:58:09 +08:00
702e874e08 1 2025-07-17 09:49:05 +08:00
7e486e463c Merge branch 'master' of https://gitea.f2b211.com/jsasg/orico-official-website 2025-07-17 09:45:12 +08:00
df482bbcdd .ql-editor>* 2025-07-17 09:45:07 +08:00
7651b056b6 feat: 后台管理 产品列表添加按添加时间倒序 2025-07-16 18:12:11 +08:00
877c8835d9 img {display: block;}注释 2025-07-16 17:44:55 +08:00
67865d64cd .narshelpCenterdetail-app .nhlpapp-search 2025-07-16 16:55:44 +08:00
699e55ffa1 Merge branch 'master' of https://gitea.f2b211.com/jsasg/orico-official-website 2025-07-16 16:53:03 +08:00
4ca9a84d14 移动端nas文章底部操作 2025-07-16 16:53:01 +08:00
ac5d0143ac fix: pc nas专题logo中文下要点击,英文下不要 2025-07-16 15:39:35 +08:00
6434d031ca fix: 产品分类排序 2025-07-16 15:32:38 +08:00
8f2dbf8798 fix: pc 产品详情添加型号 2025-07-16 15:24:22 +08:00
7a0c3af1e9 .ql-container 2025-07-16 14:51:07 +08:00
7879f7914b 文章样式 2025-07-16 14:45:33 +08:00
99a69bad5f Merge branch 'master' of https://gitea.f2b211.com/jsasg/orico-official-website 2025-07-16 14:14:05 +08:00
38783d80a0 1 2025-07-16 14:13:13 +08:00
b37ed217cd 1 2025-07-16 14:11:52 +08:00
dd687120cc 还原footer 2025-07-16 14:07:43 +08:00
004a007148 1 2025-07-16 14:02:32 +08:00
5018a59045 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-16 13:39:34 +08:00
8fa1399902 Merge branch 'dev' 2025-07-16 13:39:07 +08:00
e781887d16 fix: 产品目录同步产品默认在售 2025-07-16 13:38:54 +08:00
55d72124a0 Merge branch 'dev' 2025-07-16 11:52:05 +08:00
3eda90f2d1 fix: 后台管理 产品参数问题 2025-07-16 11:51:48 +08:00
6b815ea414 Merge branch 'dev' 2025-07-16 10:31:39 +08:00
df8001d43e fix: 产品搜索无数据语言问题 2025-07-16 10:31:14 +08:00
7f8ad55c97 pc编辑文本样式 2025-07-16 10:19:42 +08:00
14f0f1609e 添加编辑器样式 2025-07-16 10:17:58 +08:00
6c176a1039 1 2025-07-16 10:12:28 +08:00
bffe804a7b 1 2025-07-16 10:10:36 +08:00
a9beb0dda6 1 2025-07-16 10:04:54 +08:00
3c72fa125f 1 2025-07-16 10:02:47 +08:00
152 changed files with 8550 additions and 564 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,8 +54,15 @@ REFRESH_TOKEN_LIFETIME = 1209600; # 刷新令牌有效期
RESOURCE_IMAGES_DOMAIN = http://local.orico.com; # 图片资源服务器地址
RESOURCE_VIDEOS_DOMAIN = http://local.orico.com; # 视频资源服务器地址
# 视图模板规则配置
[VIEW_TPL]
# 七牛云存储配置
[QINUI]
BUCKET = orico
BASE_URL = http://local.orico.com
ACCESS_KEY = 1234567890
SECRET_KEY = 1234567890
# 前台视图模板规则配置
[INDEX_VIEW_TPL]
# 视图目录
# query 规则URL参数 mtpl=1 表示移动端访问
# 例如http://xxxx.com?mtpl=1
@@ -63,4 +77,20 @@ RULE_QUERY_VALUE = 1
RULE_DOMAIN_SCHEME[] = http
RULE_DOMAIN_SCHEME[] = https
# domain 规则域名
RULE_DOMAIN_HOST = mobile.orico.cn
RULE_DOMAIN_HOST = mobile.orico.cn
# 前台语言检测配置
[INDEX_LANG_DETECT]
# 是否启用域名检测方式来检测语言
DOMAIN_DETECT = true
# 域名规则
# 格式:域名=语言
# 例如mobile.orico.cn=zh-cn
DOMAIN_RULE[] = orico.cn=zh-cn
DOMAIN_RULE[] = orico.com.cn=zh-cn
DOMAIN_RULE[] = www.orico.cn=zh-cn
DOMAIN_RULE[] = www.orico.com.cn=zh-cn
DOMAIN_RULE[] = ow.f2b211.com=zh-cn
DOMAIN_RULE[] = orico.cc=en-us
DOMAIN_RULE[] = www.orico.cc=en-us
DOMAIN_RULE[] = ow.us.f2b211.com=en-us

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

11
.gitignore vendored
View File

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

24
.zed/settings.json Normal file
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"
]
}
}
}
}

View File

@@ -99,18 +99,20 @@ class ReceiveProductSync
}
$category = ProductCategoryModel::language($lang_id)->tcoId($tco_category['id'])->find();
$tco_parent = ProductTcoCategoryModel::language($lang_id)->tcoId($tco_category['tco_pid'])->find();
if (!empty($tco_parent)) {
$parent = ProductCategoryModel::language($lang_id)->tcoId($tco_parent['id'])->find();
if ($parent->isEmpty()) {
throw new \Exception('产品分类父级不存在');
if (!empty($category)) {
$tco_parent = ProductTcoCategoryModel::language($lang_id)->tcoId($tco_category['tco_pid'])->find();
if (!empty($tco_parent)) {
$parent = ProductCategoryModel::language($lang_id)->tcoId($tco_parent['id'])->find();
if ($parent->isEmpty()) {
throw new \Exception('产品分类父级不存在');
}
$category['pid'] = $parent['id'];
$category['path'] = $parent['path'] . $parent['pid'];
$category['level'] = $parent['level'] + 1;
}
if (!$category->save()) {
throw new \Exception('产品分类更新失败');
}
$category['pid'] = $parent['id'];
$category['path'] = $parent['path'] . $parent['pid'];
$category['level'] = $parent['level'] + 1;
}
if (!$category->save($category)) {
throw new \Exception('产品分类更新失败');
}
}
@@ -183,7 +185,7 @@ class ReceiveProductSync
'desc' => '',
'video_img' => '',
'video_url' => '',
'is_sale' => 0,
'is_sale' => 1,
'is_new' => 0,
'is_hot' => 0,
'is_show' => 0,

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',
@@ -208,7 +212,7 @@ class BannerItem
Log::error(sprintf('%s:%s %s', $th->getFile(), $th->getLine(), $th->getMessage()));
return error('操作失败');
}
return success('操作成功');
}
@@ -240,6 +244,7 @@ class BannerItem
'banner_name' => '分类名称',
'title' => '横幅名称',
'title_txt_color' => '横幅名称字体颜色',
'short_title' => '横幅简称',
'desc' => '描述',
'desc_txt_color' => '描述字体颜色',
'type' => '前台显示类型',
@@ -262,17 +267,16 @@ class BannerItem
// 获取导出数据
private function getBannerExportData()
{
$param = request()->param([
'title',
'banner_id',
'created_at'
]);
$server = request()->server();
$image_host = $server['REQUEST_SCHEME'] . "://" . $server['SERVER_NAME'] . '/';
$param = request()->param(['title', 'banner_id', 'created_at']);
return SysBannerItemModel::alias('item')
->field([
'item.id',
'banner.name' => 'banner_name',
'item.title',
'item.title_txt_color',
'item.short_title',
'item.desc',
'item.desc_txt_color',
'item.type',
@@ -311,7 +315,13 @@ class BannerItem
}
})
->order(['item.sort' => 'asc', 'item.id' => 'desc'])
->select();
->select()
->each(function($item) use($image_host) {
$item->image = !empty($item->image) ? url_join($image_host, $item->image) : '';
$item->extra_image = !empty($item->extra_image) ? url_join($image_host, $item->extra_image) : '';
$item->video = !empty($item->video) ? url_join($image_host, $item->video) : '';
return $item;
});
}
// 删除

View File

@@ -57,7 +57,7 @@ class Product
])
->categoryNullable($param['category_id']??null)
->isShowNullable(isset($param['is_show']) ? (bool)$param['is_show'] : null)
->order(['sort' => 'asc', 'id' => 'desc'])
->order(['sort' => 'asc', 'created_at' => 'desc', 'id' => 'desc'])
->paginate([
'list_rows' => $param['size'],
'page' => $param['page'],
@@ -171,7 +171,7 @@ class Product
// 更新产品参数
if ($put['params'] != "") {
ProductParamsModel::productId($id)->delete();
if (preg_match_all('/(\S+):(.[^\s]+)/', $put['params'], $match_result)) {
if (preg_match_all('/(.+):(.+)/', $put['params'], $match_result)) {
$params = [];
for ($i = 0; $i < count($match_result[0]); $i++) {
$params[] = [
@@ -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;
/**
* 文件上传控制器
@@ -71,7 +72,7 @@ class Upload
// 转换为webp格式
$webp = $image->toWebp(75);
$root = config('filesystem.disks.image.root');
$filename = $param['module'] . '/' . ($name_rule() ?? date('Ymd') . '/' . md5((string)time()) . '.webp');
$filename = $param['module'] . '/' . ($name_rule() ? $name_rule()() : date('Ymd') . '/' . md5((string)time() . random_str(8))) . '.webp';
$webp->save($this->checkPath($root . '/' . $filename));
// 获取webp文件大小
$file_size = $webp->size();
@@ -153,8 +154,8 @@ class Upload
$image_model = new SysImageUploadRecordModel();
$image_model->language_id = request()->lang_id;
$image_model->module = $param['module'];
$image_model->image_path = $filename;
$image_model->image_thumb = $thumb_filename;
$image_model->image_path = $storage . '/' . $filename;
$image_model->image_thumb = $storage . '/' . $thumb_filename;
$image_model->file_size = $file_size;
$image_model->file_type = $mime_type;
$image_model->file_md5 = $filemd5;
@@ -165,8 +166,8 @@ class Upload
}
return success('操作成功', [
'path' => $storage . '/' . $image_model->image_path,
'thumb_path' => $storage . '/' . $image_model->image_thumb,
'path' => $image_model->image_path,
'thumb_path' => $image_model->image_thumb,
'filemd5' => $image_model->file_md5,
'filesha1' => $image_model->file_sha1
]);
@@ -226,6 +227,7 @@ class Upload
'filename_keep' => (int)data_get($options, 'filename_keep.value', 0) == 1,
'filemd5_unique' => (int)data_get($options, 'filemd5_unique.value', 0) == 1,
'filetype_to' => data_get($options, 'filetype_to.value', 'original'),
'save_to' => data_get($options, 'save_to.value', 'local'),
];
}
/**
@@ -345,20 +347,35 @@ class Upload
// 获取视频上传配置
list(
'filename_keep' => $filename_keep,
'filemd5_unique' => $filemd5_unique
'filemd5_unique' => $filemd5_unique,
'save_to' => $save_to,
) = $this->getUploadOptions('upload_video');
// 是否需要根据文件MD5值检查文件是否已存在
$video = $filemd5_unique ? SysVideoUploadRecordModel::md5($filemd5)->find() : null;
if (is_null($video)) {
// 保存位置配置 key
$disk = 'video';
// 检查是否需要保留原文件名
$name_rule = fn() => $filename_keep ? $this->filenameGenerator($file) : null;
$filename = Filesystem::disk('video')->putFile($param['module'], $file, $name_rule());
// 保存到七牛云
if ($save_to == 'qiniu_cloud') {
$disk = 'video_qiniu';
$storage = config('filesystem.disks.video_qiniu.path_prefix');
}
$filename = Filesystem::disk($disk)->putFile($param['module'], $file, $name_rule());
// 组装视频路径
$video_path = $storage . '/' . $filename;
if ($save_to == 'qiniu_cloud') {
$video_path = Filesystem::disk($disk)->url($filename);
}
// 保存视频
$video = new SysVideoUploadRecordModel();
$video->language_id = request()->lang_id;
$video->module = $param['module'];
$video->video_path = $filename;
$video->video_path = $video_path;
$video->file_size = $file->getSize();
$video->file_type = $file->getOriginalMime();
$video->file_md5 = $filemd5;
@@ -369,7 +386,7 @@ class Upload
}
return success('上传成功', [
'path' => $storage . '/' . $video->video_path,
'path' => $video->video_path,
'file_md5' => $video->file_md5,
'file_sha1' => $video->file_sha1
]);
@@ -399,25 +416,42 @@ class Upload
return error($validate->getError());
}
$storage = config('filesystem.disks.public.url');
$filemd5 = $file->md5();
$filesha1 = $file->sha1();
// 获取附件上传配置
list(
'filename_keep' => $filename_keep,
'filemd5_unique' => $filemd5_unique
'filemd5_unique' => $filemd5_unique,
'save_to' => $save_to
) = $this->getUploadOptions('upload_attachment');
// 是否需要根据文件MD5值检查文件是否已存在
$attachment = $filemd5_unique ? SysAttachmentUploadRecordModel::md5($filemd5)->find() : null;
if (is_null($attachment)) {
// 保存位置配置 key
$disk = 'public';
// 检查是否需要保留原文件名
$name_rule = fn() => $filename_keep ? $this->filenameGenerator($file) : null;
$filename = Filesystem::disk('public')->putFile('attachments', $file, $name_rule());
// 保存视频
// 保存到七牛云
if ($save_to == 'qiniu_cloud') {
$disk = 'public_qiniu';
$storage = config('filesystem.disks.public_qiniu.path_prefix');
}
$filename = Filesystem::disk($disk)->putFile('attachments', $file, $name_rule());
// 组装附件路径
$attachment_path = $storage . '/' . $filename;
if ($save_to == 'qiniu_cloud') {
$attachment_path = Filesystem::disk($disk)->url($filename);
}
// 保存附件
$attachment = new SysAttachmentUploadRecordModel();
$attachment->language_id = request()->lang_id;
$attachment->attachment_path = $filename;
$attachment->attachment_path = $attachment_path;
$attachment->file_size = $file->getSize();
$attachment->file_type = $file->getOriginalMime();
$attachment->file_md5 = $filemd5;
@@ -427,9 +461,8 @@ class Upload
}
}
$storage = config('filesystem.disks.public.url');
return success('上传成功', [
'path' => $storage . '/' . $attachment->attachment_path,
'path' => $attachment->attachment_path,
'file_md5' => $attachment->file_md5,
'file_sha1' => $attachment->file_sha1
]);

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

@@ -15,7 +15,7 @@ class SysBannerItemValidate extends Validate
*/
protected $rule = [
'id' => 'require|integer',
'banner_id' => 'require|integer',
'banner_id' => 'require|integer|gt:0',
'title' => 'require|max:256',
'title_txt_color' => 'max:7',
'desc' => 'max:1024',
@@ -25,7 +25,7 @@ class SysBannerItemValidate extends Validate
'extra_image' => 'max:255',
'video' => 'max:255',
'link_to' => 'requireIf:type,image|max:64|in:article,article_category,product,product_category,system_page,custom',
'link' => 'max:255',
'link' => 'max:510',
'sort' => 'integer',
'status' => 'in:-1,1'
];
@@ -41,6 +41,7 @@ class SysBannerItemValidate extends Validate
'id.integer' => 'ID必须是整数',
'banner_id.require' => '横幅项分类不能为空',
'banner_id.integer' => '横幅项分类必须是整数',
'banner_id.gt' => '该横幅分类不可选',
'title.require' => '名称不能为空',
'title.max' => '名称最多不能超过256个字符',
'title_txt_color.max' => '名称字体颜色最多不能超过7个字符',
@@ -53,7 +54,7 @@ class SysBannerItemValidate extends Validate
'link_to.requireIf' => '链接类型不能为空',
'link_to.max' => '链接类型最多不能超过64个字符',
'link_to.in' => '链接类型必须是article,article_category,product,product_category,system_page,custom中之一',
'link.max' => '链接最多不能超过255个字符',
'link.max' => '链接最多不能超过512个字符',
'sort.integer' => '排序值必须是整数',
'status.in' => '状态必须是-1或1'
];

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;
}
@@ -144,4 +144,91 @@ if (!function_exists('thumb')) {
return mb_substr($url, 0, $idx, 'utf-8') . '_thumb' . mb_substr($url, $idx, $len - $idx, 'utf-8');
}
}
if (!function_exists('get_filesystem_url')) {
/**
* 获取文件系统的访问 URL
* @param string $url 文件地址
* @param string $disk 磁盘配置 key
* @return string
*/
function get_filesystem_url(string|null $url, string $disk): string
{
if (is_null($url)) {
return '';
}
if (\think\helper\Str::startsWith($url, ['http://', 'https://', '//'])) {
return $url;
}
if (empty($disk)) {
return '';
}
return \think\facade\Filesystem::disk($disk)->url($url);
}
}
if (!function_exists('url_filesystem_detect')) {
/**
* 检测文件地址并根据情况转换为文件系统地址
* @param string $url 文件地址
* @return string
*/
function url_filesystem_detect(string|null $url): string
{
if (is_null($url)) {
return '';
}
$idx = strrpos($url, '.');
if ($idx === false) {
return $url;
}
$disks = [
'public_qiniu' => '_' . base64_encode('public_qiniu'),
'video_qiniu' => '_' . base64_encode('video_qiniu')
];
foreach ($disks as $disk => $marker) {
if (str_ends_with(mb_substr($url, 0, $idx), $marker)) {
return get_filesystem_url($url, $disk);
}
}
return $url;
}
}
if (!function_exists('url_join')) {
/**
* 合并URL
* @param string $url 基础URL
* @param string $path 路径
* @param bool $remove_slash 是否移除首尾的斜杠
* @return string
*/
function url_join(string $url, string $path, bool $remove_slash = true): string
{
if (empty($url)) {
return $path;
}
if (empty($path)) {
return $url;
}
if (\think\helper\Str::startsWith($path, ['http://', 'https://', '//'])) {
return $path;
}
if ($remove_slash) {
if (str_ends_with($url, '/') && str_starts_with($path, '/')) {
return $url . substr($path, 1);
}
if (!str_ends_with($url, '/') && !str_starts_with($path, '/')) {
return $url . '/' . $path;
}
}
return $url . $path;
}
}

View File

@@ -17,22 +17,24 @@ class SysBannerItemBaseModel extends BaseModel
// 字段信息
protected $schema = [
'id' => 'int',
'banner_id' => 'int',
'title' => 'string',
'title_txt_color' => 'string',
'desc' => 'string',
'desc_txt_color' => 'string',
'type' => 'string',
'image' => 'string',
'extra_image' => 'string',
'video' => 'string',
'link_to' => 'string',
'link' => 'string',
'sort' => 'int',
'status' => 'int',
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime'
'id' => 'int',
'banner_id' => 'int',
'title' => 'string',
'title_txt_color' => 'string',
'short_title' => 'string',
'short_title_txt_color' => 'string',
'desc' => 'string',
'desc_txt_color' => 'string',
'type' => 'string',
'image' => 'string',
'extra_image' => 'string',
'video' => 'string',
'link_to' => 'string',
'link' => 'string',
'sort' => 'int',
'status' => 'int',
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime'
];
}

View File

@@ -194,14 +194,14 @@ if (!function_exists('get_platform')) {
} else {
// 在非移动端环境,根据配置规则判断是否要显示移动端
$view_cfg = $view_cfg = [
'rule' => env('VIEW_TPL.RULE', 'query'),
'rule' => env('INDEX_VIEW_TPL.RULE', 'query'),
'query' => [
'name' => env('VIEW_TPL.RULE_QUERY_NAME', 'mtpl'),
'value' => env('VIEW_TPL.RULE_QUERY_VALUE', '1'),
'name' => env('INDEX_VIEW_TPL.RULE_QUERY_NAME', 'mtpl'),
'value' => env('INDEX_VIEW_TPL.RULE_QUERY_VALUE', '1'),
],
'domain' => [
'scheme' => env('VIEW_TPL.RULE_DOMAIN_SCHEME', ['http']),
'host' => env('VIEW_TPL.RULE_DOMAIN_HOST'),
'scheme' => env('INDEX_VIEW_TPL.RULE_DOMAIN_SCHEME', ['http']),
'host' => env('INDEX_VIEW_TPL.RULE_DOMAIN_HOST'),
],
];
if ($view_cfg['rule'] == 'query') {

View File

@@ -21,9 +21,9 @@ class Attachment extends Common
{
$param = request()->param([
'id',
'keyword',
'page/d' => 1,
'size/d' => 12,
'keyword' => '',
'page/d' => 1,
'size/d' => 12,
]);
// 获取附件分类
@@ -48,9 +48,9 @@ class Attachment extends Common
'support_platform',
'attach',
])
->withSearch(['name'], ['name' => $param['keyword']??null])
->withSearch(['name'], ['name' => !empty($param['keyword']) ? trim($param['keyword']) : null])
->language($this->lang_id)
->category($param['id']??null)
->category(!empty($param['id']) ? $param['id'] : $categorys[0]['id']??null)
->order(['sort' => 'asc', 'id' => 'desc'])
->paginate([
'list_rows' => $param['size'],
@@ -59,6 +59,16 @@ class Attachment extends Common
'id' => $param['id']??null
]
]);
if (!$attachements->isEmpty()) {
$attachements->each(function($item) {
if (is_array($item->attach)) {
$item->attach = array_map(function($v) {
$v['file_path'] = url_filesystem_detect($v['file_path']);
return $v;
}, $item->attach);
}
});
}
View::assign('attachements', $attachements);
View::assign('page', $attachements->render());
@@ -109,9 +119,9 @@ class Attachment extends Common
'video',
'link'
])
->withSearch(['name'], ['name' => $param['keyword']??null])
->withSearch(['name'], ['name' => !empty($param['keyword']) ? trim($param['keyword']) : null])
->language($this->lang_id)
->category($param['id']??$video_categorys[0]['id']??null)
->category(!empty($param['id']) ? $param['id'] : $video_categorys[0]['id']??null)
->order(['sort' => 'asc', 'id' => 'desc'])
->paginate([
'list_rows' => $param['size'],
@@ -122,6 +132,9 @@ class Attachment extends Common
]);
if (!$videos->isEmpty()) {
$videos->each(function($item) {
$item->video = url_filesystem_detect($item->video);
});
$videos->setCollection($videos->getCollection()->chunk(2));
}
View::assign('videos', $videos);

View File

@@ -104,7 +104,7 @@ class Product extends Common
->onSale(true)
->onShelves(true)
->append(['p' => $list[0]['id']])
->order(['sort' => 'asc', 'id' => 'desc'])
->order(['sort' => 'asc', 'created_at' => 'desc', 'id' => 'desc'])
->limit(5)
->buildSql();
$query = \think\facade\Db::table("($sql) as a");
@@ -126,7 +126,7 @@ class Product extends Common
->enabled(true)
->onSale(true)
->onShelves(true)
->order(['sort' => 'asc', 'id' => 'desc'])
->order(['sort' => 'asc', 'created_at' => 'desc', 'id' => 'desc'])
->limit(5);
});
}
@@ -192,7 +192,7 @@ class Product extends Common
->enabled(true)
->onSale(true)
->onShelves(true)
->order(['sort' => 'asc', 'id' => 'desc'])
->order(['sort' => 'asc', 'created_at' => 'desc', 'id' => 'desc'])
->select();
if (!$products->isEmpty()) {
// 获取sku信息
@@ -277,7 +277,7 @@ class Product extends Common
'page/d' => 1,
'size/d' => 10
]);
$keywords = $param['keywords'] ?? '';
$keywords = !empty($param['keywords']) ? trim($param['keywords']) : '';
// 关键词搜索
$products = ProductModel::field([

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

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

@@ -53,6 +53,7 @@ return [
'product/search' => [
'搜索' => 'Search',
'请搜索' => 'Please search...',
'暂无数据' => 'No data',
],
// 产品详情
'product/detail' => [

View File

@@ -161,6 +161,7 @@ return [
// 产品 - 产品详情页
'product/detail' => [
'首页' => 'Home',
'型号' => 'Product Model',
'产品详情' => 'Product Description',
'相关产品' => 'Related Products',
'发送查询' => 'Send Inquiry',
@@ -177,6 +178,11 @@ return [
'提交' => 'SUBMIT',
],
// 产品 - 搜索
'product/search' => [
'暂无数据' => 'No data',
],
// 产品 - 分类
'product/category' => [
'查看全部' => 'View All',

View File

@@ -2,7 +2,8 @@
// 这是系统自动生成的middleware定义文件
return [
// 启用多语言支持
think\middleware\LoadLangPack::class,
// think\middleware\LoadLangPack::class,
app\index\middleware\LoadLangPack::class,
// 确认请求来源
app\index\middleware\ConfirmRequestFrom::class,
];

View File

@@ -0,0 +1,39 @@
<?php
declare (strict_types = 1);
namespace app\index\middleware;
use think\Request;
class LoadLangPack extends \think\middleware\LoadLangPack
{
// 重写检测语言方法
protected function detect(Request $request): string
{
$domain_detect = env('INDEX_LANG_DETECT.DOMAIN_DETECT', false);
if ($domain_detect) {
$lang = $this->getLangSet($request, env('INDEX_LANG_DETECT.DOMAIN_RULE', []));
if ($lang != '') {
return $lang;
}
}
return parent::detect($request);
}
// 根据请求及规则获取语言
private function getLangSet(Request $request, array $rules): string
{
$map = [];
foreach ($rules as $v) {
$val = str_replace('', ',', $v);
$item = explode(',', $v);
foreach ($item as $val) {
$it = explode('=', $val);
$map[$it[0]] = $it[1];
}
}
return $map[$request->host()] ?? '';
}
}

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

@@ -28,7 +28,7 @@
<!-- 分页 -->
<div>{$page|raw}</div>
{else/}
<div style="text-align: center; padding: 10%;">暂无数据</div>
<div style="text-align: center; padding: 10%;">{:lang_i18n('暂无数据')}</div>
{/notempty}
</div>
</div>

View File

@@ -11,7 +11,6 @@
<link rel="stylesheet" type="text/css" href="__CSS__/public.css" />
<link rel="stylesheet" type="text/css" href="__CSS__/font.css" />
<link rel="stylesheet" type="text/css" href="__CSS__/style.css" />
<!-- <link rel="stylesheet" type="text/css" href="__CSS__/fonts.css" /> -->
<link rel="stylesheet" type="text/css" href="__CSS__/header.css" />
<link rel="stylesheet" type="text/css" href="__CSS__/footer.css" />
{block name="style"}{/block}

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

@@ -12,6 +12,27 @@
<span class="icon-category cursor_p top-menu-toggle"><i class="icon-menu-svg"></i></span>
</div>
</div>
</div>
<!-- 顶部国家选择-->
<div class="top-country">
<div class="mask"></div>
<div class="action-sheet">
<div class="menu-title">
<div class="menu-name">{:lang_i18n('请择地区')}</div>
<div class="close-icon">
<img src="__IMAGES__/close.png">
</div>
</div>
<ul>
{volist name="header_languages" id="la"}
<li>
<a href="{$la.lang_url}" target="_blank">
<img src="{$la.lang_icon}">{$la.country_en_name} - {$la.lang_en_name}
</a>
</li>
{/volist}
</ul>
</div>
</div>
<!-- 顶部菜单-->
<div class="top-menu">
@@ -46,7 +67,13 @@
$(this).siblings('.it-1-2').slideToggle(800);
$(this).find('.icon-arrow').addClass('rotate');
});
// 顶部国家选择
$('.top-country-toggle').click(function(){
$(".mask,.action-sheet").show();
})
$('.top-country .close-icon').click(function(){
$(".mask,.action-sheet").hide();
})
// 移动端顶部宽度设置和主体内容宽度一致
var pageWidth = $('.oricoEGapp').outerWidth();
// 设置.header-PC元素的宽度

View File

@@ -22,25 +22,28 @@
<div class="headtop">
{eq name=":cookie('think_lang')" value="zh-cn"}
<a href="{:url('/index/topic/nas/index')}">
{else/}
<a>
{/eq}
<img src="__IMAGES__/logo.png" class="logoicoimg">
</a>
<div style="display: flex;">
<img src="__IMAGES__/fenlei.png" class="ssicoimg" id="flico">
<img src="__IMAGES__/sousuo.png" class="ssicoimg" id="ssico" style="margin-right:32px">
</div>
{else/}
<a>
{/eq}
<img src="__IMAGES__/logo.png" class="logoicoimg">
</a>
<div style="display: flex;">
<img src="__IMAGES__/fenlei.png" class="ssicoimg" id="flico">
<img src="__IMAGES__/sousuo.png" class="ssicoimg" id="ssico" style="margin-right:32px">
</div>
</div>
<!-- 文章内容 -->
<div id="rendered-content" class="nhlp-app-content">
{$article.content|raw|default=''}
<div class="ql-container">
<div id="rendered-content" class="nhlp-app-content ql-editor">
{$article.content|raw|default=''}
</div>
</div>
<!-- 搜索 -->
<div class="nhlpapp-search">
<div class="nhlpappshtop">
<div class="nhlpapp-shdiv">
<input class="nhlp-ipt" id="search-input" placeholder="{:lang_i18n('请输入搜索关键字,如安装赛博云空间,影视库')}" autocomplete="off">
<input class="nhlp-ipt" id="search-input" placeholder="{:lang_i18n('请输入搜索关键字,如安装赛博云空间,影视库')}"
autocomplete="off">
<img src="__IMAGES__/ssapp.png" class="searchimg">
</div>
<span class="closetx">{:lang_i18n('取消')}</span>
@@ -50,22 +53,44 @@
<div class="dropdown" id="dropdown"></div>
</div>
<!-- 分类文章目录 -->
<div class="nhlpapp-pagescate" {:style(['display' => $Request.get.view == 'more' ? 'block' : 'none'])}>
<div class="nhlpapp-pagescate" {:style(['display'=> $Request.get.view == 'more' ? 'block' : 'none'])}>
<div class="nars-hlpdt-ml">
{notempty name="article_categorys"}
<div class="nav-tree">
{volist name="article_categorys" id="ac" key="idx"}
<div class="categoryhelp">
<div class="categoryhelp-title">
<div>
<img src="__IMAGES__/nars-jt.png" class="arrow {if condition='$ac.id == $Request.get.cid'}rotate{/if}">
<img src="__IMAGES__/nars-jt.png"
class="arrow {if condition='$ac.id == $Request.get.cid'}rotate{/if}">
</div>
<span>{$ac.name}</span>
</div>
<ul class="sub-list" {if condition='$ac.id == $Request.get.cid'}style="display: block;"{/if}>
<ul class="sub-list" {if condition='$ac.id == $Request.get.cid' }style="display: block;" {/if}>
{volist name="ac.child" id="ad"}
<li class="two-mues">
<a href="#" class="two-a">
<div><img src="__IMAGES__/nars-jt.png"
class="arrow {if condition='$ad.id == $Request.get.pid'}rotate{/if}">
</div>
<span>{$ad.name}</span>
</a>
<ul class="thress-mues" {if condition='$ad.id == $Request.get.pid' }style="display: block;" {/if}>
{volist name="ad.article" id="ae"}
<li>
<a href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id ,'pid' => $ad.id, 'id' => $ae.id])}"
style="margin-left:18%;padding: 0.4rem;">{$ae.title}</a>
</li>
{/volist}
</ul>
</li>
{/volist}
{volist name="ac.article" id="ar"}
<li>
<a href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id , 'id' => $ar.id])}" style="padding-top: 6px;">
<a href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id , 'id' => $ar.id])}"
style="padding-top: 6px;">
{$ar.title}
</a>
</li>
@@ -73,10 +98,34 @@
</ul>
</div>
{/volist}
</div>
{/notempty}
</div>
</div>
<!-- 顶部国家选择-->
<div class="top-country">
<div class="mask"></div>
<div class="action-sheet">
<div class="menu-title">
<div class="menu-name">{:lang_i18n('请择地区')}</div>
<div class="close-icon">
<img src="__IMAGES__/close.png">
</div>
</div>
<ul>
{volist name="header_languages" id="la"}
<li>
<a href="{$la.lang_url}" target="_blank">
<img src="{$la.lang_icon}">{$la.country_en_name} - {$la.lang_en_name}
</a>
</li>
{/volist}
</ul>
</div>
</div>
</div>
</div>
{/block}
@@ -102,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();
@@ -110,6 +170,13 @@
$('.closetx').click(function () {
$('.nhlpapp-search').hide();
});
// 顶部国家选择
$('.top-country-toggle').click(function () {
$(".mask,.action-sheet").show();
})
$('.top-country .close-icon').click(function () {
$(".mask,.action-sheet").hide();
})
// 搜索
var timeout = null;
$('#search-input').on('focus input', function () {
@@ -142,6 +209,27 @@
})
}, 300);
});
// 英文截断处理
// 目标容器:富文本内容所在的元素
const contentContainer = $('#rendered-content');
// 遍历所有包含文本内容的标签p、h1-h6、strong等
contentContainer.find('*').each(function () {
const $element = $(this);
const htmlContent = $element.html();
// 条件1排除内容仅为一个&nbsp;的标签(如<p>&nbsp;</p>
if (htmlContent.trim() === '&nbsp;') {
return; // 不处理,继续下一个元素
}
// 条件2检查是否包含&nbsp;且有实际文本内容
if (htmlContent.includes('&nbsp;')) {
// 将所有&nbsp;替换为普通空格(有效占位符,支持单词完整换行)
const newContent = htmlContent.replace(/&nbsp;/g, ' ');
$element.html(newContent);
}
});
});
</script>
{/block}

View File

@@ -0,0 +1,740 @@
{extend name="public/base" /}
{block name="style"}
<link rel="stylesheet" href="__CSS__/topic_power_prodline/index.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/swiper.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/nav.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/advantage.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/mask.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/product.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/product_list.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/product_card.css">
<link rel="stylesheet" href="__CSS__/topic_power_prodline/footer.css">
{/block}
{block name="header"}
<!-- 重置header头为空 -->
{/block}
{block name="main"}
<a class="header" href="/">
<div class="header-img">
<img src="__IMAGES__/logo.png" alt="">
</div>
</a>
<!-- 轮播核心容器 -->
<div class="swiper-container auto-swiper-container" >
{notempty name="data.focus_image"}
<div class="swiper-wrapper">
{volist name="data.focus_image" id="fo"}
<a class="swiper-slide auto-swiper-slide" href="{$fo.link}">
<img src="{$fo.image}" alt="{$fo.title}" />
</a>
{/volist}
</div>
<div class="swiper-pagination"></div>
{/notempty}
</div>
<!-- 分类 -->
{notempty name="data.category"}
<div class="nav-box">
{volist name="data.category" id="ca"}
<a class="nav-item" href="{$ca.link}">
<img src="{$ca.image}" alt="{$ca.title}">
<p {:style(['color'=>$ca.title_txt_color])}>{$ca.title}</p>
</a>
{/volist}
</div>
{/notempty}
<!-- 500万 -->
{notempty name="data.why_choose"}
<div class="advantage-section">
{assign name="why_choose_title" value=":array_shift($data.why_choose)" /}
<h2 class="advantage-section__title">{$why_choose_title.title|default=''|raw}</h2>
<div class="advantage-section__list">
{volist name="data.why_choose" id="ch"}
<div class="advantage-card-wrap">
<div class="advantage-card" data-target="design">
<img src="{$ch.image}" alt="{$ch.title}:{$ch.short_title}" class="advantage-card__img">
<div class="advantage-card__content">
<!-- 标题+箭头容器:水平+垂直双居中,内部文字左、箭头右 -->
<div class="advantage-card__heading-wrap">
<div class="advantage-card__heading" {:style(['color'=>$ch.title_txt_color])}>{$ch.title}</div>
<img src="__IMAGES__/jiant.png" alt="" class="card-arrow">
</div>
<div class="advantage-card__description" {:style(['color'=>$ch.short_title_txt_color])}>{$ch.short_title}</div>
<div style="display:none;" class="mack-conten-text">{$ch.desc|raw}</div>
</div>
</div>
</div>
{/volist}
</div>
</div>
{/notempty}
<!-- 产品差旅充 -->
{notempty name="data.travel_charger"}
<div class="product-box">
{assign name="tc_title" value=":array_shift($data.travel_charger)" /}
<div class="product-title">
<h2 class="product-title-h2">{$tc_title.title|default=''}</h2>
<p class="product-title-p">{$tc_title.short_title|default=''}</p>
</div>
<div class="product-container" >
{assign name="tc_first_section_lf" value=":array_shift($data.travel_charger)" /}
{notempty name="tc_first_section_lf"}
<a class="product-left" href="{$tc_first_section_lf.link}">
<img src="{$tc_first_section_lf.image}" alt="{$tc_first_section_lf.title}" class="product-img">
<!-- 公共类+定位类:尺寸统一,定位不同 -->
<div class="product-img-hover product-img-1">
<img src="{$tc_first_section_lf.extra_image}" alt="{$tc_first_section_lf.short_title}">
</div>
</a>
{/notempty}
{assign name="tc_first_section_lr" value=":array_shift($data.travel_charger)" /}
{notempty name="tc_first_section_lr"}
<div class="product-right">
<img src="{$tc_first_section_lr.image}" alt="{$tc_first_section_lr.title}" class="right-content right-img">
<video src="{$tc_first_section_lr.video}" class="right-content right-video" muted loop playsinline>
您的浏览器不支持HTML5视频播放请升级浏览器
</video>
<button class="video-play-btn">
<span class="play-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<path d="M9 7L16 12L9 17V7Z" fill="white" />
</svg>
</span>
<!-- 暂停图标(默认隐藏) -->
<span class="pause-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<rect x="8" y="7" width="3" height="10" fill="white" />
<rect x="13" y="7" width="3" height="10" fill="white" />
</svg>
</span>
</button>
</div>
{/notempty}
</div>
{assign name="tc_second_section" value=":array_splice($data.travel_charger, 0, 4)" /}
{notempty name="tc_second_section"}
<div class="product-card-box">
<div class="product-card-container">
{volist name="tc_second_section" id="tss"}
<a class="product-card-wrap" href="{$tss.link}">
<div class="product-card" >
<div class="product-card-img">
<img src="{$tss.image}" alt="{$tss.title}">
</div>
<div class="product-card-text">
<div class="product-card-title" {:style(['color'=>$tss.title_txt_color])}>{$tss.title}</div>
<div class="product-card-desc" {:style(['color'=>$tss.short_title_txt_color])}>{$tss.short_title}</div>
</div>
<div class="product-card-link">
<img src="__IMAGES__/ljgd.png" alt="查看更多">
</div>
</div>
</a>
{/volist}
</div>
</div>
{assign name="tc_three_section" value=":array_shift($data.travel_charger)" /}
{notempty name="tc_three_section"}
<a href="{$tc_three_section.link}" class="more">
<div class="more-img">
{$tc_three_section.title}
</div>
</a>
{/notempty}
{/notempty}
</div>
{/notempty}
<!-- 产品 家居充-->
{notempty name="data.home_charger"}
<div class="product-box">
{assign name="hc_title" value=":array_shift($data.home_charger)" /}
<div class="product-title">
<h2 class="product-title-h2">{$hc_title.title|default=''}</h2>
<p class="product-title-p">{$hc_title.short_title|default=''}</p>
</div>
<div class="product-container">
{assign name="hc_first_section_lf" value=":array_shift($data.home_charger)" /}
{notempty name="hc_first_section_lf"}
<a class="product-left" href="{$hc_first_section_lf.link}">
<img src="{$hc_first_section_lf.image}" alt="{$hc_first_section_lf.title}" class="product-img">
<!-- 公共类+定位类:尺寸统一,定位不同 -->
<div class="product-img-hover product-img-1">
<img src="{$hc_first_section_lf.extra_image}" alt="{$hc_first_section_lf.short_title}">
</div>
</a>
{/notempty}
{assign name="hc_first_section_lr" value=":array_shift($data.home_charger)" /}
{notempty name="hc_first_section_lr"}
<div class="product-right">
<img src="{$hc_first_section_lr.image}" alt="{$hc_first_section_lr.title}" class="right-content right-img">
<video src="{$hc_first_section_lr.video}" class="right-content right-video" muted loop playsinline >
您的浏览器不支持HTML5视频播放请升级浏览器
</video>
<button class="video-play-btn">
<span class="play-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<path d="M9 7L16 12L9 17V7Z" fill="white" />
</svg>
</span>
<!-- 暂停图标(默认隐藏) -->
<span class="pause-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<rect x="8" y="7" width="3" height="10" fill="white" />
<rect x="13" y="7" width="3" height="10" fill="white" />
</svg>
</span>
</button>
</div>
{/notempty}
</div>
{assign name="hc_second_section" value=":array_splice($data.home_charger, 0, 4)" /}
{notempty name="hc_second_section"}
<div class="product-card-box">
<div class="product-card-container">
{volist name="hc_second_section" id="hcs"}
<a class="product-card-wrap" href="{$hcs.link}">
<div class="product-card" href="#">
<div class="product-card-img">
<img src="{$hcs.image}" alt="{$hcs.short_title}">
</div>
<div class="product-card-text">
<div class="product-card-title">{$hcs.title}</div>
<div class="product-card-desc">{$hcs.short_title}</div>
</div>
<div class="product-card-link">
<img src="__IMAGES__/ljgd.png" alt="查看更多">
</div>
</div>
</a>
{/volist}
</div>
</div>
{/notempty}
{assign name="hc_three_section" value=":array_shift($data.home_charger)" /}
{notempty name="hc_three_section"}
<a href="{$hc_three_section.link}" class="more">
<div class="more-img">
{$hc_three_section.title}
</div>
</a>
{/notempty}
</div>
{/notempty}
<!-- 产品 桌面充(悬浮图上右超出)底部列表样式不一样(左文右图) -->
<div class="product-box">
{assign name="dc_title" value=":array_shift($data.desktop_charger)" /}
<div class="product-title">
<h2 class="product-title-h2">{$dc_title.title|default=''}</h2>
<p class="product-title-p">{$dc_title.short_title|default=''}</p>
</div>
<div class="product-container">
{assign name="dc_first_section_lf" value=":array_shift($data.desktop_charger)" /}
{notempty name="dc_first_section_lf"}
<a class="product-left" href="{$dc_first_section_lf.link}">
<img src="{$dc_first_section_lf.image}" alt="{$dc_first_section_lf.short_title}" class="product-img">
<!-- 公共类+定位类:尺寸和第一个完全一致,仅定位不同 -->
<div class="product-img-hover product-img-2" >
<img src="{$dc_first_section_lf.extra_image}" alt="{$dc_first_section_lf.short_title}">
</div>
</a>
{/notempty}
{assign name="dc_first_section_lr" value=":array_shift($data.desktop_charger)" /}
{notempty name="dc_first_section_lr"}
<div class="product-right">
<img src="{$dc_first_section_lr.image}"
alt="使用场景" class="right-content right-img">
<!--muted loop playsinline controls-->
<video
src="{$dc_first_section_lr.video}"
class="right-content right-video" muted loop playsinline >
您的浏览器不支持HTML5视频播放请升级浏览器
</video>
<button class="video-play-btn">
<span class="play-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<path d="M9 7L16 12L9 17V7Z" fill="white" />
</svg>
</span>
<!-- 暂停图标(默认隐藏) -->
<span class="pause-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<rect x="8" y="7" width="3" height="10" fill="white" />
<rect x="13" y="7" width="3" height="10" fill="white" />
</svg>
</span>
</button>
</div>
{/notempty}
</div>
{assign name="dc_second_section" value=":array_splice($data.desktop_charger, 0, 2)" /}
{notempty name="dc_second_section"}
<div class="product-card-box">
<div class="product-card-container2">
{volist name="dc_second_section" id="dcs"}
<a class="product-card2" href="{$dcs.link}">
<div class="product-text2">
<!-- 新增内部容器,确保所有内容左对齐一致性 -->
<div class="product-text-content2">
<div class="product-card-title2">{$dcs.title}</div> <!-- 测试超出一行省略 -->
<div class="product-card-desc2">{$dcs.short_title}</div> <!-- 测试超出2行省略 -->
<div class="product-card-link2">
<img src="__IMAGES__/ljgd.png" alt="了解更多">
</div>
</div>
</div>
<div class="product-card-img2">
<img src="{$dcs.image}" alt="{$dcs.title}">
</div>
</a>
{/volist}
</div>
</div>
{/notempty}
{assign name="dc_three_section" value=":array_shift($data.desktop_charger)" /}
{notempty name="dc_three_section"}
<a href="{$dc_three_section.link}" class="more">
<div class="more-img">
{$dc_three_section.title}
</div>
</a>
{/notempty}
</div>
<!-- 墙插 -->
{notempty name="data.wall_charger"}
<div class="product-box">
{assign name="wc_title" value=":array_shift($data.wall_charger)" /}
<div class="product-title">
<h2 class="product-title-h2">{$wc_title.title|default=''}</h2>
<p class="product-title-p">{$wc_title.short_title|default=''}</p>
</div>
<div class="product-container">
{assign name="wc_first_section_lf" value=":array_shift($data.wall_charger)" /}
{notempty name="wc_first_section_lf"}
<a class="product-left" href="{$wc_first_section_lf.link}">
<img src="{$wc_first_section_lf.image}" alt="{$wc_first_section_lf.title}" class="product-img">
<!-- 公共类+定位类:尺寸统一,定位不同 -->
<div class="product-img-hover product-img-1">
<img src="{$wc_first_section_lf.extra_image}" alt="{$wc_first_section_lf.title}">
</div>
</a>
{/notempty}
{assign name="wc_first_section_lr" value=":array_shift($data.wall_charger)" /}
{notempty name="wc_first_section_lr"}
<div class="product-right">
<img src="{$wc_first_section_lr.image}" alt="{$wc_first_section_lr.title}" class="right-content right-img">
<video src="{$wc_first_section_lr.video}" class="right-content right-video" muted loop playsinline>
您的浏览器不支持HTML5视频播放请升级浏览器
</video>
<button class="video-play-btn">
<span class="play-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<path d="M9 7L16 12L9 17V7Z" fill="white" />
</svg>
</span>
<!-- 暂停图标(默认隐藏) -->
<span class="pause-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<rect x="8" y="7" width="3" height="10" fill="white" />
<rect x="13" y="7" width="3" height="10" fill="white" />
</svg>
</span>
</button>
</div>
{/notempty}
</div>
{assign name="wc_more_section" value=":array_shift($data.wall_charger)" /}
{notempty name="wc_more_section"}
<a href="{$wc_more_section.link}" class="more">
<div class="more-img">
{$wc_more_section.title}
</div>
</a>
{/notempty}
</div>
{/notempty}
{notempty name="data.converter"}
<!-- 转换器 -->
<div class="product-box">
{assign name="ct_title" value=":array_shift($data.converter)" /}
<div class="product-title">
<h2 class="product-title-h2">{$ct_title.title|default=''}</h2>
<p class="product-title-p">{$ct_title.short_title|default=''}</p>
</div>
{assign name="ct_more_section" value=":array_pop($data.converter)" /}
{assign name="ct_chunk_section" value=":array_chunk($data.converter, 2)" /}
{assign name="ct_chunk_section_len" value=":count($ct_chunk_section)" /}
{volist name="ct_chunk_section" id="cts" key="k"}
<div class="product-container">
{assign name="cts_lf" value=":array_shift($cts)" /}
{notempty name="cts_lf"}
<a class="product-left" href="{$cts_lf.link}">
<img src="{$cts_lf.image}" alt="{$cts_lf.title}" class="product-img">
<!-- 公共类+定位类:尺寸统一,定位不同 -->
<!--style="display:flex;justify-content: center;"-->
<div class="product-img-hover product-img-1" >
<!-- style="width:70%"-->
<img src="{$cts_lf.extra_image}" alt="{$cts_lf.title}">
</div>
</a>
{/notempty}
{assign name="cts_lr" value=":array_shift($cts)" /}
{notempty name="cts_lr"}
<div class="product-right">
<img src="{$cts_lr.image}" alt="{$cts_lr.title}" class="right-content right-img">
<video src="{$cts_lr.video}" class="right-content right-video" muted loop playsinline>
您的浏览器不支持HTML5视频播放请升级浏览器
</video>
<!-- 播放图标 -->
<button class="video-play-btn">
<span class="play-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<path d="M9 7L16 12L9 17V7Z" fill="white" />
</svg>
</span>
<!-- 暂停图标(默认隐藏) -->
<span class="pause-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" />
<rect x="8" y="7" width="3" height="10" fill="white" />
<rect x="13" y="7" width="3" height="10" fill="white" />
</svg>
</span>
</button>
</div>
{/notempty}
</div>
{neq name="k" value="$ct_chunk_section_len"}
<div class="line"></div>
{/neq}
{/volist}
{notempty name="ct_more_section"}
<a href="{$ct_more_section.link}" class="more">
<div class="more-img">
{$ct_more_section.title}
</div>
</a>
{/notempty}
</div>
{/notempty}
{notempty name="data.footer_info"}
<!-- 底部 -->
<div class="prodline-footer-box">
<div class="prodline-footer-box-img">
<img src="{$data.footer_info.0.image}" alt="">
</div>
</div>
{/notempty}
<!-- 蒙版 -->
<div class="mask" id="mask">
<div class="mask-content" >
<span class="close-btn">&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

@@ -5,7 +5,7 @@
{block name="main"}
<div class="orico_Page_achievement">
<div class="achievementMain">
<img src="__IMAGES__/Achievement.png" class="acvImg" />
<img src="__IMAGES__/Achievement.webp" class="acvImg" />
<div class="achInfo">
<div class="title">{:lang_i18n('ORICO荣耀')}</div>
{notempty name="achievement"}

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

@@ -14,7 +14,7 @@
<!-- 搜索 -->
<form action="{:url('attachment/index')}" method="get">
<div class="search_all">
<input type="hidden" name="id" value="{$Request.get.id}" />
<input type="hidden" name="id" value="{$Request.get.id??$categorys[0]['id']??''}" />
<input type="text" name="keyword" placeholder="{:lang_i18n('搜索')}" />
<button class="searchbtn" type="submit"><img src="__IMAGES__/search_blue.png" /></button>
</div>

View File

@@ -14,7 +14,7 @@
<!-- 搜索 -->
<form action="{:url('attachment/video')}" method="get">
<div class="search_all">
<input type="hidden" name="id" value="{$Request.get.id}" />
<input type="hidden" name="id" value="{$Request.get.id??$video_categorys[0]['id']??''}" />
<input type="text" name="keyword" placeholder="{:lang_i18n('搜索')}" />
<button class="searchbtn" type="submit"><img src="__IMAGES__/search_blue.png" /></button>
</div>

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> -->
<div style="background-image: url('{$scene.image}');" class="sceneimg"></div>
</a>
<div style="background-image: url('{$scene.image}');" class="sceneimg"></div>
</div>
{/volist}
</div>
@@ -129,10 +129,10 @@
<span class="otsbtitle">{:lang_i18n('强大功能、简单使用')}</span>
<div class="beforeafter ba-slider">
<!-- 对比前的图片 -->
<img src="__IMAGES__/indeximg1.jpg">
<img src="__IMAGES__/indeximg1.webp">
<div class="resize">
<!-- 对比后的图片 -->
<img src="__IMAGES__/indeximg2.jpg">
<img src="__IMAGES__/indeximg2.webp">
</div>
<!-- 可拖动的分隔条 -->
<span class="handle"></span>

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>
<!-- 产品主图切换和参数详情-->
@@ -66,6 +70,11 @@
<p>{$product.short_name|default=''}</p>
<div class="proTfg">
<ul class="swt-Table">
<li class="Table-Row">
<div class="ms3 Table-Cell">{:lang_i18n('型号')}</div>
<div class="ms2 Table-Cell"></div>
<div class="ms4 Table-Cell">{$product.spu}</div>
</li>
{volist name="product_params" id="pp"}
<li class="Table-Row">
<div class="ms3 Table-Cell">{$pp.name}</div>
@@ -124,8 +133,10 @@
{/notempty}
</div>
<!-- 富文本渲染-->
<div class="products_des" id="detail">
{$product.detail|default=''|raw}
<div class="ql-container">
<div class="products_des ql-editor" id="detail">
{$product.detail|default=''|raw}
</div>
</div>
</div>
<!-- 关联产品 -->

View File

@@ -35,7 +35,7 @@
</ul>
<div>{$page|raw}</div>
{else/}
<div style="text-align: center; padding: 10%;">暂无数据</div>
<div style="text-align: center; padding: 10%;">{:lang_i18n('暂无数据')}</div>
{/notempty}
</div>
</div>

View File

@@ -58,7 +58,7 @@
{else/}
<a href="javascript:void(0);" class="fline">
{$vo.value}
{/if}
{/if}
</a>
</li>
{/volist}

View File

@@ -1,6 +1,10 @@
<header class="narsPage-head">
<div class="headcenter">
{eq name=":cookie('think_lang')" value="zh-cn"}
<a href="{:url('/index/topic/nas/index')}">
{else/}
<a>
{/eq}
<img class="logico" style="cursor:pointer;" src="__IMAGES__/logo_nas_{:cookie('think_lang')}.png" />
</a>
{notempty name="header_navigation"}

View File

@@ -8,7 +8,7 @@
<div class="narshelpCenterPc">
<!-- banner-搜索 -->
<div class="pagetopbg">
<img src="__IMAGES__/nas_help_banner.jpg" class="hpbgimg" />
<img src="__IMAGES__/nas_help_banner.webp" class="hpbgimg" />
<div class='nhlp-search'>
<input class="nhlp-ipt" id="search-input" placeholder="{:lang_i18n('请输入搜索关键字,如安装赛博云空间,影视库')}" autocomplete="off" />
<img src="__IMAGES__/nas_help_search.png" class="searchimg" />
@@ -26,13 +26,13 @@
<h1 class="helph1">{:lang_i18n('使用教程')}</h1>
<div class="nhlp-row">
{volist name="article_categorys" id="vo" key="idx"}
<div class="nhlpit {gt name='idx' value='6'}nhlpit-w{/gt}">
<div class="nhlpit">
<div class="nhlptl">
<img src="{$vo.icon}" class="bhlpicoimg" />{$vo.name}
</div>
<div class="nhlp-tx-list">
{volist name="vo.article" id="va" key="index"}
<a class="txrow" href="{:url('/index/topic/nas/help_detail', ['cid' => $vo.id, 'id' => $va.id])}">
<a class="txrow" href="{:url('/index/topic/nas/help_detail', ['pid' => $va.category_id,'cid' => $vo.id, 'id' => $va.id])}">
<div class="nhlp-point"></div>
<span class="nhlpsp">{$va.title}</span>
<span class="narhelpgoimg">
@@ -41,7 +41,7 @@
</a>
{/volist}
{if condition="count($vo.article) >= 3"}
<a class="ckgdbt" href="{:url('/index/topic/nas/help_detail', ['cid' => $vo.id, 'id' => isset($vo.article[0])?$vo.article[0]['id']:0])}">
<a class="ckgdbt" href="{:url('/index/topic/nas/help_detail', ['cid' => $vo.id, 'id' => isset($vo.article[0])?$vo.article[0]['id']:0,'pid' => isset($vo.article[0])?$vo.article[0]['category_id']:0])}">
{:lang_i18n('查看更多')} >
</a>
{/if}

View File

@@ -1,17 +1,17 @@
{extend name="public/nas_base" /}
{block name="title"}
{notempty name="article.seo_title"}<title>{$article.seo_title}</title>{else /}{__BLOCK__}{/notempty}
{notempty name="article.seo_title"}<title>{$article.seo_title}</title>{else /}{__BLOCK__}{/notempty}
{/block}
{block name="seo"}
{notempty name="article.seo_keywords"}
<meta name="keywords" content="{$article.seo_keywords}" />
<meta name="description" content="{$article.seo_desc}" />
{else /}
{__BLOCK__}
{/notempty}
{notempty name="article.seo_keywords"}
<meta name="keywords" content="{$article.seo_keywords}" />
<meta name="description" content="{$article.seo_desc}" />
{else /}
{__BLOCK__}
{/notempty}
{/block}
{block name="style"}
<link rel="stylesheet" href="__CSS__/topic_nas_help-detail.css"/>
<link rel="stylesheet" href="__CSS__/topic_nas_help-detail.css" />
{/block}
{block name="main"}
<div class="orico_Page_index">
@@ -32,33 +32,49 @@
<div class="nars-hlpdt-ml">
{notempty name="article_categorys"}
<div class="nav-tree">
<!-- start 三级菜单 -->
{volist name="article_categorys" id="ac"}
<div class="category">
<!-- 一级 -->
<div class="category-title">
<div class="arrow {if condition='$ac.id == $Request.get.cid'}rotate{/if}">
<img src="__IMAGES__/nas-jt.png" class="arrow {if condition='$ac.id == $Request.get.cid'}rotate{/if}" />
</div>
<div class="arrow {if condition='$ac.id == $Request.get.cid'}rotate{/if}"><img src="__IMAGES__/nas-jt.png" class="arrow {if condition='$ac.id == $Request.get.cid'}rotate{/if}" /></div>
<span>{$ac.name}</span>
</div>
<ul class="sub-list" {if condition='$ac.id == $Request.get.cid'}style="display: block;"{/if}>
{volist name="ac.article" id="ar"}
<li>
<a
href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id, 'id' => $ar.id])}"
{eq name="ar.id" value="$Request.get.id"}class="active"{/eq}
>
{$ar.title}
<!-- 二级-->
<ul class="sub-list" {if condition='$ac.id == $Request.get.cid' }style="display: block;" {/if}>
{volist name="ac.child" id="ad"}
<li class="two-mues">
<a href="#" class="two-a">
<div class="arrow {if condition='$ad.id == $Request.get.pid'}rotate{/if}"><img src="__IMAGES__/nas-jt.png" class="arrow {if condition='$ad.id == $Request.get.pid'}rotate{/if}" /></div>
<span>{$ad.name}</span>
</a>
<ul class="thress-mues" {if condition='$ad.id == $Request.get.pid' }style="display: block;" {/if}>
{volist name="ad.article" id="ae"}
<li style="margin-left: 30px;"><a href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id,'pid' => $ad.id, 'id' => $ae.id])}" style="padding-top: 6px;" {eq
name="ae.id" value="$Request.get.id" }class="active" {/eq}>{$ae.title}</a></li>
{/volist}
</ul>
<!-- 三级-->
</li>
{/volist}
{volist name="ac.article" id="ar"}
<li><a href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id, 'id' => $ar.id])}" style="padding-top: 6px;" {eq
name="ar.id" value="$Request.get.id" }class="active" {/eq}>{$ar.title}</a></li>
{/volist}
</ul>
</div>
{/volist}
<!-- end 三级菜单 -->
</div>
{/notempty}
</div>
<!--文章详情 -->
<div class="nars-hlpdt-mm" id="rendered-content">{$article.content|raw|default=''}</div>
<div class="ql-container ">
<div class="nars-hlpdt-mm ql-editor" id="rendered-content">{$article.content|raw|default=''}</div>
</div>
<!--锚点定位 -->
<div class="nars-hlpdt-mr">
<div id="title-list">
@@ -73,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);
@@ -107,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>'
}
@@ -119,21 +147,27 @@
// 内容
// 清空标题列表
$("#title-list ul").empty();
// 提取 h1 标题
// 提取 h3 标题
var h1Titles = $("#rendered-content").find("h3");
h1Titles.each(function (index) {
var title = $(this);
var titleText = title.text();
var titleId = "title-" + index;
title.attr("id", titleId);
var listItem = $("<li>");
var link = $("<a>", {
href: "#" + titleId,
text: titleText
// 只有当找到h3标题且内容不为空时才进行处理
if (h1Titles.length > 0) {
h1Titles.each(function (index) {
var title = $(this);
var titleText = title.text().trim(); // 使用trim()去除空白字符
// 只有当标题文本不为空时才添加到列表
if (titleText) {
var titleId = "title-" + index;
title.attr("id", titleId);
var listItem = $("<li>");
var link = $("<a>", {
href: "#" + titleId,
text: titleText
});
listItem.append(link);
$("#title-list ul").append(listItem);
}
});
listItem.append(link);
$("#title-list ul").append(listItem);
});
}
});
</script>
{/block}

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

@@ -31,7 +31,11 @@ Route::group('v1', function() {
->middleware(\app\openapi\middleware\Auth::class);
})
->middleware(\think\middleware\Throttle::class, [
'visit_rate' => '5/m',
'prefix' => 'throttle_',
'visit_rate' => '5/m',
'key' => function($throttle, $request) {
return '__CONTROLLER__/__ACTION__/__IP__';
},
'visit_fail_response' => function (\think\middleware\Throttle $throttle, \think\Request $request, int $wait_seconds) {
return \think\Response::create('您的操作过于频繁, 请在 ' . $wait_seconds . ' 秒后再试。')->code(429);
},

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",
@@ -34,7 +34,8 @@
"topthink/think-cors": "^1.0",
"phpoffice/phpspreadsheet": "^3.8",
"friendsofsymfony/oauth2-php": "^1.3",
"mobiledetect/mobiledetectlib": "4.8.09"
"mobiledetect/mobiledetectlib": "4.8.09",
"qiniu/php-sdk": "^7.14"
},
"require-dev": {
"symfony/var-dumper": ">=4.2",

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

@@ -30,9 +30,9 @@ class SysConfigInit extends Seeder
["id" => 13, "group_id" => 7, "title" => "热线在线时段", "name" => "website_hotline_office_hours", "value" => "周一至周五:东部时间 9:00 - 18:00", "extra" => "", "type" => "textarea", "sort" => 2, "remark" => "售后与技术支持热线在线时段", "created_at" => "2025-04-08 16:11:10", "updated_at" => "2025-06-11 17:09:13", "deleted_at" => null],
["id" => 14, "group_id" => 7, "title" => "售后与技术支持热线", "name" => "website_hotline_number", "value" => "售后与技术支持热线:400-6696-298", "extra" => "", "type" => "textarea", "sort" => 3, "remark" => "售后与技术支持热线号码", "created_at" => "2025-04-08 16:12:05", "updated_at" => "2025-06-11 17:09:13", "deleted_at" => null],
["id" => 15, "group_id" => 7, "title" => "微信公众号二维码", "name" => "website_wx_qrcode", "value" => "/storage/images/webSet/20250408/073545e4b54f4f97c7c790498014d6a0.png", "extra" => "width:126px;height:126px;", "type" => "image", "sort" => 4, "remark" => "微信公众号二维码", "created_at" => "2025-04-08 16:13:58", "updated_at" => "2025-06-11 17:09:13", "deleted_at" => null],
["id" => 16, "group_id" => 8, "title" => "Technical Support", "name" => "website_technical_support_email", "value" => "Technical Support:supports@orico.com.cn1", "extra" => "", "type" => "text", "sort" => 1, "remark" => "", "created_at" => "2025-04-08 16:18:24", "updated_at" => "2025-06-12 09:55:21", "deleted_at" => null],
["id" => 17, "group_id" => 8, "title" => "Business", "name" => "website_business_email", "value" => "Business:oversea-bu@orico.com.cn1", "extra" => "", "type" => "text", "sort" => 2, "remark" => "", "created_at" => "2025-04-08 16:20:12", "updated_at" => "2025-06-12 09:55:21", "deleted_at" => null],
["id" => 18, "group_id" => 8, "title" => "ODM/OEM Service", "name" => "website_ODM/OEM_service_email", "value" => "ODM/OEM Service:odmmarket@orico.com.cn1", "extra" => "", "type" => "text", "sort" => 3, "remark" => "", "created_at" => "2025-04-08 16:27:00", "updated_at" => "2025-06-12 09:55:21", "deleted_at" => null],
["id" => 16, "group_id" => 8, "title" => "Technical Support", "name" => "website_technical_support_email", "value" => "Technical Support:supports@orico.com.cn", "extra" => "", "type" => "text", "sort" => 1, "remark" => "", "created_at" => "2025-04-08 16:18:24", "updated_at" => "2025-06-12 09:55:21", "deleted_at" => null],
["id" => 17, "group_id" => 8, "title" => "Business", "name" => "website_business_email", "value" => "Business:oversea-bu@orico.com.cn", "extra" => "", "type" => "text", "sort" => 2, "remark" => "", "created_at" => "2025-04-08 16:20:12", "updated_at" => "2025-06-12 09:55:21", "deleted_at" => null],
["id" => 18, "group_id" => 8, "title" => "ODM/OEM Service", "name" => "website_ODM/OEM_service_email", "value" => "ODM/OEM Service:odmmarket@orico.com.cn", "extra" => "", "type" => "text", "sort" => 3, "remark" => "", "created_at" => "2025-04-08 16:27:00", "updated_at" => "2025-06-12 09:55:21", "deleted_at" => null],
["id" => 19, "group_id" => 8, "title" => "Monday-Friday", "name" => "website_hotline_office_hours", "value" => "Monday-Friday,9a.m.-6p.m.GMT+81", "extra" => "", "type" => "text", "sort" => 4, "remark" => "", "created_at" => "2025-04-08 16:28:52", "updated_at" => "2025-06-12 09:55:21", "deleted_at" => null],
["id" => 20, "group_id" => 9, "title" => "知呼Icon", "name" => "website_media_zhihu.image", "value" => "/storage/images/webSet/20250408/45ef8e4863d63620ab903cf6557c3469.png", "extra" => "width:30px;height:30px;", "type" => "image", "sort" => 1, "remark" => "", "created_at" => "2025-04-08 16:45:57", "updated_at" => "2025-06-11 17:09:13", "deleted_at" => null],
["id" => 21, "group_id" => 9, "title" => "小红书Icon", "name" => "website_media_xiaohongshu.image", "value" => "/storage/images/webSet/20250408/120f13d01c89864fd20df0e24212c214.png", "extra" => "width:30px;height:30px;", "type" => "image", "sort" => 3, "remark" => "", "created_at" => "2025-04-08 16:46:40", "updated_at" => "2025-06-11 17:09:13", "deleted_at" => null],
@@ -73,12 +73,12 @@ 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],
["id" => 64, "group_id" => 8, "title" => "Technical Support", "name" => "website_email", "value" => "supports@orico.com.cn1", "extra" => null, "type" => "text", "sort" => 1, "remark" => null, "created_at" => "2025-05-23 17:06:53", "updated_at" => "2025-06-12 09:55:21", "deleted_at" => null],
["id" => 64, "group_id" => 8, "title" => "Technical Support", "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-12 09:55:21", "deleted_at" => null],
["id" => 65, "group_id" => 3, "title" => "是否开启", "name" => "watermark_enabled", "value" => "0", "extra" => "0:否\n1:是", "type" => "radio", "sort" => 1, "remark" => "", "created_at" => "2025-06-10 15:41:54", "updated_at" => "2025-06-11 17:09:13", "deleted_at" => null],
["id" => 66, "group_id" => 3, "title" => "类型", "name" => "watermark_type", "value" => "TEXT", "extra" => "TEXT:文本['watermark_text_value','watermark_text_font','watermark_text_size','watermark_text_color']\nIMAGE:图片['watermark_image_value','watermark_image_width','watermark_image_height']", "type" => "radio", "sort" => 2, "remark" => "", "created_at" => "2025-06-10 15:44:15", "updated_at" => "2025-06-11 17:09:13", "deleted_at" => null],
["id" => 67, "group_id" => 3, "title" => "水印文本", "name" => "watermark_text_value", "value" => "ORICO", "extra" => "", "type" => "text", "sort" => 3, "remark" => "中文情况下,请确认字体支持中文", "created_at" => "2025-06-10 15:48:38", "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,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: Metropolis-Bold, Metropolis;
padding-bottom: 24px;
padding-top: 40px;
font-weight: 700;
@@ -60,7 +60,7 @@
.iotbtp1 {
font-size: 14px;
font-family: Montserrat-Bold, Montserrat;
font-family: Metropolis-Bold, Metropolis;
font-weight: bold;
padding-bottom: 11px;
word-break: break-word;
@@ -69,7 +69,7 @@
.iotbts1 {
text-align: center;
font-size: 12px;
font-family: Montserrat-Medium, Montserrat;
font-family: Metropolis-Medium, Metropolis;
color: #9e9e9f;
word-break: break-word;
}
@@ -140,7 +140,7 @@
font-size: 14px;
padding-top: 12px;
text-align: center;
font-family: Montserrat-Medium, Montserrat;
font-family: Metropolis-Medium, Metropolis;
overflow-wrap: break-word;
word-break: break-word;
}
@@ -152,7 +152,7 @@
.sfbt1 {
text-align: center;
font-size: 18px;
font-family: Montserrat-Bold, Montserrat;
font-family: Metropolis-Bold, Metropolis;
font-weight: bold;
padding-bottom: 24px;
padding-top: 24px;
@@ -183,7 +183,7 @@
.cit {
width: 100%;
font-size: 14px;
font-family: Montserrat-Regular, Montserrat;
font-family: Metropolis-Regular, Metropolis;
color: #000;
display: flex;
flex-direction: row;
@@ -237,7 +237,7 @@
.wcu_s1 {
color: #000;
font: 16px;
font-family: Montserrat-Medium, Montserrat;
font-family: Metropolis-Medium, Metropolis;
font-weight: 500;
padding: 20px 24px;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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: "Metropolis-SemiBold";
font-weight: bold;
}
.oircoEgapp-head .top-menu .it-ct .it-1 {

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -25,6 +25,7 @@
flex-direction: row;
justify-content: space-between;
background: #fff;
z-index: 10;
}
.narshelpCenterdetail-app .headtop .logoicoimg {
@@ -39,18 +40,14 @@
}
.narshelpCenterdetail-app .nhlp-app-content {
margin: 1.25rem;
/* margin: 1rem; */
height: 100%;
margin-top: 9.2vh;
width: 90%;
margin: 0 auto;
margin-top: 5rem;
}
}
.narshelpCenterdetail-app .nhlp-app-content h2 {
line-height: 2.2rem;
}
.narshelpCenterdetail-app .nhlp-app-content p{
line-height: 1.5rem;
word-break: keep-all !important;
}
.narshelpCenterdetail-app #rendered-content img {
max-width: 100%;
display: inline;
@@ -58,7 +55,7 @@
.narshelpCenterdetail-app .nhlpapp-search {
position: fixed;
z-index: 2;
z-index: 12;
top: 0;
height: 100vh;
display: flex;
@@ -222,4 +219,32 @@
.narshelpCenterdetail-app .nhlpapp-pagescate .nars-hlpdt-ml .sub-list li a:hover {
color: #1f2635;
border-bottom: 1px solid #1f2635;
}
/*9.18 添加三级样式*/
.narshelpCenterdetail-app .nhlpapp-pagescate .nars-hlpdt-ml .sub-list .two-mues {
position: relative;
}
.narshelpCenterdetail-app .nhlpapp-pagescate .nars-hlpdt-ml .sub-list .two-mues .two-a {
position: relative;
padding-top: 6px;
display: flex;
font-size: 0.95rem !important;
flex-direction: row;
}
.narshelpCenterdetail-app .nhlpapp-pagescate .nars-hlpdt-ml .sub-list .two-mues .two-a:hover {
border-bottom: none;
}
.narshelpCenterdetail-app .nhlpapp-pagescate .nars-hlpdt-ml .sub-list .thress-mues {
display: none;
}
.narshelpCenterdetail-app .nhlpapp-pagescate .nars-hlpdt-ml .sub-list .thress-mues a {
padding-top: 0.375rem;
padding-left: 1.875rem;
}

View File

@@ -0,0 +1,320 @@
/* 核心模块固定90%宽度PC端优化移动端边距 */
.advantage-section {
width: 90%;
margin: 0 auto;
padding: 4rem 0 3rem 0;
position: relative;
z-index: 1;
height: auto !important;
min-height: auto !important;
}
/* 标题容器:恢复原有居中样式 */
.advantage-section__title {
font-size: clamp(1.5rem, 3vw, 2rem);
font-weight: 700;
text-align: center;
color: #333;
line-height: 1.2;
margin-bottom: clamp(1.5rem, 2vw, 2.5rem);
}
/* 列表容器:强制设置高度相关属性,确保内容正常显示 */
.advantage-section__list {
display: flex;
justify-content: center;
align-items: flex-start;
gap: clamp(0.1rem, 0.3vw, 0.8rem);
width: 100% !important;
flex-wrap: nowrap;
overflow: visible !important; /* 改为visible确保内容显示 */
padding: 0 !important;
/* 强制设置高度相关属性 */
height: auto !important;
min-height: 1px !important; /* 确保容器至少有高度 */
position: relative !important; /* 建立BFC */
}
/* 卡片包裹容器:确保为块级元素并继承高度 */
.advantage-card-wrap {
display: block !important;
width: 100% !important;
height: auto !important;
min-height: 1px !important;
}
/* 卡片核心:高度自适应内容 */
.advantage-card {
flex: 0 0 calc((100% - 4 * clamp(0.1rem, 0.3vw, 0.8rem)) / 5);
min-width: calc((100% - 4 * clamp(0.1rem, 0.3vw, 0.8rem)) / 5);
max-width: calc((100% - 4 * clamp(0.1rem, 0.3vw, 0.8rem)) / 5);
border-radius: 0.5rem;
overflow: hidden;
box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease;
cursor: pointer;
background: #fff;
position: relative;
z-index: 1;
height: auto !important; /* 高度自适应内容 */
display: flex;
flex-direction: column;
}
/* 图片容器设置为1:1比例 */
.advantage-card__img {
width: 100%;
aspect-ratio: 1 / 1; /* 1:1图片比例 */
object-fit: cover;
background-color: #f9f9f9;
display: block;
flex-shrink: 0;
}
/* 文字区域flex垂直分布确保标题和描述都垂直居中 */
.advantage-card__content {
width: 100%;
padding: clamp(0.3rem, 0.4vw, 0.75rem);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
flex-grow: 1;
gap: 4px;
}
/* 标题容器:水平居中+内部两端对齐,同时垂直居中 */
.advantage-card__heading-wrap {
display: flex;
align-items: center;
justify-content: space-between;
gap: clamp(0.3rem, 0.5vw, 0.5rem);
width: 80%;
}
/* 卡片标题:居左显示 */
.advantage-card__heading {
font-size: clamp(0.85rem, 1.5vw, 1.4rem);
font-weight: 600;
color: #333;
line-height: 1.3;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* 卡片标题右侧箭头:自适应大小,与标题协调 */
.card-arrow {
color: #409eff;
transition: transform 0.3s ease;
display: inline-flex;
align-items: center;
justify-content: center;
/* 箭头大小根据标题字体大小自适应 */
width: clamp(1rem, 1.8vw, 1.5rem);
height: clamp(1rem, 1.8vw, 1.5rem);
font-size: clamp(0.7rem, 1.2vw, 1.1rem);
flex-shrink: 0;
}
/* 卡片hover时箭头动画 */
.advantage-card:hover .card-arrow {
transform: translateX(3px);
}
/* 描述文字:水平+垂直居中,与标题容器对齐 */
.advantage-card__description {
font-size: clamp(0.6rem, 0.9vw, 0.9rem);
color: #78787a;
line-height: 1.2;
white-space: normal;
overflow: hidden;
width: 80%;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
/* 卡片hover效果 */
.advantage-card:hover {
transform: scale(1.03);
}
/* 箭头容器:自适应尺寸 */
.arrow {
position: relative;
/* 箭头尺寸跟随card-arrow自适应 */
width: 100%;
height: 100%;
}
/* 箭头线条基础样式:自适应粗细 */
.arrow::before,
.arrow::after {
content: '';
position: absolute;
background-color: #fff;
border-radius: clamp(0.05rem, 0.1vw, 0.1rem);
/* 线条粗细自适应 */
height: clamp(0.08rem, 0.15vw, 0.12rem);
}
/* 右箭头:自适应长度 */
.arrow-right::before {
width: clamp(0.3rem, 0.7vw, 0.55rem);
top: 50%;
left: 0;
transform: translateY(-50%) rotate(45deg);
transform-origin: right center;
}
.arrow-right::after {
width: clamp(0.3rem, 0.7vw, 0.55rem);
top: 50%;
left: 0;
transform: translateY(-50%) rotate(-45deg);
transform-origin: right center;
}
/* 左箭头:自适应长度 */
.arrow-left::before {
width: clamp(0.3rem, 0.7vw, 0.55rem);
top: 50%;
right: 0;
transform: translateY(-50%) rotate(-45deg);
transform-origin: left center;
}
.arrow-left::after {
width: clamp(0.3rem, 0.7vw, 0.55rem);
top: 50%;
right: 0;
transform: translateY(-50%) rotate(45deg);
transform-origin: left center;
}
/* iPad Pro适配和移动端一样一行展示2个最后一个隐藏字体放大 */
@media (max-width: 1024px) and (min-width: 768px) {
.advantage-section__list {
display: block !important;
width: 100% !important;
height: auto !important;
overflow: hidden !important;
padding: 0 !important;
}
.advantage-card-wrap {
width: calc(50% - 7.5px) !important;
float: left !important;
margin: 0 0 15px 0 !important;
height: auto !important;
}
.advantage-card-wrap:nth-child(odd) {
margin-right: 15px !important;
}
.advantage-card {
width: 100% !important;
min-width: 100% !important;
max-width: 100% !important;
flex: none !important;
height: auto !important;
display: flex;
flex-direction: column;
}
/* 只显示前4个卡片最后一个隐藏 */
.advantage-card-wrap:nth-child(n+5) {
display: none !important;
}
.advantage-card__content {
width: 100%;
flex-grow: 1;
padding: clamp(1rem, 3vw, 1.5rem) 0;
}
.advantage-card__img {
aspect-ratio: 1 / 1;
max-height: 330px;
}
/* 平板端字体放大 */
.advantage-card__heading {
font-size: clamp(1.1rem, 2vw, 1.6rem);
}
.advantage-card__description {
font-size: clamp(0.85rem, 1.3vw, 1.1rem);
}
.card-arrow {
width: clamp(1.2rem, 2vw, 1.7rem);
height: clamp(1.2rem, 2vw, 1.7rem);
font-size: clamp(0.9rem, 1.5vw, 1.3rem);
}
}
/* 移动端布局调整彻底修复高度为0问题 */
@media (max-width: 767px) {
/* 使用block布局+浮动确保高度正常 */
.advantage-section__list {
display: block !important;
width: 100% !important;
height: auto !important;
overflow: hidden !important;
padding: 0 !important;
}
/* 卡片包裹容器使用浮动实现一行2个 */
.advantage-card-wrap {
width: calc(50% - 7.5px) !important;
float: left !important;
margin: 0 0 15px 0 !important;
height: auto !important;
}
/* 偶数个卡片添加右边距 */
.advantage-card-wrap:nth-child(odd) {
margin-right: 15px !important;
}
/* 卡片尺寸调整 */
.advantage-card {
width: 100% !important;
min-width: 100% !important;
max-width: 100% !important;
flex: none !important;
height: auto !important;
display: flex;
flex-direction: column;
}
/* 只显示前4个卡片 */
.advantage-card-wrap:nth-child(n+5) {
display: none !important;
}
.advantage-card__img {
aspect-ratio: 1 / 1;
}
.advantage-card__content {
flex-grow: 1;
padding: clamp(1rem, 3vw, 1.5rem) 0; /* 平板端底部内边距稍大 */
}
}
/* 超小屏进一步优化 */
@media (max-width: 374px) {
.advantage-card-wrap {
width: calc(50% - 5px) !important;
}
.advantage-card-wrap:nth-child(odd) {
margin-right: 10px !important;
}
}

View File

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

View File

@@ -0,0 +1,75 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* 1. 根字体适配限制最小根字体为14px从源头避免文字过小 */
html {
/* PC端≥1024px1rem=16px原尺寸 */
font-size: 16px;
}
/* 平板端768px~1023px15px→16px过渡最小15px */
@media (max-width: 1023px) and (min-width: 768px) {
html {
font-size: calc(15px + (16 - 15) * (100vw - 768px) / (1023 - 768));
}
}
/* 移动端320px~767px固定14px不随屏幕缩小而变小避免文字<12px */
@media (max-width: 767px) {
html {
font-size: 14px;
}
}
/* 超小屏≤320px仍固定14px彻底杜绝文字过小 */
@media (max-width: 320px) {
html {
font-size: 14px;
}
}
body {
background: rgb(242, 243, 245);
/* margin:0 !important; */
}
a {
text-decoration: none;
display: block;
}
.more {
width: 90%;
margin: 0 auto;
display: flex;
justify-content: flex-end;
padding-top: clamp(1.5rem, 3vw, 3rem);
}
.more-img {
background: #000;
color: #fff;
font-size: clamp(0.6rem, 0.9vw, 0.9rem);
border-radius: clamp(0.875rem, 1.5vw, 1.125rem);
padding: clamp(0.1rem, 0.3vw, 0.2rem);
width: 5rem;
display: flex;
justify-content: center;
}
.line {
width: 100%;
height: clamp(1.5rem, 3vw, 3rem);
}
.header {
width: 100%;
background: #fff;
height: 60px;
}
.header-img {
margin: 0 auto;
width: 90%;
display: flex;
align-items: center;
padding-top: 0.5rem;
padding-bottom: 0.5rem;
}

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,96 @@
.nav-box {
display: flex;
justify-content: space-around;
width: 90%;
/* 平板/PC端限制最大宽度 */
margin: 0 auto;
background-color: #fff;
border-radius: 3.125rem;
/* 50px→3.125rem */
box-shadow: 0 0.125rem 0.9375rem rgba(0, 0, 0, 0.05);
/* 2px→0.125rem15px→0.9375rem */
position: relative;
z-index: 1;
padding: 0.625rem 0;
/* 10px→0.625rem(原内边距不变) */
overflow: visible;
}
.nav-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.625rem;
/* 10px→0.625rem */
cursor: pointer;
padding: 0.625rem 0 1.25rem;
/* 10px→0.625rem20px→1.25rem */
position: relative;
z-index: 2;
flex: 1;
min-width: 3rem;
/* 48px→3rem适配14px根字体 */
max-width: 5rem;
/* 80px→5rem */
text-align: center;
}
.nav-item img {
width: 4rem;
height: 4rem;
/* 60px→3.75rem16px基准14px根字体下≈52.5px,仍清晰 */
object-fit: contain;
border-radius: 0.75rem;
/* 12px→0.75rem */
position: absolute;
top: -3.125rem;
/* -50px→-3.125rem14px根字体下≈43.75px,超出效果不变) */
transform: translateY(0.625rem);
/* 10px→0.625rem */
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.nav-item:hover img {
transform: translateY(0.3125rem);
/* 5px→0.3125rem */
}
.nav-item:active img {
transform: translateY(0.4375rem);
/* 7px→0.4375rem */
box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.06);
}
/* 关键文字单独控制确保最小12px */
.nav-item p {
margin: 0;
/* PC端15px→0.9375rem16px根字体 */
font-size: 0.9375rem;
color: #37373e;
font-weight: 500;
position: relative;
z-index: 3;
top: 1.125rem;
/* 18px→1.125rem */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 0 0.125rem;
}
/* 平板端文字14px→0.9375rem15px根字体下=14px */
@media (max-width: 1023px) and (min-width: 768px) {
.nav-item p {
font-size: 0.9375rem;
}
}
/* 移动端文字强制12px用px兜底避免rem计算后过小 */
@media (max-width: 767px) {
.nav-item p {
font-size: 12px;
/* 直接用px固定最小尺寸优先级最高 */
font-size: clamp(12px, 0.857rem, 0.9375rem);
/* 增强版最小12px默认0.857rem14px根字体下≈12px最大0.9375rem */
}
}

View File

@@ -0,0 +1,184 @@
.product-box {
background: #fff;
padding: clamp(1.5rem, 3vw, 3rem) 0;
/* 产品块之间留间距 */
}
.product-title {
width: 90%;
margin: 0 auto;
padding-bottom: clamp(1.5rem, 3vw, 3rem);
}
.product-title-h2 {
font-size: clamp(1.5rem, 3vw, 2.25rem);
/* padding-top: clamp(1.5rem, 3vw, 3rem); */
}
.product-title-p {
font-size: clamp(0.875rem, 1.5vw, 1.125rem);
color: #646464;
margin-top: clamp(0.5rem, 1vw, 0.75rem);
}
/* 容器布局:两个产品通用 */
.product-container {
display: flex;
gap: clamp(0.4rem, 1vw, 0.71rem);
margin: 0 auto;
width: 90%;
align-items: flex-start;
}
/* 左侧容器:两个产品通用 */
.product-left {
flex: 1.8;
position: relative;
width: 100%;
}
.product-img {
width: 100%;
height: auto;
border-radius: 10px;
display: block;
/* 取消图片底部空隙 */
}
/* 悬浮图公共样式两个产品尺寸完全一致100%宽度) */
.product-img-hover {
position: absolute;
width: 100%;
/* 两个产品悬浮图宽度相同 */
z-index: 1;
}
.product-img-hover img {
width: 100%;
max-width: 300px;
/* 图片尺寸100%,无区别 */
height: auto;
border-radius: 10px;
}
/* 第一个产品:悬浮图居中上移(仅定位差异) */
.product-img-1 {
top: -10%;
left: 50%;
transform: translateX(-50%);
}
/* 第二个产品:悬浮图上右超出(仅定位差异) */
.product-img-2 {
top: -10%;
/* 上超出 */
transform: none;
width: 108%;
/* 取消居中 */
}
/* 右侧容器:两个产品通用 */
.product-right {
flex: 3.2;
position: relative;
border-radius: 10px;
overflow: hidden;
width: 100%;
background-color: #f5f5f5;
align-self: stretch;
position: relative;
}
.right-content {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
transition: opacity 0.3s ease;
}
.right-video {
display: none;
}
.video-play-btn {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: none;
border: none;
cursor: pointer;
opacity: 0;
transition: opacity 0.3s ease;
z-index: 2;
display: none; /* 默认隐藏 */
}
/* 播放图标默认显示,暂停图标默认隐藏 */
.play-icon {
display: inline-block;
}
.pause-icon {
display: none;
}
/* .paused类时切换图标 */
.video-play-btn.paused .play-icon {
display: none;
}
.video-play-btn.paused .pause-icon {
display: inline-block;
}
/* 视频显示时按钮可见 */
.right-video[playing] ~ .video-play-btn,
.product-right:hover .video-play-btn {
opacity: 1;
display: block;
}
/* PC端适配仅微调定位参数尺寸不变 */
@media (min-width: 1024px) {
.product-container {
width: 90%;
}
.product-left {
flex: 2;
}
.product-right {
flex: 5;
}
/* 宽度保持一致,仅调定位偏移 */
.product-img-1 {
top: -11%;
}
.product-img-2 {
top: -12%;
}
}
/* 超小屏适配:尺寸不变,微调定位 */
@media (max-width: 375px) {
.product-left {
flex: 1.5;
}
.product-right {
flex: 3.5;
}
/* 宽度仍保持一致 */
.product-img-1 {
top: -6%;
}
.product-img-2 {
top: -8%;
}
}

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(12px, 2vw, 18px);
font-weight: 600;
color: #333;
margin-bottom: 5px;
letter-spacing: 0.2px;
/* 超出一行省略号核心样式 */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
/* 基于内部容器左对齐,省略号生效 */
}
/* 描述超出2行显示省略号左对齐 */
.product-card-desc2 {
font-size: clamp(12px, 1.8vw, 14px);
color: #656565;
margin-bottom: 15px;
letter-spacing: 0.1px;
/* 超出2行显示省略号核心样式 */
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
white-space: normal;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
/* 基于内部容器左对齐 */
line-height: 1.4;
/* 优化行高2行高度适中 */
}
/* 图片容器:确保移动端显示 */
.product-card-img2 {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
min-width: 70px;
/* 强制保留图片区域,避免被挤压 */
}
.product-card-img2 img {
width: 100%;
height: auto;
max-height: 144px;
min-height: 80px;
object-fit: contain;
/* 保持图片比例完整,不拉伸 */
}
/* 链接图标:左对齐(基于内部容器) */
.product-card-link2 {
width: 100%;
display: flex;
justify-content: flex-start;
/* 图标左对齐 */
}
.product-card-link2 img {
width: clamp(60px, 4vw, 76px);
margin: 0;
/* 清除居中margin */
}
/* hover效果 */
.product-card2:hover {
transform: scale(1.03);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.12);
}
/* 媒体查询平板端768px ~ 1023px */
@media (max-width: 1023px) and (min-width: 768px) {
.product-card2 {
height: 224px;
min-width: 170px;
}
.product-text2 {
padding-left: 20px;
}
.product-card-img2 img {
max-height: 128px;
}
}
/* 媒体查询移动端≤767px */
@media (max-width: 767px) {
.product-card-box2 {
margin-top: 19px;
}
.product-card2 {
padding: 0 8px;
}
.product-card-container2 {
gap: 8px;
}
.product-card2 {
height: 208px;
min-width: 160px;
}
.product-card-img2 img {
max-height: 120px;
min-height: 72px;
}
}
/* 媒体查询小屏手机≤375px */
@media (max-width: 375px) {
.product-card2 {
height: 192px;
min-width: 140px;
}
/* 强制文字最小12px保证可读性 */
.product-card-title2,
.product-card-desc2 {
font-size: 12px;
}
.product-card-img2 img {
max-height: 104px;
min-height: 64px;
}
.product-card2 {
padding: 0 5px;
}
.product-card-link2 img {
width: 40px;
/* 固定图标尺寸,节省空间 */
}
}
/* 媒体查询超小屏手机≤320px */
@media (max-width: 320px) {
.product-card2 {
min-width: 120px;
}
.product-text2 {
padding: 0 5px;
}
.product-card-img2 {
min-width: 60px;
/* 缩小图片区域最小宽度,平衡文字空间 */
}
}

View File

@@ -0,0 +1,284 @@
/* 容器布局:通用基础样式(仅宽度、外边距,不涉及高度) */
.product-card-box {
width: 90%;
margin: clamp(1rem, 2vw, 1.5rem) auto 0;
padding: 0;
}
.product-card-container {
width: 100%;
margin: 0 auto;
display: flex;
flex-wrap: nowrap;
overflow: visible !important; /* 改为visible显示所有内容 */
padding: 0 clamp(0.2rem, 0.6vw, 0.3rem);
height: auto !important; /* 高度自适应内容 */
}
/* 卡片包裹容器:确保不独占一行 */
.product-card-wrap {
display: contents; /* 让包裹容器不影响布局 */
width: 100%;
}
/* ######################################################################### */
/* 移动端+平板样式max-width: 1023px- 后续修改仅改这里 */
/* ######################################################################### */
@media (max-width: 1023px) {
/* 卡片容器:移动端+平板特有 - 改为wrap换行一行2个高度自适应 */
.product-card-container {
align-items: flex-start; /* 改为flex-start避免拉伸 */
flex-wrap: wrap !important; /* 强制开启换行 */
justify-content: flex-start !important; /* 左对齐 */
gap: clamp(0.5rem, 1vw, 1rem) !important; /* 设置间距 */
padding: 0 clamp(0.2rem, 0.6vw, 0.3rem) clamp(1rem, 2vw, 1.5rem) !important;
height: auto !important; /* 高度自适应内容 */
}
/* 卡片包裹容器:移动端+平板适配 */
.product-card-wrap {
display: block !important;
width: calc(50% - clamp(0.25rem, 0.5vw, 0.5rem)) !important;
margin: 0 !important;
padding: 0 !important;
height: auto !important; /* 高度自适应 */
}
/* 卡片核心:移动端+平板改为一行2个高度自适应内容 */
.product-card {
background: rgb(242, 243, 245);
border-radius: clamp(0.375rem, 1vw, 0.5rem);
cursor: pointer;
width: 100% !important; /* 卡片宽度100%,由包裹容器控制 */
flex: none;
box-shadow: 0 clamp(0.1rem, 0.2vw, 0.125rem)
clamp(0.3rem, 0.8vw, 0.5rem) rgba(0, 0, 0, 0.05);
margin: 0 !important; /* 移除margin用gap控制间距 */
display: flex;
flex-direction: column;
height: auto !important; /* 高度自适应内容 */
}
/* 卡片hover效果移动端+平板特有 */
.product-card:hover {
transform: scale(clamp(1.01, 1.02, 1.03));
transition: transform 0.3s ease;
}
/* 图片容器:移动端+平板固定占比 */
.product-card-img {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
flex: 0 0 auto; /* 改为auto高度自适应 */
aspect-ratio: 3 / 2.8; /* 保持图片比例 */
margin-bottom: clamp(0.4rem, 0.6vw, 0.5rem);
overflow: hidden;
border-radius: clamp(0.2rem, 0.4vw, 0.25rem);
}
/* 产品图片:移动端+平板特有 */
.product-card img {
width: 100%;
height: 100%;
object-fit: contain;
object-position: center;
}
/* 文字容器:移动端+平板高度自适应 */
.product-card-text {
flex: 1 1 auto; /* 改为flex:1高度自适应内容 */
display: flex;
flex-direction: column;
justify-content: center;
padding-left: clamp(0.8rem, 2vw, 1.5rem);
padding-right: clamp(0.8rem, 2vw, 1.5rem);
height: auto !important; /* 高度自适应 */
}
/* 标题样式:移动端+平板特有,高度自适应 */
.product-card-title {
font-size: clamp(0.8rem, 1.3vw, 1.2rem);
font-weight: 600;
color: #333;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
height: auto !important; /* 移除固定高度 */
margin-bottom: clamp(0.2rem, 0.4vw, 0.3rem); /* 添加间距 */
line-height: 1.2;
}
/* 描述样式:移动端+平板高度自适应 */
.product-card-desc {
font-size: clamp(0.7rem, 1.1vw, 0.9rem);
color: #656565;
word-break: break-word;
height: auto !important; /* 移除固定高度 */
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
line-height: 1.4;
}
/* 链接图标容器:移动端+平板高度自适应,添加较小的底部内边距 */
.product-card-link {
width: 100%;
display: flex;
align-items: center;
flex: 0 0 auto; /* 改为auto高度自适应 */
padding: clamp(0.5rem, 1vw, 0.8rem); /* 减小上下内边距 */
padding-bottom: clamp(1rem, 3vw, 1.5rem); /* 更小的底部内边距约12px */
padding-left: clamp(0.8rem, 2vw, 1.5rem);
height: auto !important; /* 高度自适应 */
}
/* 链接图标:移动端+平板特有 */
.product-card-link img {
width: clamp(2.5rem, 5vw, 4.5rem);
height: auto;
object-fit: contain;
}
/* 平板端768px-1023px补充样式 */
@media (min-width: 768px) and (max-width: 1023px) {
.product-card-img {
aspect-ratio: 3 / 2.8; /* 保持图片比例 */
}
.product-card-link img {
width: clamp(5rem, 4vw, 6rem);
}
/* 平板端字体稍大 */
.product-card-title {
font-size: clamp(1rem, 1.5vw, 1.4rem);
}
.product-card-desc {
font-size: clamp(0.85rem, 1.2vw, 1rem);
}
/* 平板端底部内边距稍大但仍较小 */
.product-card-link {
padding-bottom: clamp(1rem, 3vw, 1.5rem);
}
}
}
/* ######################################################################### */
/* PC端样式单独配置min-width: 1024px- 后续修改仅改这里 */
/* ######################################################################### */
@media (min-width: 1024px) {
/* 卡片容器PC端特有高度自适应内容 */
.product-card-container {
align-items: flex-start; /* 改为flex-start避免拉伸 */
height: auto !important; /* 高度自适应内容 */
}
/* 卡片包裹容器PC端适配 */
.product-card-wrap {
display: contents;
}
/* 卡片核心PC端高度自适应内容 */
.product-card {
background: rgb(242, 243, 245);
border-radius: clamp(0.375rem, 1vw, 0.5rem);
cursor: pointer;
width: calc(25% - clamp(0.3rem, 0.5vw, 0.36rem));
flex: none;
box-shadow: 0 clamp(0.1rem, 0.2vw, 0.125rem)
clamp(0.3rem, 0.8vw, 0.5rem) rgba(0, 0, 0, 0.05);
margin: 0 clamp(0.16rem, 0.24vw, 0.2rem);
display: flex;
flex-direction: column;
height: auto !important; /* 高度自适应内容 */
}
/* 卡片hover效果PC端特有 */
.product-card:hover {
transform: scale(clamp(1.01, 1.02, 1.03));
transition: transform 0.3s ease;
}
/* 图片容器PC端高度自适应 */
.product-card-img {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
flex: 0 0 auto; /* 改为auto高度自适应 */
aspect-ratio: 3 / 2.8; /* 保持图片比例 */
margin-bottom: clamp(0.4rem, 0.6vw, 0.5rem);
overflow: hidden;
border-radius: clamp(0.2rem, 0.4vw, 0.25rem);
}
/* 产品图片PC端特有 */
.product-card img {
width: 100%;
height: 100%;
object-fit: contain;
object-position: center;
}
/* 文字容器PC端高度自适应 */
.product-card-text {
flex: 1 1 auto; /* 改为flex:1高度自适应内容 */
flex-direction: column;
justify-content: center;
padding-left: clamp(0.8rem, 2vw, 1.5rem);
padding-right: clamp(0.8rem, 2vw, 1.5rem);
display: flex; /* 确保flex布局 */
height: auto !important; /* 高度自适应 */
}
/* 标题样式PC端特有高度自适应 */
.product-card-title {
font-size: clamp(0.8rem, 1.3vw, 1.2rem);
font-weight: 600;
color: #333;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
height: auto !important; /* 高度自适应 */
margin-bottom: clamp(0.2rem, 0.4vw, 0.3rem); /* 添加间距 */
line-height: 1.2;
display: flex;
align-items: center;
}
/* 描述样式PC端高度自适应 */
.product-card-desc {
font-size: clamp(0.7rem, 1.1vw, 0.9rem);
color: #656565;
word-break: break-word;
height: auto !important; /* 高度自适应 */
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
line-height: 1.4;
}
/* 链接图标容器PC端高度自适应添加较小的底部内边距 */
.product-card-link {
width: 100%;
display: flex; /* 确保flex布局 */
align-items: center;
flex: 0 0 auto; /* 改为auto高度自适应 */
padding-left: clamp(0.8rem, 2vw, 1.5rem);
padding-bottom: clamp(1rem, 3vw, 1.5rem) ; /* 更小的底部内边距 */
height: auto !important; /* 高度自适应 */
}
/* 链接图标PC端特有 */
.product-card-link img {
width: clamp(2.5rem, 5vw, 4.5rem);
height: auto;
object-fit: contain;
}
}

View File

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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