增加产品模块

This commit is contained in:
李志强 2026-03-20 19:48:32 +08:00
parent 14c305f518
commit b3a25ceb82
17 changed files with 916 additions and 469 deletions

View File

@ -0,0 +1,188 @@
<?php
declare(strict_types=1);
namespace app\admin\controller\Cms\Products;
use app\admin\BaseController;
use think\response\Json;
use app\model\Cms\Products;
use think\exception\ValidateException;
/**
* 特色产品管理控制器
*/
class ProductsController extends BaseController
{
/**
* 获取特色产品列表
* @return Json
*/
public function productsList(): Json
{
try {
$page = (int)$this->request->param('page', 1);
$limit = (int)$this->request->param('limit', 10);
$keyword = $this->request->param('keyword', '');
$query = Products::where('delete_time', null)
->where('tid', $this->getTenantId());
// 关键词搜索
if (!empty($keyword)) {
$query->where('title', 'like', '%' . $keyword . '%');
}
$total = $query->count();
$list = $query->order('sort', 'asc')
->order('id', 'desc')
->page($page, $limit)
->select()
->toArray();
return json([
'code' => 200,
'msg' => 'success',
'data' => [
'list' => $list,
'total' => $total
]
]);
} catch (\Exception $e) {
return json([
'code' => 500,
'msg' => '获取失败:' . $e->getMessage(),
'data' => []
]);
}
}
/**
* 添加特色产品
* @return Json
*/
public function addProducts(): Json
{
try {
$data = $this->request->param();
$product = new Products();
$product->tid = $this->getTenantId();
$product->title = $data['title'];
$product->url = $data['url'];
$product->thumb = $data['thumb'] ?? '';
$product->desc = $data['desc'] ?? '';
$product->content = $data['content'] ?? '';
$product->sort = $data['sort'] ?? 0;
$product->create_time = date('Y-m-d H:i:s');
$product->save();
$this->logSuccess('特色产品', '添加产品', ['id' => $product->id]);
return json([
'code' => 200,
'msg' => '添加成功',
'data' => $product->toArray()
]);
} catch (ValidateException $e) {
return json([
'code' => 400,
'msg' => $e->getError()
]);
} catch (\Exception $e) {
$this->logFail('特色产品', '添加产品', $e->getMessage());
return json([
'code' => 500,
'msg' => '添加失败:' . $e->getMessage()
]);
}
}
/**
* 更新特色产品
* @param int $id
* @return Json
*/
public function editProducts(int $id): Json
{
try {
$data = $this->request->param();
$product = Products::where('id', $id)
->where('tid', $this->getTenantId())
->where('delete_time', null)
->find();
if (!$product) {
return json([
'code' => 404,
'msg' => '产品不存在'
]);
}
if (isset($data['title'])) $product->title = $data['title'];
if (isset($data['url'])) $product->url = $data['url'];
if (isset($data['thumb'])) $product->thumb = $data['thumb'];
if (isset($data['desc'])) $product->desc = $data['desc'];
if (isset($data['sort'])) $product->sort = $data['sort'];
$product->update_time = date('Y-m-d H:i:s');
$product->save();
$this->logSuccess('特色产品', '更新产品', ['id' => $id]);
return json([
'code' => 200,
'msg' => '更新成功',
'data' => $product->toArray()
]);
} catch (ValidateException $e) {
return json([
'code' => 400,
'msg' => $e->getError()
]);
} catch (\Exception $e) {
$this->logFail('特色产品', '更新产品', $e->getMessage());
return json([
'code' => 500,
'msg' => '更新失败:' . $e->getMessage()
]);
}
}
/**
* 删除特色产品
* @param int $id
* @return Json
*/
public function deleteProducts(int $id): Json
{
try {
$product = Products::where('id', $id)
->where('tid', $this->getTenantId())
->where('delete_time', null)
->find();
if (!$product) {
return json([
'code' => 404,
'msg' => '产品不存在'
]);
}
$product->delete();
$this->logSuccess('特色产品', '删除产品', ['id' => $id]);
return json([
'code' => 200,
'msg' => '删除成功'
]);
} catch (\Exception $e) {
$this->logFail('特色产品', '删除产品', $e->getMessage());
return json([
'code' => 500,
'msg' => '删除失败:' . $e->getMessage()
]);
}
}
}

View File

@ -18,13 +18,12 @@ class ServicesController extends BaseController
* 获取特色服务列表
* @return Json
*/
public function getList(): Json
public function servicesList(): Json
{
try {
$page = (int)$this->request->param('page', 1);
$limit = (int)$this->request->param('limit', 10);
$keyword = $this->request->param('keyword', '');
$status = $this->request->param('status', '');
$query = Services::where('delete_time', null)
->where('tid', $this->getTenantId());
@ -34,11 +33,6 @@ class ServicesController extends BaseController
$query->where('name', 'like', '%' . $keyword . '%');
}
// 状态筛选
if ($status !== '') {
$query->where('status', (int)$status);
}
$total = $query->count();
$list = $query->order('sort', 'asc')
->order('id', 'desc')
@ -67,19 +61,11 @@ class ServicesController extends BaseController
* 添加特色服务
* @return Json
*/
public function add(): Json
public function addServices(): Json
{
try {
$data = $this->request->param();
// 验证参数
$this->validate($data, [
'name|服务名称' => 'require|max:100',
'url|服务地址' => 'require|url|max:255',
'sort|排序' => 'integer',
'status|状态' => 'in:0,1'
]);
$service = new Services();
$service->tid = $this->getTenantId();
$service->title = $data['title'];
@ -87,7 +73,6 @@ class ServicesController extends BaseController
$service->thumb = $data['thumb'] ?? '';
$service->desc = $data['desc'] ?? '';
$service->sort = $data['sort'] ?? 0;
$service->status = $data['status'] ?? 1;
$service->create_time = date('Y-m-d H:i:s');
$service->save();
@ -117,7 +102,7 @@ class ServicesController extends BaseController
* @param int $id
* @return Json
*/
public function update(int $id): Json
public function editServices(int $id): Json
{
try {
$data = $this->request->param();
@ -134,24 +119,11 @@ class ServicesController extends BaseController
]);
}
// 验证参数
if (isset($data['name'])) {
$this->validate($data, [
'name|服务名称' => 'require|max:100'
]);
}
if (isset($data['url'])) {
$this->validate($data, [
'url|服务地址' => 'require|url|max:255'
]);
}
if (isset($data['title'])) $service->title = $data['title'];
if (isset($data['url'])) $service->url = $data['url'];
if (isset($data['thumb'])) $service->thumb = $data['thumb'];
if (isset($data['desc'])) $service->desc = $data['desc'];
if (isset($data['sort'])) $service->sort = $data['sort'];
if (isset($data['status'])) $service->status = $data['status'];
$service->update_time = date('Y-m-d H:i:s');
$service->save();
@ -181,7 +153,7 @@ class ServicesController extends BaseController
* @param int $id
* @return Json
*/
public function delete(int $id): Json
public function deleteServices(int $id): Json
{
try {
$service = Services::where('id', $id)
@ -213,39 +185,4 @@ class ServicesController extends BaseController
}
}
/**
* 批量删除特色服务
* @return Json
*/
public function batchDelete(): Json
{
try {
$ids = $this->request->param('ids', []);
if (empty($ids)) {
return json([
'code' => 400,
'msg' => '请选择要删除的服务'
]);
}
Services::whereIn('id', $ids)
->where('tid', $this->getTenantId())
->where('delete_time', null)
->update(['delete_time' => date('Y-m-d H:i:s')]);
$this->logSuccess('特色服务', '批量删除服务', ['ids' => $ids]);
return json([
'code' => 200,
'msg' => '批量删除成功'
]);
} catch (\Exception $e) {
$this->logFail('特色服务', '批量删除服务', $e->getMessage());
return json([
'code' => 500,
'msg' => '批量删除失败:' . $e->getMessage()
]);
}
}
}

View File

@ -0,0 +1,8 @@
<?php
use think\facade\Route;
// 特色产品路由
Route::get('productsList', 'app\admin\controller\Cms\Products\ProductsController@productsList');
Route::post('addProducts', 'app\admin\controller\Cms\Products\ProductsController@addProducts');
Route::put('editProducts/:id', 'app\admin\controller\Cms\Products\ProductsController@editProducts');
Route::delete('deleteProducts/:id', 'app\admin\controller\Cms\Products\ProductsController@deleteProducts');

View File

@ -2,7 +2,7 @@
use think\facade\Route;
// 特色服务路由
Route::get('services', 'app\admin\controller\Cms\Services\ServicesController@getList');
Route::post('services', 'app\admin\controller\Cms\Services\ServicesController@add');
Route::put('services/:id', 'app\admin\controller\Cms\Services\ServicesController@update');
Route::delete('services/:id', 'app\admin\controller\Cms\Services\ServicesController@delete');
Route::get('servicesList', 'app\admin\controller\Cms\Services\ServicesController@servicesList');
Route::post('addServices', 'app\admin\controller\Cms\Services\ServicesController@addServices');
Route::put('editServices/:id', 'app\admin\controller\Cms\Services\ServicesController@editServices');
Route::delete('deleteServices/:id', 'app\admin\controller\Cms\Services\ServicesController@deleteServices');

View File

@ -15,6 +15,8 @@ use think\facade\Env;
use think\facade\Request;
use app\model\Cms\TemplateSiteConfig;
use app\model\Cms\Friendlink;
use app\model\Cms\Services;
use app\model\Cms\Products;
use app\model\Tenant\Tenant;
class Index extends BaseController
@ -452,7 +454,7 @@ class Index extends BaseController
}
try {
// 1. 通过域名获取租户ID
// 通过域名获取租户ID
$tid = BaseController::getTenantIdByDomain($baseUrl);
if (empty($tid)) {
@ -463,12 +465,28 @@ class Index extends BaseController
]);
}
// 2. 获取站点基础信息 (normalinfos)
// 获取站点基础信息 (normalinfos)
$normalInfos = SystemSiteSetting::where('tid', $tid)
->field('sitename,logo,logow,ico,description,copyright,companyname,icp,companyintroduction')
->find();
// 3. 获取友情链接列表
// 获取特色服务列表
$servicesList = Services::where('delete_time', null)
->where('tid', $tid)
->order('sort', 'asc')
->field('id,title,desc,thumb,url')
->select()
->toArray();
// 获取企业产品列表
$productsList = Products::where('delete_time', null)
->where('tid', $tid)
->order('sort', 'asc')
->field('id,title,desc,content,thumb,url')
->select()
->toArray();
// 获取友情链接列表
$friendlinkList = Friendlink::where('delete_time', null)
->where('tid', $tid)
->where('status', 1)
@ -484,17 +502,18 @@ class Index extends BaseController
->field('contact_phone,contact_email,address,worktime')
->find();
// 4. 合并返回
// 合并返回
return json([
'code' => 200,
'msg' => 'success',
'data' => [
'normal' => $normalInfos ?: (object) [],
'normal' => $normalInfos ?: (object) [],
'contact' => $contact ?: (object) [],
'services' => $servicesList,
'products' => $productsList,
'links' => $friendlinkList
]
]);
} catch (\Exception $e) {
return json([
'code' => 500,

View File

@ -13,6 +13,9 @@ Route::get(':page', 'app\index\controller\Index@page')
// --- 模板初始化接口 ---
Route::get('init', 'app\index\controller\Index@init');
// --- Banner 路由 ---
Route::get('getBanners', 'app\index\controller\BannerController@getBanners');
// --- 前端其他数据路由 ---
Route::get('footerdata', 'app\index\controller\Index@getFooterData');
Route::get('companyInfos', 'app\index\controller\Index@getCompanyInfos');
@ -21,13 +24,12 @@ Route::get('homeData', 'app\index\controller\Index@getHomeData');
// --- 客户需求路由 ---
// --- 文章列表路由 ---
// --- 新闻中心列表路由 ---
Route::get('getCenterNews', 'app\index\controller\Article\NewsCenterController@getCenterNews');
// --- Banner 路由 ---
Route::get('getBanners', 'app\index\controller\BannerController@getBanners');
// --- 文章互动路由 ---
// --- 新闻中心互动路由 ---
Route::post('articleViews/:id', 'app\index\controller\Article\ArticleController@articleViews');
Route::post('articleLikes/:id', 'app\index\controller\Article\ArticleController@articleLikes');
Route::post('articleUnlikes/:id', 'app\index\controller\Article\ArticleController@articleUnlikes');

View File

@ -0,0 +1,44 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: Liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace app\model\Cms;
use think\Model;
use think\model\concern\SoftDelete;
/**
* 特色服务模型
*/
class Products extends Model
{
// 启用软删除
use SoftDelete;
// 数据库表名
protected $name = 'mete_apps_cms_products';
// 字段类型转换
protected $type = [
'id' => 'integer',
'tid' => 'integer',
'title' => 'string',
'desc' => 'string',
'content' => 'string',
'thumb' => 'string',
'url' => 'string',
'sort' => 'integer',
'create_time' => 'datetime',
'update_time' => 'datetime',
'delete_time' => 'datetime',
];
}

View File

@ -21,6 +21,8 @@ return [
// 应用映射(自动多应用模式有效)
'app_map' => [],
// 域名绑定(自动多应用模式有效)
// 多租户二级域名池场景下,不建议在这里写死具体主域名/子域名
// 否则后续新增租户域名需要反复改配置
'domain_bind' => [],
// 禁止URL访问的应用列表自动多应用模式有效
'deny_app_list' => [],

126
docs/nginx/dh2fun.md Normal file
View File

@ -0,0 +1,126 @@
server
{
listen 80;
listen 443 ssl;
listen 443 quic;
http2 on;
server_name dh2.fun ~^(?<subdomain>.+)\.dh2\.fun$;
index index.php index.html index.htm default.php default.htm default.html;
root /www/wwwroot/api.yunzer.cn/public;
#CERT-APPLY-CHECK--START
include /www/server/panel/vhost/nginx/well-known/dh2.fun.conf;
#CERT-APPLY-CHECK--END
include /www/server/panel/vhost/nginx/extension/dh2.fun/*.conf;
# 根目录的 *.html 和 *.php交给 ThinkPHP 处理
location ~* ^/(.+\.(html|php))$ {
try_files $uri /index.php?$query_string;
}
# 所有 /themes/... 直接当静态文件返回(模板静态资源)
location ^~ /themes/ {
root /www/wwwroot/api.yunzer.cn/public;
try_files $uri $uri/ =404;
expires 12h;
access_log off;
}
# /template1..100/... 预览入口
location ~ ^/(template(?:[1-9]\d?|100))/(.*)$ {
alias /www/wwwroot/api.yunzer.cn/public/themes/$1/$2;
try_files $uri $uri/ =404;
expires 12h;
access_log off;
}
#SSL-START SSL相关配置请勿删除或修改下一行带注释的404规则
#error_page 404/404.html;
#HTTP_TO_HTTPS_START
set $isRedcert 1;
if ($server_port != 443) {
set $isRedcert 2;
}
if ( $uri ~ /\.well-known/ ) {
set $isRedcert 1;
}
if ($isRedcert != 1) {
rewrite ^(/.*)$ https://$host$1 permanent;
}
#HTTP_TO_HTTPS_END
ssl_certificate /www/server/panel/vhost/cert/dh2.fun/fullchain.pem;
ssl_certificate_key /www/server/panel/vhost/cert/dh2.fun/privkey.pem;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_tickets on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security "max-age=31536000";
add_header Alt-Svc 'quic=":443"; h3=":443"; h3-29=":443"; h3-27=":443";h3-25=":443"; h3-T050=":443"; h3-Q050=":443";h3-Q049=":443";h3-Q048=":443"; h3-Q046=":443"; h3-Q043=":443"';
error_page 497 https://$host$request_uri;
#SSL-END
#ERROR-PAGE-START 错误页配置,可以注释、删除或修改
error_page 404 /404.html;
#ERROR-PAGE-END
#PHP-INFO-START PHP引用配置可以注释或修改
include enable-php-82.conf;
#PHP-INFO-END
#REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效
include /www/server/panel/vhost/rewrite/dh2.fun.conf;
#REWRITE-END
# 禁止访问的敏感文件
location ~* (\.user.ini|\.htaccess|\.htpasswd|\.env.*|\.project|\.bashrc|\.bash_profile|\.bash_logout|\.DS_Store|\.gitignore|\.gitattributes|LICENSE|README\.md|CLAUDE\.md|CHANGELOG\.md|CHANGELOG|CONTRIBUTING\.md|TODO\.md|FAQ\.md|composer\.json|composer\.lock|package(-lock)?\.json|yarn\.lock|pnpm-lock\.yaml|\.\w+~|\.swp|\.swo|\.bak(up)?|\.old|\.tmp|\.temp|\.log|\.sql(\.gz)?|docker-compose\.yml|docker\.env|Dockerfile|\.csproj|\.sln|Cargo\.toml|Cargo\.lock|go\.mod|go\.sum|phpunit\.xml|phpunit\.xml|pom\.xml|build\.gradl|pyproject\.toml|requirements\.txt|application(-\w+)?\.(ya?ml|properties))$
{
return 404;
}
# 禁止访问的敏感目录
location ~* /(\.git|\.svn|\.bzr|\.vscode|\.claude|\.idea|\.ssh|\.github|\.npm|\.yarn|\.pnpm|\.cache|\.husky|\.turbo|\.next|\.nuxt|node_modules|runtime)/ {
return 404;
}
#一键申请SSL证书验证目录相关设置
location ~ \.well-known{
allow all;
}
#禁止在证书验证目录放入敏感文件
if ( $uri ~ "^/\.well-known/.*\.(php|jsp|py|js|css|lua|ts|go|zip|tar\.gz|rar|7z|sql|bak)$" ) {
return 403;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
error_log /dev/null;
access_log /dev/null;
}
location ~ .*\.(js|css)?$
{
expires 12h;
error_log /dev/null;
access_log /dev/null;
}
# PHP 解析 + 传递子域名参数
location ~ [^/]\.php(/|$) {
include enable-php-82.conf;
fastcgi_param HTTP_SUBDOMAIN $subdomain;
fastcgi_param HTTP_MAIN_DOMAIN dh2.fun;
}
# TP路由重写
if (!-e $request_filename) {
# 将原始 URI 追加到 /index.php 后面,让 ThinkPHP 从 pathinfo 里拿到 :page
rewrite ^(.*)$ /index.php$1$is_args$args last;
}
access_log /www/wwwlogs/dh2.fun.log;
error_log /www/wwwlogs/dh2.fun.error.log;
}

120
docs/nginx/yunzercomcn.md Normal file
View File

@ -0,0 +1,120 @@
server {
listen 80;
listen 443 ssl;
listen 443 quic;
http2 on;
# 捕获子域名变量 $subdomain
server_name yunzer.com.cn ~^(?<subdomain>.+)\.yunzer\.com\.cn$;
index index.php index.html index.htm default.php default.htm default.html;
root /www/wwwroot/api.yunzer.cn/public;
#CERT-APPLY-CHECK--START
include /www/server/panel/vhost/nginx/well-known/yunzer.com.cn.conf;
#CERT-APPLY-CHECK--END
include /www/server/panel/vhost/nginx/extension/yunzer.com.cn/*.conf;
# --- SSL 配置 START ---
set $isRedcert 1;
if ($server_port != 443) {
set $isRedcert 2;
}
if ( $uri ~ /\.well-known/ ) {
set $isRedcert 1;
}
if ($isRedcert != 1) {
rewrite ^(/.*)$ https://$host$1 permanent;
}
ssl_certificate /www/server/panel/vhost/cert/yunzer.com.cn/fullchain.pem;
ssl_certificate_key /www/server/panel/vhost/cert/yunzer.com.cn/privkey.pem;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_tickets on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security "max-age=31536000";
add_header Alt-Svc 'quic=":443"; h3=":443"; h3-29=":443"; h3-27=":443";h3-25=":443"; h3-T050=":443"; h3-Q050=":443";h3-Q049=":443";h3-Q048=":443"; h3-Q046=":443"; h3-Q043=":443"';
error_page 497 https://$host$request_uri;
# --- SSL 配置 END ---
#ERROR-PAGE-START
error_page 404 /404.html;
#ERROR-PAGE-END
# --- 安全与防盗链拦截 START ---
location ~* (\.user.ini|\.htaccess|\.htpasswd|\.env.*|\.project|\.bashrc|\.bash_profile|\.bash_logout|\.DS_Store|\.gitignore|\.gitattributes|LICENSE|README\.md|CLAUDE\.md|CHANGELOG\.md|CHANGELOG|CONTRIBUTING\.md|TODO\.md|FAQ\.md|composer\.json|composer\.lock|package(-lock)?\.json|yarn\.lock|pnpm-lock\.yaml|\.\w+~|\.swp|\.swo|\.bak(up)?|\.old|\.tmp|\.temp|\.log|\.sql(\.gz)?|docker-compose\.yml|docker\.env|Dockerfile|\.csproj|\.sln|Cargo\.toml|Cargo\.lock|go\.mod|go\.sum|phpunit\.xml|phpunit\.xml|pom\.xml|build\.gradl|pyproject\.toml|requirements\.txt|application(-\w+)?\.(ya?ml|properties))$ {
return 404;
}
location ~* /(\.git|\.svn|\.bzr|\.vscode|\.claude|\.idea|\.ssh|\.github|\.npm|\.yarn|\.pnpm|\.cache|\.husky|\.turbo|\.next|\.nuxt|node_modules|runtime)/ {
return 404;
}
location ~ \.well-known {
allow all;
}
if ( $uri ~ "^/\.well-known/.*\.(php|jsp|py|js|css|lua|ts|go|zip|tar\.gz|rar|7z|sql|bak)$" ) {
return 403;
}
# --- 安全与防盗链拦截 END ---
# --- 静态资源与缓存 START ---
location ^~ /themes/ {
root /www/wwwroot/api.yunzer.cn/public;
try_files $uri $uri/ =404;
expires 12h;
access_log off;
}
location ~ ^/(template(?:[1-9]\d?|100))/(.*)$ {
alias /www/wwwroot/api.yunzer.cn/public/themes/$1/$2;
try_files $uri $uri/ =404;
expires 12h;
access_log off;
}
location ~* \.(gif|jpg|jpeg|png|bmp|swf)$ {
expires 30d;
error_log /dev/null;
access_log /dev/null;
}
location ~* \.(js|css)$ {
expires 12h;
error_log /dev/null;
access_log /dev/null;
}
# --- 静态资源与缓存 END ---
# --- 核心路由与 PHP 解析 START ---
# 1. 根目录的 *.html交给 ThinkPHP 处理
location ~* ^/(.+\.html)$ {
try_files /themes/template3/$1 /index.php?$query_string;
}
# 2. 唯一且正确的 PHP 解析块(解决了直接下载的问题)
location ~ [^/]\.php(/|$) {
# 引入宝塔的 PHP FastCGI 配置,确保 PHP 正常执行
include enable-php-82.conf;
# 传递自定义子域名参数给 ThinkPHP
fastcgi_param HTTP_SUBDOMAIN $subdomain;
fastcgi_param HTTP_MAIN_DOMAIN yunzer.com.cn;
}
# 3. 统一入口ThinkPHP 默认伪静态):先找真实文件,找不到再交给 index.php
location / {
# 当访问的路径没有对应静态文件时,将请求回退到 ThinkPHP 前端入口。
# 使用 /index.php$uri 让内部请求变成 /index.php/portfolio 这类形式,
# 从而使 ThinkPHP 能从 pathinfo 中拿到 portfolio并匹配 Route::get(':page', ...)
# 保留 query_string用于 ?page=n 之类分页参数)
try_files $uri $uri/ /index.php$uri$is_args$args;
}
# --- 核心路由与 PHP 解析 END ---
access_log /www/wwwlogs/yunzer.com.cn.log;
error_log /www/wwwlogs/yunzer.com.cn.error.log;
}

View File

@ -1925,6 +1925,7 @@ section,
font-weight: 700;
padding: 0;
margin: 0 0 20px 0;
height: 48px;
}
.blog-posts .title a {

View File

@ -37,9 +37,9 @@ require_once __DIR__ . '/header.php';
<div class="meta-top">
<ul>
<li class="d-flex align-items-center"><i class="bi bi-person"></i> <a href="<?php echo $baseUrl; ?>/blog-details.php">John Doe</a></li>
<li class="d-flex align-items-center"><i class="bi bi-clock"></i> <a href="<?php echo $baseUrl; ?>/blog-details.php"><time datetime="2020-01-01">Jan 1, 2022</time></a></li>
<li class="d-flex align-items-center"><i class="bi bi-chat-dots"></i> <a href="<?php echo $baseUrl; ?>/blog-details.php">12 Comments</a></li>
<li class="d-flex align-items-center"><i class="bi bi-person"></i> <a href="<?php echo $baseUrl; ?>/blog-details">John Doe</a></li>
<li class="d-flex align-items-center"><i class="bi bi-clock"></i> <a href="<?php echo $baseUrl; ?>/blog-details"><time datetime="2020-01-01">Jan 1, 2022</time></a></li>
<li class="d-flex align-items-center"><i class="bi bi-chat-dots"></i> <a href="<?php echo $baseUrl; ?>/blog-details">12 Comments</a></li>
</ul>
</div><!-- End meta top -->
@ -301,7 +301,7 @@ require_once __DIR__ . '/header.php';
<div class="post-item">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-recent-1.jpg" alt="" class="flex-shrink-0">
<div>
<h4><a href="<?php echo $baseUrl; ?>/blog-details.php">Nihil blanditiis at in nihil autem</a></h4>
<h4><a href="<?php echo $baseUrl; ?>/blog-details">Nihil blanditiis at in nihil autem</a></h4>
<time datetime="2020-01-01">Jan 1, 2020</time>
</div>
</div><!-- End recent post item-->
@ -309,7 +309,7 @@ require_once __DIR__ . '/header.php';
<div class="post-item">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-recent-2.jpg" alt="" class="flex-shrink-0">
<div>
<h4><a href="<?php echo $baseUrl; ?>/blog-details.php">Quidem autem et impedit</a></h4>
<h4><a href="<?php echo $baseUrl; ?>/blog-details">Quidem autem et impedit</a></h4>
<time datetime="2020-01-01">Jan 1, 2020</time>
</div>
</div><!-- End recent post item-->
@ -317,7 +317,7 @@ require_once __DIR__ . '/header.php';
<div class="post-item">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-recent-3.jpg" alt="" class="flex-shrink-0">
<div>
<h4><a href="<?php echo $baseUrl; ?>/blog-details.php">Id quia et et ut maxime similique occaecati ut</a></h4>
<h4><a href="<?php echo $baseUrl; ?>/blog-details">Id quia et et ut maxime similique occaecati ut</a></h4>
<time datetime="2020-01-01">Jan 1, 2020</time>
</div>
</div><!-- End recent post item-->
@ -325,7 +325,7 @@ require_once __DIR__ . '/header.php';
<div class="post-item">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-recent-4.jpg" alt="" class="flex-shrink-0">
<div>
<h4><a href="<?php echo $baseUrl; ?>/blog-details.php">Laborum corporis quo dara net para</a></h4>
<h4><a href="<?php echo $baseUrl; ?>/blog-details">Laborum corporis quo dara net para</a></h4>
<time datetime="2020-01-01">Jan 1, 2020</time>
</div>
</div><!-- End recent post item-->
@ -333,7 +333,7 @@ require_once __DIR__ . '/header.php';
<div class="post-item">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-recent-5.jpg" alt="" class="flex-shrink-0">
<div>
<h4><a href="<?php echo $baseUrl; ?>/blog-details.php">Et dolores corrupti quae illo quod dolor</a></h4>
<h4><a href="<?php echo $baseUrl; ?>/blog-details">Et dolores corrupti quae illo quod dolor</a></h4>
<time datetime="2020-01-01">Jan 1, 2020</time>
</div>
</div><!-- End recent post item-->

View File

@ -3,6 +3,28 @@ $pageTitle = '新闻中心 - Nova';
$pageDescription = 'Nova Bootstrap Template 的新闻中心页面';
$pageKeywords = 'blog, news, nova';
require_once __DIR__ . '/header.php';
?>
<?php
// 本页使用本地分页:根据 query 参数 ?page=n 只展示 newsList 的切片
$allNewsList = is_array($newsList ?? null) ? $newsList : [];
$currentPage = (int)($_GET['page'] ?? 1);
if ($currentPage < 1) {
$currentPage = 1;
}
$pageSize = 4; // 每页展示 4 条grid 中每条占 col-lg-6所以刚好两行
$totalCount = count($allNewsList);
$totalPages = (int)ceil($totalCount / $pageSize);
if ($totalPages < 1) {
$totalPages = 1;
}
if ($currentPage > $totalPages) {
$currentPage = $totalPages;
}
$newsListForPage = array_slice($allNewsList, ($currentPage - 1) * $pageSize, $pageSize);
?>
<!-- Page Title -->
@ -28,162 +50,68 @@ require_once __DIR__ . '/header.php';
<div class="container">
<div class="row gy-4">
<?php if (!empty($newsList)): ?>
<?php foreach ($newsListForPage as $i => $item): ?>
<?php
$title = $item['title'] ?? '无标题';
$author = $item['author'] ?? '';
$category = $item['category'] ?? ($item['category_name'] ?? '');
<div class="col-lg-6">
<article>
$publishDateRaw = $item['publish_date'] ?? '';
$postDate = !empty($publishDateRaw) ? date('Y年m月d日', strtotime($publishDateRaw)) : '';
<div class="post-img">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-1.jpg" alt="" class="img-fluid">
</div>
$thumbUrl = $item['thumb'] ?? ($item['image'] ?? '');
if (!empty($thumbUrl)) {
if (strpos($thumbUrl, 'http') === 0) {
$imgSrc = $thumbUrl;
} elseif (strpos($thumbUrl, '/') === 0) {
$imgSrc = $apiUrl . $thumbUrl;
} else {
$imgSrc = $apiUrl . '/' . $thumbUrl;
}
} else {
$imgIndex = ($i % 6) + 1; // blog-1.jpg ~ blog-6.jpg
$imgSrc = $baseUrl . "/themes/template3/assets/img/blog/blog-{$imgIndex}.jpg";
}
<p class="post-category">Politics</p>
$articleUrl = $apiUrl . '/article_detail/' . ($item['id'] ?? 0);
?>
<h2 class="title">
<a href="blog-details.php">Dolorum optio tempore voluptas dignissimos</a>
</h2>
<div class="col-lg-6">
<article>
<div class="d-flex align-items-center">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-author.jpg" alt="" class="img-fluid post-author-img flex-shrink-0">
<div class="post-meta">
<p class="post-author">Maria Doe</p>
<p class="post-date">
<time datetime="2022-01-01">Jan 1, 2022</time>
</p>
</div>
</div>
<div class="post-img">
<img src="<?php echo htmlspecialchars($imgSrc); ?>" alt="" class="img-fluid">
</div>
</article>
</div><!-- End post list item -->
<p class="post-category"><?php echo htmlspecialchars($category); ?></p>
<div class="col-lg-6">
<article>
<h2 class="title">
<a href="<?php echo htmlspecialchars($articleUrl); ?>">
<?php echo htmlspecialchars($title); ?>
</a>
</h2>
<div class="post-img">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-2.jpg" alt="" class="img-fluid">
</div>
<div class="d-flex align-items-center">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-author.jpg" alt="" class="img-fluid post-author-img flex-shrink-0">
<div class="post-meta">
<p class="post-author"><?php echo htmlspecialchars($author); ?></p>
<p class="post-date">
<time datetime="<?php echo htmlspecialchars($publishDateRaw); ?>">
<?php echo htmlspecialchars($postDate); ?>
</time>
</p>
</div>
</div>
<p class="post-category">Sports</p>
<h2 class="title">
<a href="blog-details.php">Nisi magni odit consequatur autem nulla dolorem</a>
</h2>
<div class="d-flex align-items-center">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-author-2.jpg" alt="" class="img-fluid post-author-img flex-shrink-0">
<div class="post-meta">
<p class="post-author">Allisa Mayer</p>
<p class="post-date">
<time datetime="2022-01-01">Jun 5, 2022</time>
</p>
</div>
</div>
</article>
</div><!-- End post list item -->
<div class="col-lg-6">
<article>
<div class="post-img">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-3.jpg" alt="" class="img-fluid">
</div>
<p class="post-category">Entertainment</p>
<h2 class="title">
<a href="blog-details.php">Possimus soluta ut id suscipit ea ut in quo quia et soluta</a>
</h2>
<div class="d-flex align-items-center">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-author-3.jpg" alt="" class="img-fluid post-author-img flex-shrink-0">
<div class="post-meta">
<p class="post-author">Mark Dower</p>
<p class="post-date">
<time datetime="2022-01-01">Jun 22, 2022</time>
</p>
</div>
</div>
</article>
</div><!-- End post list item -->
<div class="col-lg-6">
<article>
<div class="post-img">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-4.jpg" alt="" class="img-fluid">
</div>
<p class="post-category">Sports</p>
<h2 class="title">
<a href="blog-details.php">Non rem rerum nam cum quo minus olor distincti</a>
</h2>
<div class="d-flex align-items-center">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-author-4.jpg" alt="" class="img-fluid post-author-img flex-shrink-0">
<div class="post-meta">
<p class="post-author">Lisa Neymar</p>
<p class="post-date">
<time datetime="2022-01-01">Jun 30, 2022</time>
</p>
</div>
</div>
</article>
</div><!-- End post list item -->
<div class="col-lg-6">
<article>
<div class="post-img">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-5.jpg" alt="" class="img-fluid">
</div>
<p class="post-category">Politics</p>
<h2 class="title">
<a href="blog-details.php">Accusamus quaerat aliquam qui debitis facilis consequatur</a>
</h2>
<div class="d-flex align-items-center">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-author-5.jpg" alt="" class="img-fluid post-author-img flex-shrink-0">
<div class="post-meta">
<p class="post-author">Denis Peterson</p>
<p class="post-date">
<time datetime="2022-01-01">Jan 30, 2022</time>
</p>
</div>
</div>
</article>
</div><!-- End post list item -->
<div class="col-lg-6">
<article>
<div class="post-img">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-6.jpg" alt="" class="img-fluid">
</div>
<p class="post-category">Entertainment</p>
<h2 class="title">
<a href="blog-details.php">Distinctio provident quibusdam numquam aperiam aut</a>
</h2>
<div class="d-flex align-items-center">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-author-6.jpg" alt="" class="img-fluid post-author-img flex-shrink-0">
<div class="post-meta">
<p class="post-author">Mika Lendon</p>
<p class="post-date">
<time datetime="2022-01-01">Feb 14, 2022</time>
</p>
</div>
</div>
</article>
</div><!-- End post list item -->
</article>
</div><!-- End post list item -->
<?php endforeach; ?>
<?php else: ?>
<div class="col-12 text-center">
<p>暂无新闻数据</p>
</div>
<?php endif; ?>
</div>
</div>
@ -196,14 +124,24 @@ require_once __DIR__ . '/header.php';
<div class="container">
<div class="d-flex justify-content-center">
<ul>
<li><a href="#"><i class="bi bi-chevron-left"></i></a></li>
<li><a href="#">1</a></li>
<li><a href="#" class="active">2</a></li>
<li><a href="#">3</a></li>
<li><a href="#">4</a></li>
<li>...</li>
<li><a href="#">10</a></li>
<li><a href="#"><i class="bi bi-chevron-right"></i></a></li>
<?php
$prevPage = max(1, $currentPage - 1);
$nextPage = min($totalPages, $currentPage + 1);
$showMax = 10;
$showTotal = min($totalPages, $showMax);
?>
<li><a href="<?php echo $baseUrl; ?>/blog?page=<?php echo $prevPage; ?>"><i class="bi bi-chevron-left"></i></a></li>
<?php for ($p = 1; $p <= $showTotal; $p++): ?>
<li>
<a
href="<?php echo $baseUrl; ?>/blog?page=<?php echo $p; ?>"
<?php echo ($p === $currentPage) ? 'class="active"' : ''; ?>
>
<?php echo $p; ?>
</a>
</li>
<?php endfor; ?>
<li><a href="<?php echo $baseUrl; ?>/blog?page=<?php echo $nextPage; ?>"><i class="bi bi-chevron-right"></i></a></li>
</ul>
</div>
</div>
@ -250,7 +188,7 @@ require_once __DIR__ . '/header.php';
<div class="post-item">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-recent-1.jpg" alt="" class="flex-shrink-0">
<div>
<h4><a href="blog-details.php">Nihil blanditiis at in nihil autem</a></h4>
<h4><a href="<?php echo $baseUrl; ?>/blog-details">Nihil blanditiis at in nihil autem</a></h4>
<time datetime="2020-01-01">Jan 1, 2020</time>
</div>
</div><!-- End recent post item-->
@ -258,7 +196,7 @@ require_once __DIR__ . '/header.php';
<div class="post-item">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-recent-2.jpg" alt="" class="flex-shrink-0">
<div>
<h4><a href="blog-details.php">Quidem autem et impedit</a></h4>
<h4><a href="<?php echo $baseUrl; ?>/blog-details">Quidem autem et impedit</a></h4>
<time datetime="2020-01-01">Jan 1, 2020</time>
</div>
</div><!-- End recent post item-->
@ -266,7 +204,7 @@ require_once __DIR__ . '/header.php';
<div class="post-item">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-recent-3.jpg" alt="" class="flex-shrink-0">
<div>
<h4><a href="blog-details.php">Id quia et et ut maxime similique occaecati ut</a></h4>
<h4><a href="<?php echo $baseUrl; ?>/blog-details">Id quia et et ut maxime similique occaecati ut</a></h4>
<time datetime="2020-01-01">Jan 1, 2020</time>
</div>
</div><!-- End recent post item-->
@ -274,7 +212,7 @@ require_once __DIR__ . '/header.php';
<div class="post-item">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-recent-4.jpg" alt="" class="flex-shrink-0">
<div>
<h4><a href="blog-details.php">Laborum corporis quo dara net para</a></h4>
<h4><a href="<?php echo $baseUrl; ?>/blog-details">Laborum corporis quo dara net para</a></h4>
<time datetime="2020-01-01">Jan 1, 2020</time>
</div>
</div><!-- End recent post item-->
@ -282,33 +220,13 @@ require_once __DIR__ . '/header.php';
<div class="post-item">
<img src="<?php echo $baseUrl; ?>/themes/template3/assets/img/blog/blog-recent-5.jpg" alt="" class="flex-shrink-0">
<div>
<h4><a href="blog-details.php">Et dolores corrupti quae illo quod dolor</a></h4>
<h4><a href="<?php echo $baseUrl; ?>/blog-details">Et dolores corrupti quae illo quod dolor</a></h4>
<time datetime="2020-01-01">Jan 1, 2020</time>
</div>
</div><!-- End recent post item-->
</div><!--/Recent Posts Widget -->
<!-- Tags Widget -->
<div class="tags-widget widget-item">
<h3 class="widget-title">标签</h3>
<ul>
<li><a href="#">App</a></li>
<li><a href="#">IT</a></li>
<li><a href="#">Business</a></li>
<li><a href="#">Mac</a></li>
<li><a href="#">Design</a></li>
<li><a href="#">Office</a></li>
<li><a href="#">Creative</a></li>
<li><a href="#">Studio</a></li>
<li><a href="#">Smart</a></li>
<li><a href="#">Tips</a></li>
<li><a href="#">Marketing</a></li>
</ul>
</div><!--/Tags Widget -->
</div>
</div>
@ -318,66 +236,6 @@ require_once __DIR__ . '/header.php';
</main>
<footer id="footer" class="footer light-background">
<div class="footer-top">
<div class="container">
<div class="row gy-4">
<div class="col-lg-5 col-md-12 footer-about">
<a href="<?php echo $baseUrl; ?>/" class="logo d-flex align-items-center">
<span class="sitename">Nova</span>
</a>
<p>Cras fermentum odio eu feugiat lide par naso tierra. Justo eget nada terra videa magna derita valies darta donna mare fermentum iaculis eu non diam phasellus.</p>
<div class="social-links d-flex mt-4">
<a href=""><i class="bi bi-twitter-x"></i></a>
<a href=""><i class="bi bi-facebook"></i></a>
<a href=""><i class="bi bi-instagram"></i></a>
<a href=""><i class="bi bi-linkedin"></i></a>
</div>
</div>
<div class="col-lg-2 col-6 footer-links">
<h4>有用链接</h4>
<ul>
<li><a href="<?php echo $baseUrl; ?>/">Home</a></li>
<li><a href="<?php echo $baseUrl; ?>/about.php">About us</a></li>
<li><a href="<?php echo $baseUrl; ?>/services.php">Services</a></li>
<li><a href="#">Terms of service</a></li>
<li><a href="#">Privacy policy</a></li>
</ul>
</div>
<div class="col-lg-2 col-6 footer-links">
<h4>特色业务</h4>
<ul>
<li><a href="<?php echo $baseUrl; ?>/portfolio.php">Web Design</a></li>
<li><a href="<?php echo $baseUrl; ?>/portfolio.php">Web Development</a></li>
<li><a href="<?php echo $baseUrl; ?>/services.php">Product Management</a></li>
<li><a href="#">Marketing</a></li>
<li><a href="#">Graphic Design</a></li>
</ul>
</div>
<div class="col-lg-3 col-md-12 footer-contact text-center text-md-start">
<h4>联系我们</h4>
<p>A108 Adam Street</p>
<p>New York, NY 535022</p>
<p>United States</p>
<p class="mt-4"><strong>Phone:</strong> <span>+1 5589 55488 55</span></p>
<p><strong>Email:</strong> <span>info@example.com</span></p>
</div>
</div>
</div>
</div>
<div class="container copyright text-center">
<p>© <span>Copyright</span> <strong class="px-1 sitename">Nova</strong> <span>All Rights Reserved</span></p>
<div class="credits">
Designed by <a href="https://bootstrapmade.com/">BootstrapMade</a> Distributed by <a href="https://themewagon.com">ThemeWagon</a>
</div>
</div>
</footer>
<?php require_once __DIR__ . '/footer.php'; ?>

View File

@ -1,33 +1,67 @@
<!-- footer.php -->
<!-- Scroll Top -->
<a href="#" id="scroll-top" class="scroll-top d-flex align-items-center justify-content-center"><i class="bi bi-arrow-up-short"></i></a>
<a href="#" id="scroll-top" class="scroll-top d-flex align-items-center justify-content-center"><i class="bi bi-arrow-up-short"></i></a>
<!-- Preloader -->
<div id="preloader"></div>
<!-- Preloader -->
<div id="preloader"></div>
<!-- Footer -->
<footer id="footer" class="footer">
<!-- Footer -->
<footer id="footer" class="footer light-background">
<div class="footer-top">
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<p>Design and Developed by 云泽网 <?php echo $homeInfo['normal']['copyright']; ?> <?php echo $homeInfo['normal']['sitename']; ?> All Rights Reserved.</p>
<div class="row gy-4">
<div class="col-lg-5 col-md-12 footer-about">
<a href="<?php echo $baseUrl; ?>/" class="logo d-flex align-items-center">
<img src="<?php echo htmlspecialchars($homeInfo['normal']['logo']); ?>" alt="">
</a>
<p><?php echo htmlspecialchars($seoDescription); ?></p>
<!-- <div class="social-links d-flex mt-4">
<a href=""><i class="bi bi-twitter-x"></i></a>
<a href=""><i class="bi bi-facebook"></i></a>
<a href=""><i class="bi bi-instagram"></i></a>
<a href=""><i class="bi bi-linkedin"></i></a>
</div> -->
</div>
<div class="col-lg-2 col-6 footer-links">
<h4>链接</h4>
<ul>
<li><a href="<?php echo $baseUrl; ?>/">主页</a></li>
<li><a href="<?php echo $baseUrl; ?>/blog">新闻中心</a></li>
<li><a href="<?php echo $baseUrl; ?>/contact">联系我们</a></li>
</ul>
</div>
<div class="col-lg-3 col-md-12 footer-contact text-center text-md-start">
<h4>联系我们</h4>
<p><strong>地址:</strong> <span><?php echo ($homeInfo['contact']['address']); ?></span></p>
<p><strong>电话:</strong> <span><?php echo ($homeInfo['contact']['contact_phone']); ?></span></p>
<p><strong>邮箱:</strong> <span><?php echo ($homeInfo['contact']['contact_email']); ?></span></p>
</div>
</div>
</div>
</footer>
</div>
<!-- Vendor JS Files -->
<script src="<?php echo $baseUrl; ?>/themes/template3/assets/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="<?php echo $baseUrl; ?>/themes/template3/assets/vendor/php-email-form/validate.js"></script>
<script src="<?php echo $baseUrl; ?>/themes/template3/assets/vendor/aos/aos.js"></script>
<script src="<?php echo $baseUrl; ?>/themes/template3/assets/vendor/glightbox/js/glightbox.min.js"></script>
<script src="<?php echo $baseUrl; ?>/themes/template3/assets/vendor/swiper/swiper-bundle.min.js"></script>
<script src="<?php echo $baseUrl; ?>/themes/template3/assets/vendor/imagesloaded/imagesloaded.pkgd.min.js"></script>
<script src="<?php echo $baseUrl; ?>/themes/template3/assets/vendor/isotope-layout/isotope.pkgd.min.js"></script>
<div class="container copyright text-center">
<p>Design and Developed by 云泽网 <?php echo $homeInfo['normal']['copyright']; ?> <?php echo $homeInfo['normal']['sitename']; ?> All Rights Reserved.</p>
</div>
<!-- Main JS File -->
<script src="<?php echo $baseUrl; ?>/themes/template3/assets/js/main.js"></script>
</footer>
<!-- Vendor JS Files -->
<script src="<?php echo $baseUrl; ?>/themes/template3/assets/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="<?php echo $baseUrl; ?>/themes/template3/assets/vendor/php-email-form/validate.js"></script>
<script src="<?php echo $baseUrl; ?>/themes/template3/assets/vendor/aos/aos.js"></script>
<script src="<?php echo $baseUrl; ?>/themes/template3/assets/vendor/glightbox/js/glightbox.min.js"></script>
<script src="<?php echo $baseUrl; ?>/themes/template3/assets/vendor/swiper/swiper-bundle.min.js"></script>
<script src="<?php echo $baseUrl; ?>/themes/template3/assets/vendor/imagesloaded/imagesloaded.pkgd.min.js"></script>
<script src="<?php echo $baseUrl; ?>/themes/template3/assets/vendor/isotope-layout/isotope.pkgd.min.js"></script>
<!-- Main JS File -->
<script src="<?php echo $baseUrl; ?>/themes/template3/assets/js/main.js"></script>
</body>
</html>
</html>

View File

@ -1,4 +1,3 @@
<!-- header.php -->
<?php
// #########默认头部开始#########
// 引入 ThinkPHP 应用
@ -11,7 +10,6 @@ $scheme = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : '
$baseUrl = $baseUrl ?? ($scheme . '://' . $host);
$apiUrl = $apiUrl ?? 'https://api.yunzer.cn';
/**
* 核心请求函数fetchApiData
* 用于发送 GET 请求并解析 JSON
@ -52,10 +50,16 @@ $newsUrl = $apiUrl . '/getCenterNews?baseUrl=' . urlencode($host);
$newsRes = fetchApiData($newsUrl);
$newsList = $newsRes['list'] ?? [];
// 获取特色服务
$servicesList = $homeInfo['services'] ?? [];
// 获取企业产品
$productsList = $homeInfo['products'] ?? [];
// 获取友链数据
$friendlinkList = $homeInfo['links'] ?? [];
// 动态设置 SEO 变量
// 动态设置 SEO 变量(优先用每个页面自己的变量)
$seoTitle = $pageTitle ?? ($homeInfo['normal']['sitename'] ?? '云泽网 默认标题');
$seoDescription = $pageDescription ?? ($homeInfo['normal']['description'] ?? '');
$seoKeywords = $pageKeywords ?? ($homeInfo['normal']['keywords'] ?? '');
@ -69,9 +73,11 @@ $seoKeywords = $pageKeywords ?? ($homeInfo['normal']['keywords'] ?? '');
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<base href="/themes/template3/">
<title><?php echo htmlspecialchars($homeInfo['normal']['sitename']); ?></title>
<meta name="description" content="<?php echo $homeInfo['normal']['description']; ?>">
<meta name="keywords" content="<?php echo $seoKeywords; ?>">
<!-- 使用页面级 SEO 变量 -->
<title><?php echo htmlspecialchars($seoTitle); ?></title>
<meta name="description" content="<?php echo htmlspecialchars($seoDescription); ?>">
<meta name="keywords" content="<?php echo htmlspecialchars($seoKeywords); ?>">
<link href="<?php echo $baseUrl; ?>/themes/template3/assets/img/favicon.png" rel="icon">
<link href="<?php echo $baseUrl; ?>/themes/template3/assets/img/apple-touch-icon.png" rel="apple-touch-icon">
@ -90,17 +96,27 @@ $seoKeywords = $pageKeywords ?? ($homeInfo['normal']['keywords'] ?? '');
<header id="header" class="header d-flex align-items-center fixed-top">
<div class="container-fluid container-xl position-relative d-flex align-items-center justify-content-between">
<?php
// 安全获取 logo避免 homeInfo['normal'] 未定义时报错
$logo = '';
if (!empty($homeInfo['normal']) && !empty($homeInfo['normal']['logow'])) {
$logo = $baseUrl . $homeInfo['normal']['logow'];
} else {
// 兜底:使用模板自带的默认 logo
$logo = $baseUrl . '/themes/template3/assets/img/logo.png';
}
?>
<a href="<?php echo $baseUrl; ?>/" class="logo d-flex align-items-center">
<img src="<?php echo $baseUrl . $homeInfo['normal']['logow']; ?>" alt="">
<img src="<?php echo htmlspecialchars($logo); ?>" alt="">
</a>
<nav id="navmenu" class="navmenu">
<ul>
<li><a href="<?php echo $baseUrl; ?>/" class="active">主页</a></li>
<li><a href="<?php echo $baseUrl; ?>/blog.php">新闻中心</a></li>
<li><a href="<?php echo $baseUrl; ?>/portfolio.php">特色业务</a></li>
<li><a href="<?php echo $baseUrl; ?>/contact.php">联系我们</a></li>
<li><a href="<?php echo $baseUrl; ?>/about.php">关于我们</a></li>
<li><a href="<?php echo $baseUrl; ?>/blog">新闻中心</a></li>
<li><a href="<?php echo $baseUrl; ?>/portfolio">特色业务</a></li>
<li><a href="<?php echo $baseUrl; ?>/contact">联系我们</a></li>
<li><a href="<?php echo $baseUrl; ?>/about">关于我们</a></li>
</ul>
<i class="mobile-nav-toggle d-xl-none bi bi-list"></i>
</nav>

View File

@ -49,6 +49,29 @@ require_once __DIR__ . '/header.php';
}
document.getElementById('hero-indicator').textContent = (currentIndex + 1) + ' / ' + banners.length;
}
// 自动轮播:每 5 秒切换一张
var heroTimer = null;
function startHeroAutoplay() {
if (heroTimer) clearInterval(heroTimer);
heroTimer = setInterval(function () {
switchBanner(1);
}, 5000);
}
function stopHeroAutoplay() {
if (heroTimer) clearInterval(heroTimer);
heroTimer = null;
}
// 鼠标移入暂停,移出继续
var heroSection = document.getElementById('hero');
if (heroSection) {
heroSection.addEventListener('mouseenter', stopHeroAutoplay);
heroSection.addEventListener('mouseleave', startHeroAutoplay);
}
// 初始化启动
startHeroAutoplay();
</script>
<?php endif; ?>
@ -147,7 +170,29 @@ require_once __DIR__ . '/header.php';
<div class="row g-0">
<div class="col-xl-5 img-bg" data-aos="fade-up" data-aos-delay="100">
<img src="<?php echo $apiUrl; ?>/themes/template3/assets/img/why-us-bg.jpg" alt="">
<?php
// why-us 左侧图片随 productsList 的 swiper 切换
$whyUsFallbackImg = $apiUrl . '/themes/template3/assets/img/why-us-bg.jpg';
$whyUsThumbs = [];
if (!empty($productsList)) {
foreach ($productsList as $product) {
$thumb = $product['thumb'] ?? '';
if (!empty($thumb)) {
if (strpos($thumb, 'http') === 0) {
$whyUsThumbs[] = $thumb;
} elseif (strpos($thumb, '/') === 0) {
$whyUsThumbs[] = $baseUrl . $thumb; // /storage/... 直接拼站点域名
} else {
$whyUsThumbs[] = $baseUrl . '/' . $thumb;
}
} else {
$whyUsThumbs[] = $whyUsFallbackImg;
}
}
}
$whyUsInitialImg = !empty($whyUsThumbs) ? ($whyUsThumbs[0] ?? $whyUsFallbackImg) : $whyUsFallbackImg;
?>
<img id="why-us-img" src="<?php echo htmlspecialchars($whyUsInitialImg); ?>" alt="" data-fallback="<?php echo htmlspecialchars($whyUsFallbackImg); ?>">
</div>
<div class="col-xl-7 slides position-relative" data-aos="fade-up" data-aos-delay="200">
@ -175,46 +220,59 @@ require_once __DIR__ . '/header.php';
</script>
<div class="swiper-wrapper">
<div class="swiper-slide">
<div class="item">
<h3 class="mb-3">让我们一起成长</h3>
<h4 class="mb-3">Optio reiciendis accusantium iusto architecto at quia minima maiores quidem, dolorum.
</h4>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Repellendus, ipsam perferendis asperiores
explicabo vel tempore velit totam, natus nesciunt accusantium dicta quod quibusdam ipsum maiores nobis
non, eum. Ullam reiciendis dignissimos laborum aut, magni voluptatem velit doloribus quas sapiente
optio.</p>
</div>
</div><!-- End slide item -->
<?php if (!empty($productsList)): ?>
<?php foreach ($productsList as $i => $product): ?>
<?php
$title = $product['title'] ?? '';
$desc = $product['desc'] ?? '';
if (mb_strlen($desc) > 200) {
$desc = mb_substr($desc, 0, 200) . '...';
}
?>
<div class="swiper-slide">
<div class="item">
<h3 class="mb-3"><?php echo htmlspecialchars($title); ?></h3>
<p><?php echo htmlspecialchars($desc); ?></p>
</div>
</div><!-- End slide item -->
<?php endforeach; ?>
<?php else: ?>
<!-- productsList 为空时兜底展示(保持原示例) -->
<div class="swiper-slide">
<div class="item">
<h3 class="mb-3">让我们一起成长</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Repellendus, ipsam perferendis asperiores
explicabo vel tempore velit totam, natus nesciunt accusantium dicta quod quibusdam ipsum maiores nobis
non, eum. Ullam reiciendis dignissimos laborum aut, magni voluptatem velit doloribus quas sapiente
optio.</p>
</div>
</div><!-- End slide item -->
<div class="swiper-slide">
<div class="item">
<h3 class="mb-3">Unde perspiciatis ut repellat dolorem</h3>
<h4 class="mb-3">Amet cumque nam sed voluptas doloribus iusto. Dolorem eos aliquam quis.</h4>
<p>Dolorem quia fuga consectetur voluptatem. Earum consequatur nulla maxime necessitatibus cum
accusamus. Voluptatem dolorem ut numquam dolorum delectus autem veritatis facilis. Et ea ut repellat
ea. Facere est dolores fugiat dolor.</p>
</div>
</div><!-- End slide item -->
<div class="swiper-slide">
<div class="item">
<h3 class="mb-3">Unde perspiciatis ut repellat dolorem</h3>
<p>Dolorem quia fuga consectetur voluptatem. Earum consequatur nulla maxime necessitatibus cum
accusamus. Voluptatem dolorem ut numquam dolorum delectus autem veritatis facilis. Et ea ut repellat
ea. Facere est dolores fugiat dolor.</p>
</div>
</div><!-- End slide item -->
<div class="swiper-slide">
<div class="item">
<h3 class="mb-3">Aliquid non alias minus</h3>
<h4 class="mb-3">Necessitatibus voluptatibus explicabo dolores a vitae voluptatum.</h4>
<p>Neque voluptates aut. Soluta aut perspiciatis porro deserunt. Voluptate ut itaque velit. Aut
consectetur voluptatem aspernatur sequi sit laborum. Voluptas enim dolorum fugiat aut.</p>
</div>
</div><!-- End slide item -->
<div class="swiper-slide">
<div class="item">
<h3 class="mb-3">Aliquid non alias minus</h3>
<p>Neque voluptates aut. Soluta aut perspiciatis porro deserunt. Voluptate ut itaque velit. Aut
consectetur voluptatem aspernatur sequi sit laborum. Voluptas enim dolorum fugiat aut.</p>
</div>
</div><!-- End slide item -->
<div class="swiper-slide">
<div class="item">
<h3 class="mb-3">Necessitatibus suscipit non voluptatem quibusdam</h3>
<h4 class="mb-3">Tempora quos est ut quia adipisci ut voluptas. Deleniti laborum soluta nihil est. Eum
similique neque autem ut.</h4>
<p>Ut rerum et autem vel. Et rerum molestiae aut sit vel incidunt sit at voluptatem. Saepe dolorem et
sed voluptate impedit. Ad et qui sint at qui animi animi rerum.</p>
</div>
</div><!-- End slide item -->
<div class="swiper-slide">
<div class="item">
<h3 class="mb-3">Necessitatibus suscipit non voluptatem quibusdam</h3>
<p>Ut rerum et autem vel. Et rerum molestiae aut sit vel incidunt sit at voluptatem. Saepe dolorem et
sed voluptate impedit. Ad et qui sint at qui animi animi rerum.</p>
</div>
</div><!-- End slide item -->
<?php endif; ?>
</div>
<div class="swiper-pagination"></div>
@ -230,79 +288,112 @@ require_once __DIR__ . '/header.php';
</section><!-- /Why Us Section -->
<script>
(function () {
const section = document.getElementById('why-us');
if (!section) return;
const swiperEl = section.querySelector('.swiper.init-swiper');
const imgEl = section.querySelector('#why-us-img');
if (!swiperEl || !imgEl) return;
const wrapper = swiperEl.querySelector('.swiper-wrapper');
if (!wrapper) return;
const slides = Array.from(wrapper.querySelectorAll('.swiper-slide'));
const thumbs = <?php echo json_encode($whyUsThumbs ?? [], JSON_UNESCAPED_SLASHES); ?>;
function getActiveIndex() {
const active = wrapper.querySelector('.swiper-slide-active');
if (!active) return 0;
const idx = slides.indexOf(active);
return idx >= 0 ? idx : 0;
}
function updateImg() {
const idx = getActiveIndex();
const fallback = imgEl.dataset.fallback || imgEl.src;
const src = thumbs[idx] || thumbs[0] || fallback;
if (src) imgEl.src = src;
}
// 初始化 + 兼容 swiper 初始化时机
window.addEventListener('load', function () {
setTimeout(updateImg, 300);
});
wrapper.addEventListener('transitionend', updateImg);
swiperEl.addEventListener('transitionend', updateImg);
})();
</script>
<!-- Services Section -->
<section id="services" class="services section">
<!-- Section Title -->
<div class="container section-title" data-aos="fade-up">
<h2>我们的服务</h2>
<p>Necessitatibus eius consequatur ex aliquid fuga eum quidem sint consectetur velit</p>
<p>OUR SERVICES</p>
</div><!-- End Section Title -->
<div class="container">
<div class="row gy-4">
<?php
// 服务列表图标与颜色兜底(当接口没返回 thumb 时使用)
$serviceIcons = ['bi-briefcase', 'bi-card-checklist', 'bi-bar-chart', 'bi-binoculars', 'bi-brightness-high', 'bi-calendar4-week'];
$serviceColors = ['#f57813', '#15a04a', '#d90769', '#15bfbc', '#f5cf13', '#1335f5'];
?>
<div class="col-lg-4 col-md-6 service-item d-flex" data-aos="fade-up" data-aos-delay="100">
<div class="icon flex-shrink-0"><i class="bi bi-briefcase" style="color: #f57813;"></i></div>
<div>
<h4 class="title">Lorem Ipsum</h4>
<p class="description">Voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint
occaecati cupiditate non provident</p>
<a href="#" class="readmore stretched-link"><span>了解更多</span><i class="bi bi-arrow-right"></i></a>
</div>
</div>
<!-- End Service Item -->
<?php if (!empty($servicesList)): ?>
<?php foreach ($servicesList as $i => $item): ?>
<?php
$title = $item['title'] ?? '';
$desc = $item['desc'] ?? '';
$serviceUrl = !empty($item['url']) ? $item['url'] : '#';
<div class="col-lg-4 col-md-6 service-item d-flex" data-aos="fade-up" data-aos-delay="200">
<div class="icon flex-shrink-0"><i class="bi bi-card-checklist" style="color: #15a04a;"></i></div>
<div>
<h4 class="title">Dolor Sitema</h4>
<p class="description">Minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat tarad limino ata</p>
<a href="#" class="readmore stretched-link"><span>了解更多</span><i class="bi bi-arrow-right"></i></a>
</div>
</div><!-- End Service Item -->
$thumb = $item['thumb'] ?? '';
if ($thumb) {
if (strpos($thumb, 'http') === 0) {
$imgSrc = $thumb;
} elseif (strpos($thumb, '/') === 0) {
// 站点内相对路径,例如:/storage/uploads/xxx.jpg
$imgSrc = $baseUrl . $thumb;
} else {
// 兜底:当接口返回非以 / 开头的相对路径时
$imgSrc = $apiUrl . $thumb;
}
} else {
$imgSrc = '';
}
<div class="col-lg-4 col-md-6 service-item d-flex" data-aos="fade-up" data-aos-delay="300">
<div class="icon flex-shrink-0"><i class="bi bi-bar-chart" style="color: #d90769;"></i></div>
<div>
<h4 class="title">Sed ut perspiciatis</h4>
<p class="description">Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur</p>
<a href="#" class="readmore stretched-link"><span>了解更多</span><i class="bi bi-arrow-right"></i></a>
</div>
</div><!-- End Service Item -->
$icon = $serviceIcons[$i % count($serviceIcons)];
$color = $serviceColors[$i % count($serviceColors)];
$delay = ($i + 1) * 100;
?>
<div class="col-lg-4 col-md-6 service-item d-flex" data-aos="fade-up" data-aos-delay="400">
<div class="icon flex-shrink-0"><i class="bi bi-binoculars" style="color: #15bfbc;"></i></div>
<div>
<h4 class="title">Magni Dolores</h4>
<p class="description">Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum</p>
<a href="#" class="readmore stretched-link"><span>了解更多</span><i class="bi bi-arrow-right"></i></a>
<div class="col-lg-4 col-md-6 service-item d-flex" data-aos="fade-up" data-aos-delay="<?php echo $delay; ?>">
<div class="icon flex-shrink-0">
<?php if (!empty($imgSrc)): ?>
<img src="<?php echo htmlspecialchars($imgSrc); ?>" alt=""
style="width: 34px; height: 34px; object-fit: contain;">
<?php else: ?>
<i class="bi <?php echo $icon; ?>" style="color: <?php echo $color; ?>;"></i>
<?php endif; ?>
</div>
<div>
<h4 class="title"><?php echo htmlspecialchars($title); ?></h4>
<p class="description"><?php echo htmlspecialchars($desc); ?></p>
<a href="<?php echo htmlspecialchars($serviceUrl); ?>" class="readmore stretched-link">
<span>了解更多</span><i class="bi bi-arrow-right"></i>
</a>
</div>
</div><!-- End Service Item -->
<?php endforeach; ?>
<?php else: ?>
<div class="col-12 text-center">
<p>暂无服务数据</p>
</div>
</div><!-- End Service Item -->
<div class="col-lg-4 col-md-6 service-item d-flex" data-aos="fade-up" data-aos-delay="500">
<div class="icon flex-shrink-0"><i class="bi bi-brightness-high" style="color: #f5cf13;"></i></div>
<div>
<h4 class="title">Nemo Enim</h4>
<p class="description">At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium
voluptatum deleniti atque</p>
<a href="#" class="readmore stretched-link"><span>了解更多</span><i class="bi bi-arrow-right"></i></a>
</div>
</div><!-- End Service Item -->
<div class="col-lg-4 col-md-6 service-item d-flex" data-aos="fade-up" data-aos-delay="600">
<div class="icon flex-shrink-0"><i class="bi bi-calendar4-week" style="color: #1335f5;"></i></div>
<div>
<h4 class="title">Eiusmod Tempor</h4>
<p class="description">Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum
soluta nobis est eligendi</p>
<a href="#" class="readmore stretched-link"><span>了解更多</span><i class="bi bi-arrow-right"></i></a>
</div>
</div><!-- End Service Item -->
<?php endif; ?>
</div>
@ -314,6 +405,7 @@ require_once __DIR__ . '/header.php';
<div class="container section-title" data-aos="fade-up">
<h2>最新新闻</h2>
<p>LATEST NEWS</p>
</div>
<div class="container">
<div class="row gy-5">

View File

@ -41,7 +41,7 @@ require_once __DIR__ . '/header.php';
<h4>应用 1</h4>
<p>Lorem ipsum, dolor sit amet consectetur</p>
<a href="<?php echo $baseUrl; ?>/themes/template3/assets/img/portfolio/app-1.jpg" title="应用 1" data-gallery="portfolio-gallery-app" class="glightbox preview-link"><i class="bi bi-zoom-in"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details.php" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
</div>
</div><!-- End Portfolio Item -->
@ -51,7 +51,7 @@ require_once __DIR__ . '/header.php';
<h4>产品 1</h4>
<p>Lorem ipsum, dolor sit amet consectetur</p>
<a href="<?php echo $baseUrl; ?>/themes/template3/assets/img/portfolio/product-1.jpg" title="产品 1" data-gallery="portfolio-gallery-product" class="glightbox preview-link"><i class="bi bi-zoom-in"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details.php" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
</div>
</div><!-- End Portfolio Item -->
@ -61,7 +61,7 @@ require_once __DIR__ . '/header.php';
<h4>品牌 1</h4>
<p>Lorem ipsum, dolor sit amet consectetur</p>
<a href="<?php echo $baseUrl; ?>/themes/template3/assets/img/portfolio/branding-1.jpg" title="品牌 1" data-gallery="portfolio-gallery-branding" class="glightbox preview-link"><i class="bi bi-zoom-in"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details.php" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
</div>
</div><!-- End Portfolio Item -->
@ -71,7 +71,7 @@ require_once __DIR__ . '/header.php';
<h4>书籍 1</h4>
<p>Lorem ipsum, dolor sit amet consectetur</p>
<a href="<?php echo $baseUrl; ?>/themes/template3/assets/img/portfolio/books-1.jpg" title="品牌 1" data-gallery="portfolio-gallery-book" class="glightbox preview-link"><i class="bi bi-zoom-in"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details.php" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
</div>
</div><!-- End Portfolio Item -->
@ -81,7 +81,7 @@ require_once __DIR__ . '/header.php';
<h4>应用 2</h4>
<p>Lorem ipsum, dolor sit amet consectetur</p>
<a href="<?php echo $baseUrl; ?>/themes/template3/assets/img/portfolio/app-2.jpg" title="应用 2" data-gallery="portfolio-gallery-app" class="glightbox preview-link"><i class="bi bi-zoom-in"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details.php" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
</div>
</div><!-- End Portfolio Item -->
@ -91,7 +91,7 @@ require_once __DIR__ . '/header.php';
<h4>产品 2</h4>
<p>Lorem ipsum, dolor sit amet consectetur</p>
<a href="<?php echo $baseUrl; ?>/themes/template3/assets/img/portfolio/product-2.jpg" title="产品 2" data-gallery="portfolio-gallery-product" class="glightbox preview-link"><i class="bi bi-zoom-in"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details.php" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
</div>
</div><!-- End Portfolio Item -->
@ -101,7 +101,7 @@ require_once __DIR__ . '/header.php';
<h4>品牌 2</h4>
<p>Lorem ipsum, dolor sit amet consectetur</p>
<a href="<?php echo $baseUrl; ?>/themes/template3/assets/img/portfolio/branding-2.jpg" title="品牌 2" data-gallery="portfolio-gallery-branding" class="glightbox preview-link"><i class="bi bi-zoom-in"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details.php" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
</div>
</div><!-- End Portfolio Item -->
@ -111,7 +111,7 @@ require_once __DIR__ . '/header.php';
<h4>书籍 2</h4>
<p>Lorem ipsum, dolor sit amet consectetur</p>
<a href="<?php echo $baseUrl; ?>/themes/template3/assets/img/portfolio/books-2.jpg" title="品牌 2" data-gallery="portfolio-gallery-book" class="glightbox preview-link"><i class="bi bi-zoom-in"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details.php" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
</div>
</div><!-- End Portfolio Item -->
@ -121,7 +121,7 @@ require_once __DIR__ . '/header.php';
<h4>应用 3</h4>
<p>Lorem ipsum, dolor sit amet consectetur</p>
<a href="<?php echo $baseUrl; ?>/themes/template3/assets/img/portfolio/app-3.jpg" title="应用 3" data-gallery="portfolio-gallery-app" class="glightbox preview-link"><i class="bi bi-zoom-in"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details.php" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
</div>
</div><!-- End Portfolio Item -->
@ -131,7 +131,7 @@ require_once __DIR__ . '/header.php';
<h4>产品 3</h4>
<p>Lorem ipsum, dolor sit amet consectetur</p>
<a href="<?php echo $baseUrl; ?>/themes/template3/assets/img/portfolio/product-3.jpg" title="产品 3" data-gallery="portfolio-gallery-product" class="glightbox preview-link"><i class="bi bi-zoom-in"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details.php" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
</div>
</div><!-- End Portfolio Item -->
@ -141,7 +141,7 @@ require_once __DIR__ . '/header.php';
<h4>品牌 3</h4>
<p>Lorem ipsum, dolor sit amet consectetur</p>
<a href="<?php echo $baseUrl; ?>/themes/template3/assets/img/portfolio/branding-3.jpg" title="品牌 2" data-gallery="portfolio-gallery-branding" class="glightbox preview-link"><i class="bi bi-zoom-in"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details.php" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
</div>
</div><!-- End Portfolio Item -->
@ -151,7 +151,7 @@ require_once __DIR__ . '/header.php';
<h4>书籍 3</h4>
<p>Lorem ipsum, dolor sit amet consectetur</p>
<a href="<?php echo $baseUrl; ?>/themes/template3/assets/img/portfolio/books-3.jpg" title="品牌 3" data-gallery="portfolio-gallery-book" class="glightbox preview-link"><i class="bi bi-zoom-in"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details.php" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
<a href="<?php echo $baseUrl; ?>/portfolio-details" title="更多详情" class="details-link"><i class="bi bi-link-45deg"></i></a>
</div>
</div><!-- End Portfolio Item -->