536 Commits

Author SHA1 Message Date
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
81df05e0f9 1 2025-07-16 09:56:05 +08:00
e0fd77837d 1 2025-07-16 09:54:28 +08:00
7344691613 Merge branch 'master' of https://gitea.f2b211.com/jsasg/orico-official-website 2025-07-16 09:51:31 +08:00
fe697df167 1 2025-07-16 09:51:26 +08:00
b743688d99 Merge branch 'dev' 2025-07-15 15:00:51 +08:00
51b6841a3a fix: openapi token有效期配置 2025-07-15 15:00:38 +08:00
768ed5b0fb fix: openapi token有效期配置 2025-07-15 14:59:25 +08:00
0c2f96fd49 Merge branch 'dev' 2025-07-15 14:49:47 +08:00
40c8385776 perf: openapi token有效期配置 2025-07-15 14:49:03 +08:00
80c6647a0c Merge branch 'dev' 2025-07-15 14:45:54 +08:00
187a0affcc perf: openapi token有效期配置 2025-07-15 14:45:16 +08:00
a35288dd0b Merge branch 'dev' 2025-07-15 14:21:30 +08:00
b36627ec25 perf: openapi client授权过期 2025-07-15 14:21:16 +08:00
eb2a98e7fe fix: admapi 角色菜单权力model 2025-07-15 14:21:04 +08:00
5c79e33ce1 perf: openapi client授权过期 2025-07-15 14:20:36 +08:00
341e1f54fb fix: admapi 角色菜单权力model 2025-07-15 13:50:50 +08:00
78925fbbab Merge branch 'dev' 2025-07-15 10:48:30 +08:00
d9e056972c perf: .gitignore 2025-07-15 10:46:17 +08:00
b09f7d1e6f fix: mobile subcategory.html 2025-07-15 09:54:58 +08:00
ad0f7f4b87 fix: mobile subcategory.html 2025-07-15 09:54:38 +08:00
61e4ac1fb3 smallImgDown相对位置修改 2025-07-15 09:36:55 +08:00
728730433b bsImg 高度自适应 2025-07-15 09:32:07 +08:00
3a50a23cfa Merge branch 'master' of https://gitea.f2b211.com/jsasg/orico-official-website 2025-07-15 09:30:05 +08:00
1dc03040f1 .bttj 修改 2025-07-15 09:30:02 +08:00
900d73d389 fix: mobile subcategory.html 2025-07-15 09:25:25 +08:00
5b69987d6e perf: mobile 产品分类与搜索页改为缩略图 2025-07-15 09:22:21 +08:00
512c07b5a8 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-15 09:19:14 +08:00
885b86ded9 顶部底部自适应 2025-07-15 09:18:11 +08:00
c04b7cae38 fix: mobile view问题 2025-07-15 09:16:01 +08:00
3ff0137e4b Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-14 17:18:35 +08:00
15c18d5fc1 1 2025-07-14 17:06:45 +08:00
91b083f0e5 去掉新品的标题和更多 2025-07-14 17:05:44 +08:00
a3dccb8b19 sceneitem1 2025-07-14 16:41:58 +08:00
974f561c5a 1 2025-07-14 16:39:59 +08:00
8fd52854cc 1 2025-07-14 16:34:11 +08:00
b9b865ece0 1 2025-07-14 16:26:35 +08:00
acc39f4580 1 2025-07-14 16:25:49 +08:00
e82c201a2b 1 2025-07-14 16:24:22 +08:00
6927bdbc42 1 2025-07-14 16:23:25 +08:00
3db7e42e71 1 2025-07-14 16:09:53 +08:00
12bd511d0b 1 2025-07-14 16:09:02 +08:00
4a52be183c 1 2025-07-14 16:08:13 +08:00
58324ebb33 1 2025-07-14 16:07:06 +08:00
8ccca36e44 Merge branch 'master' of https://gitea.f2b211.com/jsasg/orico-official-website 2025-07-14 16:02:37 +08:00
d6c7a0f11e 样式修改6 2025-07-14 16:02:35 +08:00
858468b72b fix: 底部备案信息 2025-07-14 15:52:13 +08:00
3eadc5c3eb fix: 底部备案信息 2025-07-14 15:51:22 +08:00
fe324bc62f fix: 底部备案信息 2025-07-14 15:50:13 +08:00
2329b1bbe6 pref: 数据同步 2025-07-14 15:50:13 +08:00
134c75cc4b fix: 底部备案信息 2025-07-14 15:49:50 +08:00
3b737b0bd0 1 2025-07-14 15:46:47 +08:00
2da153e935 样式修改4 2025-07-14 15:46:18 +08:00
271f22ea18 样式修改2 2025-07-14 15:35:57 +08:00
4a56e7e980 Merge branch 'master' of https://gitea.f2b211.com/jsasg/orico-official-website 2025-07-14 15:13:12 +08:00
b3475a7d06 样式修改 2025-07-14 15:13:09 +08:00
988bdde6f1 pref: 数据同步 2025-07-14 14:30:59 +08:00
456209121e Merge branch 'dev' 2025-07-14 14:06:16 +08:00
8186a424de fix: 顶部搜索产品图片显示缩略图 2025-07-14 14:06:04 +08:00
ebc8c6431a Merge branch 'dev' 2025-07-14 13:44:06 +08:00
7cbb6adb5d fix: 视频描述字段长度校验 2025-07-14 13:43:52 +08:00
4b8963161f perf: 数据同步 2025-07-14 13:42:50 +08:00
eeb79e8c56 Merge branch 'dev' 2025-07-14 11:47:51 +08:00
2a503cbf68 fix: 产品详情购买链接排序 2025-07-14 11:47:41 +08:00
aed2ce4655 fix: pc 顶部“店铺”新标签打开 2025-07-14 11:27:59 +08:00
70b524ce04 Merge branch 'master' of https://gitea.f2b211.com/jsasg/orico-official-website 2025-07-14 11:27:38 +08:00
db82564148 style 2025-07-14 11:27:34 +08:00
386cd613ee fix: pc 顶部“店铺”新标签打开 2025-07-14 11:25:02 +08:00
dc8a3dc5da fix: pc 底部导航新标签页打开无效 2025-07-14 11:04:34 +08:00
4ec2985468 perf: 数据同步 2025-07-14 11:04:34 +08:00
796231a50e fix: pc 底部导航新标签页打开无效 2025-07-14 11:01:14 +08:00
6b082f2de9 perf: 数据同步 2025-07-14 11:00:43 +08:00
jsasg
83287098ee Merge branch 'dev' 2025-07-11 22:39:16 +08:00
jsasg
b67959163b fix: 图片上传 2025-07-11 22:34:32 +08:00
ba04d6d220 fix: 底部 2025-07-11 20:15:38 +08:00
457c06948c fix: 文章验证 2025-07-11 20:15:20 +08:00
c0b6ddf11b Merge branch 'dev' 2025-07-11 18:07:42 +08:00
a8960c3c81 fix: 底部 2025-07-11 18:07:25 +08:00
d4be3ff937 fix: 文章验证 2025-07-11 18:07:25 +08:00
751d4ce12d style:样式修改3 2025-07-11 17:15:44 +08:00
9c6e26ce05 style:样式调整 2025-07-11 16:52:09 +08:00
25a55ba9f5 style:样式修改 2025-07-11 16:32:58 +08:00
b8b8d8d58f fix:如果底部没有内容就不要显示li这个标签 2025-07-11 16:22:34 +08:00
31d747a0b0 style:样式修改 2025-07-11 16:13:49 +08:00
0025b0a5bb ljm master分支 2025-07-11 15:57:27 +08:00
002c4055eb Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-11 15:44:59 +08:00
738986d715 fix:pc导航修改 2025-07-11 15:44:56 +08:00
673f4d101a fix: mobile下没有jquery 2025-07-11 15:22:01 +08:00
553c010dc2 fix: 上传 2025-07-11 11:47:05 +08:00
c18ba2dbc2 fix: 导航未过滤已禁用 2025-07-11 10:32:05 +08:00
13eec27ea9 add:本地添加jQuery和swiper文件,防止cdn失效 2025-07-10 17:38:17 +08:00
84e41958c9 perf: mysql递归查询兼容处理 2025-07-10 17:30:01 +08:00
7045bd7b7d perf: 修改analytics 2025-07-09 17:30:02 +08:00
cbb0699fae pref: think文件 2025-07-09 16:34:27 +08:00
e1b4266513 perf: redis env配置 2025-07-09 16:15:58 +08:00
c109748c79 perf: env 2025-07-09 13:58:59 +08:00
87b4917120 fix: 同步产品目录产品分类及产品 2025-07-09 11:32:59 +08:00
48e3ec7c2c · 2025-07-09 10:25:02 +08:00
92679d3ebc 样式修改 2025-07-09 10:21:48 +08:00
dc94ec5f5f Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-08 10:54:46 +08:00
c67ae635d8 style:样式修改 2025-07-08 10:54:43 +08:00
4233efe422 fix: 后台图片上传路径bug 2025-07-07 18:01:12 +08:00
28e3e08f86 fix: 后台图片上传路径bug 2025-07-07 17:50:52 +08:00
be7f4edff5 pref: 图片大小调整 2025-07-07 16:39:02 +08:00
3d777043e8 pref: 图片大小调整 2025-07-07 16:22:51 +08:00
9aafb6321b 1 2025-07-07 15:27:22 +08:00
942a5706ca 1 2025-07-07 15:23:30 +08:00
73b8562d71 style:单词换行 2025-07-07 15:21:44 +08:00
c3733e24a7 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-07 15:15:32 +08:00
eeaa27d0b4 style:品类换行 2025-07-07 15:15:30 +08:00
a5e20a3840 feat: migration/seed 2025-07-05 18:01:22 +08:00
d809690724 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-05 17:35:30 +08:00
447885529e style:样式调整 2025-07-05 17:35:27 +08:00
89e46189bd feat: 后台 图片上传新增webp格式转换处理 2025-07-05 15:19:46 +08:00
29ea63199c fix: openapi 文章详情取消author,source字段输出 2025-07-05 14:41:32 +08:00
3ef1fc634a fix: openapi 文章分类取消short_name, desc字段输出 2025-07-05 14:02:17 +08:00
4d988c316b fix: openapi 取消产品分类icon,desc字段输出 2025-07-05 14:01:51 +08:00
9182ed29d9 fix: openapi取消产品详情sku->sort字段输出 2025-07-05 13:47:57 +08:00
e1388c63b7 fix: openapi 产品接口取消desc输出 2025-07-05 11:49:55 +08:00
a0d53c6e0e 返回顶部 只要页面过长就显示 2025-07-05 11:12:52 +08:00
6603af60ef id修改为类,间距调整 2025-07-05 10:20:59 +08:00
336f27bc23 Merge branch 'cssupdate' into dev 2025-07-05 09:53:30 +08:00
65ccd97e32 产品详情切换问题修改 2025-07-05 09:51:50 +08:00
256975b592 doc: 注释 2025-07-05 09:18:24 +08:00
90508c8c37 fix: openapi 产品详情不输出links->platform问题 2025-07-04 17:42:29 +08:00
f7ced51c4d Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-04 17:17:41 +08:00
aee2f81601 style:样式修改 2025-07-04 17:17:38 +08:00
cc85925f37 fix: pc nas专题页 导航选中状态 2025-07-04 16:40:03 +08:00
8897a3bbda fix: openapi 产品列表 2025-07-04 10:34:23 +08:00
9292e40053 fix: mobile 产品详情页图册中视频放第一个sku下最后一个 2025-07-03 14:01:34 +08:00
57058dd150 fix: pc 产品详情页图册中视频放第一个sku下最后一个 2025-07-03 13:56:57 +08:00
8237fb50ce fix: mobile nas专题顶部导航 2025-07-02 15:30:25 +08:00
6e2800f361 fix: pc 文章提交提示语言未区分语言 2025-07-02 15:06:28 +08:00
8bb323f3f5 pref: pc 产品详情表单提交 2025-07-02 14:44:35 +08:00
c85cb4af54 fix: pc 产品搜索结果分布 2025-07-02 14:19:53 +08:00
5d4baf4383 perf: 关键词高亮 2025-07-02 10:59:01 +08:00
dbf0a65ee7 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-02 10:57:38 +08:00
46c72f1146 swiper uc兼容 2025-07-02 10:57:35 +08:00
2a1c9f7825 feat: 从产品目录同步产品相关数据 2025-07-02 10:44:55 +08:00
878885377c fix: pc nas专题页 联系我们第一项无js效果 2025-07-02 10:44:55 +08:00
8841bc9819 style:样式问题修改8 2025-07-02 10:44:29 +08:00
bde8ef0bb3 style:样式问题修改7 2025-07-02 10:44:29 +08:00
8e78f95002 feat: 同步数据接收 2025-07-01 17:15:40 +08:00
77706e5bcb fix: 产品搜索关键词高亮 2025-07-01 17:14:04 +08:00
1100e347bd style:样式问题修改8 2025-07-01 17:03:46 +08:00
de44890014 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-01 16:43:00 +08:00
f970f22539 style:样式问题修改7 2025-07-01 16:42:57 +08:00
90c1be254b fix: mobile nas专题header头 2025-07-01 16:04:35 +08:00
87c3180229 fix: nas专题 head_languages变量报错 2025-07-01 16:04:35 +08:00
74942de6db style:样式问题修改6 2025-07-01 15:48:15 +08:00
04fb5cd3b1 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-01 15:42:07 +08:00
52a1756d5b style:样式问题修改6 2025-07-01 15:42:04 +08:00
ecd2602d35 fix: nas专题 移动端去掉顶部搜索与语言切换 2025-07-01 15:26:53 +08:00
0de7fce26d Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-01 15:24:21 +08:00
46b85b090d style:样式问题修改5 2025-07-01 15:24:18 +08:00
1074b99bb8 fix: nas专题 移动端去掉顶部搜索与语言切换 2025-07-01 15:20:44 +08:00
11091d46e9 style:样式问题修改4 2025-07-01 15:18:24 +08:00
4836f113fa 1 2025-07-01 15:14:53 +08:00
9b7679af30 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-01 15:09:10 +08:00
cc8258c764 1 2025-07-01 15:09:07 +08:00
f8734366f1 fix: 后台banner分类接口 2025-07-01 15:08:22 +08:00
b625a23856 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-01 15:03:28 +08:00
6d2135b862 style:样式问题修改3 2025-07-01 15:03:25 +08:00
927c4c65a9 fix: mobile 产品详情页相关产品 2025-07-01 14:08:21 +08:00
1295706704 fix: pc/mobile 联系我们页面文字颜色 2025-07-01 13:53:42 +08:00
50dade9517 style:样式问题修改2 2025-07-01 11:41:54 +08:00
26af0577ad Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-07-01 11:28:00 +08:00
ec20bd3741 style:样式问题修改 2025-07-01 11:27:56 +08:00
c13fcc2cb9 feat: analytics代码添加 2025-07-01 09:47:21 +08:00
74e7e145af fix: pc 视频搜索 2025-06-30 16:48:35 +08:00
b68c56cfdc refactor: 修改各表user_agent字段长度 2025-06-30 15:18:54 +08:00
e60b2a02a1 fix: pc/mobile banner的extra_image取值 2025-06-30 10:57:06 +08:00
9a9b714aad refactor: 后台横幅添加extra_image字段 2025-06-30 09:24:44 +08:00
9ab935e1ff Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-06-27 18:04:03 +08:00
c5e28d153d 样式修改 2025-06-27 18:04:00 +08:00
023ebf775d fix: 产品分类颜色 2025-06-27 17:30:01 +08:00
f086dd0239 fix: pc 文章分类搜索 2025-06-27 17:17:26 +08:00
69e45a8044 fix: ipd访问时lang错误 2025-06-27 17:11:03 +08:00
bdd6a7ba34 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-06-27 17:03:21 +08:00
cbb6bc144b 判读uc浏览器swiper的问题 2025-06-27 17:03:18 +08:00
304f7c460d fix: 产品底盘提示语 2025-06-27 15:20:25 +08:00
163de38bb2 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-06-27 14:54:30 +08:00
62baecc835 富文本图片排版 2025-06-27 14:54:27 +08:00
1dd37485a2 fix: pc/mobile 产品详情页属性 2025-06-27 14:49:24 +08:00
6eca3790d3 样式优化 2025-06-27 11:42:01 +08:00
61c7d32f50 .hd .clearfix 2025-06-27 10:59:15 +08:00
35e11d7d8f 还原 2025-06-27 10:58:14 +08:00
999bb94f70 样式 2025-06-27 10:57:26 +08:00
bd9e6009ad 1 2025-06-27 10:44:55 +08:00
47d9be28fa 1 2025-06-27 10:44:17 +08:00
e765dd4153 1 2025-06-27 10:43:05 +08:00
207106c34c 1 2025-06-27 10:41:56 +08:00
2af9f63b83 还原 2025-06-27 10:39:48 +08:00
dd3672c93a 样式优化 2025-06-27 10:29:25 +08:00
9fb3d8f874 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-06-27 10:20:20 +08:00
519160218f style:样式优化,手机详情页测试 2025-06-27 10:20:17 +08:00
81ec4a84a8 fix: 后台附件上传修改webp格式 2025-06-27 09:55:20 +08:00
a29e95a951 refactor: 后台图片上传添加允许webp格式 2025-06-27 09:54:30 +08:00
239bb64e9a fix: pc 去除多条console.log 2025-06-27 09:38:53 +08:00
774954c70b fix: mobile 产品搜索 2025-06-27 09:37:50 +08:00
a3f8668b60 fix: mobile 底部导航 2025-06-27 09:37:32 +08:00
3cb48fd462 refactor: ipd平台访问重定向为mobile view改为可配置 2025-06-27 09:18:09 +08:00
778e7180d7 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-06-26 16:31:59 +08:00
1eecd80340 视频被遮盖样式调整 2025-06-26 16:31:56 +08:00
0ba42e2a20 fix: 跳转mtpl时会去掉正常参数导致无数据问题 2025-06-26 16:04:56 +08:00
55e8e914fb fix: mobile nas专题 下载页样式问题 2025-06-26 15:50:01 +08:00
37828dafca 样式补充3 2025-06-26 15:40:56 +08:00
043bac94ec 样式修改2补充 2025-06-26 15:38:13 +08:00
e7b76ea68b 样式修改2 2025-06-26 15:34:33 +08:00
e9a2165b10 样式修改 2025-06-26 15:29:42 +08:00
93bf23f307 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-06-26 15:22:31 +08:00
fcd562595d bug修改 2025-06-26 15:22:28 +08:00
4444875e48 fix: mobile nas专题 下载页中英文样式区别 2025-06-26 15:07:51 +08:00
5e8f7549e0 style:样式修改 2025-06-26 15:02:10 +08:00
f0ea57c19f Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-06-26 13:44:43 +08:00
ed8ae64cac 还原 2025-06-26 13:44:40 +08:00
4b3f626443 fix: pc/mobile 产品详情“发送查询”按钮问题 2025-06-26 11:42:52 +08:00
d06378e264 style: 代码格式 2025-06-26 11:40:05 +08:00
0ea2fbeb1f Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-06-26 11:37:10 +08:00
cb5f4a6148 前端测试pad和pc 2025-06-26 11:36:30 +08:00
fed50a9f4c style: openapi模块代码对齐 2025-06-26 10:52:55 +08:00
d94ceb2a9c fix: ipd中区分mobile与pc问题bug 2025-06-26 10:14:32 +08:00
307c80e5e9 fix: mobile 非nas专题页顶部logo无法点击问题 2025-06-25 16:55:54 +08:00
873d043e45 fix: mobile 产品详情去除空字符串属性 2025-06-25 16:52:49 +08:00
dd328e5b9e fix: mobile nas 专题相关页面Logo点击区分中英文 2025-06-25 16:46:10 +08:00
fb135cd1dc fix: mobile nas专题 帮助中心去除logo点击链接 2025-06-25 13:37:48 +08:00
65b1fcd992 fix: mobile 产品详情相关产品输出 2025-06-25 09:52:06 +08:00
7ac132a182 fix: mobile 产品详情页属性选项 2025-06-25 09:44:47 +08:00
929608b9b9 fix: mobile 文章详情页评论记录 2025-06-25 09:27:12 +08:00
cdd4d0d09f fix: mobile 成功经销商校验bug 2025-06-24 18:02:56 +08:00
9c4cccbeb0 fix: mobile 批量购买提交bug 2025-06-24 18:00:43 +08:00
34866fd9fe fix: mobile 联系我们留言 2025-06-24 17:55:05 +08:00
c9107fce72 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-06-24 17:52:08 +08:00
4953163892 fix: mobile 文章详情英文发布时间 2025-06-24 17:51:34 +08:00
cb87b3203c Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-06-24 17:51:31 +08:00
35329b25e8 feat:样式bug移动端修改 2025-06-24 17:51:29 +08:00
6dd714dce7 fix: mobile 产品搜索无数据情况 2025-06-24 17:50:07 +08:00
80dbc75c73 fix: mobile nas专题帮助中心 2025-06-24 17:29:03 +08:00
e76fcf2822 fix: pc顶部导航 2025-06-24 14:22:38 +08:00
b4b36aa988 fix: 文章详情推荐文章 2025-06-24 14:13:55 +08:00
20deefdd5f fix: 获取系统页面url 2025-06-24 13:52:41 +08:00
迷和油
475fe19d84 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-06-21 15:21:59 +08:00
迷和油
eba4a1c96e style:样式修改 2025-06-21 15:21:56 +08:00
b4903854c1 fix: pc/mobile 批量够买问题 2025-06-21 14:12:04 +08:00
44057cb26d fix: pc/mobile 成功经销商留言问题 2025-06-21 14:05:57 +08:00
c5f88098f5 fix: mobile 文章列表发布时间问题 2025-06-21 10:21:32 +08:00
9a220bbb97 fix: mobile 产品搜索页无法点击进入详情问题 2025-06-21 10:15:17 +08:00
8ec4fd9dce fix: mobile搜索历史问题 2025-06-20 14:21:34 +08:00
迷和油
2566538006 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-06-20 14:10:46 +08:00
迷和油
64ff307d57 style:顶部宽度修改 2025-06-20 13:56:59 +08:00
e7a232ac9c refactor: cookir开启httponly 2025-06-20 13:43:20 +08:00
4f3c5fdee2 fix: 文章详情页推荐未区分中英文问题 2025-06-20 13:42:55 +08:00
eea5f83afc fix: 屏幕宽度确定pc/mobile模板问题 2025-06-20 11:29:41 +08:00
53086a83d1 fix: pc nas专题帮助中心文件分类选中问题 2025-06-19 16:51:58 +08:00
96d693af64 fix: 文章列表及详情发布时间中英显示区分 2025-06-19 16:26:17 +08:00
迷和油
70266967e1 reset:还原 2025-06-19 11:50:22 +08:00
迷和油
24959571b7 test:环境测试2 2025-06-19 11:34:53 +08:00
迷和油
5c4aa9e21d test:环境测试 2025-06-19 11:24:57 +08:00
迷和油
474ea78de5 test:测试环境 2025-06-19 11:07:24 +08:00
迷和油
addf3abae0 测试环境 2025-06-19 11:06:31 +08:00
ed5f6e0642 fix: migrations seed命名错误 2025-06-19 11:02:33 +08:00
d2bb8fbf01 fix: 无法判断出是ipad的情况 2025-06-19 10:08:40 +08:00
421d549109 docs: 修改migrations文件中的表注释 2025-06-16 15:04:26 +08:00
a2d03eb0d0 fix: “代理商企业规模类型表”migrations文件表命名错误 2025-06-13 14:44:54 +08:00
425a438852 fix: 返回顶部按钮只在中文下显示 2025-06-13 14:22:55 +08:00
迷和油
ac249f0a18 add:新增一个中文官网返回顶部的功能 2025-06-13 11:44:10 +08:00
55b45a0aef refactor: 上传 2025-06-12 17:56:20 +08:00
e6733ba338 refactor: 配置seeder 2025-06-12 17:51:52 +08:00
cea787d493 fix: pc产品详情 2025-06-12 17:46:45 +08:00
a8f3aa3a1b refactor: 处理优化migration文件与model文件字段不一致 2025-06-12 17:41:14 +08:00
c8284568aa feat: 系统用户seeder 2025-06-12 16:26:25 +08:00
306d3faa71 feat: 系统菜单seeder 2025-06-12 16:21:59 +08:00
49193a8d52 feat: 系统语言seeder 2025-06-12 16:04:35 +08:00
c138bf501e feat: 国家seeder 2025-06-12 16:00:08 +08:00
127901d864 feat: 代理商企业规模类型seeder 2025-06-12 15:54:54 +08:00
5a15210d00 feat: 代理商业务类型seeder 2025-06-12 15:50:21 +08:00
184595ce36 feat: 产品属性特性seeder 2025-06-12 15:41:51 +08:00
4214331fd3 feat: 产品购买平台seeder 2025-06-12 15:31:36 +08:00
57aba229cd feat: 配置项类型seeder 2025-06-12 15:20:27 +08:00
add17eac0c feat: 配置组/配置数据seeder 2025-06-12 15:09:59 +08:00
8f9e304294 refactor: 上传相关优化 2025-06-12 14:50:20 +08:00
6bd988f257 fix: pc nas专题帮且中心 2025-06-11 18:14:00 +08:00
0665cccd9d fix: pc文章详情发布时间中英文区分 2025-06-11 18:09:08 +08:00
80e4b502d1 fix: pc nas专题logo不需要点击 2025-06-11 18:02:12 +08:00
d522c862c2 fix: pc产品详情 2025-06-11 17:40:43 +08:00
8eee103fb6 fix: pc产品详情 2025-06-11 17:32:57 +08:00
迷和油
41fc9b81e7 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-06-11 17:24:11 +08:00
迷和油
414b79c2d8 style:搜索更改,样式更改 bug提交 2025-06-11 17:23:30 +08:00
f48f2265d8 fix: 上传图片水印 2025-06-11 17:09:41 +08:00
50f4e5db55 fix: 上传图片水印 2025-06-11 16:59:02 +08:00
adbfc34f9d fix: 上传图片水印处理 2025-06-11 16:51:13 +08:00
aa4d5b5f31 fix: 上传 2025-06-11 15:40:37 +08:00
0c4c40ce7f fix: 水印处理 2025-06-11 15:36:44 +08:00
abef3a7750 fix: pc成功经销商 2025-06-11 15:17:14 +08:00
e746952c11 refactor: 附件上传允许上传ttf字体 2025-06-11 14:47:21 +08:00
00f3cda6ac feat: 图片上传水印处理 2025-06-11 14:46:40 +08:00
a823cfaf91 fix: nas帮助中心搜索 2025-06-11 11:38:25 +08:00
51d31a1a6d fix: 后台产品分类系统urls 2025-06-11 11:03:00 +08:00
b2699a952e fix: pc附件搜索placeholder 2025-06-11 10:55:55 +08:00
5c84e7e390 refactor: 系统其他urls回显 2025-06-10 15:00:50 +08:00
648fde842c refactor: 后台视频列表/回收站输出缩略图 2025-06-10 14:33:37 +08:00
e927468965 refactor: 添加其他内页系统urls 2025-06-10 14:31:06 +08:00
a8f7758f46 fix: 顶部“店铺”按钮不能显示在中文 2025-06-10 10:08:08 +08:00
a79adefd64 fix: 首页热点产品无点击链接 2025-06-10 10:01:50 +08:00
76a652661c fix: nas主题相关页排序bug 2025-06-10 09:58:22 +08:00
迷和油
357f1fa4c0 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-06-09 16:42:40 +08:00
迷和油
c0227d2d4a style:样式bug修改 2025-06-09 16:42:34 +08:00
4779280647 refactor: 修改样式文件命名 2025-06-09 14:58:39 +08:00
776163bb09 style: mobile 语言文件 2025-06-09 14:50:59 +08:00
2333dcd188 feat: mobile nas主题客户合作页 2025-06-09 14:47:28 +08:00
9f0ad41e8f feat: mobile nas主题下载页 2025-06-09 13:49:58 +08:00
230114d110 feat: mobile nas主题产品体验页 2025-06-09 10:56:54 +08:00
迷和油
0f1e480935 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-06-09 10:55:08 +08:00
迷和油
e70b793e2b 6.9 2025-06-09 10:55:02 +08:00
a1412898af refactor: mobile nas主题帮助中心页 2025-06-09 10:37:20 +08:00
69fe15b9b6 feat: mobile nas主题帮助中心详情页 2025-06-09 10:29:50 +08:00
ae8fc70e97 fix: 横幅查询未过滤禁用的数据 2025-06-07 16:56:43 +08:00
56029236bd fix: 修复后台横幅关联产品分类提交 2025-06-07 16:48:01 +08:00
fa2b67c5b5 fix: nas 产品体验页焦点图bug 2025-06-07 16:41:51 +08:00
38ad0bc700 feat: mobile nas主题帮助中心页 2025-06-07 16:36:44 +08:00
迷和油
3e8643d1fa Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-06-07 16:04:29 +08:00
迷和油
bd0cde3261 优化 2025-06-07 16:04:25 +08:00
76b987205f fix: mobile 修复获取产品分类焦点图未区分pc与mobile数据 2025-06-07 16:04:20 +08:00
迷和油
77bd7e1031 Merge branch 'dev' of https://gitea.f2b211.com/jsasg/orico-official-website into dev 2025-06-07 15:50:27 +08:00
迷和油
65d636177f 评论样式修复 2025-06-07 15:50:22 +08:00
214 changed files with 9875 additions and 1970 deletions

5
.env
View File

@@ -1,5 +0,0 @@
[JWT]
TTL=3600
REFRESH_TTL=20160
SECRET=b43e6276644ed60e65c50d1b324ba10b

View File

@@ -1,32 +0,0 @@
APP_DEBUG = true
DB_TYPE = mysql
DB_HOST = localhost
DB_NAME = orico-official-website
DB_USER = orico-ow
DB_PASS = 14Xi17NIK8V2qAXE8oMataHEsaR8lE
DB_PORT = 3306
DB_CHARSET = utf8mb4
DB_PREFIX = ow_
DEFAULT_LANG = zh-cn
# 前端代理服务器ip影响使用代理访问情况下的客户端ip获取
PROXY_SERVER_IP[] = 120.79.27.160
[JWT]
TTL=3600
REFRESH_TTL=20160
SECRET=b43e6276644ed60e65c50d1b324ba10b
# 后台不需要登录的接口
[ADMIN_AUTH]
WHITE_LIST[] = v1/user/login
WHITE_LIST[] = v1/user/captcha
# 不需记录日志的接口
[ADMIN_API]
IGNORE_LOGGING_LIST[] = v1/OperateLog/index
MAX_IMAGE_SIZE = 5mb # 图片上传最大限制
MAX_VIDEO_SIZE = 150mb # 视频上传最大限制
MAX_ATTACHMENT_SIZE = 100mb # 附件上传最大限制

View File

@@ -1,37 +0,0 @@
APP_DEBUG = true
DB_TYPE = mysql
DB_HOST = 127.0.0.1
DB_NAME = orico-official-website
DB_USER = orico-official-website
DB_PASS = 14Xi17NIK8V2qAXE8oMataHEsaR8lE
DB_PORT = 3306
DB_CHARSET = utf8mb4
DB_PREFIX = ow_
DEFAULT_LANG = zh-cn
# 前端代理服务器ip影响使用代理访问情况下的客户端ip获取
PROXY_SERVER_IP[] = 120.79.27.160
[JWT]
TTL=3600
REFRESH_TTL=20160
SECRET=b43e6276644ed60e65c50d1b324ba10b
# 后台不需要登录的接口
[ADMIN_AUTH]
WHITE_LIST[] = v1/user/login
WHITE_LIST[] = v1/user/captcha
# 不需记录日志的接口
[ADMIN_API]
IGNORE_LOGGING_LIST[] = v1/OperateLog/index
MAX_IMAGE_SIZE = 5mb; # 图片上传最大限制
MAX_VIDEO_SIZE = 150mb; # 视频上传最大限制
MAX_ATTACHMENT_SIZE = 100mb; # 附件上传最大限制
# 开放API
[OPENAPI]
RESOURCE_IMAGES_DOMAIN = http://local.orico.com; # 图片资源服务器地址
RESOURCE_VIDEOS_DOMAIN = http://local.orico.com; # 视频资源服务器地址

View File

@@ -1,11 +1,96 @@
APP_DEBUG = true APP_DEBUG = true
DB_TYPE = mysql DB_TYPE = mysql
DB_HOST = 127.0.0.1 DB_HOST = localhost
DB_NAME = test DB_NAME = orico-official-website
DB_USER = username DB_USER = orico-ow
DB_PASS = password DB_PASS = 14Xi17NIK8V2qAXE8oMataHEsaR8lE
DB_PORT = 3306 DB_PORT = 3306
DB_CHARSET = utf8 DB_CHARSET = utf8mb4
DB_PREFIX = ow_
DB_VERSION = 8
DEFAULT_LANG = zh-cn DEFAULT_LANG = zh-cn
# 前端代理服务器ip影响使用代理访问情况下的客户端ip获取
PROXY_SERVER_IP[] = 120.79.27.160
# redis 配置
REDIS_HOST = 127.0.0.1
REDIS_PORT = 6379
REDIS_PASSWORD = ''
REDIS_PREFIX = ow:
[JWT]
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
WHITE_LIST[] = v1/user/captcha
WHITE_LIST[] = receive_sync/category
WHITE_LIST[] = receive_sync/product
# 不需记录日志的接口
[ADMIN_API]
IGNORE_LOGGING_LIST[] = v1/OperateLog/index
MAX_IMAGE_SIZE = 5mb; # 图片上传最大限制
MAX_VIDEO_SIZE = 150mb; # 视频上传最大限制
MAX_ATTACHMENT_SIZE = 100mb; # 附件上传最大限制
# 开放API
[OPENAPI]
ACCESS_TOKEN_LIFETIME = 3600; # 访问令牌有效期
REFRESH_TOKEN_LIFETIME = 1209600; # 刷新令牌有效期
RESOURCE_IMAGES_DOMAIN = http://local.orico.com; # 图片资源服务器地址
RESOURCE_VIDEOS_DOMAIN = http://local.orico.com; # 视频资源服务器地址
# 七牛云存储配置
[QINUI]
BUCKET = orico
BASE_URL = http://local.orico.com
ACCESS_KEY = 1234567890
SECRET_KEY = 1234567890
# 前台视图模板规则配置
[INDEX_VIEW_TPL]
# 视图目录
# query 规则URL参数 mtpl=1 表示移动端访问
# 例如http://xxxx.com?mtpl=1
# domain 规则:根据特定域名,判断是否移动端访问
# 例如http://mobile.orico.cn
RULE = query
# query 规则参数名
RULE_QUERY_NAME = mtpl
# query 规则参数值
RULE_QUERY_VALUE = 1
# domain 规则协议
RULE_DOMAIN_SCHEME[] = http
RULE_DOMAIN_SCHEME[] = https
# domain 规则域名
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

6
.gitignore vendored
View File

@@ -3,7 +3,13 @@ composer.phar
composer.lock composer.lock
.DS_Store .DS_Store
Thumbs.db Thumbs.db
.env
.env.dev
.env.local
.env.prod
public/dist
public/opendoc
/.idea /.idea
/.vscode /.vscode
/vendor /vendor

View File

@@ -0,0 +1,219 @@
<?php
declare (strict_types = 1);
namespace app\admin\controller;
use app\admin\model\v1\LanguageModel;
use app\admin\model\v1\ProductCategoryModel;
use app\admin\model\v1\ProductModel;
use app\admin\model\v1\ProductTcoCategoryModel;
use think\facade\Db;
class Operate_Of_ReceiveSync
{
const Add = 'add';
const Update = 'update';
const Enable = 'enable';
const Disable = 'disable';
}
/**
* 接收产品相关同步数据
*/
class ReceiveProductSync
{
// 接收产品目录分类同步数据
public function category()
{
$data = request()->post();
if (empty($data)) return error('请确认同步数据');
$validate = validate([
'name|分类名称' => 'require',
'erp_code|分类ERP编码' => 'require',
]);
if (!$validate->check($data)) {
return error((string)$validate->getError());
}
// 获取对应语言ID
$lang_id = LanguageModel::where('code', $data['lang'])->value('id');
if (empty($lang_id)) {
return error('语言不存在');
}
Db::startTrans();
try {
$tco_category_data = [
'language_id' => $lang_id,
'name' => $data['name'],
'tco_id' => $data['tco_id'],
'tco_pid' => $data['tco_pid'],
'tco_path' => $data['tco_path'],
'erp_id' => $data['erp_id'],
'erp_pid' => $data['erp_pid'],
'erp_code' => $data['erp_code'],
'erp_path' => $data['erp_path'],
'disabled' => Operate_Of_ReceiveSync::Disable == $data['operate'] ? 1 : 0,
'sync_time' => strtotime($data['created_at'])
];
$tco_category = ProductTcoCategoryModel::language($lang_id)->erpCode($tco_category_data['erp_code'])->find();
if (empty($tco_category)) {
$tco_category = ProductTcoCategoryModel::create($tco_category_data);
if ($tco_category->isEmpty()) {
throw new \Exception('产品目录分类创建失败');
}
$category_data = [
'language_id' => $lang_id,
'unique_id' => uniqid('PRO_CATE_'),
'pid' => 0,
'path' => '',
'name' => $tco_category_data['name'],
'icon' => '',
'desc' => '',
'related_tco_category' => $tco_category['id'],
'sort' => 0,
'level' => 1,
'is_show' => 1,
];
$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_data['pid'] = $parent['id'];
$category_data['path'] = $parent['path'] . $parent['pid'];
$category_data['level'] = $parent['level'] + 1;
}
$category = ProductCategoryModel::create($category_data);
if ($category->isEmpty()) {
throw new \Exception('产品分类创建失败');
}
}
else if ($tco_category['sync_time'] < $tco_category_data['sync_time']) {
$success = $tco_category->save($tco_category_data);
if (!$success) {
throw new \Exception('产品目录分类更新失败');
}
$category = ProductCategoryModel::language($lang_id)->tcoId($tco_category['id'])->find();
if (!empty($category)) {
$tco_parent = ProductTcoCategoryModel::language($lang_id)->tcoId($tco_category['tco_pid'])->find();
if (!empty($tco_parent)) {
$parent = ProductCategoryModel::language($lang_id)->tcoId($tco_parent['id'])->find();
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('产品分类更新失败');
}
}
}
Db::commit();
} catch (\Throwable $th) {
Db::rollback();
return error(sprintf('%s %s:%d', $th->getMessage(), $th->getFile(), $th->getLine()));
}
return success('同步成功');
}
// 接收产品同步数据
public function product()
{
$data = request()->post();
if (empty($data)) {
return error('请确认同步数据');
}
$validate = validate([
'spu' => 'require',
'name' => 'require',
'category_erp_code' => 'require',
'lang' => 'require',
'created_at' => 'require',
]);
if (!$validate->check($data)) {
return error((string)$validate->getError());
}
// 获取对应语言ID
$lang_id = LanguageModel::where('code', $data['lang'])->value('id');
if (empty($lang_id)) {
return error('语言不存在');
}
// 如果 spu_before_modification 存在则根据 spu_before_modification 更新型号
$product = null;
if (!empty($data['spu_before_modification'])) {
$product = ProductModel::language($lang_id)->spu($data['spu_before_modification'])->find();
}
if (
(empty($data['spu_before_modification']) && !empty($data['spu']))
// 避免 spu_before_modification 更新型号时,人为删除了旧型号导致的新增,从而出现重复型号问题,而进行再次验证
|| (!empty($data['spu_before_modification']) && empty($product))
) {
$product = ProductModel::language($lang_id)->spu($data['spu'])->find();
}
try {
$product_tco_category = ProductTcoCategoryModel::language($lang_id)->erpCode($data['category_erp_code'])->find();
if (empty($product_tco_category)) {
throw new \Exception('官网未找到产品目录同步分类');
}
$product_category = ProductCategoryModel::language($lang_id)->tcoId($product_tco_category['id'])->find();
if (empty($product_category)) {
throw new \Exception('官网未找到产品目录同步分类关联的分类');
}
if (empty($product)) {
$product = ProductModel::create([
'language_id' => $lang_id,
'category_id' => $product_category['id'],
'spu' => $data['spu'],
'name' => $data['name'],
'short_name' => '',
'cover_image' => '',
'desc' => '',
'video_img' => '',
'video_url' => '',
'is_sale' => 1,
'is_new' => 0,
'is_hot' => 0,
'is_show' => 0,
'sort' => 0,
'detail' => '',
'status' => Operate_Of_ReceiveSync::Disable == $data['operate'] ? -1 : 1,
'seo_title' => '',
'seo_keywords' => '',
'seo_desc' => '',
'updated_at' => $data['created_at'],
]);
if ($product->isEmpty()) {
throw new \Exception('产品创建失败');
}
}
else if (strtotime($product['updated_at']) < strtotime($data['created_at'])) {
$product->spu = $data['spu'];
$product->name = $data['name'];
$product->category_id = $product_category['id'];
$product->status = Operate_Of_ReceiveSync::Disable == $data['operate'] ? -1 : 1;
if (!$product->save()) {
throw new \Exception('产品更新失败');
}
}
} catch (\Throwable $th) {
return error(sprintf('%s %s:%d', $th->getMessage(), $th->getFile(), $th->getLine()));
}
return success('同步成功');
}
}

View File

@@ -228,7 +228,7 @@ class Article
private function getExportArticleData() private function getExportArticleData()
{ {
$server = request()->server(); $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']); $param = request()->param(['title', 'category_id', 'release_time']);
$data = ArticleModel::field([ $data = ArticleModel::field([
'*', '*',
@@ -253,7 +253,7 @@ class Article
]) ])
->bindAttr('category', ['category_name' => 'name']) ->bindAttr('category', ['category_name' => 'name'])
->each(function ($item) use($image_host) { ->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; return $item;
}); });

View File

@@ -34,12 +34,12 @@ class Banner
$datas = []; $datas = [];
if (!$banners->isEmpty()) { if (!$banners->isEmpty()) {
$temp = []; $temp = [];
$map = ['pc' => 'PC端', 'mobile' => '移动端']; $map = ['pc' => ['id' => -1, 'name' => 'PC端'], 'mobile' => ['id' => -2, 'name' => '移动端']];
foreach ($banners as $banner) { foreach ($banners as $banner) {
if (!isset($temp[$banner->at_platform])) { if (!isset($temp[$banner->at_platform])) {
$temp[$banner->at_platform] = [ $temp[$banner->at_platform] = [
'id' => 0, 'id' => $map[$banner->at_platform]['id'] ?? 0,
'name' => $map[$banner->at_platform] ?? '未知平台', 'name' => $map[$banner->at_platform]['name'] ?? '未知平台',
'children' => [] 'children' => []
]; ];
} }

View File

@@ -105,6 +105,7 @@ class BannerItem
'desc_txt_color', 'desc_txt_color',
'type', 'type',
'image', 'image',
'extra_image',
'video', 'video',
'link_to' => 'custom', 'link_to' => 'custom',
'link', 'link',
@@ -159,6 +160,7 @@ class BannerItem
'desc_txt_color', 'desc_txt_color',
'type', 'type',
'image', 'image',
'extra_image',
'video', 'video',
'link_to', 'link_to',
'link', 'link',
@@ -187,10 +189,7 @@ class BannerItem
// 更新关联的产品分类 // 更新关联的产品分类
if (!empty($put['rel_prod_cate_id'])) { if (!empty($put['rel_prod_cate_id'])) {
$ok = SysBannerProdCateMappingModel::where('banner_item_id', '=', $id)->delete(); SysBannerProdCateMappingModel::where('banner_item_id', '=', $id)->delete();
if (!$ok) {
throw new InvalidOperateException('更新横幅与产品分类关联失败');
}
$mapping = SysBannerProdCateMappingModel::create([ $mapping = SysBannerProdCateMappingModel::create([
'banner_item_id' => $id, 'banner_item_id' => $id,
'product_category_id' => $put['rel_prod_cate_id'] 'product_category_id' => $put['rel_prod_cate_id']
@@ -245,6 +244,7 @@ class BannerItem
'desc_txt_color' => '描述字体颜色', 'desc_txt_color' => '描述字体颜色',
'type' => '前台显示类型', 'type' => '前台显示类型',
'image' => '图片地址', 'image' => '图片地址',
'extra_image' => '额外图片地址',
'video' => '视频地址', 'video' => '视频地址',
'link_to' => '链接类型', 'link_to' => '链接类型',
'link' => '链接地址', 'link' => '链接地址',
@@ -262,11 +262,9 @@ class BannerItem
// 获取导出数据 // 获取导出数据
private function getBannerExportData() private function getBannerExportData()
{ {
$param = request()->param([ $server = request()->server();
'title', $image_host = $server['REQUEST_SCHEME'] . "://" . $server['SERVER_NAME'] . '/';
'banner_id', $param = request()->param(['title', 'banner_id', 'created_at']);
'created_at'
]);
return SysBannerItemModel::alias('item') return SysBannerItemModel::alias('item')
->field([ ->field([
'item.id', 'item.id',
@@ -277,6 +275,7 @@ class BannerItem
'item.desc_txt_color', 'item.desc_txt_color',
'item.type', 'item.type',
'item.image', 'item.image',
'item.extra_image',
'item.video', 'item.video',
'item.link_to', 'item.link_to',
'item.link', 'item.link',
@@ -310,7 +309,13 @@ class BannerItem
} }
}) })
->order(['item.sort' => 'asc', 'item.id' => 'desc']) ->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) ->categoryNullable($param['category_id']??null)
->isShowNullable(isset($param['is_show']) ? (bool)$param['is_show'] : 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([ ->paginate([
'list_rows' => $param['size'], 'list_rows' => $param['size'],
'page' => $param['page'], 'page' => $param['page'],
@@ -171,7 +171,7 @@ class Product
// 更新产品参数 // 更新产品参数
if ($put['params'] != "") { if ($put['params'] != "") {
ProductParamsModel::productId($id)->delete(); ProductParamsModel::productId($id)->delete();
if (preg_match_all('/(\S+):(.[^\s]+)/', $put['params'], $match_result)) { if (preg_match_all('/(.+):(.+)/', $put['params'], $match_result)) {
$params = []; $params = [];
for ($i = 0; $i < count($match_result[0]); $i++) { for ($i = 0; $i < count($match_result[0]); $i++) {
$params[] = [ $params[] = [
@@ -346,7 +346,7 @@ class Product
private function getExportProductData() private function getExportProductData()
{ {
$server = request()->server(); $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([ $param = request()->param([
'name', 'name',
'spu', 'spu',
@@ -360,10 +360,10 @@ class Product
'spu', 'spu',
'name', 'name',
'short_name', 'short_name',
'CONCAT("' . $image_host . '", `cover_image`)' => 'cover_image', 'cover_image',
'desc', 'desc',
'CONCAT("' . $image_host . '", `video_img`)' => 'video_img', 'video_img',
'CONCAT("' . $image_host . '", `video_url`)' => 'video_url', 'video_url',
'CASE WHEN is_new = 1 THEN "是" ELSE "否" END' => 'is_new', 'CASE WHEN is_new = 1 THEN "是" ELSE "否" END' => 'is_new',
'CASE WHEN is_hot = 1 THEN "是" ELSE "否" END' => 'is_hot', 'CASE WHEN is_hot = 1 THEN "是" ELSE "否" END' => 'is_hot',
'CASE WHEN is_sale = 1 THEN "是" ELSE "否" END' => 'is_sale', 'CASE WHEN is_sale = 1 THEN "是" ELSE "否" END' => 'is_sale',
@@ -390,7 +390,18 @@ class Product
->order(['id' => 'asc']) ->order(['id' => 'asc'])
->select() ->select()
->bindAttr('category', ['category_name' => 'name']) ->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()) { if (!$products->isEmpty()) {
// 产品参数 // 产品参数

View File

@@ -16,8 +16,9 @@ class ProductTcoCategory
$param = request()->param(['name']); $param = request()->param(['name']);
$categorys = ProductTcoCategoryModel::field([ $categorys = ProductTcoCategoryModel::field([
'tco_id' => 'id', 'id',
'tco_pid' => 'pid', 'tco_id',
'tco_pid',
'name', 'name',
]) ])
->withSearch(['name'], [ ->withSearch(['name'], [
@@ -25,10 +26,10 @@ class ProductTcoCategory
]) ])
->language(request()->lang_id) ->language(request()->lang_id)
->enabled() ->enabled()
->order(['id' => 'asc']) ->order(['tco_id' => 'asc'])
->select() ->select()
->toArray(); ->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

@@ -141,6 +141,61 @@ class SiteConfig
return $ret; return $ret;
} }
// 根据分组获取配置
public function getByGroupUniqueLabel($unique_label)
{
$configs = SysConfigModel::alias('c')
->field([
'c.id',
'c.title',
'c.name',
'c.value',
])
->join(SysConfigGroupModel::getTable(). ' g', 'g.id = c.group_id')
->where('g.language_id', '=', request()->lang_id)
->where('g.unique_label', '=', $unique_label)
->where('g.status', '=', 1)
->order(['c.sort' => 'asc', 'c.id' => 'desc'])
->select()
->each(function ($item) {
// 修改字段为null的输出为空字符串
$keys = array_keys($item->toArray());
foreach ($keys as $key) {
if (is_null($item[$key])) {
$item[$key] = '';
}
}
return $item;
})
->toArray();
if (!empty($configs)) {
$configs_map = [];
foreach ($configs as $cfg) {
$current = &$configs_map;
// 根据name中"."拆分为多维数组
$parts = explode('.', $cfg['name']);
foreach ($parts as $part) {
if (!isset($current[$part])) {
$current[$part] = [];
}
$current = &$current[$part];
}
$current = [
'id' => $cfg['id'],
'title' => $cfg['title'],
'name' => $cfg['name'],
'value' => $cfg['value']
];
}
unset($current);
return $configs_map;
}
return [];
}
// 更新配置 // 更新配置
public function update() public function update()
{ {

View File

@@ -8,7 +8,6 @@ use app\admin\model\v1\ArticleModel;
use app\admin\model\v1\ProductCategoryModel; use app\admin\model\v1\ProductCategoryModel;
use app\admin\model\v1\ProductModel; use app\admin\model\v1\ProductModel;
use think\facade\Db; use think\facade\Db;
use think\facade\Route;
class System class System
{ {
@@ -147,7 +146,11 @@ class System
'name' => '产品分类', 'name' => '产品分类',
'link_to' => 'product_category', 'link_to' => 'product_category',
'data' => array_to_tree(array_map(function($item) { 'data' => array_to_tree(array_map(function($item) {
$item['url'] = (string)url('/index/product/category/' . $item['id']); if ($item['pid'] == 0) {
$item['url'] = (string)url('/index/product/category/'. $item['id']);
} else {
$item['url'] = (string)url('/index/product/subcategory/' . $item['id']);
}
return $item; return $item;
}, $product_category), 0, 'pid', false, false) }, $product_category), 0, 'pid', false, false)
], ],
@@ -155,6 +158,11 @@ class System
'name' => '产品', 'name' => '产品',
'link_to' => 'product', 'link_to' => 'product',
'data' => array_to_tree($product_category, 0, 'pid', false, false) 'data' => array_to_tree($product_category, 0, 'pid', false, false)
],
[
'name' => '其他内页',
'link_to' => 'system_page',
'data' => self::getSystemOtherPages()
] ]
]; ];
@@ -220,10 +228,128 @@ class System
return $data->toArray(); return $data->toArray();
} }
// 获取系统其他内页
static private function getSystemOtherPages()
{
return [
[
'id' => 1,
'name' => '首页',
'url' => (string)url('/index/index/index')
],
[
'id' => 2,
'name' => '新品上市',
'url' => (string)url('/index/product/newpro')
],
[
'id' => 3,
'name' => '附件下载',
'url' => (string)url('/index/attachment/index')
],
[
'id' => 4,
'name' => '问答中心',
'url' => (string)url('/index/faq/index')
],
[
'id' => 5,
'name' => '关于我们',
'url' => '',
'children' => [
[
'id' => 51,
'name' => '品牌介绍',
'url' => (string)url('/index/aboutus/introduction')
],
[
'id' => 52,
'name' => '品牌故事',
'url' => (string)url('/index/aboutus/story')
],
[
'id' => 53,
'name' => '品牌历程',
'url' => (string)url('/index/aboutus/mileage')
],
[
'id' => 54,
'name' => '文化介绍',
'url' => (string)url('/index/aboutus/culture')
],
[
'id' => 55,
'name' => '售后政策',
'url' => (string)url('/index/aboutus/policy')
]
]
],
[
'id' => 6,
'name' => '联系我们',
'url' => '',
'children' => [
[
'id' => 61,
'name' => '联系我们',
'url' => (string)url('/index/contactus/index')
],
[
'id' => 62,
'name' => '留言联系我们',
'url' => (string)url('/index/contactus/message')
],
[
'id' => 63,
'name' => '留言成为分销商',
'url' => (string)url('/index/contactus/distributor')
],
[
'id' => 64,
'name' => '留言批量购买',
'url' => (string)url('/index/contactus/bulkbuy')
]
]
],
[
'id' => 7,
'name' => 'NAS专题',
'url' => '',
'children' => [
[
'id' => 71,
'name' => '首页',
'url' => (string)url('/index/topic/nas/index')
],
[
'id' => 72,
'name' => '产品体验',
'url' => (string)url('/index/topic/nas/product')
],
[
'id' => 73,
'name' => '客户合作',
'url' => (string)url('/index/topic/nas/cooperation')
],
[
'id' => 74,
'name' => '帮助中心',
'url' => (string)url('/index/topic/nas/help')
],
[
'id' => 75,
'name' => '软件下载',
'url' => (string)url('/index/topic/nas/download')
]
]
]
];
}
// 根据系统页面url获取回显数据项 // 根据系统页面url获取回显数据项
static public function getEchoDataBySystemPageUrl($link_to, $link) static public function getEchoDataBySystemPageUrl($link_to, $link)
{ {
if ('custom' == $link_to) return []; if ('custom' == $link_to || empty($link)) return [];
$data = []; $data = [];
$params = []; $params = [];
@@ -235,21 +361,29 @@ class System
parse_str($url, $params); parse_str($url, $params);
} }
if (empty($params['id'])) return [];
switch ($link_to) { switch ($link_to) {
case 'article_category': case 'article_category':
if (empty($params['id'])) return [];
$data = ArticleCategoryModel::field(['id', 'name'])->bypk($params['id'])->find(); $data = ArticleCategoryModel::field(['id', 'name'])->bypk($params['id'])->find();
break; break;
case 'article': case 'article':
if (empty($params['id'])) return [];
$data = ArticleModel::field(['id', 'title' => 'name'])->bypk($params['id'])->find(); $data = ArticleModel::field(['id', 'title' => 'name'])->bypk($params['id'])->find();
break; break;
case 'product_category': case 'product_category':
if (empty($params['id'])) return [];
$data = ProductCategoryModel::field(['id', 'name'])->bypk($params['id'])->find(); $data = ProductCategoryModel::field(['id', 'name'])->bypk($params['id'])->find();
break; break;
case 'product': case 'product':
if (empty($params['id'])) return [];
$data = ProductModel::field(['id', 'name'])->bypk($params['id'])->find(); $data = ProductModel::field(['id', 'name'])->bypk($params['id'])->find();
break; break;
case 'system_page':
$data = self::filterSystemOtherPage(self::getSystemOtherPages(), function($item) use ($params, $link) {
if (empty($params['id'])) return $item['url'] == $link;
return $item['id'] == $params['id'];
});
break;
default: default:
return []; return [];
break; break;
@@ -262,4 +396,22 @@ class System
'link' => $link 'link' => $link
]; ];
} }
// 根据条件过滤结果
static private function filterSystemOtherPage(array $data, callable $callback): array
{
foreach ($data as $it) {
if ($callback($it)) {
return $it;
}
if (isset($it['children'])) {
$child = self::filterSystemOtherPage($it['children'], $callback);
if (!empty($child)) {
return $child;
}
}
}
return [];
}
} }

View File

@@ -7,7 +7,9 @@ use app\admin\model\v1\SysImageUploadRecordModel;
use app\admin\model\v1\SysVideoUploadRecordModel; use app\admin\model\v1\SysVideoUploadRecordModel;
use app\admin\model\v1\SysAttachmentUploadRecordModel; use app\admin\model\v1\SysAttachmentUploadRecordModel;
use Intervention\Image\ImageManager; use Intervention\Image\ImageManager;
use Intervention\Image\Typography\FontFactory;
use think\facade\Filesystem; use think\facade\Filesystem;
use filesystem\Qiniu;
/** /**
* 文件上传控制器 * 文件上传控制器
@@ -30,7 +32,7 @@ class Upload
$max_size = strtobytes(env('ADMIN_API.MAX_IMAGE_SIZE', '1mb')); $max_size = strtobytes(env('ADMIN_API.MAX_IMAGE_SIZE', '1mb'));
$validate = validate([ $validate = validate([
'module' => 'require|max:64', 'module' => 'require|max:64',
'image' => "fileSize:$max_size|fileExt:jpg,jpeg,png,gif" 'image' => "fileSize:$max_size|fileExt:jpg,jpeg,png,gif,webp"
]); ]);
if (!$validate->check(['module' => $param['module'], 'image' => $file])) { if (!$validate->check(['module' => $param['module'], 'image' => $file])) {
return error($validate->getError()); return error($validate->getError());
@@ -41,25 +43,121 @@ class Upload
$filemd5 = $file->md5(); $filemd5 = $file->md5();
$filesha1 = $file->sha1(); $filesha1 = $file->sha1();
$image_model = SysImageUploadRecordModel::md5($filemd5)->find(); // 获取图片上传配置
list(
'filename_keep' => $filename_keep,
'filemd5_unique' => $filemd5_unique,
'filetype_to' => $filetype_to,
) = $this->getUploadOptions('upload_image');
// 获取文件大小
$file_size = $file->getSize();
// 获取文件mime类型
$mime_type = $file->getOriginalMime();
// 是否需要根据文件MD5值检查文件是否已存在
$image_model = $filemd5_unique ? SysImageUploadRecordModel::md5($filemd5)->find() : null;
if (is_null($image_model)) { if (is_null($image_model)) {
$filename = Filesystem::disk('image')->putFile($param['module'], $file); // 检查是否需要保留原文件名生成器
// 生成缩略图 $name_rule = fn() => $filename_keep ? $this->filenameGenerator($file) : null;
$image_manager = new ImageManager(new \Intervention\Image\Drivers\Imagick\Driver());
$image = $image_manager->read('.' . $storage . '/' . $filename); // 处理图片
$image_manager = ImageManager::gd();
if ($filetype_to == 'original') {
$filename = Filesystem::disk('image')->putFile($param['module'], $file, $name_rule());
$image = $image_manager->read('.' . $storage . '/' . $filename);
}
else if ($filetype_to == 'webp') {
$image = $image_manager->read($file->getRealPath());
// 转换为webp格式
$webp = $image->toWebp(75);
$root = config('filesystem.disks.image.root');
$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();
// 获取webp文件mime类型
$mime_type = $webp->mimetype();
}
// 水印
list(
'enabled' => $enabled,
'type' => $type,
'text_options' => $text_options,
'image_options' => $image_options
) = $this->getWatermarkOptions();
if ($enabled) {
// 图片水印
if ($type == 'IMAGE' && $image_options['image'] != '') {
// 读取水印图片
$watermark_image = $image_manager->read(public_path() . $image_options['image']);
// 缩放水印图片
$watermark_image->scale($image_options['width'], $image_options['height']);
// 绘制水印图片
$image->place(
$watermark_image,
$image_options['position'],
$image_options['offset_x'],
$image_options['offset_y'],
$image_options['opacity']
);
}
// 文字水印
else if ($type == 'TEXT' && $text_options['txt'] != '') {
// 原图宽度
$origin_width = $image->width();
// 原图高度
$origin_height = $image->height();
$font_factory = new FontFactory(function(FontFactory $font) use($text_options) {
// 设置字体
$font->filename(public_path() . $text_options['font']);
// 设置字体大小
$font->size($text_options['size']);
// 设置字体颜色及透明度
$opacity = $text_options['opacity'] > 0 ? dechex((int)ceil(255 * ($text_options['opacity'] / 100))) : '00';
$font->color($text_options['color'] . $opacity);
$font->align('left');
$font->valign('top');
});
// 文字尺寸
$font_rect = $image->driver()->fontProcessor()->boxSize($text_options['txt'], $font_factory());
// 计算偏移量
list($offset_x, $offset_y) = $this->scaleTxtOffsetXYByPosition(
$text_options['position'],
$text_options['offset_x'],
$text_options['offset_y'],
$origin_width,
$origin_height,
$font_rect->width(),
$font_rect->height()
);
// 绘制文字
$image->text(
$text_options['txt'],
$offset_x,
$offset_y,
$font_factory()
);
}
$image->save('.'. $storage. '/'. $filename);
}
// 缩略图
$image->scale(200, 200); $image->scale(200, 200);
$idx = strrpos($filename, '.'); $idx = strrpos($filename, '.');
$thumb_filename = mb_substr($filename, 0, $idx) . '_thumb.' . mb_substr($filename, $idx + 1); $thumb_filename = mb_substr($filename, 0, $idx) . '_thumb.' . mb_substr($filename, $idx + 1);
$image->save('.' . $storage . '/' . $thumb_filename); $image->save('.' . $storage . '/' . $thumb_filename);
// 保存图片 // 保存图片
$image_model = new SysImageUploadRecordModel(); $image_model = new SysImageUploadRecordModel();
$image_model->language_id = request()->lang_id; $image_model->language_id = request()->lang_id;
$image_model->module = $param['module']; $image_model->module = $param['module'];
$image_model->image_path = $filename; $image_model->image_path = $storage . '/' . $filename;
$image_model->image_thumb = $thumb_filename; $image_model->image_thumb = $storage . '/' . $thumb_filename;
$image_model->file_size = $file->getSize(); $image_model->file_size = $file_size;
$image_model->file_type = $file->getOriginalMime(); $image_model->file_type = $mime_type;
$image_model->file_md5 = $filemd5; $image_model->file_md5 = $filemd5;
$image_model->file_sha1 = $filesha1; $image_model->file_sha1 = $filesha1;
if (!$image_model->save()) { if (!$image_model->save()) {
@@ -68,8 +166,8 @@ class Upload
} }
return success('操作成功', [ return success('操作成功', [
'path' => $storage . '/' . $image_model->image_path, 'path' => $image_model->image_path,
'thumb_path' => $storage . '/' . $image_model->image_thumb, 'thumb_path' => $image_model->image_thumb,
'filemd5' => $image_model->file_md5, 'filemd5' => $image_model->file_md5,
'filesha1' => $image_model->file_sha1 'filesha1' => $image_model->file_sha1
]); ]);
@@ -79,6 +177,143 @@ class Upload
return error('上传失败'); return error('上传失败');
} }
/**
* 检查路径
*
* @param string $path
* @return string
*/
private function checkPath($path): string
{
$ok = true;
$filename = basename($path);
$dirname = dirname($path);
if (!is_dir($dirname)) {
$ok = @mkdir($dirname, 0755, true);
}
else if (!is_writable($dirname)) {
$ok = @chmod($dirname,0755);
}
if ($ok) {
return $dirname . '/' . $filename;
}
throw new \Exception("上传目标目录不可用");
}
/**
* 文件名生成回调
*
* @param \think\file\UploadedFile $file
* @return callable
*/
private function filenameGenerator(\think\file\UploadedFile $file): callable
{
return fn() => date('Ymd') . '/' . pathinfo($file->getOriginalName(), PATHINFO_FILENAME);
}
/**
* 获取上传配置
*
* @param string $module
* @return array
*/
private function getUploadOptions($module)
{
$config_model = new \app\admin\controller\v1\SiteConfig;
$config = $config_model->getByGroupUniqueLabel('upload');
$options = data_get($config, $module, []);
return [
'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'),
];
}
/**
* 获取水印配置
*
* @return array
*/
private function getWatermarkOptions(): array
{
$config_model = new \app\admin\controller\v1\SiteConfig;
$watermark_config = $config_model->getByGroupUniqueLabel('watermark');
$opacity = data_get($watermark_config, 'watermark_opacity.value', 100);
if ($opacity == '') {
$opacity = 100;
}
return [
'enabled' => data_get($watermark_config, 'watermark_enabled.value', 0) == 1,
'type' => data_get($watermark_config, 'watermark_type.value', ''),
'text_options' => [
'txt' => data_get($watermark_config, 'watermark_text_value.value', ''),
'font' => data_get($watermark_config, 'watermark_text_font.value', ''),
'size' => (float)data_get($watermark_config, 'watermark_text_size.value', 12)?:12,
'color' => data_get($watermark_config, 'watermark_text_color.value', '#000000')?:'#000000',
'position' => data_get($watermark_config, 'watermark_position.value', 'top-left')?:'top-left',
'offset_x' => (int)data_get($watermark_config, 'watermark_offset_x.value', 0),
'offset_y' => (int)data_get($watermark_config, 'watermark_offset_y.value', 0),
'opacity' => (int)$opacity,
],
'image_options' => [
'image' => data_get($watermark_config, 'watermark_image_value.value', ''),
'width' => (int)data_get($watermark_config, 'watermark_image_width.value')?:null,
'height' => (int)data_get($watermark_config, 'watermark_image_height.value')?:null,
'position' => data_get($watermark_config, 'watermark_position.value', 'top-left')?:'top-left',
'offset_x' => (int)data_get($watermark_config, 'watermark_offset_x.value', 0),
'offset_y' => (int)data_get($watermark_config, 'watermark_offset_y.value', 0),
'opacity' => (int)$opacity,
]
];
}
/**
* 计算文本水印偏移量
*
* @param string $position
* @param integer $offset_x
* @param integer $offset_y
* @param integer $image_width
* @param integer $image_height
* @param integer $txt_width
* @param integer $txt_height
* @return array
*/
private function scaleTxtOffsetXYByPosition(string $position, int $offset_x, int $offset_y, int $image_width, int $image_height, int $txt_width, int $txt_height)
{
switch ($position) {
case 'top-left':
// top-left:左上角
return [$offset_x, $offset_y];
case 'top-right':
// top-right:右上角
return [(int)($image_width-$txt_width-$offset_x), $offset_y];
case 'top':
// top:上 - 水平居中
return [(int)(($image_width-$txt_width+$offset_x)/2), $offset_y];
case 'left':
// left:左 - 垂直居中
return [$offset_x, (int)(($image_height-$txt_height)/2+$offset_y)];
case 'center':
// center:水平垂直居中
return [(int)(($image_width-$txt_width)/2+$offset_x), (int)(($image_height-$txt_height)/2+$offset_y)];
case 'right':
// right:右 - 垂直居中
return [(int)($image_width-$txt_width-$offset_x), (int)(($image_height-$txt_height)/2+$offset_y)];
case'bottom':
// bottom:下 - 水平居中
return [(int)(($image_width-$txt_width+$offset_x)/2), (int)($image_height-$txt_height-$offset_y)];
case'bottom-left':
// bottom-left:左下角
return [$offset_x, (int)($image_height-$txt_height-$offset_y)];
case'bottom-right':
// bottom-right:右下角
return [(int)($image_width-$txt_width-$offset_x), (int)($image_height-$txt_height-$offset_y)];
default:
throw new \InvalidArgumentException('Invalid position');
}
}
/** /**
* 上传视频 * 上传视频
@@ -109,15 +344,38 @@ class Upload
$filemd5 = $file->md5(); $filemd5 = $file->md5();
$filesha1 = $file->sha1(); $filesha1 = $file->sha1();
$video = SysVideoUploadRecordModel::md5($filemd5)->find(); // 获取视频上传配置
list(
'filename_keep' => $filename_keep,
'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)) { if (is_null($video)) {
$filename = Filesystem::disk('video')->putFile($param['module'], $file); // 保存位置配置 key
$disk = 'video';
// 检查是否需要保留原文件名
$name_rule = fn() => $filename_keep ? $this->filenameGenerator($file) : null;
// 保存到七牛云
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 = new SysVideoUploadRecordModel();
$video->language_id = request()->lang_id; $video->language_id = request()->lang_id;
$video->module = $param['module']; $video->module = $param['module'];
$video->video_path = $filename; $video->video_path = $video_path;
$video->file_size = $file->getSize(); $video->file_size = $file->getSize();
$video->file_type = $file->getOriginalMime(); $video->file_type = $file->getOriginalMime();
$video->file_md5 = $filemd5; $video->file_md5 = $filemd5;
@@ -128,7 +386,7 @@ class Upload
} }
return success('上传成功', [ return success('上传成功', [
'path' => $storage . '/' . $video->video_path, 'path' => $video->video_path,
'file_md5' => $video->file_md5, 'file_md5' => $video->file_md5,
'file_sha1' => $video->file_sha1 'file_sha1' => $video->file_sha1
]); ]);
@@ -152,23 +410,48 @@ class Upload
try { try {
$max_size = strtobytes(env('ADMIN_API.MAX_ATTACHMENT_SIZE', '100mb')); $max_size = strtobytes(env('ADMIN_API.MAX_ATTACHMENT_SIZE', '100mb'));
$validate = validate([ $validate = validate([
'attachment' => "fileSize:$max_size|fileExt:biz,bz,bz2,gz,tgz,zip,rar,7z,doc,docx,xls,xlsx,csv,ppt,pptx,pdf,txt,jpg,jpeg,png" 'attachment' => "fileSize:$max_size|fileExt:biz,bz,bz2,gz,tgz,zip,rar,7z,doc,docx,xls,xlsx,csv,ppt,pptx,pdf,txt,jpg,jpeg,png,webp,ttf"
]); ]);
if (!$validate->check(['attachment' => $file])) { if (!$validate->check(['attachment' => $file])) {
return error($validate->getError()); return error($validate->getError());
} }
$storage = config('filesystem.disks.public.url');
$filemd5 = $file->md5(); $filemd5 = $file->md5();
$filesha1 = $file->sha1(); $filesha1 = $file->sha1();
$attachment = SysAttachmentUploadRecordModel::md5($filemd5)->find(); // 获取附件上传配置
list(
'filename_keep' => $filename_keep,
'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)) { if (is_null($attachment)) {
$filename = Filesystem::disk('public')->putFile('attachments', $file); // 保存位置配置 key
$disk = 'public';
// 检查是否需要保留原文件名
$name_rule = fn() => $filename_keep ? $this->filenameGenerator($file) : null;
// 保存视频 // 保存到七牛云
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 = new SysAttachmentUploadRecordModel();
$attachment->language_id = request()->lang_id; $attachment->language_id = request()->lang_id;
$attachment->attachment_path = $filename; $attachment->attachment_path = $attachment_path;
$attachment->file_size = $file->getSize(); $attachment->file_size = $file->getSize();
$attachment->file_type = $file->getOriginalMime(); $attachment->file_type = $file->getOriginalMime();
$attachment->file_md5 = $filemd5; $attachment->file_md5 = $filemd5;
@@ -178,9 +461,8 @@ class Upload
} }
} }
$storage = config('filesystem.disks.public.url');
return success('上传成功', [ return success('上传成功', [
'path' => $storage . '/' . $attachment->attachment_path, 'path' => $attachment->attachment_path,
'file_md5' => $attachment->file_md5, 'file_md5' => $attachment->file_md5,
'file_sha1' => $attachment->file_sha1 'file_sha1' => $attachment->file_sha1
]); ]);

View File

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

View File

@@ -47,7 +47,8 @@ class VideoTrash
'page' => $params['page'], 'page' => $params['page'],
]) ])
->bindAttr('category', ['category_name']) ->bindAttr('category', ['category_name'])
->hidden(['category_id', 'category']); ->hidden(['category_id', 'category'])
?->each(fn($item) => $item->image = thumb($item->image));
return success('获取成功', $videos); return success('获取成功', $videos);
} }

View File

@@ -29,6 +29,12 @@ class ProductCategoryModel extends ProductCategoryBaseModel
$query->where('language_id', '=', $value); $query->where('language_id', '=', $value);
} }
// 所属产品目录分类id查询
public function scopeTcoId($query, $value)
{
$query->where('related_tco_category', '=', $value);
}
/** /**
* 根据是否显示查询 * 根据是否显示查询
* @param $query * @param $query

View File

@@ -80,6 +80,12 @@ class ProductModel extends ProductBaseModel
$query->where('category_id', '=', $value); $query->where('category_id', '=', $value);
} }
// 规格型号查询
public function scopeSpu($query, $spu)
{
$query->where('spu', '=', $spu);
}
// 启用状态查询 // 启用状态查询
public function scopeEnabled($query) public function scopeEnabled($query)
{ {

View File

@@ -23,6 +23,18 @@ class ProductTcoCategoryModel extends ProductTcoCategoryBaseModel
$query->where('language_id', '=', $value); $query->where('language_id', '=', $value);
} }
// 根据 tco_id 查询
public function scopeTcoId($query, $value)
{
$query->where('tco_id', '=', $value);
}
// 根据ERP Code查询
public function scopeErpCode($query, $value)
{
$query->where('erp_code', '=', $value);
}
// 按分类名称搜索 // 按分类名称搜索
public function searchNameAttr($query, $value, $data) public function searchNameAttr($query, $value, $data)
{ {

View File

@@ -616,6 +616,12 @@ Route::group('v1', function () {
}); });
})->prefix('v1.'); })->prefix('v1.');
// 接收产品目录同步数据
Route::group('receive_sync', function () {
Route::post('category', 'ReceiveProductSync/category');
Route::post('product', 'ReceiveProductSync/product');
});
Route::miss(function() { Route::miss(function() {
return '404 Not Found!'; return '404 Not Found!';
}); });

View File

@@ -64,19 +64,36 @@ class ArticleCategoryValidate extends Validate
if ($value == 0) { if ($value == 0) {
return true; return true;
} }
$children = [];
$table_name = (new ArticleCategoryModel)->getTable(); $table_name = (new ArticleCategoryModel)->getTable();
$children = Db::query( if (env('DB_VERSION', '5') == '8') {
preg_replace( $children = Db::query(
'/\s+/u', preg_replace(
' ', '/\s+/u',
"WITH RECURSIVE article_tree_by AS ( ' ',
SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$data['id']} "WITH RECURSIVE article_tree_by AS (
UNION ALL SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$data['id']}
SELECT k.id, k.pid FROM $table_name k INNER JOIN article_tree_by t ON t.id = k.pid UNION ALL
SELECT k.id, k.pid FROM $table_name k INNER JOIN article_tree_by t ON t.id = k.pid
)
SELECT id FROM article_tree_by WHERE id <> {$data['id']};"
) )
SELECT id FROM article_tree_by WHERE id <> {$data['id']};" );
) } else {
); $children = \think\facade\Db::query("
SELECT t2.id
FROM (
SELECT
@r AS _id, (SELECT @r := GROUP_CONCAT(id) FROM $table_name WHERE FIND_IN_SET(pid, _id)) AS parent_id
FROM
(SELECT @r := {$data['id']}) vars, $table_name h
WHERE @r <> 0) t1
JOIN $table_name t2
ON FIND_IN_SET(t2.pid, t1._id)
ORDER BY t2.id;
");
}
if (!empty($children) && in_array($data['pid'], array_column($children, 'id'))) { if (!empty($children) && in_array($data['pid'], array_column($children, 'id'))) {
return false; return false;
} }

View File

@@ -23,9 +23,9 @@ class ArticleValidate extends Validate
'sort' => 'integer', 'sort' => 'integer',
'recommend' => 'require|in:0,1', 'recommend' => 'require|in:0,1',
'release_time' => 'dateFormat:Y-m-d H:i:s', 'release_time' => 'dateFormat:Y-m-d H:i:s',
'seo_title' => 'max:255', 'seo_title' => 'max:512',
'seo_keywords' => 'max:255', 'seo_keywords' => 'max:512',
'seo_desc' => 'max:255' 'seo_desc' => 'max:1024'
]; ];
/** /**
@@ -48,8 +48,8 @@ class ArticleValidate extends Validate
'recommend.require' => '推荐状态不能为空', 'recommend.require' => '推荐状态不能为空',
'recommend.in' => '推荐状态的值必须是0或1', 'recommend.in' => '推荐状态的值必须是0或1',
'release_time.dateFormat' => '发布时间格式不正确', 'release_time.dateFormat' => '发布时间格式不正确',
'seo_title.max' => 'SEO标题长度不能超过255个字符', 'seo_title.max' => 'SEO标题长度不能超过512个字符',
'seo_keywords.max' => 'SEO关键字长度不能超过255个字符', 'seo_keywords.max' => 'SEO关键字长度不能超过512个字符',
'seo_desc.max' => 'SEO描述长度不能超过255个字符' 'seo_desc.max' => 'SEO描述长度不能超过1024个字符'
]; ];
} }

View File

@@ -49,19 +49,36 @@ class AttachmentCategoryValidate extends Validate
if ($value == 0) { if ($value == 0) {
return true; return true;
} }
$children = [];
$table_name = (new AttachmentCategoryModel)->getTable(); $table_name = (new AttachmentCategoryModel)->getTable();
$children = Db::query( if (env('DB_VERSION', '5') == '8') {
preg_replace( $children = Db::query(
'/\s+/u', preg_replace(
' ', '/\s+/u',
"WITH RECURSIVE attachment_tree_by AS ( ' ',
SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$data['id']} "WITH RECURSIVE attachment_tree_by AS (
UNION ALL SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$data['id']}
SELECT k.id, k.pid FROM $table_name k INNER JOIN attachment_tree_by t ON t.id = k.pid UNION ALL
SELECT k.id, k.pid FROM $table_name k INNER JOIN attachment_tree_by t ON t.id = k.pid
)
SELECT id FROM attachment_tree_by WHERE id <> {$data['id']};"
) )
SELECT id FROM attachment_tree_by WHERE id <> {$data['id']};" );
) } else {
); $children = \think\facade\Db::query("
SELECT t2.id
FROM (
SELECT
@r AS _id, (SELECT @r := GROUP_CONCAT(id) FROM $table_name WHERE FIND_IN_SET(pid, _id)) AS parent_id
FROM
(SELECT @r := {$data['id']}) vars, $table_name h
WHERE @r <> 0) t1
JOIN $table_name t2
ON FIND_IN_SET(t2.pid, t1._id)
ORDER BY t2.id;
");
}
if (!empty($children) && in_array($data['pid'], array_column($children, 'id'))) { if (!empty($children) && in_array($data['pid'], array_column($children, 'id'))) {
return false; return false;
} }

View File

@@ -21,7 +21,7 @@ class NavigationItemValidate extends Validate
'pid' => 'integer|different:id|checkPidNotBeChildren', 'pid' => 'integer|different:id|checkPidNotBeChildren',
'name' => 'require|max:64', 'name' => 'require|max:64',
'icon' => 'max:64', 'icon' => 'max:64',
'link_to' => 'require|max:64|in:article,article_category,product,product_category,custom', 'link_to' => 'require|max:64|in:article,article_category,product,product_category,system_page,custom',
'link' => 'max:255', 'link' => 'max:255',
'sort' => 'integer', 'sort' => 'integer',
'blank' => 'in:0,1', 'blank' => 'in:0,1',
@@ -47,7 +47,7 @@ class NavigationItemValidate extends Validate
'icon.max' => '图标最多不能超过64个字符', 'icon.max' => '图标最多不能超过64个字符',
'link_to.require' => '链接类型不能为空', 'link_to.require' => '链接类型不能为空',
'link_to.max' => '链接类型最多不能超过64个字符', 'link_to.max' => '链接类型最多不能超过64个字符',
'link_to.in' => '链接类型必须是article,goods_category,goods,custom中之一', 'link_to.in' => '链接类型必须是article,article_category,product_category,product,system_page,custom中之一',
'link.max' => '链接最多不能超过255个字符', 'link.max' => '链接最多不能超过255个字符',
'sort.integer' => '排序必须为整数', 'sort.integer' => '排序必须为整数',
'blank.in' => '是否新窗口打开只能是0或1', 'blank.in' => '是否新窗口打开只能是0或1',
@@ -61,19 +61,36 @@ class NavigationItemValidate extends Validate
if ($value == 0) { if ($value == 0) {
return true; return true;
} }
$children = [];
$table_name = (new SysNavigationItemModel)->getTable(); $table_name = (new SysNavigationItemModel)->getTable();
$children = Db::query( if (env('DB_VERSION', '5') == '8') {
preg_replace( $children = Db::query(
'/\s+/u', preg_replace(
' ', '/\s+/u',
"WITH RECURSIVE tree_by AS ( ' ',
SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$data['id']} "WITH RECURSIVE tree_by AS (
UNION ALL SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$data['id']}
SELECT k.id, k.pid FROM $table_name k INNER JOIN tree_by t ON t.id = k.pid UNION ALL
SELECT k.id, k.pid FROM $table_name k INNER JOIN tree_by t ON t.id = k.pid
)
SELECT id FROM tree_by WHERE id <> {$data['id']};"
) )
SELECT id FROM tree_by WHERE id <> {$data['id']};" );
) } else {
); $children = \think\facade\Db::query("
SELECT t2.id
FROM (
SELECT
@r AS _id, (SELECT @r := GROUP_CONCAT(id) FROM $table_name WHERE FIND_IN_SET(pid, _id)) AS parent_id
FROM
(SELECT @r := {$data['id']}) vars, $table_name h
WHERE @r <> 0) t1
JOIN $table_name t2
ON FIND_IN_SET(t2.pid, t1._id)
ORDER BY t2.id;
");
}
if (!empty($children) && in_array($data['pid'], array_column($children, 'id'))) { if (!empty($children) && in_array($data['pid'], array_column($children, 'id'))) {
return false; return false;
} }

View File

@@ -15,16 +15,17 @@ class SysBannerItemValidate extends Validate
*/ */
protected $rule = [ protected $rule = [
'id' => 'require|integer', 'id' => 'require|integer',
'banner_id' => 'require|integer', 'banner_id' => 'require|integer|gt:0',
'title' => 'require|max:256', 'title' => 'require|max:256',
'title_txt_color' => 'max:7', 'title_txt_color' => 'max:7',
'desc' => 'max:1024', 'desc' => 'max:1024',
'desc_txt_color' => 'max:7', 'desc_txt_color' => 'max:7',
'type' => 'in:image,video', 'type' => 'in:image,video',
'image' => 'max:255', 'image' => 'max:255',
'extra_image' => 'max:255',
'video' => 'max:255', 'video' => 'max:255',
'link_to' => 'requireIf:type,image|max:64|in:article,article_category,product,product_category,custom', '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', 'sort' => 'integer',
'status' => 'in:-1,1' 'status' => 'in:-1,1'
]; ];
@@ -40,6 +41,7 @@ class SysBannerItemValidate extends Validate
'id.integer' => 'ID必须是整数', 'id.integer' => 'ID必须是整数',
'banner_id.require' => '横幅项分类不能为空', 'banner_id.require' => '横幅项分类不能为空',
'banner_id.integer' => '横幅项分类必须是整数', 'banner_id.integer' => '横幅项分类必须是整数',
'banner_id.gt' => '该横幅分类不可选',
'title.require' => '名称不能为空', 'title.require' => '名称不能为空',
'title.max' => '名称最多不能超过256个字符', 'title.max' => '名称最多不能超过256个字符',
'title_txt_color.max' => '名称字体颜色最多不能超过7个字符', 'title_txt_color.max' => '名称字体颜色最多不能超过7个字符',
@@ -47,11 +49,12 @@ class SysBannerItemValidate extends Validate
'desc_txt_color.max' => '描述字体颜色最多不能超过7个字符', 'desc_txt_color.max' => '描述字体颜色最多不能超过7个字符',
'type.in' => '显示类型必须是image或video', 'type.in' => '显示类型必须是image或video',
'image.max' => '图片地址最多不能超过255个字符', 'image.max' => '图片地址最多不能超过255个字符',
'extra_image.max' => '额外图片地址最多不能超过255个字符',
'video.max' => '视频地址最多不能超过255个字符', 'video.max' => '视频地址最多不能超过255个字符',
'link_to.requireIf' => '链接类型不能为空', 'link_to.requireIf' => '链接类型不能为空',
'link_to.max' => '链接类型最多不能超过64个字符', 'link_to.max' => '链接类型最多不能超过64个字符',
'link_to.in' => '链接类型必须是article,article_category,product,product_category,custom中之一', 'link_to.in' => '链接类型必须是article,article_category,product,product_category,system_page,custom中之一',
'link.max' => '链接最多不能超过255个字符', 'link.max' => '链接最多不能超过512个字符',
'sort.integer' => '排序值必须是整数', 'sort.integer' => '排序值必须是整数',
'status.in' => '状态必须是-1或1' 'status.in' => '状态必须是-1或1'
]; ];

View File

@@ -74,19 +74,36 @@ class SysMenuValidate extends Validate
if ($value == 0) { if ($value == 0) {
return true; return true;
} }
$children = [];
$table_name = (new SysMenuModel)->getTable(); $table_name = (new SysMenuModel)->getTable();
$children = Db::query( if (env('DB_VERSION', '5') == '8') {
preg_replace( $children = Db::query(
'/\s+/u', preg_replace(
' ', '/\s+/u',
"WITH RECURSIVE menu_tree_by AS ( ' ',
SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$data['id']} "WITH RECURSIVE menu_tree_by AS (
UNION ALL SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$data['id']}
SELECT k.id, k.pid FROM $table_name k INNER JOIN menu_tree_by t ON t.id = k.pid UNION ALL
SELECT k.id, k.pid FROM $table_name k INNER JOIN menu_tree_by t ON t.id = k.pid
)
SELECT id FROM menu_tree_by WHERE id <> {$data['id']};"
) )
SELECT id FROM menu_tree_by WHERE id <> {$data['id']};" );
) } else {
); $children = \think\facade\Db::query("
SELECT t2.id
FROM (
SELECT
@r AS _id, (SELECT @r := GROUP_CONCAT(id) FROM $table_name WHERE FIND_IN_SET(pid, _id)) AS parent_id
FROM
(SELECT @r := {$data['id']}) vars, $table_name h
WHERE @r <> 0) t1
JOIN $table_name t2
ON FIND_IN_SET(t2.pid, t1._id)
ORDER BY t2.id;
");
}
if (!empty($children) && in_array($data['pid'], array_column($children, 'id'))) { if (!empty($children) && in_array($data['pid'], array_column($children, 'id'))) {
return false; return false;
} }

View File

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

View File

@@ -61,6 +61,9 @@ class DataMigration extends Command
// 迁移文章 // 迁移文章
// $this->migrateArticle([ // $this->migrateArticle([
// 16 => 7,
// 31 => 9,
// 32 => 8,
// 68 => 10, // 68 => 10,
// 69 => 11, // 69 => 11,
// 70 => 12, // 70 => 12,
@@ -290,14 +293,15 @@ class DataMigration extends Command
$old_db = Db::connect('old'); $old_db = Db::connect('old');
$success_map = []; $success_map = [];
$success_arr = include_once(runtime_path() . 'product_success.php'); $success_arr = []; // include_once(runtime_path() . 'product_success.php');
foreach ($success_arr as $so) { foreach ($success_arr as $so) {
$success_map['p_' . $so['cod_product_id']] = $so; $success_map['p_' . $so['cod_product_id']] = $so;
} }
$arr = include_once(runtime_path() . 'product_ids.php');
$products = $old_db->name('product') $products = $old_db->name('product')
->where('country_code', 'in', ['ZH', 'US']) ->where('country_code', 'in', ['ZH', 'US'])
->where('id', '>', 15789) ->where('id', 'in', array_unique(array_column($arr, 'cod_product_id')))
->order(['id' => 'asc']) ->order(['id' => 'asc'])
->cursor(); ->cursor();
@@ -374,7 +378,16 @@ class DataMigration extends Command
'deleted_at' => $v['stat'] == -1 ? date('Y-m-d H:i:s') : null, 'deleted_at' => $v['stat'] == -1 ? date('Y-m-d H:i:s') : null,
]; ];
// 保存产品数据 // 保存产品数据
$id = Db::name('product')->insertGetId($item); $prod = Db::name('product')
->where('language_id', '=', $item['language_id'])
->where('spu', '=', $item['spu'])
->find();
if (!empty($prod)) {
$id = $prod['id'];
Db::name('product')->where('id', '=', $prod['id'])->update($item);
} else {
$id = Db::name('product')->insertGetId($item);
}
// 保存产品参数数据 // 保存产品参数数据
if (!empty($v['product_view'])) { if (!empty($v['product_view'])) {
@@ -387,7 +400,21 @@ class DataMigration extends Command
'value' => $p['desc_desc'] 'value' => $p['desc_desc']
]; ];
} }
Db::name('product_params')->insertAll($prarms); $old_params = Db::name('product_params')
->where('product_id', '=', $id)
->select();
if ($old_params->isEmpty()) {
Db::name('product_params')->insertAll($prarms);
} else {
foreach ($old_params as $op) {
Db::name('product_params')
->where('product_id', '=', $id)
->where('name', '=', $op['name'])
->update([
'value' => $op['value']
]);
}
}
} }
// 保存sku数据 // 保存sku数据
@@ -444,7 +471,7 @@ class DataMigration extends Command
if ($k != 'sort') { if ($k != 'sort') {
$attr_value = $at; $attr_value = $at;
if (in_array($k, ['颜色', 'Color'])) { if (in_array($k, ['颜色', 'Color'])) {
if ($k == 'Color') $k = '颜色'; // if ($k == 'Color') $k = '颜色';
$attr_value = '/static/common/images/colors/' . $at . '.png'; $attr_value = '/static/common/images/colors/' . $at . '.png';
} }
$images[$pkey]['color'] = $at; $images[$pkey]['color'] = $at;
@@ -468,7 +495,7 @@ class DataMigration extends Command
} }
} }
$attr_arr = [ $attr_arr = [
'attr_id' => $attrs_map[$v['country_code']]['颜色'], 'attr_id' => $attrs_map[$v['country_code']][$v['country_code'] == 'ZH' ? '颜色' : 'Color'],
'attr_value' => $attr_value, 'attr_value' => $attr_value,
]; ];
if ( if (
@@ -514,7 +541,7 @@ class DataMigration extends Command
$skus[] = [ $skus[] = [
'main_image' => $ti['image_url'], 'main_image' => $ti['image_url'],
'attrs' => [[ 'attrs' => [[
'attr_id' => $attrs_map[$v['country_code']]['颜色'], 'attr_id' => $attrs_map[$v['country_code']][$v['country_code'] == 'ZH' ? '颜色' : 'Color'],
'attr_value' => $ti['image_color'], 'attr_value' => $ti['image_color'],
]], ]],
'pkey' => $tpkey 'pkey' => $tpkey
@@ -575,6 +602,7 @@ class DataMigration extends Command
} }
foreach ($skus as $sku) { foreach ($skus as $sku) {
Db::name('product_sku')->where('product_id', '=', $sku['product_id'])->delete();
$sku_id = Db::name('product_sku')->insertGetId([ $sku_id = Db::name('product_sku')->insertGetId([
'product_id' => $sku['product_id'], 'product_id' => $sku['product_id'],
'sku' => $sku['sku']??'', 'sku' => $sku['sku']??'',
@@ -584,6 +612,7 @@ class DataMigration extends Command
if (!empty($sku['attrs'])) { if (!empty($sku['attrs'])) {
foreach ($sku['attrs'] as $attr) { foreach ($sku['attrs'] as $attr) {
if (!empty($sku_id)) { if (!empty($sku_id)) {
Db::name('product_sku_attr')->where('sku_id', '=', $sku_id)->delete();
Db::name('product_sku_attr')->insert([ Db::name('product_sku_attr')->insert([
'sku_id' => $sku_id, 'sku_id' => $sku_id,
'attr_id' => $attr['attr_id'], 'attr_id' => $attr['attr_id'],
@@ -601,7 +630,7 @@ class DataMigration extends Command
sprintf('["ow_product_id" => %d, "cod_product_id" => %d]'.PHP_EOL, $id, $v['id']), sprintf('["ow_product_id" => %d, "cod_product_id" => %d]'.PHP_EOL, $id, $v['id']),
FILE_APPEND FILE_APPEND
); );
$this->println(sprintf('迁移产品ID%s => %s 【耗时:%s】', $v['id'], 0, round(microtime(true) - $start, 2) . 's')); $this->println(sprintf('迁移产品ID%s => %s 【耗时:%s】', $v['id'], $id, round(microtime(true) - $start, 2) . 's'));
} catch (\Throwable $th) { } catch (\Throwable $th) {
Db::rollback(); Db::rollback();
file_put_contents( file_put_contents(
@@ -694,9 +723,12 @@ class DataMigration extends Command
throw new \Exception('请确认分类ID'); throw new \Exception('请确认分类ID');
} }
// 1634
$article = Db::connect('old') $article = Db::connect('old')
->name('article') ->name('article')
->where('country_code', 'in', ['ZH', 'US'])
->where('cid', 'in', array_keys($category_map)) ->where('cid', 'in', array_keys($category_map))
->where('id', '=', 351)
->order(['id' => 'asc']) ->order(['id' => 'asc'])
->cursor(); ->cursor();
@@ -745,7 +777,16 @@ class DataMigration extends Command
'release_time' => date('Y-m-d H:i:s', $v['createtime']), 'release_time' => date('Y-m-d H:i:s', $v['createtime']),
'deleted_at' => $v['stat'] == -1 ? date('Y-m-d H:i:s') : null 'deleted_at' => $v['stat'] == -1 ? date('Y-m-d H:i:s') : null
]; ];
$id = Db::name('article')->insertGetId($item); $ret = Db::name('article')
->where('language_id', '=', $item['language_id'])
->where('title', '=', $item['title'])
->find();
if (empty($ret)) {
$id = Db::name('article')->insertGetId($item);
} else {
$id = $ret['id'];
Db::name('article')->where('id', '=', $ret['id'])->update($item);
}
$this->println(sprintf('迁移文章ID%s => %s', $v['id'], $id)); $this->println(sprintf('迁移文章ID%s => %s', $v['id'], $id));
} }
@@ -779,7 +820,15 @@ class DataMigration extends Command
'recommend' => $val['is_home'], 'recommend' => $val['is_home'],
'sort' => $val['sort'] == 9999 ? 0 : $val['sort'] 'sort' => $val['sort'] == 9999 ? 0 : $val['sort']
]; ];
Db::name('faq')->insert($item); $ret = Db::name('faq')
->where('language_id', '=', $item['language_id'])
->where('question', '=', $item['question'])
->find();
if (empty($ret)) {
Db::name('faq')->insert($item);
} else {
Db::name('faq')->where('id', '=', $ret['id'])->update($item);
}
} }
} }
@@ -881,7 +930,8 @@ class DataMigration extends Command
{ {
$videos = Db::connect('old') $videos = Db::connect('old')
->name('video') ->name('video')
->where('id', '>', 844) // ->where('id', '>', 844)
->where('cid', 'in', array_keys($category_map))
->where('country_code', 'in', ['ZH', 'US']) ->where('country_code', 'in', ['ZH', 'US'])
->order(['id' => 'asc']) ->order(['id' => 'asc'])
->cursor(); ->cursor();
@@ -921,7 +971,16 @@ class DataMigration extends Command
'seo_desc' => $val['seo_description'], 'seo_desc' => $val['seo_description'],
'deleted_at' => $val['stat'] == -1 ? date('Y-m-d H:i:s') : null 'deleted_at' => $val['stat'] == -1 ? date('Y-m-d H:i:s') : null
]; ];
Db::name('video')->insert($item); $ret = Db::name('video')
->where('language_id', '=', $item['language_id'])
->where('name', '=', $item['name'])
->find();
if (empty($ret)) {
Db::name('video')->insert($item);
} else {
Db::name('video')->where('id', '=', $ret['id'])->update($item);
}
$this->println('迁移视频ID' . $val['id']); $this->println('迁移视频ID' . $val['id']);
} }
} }
@@ -929,7 +988,7 @@ class DataMigration extends Command
class UploadMannager class UploadMannager
{ {
const UPLOAD_BASE_API = 'http://dev.ow.f2b211.com'; const UPLOAD_BASE_API = 'http://ow.f2b211.com';
const DOWNLOAD_BASE_API = 'http://www.orico.com.cn'; const DOWNLOAD_BASE_API = 'http://www.orico.com.cn';
const DOWNLOAD_TEMP_PATH = '/var/www/html/orico-official-website/public/migrate_temp_images'; const DOWNLOAD_TEMP_PATH = '/var/www/html/orico-official-website/public/migrate_temp_images';
private $username = 'admin'; private $username = 'admin';
@@ -942,7 +1001,7 @@ class UploadMannager
{ {
// 登录获取token // 登录获取token
$this->token = $this->getAuthorization(); $this->token = $this->getAuthorization();
$this->maps = include_once(runtime_path() . 'fiber_product_image_mapping.php'); $this->maps = []; // include_once(runtime_path() . 'fiber_product_image_mapping.php');
} }
// 下载图片 // 下载图片
@@ -1062,6 +1121,7 @@ class UploadMannager
print($http_code . PHP_EOL); print($http_code . PHP_EOL);
} }
file_put_contents(runtime_path() . 'upload.txt', $response . PHP_EOL, FILE_APPEND);
$ret = json_decode($response, true); $ret = json_decode($response, true);
if (empty($ret)) { if (empty($ret)) {
throw new \Exception($response); throw new \Exception($response);

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 * @param bool $keep_pid 是否保留pid
* @return array * @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 = []; $ret = [];
foreach ($data as $item) { foreach ($data as $item) {
@@ -93,7 +93,7 @@ if (!function_exists('array_to_tree')) {
if ($keep_pid === false) { if ($keep_pid === false) {
unset($item[$with]); 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) { if ($children) {
$item['children'] = $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'); 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

@@ -25,6 +25,7 @@ class ProductTcoCategoryBaseModel extends BaseModel
'tco_path' => 'string', 'tco_path' => 'string',
'erp_id' => 'int', 'erp_id' => 'int',
'erp_pid' => 'int', 'erp_pid' => 'int',
'erp_code' => 'string',
'erp_path' => 'string', 'erp_path' => 'string',
'disabled' => 'int', 'disabled' => 'int',
'sync_time' => 'int', 'sync_time' => 'int',

View File

@@ -25,6 +25,7 @@ class SysBannerItemBaseModel extends BaseModel
'desc_txt_color' => 'string', 'desc_txt_color' => 'string',
'type' => 'string', 'type' => 'string',
'image' => 'string', 'image' => 'string',
'extra_image' => 'string',
'video' => 'string', 'video' => 'string',
'link_to' => 'string', 'link_to' => 'string',
'link' => 'string', 'link' => 'string',

View File

@@ -17,13 +17,14 @@ class SysConfigGroupBaseModel extends BaseModel
// 字段信息 // 字段信息
protected $schema = [ protected $schema = [
'id' => 'int', 'id' => 'int',
'language_id' => 'int', 'language_id' => 'int',
'name' => 'string', 'unique_label' => 'string',
'sort' => 'int', 'name' => 'string',
'status' => 'int', 'sort' => 'int',
'created_at' => 'datetime', 'status' => 'int',
'updated_at' => 'datetime', 'created_at' => 'datetime',
'deleted_at' => 'datetime', 'updated_at' => 'datetime',
'deleted_at' => 'datetime',
]; ];
} }

View File

@@ -18,6 +18,6 @@ class SysRoleAuthorityBaseModel extends Model
protected $schema = [ protected $schema = [
'role_id' => 'int', 'role_id' => 'int',
'menu_id' => 'int', 'menu_id' => 'int',
'permission' => 'int', 'permission' => 'string',
]; ];
} }

View File

@@ -111,3 +111,133 @@ if (!function_exists('lang_i18n')) {
return Lang::get($lang_key, $vars, $lang); return Lang::get($lang_key, $vars, $lang);
} }
} }
if (!function_exists('date_format_i18n')) {
/**
* 格式化日期时间为指定语言
* @param int|string $datetime 要格式化的日期时间字符串
* @param string $lang 语言标识
* @param bool $keep_time 是否保留时间
* @return string
*/
function date_format_i18n(int|string|null $datetime, string $lang = '', bool $keep_time = false): string
{
// 处理语言标识,若未提供则使用当前语言设置,并转换为小写
$lang = $lang ?: Lang::getLangSet();
$lang = strtolower($lang);
// 处理日期时间输入
if (is_numeric($datetime)) {
// 若输入为数字,直接作为时间戳处理
$timestamp = (int)$datetime;
} elseif (is_string($datetime)) {
// 尝试将字符串转换为时间戳
$timestamp = strtotime($datetime);
if ($timestamp === false) {
return '';
}
} else {
return '';
}
// 根据$datetime传值决定格式
$date_parts = [];
if (is_numeric($datetime)) {
$date_str = date('Y-m-d', $timestamp);
$date_parts = explode('-', $date_str);
} elseif (is_string($datetime)) {
if (preg_match('/^\d{4}$/', $datetime)) {
$date_parts = [$datetime];
} elseif (preg_match('/^\d{4}-\d{1,2}$/', $datetime)) {
$date_parts = explode('-', $datetime);
} elseif (preg_match('/^\d{4}-\d{1,2}-\d{1,2}(.{1,9})?$/', $datetime)) {
$date_parts = explode('-', $datetime);
}
}
// 定义默认格式
$fmt = '';
// 根据语言和日期部分数量设置日期格式
$format = [
'zh-cn' => [0 => '', 1 => 'Y', 2 => 'Y-m', 3 => 'Y-m-d'],
'en-us' => [0 => '', 1 => 'Y', 2 => 'F Y', 3 => 'F j, Y'],
'default' => [0 => '', 1 => 'Y', 2 => 'Y-m', 3 => 'Y-m-d']
];
$fmt = $format[$lang][count($date_parts)] ?? $format['default'][count($date_parts)];
// 若需要保留时间
if ($keep_time) {
if ($lang === 'en-us') {
$fmt .= ', g:i A';
} else {
$fmt .= ' H:i:s';
}
}
return date($fmt, $timestamp);
}
}
if (!function_exists('get_platform')) {
/**
* 获取平台
* @return string
*/
function get_platform(): string
{
$detect = new \Detection\MobileDetect();
$platform = 'pc';
if ($detect->isMobile() || $detect->isTablet()) {
$platform = 'mobile';
} else {
// 在非移动端环境,根据配置规则判断是否要显示移动端
$view_cfg = $view_cfg = [
'rule' => env('INDEX_VIEW_TPL.RULE', 'query'),
'query' => [
'name' => env('INDEX_VIEW_TPL.RULE_QUERY_NAME', 'mtpl'),
'value' => env('INDEX_VIEW_TPL.RULE_QUERY_VALUE', '1'),
],
'domain' => [
'scheme' => env('INDEX_VIEW_TPL.RULE_DOMAIN_SCHEME', ['http']),
'host' => env('INDEX_VIEW_TPL.RULE_DOMAIN_HOST'),
],
];
if ($view_cfg['rule'] == 'query') {
$name = $view_cfg['query']['name'];
$value = $view_cfg['query']['value'];
if (request()->get($name) == $value) {
$platform = 'mobile';
}
} elseif ($view_cfg['rule'] == 'domain') {
$scheme = $view_cfg['domain']['scheme'];
$host = $view_cfg['domain']['host'];
if (in_array(request()->scheme(), $scheme) && $host == request()->host()) {
$platform = 'mobile';
}
}
}
return $platform;
}
}
if (!function_exists('highlight_keywords')) {
/**
* 高亮关键词
* @param string $text // 要处理的文本
* @param string $keyword // 关键词
* @param string|callable $repalce // 替换函数或字符串
* @return string
*/
function highlight_keywords(string $text, string $keyword, string|callable $replace): string
{
return preg_replace_callback('/' . preg_quote($keyword, '/') . '+/i', function($match) use($text, $replace) {
if (empty($match)) return $text;
if (is_string($replace)) return '<strong>' . $match[0] . '</strong>';
if (is_callable($replace)) return $replace($match[0]);
return $match[0];
}, $text);
}
}

View File

@@ -19,7 +19,7 @@ return [
// 扩展语言包 // 扩展语言包
'extend_list' => [ 'extend_list' => [
'en-us' => [ 'en-us' => [
app()->getAppPath() . '/lang/en-us/' . (request()->isMobile() ? 'mobile' : 'pc') . '.php', app()->getAppPath() . '/lang/en-us/' . get_platform() . '.php',
app()->getAppPath() . '/lang/en-us/validate.php', app()->getAppPath() . '/lang/en-us/validate.php',
], ],
], ],

View File

@@ -2,10 +2,8 @@
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | 模板设置 // | 模板设置
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
$view_device_name = 'pc';
if (request()->isMobile()) { $view_device_name = get_platform();
$view_device_name = 'mobile';
}
return [ return [
// 模板引擎类型使用Think // 模板引擎类型使用Think

View File

@@ -115,13 +115,18 @@ class Article extends Common
View::assign('comments', $comments); View::assign('comments', $comments);
// 获取倒序或发布时间倒序3篇文章做为推荐文章 // 获取倒序或发布时间倒序3篇文章做为推荐文章
$recommends = ArticleModel::field([ $category_model = new ArticleCategoryModel;
$parent_id = $category_model->bypk($detail['category_id'])->value('pid');
$categorys = $category_model->child($parent_id)->column('id');
$recommends = ArticleModel::field([
'id', 'id',
'title', 'title',
'desc', 'desc',
'image' 'image'
]) ])
->where('id', '<>', $id) ->where('id', '<>', $id)
->language($this->lang_id)
->category($categorys)
->order(['release_time' => 'desc', 'id' => 'desc']) ->order(['release_time' => 'desc', 'id' => 'desc'])
->limit(3) ->limit(3)
->select(); ->select();
@@ -165,9 +170,9 @@ class Article extends Common
]); ]);
$ret = ArticleLeaveMessageModel::create($data); $ret = ArticleLeaveMessageModel::create($data);
if ($ret->isEmpty()) { if ($ret->isEmpty()) {
return error(lang('留言提交失败')); return error(lang('信息提交失败'));
} }
return success(lang('留言提交成功')); return success(lang('信息已成功提交!'));
} }
} }

View File

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

View File

@@ -106,6 +106,7 @@ abstract class Common extends BaseController
'language_id' => $language, 'language_id' => $language,
'status' => 1 'status' => 1
]) ])
->where('status', '=', 1)
->order(['sort' => 'asc', 'id' => 'asc']) ->order(['sort' => 'asc', 'id' => 'asc'])
->select(); ->select();
if ($nav->isEmpty()) { if ($nav->isEmpty()) {

View File

@@ -45,14 +45,7 @@ class ContactUs extends Common
$banner_map[$v->unique_label] = $v; $banner_map[$v->unique_label] = $v;
} }
$focus_image = data_get($banner_map, 'BANNER_6805e3d32dcc2')?->items->first()?->toArray(); $focus_image = data_get($banner_map, 'BANNER_6805e3d32dcc2')?->items->first()?->toArray();
$info_datas = data_get($banner_map, 'BANNER_6806090c1838f')?->items->each(function($item) { $info_datas = data_get($banner_map, 'BANNER_6806090c1838f')?->items->toArray();
if (Str::contains($item->title, '<br/>')) {
$title = explode('<br/>', $item->title);
$item->title = $title[0];
$item->title_short = $title[1];
}
return $item;
})->toArray();
} }
View::assign('focus_image', $focus_image); View::assign('focus_image', $focus_image);
View::assign('info_datas', $info_datas); View::assign('info_datas', $info_datas);
@@ -136,6 +129,7 @@ class ContactUs extends Common
'corp_name', 'corp_name',
'email', 'email',
'phone', 'phone',
'website_url',
'business_type', 'business_type',
'enterprise_size', 'enterprise_size',
'address', 'address',
@@ -155,7 +149,7 @@ class ContactUs extends Common
'email' => $form_data['email'], 'email' => $form_data['email'],
'phone' => $form_data['phone'], 'phone' => $form_data['phone'],
'referer_url' => request()->header('referer'), 'referer_url' => request()->header('referer'),
'website_url' => request()->header('host'), 'website_url' => $form_data['website_url'],
'business_type' => $form_data['business_type'], 'business_type' => $form_data['business_type'],
'enterprise_size' => $form_data['enterprise_size'], 'enterprise_size' => $form_data['enterprise_size'],
'address' => $form_data['address'], 'address' => $form_data['address'],

View File

@@ -29,6 +29,7 @@ class Faq extends Common
'at_platform' => request()->from 'at_platform' => request()->from
]) ])
->type('image') ->type('image')
->enabled()
->visible(['id', 'title', 'image', 'link']) ->visible(['id', 'title', 'image', 'link'])
->find(); ->find();
View::assign('banner', $banner); View::assign('banner', $banner);

View File

@@ -45,6 +45,7 @@ class Product extends Common
->where('status', '=', 1) ->where('status', '=', 1)
->order(['sort' => 'asc', 'id' => 'desc']); ->order(['sort' => 'asc', 'id' => 'desc']);
}]) }])
->atPlatform(request()->from)
->uniqueLabel(['BANNER_6808abd813d78']) ->uniqueLabel(['BANNER_6808abd813d78'])
->language($this->lang_id) ->language($this->lang_id)
->enabled(true) ->enabled(true)
@@ -103,7 +104,7 @@ class Product extends Common
->onSale(true) ->onSale(true)
->onShelves(true) ->onShelves(true)
->append(['p' => $list[0]['id']]) ->append(['p' => $list[0]['id']])
->order(['sort' => 'asc', 'id' => 'desc']) ->order(['sort' => 'asc', 'created_at' => 'desc', 'id' => 'desc'])
->limit(5) ->limit(5)
->buildSql(); ->buildSql();
$query = \think\facade\Db::table("($sql) as a"); $query = \think\facade\Db::table("($sql) as a");
@@ -125,7 +126,7 @@ class Product extends Common
->enabled(true) ->enabled(true)
->onSale(true) ->onSale(true)
->onShelves(true) ->onShelves(true)
->order(['sort' => 'asc', 'id' => 'desc']) ->order(['sort' => 'asc', 'created_at' => 'desc', 'id' => 'desc'])
->limit(5); ->limit(5);
}); });
} }
@@ -191,7 +192,7 @@ class Product extends Common
->enabled(true) ->enabled(true)
->onSale(true) ->onSale(true)
->onShelves(true) ->onShelves(true)
->order(['sort' => 'asc', 'id' => 'desc']) ->order(['sort' => 'asc', 'created_at' => 'desc', 'id' => 'desc'])
->select(); ->select();
if (!$products->isEmpty()) { if (!$products->isEmpty()) {
// 获取sku信息 // 获取sku信息
@@ -222,7 +223,7 @@ class Product extends Common
foreach ($skus as $v) { foreach ($skus as $v) {
// 找到相应产品的sku图片信息 // 找到相应产品的sku图片信息
$skus_map[$v['product_id']][] = [ $skus_map[$v['product_id']][] = [
'id' => $v['id'], 'id' => $v['id'],
'sku' => $v['sku'], 'sku' => $v['sku'],
'main_image' => $v['main_image'], 'main_image' => $v['main_image'],
]; ];
@@ -230,7 +231,7 @@ class Product extends Common
$attr = $sku_attrs_map[$v['id']]?? []; $attr = $sku_attrs_map[$v['id']]?? [];
if (!empty($attr)) { if (!empty($attr)) {
foreach ($attr as $at) { foreach ($attr as $at) {
if ($at['attr_name'] == '颜色') { if (in_array($at['attr_name'], ['颜色', 'Color'])) {
$color_map[$v['product_id']][] = $at; $color_map[$v['product_id']][] = $at;
} }
} }
@@ -276,7 +277,7 @@ class Product extends Common
'page/d' => 1, 'page/d' => 1,
'size/d' => 10 'size/d' => 10
]); ]);
$keywords = $param['keywords'] ?? ''; $keywords = !empty($param['keywords']) ? trim($param['keywords']) : '';
// 关键词搜索 // 关键词搜索
$products = ProductModel::field([ $products = ProductModel::field([
@@ -298,9 +299,10 @@ class Product extends Common
'query' => request()->param() 'query' => request()->param()
]) ])
->each(function ($item) use($keywords) { ->each(function ($item) use($keywords) {
$item['spu'] = str_replace($keywords, '<strong class="redpoint">'.$keywords.'</strong>', $item['spu']); $replace = fn($txt) => '<strong class="redpoint">' . $txt . '</strong>';
$item['name'] = str_replace($keywords, '<strong class="redpoint">'.$keywords.'</strong>', $item['name']); $item['spu'] = highlight_keywords($item['spu'], $keywords, $replace);
$item['short_name'] = str_replace($keywords, '<strong class="redpoint">'.$keywords.'</strong>', $item['short_name']); $item['name'] = highlight_keywords($item['name'], $keywords, $replace);
$item['short_name'] = highlight_keywords($item['short_name'], $keywords, $replace);
return $item; return $item;
}); });
View::assign('products', $products); View::assign('products', $products);
@@ -372,10 +374,12 @@ class Product extends Common
// 获取属性名称 // 获取属性名称
$attrs = ProductAttrModel::bypks(array_unique(Arr::pluck($sku_attrs, 'attr_id')))->column(['attr_name'], 'id'); $attrs = ProductAttrModel::bypks(array_unique(Arr::pluck($sku_attrs, 'attr_id')))->column(['attr_name'], 'id');
foreach ($sku_attrs as $v) { foreach ($sku_attrs as $v) {
if (empty($v['attr_value'])) continue;
$v['attr_name'] = $attrs[$v['attr_id']]?? ''; $v['attr_name'] = $attrs[$v['attr_id']]?? '';
// 按属性分组 // 按属性分组
$product_sku_attrs[$v['attr_id']]['attr_id'] = $v['attr_id']; $product_sku_attrs[$v['attr_id']]['attr_id'] = $v['attr_id'];
$product_sku_attrs[$v['attr_id']]['attr_name'] = $v['attr_name']; $product_sku_attrs[$v['attr_id']]['attr_name'] = $v['attr_name'];
$product_sku_attrs[$v['attr_id']]['attr_values'][] = [ $product_sku_attrs[$v['attr_id']]['attr_values'][] = [
'sku_id' => $v['sku_id'], 'sku_id' => $v['sku_id'],
'attr_value' => $v['attr_value'], 'attr_value' => $v['attr_value'],
@@ -392,8 +396,11 @@ class Product extends Common
->order(['sort' => 'asc', 'id' => 'desc']) ->order(['sort' => 'asc', 'id' => 'desc'])
->select() ->select()
->hidden(['platform']) ->hidden(['platform'])
->bindAttr('platform', ['platform_name' => 'platform']) ->bindAttr('platform', ['platform_name' => 'platform', 'platform_sort' => 'sort'])
->toArray(); ->toArray();
// 根据购买链接平台排序
$sort_by_arr = array_column($product_purchase_links, 'platform_sort');
array_multisort($sort_by_arr, SORT_ASC, $product_purchase_links);
// 获取相关产品信息 // 获取相关产品信息
$related = ProductRelatedModel::with(['product' => function($query) { $related = ProductRelatedModel::with(['product' => function($query) {
@@ -456,9 +463,9 @@ class Product extends Common
'message' => $post['message'], 'message' => $post['message'],
]); ]);
if ($ret->isEmpty()) { if ($ret->isEmpty()) {
return error(lang('提交成功')); return error(lang('提交失败'));
} }
return success(lang('提交失败')); return success(lang('提交成功'));
} }
/** /**
@@ -478,6 +485,7 @@ class Product extends Common
->where('status', '=', 1) ->where('status', '=', 1)
->order(['sort' => 'asc', 'id' => 'desc']); ->order(['sort' => 'asc', 'id' => 'desc']);
}]) }])
->atPlatform(request()->from)
->uniqueLabel(['BANNER_680dd7ceaa529']) ->uniqueLabel(['BANNER_680dd7ceaa529'])
->language($this->lang_id) ->language($this->lang_id)
->enabled(true) ->enabled(true)

View File

@@ -21,7 +21,7 @@ class TopicNas extends Common
// 获取国家/语言列表 // 获取国家/语言列表
$languages = $this->getLanguages(); $languages = $this->getLanguages();
// 输出国家/语言列表 // 输出国家/语言列表
if (request()->isMobile()) { if (get_platform() == 'mobile') {
View::assign('header_languages', $languages); View::assign('header_languages', $languages);
} }
@@ -66,7 +66,8 @@ class TopicNas extends Common
// 获取banner数据 // 获取banner数据
$banners = SysBannerModel::with(['items' => function($query) { $banners = SysBannerModel::with(['items' => function($query) {
$query->withoutField(['sort', 'created_at', 'updated_at', 'deleted_at']) $query->withoutField(['sort', 'created_at', 'updated_at', 'deleted_at'])
->order(['sort' => 'asc', 'id' => 'desc']); ->order(['sort' => 'asc', 'id' => 'desc'])
->enabled(true);
}]) }])
->atPlatform(request()->from) ->atPlatform(request()->from)
->uniqueLabel([ ->uniqueLabel([
@@ -110,8 +111,11 @@ class TopicNas extends Common
$trial_instructions = []; $trial_instructions = [];
// 获取banner数据 // 获取banner数据
$banners = SysBannerModel::with(['items' => function($query) { $banners = SysBannerModel::with(['items' => function($query) {
$query->withoutField(['sort', 'created_at', 'updated_at', 'deleted_at']); $query->withoutField(['sort', 'created_at', 'updated_at', 'deleted_at'])
->order(['sort' => 'asc', 'id' => 'desc'])
->enabled(true);
}]) }])
->atPlatform(request()->from)
->uniqueLabel([ ->uniqueLabel([
'BANNER_68103aaebe4c4', 'BANNER_68103aaebe4c4',
'BANNER_68103acd1a8b9', 'BANNER_68103acd1a8b9',
@@ -148,8 +152,11 @@ class TopicNas extends Common
$cooperation_cotacts = []; $cooperation_cotacts = [];
// 获取banner数据 // 获取banner数据
$banners = SysBannerModel::with(['items' => function($query) { $banners = SysBannerModel::with(['items' => function($query) {
$query->withoutField(['sort', 'created_at', 'updated_at', 'deleted_at']); $query->withoutField(['sort', 'created_at', 'updated_at', 'deleted_at'])
->order(['sort' => 'asc', 'id' => 'desc'])
->enabled(true);
}]) }])
->atPlatform(request()->from)
->uniqueLabel([ ->uniqueLabel([
'BANNER_6810670b8ef17', 'BANNER_6810670b8ef17',
'BANNER_681067451b78f', 'BANNER_681067451b78f',
@@ -185,25 +192,66 @@ class TopicNas extends Common
{ {
// 获取文章分类及文章数据 // 获取文章分类及文章数据
$parent = ArticleCategoryModel::uniqueLabel('CATEGORY_681182e0a4529')->language($this->lang_id)->value('id'); $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) { $article_categorys = ArticleCategoryModel::with(['article' => function($query) {
$query->field(['id', 'title', 'category_id'])->limit(3); $query->field(['id', 'title', 'category_id'])
->order(['sort' => 'asc', 'id' => 'desc'])
->limit(3);
}]) }])
->field([ ->field([
'id', 'id',
'pid',
'name', 'name',
'icon' 'icon'
]) ])
->language($this->lang_id) ->language($this->lang_id)
->parent($parent) // ->parent($parent)
->parentChild($parent_two)
->isShow(true) ->isShow(true)
->order(['sort' => 'asc', 'id' => 'desc'])
->select(); ->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 = []; $contacts = [];
// 获取banner数据 // 获取banner数据
$banners = SysBannerModel::with(['items' => function ($query) { $banners = SysBannerModel::with(['items' => function ($query) {
$query->withoutField(['sort', 'created_at', 'updated_at', 'deleted_at']); $query->withoutField(['sort', 'created_at', 'updated_at', 'deleted_at'])
->order(['sort' => 'asc', 'id' => 'desc'])
->enabled(true);
}]) }])
->atPlatform(request()->from)
->uniqueLabel(['BANNER_6819754be2dc6']) ->uniqueLabel(['BANNER_6819754be2dc6'])
->language($this->lang_id) ->language($this->lang_id)
->enabled(true) ->enabled(true)
@@ -233,19 +281,46 @@ class TopicNas extends Common
// 获取文章分类及文章数据 // 获取文章分类及文章数据
$parent = ArticleCategoryModel::uniqueLabel('CATEGORY_681182e0a4529')->language($this->lang_id)->value('id'); $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) { $article_categorys = ArticleCategoryModel::with(['article' => function ($query) {
$query->field(['id', 'title', 'category_id']); $query->field(['id', 'title', 'category_id'])->order(['sort' => 'asc', 'id' => 'desc']);
}]) }])
->field([ ->field([
'id', 'id',
'pid',
'name', 'name',
'icon' 'icon'
]) ])
->language($this->lang_id) ->language($this->lang_id)
->parent($parent) // ->parent($parent)
->parentChild($parent_two)
->isShow(true) ->isShow(true)
->order(['sort' => 'asc', 'id' => 'desc'])
->select(); ->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'); return View::fetch('help_detail');
} }
@@ -257,17 +332,64 @@ class TopicNas extends Common
{ {
$keywords = request()->post('keywords'); $keywords = request()->post('keywords');
// 根据关键词查询文章 // 根据关键词查询文章
$parent = ArticleCategoryModel::uniqueLabel('CATEGORY_681182e0a4529')
->language($this->lang_id)
->value('id');
// 获取帮且中心分类子分类
$categorys = [];
$table_name = (new ArticleCategoryModel)->getTable();
if (env('DB_VERSION', '5') == '8') {
$categorys = \think\facade\Db::query(preg_replace(
'/\s+/u',
' ',
"WITH RECURSIVE article_tree_by AS (
SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$parent}
UNION ALL
SELECT k.id, k.pid FROM $table_name k INNER JOIN article_tree_by t ON t.id = k.pid
)
SELECT id FROM article_tree_by WHERE id <> {$parent}"
));
} else {
$categorys = \think\facade\Db::query("
SELECT t2.id
FROM (
SELECT
@r AS _id, (SELECT @r := GROUP_CONCAT(id) FROM $table_name WHERE FIND_IN_SET(pid, _id)) AS parent_id
FROM
(SELECT @r := $parent) vars, $table_name h
WHERE @r <> 0) t1
JOIN $table_name t2
ON FIND_IN_SET(t2.pid, t1._id)
ORDER BY t2.id;
");
}
if (empty($categorys)) return success('success', []);
// 获取文章数据
$articles = ArticleModel::field([ $articles = ArticleModel::field([
'id', 'id',
'category_id',
'title' 'title'
]) ])
->withSearch(['title'], [ ->withSearch(['title'], [
'title' => $keywords??null 'title' => $keywords??null
]) ])
->language($this->lang_id) ->language($this->lang_id)
->where('category_id', 'IN', array_column($categorys, 'id'))
->select(); ->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);
} }
/** /**
@@ -278,8 +400,11 @@ class TopicNas extends Common
$data = []; $data = [];
// 获取banner数据 // 获取banner数据
$banners = SysBannerModel::with(['items' => function($query) { $banners = SysBannerModel::with(['items' => function($query) {
$query->withoutField(['sort', 'created_at', 'updated_at', 'deleted_at']); $query->withoutField(['sort', 'created_at', 'updated_at', 'deleted_at'])
->order(['sort' => 'asc', 'id' => 'desc'])
->enabled(true);
}]) }])
->atPlatform(request()->from)
->uniqueLabel([ ->uniqueLabel([
'BANNER_6810798e6e828', 'BANNER_6810798e6e828',
'BANNER_68107a0a63910', 'BANNER_68107a0a63910',

View File

@@ -39,6 +39,7 @@ return [
'电子邮箱' => 'Email', '电子邮箱' => 'Email',
'您的电子邮件地址不会被公开' => 'Your email address will not be pulished.', '您的电子邮件地址不会被公开' => 'Your email address will not be pulished.',
'留言内容' => 'Comment', '留言内容' => 'Comment',
'评论' => 'COMMENT',
'提交留言' => 'POST COMMENT', '提交留言' => 'POST COMMENT',
'你可能还喜欢' => 'Recommended for you', '你可能还喜欢' => 'Recommended for you',
'链接复制成功' => 'Link copied successfully', '链接复制成功' => 'Link copied successfully',
@@ -52,6 +53,7 @@ return [
'product/search' => [ 'product/search' => [
'搜索' => 'Search', '搜索' => 'Search',
'请搜索' => 'Please search...', '请搜索' => 'Please search...',
'暂无数据' => 'No data',
], ],
// 产品详情 // 产品详情
'product/detail' => [ 'product/detail' => [
@@ -178,4 +180,43 @@ return [
'网络存储解决方案' => 'Network Storage Solutions', '网络存储解决方案' => 'Network Storage Solutions',
'配套软件' => 'Software', '配套软件' => 'Software',
], ],
// nas主题 - 客户合作页
'topicnas/cooperation' => [
'成为ORICO合作伙伴' => 'Be an ORICO partner',
'合作伙伴招募' => 'Partner recruitment',
'广告代理' => 'Advertising Agency',
'抖音销售' => 'Douyin Sales',
'代理经销合作' => 'Proxy and distribution cooperation',
'ODM合作' => 'ODM cooperation',
'合作优势' => 'Cooperation advantages',
'期待与您的合作' => 'Looking forward to working with you'
],
// nas主题 - 下载页
'topicnas/download' => [
'CyberData赛博云空间' => 'CyberData',
'Weline微链接' => 'Weline'
],
// nas主题 - 帮助页
'topicnas/help' => [
'帮助中心' => 'Quick Start Guide',
'请输入搜索关键字,如安装赛博云空间,影视库' => 'What are you looking for?',
'取消' => 'Cancel',
'使用教程' => 'User\' s Guide',
'查看更多' => 'Click to view more',
'联系我们' => 'Contact US',
'目录' => 'Content'
],
// nas主题 - 帮助详情页
'topicnas/helpdetail' => [
'帮助中心' => 'Quick Start Guide',
'请输入搜索关键字,如安装赛博云空间,影视库' => 'What are you looking for?',
'取消' => 'Cancel',
'使用教程' => 'User\' s Guide',
'联系我们' => 'Contact US',
'目录' => 'Content'
],
]; ];

View File

@@ -1,6 +1,7 @@
<?php <?php
return [ return [
'首页' => 'Home',
'产品列表' => 'Products', '产品列表' => 'Products',
'店铺' => 'Store', '店铺' => 'Store',
'搜索记录' => 'Search History', '搜索记录' => 'Search History',
@@ -35,6 +36,7 @@ return [
'电子邮箱' => 'Email', '电子邮箱' => 'Email',
'您的电子邮件地址不会被公开' => 'Your email address will not be pulished.', '您的电子邮件地址不会被公开' => 'Your email address will not be pulished.',
'留言内容' => 'Comment', '留言内容' => 'Comment',
'评论' => 'COMMENT',
'提交留言' => 'POST COMMENT', '提交留言' => 'POST COMMENT',
'你可能还喜欢' => 'Recommended for you', '你可能还喜欢' => 'Recommended for you',
'链接复制成功' => 'Link copied successfully', '链接复制成功' => 'Link copied successfully',
@@ -51,14 +53,14 @@ return [
'视频' => 'Videos', '视频' => 'Videos',
'支持型号' => 'Supported Models', '支持型号' => 'Supported Models',
'支持系统' => 'Supported Systems', '支持系统' => 'Supported Systems',
'搜索型号' => 'Search model', '搜索' => 'Search',
'查询无结果!' => 'No Result', '查询无结果!' => 'No Result',
], ],
// 附件页 - 视频 // 附件页 - 视频
'attachment/video' => [ 'attachment/video' => [
'软件和驱动程序' => 'Software and Drivers', '软件和驱动程序' => 'Software and Drivers',
'搜索型号' => 'Search model', '搜索' => 'Search',
'视频' => 'Videos', '视频' => 'Videos',
'查询无此视频!' => 'No Video', '查询无此视频!' => 'No Video',
], ],
@@ -159,6 +161,7 @@ return [
// 产品 - 产品详情页 // 产品 - 产品详情页
'product/detail' => [ 'product/detail' => [
'首页' => 'Home', '首页' => 'Home',
'型号' => 'Product Model',
'产品详情' => 'Product Description', '产品详情' => 'Product Description',
'相关产品' => 'Related Products', '相关产品' => 'Related Products',
'发送查询' => 'Send Inquiry', '发送查询' => 'Send Inquiry',
@@ -175,6 +178,11 @@ return [
'提交' => 'SUBMIT', '提交' => 'SUBMIT',
], ],
// 产品 - 搜索
'product/search' => [
'暂无数据' => 'No data',
],
// 产品 - 分类 // 产品 - 分类
'product/category' => [ 'product/category' => [
'查看全部' => 'View All', '查看全部' => 'View All',

View File

@@ -9,17 +9,20 @@ return [
'姓名不能超过:rule个字符' => 'Name cannot exceed :rule characters', '姓名不能超过:rule个字符' => 'Name cannot exceed :rule characters',
'电话号码不能为空' => 'Phone Number is required', '电话号码不能为空' => 'Phone Number is required',
'电话号码不能超过:rule个字符' => 'Phone number cannot exceed :rule characters', '电话号码不能超过:rule个字符' => 'Phone number cannot exceed :rule characters',
'感兴趣的产品种类不能为空' => 'Interested product categories is required',
'感兴趣的产品种类不能超过:rule个字符' => 'Interested product categories cannot exceed :rule characters', '感兴趣的产品种类不能超过:rule个字符' => 'Interested product categories cannot exceed :rule characters',
'邮箱不能为空' => 'Email is required', '邮箱不能为空' => 'Email is required',
'邮箱格式不正确' => 'Email format is incorrect', '邮箱格式不正确' => 'Email format is incorrect',
'邮箱不能超过:rule个字符' => 'Email cannot exceed :rule characters', '邮箱不能超过:rule个字符' => 'Email cannot exceed :rule characters',
'国家不能为空' => 'Country is required', '国家不能为空' => 'Country is required',
'国家不能超过:rule个字符' => 'Country cannot exceed :rule characters', '国家不能超过:rule个字符' => 'Country cannot exceed :rule characters',
'网址格式不正确' => 'URL format is incorrect',
'网址不能超过:rule个字符' => 'URL cannot exceed :rule characters', '网址不能超过:rule个字符' => 'URL cannot exceed :rule characters',
'公司名称不能为空' => 'Company Name is required', '公司名称不能为空' => 'Company Name is required',
'公司名称不能超过:rule个字符' => 'Company name cannot exceed :rule characters', '公司名称不能超过:rule个字符' => 'Company name cannot exceed :rule characters',
'公司地址不能为空' => 'Company Address is required', '公司地址不能为空' => 'Company Address is required',
'公司地址不能超过:rule个字符' => 'Company Address cannot exceed :rule characters', '公司地址不能超过:rule个字符' => 'Company Address cannot exceed :rule characters',
'留言不能为空' => 'Message is required',
'企业规模不能为空' => 'Enterprise Size is required', '企业规模不能为空' => 'Enterprise Size is required',
'企业规模不能超过:rule个字符' => 'Enterprise Size cannot exceed :rule characters', '企业规模不能超过:rule个字符' => 'Enterprise Size cannot exceed :rule characters',
'业务类型不能为空' => 'Type of Business is required', '业务类型不能为空' => 'Type of Business is required',

View File

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

View File

@@ -15,10 +15,7 @@ class ConfirmRequestFrom
public function handle($request, \Closure $next) public function handle($request, \Closure $next)
{ {
// 确认请求来源 // 确认请求来源
$request->from = 'pc'; $request->from = get_platform();
if ($request->isMobile()) {
$request->from = 'mobile';
}
return $next($request); return $next($request);
} }

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,38 @@ class ArticleCategoryModel extends ArticleCategoryBaseModel
$query->where('pid', '=', $parent); $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)
{
$query->where(function($q) use($id, $merge_self) {
$q->where('pid', '=', $id);
if ($merge_self) {
$q->whereOr('id', '=', $id);
}
});
}
// 是否显示状态范围查询 // 是否显示状态范围查询
public function scopeIsShow($query, bool $is_show) public function scopeIsShow($query, bool $is_show)
{ {

View File

@@ -32,6 +32,11 @@ class ArticleModel extends ArticleBaseModel
// 文章分类范围查询 // 文章分类范围查询
public function scopeCategory($query, $category) public function scopeCategory($query, $category)
{ {
if (is_null($category)) return;
if (is_array($category)) {
$query->where('category_id', 'in', $category);
return;
}
$query->where('category_id', '=', $category); $query->where('category_id', '=', $category);
} }

View File

@@ -79,6 +79,6 @@ class ProductModel extends ProductBaseModel
// 关键词搜索 // 关键词搜索
public function searchKeywordsAttr($query, string $keywords) public function searchKeywordsAttr($query, string $keywords)
{ {
$query->whereRaw('BINARY spu LIKE "%' . $keywords . '%" OR BINARY name LIKE "%' . $keywords . '%" OR BINARY short_name LIKE "%' . $keywords . '%"'); $query->whereRaw('spu LIKE "%' . $keywords . '%" OR name LIKE "%' . $keywords . '%" OR short_name LIKE "%' . $keywords . '%"');
} }
} }

View File

@@ -15,12 +15,12 @@ class ContactUsBulkBuyValidate extends Validate
*/ */
protected $rule = [ protected $rule = [
'corp_name' => 'require|max:128', 'corp_name' => 'require|max:128',
'url' => 'max:255', 'url' => 'url|max:255',
'first_name' => 'require|max:64', 'first_name' => 'require|max:64',
'last_name' => 'require|max:64', 'last_name' => 'require|max:64',
'email' => 'require|email|max:128', 'email' => 'require|email|max:128',
'phone' => 'max:32', 'phone' => 'max:32',
'interested' => 'max:255', 'interested' => 'require|max:255',
'message' => 'require|max:1024', 'message' => 'require|max:1024',
]; ];
@@ -33,6 +33,7 @@ class ContactUsBulkBuyValidate extends Validate
protected $message = [ protected $message = [
'corp_name.require' => '公司名称不能为空', 'corp_name.require' => '公司名称不能为空',
'corp_name.max' => '公司名称不能超过:rule个字符', 'corp_name.max' => '公司名称不能超过:rule个字符',
'url.url' => '网址格式不正确',
'url.max' => '网址不能超过:rule个字符', 'url.max' => '网址不能超过:rule个字符',
'first_name.require' => '名不能为空', 'first_name.require' => '名不能为空',
'first_name.max' => '名不能超过:rule个字符', 'first_name.max' => '名不能超过:rule个字符',
@@ -42,6 +43,7 @@ class ContactUsBulkBuyValidate extends Validate
'email.email' => '邮箱格式不正确', 'email.email' => '邮箱格式不正确',
'email.max' => '邮箱不能超过:rule个字符', 'email.max' => '邮箱不能超过:rule个字符',
'phone.max' => '电话号码不能超过:rule个字符', 'phone.max' => '电话号码不能超过:rule个字符',
'interested.require' => '感兴趣的产品种类不能为空',
'interested.max' => '感兴趣的产品种类不能超过:rule个字符', 'interested.max' => '感兴趣的产品种类不能超过:rule个字符',
'message.require' => '留言内容不能为空', 'message.require' => '留言内容不能为空',
'message.max' => '留言内容不能超过:rule个字符', 'message.max' => '留言内容不能超过:rule个字符',

View File

@@ -17,6 +17,7 @@ class ContactUsDistributorValidate extends Validate
'corp_name' => 'require|max:64', 'corp_name' => 'require|max:64',
'email' => 'require|email|max:128', 'email' => 'require|email|max:128',
'phone' => 'require|max:64', 'phone' => 'require|max:64',
'website_url' => 'url|max:255',
'business_type' => 'require|max:128', 'business_type' => 'require|max:128',
'enterprise_size' => 'require|max:128', 'enterprise_size' => 'require|max:128',
'address' => 'require|max:255', 'address' => 'require|max:255',
@@ -37,6 +38,8 @@ class ContactUsDistributorValidate extends Validate
'email.max' => '邮箱不能超过:rule个字符', 'email.max' => '邮箱不能超过:rule个字符',
'phone.require' => '电话号码不能为空', 'phone.require' => '电话号码不能为空',
'phone.max' => '电话号码不能超过:rule个字符', 'phone.max' => '电话号码不能超过:rule个字符',
'website_url.url' => '网址格式不正确',
'website_url.max' => '网址不能超过:rule个字符',
'business_type.require' => '业务类型不能为空', 'business_type.require' => '业务类型不能为空',
'business_type.max' => '业务类型不能超过:rule个字符', 'business_type.max' => '业务类型不能超过:rule个字符',
'enterprise_size.require' => '企业规模不能为空', 'enterprise_size.require' => '企业规模不能为空',

View File

@@ -21,10 +21,23 @@
<div class="blog_detail"> <div class="blog_detail">
<div class="blog_title"> <div class="blog_title">
<h2>{$detail.title}</h2> <h2>{$detail.title}</h2>
<p>{$detail.release_time}</p> <p>{$detail.release_time|date_format_i18n}</p>
</div> </div>
<div class="blog_content">{$detail.content|raw}</div> <div class="blog_content">{$detail.content|raw}</div>
</div> </div>
{notempty name="comments"}
<div class="pl_box">
<div class="blog_pl">
<h3>{:lang_i18n('评论')}</h3>
{volist name="comments" id="cm"}
<div class="plitem">
<div class="pl_name">{$cm.name}:</div>
<div class="pl_text">{$cm.content}</div>
</div>
{/volist}
</div>
</div>
{/notempty}
<div class="share_box"> <div class="share_box">
{notempty name="share_config"} {notempty name="share_config"}
<div class="blog_share"> <div class="blog_share">
@@ -37,7 +50,7 @@
{notempty name="sc.url.value"}href="{$sc.url.value}"{/notempty}> {notempty name="sc.url.value"}href="{$sc.url.value}"{/notempty}>
{eq name=":array_key_exists('triggered_qrcode', $sc)" value="true"} {eq name=":array_key_exists('triggered_qrcode', $sc)" value="true"}
<img class="toggle_qrcode" src="{$sc.image.value}" /> <img class="toggle_qrcode" src="{$sc.image.value}" />
<div class="triggered_qrcode"> <div class="triggered_qrcode wechat_code">
<img src="{$sc.triggered_qrcode.value}" /> <img src="{$sc.triggered_qrcode.value}" />
</div> </div>
{else /} {else /}
@@ -73,7 +86,7 @@
<p class="thtitle">{:lang_i18n('你可能还喜欢')}</p> <p class="thtitle">{:lang_i18n('你可能还喜欢')}</p>
<p><img src="__IMAGES__/1line.webp"></p> <p><img src="__IMAGES__/1line.webp"></p>
</div> </div>
<div class="swiper-container loveswiper"> <div class="swiper loveswiper">
<div class="swiper-wrapper"> <div class="swiper-wrapper">
{volist name="recommends" id="vo"} {volist name="recommends" id="vo"}
<div class="swiper-slide"> <div class="swiper-slide">
@@ -115,18 +128,15 @@
}) })
$('.toggle_qrcode').click(function() { $('.toggle_qrcode').click(function() {
$(this).siblings('.triggered_qrcode').toggle(); const qrcode = $(this).siblings('.triggered_qrcode');
}) qrcode.css('display', qrcode.css('display') === 'none' ? 'flex' : 'none');
});
}) })
//banner轮播 //banner轮播
var loveswiper = new Swiper('.loveswiper', { var loveswiper = new Swiper('.loveswiper', {
// 配置选项 // 配置选项
slidesPerView: 2, slidesPerView: 2,
spaceBetween: 30, spaceBetween: 30,
loop: true,
autoplay: {
delay: 3000,
},
pagination: { pagination: {
el: '.swiper-pagination', el: '.swiper-pagination',
} }

View File

@@ -32,7 +32,7 @@
<form action="{:url('article/index', ['pid' => $Request.param.pid])}" method="get" autocomplete="off"> <form action="{:url('article/index', ['pid' => $Request.param.pid])}" method="get" autocomplete="off">
<input type="text" class="search" id="article-blog-in" name="keywords" value=""> <input type="text" class="search" id="article-blog-in" name="keywords" value="">
<input type="hidden" class="search" id="article-blog-in" name="cid" value="{$Request.get.cid}"> <input type="hidden" class="search" id="article-blog-in" name="cid" value="{$Request.get.cid}">
<button id="blog-btnput" class="search-button-blog" style="padding:5px 12px;">{:lang_i18n('搜索')}</button> <button id="blog-btnput" class="search-button-blog">{:lang_i18n('搜索')}</button>
</form> </form>
</div> </div>
{notempty name="articles"} {notempty name="articles"}
@@ -45,7 +45,7 @@
<h3>{$ar.title}</h3> <h3>{$ar.title}</h3>
<p>{$ar.desc|raw}</p> <p>{$ar.desc|raw}</p>
</a> </a>
<span class="blue">{$ar.release_time|default=''|date='Y-m-d'}</span> <span class="blue">{$ar.release_time|date_format_i18n}</span>
</li> </li>
{/volist} {/volist}
</ul> </ul>

View File

@@ -14,7 +14,7 @@
<div class="tabs"> <div class="tabs">
{notempty name="video_categorys"} {notempty name="video_categorys"}
{volist name="video_categorys" id="va"} {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} {/volist}
{/notempty} {/notempty}
</div> </div>

View File

@@ -44,7 +44,7 @@
</div> </div>
<div class="theit"> <div class="theit">
<div class="bditem bditem1"> <div class="bditem bditem1">
<label class="itlable">{:lang_i18n('您对哪个产品品类感兴趣?')}</label> <label class="itlable">{:lang_i18n('您对哪个产品品类感兴趣?')}<span class="redtag">*</span></label>
<div class="sfbchecks"> <div class="sfbchecks">
{notempty name="interested"} {notempty name="interested"}
{volist name="interested" id="it"} {volist name="interested" id="it"}

View File

@@ -19,19 +19,19 @@
<div class="theit"> <div class="theit">
<div class="bditem"> <div class="bditem">
<label class="itlable">{:lang_i18n('公司名称')}<span class="redtag">*</span></label> <label class="itlable">{:lang_i18n('公司名称')}<span class="redtag">*</span></label>
<input type="text" class="form-control itinp companyName" placeholder="{:lang_i18n('请输入公司名称')}" /> <input type="text" name="corp_name" class="form-control itinp companyName" placeholder="{:lang_i18n('请输入公司名称')}" />
</div> </div>
</div> </div>
<div class="theit"> <div class="theit">
<div class="bditem"> <div class="bditem">
<label class="itlable">{:lang_i18n('电子邮件')}<span class="redtag">*</span></label> <label class="itlable">{:lang_i18n('电子邮件')}<span class="redtag">*</span></label>
<input type="text" class="form-control itinp email" placeholder="{:lang_i18n('请输入邮箱')}" /> <input type="text" name="email" class="form-control itinp email" placeholder="{:lang_i18n('请输入邮箱')}" />
</div> </div>
</div> </div>
<div class="theit"> <div class="theit">
<div class="bditem bditem1"> <div class="bditem bditem1">
<label class="itlable">{:lang_i18n('电话号码')}<span class="redtag">*</span></label> <label class="itlable">{:lang_i18n('电话号码')}<span class="redtag">*</span></label>
<input type="text" class="form-control itinp mphone" placeholder="{:lang_i18n('请输入电话号码')}" /> <input type="text" name="phone" class="form-control itinp mphone" placeholder="{:lang_i18n('请输入电话号码')}" />
</div> </div>
</div> </div>
<div class="theit"> <div class="theit">
@@ -47,7 +47,7 @@
<div class="theit"> <div class="theit">
<div class="bditem"> <div class="bditem">
<label class="itlable">{:lang_i18n('在线商店网址')}</label> <label class="itlable">{:lang_i18n('在线商店网址')}</label>
<input type="text" class="form-control itinp url" placeholder="{:lang_i18n('请输入网址')}" /> <input type="text" name="website_url" class="form-control itinp url" placeholder="{:lang_i18n('请输入网址')}" />
</div> </div>
</div> </div>
<div class="theit"> <div class="theit">
@@ -63,13 +63,13 @@
<div class="theit"> <div class="theit">
<div class="bditem bditem1"> <div class="bditem bditem1">
<label class="itlable">{:lang_i18n('公司地址')}<span class="redtag">*</span></label> <label class="itlable">{:lang_i18n('公司地址')}<span class="redtag">*</span></label>
<input type="text" class="form-control itinp address" placeholder="{:lang_i18n('请输入地址')}"> <input type="text" name="address" class="form-control itinp address" placeholder="{:lang_i18n('请输入地址')}">
</div> </div>
</div> </div>
<div class="theit"> <div class="theit">
<div class="bditem bditem1"> <div class="bditem bditem1">
<label class="itlable">{:lang_i18n('留言')}<span class="redtag">*</span></label> <label class="itlable">{:lang_i18n('留言')}<span class="redtag">*</span></label>
<textarea class="ittextarea message" placeholder="{:lang_i18n('请输入留言')}"></textarea> <textarea name="message" class="ittextarea message" placeholder="{:lang_i18n('请输入留言')}"></textarea>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -23,14 +23,14 @@
{volist name="ch" id="item"} {volist name="ch" id="item"}
<div class="narskfit" {notempty name="item.link"}onclick="location.href='{$item.link}'"{/notempty}> <div class="narskfit" {notempty name="item.link"}onclick="location.href='{$item.link}'"{/notempty}>
<img src="{$item.image}" class="narskico-img" /> <img src="{$item.image}" class="narskico-img" />
<span class="narskf-title">{$item.title}</span> <span class="narskf-title" {:style(['color' => $item['title_txt_color']])}>{$item.title}</span>
{notempty name="item.title_short"}
<span class="narskf-sm">{$item.title_short}</span>
{/notempty}
{notempty name="item.desc"} {notempty name="item.desc"}
{if condition="str_contains($item.desc, '<img')"} <span class="narskf-sm" {:style(['color' => $item['desc_txt_color']])}>{$item.desc|raw}</span>
<div class="narskfactive-ewm" style="display: none;">{$item.desc|raw}</div> {/notempty}
{/if} {notempty name="item.extra_image"}
<div class="narskfactive-ewm" style="display: none;">
<img src="{$item.extra_image}" alt="" />
</div>
{/notempty} {/notempty}
</div> </div>
{/volist} {/volist}
@@ -41,8 +41,8 @@
<div class="narskfit narskfit2"> <div class="narskfit narskfit2">
<img src="{$item.image}" class="narskico-img"> <img src="{$item.image}" class="narskico-img">
<div class="narskfit2-ct"> <div class="narskfit2-ct">
<span class="narskf-title">{$item.title}</span> <span class="narskf-title" {:style(['color' => $item['title_txt_color']])}>{$item.title}</span>
<span class="narskf-sm">{$item.desc|raw}</span> <span class="narskf-sm" {:style(['color' => $item['desc_txt_color']])}>{$item.desc|raw}</span>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -63,7 +63,7 @@
<div class="question"> <div class="question">
<div class="title">{:lang_i18n('您的问题')} <span class="red">*</span></div> <div class="title">{:lang_i18n('您的问题')} <span class="red">*</span></div>
<div class="des"> <div class="des">
<textarea rows="6" name="message" id="message" class="ittextarea message" placeholder="{:lang_i18n('请输入内容...')}"></textarea> <textarea rows="6" name="content" id="message" class="ittextarea message" placeholder="{:lang_i18n('请输入内容...')}"></textarea>
</div> </div>
</div> </div>
<div class="question"> <div class="question">

View File

@@ -101,8 +101,8 @@
<a href="{$sc.link}"><img src="{$sc.image}" /></a> <a href="{$sc.link}"><img src="{$sc.image}" /></a>
<div class="position_a text_center wow animated bounceInLeft"> <div class="position_a text_center wow animated bounceInLeft">
<p class="f_weight_500 timetitle" {:style(['color'=>$sc['title_txt_color']])}>{$sc.title}</p> <p class="f_weight_500 timetitle" {:style(['color'=>$sc['title_txt_color']])}>{$sc.title}</p>
<p class=" margin-top-14 f_weight_100 timedesin" {:style(['color'=>$sc['desc_txt_color']])}>{$sc.desc}</p> <p class=" margin-top-14 f_weight_400 timedesin" {:style(['color'=>$sc['desc_txt_color']])}>{$sc.desc|raw}</p>
<p class=" margin-top-20 f_weight_100"> <p class=" margin-top-20 f_weight_400">
<a href="{$sc.link}" class="timeblue"> {:lang_i18n('了解更多')} <img src="__IMAGES__/more-r.png"></a> <a href="{$sc.link}" class="timeblue"> {:lang_i18n('了解更多')} <img src="__IMAGES__/more-r.png"></a>
</p> </p>
</div> </div>
@@ -141,8 +141,8 @@
<img src="{$bs.image}"> <img src="{$bs.image}">
<div class="position_a text_center"> <div class="position_a text_center">
<p class=" timetitle" {:style(['color'=>$bs['title_txt_color']])}>{$bs.title} </p> <p class=" timetitle" {:style(['color'=>$bs['title_txt_color']])}>{$bs.title} </p>
<p class=" margin-top-14 f_weight_100 timedesin" {:style(['color'=>$bs['desc_txt_color']])}>{$bs.desc}</p> <p class=" margin-top-14 f_weight_400 timedesin" {:style(['color'=>$bs['desc_txt_color']])}>{$bs.desc|raw}</p>
<p class=" margin-top-20 f_weight_100"> <p class=" margin-top-20 f_weight_400">
<span class=" timeblue"> <span class=" timeblue">
<a href="{$bs.link}">{:lang_i18n('了解更多')}<img src="__IMAGES__/more-r.png"></a> <a href="{$bs.link}">{:lang_i18n('了解更多')}<img src="__IMAGES__/more-r.png"></a>
</span> </span>
@@ -310,6 +310,16 @@
icon.removeClass('icon-jian-svg').addClass('icon-add-svg'); icon.removeClass('icon-jian-svg').addClass('icon-add-svg');
} }
}); });
// 判断年份
// 计算.timeline下的li元素数量
var liCount = $('.timeline ol li').length;
// 如果有li元素则设置a标签的宽度
if (liCount > 0) {
var widthPerItem = (100 / liCount-0.3) + '%';
$('.timeline ol li a').css('width', widthPerItem);
}
}); });
</script> </script>
{/block} {/block}

View File

@@ -9,7 +9,7 @@
<div> <div>
{volist name="focus_image" id="fi"} {volist name="focus_image" id="fi"}
<a {notempty name="fi.link" }href="{$fi.link}"{/notempty}> <a {notempty name="fi.link" }href="{$fi.link}"{/notempty}>
<img src="{$fi.image}" /> <img src="{$fi.image}" style="width: 100%;margin-top: 3.5rem;"/>
</a> </a>
{/volist} {/volist}
</div> </div>
@@ -46,7 +46,7 @@
{volist name="vo.products" id="pro" length="4"} {volist name="vo.products" id="pro" length="4"}
<li class="img-responsive"> <li class="img-responsive">
<a href="{:url('product/detail', ['id' => $pro.id])}"> <a href="{:url('product/detail', ['id' => $pro.id])}">
<img src="{$pro.cover_image}"> <img src="{:thumb($pro.cover_image)}">
<span class="title">{$pro.name}</span> <span class="title">{$pro.name}</span>
<span class="subtitle">{$pro.spu}</span> <span class="subtitle">{$pro.spu}</span>
</a> </a>

View File

@@ -22,7 +22,11 @@
<a class="href_01">{:lang_i18n('首页')}</a> <a class="href_01">{:lang_i18n('首页')}</a>
{volist name="product_categorys" id="ca"} {volist name="product_categorys" id="ca"}
<span class="icon-arrow arrow_address"></span> <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> <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} {/volist}
</div> </div>
</div> </div>
@@ -37,6 +41,13 @@
<img src="{$photo}" alt="" /> <img src="{$photo}" alt="" />
</div> </div>
{/volist} {/volist}
{if condition="!empty($product.video_img) && !empty($product.video_url) && $idx == 1"}
<div class="swiper-slide">
<video poster="{$product.video_img}" autoplay="autoplay" muted="muted" loop="loop" id="video" controls>
<source src="{$product.video_url}" type="video/mp4"/>
</video>
</div>
{/if}
</div> </div>
<!-- 如果需要分页器 --> <!-- 如果需要分页器 -->
<div class="swiper-pagination"></div> <div class="swiper-pagination"></div>
@@ -44,9 +55,9 @@
{/volist} {/volist}
</div> </div>
{/notempty} {/notempty}
<!-- 规格参数--> <!-- 规格参数 -->
<div class="m_Container"> <div class="m_Container">
<!--颜色--> <!-- 颜色/属性 -->
{notempty name="product_sku_attrs"} {notempty name="product_sku_attrs"}
<div class="slideTxtBox"> <div class="slideTxtBox">
<div class="hd clearfix"> <div class="hd clearfix">
@@ -57,7 +68,11 @@
<ul class="hd clearfix"> <ul class="hd clearfix">
{volist name="ps.attr_values" id="pv" key="pk"} {volist name="ps.attr_values" id="pv" key="pk"}
{assign name="attr_value_type" value=":rgb_or_image($pv.attr_value)" /} {assign name="attr_value_type" value=":rgb_or_image($pv.attr_value)" /}
{between name="ps.attr_id" value="1,2"}
<li class="attr_value tip1 attr_item" data-index="{$pk}"> <li class="attr_value tip1 attr_item" data-index="{$pk}">
{else/}
<li class="attr_value tip1 attr_item_defalut" data-index="{$pk}">
{/between}
{eq name="attr_value_type" value="IMAGE"} {eq name="attr_value_type" value="IMAGE"}
<span class="co-bg"><img src="{$pv.attr_value}" /></span> <span class="co-bg"><img src="{$pv.attr_value}" /></span>
{elseif condition="$attr_value_type == 'RGB'" /} {elseif condition="$attr_value_type == 'RGB'" /}
@@ -96,7 +111,9 @@
</div> </div>
{/notempty} {/notempty}
<div class="platform_buy"> <div class="platform_buy">
{eq name=":cookie('think_lang')" value="en-us"}
<a class="btn-blue-detail business-button">{:lang_i18n('发送查询')}</a> <a class="btn-blue-detail business-button">{:lang_i18n('发送查询')}</a>
{/eq}
</div> </div>
</div> </div>
<!-- 产品描述 --> <!-- 产品描述 -->
@@ -104,7 +121,7 @@
<ul class="cpa des cursor_p"> <ul class="cpa des cursor_p">
<li class="active" id="one">{:lang_i18n('产品描述')}</li> <li class="active" id="one">{:lang_i18n('产品描述')}</li>
{notempty name="product_related"} {notempty name="product_related"}
<li>{:lang_i18n('关联产品')}</li> <li onclick="javascript:location.href='#related'">{:lang_i18n('关联产品')}</li>
{/notempty} {/notempty}
<div class="clear"></div> <div class="clear"></div>
</ul> </ul>
@@ -112,13 +129,19 @@
<!-- 产品图片--> <!-- 产品图片-->
<div class="goods_des img-responsives" id="description-tab">{$product.detail|raw}</div> <div class="goods_des img-responsives" id="description-tab">{$product.detail|raw}</div>
<!-- 关联产品--> <!-- 关联产品-->
<div class="glcplist" id="related-tab" style="display: none;"> {notempty name="product_related"}
<div class="glcpitem" > <div class="glcplist" id="related">
<img src="indeximg/i560-800-1.png" src="glcpimg" /> {volist name="product_related" id="rel"}
<span class="glt1" >98系列多盘位DAS桌面阵列存储系统</span> <div class="glcpitem">
<span class="glt2">ORICO-9858RU3</span> <a href="{:url('product/detail', ['id'=>$rel.id])}">
</div> <img src="{:thumb($rel.cover_image)}" class="glcpimg" />
</div> <span class="glt1">{$rel.name}</span>
<span class="glt2">{$rel.spu}</span>
</a>
</div>
{/volist}
</div>
{/notempty}
<!-- 弹窗--> <!-- 弹窗-->
<div class="marsk-container-detail"> <div class="marsk-container-detail">
<div class="popup-quick"> <div class="popup-quick">
@@ -212,9 +235,7 @@
$('.tab-pane').hide(); $('.tab-pane').hide();
if (targetTab === 'description') { if (targetTab === 'description') {
$('#description-tab').show(); $('#description-tab').show();
$('#related-tab').hide();
} else if (targetTab === 'related') { } else if (targetTab === 'related') {
$('#related-tab').show();
$('#description-tab').hide(); $('#description-tab').hide();
} }
}); });
@@ -223,8 +244,8 @@
var index = $(this).data('index'); var index = $(this).data('index');
$('.pdetailswiper').hide(); $('.pdetailswiper').hide();
$('.pdetailswiper[data-index="' + index + '"]').show(); $('.pdetailswiper[data-index="' + index + '"]').show();
$('.attr_value').removeClass('active'); $('.attr_value').removeClass('attr_item_on');
$(this).addClass('active'); $(this).addClass('attr_item_on');
}); });
// 提交产品询价查询 // 提交产品询价查询

View File

@@ -16,8 +16,8 @@
{notempty name="products"} {notempty name="products"}
<div class="prlist"> <div class="prlist">
{volist name="products" id="pro"} {volist name="products" id="pro"}
<a class="pritem"> <a class="pritem" href="{:url('product/detail',['id'=>$pro.id])}">
<img src="{$pro.cover_image}" class="primg"/> <img src="{:thumb($pro.cover_image)}" class="primg"/>
<div class="prinfo"> <div class="prinfo">
<span class="t1">{$pro.name|raw}</span> <span class="t1">{$pro.name|raw}</span>
<span class="t2">{$pro.spu|raw}</span> <span class="t2">{$pro.spu|raw}</span>
@@ -27,6 +27,8 @@
</div> </div>
<!-- 分页 --> <!-- 分页 -->
<div>{$page|raw}</div> <div>{$page|raw}</div>
{else/}
<div style="text-align: center; padding: 10%;">{:lang_i18n('暂无数据')}</div>
{/notempty} {/notempty}
</div> </div>
</div> </div>

View File

@@ -19,6 +19,7 @@
<div class="m_Container"> <div class="m_Container">
{notempty name="categorys_data"} {notempty name="categorys_data"}
<div class="product_list"> <div class="product_list">
{if condition="in_array('products', array_keys($categorys_data[0]))"}
<ul> <ul>
{assign name="products" value=":\think\helper\Arr::flatMap(fn($pro) => $pro['products'], $categorys_data)" /} {assign name="products" value=":\think\helper\Arr::flatMap(fn($pro) => $pro['products'], $categorys_data)" /}
{volist name="products" id="pr"} {volist name="products" id="pr"}
@@ -55,6 +56,7 @@
</li> </li>
{/volist} {/volist}
</ul> </ul>
{/if}
</div> </div>
{/notempty} {/notempty}
</div> </div>

View File

@@ -11,15 +11,34 @@
<link rel="stylesheet" type="text/css" href="__CSS__/public.css" /> <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__/font.css" />
<link rel="stylesheet" type="text/css" href="__CSS__/style.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__/header.css" />
<link rel="stylesheet" type="text/css" href="__CSS__/footer.css" /> <link rel="stylesheet" type="text/css" href="__CSS__/footer.css" />
{block name="style"}{/block} {block name="style"}{/block}
<link rel="stylesheet" href="https://unpkg.com/swiper@9/swiper-bundle.min.css"> <link rel="stylesheet" href="__JS__/swiper-bundle9.4.1.min.css" />
<script type="text/javascript" src='https://code.jquery.com/jquery-3.6.0.min.js'></script> <script src="__JS__/jquery-3.6.0.min.js"></script>
<script type="text/javascript" src="https://unpkg.com/swiper@9.4.1/swiper-bundle.min.js"></script> <script type="text/javascript" src="__JS__/swiper-bundle9.4.1.min.js"></script>
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//analytics.f2b211.com/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '2']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
</head> </head>
<body> <body>
<noscript>
<!-- Matomo Image Tracker-->
<img referrerpolicy="no-referrer-when-downgrade" src="https://analytics.f2b211.com/matomo.php?idsite=2&amp;rec=1" style="border:0" alt="" />
<!-- End Matomo -->
</noscript>
{block name="header"} {block name="header"}
{include file="public/header"/} {include file="public/header"/}
{/block} {/block}
@@ -28,5 +47,31 @@
{include file="public/footer"/} {include file="public/footer"/}
{/block} {/block}
{block name="script"}{/block} {block name="script"}{/block}
<script>
$(window).ready(function () {
// 为所有站内链接,添加标识
// 使用mtpl=1参数标识解决ipad访问站点时从pc重定向到mobile每次页面都会pc - mobile闪现问题
var LURL = new URL(window.location.href);
if (LURL.searchParams.get('mtpl') == 1) {
$('a').each(function () {
var href = $(this).attr('href');
if (href) {
var origin = LURL.origin;
if (href.indexOf('http') == -1) {
href = new URL(href, origin);
href.searchParams.set('mtpl', '1');
$(this).attr('href', href);
} else {
href = new URL(href);
if (href.origin == origin) {
href.searchParams.set('mtpl', '1');
$(this).attr('href', href);
}
}
}
})
}
})
</script>
</body> </body>
</html> </html>

View File

@@ -18,7 +18,9 @@
{notempty name="fn.children"} {notempty name="fn.children"}
{volist name="fn.children" id="fnc"} {volist name="fn.children" id="fnc"}
<p> <p>
<a href="{$fnc.link}" target="_blank" class="inline-block link-faded break-all">{$fnc.name}</a> <a href="{$fnc.link}" {eq name="fnc.link" value="1"}target="_blank"{/eq} class="inline-block link-faded break-all">
{$fnc.name}
</a>
</p> </p>
{/volist} {/volist}
{/notempty} {/notempty}
@@ -27,12 +29,13 @@
{/notempty} {/notempty}
<li> <li>
<h3>{:lang_i18n('联系方式')}</h3> <h3>{:lang_i18n('联系方式')}</h3>
{notempty name="contact_config.website_email"} {if condition="!empty($contact_config)"}
<p>{$contact_config.website_email.title} {$contact_config.website_email.value}</p> {volist name="contact_config" id="vo"}
{/notempty} {if condition="$vo.type != 'image'"}
{notempty name="contact_config.website_hotline_office_hours"} <p>{$vo.value}</p>
<p>{$contact_config.website_hotline_office_hours.title} {$contact_config.website_hotline_office_hours.value}</p> {/if}
{/notempty} {/volist}
{/if}
</li> </li>
</ul> </ul>
</div> </div>
@@ -62,7 +65,7 @@
<div class="copy-text"> <div class="copy-text">
{$basic_config.website_powerby.value} {$basic_config.website_powerby.value}
{notempty name="$basic_config.website_icp"} {notempty name="$basic_config.website_icp"}
<a href="https://beian.miit.gov.cn/" style="color:white;">{$basic_config.website_icp.value}</a> <a href="https://beian.miit.gov.cn/" style="color:white;">{$basic_config.website_icp.value|raw}</a>
{/notempty} {/notempty}
</div> </div>
{/notempty} {/notempty}

View File

@@ -1,6 +1,6 @@
<header class="oircoEgapp-head"> <header class="oircoEgapp-head">
<div class="headtop"> <div class="headtop">
<a><img src="__IMAGES__/logo.png" class="headerlogimg" /></a> <a href="/"><img src="__IMAGES__/logo.png" class="headerlogimg" /></a>
<div class="action-r"> <div class="action-r">
<div class="right img-responsive cursor_p"> <div class="right img-responsive cursor_p">
<span class="icon-category cursor_p top-menu-toggle"><i class="icon-menu-svg"></i></span> <span class="icon-category cursor_p top-menu-toggle"><i class="icon-menu-svg"></i></span>
@@ -53,6 +53,7 @@
</form> </form>
<div class="title-text"> <div class="title-text">
<p><a href="#">{:lang_i18n('搜索历史')}</a></p> <p><a href="#">{:lang_i18n('搜索历史')}</a></p>
<div id="history"></div>
</div> </div>
</div> </div>
</div> </div>
@@ -107,5 +108,54 @@
$('.top-country .close-icon').click(function(){ $('.top-country .close-icon').click(function(){
$(".mask,.action-sheet").hide(); $(".mask,.action-sheet").hide();
}) })
// 移动端顶部宽度设置和主体内容宽度一致
var pageWidth = $('.oricoEGapp').outerWidth();
// 设置.header-PC元素的宽度
$('.oircoEgapp-head').css('width', pageWidth + 'px');
// 可选:监听窗口大小变化,实时更新宽度
$(window).resize(function() {
var newWidth = $('.oricoEGapp').outerWidth();
$('.oircoEgapp-head').css('width', newWidth + 'px');
});
// 回显搜索历史记录
history();
}) })
function history() {
var keywords = new URL(window.location.href).searchParams.get('keywords')
var history_keywords = localStorage.getItem('header_search_keywords');
if (!history_keywords) {
history_keywords = [];
} else {
history_keywords = JSON.parse(history_keywords);
}
// 记录搜索关键词
if (keywords) {
if (history_keywords.includes(keywords)) {
history_keywords.splice(history_keywords.indexOf(keywords), 1);
}
history_keywords.unshift(keywords);
if (history_keywords.length > 3) {
history_keywords.pop();
}
localStorage.setItem('header_search_keywords', JSON.stringify(history_keywords));
}
// 回显搜索历史
history_keywords.forEach(function(item) {
$('#history').append(
$('<a>')
.css({
'margin-right': '10px'
})
.attr('href', '{:url("product/search")}?keywords=' + item)
.text(item)
);
});
return history_keywords;
}
</script> </script>

View File

@@ -0,0 +1,126 @@
<header class="oircoEgapp-head">
<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="headerlogimg" />
</a>
<div class="action-r">
<div class="right img-responsive cursor_p">
<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">
{notempty name="header_navigation"}
{volist name="header_navigation" id="nav"}
<div class="it-ct">
<div class="it-1">
{empty name="nav.children"}
<a href="{$nav.link}">{$nav.name}</a>
{else/}
<div class="it-1-more">{$nav.name}<i class="icon-arrow"></i></div>
{volist name="nav.children" id="ch"}
<div class="it-1-2"><a href="{$ch.link}">{$ch.name}</a></div>
{/volist}
{/empty}
</div>
</div>
{/volist}
{/notempty}
</div>
</header>
<script type="text/javascript">
$(function() {
// 点击顶部菜单
$(".top-menu-toggle").click(function() {
$(".top-menu").slideToggle(800);
})
// 点击一级菜单显示二级菜单
$(".it-1-more").on("click", function() {
$('.it-1-2').hide();
$('.icon-arrow').removeClass('rotate');
$(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元素的宽度
$('.oircoEgapp-head').css('width', pageWidth + 'px');
// 可选:监听窗口大小变化,实时更新宽度
$(window).resize(function() {
var newWidth = $('.oricoEGapp').outerWidth();
$('.oircoEgapp-head').css('width', newWidth + 'px');
});
// 回显搜索历史记录
history();
})
function history() {
var keywords = new URL(window.location.href).searchParams.get('keywords')
var history_keywords = localStorage.getItem('header_search_keywords');
if (!history_keywords) {
history_keywords = [];
} else {
history_keywords = JSON.parse(history_keywords);
}
// 记录搜索关键词
if (keywords) {
if (history_keywords.includes(keywords)) {
history_keywords.splice(history_keywords.indexOf(keywords), 1);
}
history_keywords.unshift(keywords);
if (history_keywords.length > 3) {
history_keywords.pop();
}
localStorage.setItem('header_search_keywords', JSON.stringify(history_keywords));
}
// 回显搜索历史
history_keywords.forEach(function(item) {
$('#history').append(
$('<a>')
.css({
'margin-right': '10px'
})
.attr('href', '{:url("product/search")}?keywords=' + item)
.text(item)
);
});
return history_keywords;
}
</script>

View File

@@ -0,0 +1,69 @@
{extend name="public/base" /}
{block name="style"}
<link rel="stylesheet" href="__CSS__/topic_nas_cooperation.css">
{/block}
{block name="header"}
{include file="public/nas_header" /}
{/block}
{block name="main"}
<div class="oricoEGapp">
<div class="narshzhbMbpage">
<!-- banner -->
{notempty name="focus_image"}
<div class="narshzhb-banner">
<img src="{$focus_image.image}" style="margin-top: 3.7rem;">
<!-- <div class="narshzhb-banner-content">
<span class="t1">{:lang_i18n('成为ORICO合作伙伴')}</span>
<h2><strong style="color: #004BFA;">NAS</strong>{:lang_i18n('合作伙伴招募')}</h2>
<div class="narshzhb-banner-btct">
<span>{:lang_i18n('广告代理')}</span>
<span>{:lang_i18n('抖音销售')}</span>
<span>{:lang_i18n('代理经销合作')}</span>
<span>{:lang_i18n('ODM合作')}</span>
</div>
</div> -->
</div>
{/notempty}
<!-- top 介绍 -->
{notempty name="cooperation_methods"}
{volist name="cooperation_methods" id="method" key="idx"}
<div class="narshzhbmb-cttop-it {neq name='idx' value='1'}narshzhbmb-cttop-it2{/neq}">
<img src="{$method.image}">
<div class="cts" {:style(['color' => $method.desc_txt_color])}>{$method.desc|raw}</div>
{eq name="idx" value="1"}
<h2 {:style(['color' => $method.title_txt_color])}>{$method.title}</h2>
{/eq}
</div>
{/volist}
{/notempty}
{notempty name="cooperation_advantages"}
<h2 class="narshzhb-title">{:lang_i18n('合作优势')}</h2>
{assign name="cooperation_advantages_chunk" value=":array_chunk($cooperation_advantages, 2)" /}
{volist name="cooperation_advantages_chunk" id="adv"}
<div class="narshzhbmb-rowits">
{volist name="adv" id="it"}
<div class="narshzhbmb-item">
<img src="{$it.image}" class="hzhbappico">
<h3 class="hzhbapptitle" {:style(['color' => $it.title_txt_color])}>{$it.title}</h3>
<div class="srt" {:style(['color' => $it.desc_txt_color])}>{$it.desc|raw}</div>
</div>
{/volist}
</div>
{/volist}
{/notempty}
<!-- 期待与您的合作 -->
{notempty name="cooperation_cotacts"}
<h2 class="narshzhb-title">{:lang_i18n('期待与您的合作')}</h2>
{assign name="cooperation_cotacts_flat" value=":array_flatten($cooperation_cotacts)" /}
{volist name="cooperation_cotacts_flat" id="ct" key="idx"}
<div class="narshzhbmb-rowits">
<div class="narshzhbmb-item narshzhbmb-item2">
<img src="{$ct.image}" class="hzhbappico">
<span class="srt" {:style(['color'=>$ct.title_txt_color])}>{$ct.title}</span>
</div>
</div>
{/volist}
{/notempty}
</div>
</div>
{/block}

View File

@@ -0,0 +1,89 @@
{extend name="public/base" /}
{block name="style"}
<link rel="stylesheet" href="__CSS__/topic_nas_download.css" />
{/block}
{block name="header"}
{include file="public/nas_header" /}
{/block}
{block name="main"}
<div class="oricoEGapp">
<div class="narsDowloadPc">
{egt name=":count($data)" value="2"}
<div class="narsDtabs">
{notempty name="data.cyber"}
<div class="narsDtabIt narsDtabIt_active">{:lang_i18n('CyberData赛博云空间')}</div>
{/notempty}
{notempty name="data.weline"}
<div class="narsDtabIt">{:lang_i18n('Weline微链接')}</div>
{/notempty}
</div>
{/egt}
<!-- 赛博云 -->
{notempty name="data.cyber"}
<div class="nDtopCtMian narssbshow" style="display: block;">
{notempty name="data.cyber.focus_image"}
<div class="nDtopIt">
<img src="{$data.cyber.focus_image.image}" class="tpimg">
</div>
{/notempty}
{notempty name="data.cyber.down_items"}
<div class="nDtopIt2">
{volist name="data.cyber.down_items" id="it" length="4"}
<a class="nDitImg" {notempty name="it.link"}href="{$it.link}"{/notempty}>
<div class="nDitImg"><img src="{$it.image}"></div>
{eq name=":cookie('think_lang')" value="en-us"}
<div class="yy_name" {:style(['color'=>$it.title_txt_color])}>{$it.title}</div>
<div class="dwbt">Download</div>
{/eq}
</a>
{/volist}
</div>
{volist name="data.cyber.down_items" id="it" offset="4"}
<a {notempty name="it.link"}href="{$it.link}"{/notempty}>
<div class="nDitImg nrowimg" style="margin-bottom: 25px;">
<img src="{$it.image}">
</div>
</a>
{/volist}
{/notempty}
</div>
{/notempty}
<!-- 微链接 -->
{notempty name="data.weline"}
<div class="nDtopCtMian narswljshow">
{notempty name="data.weline.focus_image"}
<div class="nDtopIt">
<img src="{$data.weline.focus_image.image}" class="tpimg">
</div>
{/notempty}
{notempty name="data.weline.down_items"}
<div class="nDtopIt2" style="margin-bottom: 25px;">
{volist name="data.weline.down_items" id="it"}
<a class="nDitImg" {notempty name="it.link"}href="{$it.link}"{/notempty}>
<div class="nDitImg"><img src="{$it.image}"></div>
</a>
{/volist}
</div>
{/notempty}
</div>
{/notempty}
</div>
</div>
{/block}
{block name="script"}
<script type="text/javascript">
$(document).ready(function () {
$('.narsDtabIt').click(function () {
$('.narsDtabIt').removeClass('narsDtabIt_active');
$(this).addClass('narsDtabIt_active');
if ($(this).index() === 0) {
$('.narssbshow').show();
$('.narswljshow').hide();
} else {
$('.narssbshow').hide();
$('.narswljshow').show();
}
});
});
</script>
{/block}

View File

@@ -0,0 +1,137 @@
{extend name="public/base" /}
{block name="style"}
<link rel="stylesheet" href="__CSS__/topic_nas_help.css" />
{/block}
{block name="header"}
<!-- 重置header头为空 -->
{/block}
{block name="main"}
<div class="oricoEGapp">
<div class="narshelpCenterPc-app">
<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>
<img src="__IMAGES__/ssapp.png" class="ssicoimg">
</div>
<!-- banner -->
<img src="__IMAGES__/nhlpapp-banner.webp" class="nhlpbner">
<!-- 使用教程 -->
{notempty name="article_categorys"}
<h1 class="nhlpapp-title">{:lang_i18n('使用教程')}</h1>
{volist name="article_categorys" id="vo" key="idx"}
<div class="nhlpappit">
<div class="nhlptl">
<img src="{$vo.icon}" class="bhlpicoimg">{$vo.name}
</div>
<div class="nhlp-tx-list">
{volist name="vo.article" id="va"}
<a class="txrow" href="{:url('/index/topic/nas/help_detail', ['cid' => $vo.id,'id' => $va.id])}">
<div class="nhlp-point"></div>
<span class="nhlpsp">{$va.title}</span>
<span class="narhelpgoimg"><img src="__IMAGES__/nars-jt.png"></span>
</a>
{/volist}
{if condition="count($vo.article) >= 3"}
<a href="{:url('/index/topic/nas/help_detail', ['cid' => $vo.id, 'id' => isset($vo.article[0])?$vo.article[0]['id']:0, 'view' => 'more'])}">
<div class="ckgdbt">{:lang_i18n('查看更多')} <img src="__IMAGES__/nars-jt.png"></div>
</a>
{/if}
</div>
</div>
{/volist}
{/notempty}
<!-- 联系我们 -->
{notempty name="contacts"}
<h1 class="nhlpapp-title">{:lang_i18n('联系我们')}</h1>
<div class="nhlpapp-row">
{assign name="first_section" value=":array_splice($contacts, 0, count($contacts) - 3)"}
<div class="sec-1">
{volist name="first_section" id="co"}
<a class="nhlplxwmit" {notempty name="co.link"}href="{$co.link}"{/notempty}>
<img src="{$co.image}" class="lximg">
<span class="t1" {:style(['color'=>$co.title_txt_color])}>{$co.title}</span>
{notempty name="co.desc"}
<span class="t2" {:style(['color'=>$co.desc_txt_color])}>{$co.desc|raw}</span>
{/notempty}
</a>
{/volist}
</div>
<div class="sec-2">
{volist name="contacts" id="co"}
<a class="nhlplxwmit nhlplxwmit-w1" {notempty name="co.link"}href="{$co.link}"{/notempty}>
<img src="{$co.image}" class="lximg">
<span class="t1" {:style(['color'=>$co.title_txt_color])}>{$co.title}<br></span>
</a>
{/volist}
</div>
</div>
{/notempty}
<!-- 搜索 -->
<div class="nhlpapp-search">
<div class="nhlpappshtop">
<div class="nhlpapp-shdiv">
<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>
</div>
<div class="nhlpappline"></div>
<!-- 下拉搜索框 -->
<div class="dropdown" id="dropdown"></div>
</div>
</div>
</div>
{/block}
{block name="script"}
<script type="text/javascript">
$(document).ready(function () {
$('.closetx').click(function () {
$('.nhlpapp-search').hide();
});
$('.ssicoimg').click(function () {
$('.nhlpapp-search').show();
});
// 搜索
var timeout = null;
$('#search-input').on('focus input', function () {
clearTimeout(timeout);
var _this = this;
timeout = setTimeout(function () {
var keywords = $(_this).val();
if (keywords == '') {
$('#dropdown').hide().html('');
return;
}
$.ajax({
url: "{:url('/index/topic/nas/help_search')}",
type: 'POST',
data: { keywords: keywords },
dataType: 'JSON',
success: function (r) {
var html = '';
if (r.code == 0) {
html = '<ul>'
$.each(r.data, function (k, v) {
html += '<li><a class="search-item" href="{:url(\'/index/topic/nas/help_detail\')}?id=' + v.id + '">' + v.title + '</a></li>'
})
html += '</ul>'
}
$('#dropdown').show().html(html);
}
})
}, 300);
});
$('.nhlplxwmit:not(:first)').hover(function () {
$(this).find('.lximg').show();
}, function () {
$(this).find('.lximg').show();
});
});
</script>
{/block}

View File

@@ -0,0 +1,235 @@
{extend name="public/base" /}
{block name="title"}
{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}
{/block}
{block name="style"}
<link rel="stylesheet" href="__CSS__/topic_nas_help-detail.css" />
{/block}
{block name="header"}
<!-- 重置header头为空 -->
{/block}
{block name="main"}
<div class="oricoEGapp">
<div class="narshelpCenterdetail-app">
<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>
</div>
<!-- 文章内容 -->
<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">
<img src="__IMAGES__/ssapp.png" class="searchimg">
</div>
<span class="closetx">{:lang_i18n('取消')}</span>
</div>
<div class="nhlpappline"></div>
<!-- 下拉搜索框 -->
<div class="dropdown" id="dropdown"></div>
</div>
<!-- 分类文章目录 -->
<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}">
</div>
<span>{$ac.name}</span>
</div>
<ul class="sub-list" {if condition='$ac.id == $Request.get.cid' }style="display: block;" {/if}>
{volist name="ac.child" id="ad"}
<li class="two-mues">
<a href="#" class="two-a">
<div><img src="__IMAGES__/nars-jt.png"
class="arrow {if condition='$ad.id == $Request.get.pid'}rotate{/if}">
</div>
<span>{$ad.name}</span>
</a>
<ul class="thress-mues" {if condition='$ad.id == $Request.get.pid' }style="display: block;" {/if}>
{volist name="ad.article" id="ae"}
<li>
<a href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id ,'pid' => $ad.id, 'id' => $ae.id])}"
style="margin-left:18%;padding: 0.4rem;">{$ae.title}</a>
</li>
{/volist}
</ul>
</li>
{/volist}
{volist name="ac.article" id="ar"}
<li>
<a href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id , 'id' => $ar.id])}"
style="padding-top: 6px;">
{$ar.title}
</a>
</li>
{/volist}
</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}
{block name="script"}
<script type="text/javascript">
$(document).ready(function () {
// 点击顶部分类图标
$('#flico').click(function () {
$('.nhlpapp-pagescate').toggle();
// 检查分类菜单是否显示
if ($('.nhlpapp-pagescate').is(':visible')) {
// 如果分类菜单显示,则隐藏文章内容
$('#rendered-content').hide();
$('.footer').hide()
} else {
// 如果分类菜单隐藏,则显示文章内容
$('#rendered-content').show();
$('.footer').show()
}
});
// 点击分类的交互
$('.categoryhelp-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();
});
// 点击顶部搜索图标-点击取消关闭
$('#ssico').click(function () {
$('.nhlpapp-pagescate').hide();
$('.nhlpapp-search').show();
});
$('.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 () {
clearTimeout(timeout);
var _this = this;
timeout = setTimeout(function () {
var keywords = $(_this).val();
if (keywords == '') {
$('#dropdown').hide().html('');
return;
}
$.ajax({
url: "{:url('/index/topic/nas/help_search')}",
type: 'POST',
data: {
keywords: keywords
},
dataType: 'JSON',
success: function (r) {
var html = '';
if (r.code == 0) {
html = '<ul>'
$.each(r.data, function (k, v) {
html += '<li><a class="search-item" href="{:url(\'/index/topic/nas/help_detail\')}?id=' + v.id + '">' + v.title + '</a></li>'
})
html += '</ul>'
}
$('#dropdown').show().html(html);
}
})
}, 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

@@ -2,6 +2,9 @@
{block name="style"} {block name="style"}
<link rel="stylesheet" href="__CSS__/topic_nas_index.css"> <link rel="stylesheet" href="__CSS__/topic_nas_index.css">
{/block} {/block}
{block name="header"}
{include file="public/nas_header" /}
{/block}
{block name="main"} {block name="main"}
<div class="oricoEGapp"> <div class="oricoEGapp">
<!-- 首页 --> <!-- 首页 -->

View File

@@ -0,0 +1,61 @@
{extend name="public/base" /}
{block name="style"}
<link rel="stylesheet" type="text/css" href="__CSS__/topic_nas_product.css" />
{/block}
{block name="header"}
{include file="public/nas_header" /}
{/block}
{block name="main"}
<div class="narsZTPC">
<div class="nZTtopCtMian narssbshow">
{notempty name="focus_image"}
<a {notempty name="focus_image.link"}href="{$focus_image.link}"{/notempty}>
<img src="{$focus_image.image}" class="narsZCimg">
</a>
{/notempty}
{notempty name="step"}
<div class="narsZTicos">
{volist name="step" id="st"}
<div class="nztit">
<img src="{$st.image}" class="narsicimg">
<span class="narsstep">{$st.title}</span>
<span class="narszttext">{$st.desc|raw}</span>
</div>
{/volist}
</div>
{/notempty}
{notempty name="trial_instructions"}
<div class="narsZTinfo">
<div class="nztif-left">
{volist name="trial_instructions" id="trial" offset="0" length="2"}
<div class="narsztewmit">
<a {notempty name="trial.link"}href="{$trial.link}" target="_blank"{/notempty}>
<img src="{$trial.image}" class="nztewmimg">
</a>
<p {:style(["color"=>$trial.title_txt_color])}>{$trial.title}</p>
<span {:style(["color"=>$trial.desc_txt_color])}>{$trial.desc|raw}</span>
</div>
{/volist}
</div>
<div class="nztif-right">
{notempty name="trial_instructions.2"}
<span class="sysmtxt" {:style(["color"=>$trial_instructions.2.title_txt_color])}>
{$trial_instructions.2.title|default=''}
</span>
<div class="sminfo" {:style(["color"=>$trial_instructions.2.desc_txt_color])}>
{$trial_instructions.2.desc|raw|default=''}
</div>
{/notempty}
<div class="nztbzyj">
{volist name="trial_instructions" id="trial" offset="3"}
<a {notempty name="trial.link"}href="{$trial.link}" target="_blank"{/notempty}>
<span {:style(["color"=>$trial.title_txt_color])}>{$trial.title}</span>
</a>
{/volist}
</div>
</div>
</div>
{/notempty}
</div>
</div>
{/block}

View File

@@ -11,12 +11,13 @@
<div class="orico_Page_productxc"> <div class="orico_Page_productxc">
<!--内容 --> <!--内容 -->
<div class="productxcMain"> <div class="productxcMain">
<div class="culture_top"> {notempty name="focus_image"}
{notempty name="focus_image"} <a class="topimg" {notempty name="focus_image.link"}href="{$focus_image.link}"{/notempty}>
<a {notempty name="focus_image.link"}href="{$focus_image.link}"{/notempty}>
<img src="{$focus_image.image}"> <img src="{$focus_image.image}">
</a> </a>
{/notempty} {/notempty}
<div class="culture_top">
{notempty name="culture"} {notempty name="culture"}
<div class="culture_bril_con"> <div class="culture_bril_con">
{volist name="culture" id="cul" offset="0" length="3"} {volist name="culture" id="cul" offset="0" length="3"}

View File

@@ -1,11 +1,11 @@
{extend name="public/base" /} {extend name="public/base" /}
{block name="style"} {block name="style"}
<link rel="stylesheet" href="__CSS__/achievement.css" /> <link rel="stylesheet" href="__CSS__/aboutus_mileage.css" />
{/block} {/block}
{block name="main"} {block name="main"}
<div class="orico_Page_achievement"> <div class="orico_Page_achievement">
<div class="achievementMain"> <div class="achievementMain">
<img src="__IMAGES__/Achievement.png" class="acvImg" /> <img src="__IMAGES__/Achievement.webp" class="acvImg" />
<div class="achInfo"> <div class="achInfo">
<div class="title">{:lang_i18n('ORICO荣耀')}</div> <div class="title">{:lang_i18n('ORICO荣耀')}</div>
{notempty name="achievement"} {notempty name="achievement"}

View File

@@ -1,12 +1,12 @@
{extend name="public/base" /} {extend name="public/base" /}
{block name="style"} {block name="style"}
<link rel="stylesheet" href="__CSS__/brand.css" /> <link rel="stylesheet" href="__CSS__/aboutus_story.css" />
{/block} {/block}
{block name="main"} {block name="main"}
<div class="orico_Page_brand"> <div class="orico_Page_brand">
<!--内容 --> <!--内容 -->
<div class="brandMain"> <div class="brandMain">
<img src="__IMAGES__/OurBrand.png" class="img-responsive" /> <img src="__IMAGES__/OurBrand.webp" class="img-responsive" />
{notempty name="banners"} {notempty name="banners"}
<div class="our_brand_con"> <div class="our_brand_con">
{volist name="banners" id="ba" offset="0" length="2"} {volist name="banners" id="ba" offset="0" length="2"}

View File

@@ -15,87 +15,88 @@
{/block} {/block}
{block name="main"} {block name="main"}
<div class="orico_Page_articleDetail"> <div class="orico_Page_articleDetail">
<!-- 内容 --> <!--内容 -->
<div class="articleDetailMain"> <div class="articleDetailMain">
<div class="atmleft"> <div class="atmleft">
<div class="blog_title"> <div class="ct">
<h2>{$detail.title}</h2> <div class="blog_title">
<p>{$detail.release_time}</p> <h2>{$detail.title}</h2>
</div> <p>{$detail.release_time|date_format_i18n}</p>
<!-- 文本渲染 -->
<div class="blog_content">{$detail.content|raw}</div>
</div>
<!-- 文本渲染 -->
<div class="blog_content">{$detail.content|raw}</div>
</div>
{notempty name="comments"}
<div class="plmain">
<div class="pl">
<span class="titlepp">{:lang_i18n('评论')}</span>
{volist name="comments" id="cm"}
<div class="plit">
<span class="name">{$cm.name}:</span>
<p>{$cm.content}</p>
</div>
{/volist}
</div>
</div>
{/notempty}
</div>
<div class="atmright">
{notempty name="share_config"}
<div class="blog_share">
<h3>{:lang_i18n('分享')}</h3>
<div class="share_list">
{volist name="share_config" id="sc"}
<a class="atdit" {if condition="!empty($sc.is_blank) && $sc.is_blank.value == 1" }target="_blank" {/if} {notempty name="sc.url.value" }href="{$sc.url.value}" {/notempty}> <img src="{$sc.image.value}" />
{eq name=":array_key_exists('triggered_qrcode', $sc)" value="true"}
<div class="triggered_qrcode">
<img src="{$sc.triggered_qrcode.value}" />
</div> </div>
{/eq} <!-- 文本渲染-->
</a> <div class="ql-container">
{/volist} <div class="blog_content ql-editor">{$detail.content|raw}</div>
</div>
</div>
<!-- 评论只显示前面五条--->
{notempty name="comments"}
<div class="plmain">
<div class="pl">
<span class="titlepp">{:lang_i18n('评论')}</span>
{volist name="comments" id="cm"}
<div class="plit">
<span class="name">{$cm.name}:</span>
<p>{$cm.content}</p>
</div>
{/volist}
</div>
</div>
{/notempty}
</div>
<div class="atmright">
{notempty name="share_config"}
<div class="blog_share">
<h3>{:lang_i18n('分享')}</h3>
<div class="share_list">
{volist name="share_config" id="sc"}
<a class="atdit" {if condition="!empty($sc.is_blank) && $sc.is_blank.value == 1" }target="_blank" {/if} {notempty name="sc.url.value" }href="{$sc.url.value}" {/notempty}> <img src="{$sc.image.value}" />
{eq name=":array_key_exists('triggered_qrcode', $sc)" value="true"}
<div class="triggered_qrcode">
<img src="{$sc.triggered_qrcode.value}" />
</div>
{/eq}
</a>
{/volist}
</div>
</div>
{/notempty}
<div class="repply">
<h3>{:lang_i18n('留言')}</h3>
<form action="{:url('article/comment', ['id' => $detail.id])}" method="POST" autocomplete="off">
<span>{:lang_i18n('名称')}</span>
<input class="form-control itinp new_name" type="text" name="name" style="text-indent: 10px;">
<span>{:lang_i18n('电子邮箱')}</span>
<input class="form-control itinp new_email" type="email" name="email" style="text-indent: 10px; margin-bottom:0;">
<p style="color: #C6C7C9; font-size: 0.75rem; margin-bottom: 0.625rem;">{:lang_i18n('您的电子邮件地址不会被公开')}</p>
<span>{:lang_i18n('留言内容')}</span>
<textarea class="form-control itinp new_comment" name="content" rows="3" style="text-indent: 10px;width: 98%; margin-top: 0.625rem;margin-bottom: 0.625rem;border: 1px solid #DBDBDB;"></textarea>
<div class="comment_btn" style="color:#ffffff;">{:lang_i18n('提交留言')}</div>
</form>
</div>
</div>
</div>
{notempty name="$recommends"}
<div class="xq">
<!-- 猜您喜欢 -->
<div class="love">
<div class="love1">
<p class="tt">{:lang_i18n('你可能还喜欢')}</p>
<p><img src="__IMAGES__/1line.png" height="7"></p>
</div>
<ul class="love2">
{volist name="recommends" id="vo"}
<li>
<a href="{:url('article/detail', ['id' => $vo.id])}">
<div class="lvimg"><img src="{$vo.image}"></div>
<p class="lvtit">{$vo.title}</p>
</a>
</li>
{/volist}
<div class="clear"></div>
</ul>
</div> </div>
</div> </div>
{/notempty} {/notempty}
<div class="repply">
<h3>{:lang_i18n('留言')}</h3>
<form action="{:url('article/comment', ['id' => $detail.id])}" method="POST" autocomplete="off">
<span>{:lang_i18n('名称')}</span>
<input class="form-control itinp new_name" type="text" name="name" style="text-indent: 10px;">
<span>{:lang_i18n('电子邮箱')}</span>
<input class="form-control itinp new_email" type="email" name="email" style="text-indent: 10px; margin-bottom:0;">
<p style="color: #C6C7C9; font-size: 0.75rem; margin-bottom: 0.625rem;">{:lang_i18n('您的电子邮件地址不会被公开')}</p>
<span>{:lang_i18n('留言内容')}</span>
<textarea class="form-control itinp new_comment" name="content" rows="3" style="text-indent: 10px;width: 98%; margin-top: 0.625rem;margin-bottom: 0.625rem;border: 1px solid #DBDBDB;"></textarea>
<div class="comment_btn" style="color:#ffffff;">{:lang_i18n('提交留言')}</div>
</form>
</div>
</div>
</div>
{notempty name="$recommends"}
<div class="xq">
<!-- 猜您喜欢 -->
<div class="love">
<div class="love1">
<p class="tt">{:lang_i18n('你可能还喜欢')}</p>
<p><img src="__IMAGES__/1line.png" height="7"></p>
</div>
<ul class="love2">
{volist name="recommends" id="vo"}
<li>
<a href="{:url('article/detail', ['id' => $vo.id])}">
<div class="lvimg"><img src="{$vo.image}"></div>
<p class="lvtit">{$vo.title}</p>
</a>
</li>
{/volist}
<div class="clear"></div>
</ul>
</div>
</div>
{/notempty}
</div> </div>
{/block} {/block}
{block name="script"} {block name="script"}

View File

@@ -1,6 +1,6 @@
{extend name="public/base" /} {extend name="public/base" /}
{block name="style"} {block name="style"}
<link rel="stylesheet" type="text/css" href="__CSS__/article_category.css" /> <link rel="stylesheet" type="text/css" href="__CSS__/article_index.css" />
{/block} {/block}
{block name="main"} {block name="main"}
<div class="orico_Page_category"> <div class="orico_Page_category">
@@ -23,6 +23,7 @@
<div class="categorySearch"> <div class="categorySearch">
<form action="{:url('article/index', ['pid' => $Request.param.pid])}" method="get"> <form action="{:url('article/index', ['pid' => $Request.param.pid])}" method="get">
<i class="search_icon"></i> <i class="search_icon"></i>
<input type="hidden" name="cid" value="{$Request.param.cid}" />
<input type="text" class="search" id="article-search-in" name="keywords" value=""> <input type="text" class="search" id="article-search-in" name="keywords" value="">
</form> </form>
</div> </div>
@@ -36,13 +37,15 @@
<img src="{$ar.image}" /> <img src="{$ar.image}" />
<h3>{$ar.title}</h3> <h3>{$ar.title}</h3>
<p>{$ar.desc}</p> <p>{$ar.desc}</p>
<p>{$ar.release_time}</p> <p>{$ar.release_time|date_format_i18n}</p>
</a> </a>
</div> </div>
{/volist} {/volist}
</div> </div>
<!-- 分页--> <!-- 分页-->
<div>{$articles|raw}</div> <div>{$articles|raw}</div>
{else/}
<div style="text-align: center; padding: 10%;">暂无数据</div>
</div> </div>
{/notempty} {/notempty}
</div> </div>

View File

@@ -1,21 +1,21 @@
{extend name="public/base" /} {extend name="public/base" /}
{block name="style"} {block name="style"}
<link rel="stylesheet" href="__CSS__/download.css" /> <link rel="stylesheet" href="__CSS__/attachment_index.css" />
{/block} {/block}
{block name="main"} {block name="main"}
<div class="orico_Page_download"> <div class="orico_Page_download">
<!-- 内容 --> <!-- 内容 -->
<div class="downloadMain"> <div class="downloadMain">
<div class="topimg"> <div class="topimg">
<img src="__IMAGES__/banner_01.png" /> <img src="__IMAGES__/banner_01.webp" />
<div class="banner_title">{:lang_i18n('软件和驱动程序')}</div> <div class="banner_title">{:lang_i18n('软件和驱动程序')}</div>
</div> </div>
<div class="contact_c"> <div class="contact_c">
<!-- 搜索 --> <!-- 搜索 -->
<form action="{:url('attachment/index')}" method="get"> <form action="{:url('attachment/index')}" method="get">
<div class="search_all"> <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('搜索型号')}" /> <input type="text" name="keyword" placeholder="{:lang_i18n('搜索')}" />
<button class="searchbtn" type="submit"><img src="__IMAGES__/search_blue.png" /></button> <button class="searchbtn" type="submit"><img src="__IMAGES__/search_blue.png" /></button>
</div> </div>
</form> </form>

View File

@@ -1,20 +1,21 @@
{extend name="public/base" /} {extend name="public/base" /}
{block name="style"} {block name="style"}
<link rel="stylesheet" href="__CSS__/download.css" /> <link rel="stylesheet" href="__CSS__/attachment_index.css" />
{/block} {/block}
{block name="main"} {block name="main"}
<div class="orico_Page_download"> <div class="orico_Page_download">
<!-- 内容 --> <!-- 内容 -->
<div class="downloadMain"> <div class="downloadMain">
<div class="topimg"> <div class="topimg">
<img src="__IMAGES__/banner_01.png" /> <img src="__IMAGES__/banner_01.webp" />
<div class="banner_title">{:lang_i18n('软件和驱动程序')}</div> <div class="banner_title">{:lang_i18n('软件和驱动程序')}</div>
</div> </div>
<div class="contact_c"> <div class="contact_c">
<!-- 搜索 --> <!-- 搜索 -->
<form action="{:url('attachment/video')}" method="get"> <form action="{:url('attachment/video')}" method="get">
<div class="search_all"> <div class="search_all">
<input type="text" name="keyword" placeholder="{:lang_i18n('搜索型号')}" /> <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> <button class="searchbtn" type="submit"><img src="__IMAGES__/search_blue.png" /></button>
</div> </div>
</form> </form>

View File

@@ -46,7 +46,7 @@
</div> </div>
<div class="bditem"> <div class="bditem">
<label class="itlable">{:lang_i18n('在线商店网址')}</label> <label class="itlable">{:lang_i18n('在线商店网址')}</label>
<input type="text" class="form-control itinp" name="url" placeholder="{:lang_i18n('请输入网址')}" /> <input type="text" class="form-control itinp" name="website_url" placeholder="{:lang_i18n('请输入网址')}" />
</div> </div>
</div> </div>
<div class="theit"> <div class="theit">
@@ -61,7 +61,7 @@
</div> </div>
<div class="theit"> <div class="theit">
<div class="bditem bditem1"> <div class="bditem bditem1">
<label class="itlable">{:lang_i18n('c公司地址')}<span class="redtag">*</span></label> <label class="itlable">{:lang_i18n('公司地址')}<span class="redtag">*</span></label>
<input class="form-control itinp" name="address" placeholder="{:lang_i18n('请输入地址')}" /> <input class="form-control itinp" name="address" placeholder="{:lang_i18n('请输入地址')}" />
</div> </div>
</div> </div>

View File

@@ -23,17 +23,13 @@
{volist name="items" id="item"} {volist name="items" id="item"}
<a class="narskfit" href="{$item.link}"> <a class="narskfit" href="{$item.link}">
<img src="{$item.image}" class="narskico-img" /> <img src="{$item.image}" class="narskico-img" />
<span class="narskf-title">{$item.title}</span> <span class="narskf-title" {:style(['color' => $item['title_txt_color']])}>{$item.title}</span>
{notempty name="item.title_short"}
<span class="narskf-sm">{$item.title_short}</span>
{/notempty}
{notempty name="item.desc"} {notempty name="item.desc"}
{if condition="str_contains($item.desc, '<img')"} <span class="narskf-sm" {:style(['color' => $item['desc_txt_color']])}>{$item.desc|raw}</span>
{/notempty}
{notempty name="item.extra_image"}
<div class="narskfactive-ewm"> <div class="narskfactive-ewm">
{else/} <img src="{$item.extra_image}" alt="" />
<div class="narskf-sm narskf-font-26">
{/if}
{$item.desc|raw}
</div> </div>
{/notempty} {/notempty}
</a> </a>
@@ -43,8 +39,8 @@
<div class="narskfit narskfit2"> <div class="narskfit narskfit2">
<img src="{$item.image}" class="narskico-img" /> <img src="{$item.image}" class="narskico-img" />
<div class="narskfit2-ct"> <div class="narskfit2-ct">
<span class="narskf-title">{$item.title}</span> <span class="narskf-title" {:style(['color' => $item['title_txt_color']])}>{$item.title}</span>
<span class="narskf-sm">{$item.desc|raw}</span> <span class="narskf-sm" {:style(['color' => $item['desc_txt_color']])}>{$item.desc|raw}</span>
</div> </div>
</div> </div>
{/volist} {/volist}

View File

@@ -6,429 +6,419 @@
{/block} {/block}
{block name="main"} {block name="main"}
<div class="orico_Page_index"> <div class="orico_Page_index">
<div class="pageMain"> <div class="pageMain">
<!-- banner --> <!-- banner -->
{notempty name="focus_images"} {notempty name="focus_images"}
<div class="swiper-container bannerswiper"> <div class="swiper-container bannerswiper">
<div class="swiper-wrapper"> <div class="swiper-wrapper">
{volist name="focus_images" id="focus"} {volist name="focus_images" id="focus"}
<div class="swiper-slide"> <div class="swiper-slide">
<a href="{$focus.link}" target="_blank"><img src="{$focus.image}" alt="{$focus.title}"></a> <a href="{$focus.link}" target="_blank"><img src="{$focus.image}" alt="{$focus.title}"></a>
</div> </div>
{/volist} {/volist}
</div>
<!-- 如果需要分页器 -->
<div class="swiper-pagination"></div>
<!-- 如果需要导航按钮 -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
{/notempty}
<!-- 产品分类信息 -->
{notempty name="product_categorys"}
<div class="catMain">
{volist name="product_categorys" id="cate"}
<a class="catit" href="{$cate.link}">
<img src="{$cate.image}" class="catIcoImg" />
<span class="catName" {notempty name="cate.title_txt_color" }style="color:{$cate.title_txt_color};"
{/notempty}>{$cate.title}</span>
</a>
{/volist}
</div>
{/notempty}
<!-- 特色专题及公司实力 -->
{notempty name="featured_topics"}
<div class="featuredtopicsMain">
<div class="ftcontent">
{volist name="featured_topics" id="topic" mod="2"}
<a class="ftItme" href="{$topic.link}">
{if condition="$mod == '1'"}
<div class="ftItme_right">
<img src="{$topic.image}" />
</div>
<div class="ftItme_left">
<p>{$topic.title}</p>
<div class="subtitle">
<span>{:lang_i18n('查看所有')}</span>
<div class="tpicture"></div>
</div>
</div>
{else/}
<div class="ftItme_left">
<p>{$topic.title}</p>
<div class="subtitle">
<span>{:lang_i18n('查看所有')}</span>
<div class="tpicture"></div>
</div>
</div>
<div class="ftItme_right">
<img src="{$topic.image}" />
</div>
{/if}
</a>
{/volist}
</div>
</div>
{/notempty}
<!-- 明星产品/热点产品 -->
{notempty name="featured_products"}
<div class="featuredProducts">
<p class="biaoti">{:lang_i18n('明星产品/热点产品')}</p>
<div class="swiper fpSwiper">
<div class="swiper-wrapper">
{volist name="featured_products" id="product"}
<div class="swiper-slide picture">
<a class="primg">
<img src="{$product.cover_image}" />
</a>
<div class="fpptitle">{$product.name}</div>
<div class="subtitle">{$product.short_name}</div>
<a class="more">{:lang_i18n('了解更多')} ></a>
</div>
{/volist}
</div>
<div class="swiperasd">
<div class="swiper-container1">
<div class="slideshow-pag swiper-pagination"></div>
</div>
<div class="swiper-container swi1">
<img class="slideshow-btn swiper-button-next" src="__IMAGES__/rightcheck.png">
<img class="slideshow-btn swiper-button-prev" src="__IMAGES__/lefta.png">
</div>
</div>
</div>
</div>
{/notempty}
<!-- 视频宣传 -->
{notempty name="video"}
<div class="hotProduct">
<div class="hotvideo">
<video poster="{$video.image}"
src="{$video.video}"
style="max-height:50rem;z-index:9999;width: 100%;object-fit: cover;"
autoplay
loop
controls
id="oricoVideo"></video>
</div> </div>
<img src="{$video.image}" class="hotImg" /> <!-- 如果需要分页器 -->
<div class="swiper-pagination"></div>
<!-- 如果需要导航按钮 -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div> </div>
{/notempty} {/notempty}
<!-- 场景介绍 --> <!-- 产品分类信息 -->
{notempty name="scenes"} {notempty name="product_categorys"}
<div class="sceneIntroduction"> <div class="catMain">
{volist name="scenes" id="scene"} {volist name="product_categorys" id="cate"}
<div class="sceneitem"> <a class="catit" href="{$cate.link}">
<div class="sceneInfo"> <img src="{$cate.image}" class="catIcoImg" />
<p class="scenetitle" {notempty name="scene.title_txt_color" }style="color:{$scene.title_txt_color};" <span class="catName" {notempty name="cate.title_txt_color" }style="color:{$cate.title_txt_color};" {/notempty}>{$cate.title}</span>
{/notempty}>{$scene.title}</p> </a>
<p class="subtitle" {notempty name="scene.desc_txt_color" }style="color:{$scene.desc_txt_color};" {/notempty}> {/volist}
{$scene.desc|raw}</p> </div>
<a class="sceneMore" href="{$scene.link}">{:lang_i18n('了解更多')} ></a> {/notempty}
</div> <!-- 特色专题及公司实力 -->
<div style="background-image: url('{$scene.image}');" class="sceneimg"></div> {notempty name="featured_topics"}
</div> <div class="featuredtopicsMain">
{/volist} <div class="ftcontent">
</div> {volist name="featured_topics" id="topic" mod="2"}
{/notempty} <a class="ftItme" href="{$topic.link}">
<!-- orico科技 --> {if condition="$mod == '1'"}
<div class="oricoTechnology"> <div class="ftItme_right">
<p class="ottitle">{:lang_i18n('ORICO 技术')}</p> <img src="{$topic.image}" />
<span class="otsbtitle">{:lang_i18n('强大功能、简单使用')}</span> </div>
<div class="beforeafter ba-slider"> <div class="ftItme_left">
<!-- 对比前的图片 --> <p>{$topic.title}</p>
<img src="__IMAGES__/indeximg1.jpg"> <div class="subtitle">
<div class="resize"> <span>{:lang_i18n('查看所有')}</span>
<!-- 对比后的图片 --> <div class="tpicture"></div>
<img src="__IMAGES__/indeximg2.jpg"> </div>
</div> </div>
<!-- 可拖动的分隔条 --> {else/}
<span class="handle"></span> <div class="ftItme_left">
</div> <p>{$topic.title}</p>
</div> <div class="subtitle">
<!-- 品牌故事 --> <span>{:lang_i18n('查看所有')}</span>
{notempty name="brand_story"} <div class="tpicture"></div>
<div class="brandStory"> </div>
<div class="swiper brandStoryswiper"> </div>
<div class="swiper-wrapper"> <div class="ftItme_right">
{volist name="brand_story" id="story"} <img src="{$topic.image}" />
<div class="swiper-slide bsitem"> </div>
<div class="itmImg"> {/if}
<img src="{$story.image}" class="bsImg" /> </a>
</div> {/volist}
<div class="bsinf"> </div>
<div class="bstitle" {notempty name="story.title_txt_color" }style="color:{$story.title_txt_color};" </div>
{/notempty}>{$story.title}</div> {/notempty}
<div class="bssubtitle" {notempty name="story.desc_txt_color" }style="color:{$story.desc_txt_color};" <!-- 明星产品/热点产品 -->
{/notempty}>{$story.desc|raw}</div> {notempty name="featured_products"}
<a class="bsmore" href="{$story.link}">{:lang_i18n('了解更多')} ></a> <div class="featuredProducts">
</div> <p class="biaoti">{:lang_i18n('明星产品/热点产品')}</p>
</div> <div class="swiper fpSwiper">
{/volist} <div class="swiper-wrapper">
</div> {volist name="featured_products" id="product"}
<div class="swiperasd bs_swiperasd" id="timeline"> <div class="swiper-slide picture">
<div class="bs_swcontainer"> <a class="primg" href="{:url('product/detail', ['id' => $product.id])}">
<div class="swiper-pagination bs_pagination"></div> <img src="{$product.cover_image}" />
<hr> </a>
{volist name="brand_story" id="story" key="k"} <div class="fpptitle">{$product.name}</div>
<span class="time">{$story.year}</span> <div class="subtitle">{$product.short_name}</div>
{/volist} <a class="more" href="{:url('product/detail', ['id' => $product.id])}">{:lang_i18n('了解更多')} ></a>
</div> </div>
<div class="swiper-container bs_bts"> {/volist}
<img class="slideshow-btn swiper-button-next" src="__IMAGES__/rightcheck.png" alt="" /> </div>
<img class="slideshow-btn swiper-button-prev " src="__IMAGES__/lefta.png" alt="" /> <div class="swiperasd">
</div> <div class="swiper-container1">
</div> <div class="slideshow-pag swiper-pagination"></div>
</div> </div>
</div> <div class="swiper-container swi1">
{/notempty} <img class="slideshow-btn swiper-button-next" src="__IMAGES__/rightcheck.png">
<!-- 数据统计--> <img class="slideshow-btn swiper-button-prev" src="__IMAGES__/lefta.png">
{notempty name="data_statistics"} </div>
<div class="oricoDataStatistics"> </div>
<div class="odsmain"> </div>
{volist name="data_statistics" id="ods"} </div>
<div class="odsItem"> {/notempty}
<h1 {notempty name="ods.desc_txt_color" }style="color:{$ods.desc_txt_color};" {/notempty}>{$ods.desc|raw}</h1> <!-- 视频宣传 -->
<h3 {notempty name="ods.title_txt_color" }style="color:{$ods.title_txt_color};" {/notempty}>{$ods.title}</h3> {notempty name="video"}
</div> <div class="hotProduct">
{/volist} <div class="hotvideo">
</div> <video poster="{$video.image}" src="{$video.video}" style="max-height:50rem;z-index:9999;width: 100%;object-fit: cover;" autoplay loop controls id="oricoVideo"></video>
</div> </div>
{/notempty} <!-- <img src="{$video.image}" class="hotImg" /> -->
<!-- 文章轮播 --> </div>
{notempty name="recommend_articles"} {/notempty}
<div class="oricoPub"> <!-- 场景介绍 -->
<div class="swiper pubswiper"> {notempty name="scenes"}
<div class="swiper-wrapper"> <div class="sceneIntroduction">
{volist name="recommend_articles" id="article"} {volist name="scenes" id="scene"}
<div class="swiper-slide pubSwitem"> <div class="sceneitem">
<a class="pubimgdiv" href="{:url('article/detail', ['id' => $article.id])}"> <a class="sceneInfo" href="{$scene.link}">
<img src="{$article.image}" class="pubimg" /> <!-- <p class="scenetitle" {notempty name="scene.title_txt_color" }style="color:{$scene.title_txt_color};" {/notempty}>{$scene.title}</p>
</a> <p class="subtitle" {notempty name="scene.desc_txt_color" }style="color:{$scene.desc_txt_color};" {/notempty}>
<a class="pubinfo"> {$scene.desc|raw}</p>
<span>{$article.title|raw}</span> <a class="sceneMore" href="{$scene.link}">{:lang_i18n('了解更多')} ></a> -->
</a> <div style="background-image: url('{$scene.image}');" class="sceneimg"></div>
</div> </a>
{/volist} </div>
</div> {/volist}
<div class="swiperasd pubswiperasd"> </div>
<div class="swiper-container"> {/notempty}
<img class="slideshow-btn swiper-button-next" src="__IMAGES__/rightcheck.png"> <!-- orico科技 -->
<img class="slideshow-btn swiper-button-prev" src="__IMAGES__/lefta.png"> <div class="oricoTechnology">
</div> <p class="ottitle">{:lang_i18n('ORICO 技术')}</p>
</div> <span class="otsbtitle">{:lang_i18n('强大功能、简单使用')}</span>
</div> <div class="beforeafter ba-slider">
</div> <!-- 对比前的图片 -->
{/notempty} <img src="__IMAGES__/indeximg1.webp">
<!-- FAQ--> <div class="resize">
{notempty name="recommend_faq"} <!-- 对比后的图片 -->
<div class="oricoFQA"> <img src="__IMAGES__/indeximg2.webp">
<div class="fqaleft"> </div>
<h1 class="title">{:lang_i18n('常见问题')}</h1> <!-- 可拖动的分隔条 -->
<p class="dec">{:lang_i18n('回答您最关心的问题')}</p> <span class="handle"></span>
<p class="sudec">{:lang_i18n('客服团队的工作时间周一到周五早9点到晚6点 平均应答时间24小时内')}</p> </div>
</div> </div>
<div class="fqaright"> <!-- 品牌故事 -->
<ul class="accordion"> {notempty name="brand_story"}
{volist name="recommend_faq" id="faq"} <div class="brandStory">
<li class="fqali"> <div class="swiper brandStoryswiper">
<div class="fqa-question"> <div class="swiper-wrapper">
<h3>{$faq.question} </h3> {volist name="brand_story" id="story"}
<span class="xiala">+</span> <div class="swiper-slide bsitem">
</div> <div class="itmImg">
<div class="fqa-answer"> <img src="{$story.image}" class="bsImg" />
<p>{$faq.answer|raw}</p> </div>
</div> <div class="bsinf">
</li> <div class="bstitle" {notempty name="story.title_txt_color" }style="color:{$story.title_txt_color};" {/notempty}>{$story.title}</div>
{/volist} <div class="bssubtitle" {notempty name="story.desc_txt_color" }style="color:{$story.desc_txt_color};" {/notempty}>{$story.desc|raw}</div>
</ul> <a class="bsmore" href="{$story.link}">{:lang_i18n('了解更多')} ></a>
</div> </div>
</div> </div>
{/notempty} {/volist}
<!-- 底部固定提示 --> </div>
{eq name="Request.cookie.think_lang" value="en-us"} <div class="swiperasd bs_swiperasd" id="timeline">
<div class="oricofixd-info"> <div class="bs_swcontainer">
<div class="ofiinfo">We use cookies to ensure you get the best experience on our website. By <div class="swiper-pagination bs_pagination"></div>
continuing to browse, you agree to our use of cookies.</div> <hr>
<div class="ofibt"><button>OK,got it!</button></div> {volist name="brand_story" id="story" key="k"}
<div class="oficlose"><span class="close-btn">×</span></div> <span class="time">{$story.year}</span>
</div> {/volist}
{/eq} </div>
</div> <div class="swiper-container bs_bts">
<img class="slideshow-btn swiper-button-next" src="__IMAGES__/rightcheck.png" alt="" />
<img class="slideshow-btn swiper-button-prev " src="__IMAGES__/lefta.png" alt="" />
</div>
</div>
</div>
</div>
{/notempty}
<!-- 数据统计-->
{notempty name="data_statistics"}
<div class="oricoDataStatistics">
<div class="odsmain">
{volist name="data_statistics" id="ods"}
<div class="odsItem">
<h1 {notempty name="ods.desc_txt_color" }style="color:{$ods.desc_txt_color};" {/notempty}>{$ods.desc|raw}</h1>
<h3 {notempty name="ods.title_txt_color" }style="color:{$ods.title_txt_color};" {/notempty}>{$ods.title}</h3>
</div>
{/volist}
</div>
</div>
{/notempty}
<!-- 文章轮播 -->
{notempty name="recommend_articles"}
<div class="oricoPub">
<div class="swiper pubswiper">
<div class="swiper-wrapper">
{volist name="recommend_articles" id="article"}
<div class="swiper-slide pubSwitem">
<a class="pubimgdiv" href="{:url('article/detail', ['id' => $article.id])}">
<img src="{$article.image}" class="pubimg" />
</a>
<a class="pubinfo">
<span>{$article.title|raw}</span>
</a>
</div>
{/volist}
</div>
<div class="swiperasd pubswiperasd">
<div class="swiper-container">
<img class="slideshow-btn swiper-button-next" src="__IMAGES__/rightcheck.png">
<img class="slideshow-btn swiper-button-prev" src="__IMAGES__/lefta.png">
</div>
</div>
</div>
</div>
{/notempty}
<!-- FAQ-->
{notempty name="recommend_faq"}
<div class="oricoFQA">
<div class="fqaleft">
<h1 class="title">{:lang_i18n('常见问题')}</h1>
<p class="dec">{:lang_i18n('回答您最关心的问题')}</p>
<p class="sudec">{:lang_i18n('客服团队的工作时间周一到周五早9点到晚6点 平均应答时间24小时内')}</p>
</div>
<div class="fqaright">
<ul class="accordion">
{volist name="recommend_faq" id="faq"}
<li class="fqali">
<div class="fqa-question">
<h3>{$faq.question} </h3>
<span class="xiala">+</span>
</div>
<div class="fqa-answer">
<p>{$faq.answer|raw}</p>
</div>
</li>
{/volist}
</ul>
</div>
</div>
{/notempty}
<!-- 底部固定提示 -->
{eq name="Request.cookie.think_lang" value="en-us"}
<div class="oricofixd-info">
<div class="ofiinfo">We use cookies to ensure you get the best experience on our website. By
continuing to browse, you agree to our use of cookies.</div>
<div class="ofibt"><button>OK,got it!</button></div>
<div class="oficlose"><span class="close-btn">×</span></div>
</div>
{/eq}
</div>
</div> </div>
{/block} {/block}
{block name="script"} {block name="script"}
<script> <script>
$(document).ready(function () { $(document).ready(function () {
// 图片左右移动显示全部 // 图片左右移动显示全部
$('.ba-slider').beforeAfter({ $('.ba-slider').beforeAfter({
startPercent: 50, // 初始分隔条位置为 50% startPercent: 50, // 初始分隔条位置为 50%
handle: '.handle', // 指定分隔条元素的选择器 handle: '.handle', // 指定分隔条元素的选择器
resize: '.resize' // 指定可调整大小部分的选择器 resize: '.resize' // 指定可调整大小部分的选择器
}); });
// 底部关闭 // 底部关闭
$(".oficlose").on("click", function () { $(".oficlose").on("click", function () {
$(".oricofixd-info").hide(); $(".oricofixd-info").hide();
}); });
// 视频 // 视频
const video = $('#oricoVideo'); const video = $('#oricoVideo');
const videoContainer = $('.hotvideo'); const videoContainer = $('.hotvideo');
const img = $('.hotImg'); const img = $('.hotImg');
// 监听视频加载完成事件 // 监听视频加载完成事件
video.on('canplaythrough', function() { video.on('canplaythrough', function () {
// 显示视频容器,隐藏图片 // 显示视频容器,隐藏图片
videoContainer.css('display', 'block'); videoContainer.css('display', 'block');
img.hide(); img.hide();
console.log('视频可以流畅播放'); console.log('视频可以流畅播放');
});
// 处理视频加载失败(可选)
video.on('error', function () {
// 可在此添加失败提示,如显示错误信息或保留图片
img.show();
videoContainer.css('display', 'none');
console.log('视频加载或播放出错');
});
});
$(function () {
// banner轮播
var mySwiper = new Swiper('.bannerswiper', {
// 配置选项
loop: true,
autoplay: {
delay: 3000,
},
pagination: {
el: '.swiper-pagination',
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
});
var fpSwiper = new Swiper(".fpSwiper", {
slidesPerView: 3,
spaceBetween: 30,
slidesPerGroup: 1,
loop: true,
autoplay: {
delay: 5000,
pauseOnMouseEnter: true,
disableOnInteraction: false,
},
slidesPerView: "auto",
centeredSlides: true,
loopFillGroupWithBlank: true,
loopAdditionalSlides: 3,
pagination: {
el: ".swiper-pagination",
type: "progressbar",
},
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
});
//品牌故事轮播
var brandStoryswiper = new Swiper(".brandStoryswiper", {
pagination: {
el: ".swiper-pagination",
},
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
});
// 计算品牌故事轮播个数样式调整
function calculateDisplayValue(n) {
return 8 - n;
}
// 动态调整分页点和年份位置
function adjustTimeline() {
const slideCount = brandStoryswiper.slides.length; // 获取轮播项个数
if (slideCount === 0) return;
// 计算分页点间距
const bulletMargin = ((100 / slideCount) - 2) + "%";
$(".orico_Page_index .pageMain .brandStory .bs_swiperasd .bs_swcontainer .bs_pagination .swiper-pagination-bullet").css("margin-right", bulletMargin);
// 最后一个分页点的 margin-right 设为 0
$(".orico_Page_index .pageMain .brandStory .bs_swiperasd .bs_swcontainer .bs_pagination .swiper-pagination-bullet:last-child").css("margin-right", "0");
// 计算年份位置固定间隔21%
const timeSpans = $(".orico_Page_index .pageMain .brandStory .bs_swiperasd .bs_swcontainer .time");
var tag = 0
var percent = 0
var basenum = calculateDisplayValue(slideCount)
timeSpans.each(function (index) {
if (index == 1) {
tag = ((100 / slideCount)) * index - (index > 0 ? basenum : 0)
percent = tag
}
if (index > 1) {
percent = tag * index
}
$(this).css("left", `${percent}%`);
}); });
// 处理视频加载失败(可选) }
video.on('error', function() { // 初始化时调用
// 可在此添加失败提示,如显示错误信息或保留图片 adjustTimeline();
img.show(); // 窗口Resize时重新计算可选
videoContainer.css('display', 'none'); $(window).on("resize", adjustTimeline);
console.log('视频加载或播放出错'); // 宣传banner
var pubswiper = new Swiper(".pubswiper", {
loop: true,
autoplay: {
delay: 5000,
pauseOnMouseEnter: true,
disableOnInteraction: false,
},
//slidesPerView: 1,
slidesPerView: "auto",
centeredSlides: true,
spaceBetween: 32,
pagination: {
el: ".swiper-pagination",
click: true
},
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
});
// FAQ问答展开收起
$(".fqali").on('click', function () {
if ($(this).children("div.fqa-answer").is(':visible')) {
$(".fqali").removeClass('active');
$(".fqa-answer").hide();
$(".text-name").addClass('text-hidden');
$(".xiala").text('+');
} else {
$(".fqali").removeClass('active');
$(".fqa-answer").hide();
$(".text-name").addClass('text-hidden')
$(".xiala").text('+');
$(this).addClass('active');
$(this).children('div.fqa-answer').show();
$(this).children('div.fqa-question').find('span').text('-');
$(this).children('div.fqa-question').find('h3').removeClass('text-hidden');
}
})
// 首先隐藏视频元素和加载中的图片 要放开注释
$("#hotvideo").hide();
// 监听视频的加载事件
setTimeout(function () {
$("#hotvideo").on("load", function () {
// 视频加载完成时,显示视频元素,隐藏加载中的图片
$("#hotvideo").show();
$("#hotImg").hide();
}); });
}); }, 1000);
$(function () { // 监听视频的加载失败事件
// banner轮播 setTimeout(function () {
var mySwiper = new Swiper('.bannerswiper', { $("#hotvideo").on("error", function () {
// 配置选项 // 视频加载失败时,显示加载中的图片,隐藏视频元素
loop: true, $("#hotImg").show();
autoplay: { $("#videoElement").hide();
delay: 3000, });
}, }, 1500);
pagination: { });
el: '.swiper-pagination',
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
});
var fpSwiper = new Swiper(".fpSwiper", {
slidesPerView: 3,
spaceBetween: 30,
slidesPerGroup: 1,
loop: true,
autoplay: {
delay: 5000,
pauseOnMouseEnter: true,
disableOnInteraction: false,
},
slidesPerView: "auto",
centeredSlides: true,
loopFillGroupWithBlank: true,
loopAdditionalSlides: 3,
pagination: {
el: ".swiper-pagination",
type: "progressbar",
},
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
});
//品牌故事轮播
var brandStoryswiper = new Swiper(".brandStoryswiper", {
pagination: {
el: ".swiper-pagination",
},
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
});
// 计算品牌故事轮播个数样式调整
function calculateDisplayValue (n) {
return 8 - n;
}
// 动态调整分页点和年份位置
function adjustTimeline () {
const slideCount = brandStoryswiper.slides.length; // 获取轮播项个数
if (slideCount === 0) return;
// 计算分页点间距
const bulletMargin = ((100 / slideCount) - 2) + "%";
$(".orico_Page_index .pageMain .brandStory .bs_swiperasd .bs_swcontainer .bs_pagination .swiper-pagination-bullet").css("margin-right", bulletMargin);
// 最后一个分页点的 margin-right 设为 0
$(".orico_Page_index .pageMain .brandStory .bs_swiperasd .bs_swcontainer .bs_pagination .swiper-pagination-bullet:last-child").css("margin-right", "0");
// 计算年份位置固定间隔21%
const timeSpans = $(".orico_Page_index .pageMain .brandStory .bs_swiperasd .bs_swcontainer .time");
var tag = 0
var percent = 0
var basenum = calculateDisplayValue(slideCount)
timeSpans.each(function (index) {
if (index == 1) {
tag = ((100 / slideCount)) * index - (index > 0 ? basenum : 0)
percent = tag
}
if (index > 1) {
percent = tag * index
}
$(this).css("left", `${percent}%`);
});
}
// 初始化时调用
adjustTimeline();
// 窗口Resize时重新计算可选
$(window).on("resize", adjustTimeline);
// 宣传banner
var pubswiper = new Swiper(".pubswiper", {
loop: true,
autoplay: {
delay: 5000,
pauseOnMouseEnter: true,
disableOnInteraction: false,
},
//slidesPerView: 1,
slidesPerView: "auto",
centeredSlides: true,
spaceBetween: 32,
pagination: {
el: ".swiper-pagination",
click: true
},
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
});
// FAQ问答展开收起
$(".fqali").on('click', function () {
if ($(this).children("div.fqa-answer").is(':visible')) {
$(".fqali").removeClass('active');
$(".fqa-answer").hide();
$(".text-name").addClass('text-hidden');
$(".xiala").text('+');
} else {
$(".fqali").removeClass('active');
$(".fqa-answer").hide();
$(".text-name").addClass('text-hidden')
$(".xiala").text('+');
$(this).addClass('active');
$(this).children('div.fqa-answer').show();
$(this).children('div.fqa-question').find('span').text('-');
$(this).children('div.fqa-question').find('h3').removeClass('text-hidden');
}
})
// 首先隐藏视频元素和加载中的图片 要放开注释
$("#hotvideo").hide();
// 监听视频的加载事件
setTimeout(function () {
$("#hotvideo").on("load", function () {
// 视频加载完成时,显示视频元素,隐藏加载中的图片
$("#hotvideo").show();
$("#hotImg").hide();
});
}, 1000);
// 监听视频的加载失败事件
setTimeout(function () {
$("#hotvideo").on("error", function () {
// 视频加载失败时,显示加载中的图片,隐藏视频元素
$("#hotImg").show();
$("#videoElement").hide();
});
}, 1500);
});
</script> </script>
{/block} {/block}

View File

@@ -22,7 +22,11 @@
<a class="pathname" href="/">{:lang_i18n('首页')}</a> <a class="pathname" href="/">{:lang_i18n('首页')}</a>
{volist name="product_categorys" id="ca"} {volist name="product_categorys" id="ca"}
<div class="arrow"></div> <div class="arrow"></div>
{eq name="ca.pid" value="0"}
<a class="pathname" href="{:url('product/category', ['id' => $ca.id])}">{$ca.name}</a> <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} {/volist}
</div> </div>
<!-- 产品主图切换和参数详情--> <!-- 产品主图切换和参数详情-->
@@ -35,33 +39,26 @@
<!-- 左边切换按钮 --> <!-- 左边切换按钮 -->
<div class="scrollbutton smallImgUp disabled"></div> <div class="scrollbutton smallImgUp disabled"></div>
<!-- 小图片预览 --> <!-- 小图片预览 -->
<div id="imageMenu"> <div id="imageMenu_{$sku.id}" class="imageMenu">
<ul class="image_list"> <ul class="image_list">
{volist name="sku.photo_album" id="photo"}
<li class="onlickImg"><img src="{:thumb($photo)}" data-url="{$photo}" /></li>
{/volist}
{if condition="!empty($product.video_img) && !empty($product.video_url) && $idx == 1"} {if condition="!empty($product.video_img) && !empty($product.video_url) && $idx == 1"}
<!-- 产品视频 --> <!-- 产品视频 -->
<li id="onlickImg"><img src="{:thumb($product.video_img)}" data-url="{$product.video_url}" /></li> <li class="onlickImg"><img src="{:thumb($product.video_img)}" data-url="{$product.video_url}" /></li>
{/if} {/if}
{volist name="sku.photo_album" id="photo"}
<li id="onlickImg"><img src="{:thumb($photo)}" data-url="{$photo}" /></li>
{/volist}
</ul> </ul>
</div> </div>
<!-- 右边切换按钮 --> <!-- 右边切换按钮 -->
<div class="scrollbutton smallImgDown"></div> <div class="scrollbutton smallImgDown"></div>
</div> </div>
<!-- 产品大图 --> <!-- 产品大图 -->
<div class="bigImg" id="vertical"> <div class="bigImg" id="vertical" style="width: 75%;">
<!-- 主图 --> <!-- 主图 -->
{if condition="!empty($product.video_img) && !empty($product.video_url) && $idx == 1"}
<!-- 如果有视频情况下默认先显示视频 -->
<video poster="{$product.video_img}" autoplay="autoplay" muted="muted" loop="loop" id="video" controls style="width: 510px;height: 510px; position: relative;z-index: 998;">
<source src="{$product.video_url}" type="video/mp4"/>
</video>
{else/}
{notempty name="sku.photo_album[0]"} {notempty name="sku.photo_album[0]"}
<img src="{$sku.photo_album[0]}" id="midimg" /> <img src="{$sku.photo_album[0]}" id="midimg" />
{/notempty} {/notempty}
{/if}
</div> </div>
</div> </div>
{/volist} {/volist}
@@ -73,6 +70,11 @@
<p>{$product.short_name|default=''}</p> <p>{$product.short_name|default=''}</p>
<div class="proTfg"> <div class="proTfg">
<ul class="swt-Table"> <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"} {volist name="product_params" id="pp"}
<li class="Table-Row"> <li class="Table-Row">
<div class="ms3 Table-Cell">{$pp.name}</div> <div class="ms3 Table-Cell">{$pp.name}</div>
@@ -82,22 +84,28 @@
{/volist} {/volist}
</ul> </ul>
</div> </div>
<!-- 颜色--> <!-- 颜色/属性 -->
{volist name="product_sku_attrs" id="ps"} {volist name="product_sku_attrs" id="ps"}
<div class="prcolors"> <div class="prcolors">
<div class="dt">{$ps.attr_name}</div> <div class="dt">{$ps.attr_name}</div>
<ul class="dowebok"> <ul class="dowebok">
{volist name="ps.attr_values" id="pv" key="k"} {volist name="ps.attr_values" id="pv" key="k"}
{assign name="attr_value_type" value=":rgb_or_image($pv.attr_value)" /} {assign name="attr_value_type" value=":rgb_or_image($pv.attr_value)" /}
<a {eq name='k' value='1'}class="on"{/eq} data-sku_id="{$pv.sku_id}"> <li>
{eq name="attr_value_type" value="IMAGE"} {between name='ps.attr_id' value='1,2'}
<span class="itemcolor"><img src="{$pv.attr_value}" /></span> <a class="{eq name='k' value='1'}on{/eq}" data-sku_id="{$pv.sku_id}">
{elseif condition="$attr_value_type == 'RGB'" /}
<span class="itemcolor" {:style(['background-color'=>$pv.attr_value])}></span>
{else /} {else /}
<span>{$pv.attr_value}</span> <a class="charging {eq name='k' value='1'}on{/eq}" data-sku_id="{$pv.sku_id}">
{/eq} {/between}
</a> {eq name="attr_value_type" value="IMAGE"}
<span class="itemcolor"><img src="{$pv.attr_value}" /></span>
{elseif condition="$attr_value_type == 'RGB'" /}
<span class="itemcolor" {:style(['background-color'=>$pv.attr_value])}></span>
{else /}
<span>{$pv.attr_value}</span>
{/eq}
</a>
</li>
{/volist} {/volist}
</ul> </ul>
</div> </div>
@@ -108,7 +116,10 @@
{volist name="product_purchase_links" id="ppp" key="k"} {volist name="product_purchase_links" id="ppp" key="k"}
<a class="thebt bttype{$k}" href="{$ppp.link}">{$ppp.platform_name}</a> <a class="thebt bttype{$k}" href="{$ppp.link}">{$ppp.platform_name}</a>
{/volist} {/volist}
<br/>
{eq name=":cookie('think_lang')" value="en-us"}
<a class="thebt bttype3" id="open_form_modal">{:lang_i18n('发送查询')}</a> <a class="thebt bttype3" id="open_form_modal">{:lang_i18n('发送查询')}</a>
{/eq}
</div> </div>
</div> </div>
</div> </div>
@@ -122,8 +133,10 @@
{/notempty} {/notempty}
</div> </div>
<!-- 富文本渲染--> <!-- 富文本渲染-->
<div class="products_des" id="detail"> <div class="ql-container">
{$product.detail|default=''|raw} <div class="products_des ql-editor" id="detail">
{$product.detail|default=''|raw}
</div>
</div> </div>
</div> </div>
<!-- 关联产品 --> <!-- 关联产品 -->
@@ -217,7 +230,7 @@
<textarea name="message" id="message"></textarea> <textarea name="message" id="message"></textarea>
</div> </div>
</div> </div>
<button type="button" id="send" class="submit-btn">{:lang_i18n('提交')}</button> <button type="submit" class="submit-btn">{:lang_i18n('提交')}</button>
</form> </form>
</div> </div>
</div> </div>
@@ -237,7 +250,7 @@
// 切换图册 // 切换图册
$('.prcolors .dowebok a').click(function() { $('.prcolors .dowebok a').click(function() {
// 移除所有 .on 类 // 移除所有 .on 类
$(this).addClass('on').siblings('a').removeClass('on'); $(this).addClass('on').parent('li').siblings('li').find('a').removeClass('on');
// 获取当前点击的元素的 data-sku_id 值 // 获取当前点击的元素的 data-sku_id 值
var skuId = $(this).data('sku_id'); var skuId = $(this).data('sku_id');
// 根据 skuId 显示对应的预览 // 根据 skuId 显示对应的预览
@@ -265,21 +278,12 @@
// 处理表单提交 // 处理表单提交
modal.find("form").submit(function(e) { modal.find("form").submit(function(e) {
e.preventDefault(); e.preventDefault();
var form = $(this)
var formData = $(this).serialize(); var formData = $(this).serialize();
// 这里可以添加代码将formData发送到服务器
// 例如通过AJAX
console.log("提交的数据: " + formData);
// 提交成功后可以选择关闭模态框
modal.hide();
});
// 提交询盘
$('#send').click(function() {
var form = $(this).parents('form');
$.ajax({ $.ajax({
url: "{:url('product/inquiry')}", url: "{:url('product/inquiry')}",
type: 'POST', type: 'POST',
data: form.serialize(), data: formData,
success: function(r) { success: function(r) {
if (r.code == 0) { if (r.code == 0) {
form[0].reset(); // 重置表单 form[0].reset(); // 重置表单
@@ -289,6 +293,7 @@
}, },
error: function(e) { error: function(e) {
console.error(e); console.error(e);
modal.hide();
} }
}) })
}); });
@@ -324,8 +329,6 @@
slidesPerView: 3, slidesPerView: 3,
spaceBetween: 30, spaceBetween: 30,
slidesPerGroup: 3, slidesPerGroup: 3,
loop: true,
loopFillGroupWithBlank: true,
navigation: { navigation: {
nextEl: '.swiper-button-next', nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev', prevEl: '.swiper-button-prev',

View File

@@ -14,6 +14,7 @@
</div> </div>
</form> </form>
<!-- 搜索结果列表--> <!-- 搜索结果列表-->
{notempty name="products"}
<ul class="seul"> <ul class="seul">
{volist name="products" id="pro"} {volist name="products" id="pro"}
<a href="{:url('product/detail', ['id' => $pro['id']])}"> <a href="{:url('product/detail', ['id' => $pro['id']])}">
@@ -32,6 +33,10 @@
</a> </a>
{/volist} {/volist}
</ul> </ul>
<div>{$page|raw}</div>
{else/}
<div style="text-align: center; padding: 10%;">{:lang_i18n('暂无数据')}</div>
{/notempty}
</div> </div>
</div> </div>
{/block} {/block}

View File

@@ -1,32 +1,136 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head>
<meta charset="utf-8" /> <head>
{block name="title"}<title>{$basic_config['website_seo_title']['value']}</title>{/block} <meta charset="utf-8" />
{block name="seo"} {block name="title"}<title>{$basic_config['website_seo_title']['value']}</title>{/block}
<meta name="keywords" content="{$basic_config['website_seo_keyword']['value']}" /> {block name="seo"}
<meta name="description" content="{$basic_config['website_seo_description']['value']}" /> <meta name="keywords" content="{$basic_config['website_seo_keyword']['value']}" />
{/block} <meta name="description" content="{$basic_config['website_seo_description']['value']}" />
<meta name="viewport" content="width=device-width, initial-scale=1"> {/block}
<link rel="stylesheet" type="text/css" href="__CSS__/public.css" /> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="__CSS__/fonts.css" /> <link rel="stylesheet" type="text/css" href="__CSS__/public.css" />
<link rel="stylesheet" type="text/css" href="__CSS__/orico_header.css" /> <link rel="stylesheet" type="text/css" href="__CSS__/fonts.css" />
<link rel="stylesheet" type="text/css" href="__CSS__/orico_footer.css" /> <link rel="stylesheet" type="text/css" href="__CSS__/orico_header.css" />
{block name="style"}{/block} <link rel="stylesheet" type="text/css" href="__CSS__/orico_footer.css" />
<link rel="stylesheet" href="https://unpkg.com/swiper@9/swiper-bundle.min.css"> {block name="style"}{/block}
<script type="text/javascript" src='https://code.jquery.com/jquery-3.6.0.min.js'></script> <script>
<script type="text/javascript" src="https://unpkg.com/swiper@9.4.1/swiper-bundle.min.js"></script> // 增强型 UC 浏览器检测
<script type="text/javascript" src="__JS__/before-after.min.js"></script> function isUCBrowser() {
<script type="text/javascript" src="__JS__/large.js"></script> const ua = navigator.userAgent.toLowerCase();
</head> return ua.includes('ubrowser');
<body> }
{block name="header"}
{include file="public/header"/} // 直接输出对应的 HTML 标签
{/block} if (isUCBrowser()) {
{block name="main"}{/block} document.write(`
{block name="footer"} <link rel="stylesheet" href="__JS__/swiper-bundle8.4.7.min.css">
{include file="public/footer"/} <script type="text/javascript" src="__JS__/swiper-bundle8.4.7.min.js"><\/script>
{/block} `);
{block name="script"}{/block} } else {
</body> document.write(`
<link rel="stylesheet" href="__JS__/swiper-bundle9.4.1.min.css">
<script type="text/javascript" src="__JS__/swiper-bundle9.4.1.min.js"><\/script>
`);
}
</script>
<!-- 你的 jQuery 和其他脚本 -->
<script src="__JS__/jquery-3.6.0.min.js"></script>
<script type="text/javascript" src="__JS__/before-after.min.js"></script>
<script type="text/javascript" src="__JS__/large.js"></script>
<script type="text/javascript">
function detectDeviceByResolution() {
// 获取屏幕信息
const screenWidth = window.screen.width;
const screenHeight = window.screen.height;
const aspectRatio = screenWidth / screenHeight;
const pixelDensity = window.devicePixelRatio || 1;
// 计算物理屏幕尺寸(对角线英寸数)
// 注意:此计算依赖浏览器提供准确的 devicePixelRatio
const diagonalPixels = Math.sqrt(
Math.pow(screenWidth, 2) + Math.pow(screenHeight, 2)
);
const diagonalInches = diagonalPixels / pixelDensity / 96;
// 设备类型判断阈值
const isTabletSize = diagonalInches >= 7 && diagonalInches <= 13;
const isLaptopSize = diagonalInches > 13 && diagonalInches <= 17;
const isDesktopSize = diagonalInches > 17;
// 常见平板分辨率模式(非绝对标准)
const isTabletResolution = (
(screenWidth >= 768 && screenWidth <= 1100 && aspectRatio <= 1.7) || // 竖屏或方屏平板
(screenHeight >= 768 && screenHeight <= 1100 && aspectRatio >= 1.5) // 横屏平板
);
// 常见PC/笔记本分辨率模式
const isPcResolution = (
(screenWidth >= 1280 && aspectRatio >= 1.6) || // 宽屏笔记本/桌面
(screenWidth >= 1920) // 高分辨率桌面
);
if (isTabletSize && isTabletResolution) {
return 'tablet';
} else if (isLaptopSize && isPcResolution) {
return 'laptop';
} else if (isDesktopSize && isPcResolution) {
return 'desktop';
} else {
return 'unknown';
}
}
// $(window).ready(function () {
// const deviceType = detectDeviceByResolution();
// if (deviceType=='tablet') {
// window.location.href = '?mtpl=1';
// }
// })
$(window).ready(function () {
if ($(window).width() < 1024) {
var locationURL = new URL(window.location.href);
var mtpl = locationURL.searchParams.get("mtpl");
if (mtpl == null) {
locationURL.searchParams.set("mtpl", "1");
window.location.href = locationURL.href;
}
}
})
</script>
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//analytics.f2b211.com/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '2']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
</head>
<body>
<noscript>
<!-- Matomo Image Tracker-->
<img referrerpolicy="no-referrer-when-downgrade" src="https://analytics.f2b211.com/matomo.php?idsite=2&amp;rec=1" style="border:0" alt="" />
<!-- End Matomo -->
</noscript>
{block name="header"}
{include file="public/header"/}
{/block}
{block name="main"}{/block}
{block name="footer"}
{include file="public/footer"/}
{/block}
{block name="script"}{/block}
</body>
</html> </html>

View File

@@ -27,7 +27,9 @@
<p class="ftitle">{:lang_i18n('产品')}</p> <p class="ftitle">{:lang_i18n('产品')}</p>
<ul> <ul>
{volist name="header_categorys" id="vo"} {volist name="header_categorys" id="vo"}
<li><a href="{:url('product/category', ['id' => $vo.id])}" class="fline">{$vo.name}</a></li> {if condition="!empty($vo.name)"}
<li><a href="{:url('product/category', ['id' => $vo.id])}" class="fline">{$vo.name}</a></li>
{/if}
{/volist} {/volist}
</ul> </ul>
</div> </div>
@@ -38,7 +40,7 @@
{if condition="!empty($vo.children)"} {if condition="!empty($vo.children)"}
<ul> <ul>
{volist name="vo.children" id="vc"} {volist name="vo.children" id="vc"}
<li><a href="{$vc.link}" class="fline">{$vc.name}</a></li> <li><a href="{$vc.link}" class="fline" target="{$vc.blank==1?'_blank':'_self'}">{$vc.name}</a></li>
{/volist} {/volist}
</ul> </ul>
{/if} {/if}
@@ -51,12 +53,12 @@
<ul> <ul>
{volist name="contact_config" id="vo"} {volist name="contact_config" id="vo"}
<li> <li>
{if condition="$vo.type == 'image'"}
<img src="{$vo.value}" {if condition="!empty($vo.extra)" }style="{$vo.extra}" {/if} />
{else/}
<a href="javascript:void(0);" class="fline"> <a href="javascript:void(0);" class="fline">
{if condition="$vo.type == 'image'"}
<img src="{$vo.value}" {if condition="!empty($vo.extra)" }style="{$vo.extra}" {/if} />
{else/}
{$vo.value} {$vo.value}
{/if} {/if}
</a> </a>
</li> </li>
{/volist} {/volist}
@@ -70,7 +72,7 @@
<ul> <ul>
{volist name="media_config" id="vo"} {volist name="media_config" id="vo"}
<a href="{$vo.url.value}"> <a href="{$vo.url.value}">
<img src="{$vo.image.value}" {if condition="!empty($vo.image.extra)"}style="{$vo.image.extra}" {/if} /> <img src="{$vo.image.value}" {if condition="!empty($vo.image.extra)" }style="{$vo.image.extra}" {/if} />
</a> </a>
{/volist} {/volist}
</ul> </ul>
@@ -80,7 +82,7 @@
<div class="ftcopyright"> <div class="ftcopyright">
<span>{$basic_config.website_powerby.value}</span> <span>{$basic_config.website_powerby.value}</span>
{if condition="!empty($basic_config.website_icp)"} {if condition="!empty($basic_config.website_icp)"}
<a href="https://beian.miit.gov.cn/">{$basic_config.website_icp.value}</a> <a href="https://beian.miit.gov.cn/">{$basic_config.website_icp.value|raw}</a>
{/if} {/if}
</div> </div>
{/if} {/if}
@@ -88,4 +90,34 @@
</div> </div>
</div> </div>
</div> </div>
</footer> </footer>
<div class="backtop">
<img src="__IMAGES__/ic-backtop.png" class="ictop" />
<span>{eq name=":cookie('think_lang')" value="en-us"}TOP{else /}返回顶部{/eq}</span>
</div>
<script>
$(document).ready(function () {
// 获取窗口高度
var windowHeight = $(window).height();
// 监听滚动事件
$(window).scroll(function () {
// 检查滚动距离是否超过一屏幕高度
if ($(this).scrollTop() > windowHeight) {
// 如果超过,显示返回顶部按钮
$('.backtop').fadeIn(300);
} else {
// 如果未超过,隐藏返回顶部按钮
$('.backtop').fadeOut(300);
}
});
// 点击返回顶部按钮时的事件处理
$('.backtop').click(function () {
// 平滑滚动到页面顶部
$('html, body').animate({
scrollTop: 0
}, 800);
return false;
});
});
</script>

View File

@@ -1,203 +1,250 @@
<header class="header-PC"> <header class="header-PC">
<div id="header"> <div id="header">
<!-- LOG --> <!-- LOG -->
<div class="nav1"> <div class="nav1">
<a href="/"> <a href="/">
<img src="__IMAGES__/logo.png" /> <img src="__IMAGES__/logo.png" />
</a> </a>
</div> </div>
<!--顶部导航栏 --> <!--顶部导航栏 -->
<div class="nav2"> <div class="nav2">
<nav id="booNavigation" class="booNavigation"> <nav id="booNavigation" class="booNavigation">
<ul> <ul>
{if condition="!empty($header_categorys)"} {if condition="!empty($header_categorys)"}
<li class="navItem"> <li class="navItem">
<a href="javascript:void(0);">{:lang_i18n('产品列表')}</a> <a href="javascript:void(0);">{:lang_i18n('产品列表')}</a>
<img src="__IMAGES__/black-down.png" class="downimg" /> <img src="__IMAGES__/black-down.png" class="downimg" />
<ol class="navItemConten"> <ol class="navItemConten">
<!-- 左边子菜单--> <!-- 左边子菜单-->
<ul class="navItem_cyleft"> <ul class="navItem_cyleft">
{volist name="header_categorys" id="vo"} {volist name="header_categorys" id="vo"}
<li class="{$key == 0 ? 'it_active' : ''}"> <li class="{$key == 0 ? 'it_active' : ''}">
<a href="{:url('product/category', ['id' => $vo.id])}">{$vo.name}</a> <a href="{:url('product/category', ['id' => $vo.id])}">{$vo.name}</a>
</li> </li>
{/volist} {/volist}
</ul> </ul>
<!-- 右边子菜单--> <!-- 右边子菜单-->
{volist name="header_categorys" id="vo" key="idx"} {volist name="header_categorys" id="vo" key="idx"}
<div class="navItem_cyright" {eq name="idx" value="1" }style="display: block;"{else/}style="display: none;"{/eq}> <div class="navItem_cyright" {eq name="idx" value="1" }style="display: block;"{else/}style="display: none;"{/eq}>
{volist name="vo.children" id="vc"} {if condition="!empty($vo.children)"}
<dl class="nav_cyrightit"> {volist name="vo.children" id="vc"}
<dt> <dl class="nav_cyrightit">
<a href="{:url('product/subcategory', ['id' => $vc.id])}">{$vc.name}</a> <dt>
</dt> <a href="{:url('product/subcategory', ['id' => $vc.id])}">{$vc.name}</a>
{volist name="vc.children" id="vcc"} </dt>
<dd> {if condition="!empty($vc.children)"}
<a href="{:url('product/subcategory', ['id' => $vcc.id])}">{$vcc.name}</a> {volist name="vc.children" id="vcc"}
</dd> <dd>
{/volist} <a href="{:url('product/subcategory', ['id' => $vcc.id])}">{$vcc.name}</a>
</dl> </dd>
{/volist} {/volist}
</div> {/if}
{/volist} </dl>
</ol> {/volist}
</li> {/if}
{/if} </div>
{volist name="header_navigation" id="vo"} {/volist}
<li class="navItem"> </ol>
<a href="{$vo.link}" target="{$vo.blank==1?'_blank':'_self'}">{$vo.name}</a> </li>
{if condition="!empty($vo.children)"} {/if}
<img src="__IMAGES__/black-down.png" class="downimg" /> {volist name="header_navigation" id="vo"}
<!--下拉菜单 --> <li class="navItem">
<ol class="navItemConten1"> <a href="{$vo.link}" target="{$vo.blank==1?'_blank':'_self'}">{$vo.name}</a>
{volist name="vo.children" id="voc"} {if condition="!empty($vo.children)"}
<li> <img src="__IMAGES__/black-down.png" class="downimg" />
<a href="{$voc.link}" target="{$voc.blank==1?'_blank':'_self'}">{$voc.name}</a> <!--下拉菜单 -->
</li> <ol class="navItemConten1">
{/volist} {volist name="vo.children" id="voc"}
</ol> <li>
{/if} <a href="{$voc.link}" target="{$voc.blank==1?'_blank':'_self'}">{$voc.name}</a>
</li> </li>
{/volist} {/volist}
</ul> </ol>
</nav> {/if}
</div> </li>
<!-- 顶部搜索/国家选择/商店--> {/volist}
<div class="nav3"> </ul>
<img src="__IMAGES__/icon-search.png" id="openModalBtn" class="searchimg" /> </nav>
<div class="choesCountry"> </div>
<img src="__IMAGES__/icon-language.png" id="countrycheck" class="checkimg" /> <!-- 顶部搜索/国家选择/商店-->
<!--国家选择 --> <div class="nav3">
<div class="topCountry" id="top-country"> <img src="__IMAGES__/icon-search.png" id="openModalBtn" class="searchimg" />
<ul> <div class="choesCountry">
<li class="closec"> <img src="__IMAGES__/icon-language.png" id="countrycheck" class="checkimg" />
<span class="closecountrybt">×</span> <!--国家选择 -->
</li> <div class="topCountry" id="top-country">
{volist name="header_languages" id="vo"} <ul>
<a href="{$vo.lang_url}"> <li class="closec">
<li> <span class="closecountrybt">×</span>
<div class="cico"> </li>
<img src="{$vo.lang_icon}" class="countryimg" /> {volist name="header_languages" id="vo"}
</div> <a href="{$vo.lang_url}">
<p class="countryName">{$vo.country_en_name} - {$vo.lang_en_name}</p> <li>
</li> <div class="cico">
</a> <img src="{$vo.lang_icon}" class="countryimg" />
{/volist} </div>
</ul> <p class="countryName">{$vo.country_en_name} - {$vo.lang_en_name}</p>
</div> </li>
</div> </a>
{notempty name="basic_config['navigation_store_url']['value']"} {/volist}
<a class="storetopbt" href="{$basic_config['navigation_store_url']['value']}"> </ul>
<img src="__IMAGES__/shopico.png" class="storeImgico" />{:lang_i18n('店铺')} </div>
</a> </div>
{/notempty} {eq name=":cookie('think_lang')" value="en-us"}
</div> {notempty name="basic_config['navigation_store_url']['value']"}
</div> <a class="storetopbt" href="{$basic_config['navigation_store_url']['value']}" target="_blank">
<img src="__IMAGES__/shopico.png" class="storeImgico" />{:lang_i18n('店铺')}
</a>
{/notempty}
{/eq}
</div>
</div>
<!-- 搜索弹框--> <!-- 搜索弹框-->
<div class="searchmodalMian" id="scmodal"> <div class="searchmodalMian" id="scmodal">
<div class="searchmodalct"> <div class="searchmodalct">
<span class="close-btn">×</span> <span class="close-btn">×</span>
<input type="text" name="keywords" id="serrchinput" autocomplete="off" /> <input type="text" name="keywords" id="serrchinput" autocomplete="off" />
<!-- 历史记录 --> <!-- 历史记录 -->
<div class="searchhistory"> <div class="searchhistory">
<p class="h_title">{:lang_i18n('搜索记录')}</p> <p class="h_title">{:lang_i18n('搜索记录')}</p>
<ul></ul> <ul></ul>
</div> </div>
<div class="popProduct"> <div class="popProduct">
<p class="h_title">{:lang_i18n('热销产品')}</p> <p class="h_title">{:lang_i18n('热销产品')}</p>
<div class="popmain"> <div class="popmain">
{volist name="header_hot_products" id="vo"} {volist name="header_hot_products" id="vo"}
<div class="popitem"> <div class="popitem">
<a href="{:url('product/detail', ['id' => $vo.id])}"><img src="{$vo.cover_image}" class="popimg" /></a> <a href="{:url('product/detail', ['id' => $vo.id])}"><img src="{:thumb($vo.cover_image)}" class="popimg" /></a>
<div class="productName">{$vo.name}</div> <div class="productName">{$vo.name}</div>
<div class="produc-dec">{$vo.short_name}</div> <div class="produc-dec">{$vo.short_name}</div>
</div> </div>
{/volist} {/volist}
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</header> </header>
<script> <script>
$(document).ready(function () { $(document).ready(function () {
// 搜索历史记录处理 // 搜索历史记录处理
function history (keywords) { function history(keywords) {
var history = localStorage.getItem('header_search_keywords'); var history = localStorage.getItem('header_search_keywords');
if (!history) { if (!history) {
history = []; history = [];
} else { } else {
history = JSON.parse(history); history = JSON.parse(history);
} }
// 记录搜索关键词 // 记录搜索关键词
if (keywords) { if (keywords) {
if (history.includes(keywords)) { if (history.includes(keywords)) {
history.splice(history.indexOf(keywords), 1); history.splice(history.indexOf(keywords), 1);
} }
history.unshift(keywords); history.unshift(keywords);
if (history.length > 3) { if (history.length > 3) {
history.pop(); history.pop();
} }
localStorage.setItem('header_search_keywords', JSON.stringify(history)); localStorage.setItem('header_search_keywords', JSON.stringify(history));
return history; return history;
} }
// 回显搜索历史记录 // 回显搜索历史记录
history.forEach(function (item) { history.forEach(function (item) {
$('.searchhistory ul').append('<li><a href="{:url(\'product/search\')}?keywords=' + item + '">' + item + '</a></li>'); $('.searchhistory ul').append('<li><a href="{:url(\'product/search\')}?keywords=' + item + '">' + item + '</a></li>');
}); });
return history; return history;
} }
// 封装一个函数用于处理鼠标悬停显示和隐藏内容
function handleHover ($element, $content) {
$element.mouseenter(function () {
$content.stop(true, true).slideDown(60);
}).mouseleave(function () {
$content.stop(true, true).slideUp(60);
});
}
// 处理第一个导航项
handleHover($('.navItem').eq(0), $('.navItem').eq(0).find('.navItemConten'));
// 鼠标移入navItem_cyleft里面的li标签添加类移除其他li的类
$('.navItem_cyleft li').mouseenter(function () {
$(this).addClass('it_active').siblings().removeClass('it_active');
$('.navItem_cyright').hide();
$('.navItem_cyright').eq($(this).index()).show();
});
// 处理第5 - 8个导航项
for (let i = 4; i < 8; i++) {
handleHover($('.navItem').eq(i), $('.navItem').eq(i).find('.navItemConten1'));
}
// 点击搜索
$('#openModalBtn').click(function () {
$('#scmodal').toggle();
});
$('.close-btn').click(function () {
$('#scmodal').hide();
});
// 搜索历史记录回显
history();
// 执行搜索
$('#serrchinput').keydown(function (event) {
if (event.originalEvent.keyCode == 13) {
var keywords = $(this).val();
if (keywords == '') {
return false;
}
// 记录搜索关键词
history(keywords);
// 跳转到搜索页面 // 封装一个函数用于处理鼠标悬停显示和隐藏内容
window.location.href = "{:url('product/search')}" + '?keywords=' + keywords; function handleHover($element, $content) {
} // 同时支持鼠标悬停和点击事件
}); $element
// 点击选择国家 .mouseenter(function () {
$('#countrycheck').click(function () { $content.stop(true, true).slideDown(60);
$('#top-country').toggle(); })
}); .mouseleave(function () {
$('.closecountrybt').click(function () { $content.stop(true, true).slideUp(60);
$('#top-country').hide(); })
}); .click(function (e) {
}); // 阻止链接默认跳转(如果有链接的话)
if ($content.is(':visible')) {
$content.stop(true, true).slideUp(60);
} else {
$content.stop(true, true).slideDown(60);
}
// 防止点击事件冒泡到a标签
e.preventDefault();
e.stopPropagation();
});
}
// 处理产品列表的下拉菜单
var $firstNav = $('.navItem').eq(0);
if ($firstNav.find('.navItemConten').length) {
handleHover($firstNav, $firstNav.find('.navItemConten'));
}
// 鼠标移入左侧子菜单切换显示
$('.navItem_cyleft li').mouseenter(function () {
$(this).addClass('it_active').siblings().removeClass('it_active');
$('.navItem_cyright').hide();
$('.navItem_cyright').eq($(this).index()).show();
});
// 动态处理所有带有navItemConten1的导航项
$('.navItem').each(function () {
var $this = $(this);
var $dropdown = $this.find('.navItemConten1');
// 只给有下拉菜单的导航项绑定事件
if ($dropdown.length) {
handleHover($this, $dropdown);
}
});
// 点击搜索
$('#openModalBtn').click(function () {
$('#scmodal').toggle();
});
$('.close-btn').click(function () {
$('#scmodal').hide();
});
// 点击空白处关闭下拉菜单
$(document).click(function () {
$('.navItemConten, .navItemConten1, #top-country').slideUp(60);
});
// 防止下拉菜单内部点击触发空白处关闭事件
$('.navItemConten, .navItemConten1, #top-country').click(function (e) {
e.stopPropagation();
});
// 搜索历史记录回显
history();
// 执行搜索
$('#serrchinput').keydown(function (event) {
if (event.originalEvent.keyCode == 13) {
var keywords = $(this).val();
if (keywords == '') {
return false;
}
// 记录搜索关键词
history(keywords);
// 跳转到搜索页面
window.location.href = "{:url('product/search')}" + '?keywords=' + keywords;
}
});
// 点击选择国家
$('#countrycheck').click(function (e) {
$('#top-country').toggle();
e.stopPropagation();
});
$('.closecountrybt').click(function () {
$('#top-country').hide();
});
});
</script> </script>

View File

@@ -13,9 +13,61 @@
<link rel="stylesheet" type="text/css" href="__CSS__/topic_nas_header.css" /> <link rel="stylesheet" type="text/css" href="__CSS__/topic_nas_header.css" />
<link rel="stylesheet" type="text/css" href="__CSS__/orico_footer.css" /> <link rel="stylesheet" type="text/css" href="__CSS__/orico_footer.css" />
{block name="style"}{/block} {block name="style"}{/block}
<script type="text/javascript" src='https://code.jquery.com/jquery-3.6.0.min.js'></script> <script src="__JS__/jquery-3.6.0.min.js"></script>
<script>
// 增强型 UC 浏览器检测
function isUCBrowser() {
const ua = navigator.userAgent.toLowerCase();
return ua.includes('ubrowser');
}
// 直接输出对应的 HTML 标签
if (isUCBrowser()) {
document.write(`
<link rel="stylesheet" href="__JS__/swiper-bundle8.4.7.min.css">
<script type="text/javascript" src="__JS__/swiper-bundle8.4.7.min.js"><\/script>
`);
} else {
document.write(`
<link rel="stylesheet" href="__JS__/swiper-bundle9.4.1.min.css">
<script type="text/javascript" src="__JS__/swiper-bundle9.4.1.min.js"><\/script>
`);
}
</script>
<script>
$(window).ready(function () {
if ($(window).width() < 1024) {
var locationURL = new URL(window.location.href);
var mtpl = locationURL.searchParams.get("mtpl");
if (mtpl == null) {
locationURL.searchParams.set("mtpl", "1");
window.location.href = locationURL.href;
}
}
})
</script>
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//analytics.f2b211.com/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '2']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
</head> </head>
<body> <body>
<noscript>
<!-- Matomo Image Tracker-->
<img referrerpolicy="no-referrer-when-downgrade" src="https://analytics.f2b211.com/matomo.php?idsite=2&amp;rec=1" style="border:0" alt="" />
<!-- End Matomo -->
</noscript>
{block name="header"} {block name="header"}
{include file="public/nas_header"/} {include file="public/nas_header"/}
{/block} {/block}

View File

@@ -63,7 +63,7 @@
<div class="ftcopyright"> <div class="ftcopyright">
<span>{$basic_config.website_powerby.value}</span> <span>{$basic_config.website_powerby.value}</span>
{if condition="!empty($basic_config.website_icp)"} {if condition="!empty($basic_config.website_icp)"}
<a href="https://beian.miit.gov.cn/">{$basic_config.website_icp.value}</a> <a href="https://beian.miit.gov.cn/">{$basic_config.website_icp.value|raw}</a>
{/if} {/if}
</div> </div>
{/if} {/if}

View File

@@ -1,6 +1,10 @@
<header class="narsPage-head"> <header class="narsPage-head">
<div class="headcenter"> <div class="headcenter">
{eq name=":cookie('think_lang')" value="zh-cn"}
<a href="{:url('/index/topic/nas/index')}"> <a href="{:url('/index/topic/nas/index')}">
{else/}
<a>
{/eq}
<img class="logico" style="cursor:pointer;" src="__IMAGES__/logo_nas_{:cookie('think_lang')}.png" /> <img class="logico" style="cursor:pointer;" src="__IMAGES__/logo_nas_{:cookie('think_lang')}.png" />
</a> </a>
{notempty name="header_navigation"} {notempty name="header_navigation"}
@@ -17,9 +21,10 @@
<script type="text/javascript"> <script type="text/javascript">
$(function() { $(function() {
$('.headnav .navitem').each(function(idx, item) { $('.headnav .navitem').each(function(idx, item) {
$(item).removeClass('hover'); var _item = $(item);
if (compareUrls(location.href, item.href)) { _item.removeClass('hover');
$(item).addClass('hover').siblings(); if (_item.attr('href') && compareUrls(location.href, _item.get(0).href)) {
_item.addClass('hover').siblings();
} }
}); });

View File

@@ -8,7 +8,7 @@
<div class="narshelpCenterPc"> <div class="narshelpCenterPc">
<!-- banner-搜索 --> <!-- banner-搜索 -->
<div class="pagetopbg"> <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'> <div class='nhlp-search'>
<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__/nas_help_search.png" class="searchimg" /> <img src="__IMAGES__/nas_help_search.png" class="searchimg" />
@@ -26,13 +26,13 @@
<h1 class="helph1">{:lang_i18n('使用教程')}</h1> <h1 class="helph1">{:lang_i18n('使用教程')}</h1>
<div class="nhlp-row"> <div class="nhlp-row">
{volist name="article_categorys" id="vo" key="idx"} {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"> <div class="nhlptl">
<img src="{$vo.icon}" class="bhlpicoimg" />{$vo.name} <img src="{$vo.icon}" class="bhlpicoimg" />{$vo.name}
</div> </div>
<div class="nhlp-tx-list"> <div class="nhlp-tx-list">
{volist name="vo.article" id="va" key="index"} {volist name="vo.article" id="va" key="index"}
<a class="txrow" href="{:url('/index/topic/nas/help_detail', ['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> <div class="nhlp-point"></div>
<span class="nhlpsp">{$va.title}</span> <span class="nhlpsp">{$va.title}</span>
<span class="narhelpgoimg"> <span class="narhelpgoimg">
@@ -41,7 +41,7 @@
</a> </a>
{/volist} {/volist}
{if condition="count($vo.article) >= 3"} {if condition="count($vo.article) >= 3"}
<a class="ckgdbt" href="{:url('/index/topic/nas/help_detail', ['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('查看更多')} > {:lang_i18n('查看更多')} >
</a> </a>
{/if} {/if}
@@ -57,33 +57,37 @@
<h1 class="lxwmtitle">{:lang_i18n('联系我们')}</h1> <h1 class="lxwmtitle">{:lang_i18n('联系我们')}</h1>
<div class="nhlp-row"> <div class="nhlp-row">
<div class="nhlp-row-content"> <div class="nhlp-row-content">
{volist name="contacts" id="co" key="idx" offset="0" length="3"} {assign name="fist_section" value=":array_splice($contacts, 0, 3)" /}
<a class="nhlplxwmit nhlplxwmit-w1" {notempty name="co.link"}href="{$co.link}"{/notempty} {eq name="idx" value="3"}style="margin-right: 0;"{/eq}> {volist name="fist_section" id="co"}
<a class="nhlplxwmit nhlplxwmit-w1" {notempty name="co.link"}href="{$co.link}"{/notempty}>
<img src="{$co.image}" class="lximg" /> <img src="{$co.image}" class="lximg" />
{if condition="!empty($co.desc) && str_contains($co.desc, '<img')"} {notempty name="co.extra_image"}
<img src="{:get_path_from_img_tag($co.desc)}" class="lxewmimg" /> <img src="{$co.extra_image}" class="lxewmimg" />
<span class="t1" {:style(['color'=>$co.title_txt_color])}>{$co.title}</span> {/notempty}
{else/}
<span class="t1" {:style(['color'=>$co.title_txt_color])}>{$co.title}</span> <span class="t1" {:style(['color'=>$co.title_txt_color])}>{$co.title}</span>
{notempty name="co.desc"}
<span class="t2" {:style(['color'=>$co.desc_txt_color])}>{$co.desc|raw}</span> <span class="t2" {:style(['color'=>$co.desc_txt_color])}>{$co.desc|raw}</span>
{/if} {/notempty}
</a> </a>
{/volist} {/volist}
</div> </div>
{assign name="second_section" value=":array_chunk($contacts, 4)" /}
{volist name="second_section" id="chunk"}
<div class="nhlp-row-content"> <div class="nhlp-row-content">
{volist name="contacts" id="co" key="idx" offset="3"} {volist name="chunk" id="co"}
<a class="nhlplxwmit nhlplxwmit-w2" {notempty name="co.link"}href="{$co.link}"{/notempty} {eq name="idx%4" value="0"}style="margin-right: 0;"{/eq}> <a class="nhlplxwmit nhlplxwmit-w2" {notempty name="co.link"}href="{$co.link}"{/notempty}>
<img src="{$co.image}" class="lximg" /> <img src="{$co.image}" class="lximg" />
{if condition="!empty($co.desc) && str_contains($co.desc, '<img')"} {notempty name="co.extra_image"}
<img src="{:get_path_from_img_tag($co.desc)}" class="lxewmimg" /> <img src="{$co.extra_image}" class="lxewmimg" />
<span class="t1" {:style(['color'=>$co.title_txt_color])}>{$co.title}</span> {/notempty}
{else/}
<span class="t1" {:style(['color'=>$co.title_txt_color])}>{$co.title}</span> <span class="t1" {:style(['color'=>$co.title_txt_color])}>{$co.title}</span>
{notempty name="co.desc"}
<span class="t2" {:style(['color'=>$co.desc_txt_color])}>{$co.desc|raw}</span> <span class="t2" {:style(['color'=>$co.desc_txt_color])}>{$co.desc|raw}</span>
{/if} {/notempty}
</a> </a>
{/volist} {/volist}
</div> </div>
{/volist}
</div> </div>
</div> </div>
{/notempty} {/notempty}
@@ -132,7 +136,7 @@
$('#dropdown').hide(); $('#dropdown').hide();
} }
}); });
$('.nhlplxwmit:not(:first)').hover(function () { $('.nhlplxwmit').hover(function () {
// 当鼠标移入时,显示.lxewmimg 并隐藏.lximg // 当鼠标移入时,显示.lxewmimg 并隐藏.lximg
var lxe = $(this).find('.lxewmimg'); var lxe = $(this).find('.lxewmimg');
var lxi = $(this).find('.lximg'); var lxi = $(this).find('.lximg');

View File

@@ -1,17 +1,17 @@
{extend name="public/nas_base" /} {extend name="public/nas_base" /}
{block name="title"} {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}
{block name="seo"} {block name="seo"}
{notempty name="article.seo_keywords"} {notempty name="article.seo_keywords"}
<meta name="keywords" content="{$article.seo_keywords}" /> <meta name="keywords" content="{$article.seo_keywords}" />
<meta name="description" content="{$article.seo_desc}" /> <meta name="description" content="{$article.seo_desc}" />
{else /} {else /}
{__BLOCK__} {__BLOCK__}
{/notempty} {/notempty}
{/block} {/block}
{block name="style"} {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}
{block name="main"} {block name="main"}
<div class="orico_Page_index"> <div class="orico_Page_index">
@@ -26,30 +26,55 @@
<!-- 下拉搜索框 --> <!-- 下拉搜索框 -->
<div class="dropdown" id="dropdown"></div> <div class="dropdown" id="dropdown"></div>
</div> </div>
<!-- 目录-文章详情-锚点定位---> <!-- 目录-文章详情-锚点定位- -->
<div class="nars-help-content"> <div class="nars-help-content">
<!--目录 --> <!-- 目录 -->
<div class="nars-hlpdt-ml"> <div class="nars-hlpdt-ml">
{notempty name="article_categorys"} {notempty name="article_categorys"}
<div class="nav-tree"> <div class="nav-tree">
<!-- start 三级菜单 -->
{volist name="article_categorys" id="ac"} {volist name="article_categorys" id="ac"}
<div class="category"> <div class="category">
<!-- 一级 -->
<div class="category-title"> <div class="category-title">
<div class="arrow"><img src="__IMAGES__/nas-jt.png" class="arrow" /></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> <span>{$ac.name}</span>
</div> </div>
<ul class="sub-list"> <!-- 二级-->
{volist name="ac.article" id="ar"} <ul class="sub-list" {if condition='$ac.id == $Request.get.cid' }style="display: block;" {/if}>
<li><a href="{:url('/index/topic/nas/help_detail', ['id' => $ar.id])}" style="padding-top: 6px;">{$ar.title}</a></li> {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><a href="{:url('/index/topic/nas/help_detail', ['cid' => $ac.id,'pid' => $ad.id, 'id' => $ae.id])}" style="padding-top: 6px;padding-left: 30px;" {eq
name="ae.id" value="$Request.get.id" }class="active" {/eq}>{$ae.title}</a></li>
{/volist}
</ul>
<!-- 三级-->
</li>
{/volist} {/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> </ul>
</div> </div>
{/volist} {/volist}
<!-- end 三级菜单 -->
</div> </div>
{/notempty} {/notempty}
</div> </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 class="nars-hlpdt-mr">
<div id="title-list"> <div id="title-list">
@@ -64,10 +89,22 @@
{block name="script"} {block name="script"}
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function () { $(document).ready(function () {
// 一级菜单点击事件
$('.category-title').click(function () { $('.category-title').click(function () {
$(this).next('.sub-list').slideToggle(); $(this).next('.sub-list').slideToggle();
$(this).find('.arrow').toggleClass('rotate'); $(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) { $(document).on('click', function (e) {
var target = $(e.target); var target = $(e.target);
@@ -98,7 +135,7 @@
html = '<ul>' html = '<ul>'
$.each(r.data, function (k, v) { $.each(r.data, function (k, v) {
html += html +=
'<li><a href="{:url(\'/index/topic/nas/help_detail\')}?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>' html += '</ul>'
} }
@@ -110,21 +147,27 @@
// 内容 // 内容
// 清空标题列表 // 清空标题列表
$("#title-list ul").empty(); $("#title-list ul").empty();
// 提取 h1 标题 // 提取 h3 标题
var h1Titles = $("#rendered-content").find("h3"); var h1Titles = $("#rendered-content").find("h3");
h1Titles.each(function (index) { // 只有当找到h3标题且内容不为空时才进行处理
var title = $(this); if (h1Titles.length > 0) {
var titleText = title.text(); h1Titles.each(function (index) {
var titleId = "title-" + index; var title = $(this);
title.attr("id", titleId); var titleText = title.text().trim(); // 使用trim()去除空白字符
var listItem = $("<li>"); // 只有当标题文本不为空时才添加到列表
var link = $("<a>", { if (titleText) {
href: "#" + titleId, var titleId = "title-" + index;
text: titleText 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> </script>
{/block} {/block}

View File

@@ -113,7 +113,7 @@
</div> </div>
{/block} {/block}
{block name="script"} {block name="script"}
<script type="text/javascript" src="https://unpkg.com/swiper@9.4.1/swiper-bundle.min.js"></script> <!-- <script type="text/javascript" src="https://unpkg.com/swiper@9.4.1/swiper-bundle.min.js"></script> -->
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function () { $(document).ready(function () {
// banner轮播 // banner轮播

View File

@@ -18,7 +18,7 @@ if (!function_exists('image_domain_concat')) {
return $path; 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 $path;
} }
return rtrim($domain, '/') . '/' . ltrim($path, '/'); return url_join($domain, $path);
} }
} }

View File

@@ -15,8 +15,8 @@ class Article
$params = request()->get([ $params = request()->get([
'category_id', 'category_id',
'language' => 'zh-cn', 'language' => 'zh-cn',
'page/d' => 1, 'page/d' => 1,
'size/d' => 50 'size/d' => 50
]); ]);
if ($params['size'] > 200) { if ($params['size'] > 200) {
@@ -66,6 +66,8 @@ class Article
]) ])
->withoutField([ ->withoutField([
'language_id', 'language_id',
'author',
'source',
'seo_title', 'seo_title',
'seo_keywords', 'seo_keywords',
'seo_desc', 'seo_desc',

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