修复若干bug
This commit is contained in:
parent
7cdb591f69
commit
98156991c1
@ -100,10 +100,13 @@ class MenuController extends BaseController
|
||||
]);
|
||||
}
|
||||
|
||||
// 获取有权限的菜单及其所有父级菜单
|
||||
$allMenuIds = $this->getMenuIdsWithParents($menuIds);
|
||||
|
||||
// 获取有权限的菜单
|
||||
$menus = SystemMenu::where('delete_time', null)
|
||||
->where('status', 1)
|
||||
->whereIn('id', $menuIds)
|
||||
->whereIn('id', $allMenuIds)
|
||||
->field('id,pid,title,path,component_path,icon,sort')
|
||||
->order('sort', 'asc')
|
||||
->select();
|
||||
@ -489,6 +492,41 @@ class MenuController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取菜单ID及其所有父级菜单ID
|
||||
* @param array $menuIds 菜单ID数组
|
||||
* @return array 包含所有父级菜单的ID数组
|
||||
*/
|
||||
private function getMenuIdsWithParents(array $menuIds): array
|
||||
{
|
||||
if (empty($menuIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$allIds = $menuIds;
|
||||
$toCheck = $menuIds;
|
||||
|
||||
while (!empty($toCheck)) {
|
||||
// 查询这些菜单的父级
|
||||
$parents = SystemMenu::whereIn('id', $toCheck)
|
||||
->where('delete_time', null)
|
||||
->column('pid');
|
||||
|
||||
// 过滤掉已经存在的和为0的父ID
|
||||
$newParents = [];
|
||||
foreach ($parents as $pid) {
|
||||
if ($pid > 0 && !in_array($pid, $allIds)) {
|
||||
$newParents[] = $pid;
|
||||
$allIds[] = $pid;
|
||||
}
|
||||
}
|
||||
|
||||
$toCheck = $newParents;
|
||||
}
|
||||
|
||||
return $allIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建菜单树形结构
|
||||
* @param array $menus 菜单列表
|
||||
|
||||
@ -8,6 +8,8 @@ use app\admin\BaseController;
|
||||
use think\response\Json;
|
||||
use app\model\AdminModules;
|
||||
use app\model\System\AdminUserGroup;
|
||||
use app\model\SystemMenu;
|
||||
use Symfony\Component\VarDumper\VarDumper;
|
||||
|
||||
class ModulesController extends BaseController
|
||||
{
|
||||
@ -52,7 +54,6 @@ class ModulesController extends BaseController
|
||||
{
|
||||
try {
|
||||
$userInfo = $this->getAdminUserInfo();
|
||||
|
||||
$groupId = $userInfo['group_id'] ?? null;
|
||||
$menuIds = [];
|
||||
|
||||
@ -76,8 +77,13 @@ class ModulesController extends BaseController
|
||||
]);
|
||||
}
|
||||
|
||||
// 根据子菜单ID查询所有父级模块ID
|
||||
$moduleIds = $this->getModuleIdsByMenuIds($menuIds);
|
||||
|
||||
$modules = AdminModules::where('delete_time', null)
|
||||
->whereIn('mid', $menuIds)
|
||||
->whereIn('id', $moduleIds)
|
||||
->where('status', 1)
|
||||
->where('is_show', 1)
|
||||
->order('sort', 'asc')
|
||||
->order('id', 'asc')
|
||||
->select()
|
||||
@ -386,6 +392,64 @@ class ModulesController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据菜单ID列表获取对应的模块ID列表(包括父级模块)
|
||||
* @param array $menuIds 菜单ID列表(子菜单)
|
||||
* @return array 模块ID列表
|
||||
*/
|
||||
private function getModuleIdsByMenuIds(array $menuIds): array
|
||||
{
|
||||
if (empty($menuIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// 1. 获取所有子菜单及其父级菜单ID
|
||||
$allMenuIds = $this->getMenuIdsWithParents($menuIds);
|
||||
|
||||
// 2. 获取所有匹配的模块(mid在allMenuIds中)
|
||||
$moduleIds = AdminModules::where('delete_time', null)
|
||||
->whereIn('mid', $allMenuIds)
|
||||
->column('id');
|
||||
|
||||
// 去重并返回
|
||||
return array_unique($moduleIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取菜单ID及其所有父级菜单ID
|
||||
* @param array $menuIds 菜单ID数组
|
||||
* @return array 包含所有父级菜单的ID数组
|
||||
*/
|
||||
private function getMenuIdsWithParents(array $menuIds): array
|
||||
{
|
||||
if (empty($menuIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$allIds = $menuIds;
|
||||
$toCheck = $menuIds;
|
||||
|
||||
while (!empty($toCheck)) {
|
||||
// 查询这些菜单的父级
|
||||
$parents = SystemMenu::whereIn('id', $toCheck)
|
||||
->where('delete_time', null)
|
||||
->column('pid');
|
||||
|
||||
// 过滤掉已经存在的和为0的父ID
|
||||
$newParents = [];
|
||||
foreach ($parents as $pid) {
|
||||
if ($pid > 0 && !in_array($pid, $allIds)) {
|
||||
$newParents[] = $pid;
|
||||
$allIds[] = $pid;
|
||||
}
|
||||
}
|
||||
|
||||
$toCheck = $newParents;
|
||||
}
|
||||
|
||||
return $allIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模块选择列表
|
||||
* @return Json
|
||||
|
||||
@ -43,7 +43,9 @@ class RoleController extends BaseController
|
||||
public function getRoleById(int $id)
|
||||
{
|
||||
$role = AdminUserGroup::where('id', $id)
|
||||
->where('tid', $this->getTenantId())
|
||||
->where(function ($query) {
|
||||
$query->where('tid', $this->getTenantId())->whereOr('tid', 0);
|
||||
})
|
||||
->where('delete_time', null)
|
||||
->find();
|
||||
if (!$role) {
|
||||
@ -143,9 +145,11 @@ class RoleController extends BaseController
|
||||
'rights|权限' => 'array'
|
||||
]);
|
||||
|
||||
// 查找角色(验证tid)
|
||||
// 查找角色(验证tid,tid为0的系统角色也可编辑)
|
||||
$role = AdminUserGroup::where('id', $id)
|
||||
->where('tid', $this->getTenantId())
|
||||
->where(function ($query) {
|
||||
$query->where('tid', $this->getTenantId())->whereOr('tid', 0);
|
||||
})
|
||||
->where('delete_time', null)
|
||||
->find();
|
||||
if (!$role) {
|
||||
@ -155,10 +159,12 @@ class RoleController extends BaseController
|
||||
]);
|
||||
}
|
||||
|
||||
// 检查角色名称是否已被其他角色使用
|
||||
// 检查角色名称是否已被其他角色使用(tid为0或当前用户tid的角色)
|
||||
$exists = AdminUserGroup::where('name', $data['name'])
|
||||
->where('id', '<>', $id)
|
||||
->where('tid', $this->getTenantId())
|
||||
->where(function ($query) {
|
||||
$query->where('tid', $this->getTenantId())->whereOr('tid', 0);
|
||||
})
|
||||
->where('delete_time', null)
|
||||
->find();
|
||||
if ($exists) {
|
||||
@ -169,18 +175,23 @@ class RoleController extends BaseController
|
||||
}
|
||||
|
||||
// 更新数据
|
||||
$role->name = $data['name'];
|
||||
$role->status = $data['status'] ?? 1;
|
||||
$role->rights = !empty($data['rights']) ? json_encode($data['rights']) : null;
|
||||
$role->update_time = date('Y-m-d H:i:s');
|
||||
$role->save();
|
||||
$updateData = [
|
||||
'name' => $data['name'],
|
||||
'status' => $data['status'] ?? 1,
|
||||
'rights' => !empty($data['rights']) ? json_encode($data['rights']) : null,
|
||||
'update_time' => date('Y-m-d H:i:s')
|
||||
];
|
||||
AdminUserGroup::where('id', $id)->update($updateData);
|
||||
|
||||
// 重新查询获取最新数据
|
||||
$updatedRole = AdminUserGroup::where('id', $id)->find();
|
||||
|
||||
// 记录操作日志
|
||||
$this->logSuccess('角色管理', '更新角色', ['id' => $id]);
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '更新成功',
|
||||
'data' => $role->toArray()
|
||||
'data' => $updatedRole->toArray()
|
||||
]);
|
||||
} catch (ValidateException $e) {
|
||||
// 记录失败日志
|
||||
|
||||
@ -5,8 +5,9 @@ return [
|
||||
// \think\middleware\CheckRequestCache::class,
|
||||
// 多语言加载
|
||||
// \think\middleware\LoadLangPack::class,
|
||||
// Session初始化
|
||||
// 跨域支持
|
||||
\app\common\middleware\AllowCrossDomain::class,
|
||||
// Session初始化
|
||||
\think\middleware\SessionInit::class,
|
||||
];
|
||||
|
||||
|
||||
@ -15,47 +15,21 @@ class AllowCrossDomain
|
||||
{
|
||||
$origin = $request->header('origin', '');
|
||||
|
||||
$allowedDomains = [
|
||||
'http://localhost:3000',
|
||||
'http://localhost:5000',
|
||||
'http://localhost:8000',
|
||||
'http://127.0.0.1:3000',
|
||||
'http://127.0.0.1:5000',
|
||||
'http://127.0.0.1:8000',
|
||||
'http://localhost:5173',
|
||||
'http://backapi.yunzer.cn',
|
||||
'http://www.yunzer.cn',
|
||||
'https://www.yunzer.cn',
|
||||
'http://yunzer.cn',
|
||||
'https://yunzer.cn',
|
||||
'http://back.yunzer.cn',
|
||||
'https://back.yunzer.cn',
|
||||
'http://backend.yunzer.cn',
|
||||
'https://backend.yunzer.cn',
|
||||
];
|
||||
|
||||
if (in_array($origin, $allowedDomains)) {
|
||||
$header['Access-Control-Allow-Origin'] = $origin;
|
||||
} else {
|
||||
if (!empty($origin)) {
|
||||
$header['Access-Control-Allow-Origin'] = $origin;
|
||||
} else {
|
||||
$header['Access-Control-Allow-Origin'] = '*';
|
||||
}
|
||||
}
|
||||
// 允许所有来源(生产环境建议限制具体域名)
|
||||
$header['Access-Control-Allow-Origin'] = $origin ?: '*';
|
||||
|
||||
if ($request->method() === 'OPTIONS') {
|
||||
$header['Access-Control-Allow-Credentials'] = 'true';
|
||||
$header['Access-Control-Max-Age'] = 1800;
|
||||
$header['Access-Control-Allow-Methods'] = 'GET, POST, PATCH, PUT, DELETE, OPTIONS';
|
||||
$header['Access-Control-Allow-Headers'] = 'Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With';
|
||||
$header['Access-Control-Allow-Headers'] = 'Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With, X-Current-Domain';
|
||||
return response('', 200, $header);
|
||||
}
|
||||
|
||||
$header['Access-Control-Allow-Credentials'] = 'true';
|
||||
$header['Access-Control-Max-Age'] = 1800;
|
||||
$header['Access-Control-Allow-Methods'] = 'GET, POST, PATCH, PUT, DELETE, OPTIONS';
|
||||
$header['Access-Control-Allow-Headers'] = 'Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With';
|
||||
$header['Access-Control-Allow-Headers'] = 'Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With, X-Current-Domain';
|
||||
|
||||
return $next($request)->header($header);
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ use think\App;
|
||||
use think\exception\ValidateException;
|
||||
use think\Validate;
|
||||
use think\Request;
|
||||
use think\facade\Db;
|
||||
|
||||
// 在控制器方法中添加
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
@ -44,6 +45,12 @@ abstract class BaseController
|
||||
*/
|
||||
protected $middleware = [];
|
||||
|
||||
/**
|
||||
* 当前租户ID
|
||||
* @var int
|
||||
*/
|
||||
protected $tenantId = 0;
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
* @access public
|
||||
@ -59,7 +66,48 @@ abstract class BaseController
|
||||
}
|
||||
|
||||
// 初始化
|
||||
protected function initialize() {}
|
||||
protected function initialize()
|
||||
{
|
||||
// 自动检测并设置租户ID
|
||||
$this->initTenantId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化租户ID
|
||||
* 优先从 Referer 获取来源域名,否则使用当前访问域名
|
||||
* 从 mete_tenant_domain 表查询对应的 tid
|
||||
*/
|
||||
protected function initTenantId(): void
|
||||
{
|
||||
// 优先从 Referer 获取来源域名(跨域调用场景)
|
||||
$referer = $this->request->header('Referer');
|
||||
if ($referer) {
|
||||
$host = parse_url($referer, PHP_URL_HOST);
|
||||
} else {
|
||||
// 否则使用当前访问域名
|
||||
$host = $this->request->host(true);
|
||||
}
|
||||
|
||||
// 查询域名对应的租户ID
|
||||
$tenantDomain = Db::name('mete_tenant_domain')
|
||||
->where('full_domain', $host)
|
||||
->where('status', 1)
|
||||
->whereNull('delete_time')
|
||||
->find();
|
||||
|
||||
if ($tenantDomain) {
|
||||
$this->tenantId = (int)$tenantDomain['tid'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前租户ID
|
||||
* @return int
|
||||
*/
|
||||
protected function getTenantId(): int
|
||||
{
|
||||
return $this->tenantId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证数据
|
||||
|
||||
@ -12,257 +12,46 @@ use think\facade\Session;
|
||||
use think\response\Json;
|
||||
use think\db\exception\DbException;
|
||||
|
||||
use app\model\Articles;
|
||||
use app\model\ArticlesCategory;
|
||||
use app\model\Cms\Articles;
|
||||
use app\model\Cms\ArticlesCategory;
|
||||
|
||||
|
||||
class NewsCenterController extends BaseController
|
||||
{
|
||||
/**
|
||||
* 根据分类获取文章
|
||||
* @param string $category 分类名称
|
||||
* 根据域名获取新闻数据
|
||||
* @return Json
|
||||
*/
|
||||
public function getNewsByCategory(string $category): Json
|
||||
public function getCenterNews(): Json
|
||||
{
|
||||
// 查询分类
|
||||
$categoryInfo = ArticlesCategory::where('name', $category)
|
||||
->where('delete_time', null)
|
||||
->find();
|
||||
// 从 BaseController 获取当前租户ID
|
||||
$tid = $this->getTenantId();
|
||||
|
||||
if (!$categoryInfo) {
|
||||
if (empty($tid)) {
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => 'success',
|
||||
'code' => 400,
|
||||
'msg' => '无法识别租户信息',
|
||||
'list' => [],
|
||||
]);
|
||||
}
|
||||
|
||||
// 查询文章
|
||||
// 查询该租户下的文章
|
||||
$articles = Articles::published()
|
||||
->where('cate', $categoryInfo['id'])
|
||||
->where('tid', $tid)
|
||||
->where('delete_time', null)
|
||||
->order('publish_date', 'desc')
|
||||
->limit(4)
|
||||
->limit(8)
|
||||
->select();
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => 'success',
|
||||
'list' => $articles,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取企业新闻
|
||||
* @return Json
|
||||
*/
|
||||
public function getCompanyNews(): Json
|
||||
{
|
||||
// 获取分页参数
|
||||
$page = Request::param('page', 1);
|
||||
$limit = Request::param('limit', 10);
|
||||
$page = max(1, intval($page));
|
||||
$limit = max(1, min(50, intval($limit))); // 限制每页最多50条
|
||||
|
||||
// 查询分类
|
||||
$categoryInfo = ArticlesCategory::where('name', '企业新闻')
|
||||
->where('delete_time', null)
|
||||
->find();
|
||||
|
||||
if (!$categoryInfo) {
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => 'success',
|
||||
'list' => [],
|
||||
'total' => 0,
|
||||
'page' => $page,
|
||||
'limit' => $limit,
|
||||
]);
|
||||
}
|
||||
|
||||
// 查询总数
|
||||
$total = Articles::where('cate', $categoryInfo['id'])
|
||||
->where('delete_time', null)
|
||||
->where('status', 2)
|
||||
->count();
|
||||
|
||||
// 查询文章
|
||||
$articles = Articles::where('cate', $categoryInfo['id'])
|
||||
->where('delete_time', null)
|
||||
->where('status', 2)
|
||||
->order('top', 'desc')
|
||||
->order('recommend', 'desc')
|
||||
->order('sort', 'desc')
|
||||
->order('publish_date', 'desc')
|
||||
->page($page, $limit)
|
||||
->select();
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => 'success',
|
||||
'list' => $articles,
|
||||
'total' => $total,
|
||||
'page' => $page,
|
||||
'limit' => $limit,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取金蝶新闻
|
||||
* @return Json
|
||||
*/
|
||||
public function getKingdeeNews(): Json
|
||||
{
|
||||
// 获取分页参数
|
||||
$page = Request::param('page', 1);
|
||||
$limit = Request::param('limit', 10);
|
||||
$page = max(1, intval($page));
|
||||
$limit = max(1, min(50, intval($limit))); // 限制每页最多50条
|
||||
|
||||
// 查询分类
|
||||
$categoryInfo = ArticlesCategory::where('name', '金蝶新闻')
|
||||
->where('delete_time', null)
|
||||
->find();
|
||||
|
||||
if (!$categoryInfo) {
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => 'success',
|
||||
'list' => [],
|
||||
'total' => 0,
|
||||
'page' => $page,
|
||||
'limit' => $limit,
|
||||
]);
|
||||
}
|
||||
|
||||
// 查询总数
|
||||
$total = Articles::where('cate', $categoryInfo['id'])
|
||||
->where('delete_time', null)
|
||||
->where('status', 2)
|
||||
->count();
|
||||
|
||||
// 查询文章
|
||||
$articles = Articles::where('cate', $categoryInfo['id'])
|
||||
->where('delete_time', null)
|
||||
->where('status', 2)
|
||||
->order('top', 'desc')
|
||||
->order('recommend', 'desc')
|
||||
->order('sort', 'desc')
|
||||
->order('publish_date', 'desc')
|
||||
->page($page, $limit)
|
||||
->select();
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => 'success',
|
||||
'list' => $articles,
|
||||
'total' => $total,
|
||||
'page' => $page,
|
||||
'limit' => $limit,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取技术中心子分类
|
||||
* @return Json
|
||||
*/
|
||||
public function getTechnologyCategories(): Json
|
||||
{
|
||||
// 获取"技术中心"主分类
|
||||
$parentCategory = ArticlesCategory::where('name', '技术中心')
|
||||
->where('delete_time', null)
|
||||
->find();
|
||||
|
||||
if (!$parentCategory) {
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => 'success',
|
||||
'data' => []
|
||||
]);
|
||||
}
|
||||
|
||||
// 查找所有子分类
|
||||
$subCategories = ArticlesCategory::where('cid', $parentCategory['id'])
|
||||
->where('delete_time', null)
|
||||
->field('id,name,desc,sort,image')
|
||||
->order('sort', 'desc')
|
||||
->select();
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => 'success',
|
||||
'data' => $subCategories
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取技术中心
|
||||
* @return Json
|
||||
*/
|
||||
public function getTechnologyCenter(): Json
|
||||
{
|
||||
// 1. 分页参数规范化
|
||||
$page = max(1, intval(Request::param('page', 1)));
|
||||
$limit = max(1, min(50, intval(Request::param('limit', 10))));
|
||||
|
||||
// 获取分类ID参数(可选)
|
||||
$categoryId = Request::param('category_id', null);
|
||||
|
||||
// 2. 第一步:获取“技术中心”主分类的 id
|
||||
$parentCategory = ArticlesCategory::where('name', '技术中心')
|
||||
->where('delete_time', null)
|
||||
->find();
|
||||
|
||||
// print_r($parentCategory['id']);
|
||||
|
||||
if (!$parentCategory) {
|
||||
return $this->emptyResponse($page, $limit);
|
||||
}
|
||||
|
||||
// 3. 第二步:查找 cid 等于主分类 id 的所有子分类 id
|
||||
$subCategoryQuery = ArticlesCategory::where('cid', $parentCategory['id'])
|
||||
->where('delete_time', null);
|
||||
|
||||
// print_r($subCategoryQuery->select());
|
||||
|
||||
// 如果指定了分类ID,则只查询该分类
|
||||
if ($categoryId) {
|
||||
$subCategoryQuery->where('id', $categoryId);
|
||||
}
|
||||
|
||||
$subCategoryIds = $subCategoryQuery->column('id');
|
||||
|
||||
// print_r($subCategoryIds);
|
||||
|
||||
if (empty($subCategoryIds)) {
|
||||
return $this->emptyResponse($page, $limit);
|
||||
}
|
||||
|
||||
// 5. 第三步:查询 Articles 表,并限定字段
|
||||
$articleQuery = Articles::whereIn('cate', $subCategoryIds)
|
||||
->where('delete_time', null)
|
||||
->where('status', 2);
|
||||
|
||||
// 获取总数
|
||||
$total = (clone $articleQuery)->count();
|
||||
|
||||
// 获取列表:限定返回 id, title, desc, publish_date, image, likes, views
|
||||
$articles = $articleQuery->field('id,title,desc,publish_date,image,likes,views,cate')
|
||||
->order([
|
||||
'top' => 'desc',
|
||||
'recommend' => 'desc',
|
||||
'sort' => 'desc',
|
||||
'publish_date' => 'desc'
|
||||
])
|
||||
->page($page, $limit)
|
||||
->select();
|
||||
|
||||
// 如果文章没有image,查询对应分类的image
|
||||
$categoryImages = ArticlesCategory::whereIn('id', $subCategoryIds)->column('image', 'id');
|
||||
|
||||
// 处理图片:如果文章image为空,则取分类的image
|
||||
foreach ($articles as &$article) {
|
||||
if (empty($article['image']) && isset($categoryImages[$article['cate']])) {
|
||||
$article['image'] = $categoryImages[$article['cate']];
|
||||
if (empty($article['image']) && !empty($article['cate'])) {
|
||||
$category = ArticlesCategory::where('id', $article['cate'])
|
||||
->where('delete_time', null)
|
||||
->find();
|
||||
if ($category && !empty($category['image'])) {
|
||||
$article['image'] = $category['image'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,92 +59,9 @@ class NewsCenterController extends BaseController
|
||||
'code' => 200,
|
||||
'msg' => 'success',
|
||||
'list' => $articles,
|
||||
'total' => $total,
|
||||
'page' => $page,
|
||||
'limit' => $limit,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一空返回
|
||||
*/
|
||||
private function emptyResponse($page, $limit): Json
|
||||
{
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => 'success',
|
||||
'list' => [],
|
||||
'total' => 0,
|
||||
'page' => $page,
|
||||
'limit' => $limit,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取金蝶新闻详情
|
||||
*/
|
||||
public function getKingdeeNewsDetail(int $id): Json
|
||||
{
|
||||
$article = Articles::where('id', $id)
|
||||
->where('delete_time', null)
|
||||
->where('status', 2)
|
||||
->field('id,title,cate,image,desc,author,content,publisher,publish_date,views,likes,is_trans,transurl')
|
||||
->find();
|
||||
|
||||
if (!$article) {
|
||||
return json(['code' => 404, 'msg' => '文章不存在', 'data' => null]);
|
||||
}
|
||||
|
||||
$cate = (int) $article['cate'];
|
||||
|
||||
// 转换为数组再处理
|
||||
$articleData = $article->toArray();
|
||||
// $articleData['catename'] = $this->getCategoryName($cate);
|
||||
|
||||
// 获取相关文章
|
||||
$articleData['relatedArticles'] = $this->getRelatedArticles($id, $cate);
|
||||
|
||||
// 获取上一篇下一篇
|
||||
$articleData['nextPreviousArticles'] = $this->getNextPreviousArticles($id, $cate);
|
||||
|
||||
// 增加浏览量
|
||||
Articles::where('id', $id)->inc('views')->update();
|
||||
|
||||
return json(['code' => 200, 'msg' => 'success', 'data' => $articleData]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取企业新闻详情
|
||||
*/
|
||||
public function getCompanyNewsDetail(int $id): Json
|
||||
{
|
||||
$article = Articles::where('id', $id)
|
||||
->where('delete_time', null)
|
||||
->where('status', 2)
|
||||
->find();
|
||||
|
||||
if (!$article) {
|
||||
return json(['code' => 404, 'msg' => '文章不存在', 'data' => null]);
|
||||
}
|
||||
|
||||
$cate = (int) $article['cate'];
|
||||
|
||||
// 转换为数组再处理
|
||||
$articleData = $article->toArray();
|
||||
$articleData['catename'] = $this->getCategoryName($cate);
|
||||
|
||||
// 获取相关文章
|
||||
$articleData['relatedArticles'] = $this->getRelatedArticles($id, $cate);
|
||||
|
||||
// 获取上一篇下一篇
|
||||
$articleData['nextPreviousArticles'] = $this->getNextPreviousArticles($id, $cate);
|
||||
|
||||
// 增加浏览量
|
||||
Articles::where('id', $id)->inc('views')->update();
|
||||
|
||||
return json(['code' => 200, 'msg' => 'success', 'data' => $articleData]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上一篇下一篇
|
||||
* @param int $id 文章ID
|
||||
|
||||
@ -34,7 +34,8 @@ class Index extends BaseController
|
||||
|
||||
// 兼容:从header获取
|
||||
if ($tid == 0) {
|
||||
$tid = (int)$request->header('X-Tenant-Id', 0);
|
||||
$headerTid = $request->header('X-Tenant-Id');
|
||||
$tid = $headerTid ? (int)$headerTid : 0;
|
||||
}
|
||||
|
||||
// 调试:检查tid
|
||||
|
||||
@ -11,27 +11,10 @@ Route::get('init', 'app\index\controller\Index@init');
|
||||
// --- 前端底部数据路由 ---
|
||||
Route::get('footerdata', 'app\index\controller\Index@getFooterData');
|
||||
|
||||
// --- 文章详情路由 ---
|
||||
Route::get('kingdeenews/detail/:id', 'app\index\controller\Article\NewsCenterController@getKingdeeNewsDetail');
|
||||
Route::get('companynews/detail/:id', 'app\index\controller\Article\NewsCenterController@getCompanyNewsDetail');
|
||||
|
||||
// --- 文章列表路由 ---
|
||||
Route::get('kingdeenews$', 'app\index\controller\Article\NewsCenterController@getKingdeeNews');
|
||||
Route::get('companynews$', 'app\index\controller\Article\NewsCenterController@getCompanyNews');
|
||||
Route::get('technologyCenter$', 'app\index\controller\Article\NewsCenterController@getTechnologyCenter');
|
||||
Route::get('technologyCategories$', 'app\index\controller\Article\NewsCenterController@getTechnologyCategories');
|
||||
Route::get('newscentertop4', 'app\index\controller\Article\ArticleController@getNewsCenterTop4');
|
||||
Route::get('newsbycategory/:category', 'app\index\controller\Article\NewsCenterController@getNewsByCategory');
|
||||
Route::get('getCenterNews', 'app\index\controller\Article\NewsCenterController@getCenterNews');
|
||||
|
||||
// --- 文章互动路由 ---
|
||||
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');
|
||||
|
||||
// --- 前端导航与单页路由 ---
|
||||
Route::get('headmenu', 'app\index\controller\Index@getHeadMenu');
|
||||
Route::rule('onepage/:path', 'app\index\controller\Index@getOnePageByPath', 'GET')->pattern(['path' => '.*']);
|
||||
|
||||
// --- 日志相关路由 ---
|
||||
Route::get('index/getLogs', 'app\index\controller\Index@getLogs');
|
||||
Route::get('getLogs', 'app\index\controller\Index@getLogs');
|
||||
9
public/themes/default/assets/css/all.min.css
vendored
Normal file
9
public/themes/default/assets/css/all.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
6
public/themes/default/assets/js/all.min.js
vendored
Normal file
6
public/themes/default/assets/js/all.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,20 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="no-js" lang="">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge" />
|
||||
<title>Nova - Bootstrap 5 Template</title>
|
||||
<meta name="description" content="" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<!-- Place favicon.ico in the root directory -->
|
||||
|
||||
<!-- ========================= CSS here ========================= -->
|
||||
<link rel="stylesheet" href="assets/css/bootstrap-5.0.0-beta1.min.css" />
|
||||
<link rel="stylesheet" href="assets/css/LineIcons.2.0.css" />
|
||||
<link rel="stylesheet" href="assets/css/tiny-slider.css" />
|
||||
<link rel="stylesheet" href="assets/css/animate.css" />
|
||||
<link rel="stylesheet" href="assets/css/lindy-uikit.css" />
|
||||
<link rel="stylesheet" href="assets/css/all.min.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!--[if lte IE 9]>
|
||||
<p class="browserupgrade">
|
||||
@ -24,7 +24,6 @@
|
||||
</p>
|
||||
<![endif]-->
|
||||
|
||||
<!-- ========================= preloader start ========================= -->
|
||||
<div class="preloader">
|
||||
<div class="loader">
|
||||
<div class="spinner">
|
||||
@ -41,12 +40,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ========================= preloader end ========================= -->
|
||||
|
||||
<!-- ========================= hero-section-wrapper-5 start ========================= -->
|
||||
<section id="home" class="hero-section-wrapper-5">
|
||||
|
||||
<!-- ========================= header-6 start ========================= -->
|
||||
<header class="header header-6">
|
||||
<div class="navbar-area">
|
||||
<div class="container">
|
||||
@ -65,42 +59,29 @@
|
||||
<div class="collapse navbar-collapse sub-menu-bar" id="navbarSupportedContent6">
|
||||
<ul id="nav6" class="navbar-nav ms-auto">
|
||||
<li class="nav-item">
|
||||
<a class="page-scroll active" href="#home">Home</a>
|
||||
<a class="page-scroll active" href="#home">主页</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="page-scroll" href="#feature">Feature</a>
|
||||
<a class="page-scroll" href="#feature">文章中心</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="page-scroll" href="#about">About</a>
|
||||
<a class="page-scroll" href="#about">关于我们</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="page-scroll" href="#pricing">Pricing</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="page-scroll" href="#contact">Contact</a>
|
||||
<a class="page-scroll" href="#contact">联系我们</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="header-action d-flex">
|
||||
<a href="#0"> <i class="lni lni-cart"></i> </a>
|
||||
<a href="#0"> <i class="lni lni-alarm"></i> </a>
|
||||
</div>
|
||||
<!-- navbar collapse -->
|
||||
</nav>
|
||||
<!-- navbar -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- row -->
|
||||
</div>
|
||||
<!-- container -->
|
||||
</div>
|
||||
<!-- navbar area -->
|
||||
</header>
|
||||
<!-- ========================= header-6 end ========================= -->
|
||||
|
||||
<!-- ========================= hero-5 start ========================= -->
|
||||
<div class="hero-section hero-style-5 img-bg" style="background-image: url('assets/img/hero/hero-5/hero-bg.svg')">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@ -119,115 +100,23 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ========================= hero-5 end ========================= -->
|
||||
|
||||
</section>
|
||||
<!-- ========================= hero-section-wrapper-6 end ========================= -->
|
||||
|
||||
<!-- ========================= feature style-5 start ========================= -->
|
||||
<section id="feature" class="feature-section feature-style-5">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-xxl-5 col-xl-5 col-lg-7 col-md-8">
|
||||
<div class="section-title text-center mb-60">
|
||||
<h3 class="mb-15 wow fadeInUp" data-wow-delay=".2s">Specializing In</h3>
|
||||
<p class="wow fadeInUp" data-wow-delay=".4s">Stop wasting time and money designing and managing a website that doesn’t get results. Happiness guaranteed!</p>
|
||||
<h3 class="mb-15 wow fadeInUp" data-wow-delay=".2s">文章中心</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="single-feature wow fadeInUp" data-wow-delay=".2s">
|
||||
<div class="icon">
|
||||
<i class="lni lni-vector"></i>
|
||||
<svg width="110" height="72" viewBox="0 0 110 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M110 54.7589C110 85.0014 85.3757 66.2583 55 66.2583C24.6243 66.2583 0 85.0014 0 54.7589C0 24.5164 24.6243 0 55 0C85.3757 0 110 24.5164 110 54.7589Z" fill="#EBF4FF"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h5>Graphics Design</h5>
|
||||
<p>Short description for the ones who look for something new.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="single-feature wow fadeInUp" data-wow-delay=".4s">
|
||||
<div class="icon">
|
||||
<i class="lni lni-pallet"></i>
|
||||
<svg width="110" height="72" viewBox="0 0 110 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M110 54.7589C110 85.0014 85.3757 66.2583 55 66.2583C24.6243 66.2583 0 85.0014 0 54.7589C0 24.5164 24.6243 0 55 0C85.3757 0 110 24.5164 110 54.7589Z" fill="#EBF4FF"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h5>Print Design</h5>
|
||||
<p>Short description for the ones who look for something new.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="single-feature wow fadeInUp" data-wow-delay=".6s">
|
||||
<div class="icon">
|
||||
<i class="lni lni-stats-up"></i>
|
||||
<svg width="110" height="72" viewBox="0 0 110 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M110 54.7589C110 85.0014 85.3757 66.2583 55 66.2583C24.6243 66.2583 0 85.0014 0 54.7589C0 24.5164 24.6243 0 55 0C85.3757 0 110 24.5164 110 54.7589Z" fill="#EBF4FF"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h5>Business Analysis</h5>
|
||||
<p>Short description for the ones who look for something new.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="single-feature wow fadeInUp" data-wow-delay=".2s">
|
||||
<div class="icon">
|
||||
<i class="lni lni-code-alt"></i>
|
||||
<svg width="110" height="72" viewBox="0 0 110 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M110 54.7589C110 85.0014 85.3757 66.2583 55 66.2583C24.6243 66.2583 0 85.0014 0 54.7589C0 24.5164 24.6243 0 55 0C85.3757 0 110 24.5164 110 54.7589Z" fill="#EBF4FF"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h5>Web Development</h5>
|
||||
<p>Short description for the ones who look for something new.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="single-feature wow fadeInUp" data-wow-delay=".4s">
|
||||
<div class="icon">
|
||||
<i class="lni lni-lock"></i>
|
||||
<svg width="110" height="72" viewBox="0 0 110 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M110 54.7589C110 85.0014 85.3757 66.2583 55 66.2583C24.6243 66.2583 0 85.0014 0 54.7589C0 24.5164 24.6243 0 55 0C85.3757 0 110 24.5164 110 54.7589Z" fill="#EBF4FF"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h5>Best Security</h5>
|
||||
<p>Short description for the ones who look for something new.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="single-feature wow fadeInUp" data-wow-delay=".6s">
|
||||
<div class="icon">
|
||||
<i class="lni lni-code"></i>
|
||||
<svg width="110" height="72" viewBox="0 0 110 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M110 54.7589C110 85.0014 85.3757 66.2583 55 66.2583C24.6243 66.2583 0 85.0014 0 54.7589C0 24.5164 24.6243 0 55 0C85.3757 0 110 24.5164 110 54.7589Z" fill="#EBF4FF"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h5>Web Design</h5>
|
||||
<p>Short description for the ones who look for something new.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" id="news-container">
|
||||
<!-- 卡片将通过 JavaScript 动态加载 -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
<!-- ========================= feature style-5 end ========================= -->
|
||||
|
||||
<!-- ========================= about style-4 start ========================= -->
|
||||
<section id="about" class="about-section about-style-4">
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
@ -262,9 +151,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- ========================= about style-4 end ========================= -->
|
||||
|
||||
<!-- ========================= pricing style-4 start ========================= -->
|
||||
<section id="pricing" class="pricing-section pricing-style-4 bg-light">
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
@ -326,9 +212,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- ========================= pricing style-4 end ========================= -->
|
||||
|
||||
<!-- ========================= contact-style-3 start ========================= -->
|
||||
<section id="contact" class="contact-section contact-style-3">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
@ -427,9 +310,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- ========================= contact-style-3 end ========================= -->
|
||||
|
||||
<!-- ========================= clients-logo start ========================= -->
|
||||
<section class="clients-logo-section pt-100 pb-100">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@ -441,9 +321,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- ========================= clients-logo end ========================= -->
|
||||
|
||||
<!-- ========================= footer style-4 start ========================= -->
|
||||
<footer class="footer footer-style-4">
|
||||
<div class="container">
|
||||
<div class="widget-wrapper">
|
||||
@ -455,28 +332,27 @@
|
||||
</div>
|
||||
<p class="desc">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Facilisis nulla placerat amet amet congue.</p>
|
||||
<ul class="socials">
|
||||
<li> <a href="#0"> <i class="lni lni-facebook-filled"></i> </a> </li>
|
||||
<li> <a href="#0"> <i class="lni lni-twitter-filled"></i> </a> </li>
|
||||
<li> <a href="#0"> <i class="lni lni-instagram-filled"></i> </a> </li>
|
||||
<li> <a href="#0"> <i class="lni lni-linkedin-original"></i> </a> </li>
|
||||
<li> <a href="#0"> <i class="fa-brands fa-qq"></i> </a> </li>
|
||||
<li> <a href="#0"> <i class="fa-brands fa-weixin"></i> </a> </li>
|
||||
<li> <a href="#0"> <i class="fa-brands fa-weibo"></i> </a> </li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-2 offset-xl-1 col-lg-2 col-md-6 col-sm-6">
|
||||
<div class="footer-widget wow fadeInUp" data-wow-delay=".3s">
|
||||
<h6>Quick Link</h6>
|
||||
<h6>快捷链接</h6>
|
||||
<ul class="links">
|
||||
<li> <a href="#0">Home</a> </li>
|
||||
<li> <a href="#0">About</a> </li>
|
||||
<li> <a href="#0">Service</a> </li>
|
||||
<li> <a href="#0">Testimonial</a> </li>
|
||||
<li> <a href="#0">Contact</a> </li>
|
||||
<li> <a href="#0">主页</a> </li>
|
||||
<li> <a href="#0">关于我们</a> </li>
|
||||
<li> <a href="#0">服务</a> </li>
|
||||
<li> <a href="#0">客户评价</a> </li>
|
||||
<li> <a href="#0">联系</a> </li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-lg-3 col-md-6 col-sm-6">
|
||||
<div class="footer-widget wow fadeInUp" data-wow-delay=".4s">
|
||||
<h6>Services</h6>
|
||||
<h6>服务</h6>
|
||||
<ul class="links">
|
||||
<li> <a href="#0">Web Design</a> </li>
|
||||
<li> <a href="#0">Web Development</a> </li>
|
||||
@ -487,7 +363,7 @@
|
||||
</div>
|
||||
<div class="col-xl-3 col-lg-3 col-md-6">
|
||||
<div class="footer-widget wow fadeInUp" data-wow-delay=".5s">
|
||||
<h6>Download App</h6>
|
||||
<h6>软件下载</h6>
|
||||
<ul class="download-app">
|
||||
<li>
|
||||
<a href="#0">
|
||||
@ -507,21 +383,175 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="copyright-wrapper wow fadeInUp" data-wow-delay=".2s">
|
||||
<p>Design and Developed by <a href="https://uideck.com" rel="nofollow" target="_blank">UIdeck</a> Built-with <a href="https://uideck.com" rel="nofollow" target="_blank">Lindy UI Kit</a>. Distributed by <a href="https://themewagon.com" target="_blank">ThemeWagon</a></p>
|
||||
<p>Design and Developed by <a href="https://www.yunzer.cn" rel="nofollow" target="_blank">云泽网</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<!-- ========================= footer style-4 end ========================= -->
|
||||
|
||||
<!-- ========================= scroll-top start ========================= -->
|
||||
<a href="#" class="scroll-top"> <i class="lni lni-chevron-up"></i> </a>
|
||||
<!-- ========================= scroll-top end ========================= -->
|
||||
|
||||
|
||||
<!-- ========================= JS here ========================= -->
|
||||
<script src="assets/js/bootstrap-5.0.0-beta1.min.js"></script>
|
||||
<script src="assets/js/tiny-slider.js"></script>
|
||||
<script src="assets/js/wow.min.js"></script>
|
||||
<script src="assets/js/main.js"></script>
|
||||
<script src="assets/js/all.min.js"></script>
|
||||
|
||||
<!-- 加载新闻数据 -->
|
||||
<script>
|
||||
// API 接口地址配置
|
||||
const API_BASE_URL = 'https://api.yunzer.cn';
|
||||
|
||||
// 去除 HTML 标签,提取纯文本
|
||||
function stripHtml(html) {
|
||||
if (!html) return '';
|
||||
// 先替换所有 HTML 标签为空格
|
||||
var text = html.replace(/<[^>]+>/g, ' ');
|
||||
// 替换多个空格为单个空格
|
||||
text = text.replace(/\s+/g, ' ');
|
||||
// 去除首尾空格
|
||||
return text.trim();
|
||||
}
|
||||
|
||||
// 获取完整图片地址
|
||||
function getFullImageUrl(imagePath) {
|
||||
if (!imagePath) return '';
|
||||
// 如果已经是完整 URL,直接返回
|
||||
if (imagePath.startsWith('http://') || imagePath.startsWith('https://')) {
|
||||
return imagePath;
|
||||
}
|
||||
// 拼接完整 URL
|
||||
return API_BASE_URL + (imagePath.startsWith('/') ? imagePath : '/' + imagePath);
|
||||
}
|
||||
|
||||
// 页面加载完成后执行
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const container = document.getElementById('news-container');
|
||||
if (!container) return;
|
||||
|
||||
// 请求数据(后端从 Referer 自动识别租户域名)
|
||||
fetch(API_BASE_URL + '/getCenterNews')
|
||||
.then(res => res.json())
|
||||
.then(result => {
|
||||
if (result.code !== 200 || !result.list || result.list.length === 0) {
|
||||
container.innerHTML = '<p style="text-align:center;width:100%">暂无新闻</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
let html = '';
|
||||
|
||||
result.list.forEach((item, i) => {
|
||||
const title = item.title || '无标题';
|
||||
let desc = item.summary || item.description || '';
|
||||
// 去除 HTML 标签后截取
|
||||
if (!desc && item.content) {
|
||||
desc = stripHtml(item.content);
|
||||
}
|
||||
if (!desc) desc = '暂无描述';
|
||||
|
||||
// 获取缩略图地址(优先使用 thumb,其次使用 image)
|
||||
const thumbUrl = getFullImageUrl(item.thumb || item.image);
|
||||
const thumbHtml = thumbUrl ?
|
||||
'<img src="' + thumbUrl + '" alt="' + title + '" class="news-thumb">' :
|
||||
'<div class="news-thumb-placeholder">暂无图片</div>';
|
||||
|
||||
html += '<div class="col-lg-3 col-md-6 mb-4">' +
|
||||
'<div class="news-card wow fadeInUp" data-wow-delay=".2s">' +
|
||||
'<div class="news-thumb-wrap">' +
|
||||
thumbHtml +
|
||||
'</div>' +
|
||||
'<div class="news-body">' +
|
||||
'<h5 class="news-title">' + title + '</h5>' +
|
||||
'<p class="news-desc">' + desc + '</p>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
});
|
||||
|
||||
container.innerHTML = html;
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('加载失败:', err);
|
||||
container.innerHTML = '<p style="text-align:center;width:100%">加载失败</p>';
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- 新闻卡片样式 -->
|
||||
<style>
|
||||
|
||||
.news-card {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.news-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.news-thumb-wrap {
|
||||
width: 100%;
|
||||
height: 160px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.news-thumb {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.news-thumb-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #f0f0f0;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.news-body {
|
||||
padding: 16px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.news-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 8px;
|
||||
color: #333;
|
||||
/* 显示2行,超出省略 */
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
min-height: 44px;
|
||||
}
|
||||
|
||||
.news-desc {
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
color: #666;
|
||||
margin: 0;
|
||||
/* 显示2行,超出省略 */
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
min-height: 42px;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
243
public/themes/template2/assets/css/fontgoogle.css
Normal file
243
public/themes/template2/assets/css/fontgoogle.css
Normal file
@ -0,0 +1,243 @@
|
||||
/* devanagari */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 100;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiGyp8kv8JHgFVrLPTucXtAKPY.woff2) format('woff2');
|
||||
unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0, U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 100;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiGyp8kv8JHgFVrLPTufntAKPY.woff2) format('woff2');
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 100;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiGyp8kv8JHgFVrLPTucHtA.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* devanagari */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 200;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLFj_Z11lFc-K.woff2) format('woff2');
|
||||
unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0, U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 200;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLFj_Z1JlFc-K.woff2) format('woff2');
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 200;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLFj_Z1xlFQ.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* devanagari */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLDz8Z11lFc-K.woff2) format('woff2');
|
||||
unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0, U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLDz8Z1JlFc-K.woff2) format('woff2');
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLDz8Z1xlFQ.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* devanagari */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiEyp8kv8JHgFVrJJbecmNE.woff2) format('woff2');
|
||||
unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0, U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiEyp8kv8JHgFVrJJnecmNE.woff2) format('woff2');
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiEyp8kv8JHgFVrJJfecg.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* devanagari */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLGT9Z11lFc-K.woff2) format('woff2');
|
||||
unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0, U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLGT9Z1JlFc-K.woff2) format('woff2');
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLGT9Z1xlFQ.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* devanagari */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLEj6Z11lFc-K.woff2) format('woff2');
|
||||
unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0, U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLEj6Z1JlFc-K.woff2) format('woff2');
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLEj6Z1xlFQ.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* devanagari */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLCz7Z11lFc-K.woff2) format('woff2');
|
||||
unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0, U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLCz7Z1JlFc-K.woff2) format('woff2');
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLCz7Z1xlFQ.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* devanagari */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLDD4Z11lFc-K.woff2) format('woff2');
|
||||
unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0, U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLDD4Z1JlFc-K.woff2) format('woff2');
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLDD4Z1xlFQ.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* devanagari */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLBT5Z11lFc-K.woff2) format('woff2');
|
||||
unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0, U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLBT5Z1JlFc-K.woff2) format('woff2');
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
font-display: swap;
|
||||
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiByp8kv8JHgFVrLBT5Z1xlFQ.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
13
public/themes/template2/assets/css/swiper-bundle.min.css
vendored
Normal file
13
public/themes/template2/assets/css/swiper-bundle.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,24 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet">
|
||||
<link href="/themes/template2/assets/css/fontgoogle.css" rel="stylesheet">
|
||||
|
||||
<title>Lugx Gaming Shop HTML5 Template</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
<link href="vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="/themes/template2/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
||||
|
||||
|
||||
<!-- Additional CSS Files -->
|
||||
<link rel="stylesheet" href="assets/css/fontawesome.css">
|
||||
<link rel="stylesheet" href="assets/css/templatemo-lugx-gaming.css">
|
||||
<link rel="stylesheet" href="assets/css/owl.css">
|
||||
<link rel="stylesheet" href="assets/css/animate.css">
|
||||
<link rel="stylesheet"href="https://unpkg.com/swiper@7/swiper-bundle.min.css"/>
|
||||
<link rel="stylesheet" href="/themes/template2/assets/css/fontawesome.css">
|
||||
<link rel="stylesheet" href="/themes/template2/assets/css/templatemo-lugx-gaming.css">
|
||||
<link rel="stylesheet" href="/themes/template2/assets/css/owl.css">
|
||||
<link rel="stylesheet" href="/themes/template2/assets/css/animate.css">
|
||||
<link rel="stylesheet" href="/themes/template2/assets/css/swiper-bundle.min.css"/>
|
||||
<!--
|
||||
|
||||
TemplateMo 589 lugx gaming
|
||||
@ -51,7 +50,7 @@ https://templatemo.com/tm-589-lugx-gaming
|
||||
<nav class="main-nav">
|
||||
<!-- ***** Logo Start ***** -->
|
||||
<a href="index.html" class="logo">
|
||||
<img src="assets/images/logo.png" alt="" style="width: 158px;">
|
||||
<img src="/themes/template2/assets/images/logo.png" alt="" style="width: 158px;">
|
||||
</a>
|
||||
<!-- ***** Logo End ***** -->
|
||||
<!-- ***** Menu Start ***** -->
|
||||
@ -91,7 +90,7 @@ https://templatemo.com/tm-589-lugx-gaming
|
||||
</div>
|
||||
<div class="col-lg-4 offset-lg-2">
|
||||
<div class="right-image">
|
||||
<img src="assets/images/banner-image.jpg" alt="">
|
||||
<img src="/themes/template2/assets/images/banner-image.jpg" alt="">
|
||||
<span class="price">$22</span>
|
||||
<span class="offer">-40%</span>
|
||||
</div>
|
||||
@ -107,7 +106,7 @@ https://templatemo.com/tm-589-lugx-gaming
|
||||
<a href="#">
|
||||
<div class="item">
|
||||
<div class="image">
|
||||
<img src="assets/images/featured-01.png" alt="" style="max-width: 44px;">
|
||||
<img src="/themes/template2/assets/images/featured-01.png" alt="" style="max-width: 44px;">
|
||||
</div>
|
||||
<h4>Free Storage</h4>
|
||||
</div>
|
||||
@ -117,7 +116,7 @@ https://templatemo.com/tm-589-lugx-gaming
|
||||
<a href="#">
|
||||
<div class="item">
|
||||
<div class="image">
|
||||
<img src="assets/images/featured-02.png" alt="" style="max-width: 44px;">
|
||||
<img src="/themes/template2/assets/images/featured-02.png" alt="" style="max-width: 44px;">
|
||||
</div>
|
||||
<h4>User More</h4>
|
||||
</div>
|
||||
@ -127,7 +126,7 @@ https://templatemo.com/tm-589-lugx-gaming
|
||||
<a href="#">
|
||||
<div class="item">
|
||||
<div class="image">
|
||||
<img src="assets/images/featured-03.png" alt="" style="max-width: 44px;">
|
||||
<img src="/themes/template2/assets/images/featured-03.png" alt="" style="max-width: 44px;">
|
||||
</div>
|
||||
<h4>Reply Ready</h4>
|
||||
</div>
|
||||
@ -137,7 +136,7 @@ https://templatemo.com/tm-589-lugx-gaming
|
||||
<a href="#">
|
||||
<div class="item">
|
||||
<div class="image">
|
||||
<img src="assets/images/featured-04.png" alt="" style="max-width: 44px;">
|
||||
<img src="/themes/template2/assets/images/featured-04.png" alt="" style="max-width: 44px;">
|
||||
</div>
|
||||
<h4>Easy Layout</h4>
|
||||
</div>
|
||||
@ -164,7 +163,7 @@ https://templatemo.com/tm-589-lugx-gaming
|
||||
<div class="col-lg-3 col-md-6">
|
||||
<div class="item">
|
||||
<div class="thumb">
|
||||
<a href="product-details.html"><img src="assets/images/trending-01.jpg" alt=""></a>
|
||||
<a href="product-details.html"><img src="/themes/template2/assets/images/trending-01.jpg" alt=""></a>
|
||||
<span class="price"><em>$28</em>$20</span>
|
||||
</div>
|
||||
<div class="down-content">
|
||||
@ -177,7 +176,7 @@ https://templatemo.com/tm-589-lugx-gaming
|
||||
<div class="col-lg-3 col-md-6">
|
||||
<div class="item">
|
||||
<div class="thumb">
|
||||
<a href="product-details.html"><img src="assets/images/trending-02.jpg" alt=""></a>
|
||||
<a href="product-details.html"><img src="/themes/template2/assets/images/trending-02.jpg" alt=""></a>
|
||||
<span class="price">$44</span>
|
||||
</div>
|
||||
<div class="down-content">
|
||||
@ -190,7 +189,7 @@ https://templatemo.com/tm-589-lugx-gaming
|
||||
<div class="col-lg-3 col-md-6">
|
||||
<div class="item">
|
||||
<div class="thumb">
|
||||
<a href="product-details.html"><img src="assets/images/trending-03.jpg" alt=""></a>
|
||||
<a href="product-details.html"><img src="/themes/template2/assets/images/trending-03.jpg" alt=""></a>
|
||||
<span class="price"><em>$64</em>$44</span>
|
||||
</div>
|
||||
<div class="down-content">
|
||||
@ -203,7 +202,7 @@ https://templatemo.com/tm-589-lugx-gaming
|
||||
<div class="col-lg-3 col-md-6">
|
||||
<div class="item">
|
||||
<div class="thumb">
|
||||
<a href="product-details.html"><img src="assets/images/trending-04.jpg" alt=""></a>
|
||||
<a href="product-details.html"><img src="/themes/template2/assets/images/trending-04.jpg" alt=""></a>
|
||||
<span class="price">$32</span>
|
||||
</div>
|
||||
<div class="down-content">
|
||||
@ -234,7 +233,7 @@ https://templatemo.com/tm-589-lugx-gaming
|
||||
<div class="col-lg-2 col-md-6 col-sm-6">
|
||||
<div class="item">
|
||||
<div class="thumb">
|
||||
<a href="product-details.html"><img src="assets/images/top-game-01.jpg" alt=""></a>
|
||||
<a href="product-details.html"><img src="/themes/template2/assets/images/top-game-01.jpg" alt=""></a>
|
||||
</div>
|
||||
<div class="down-content">
|
||||
<span class="category">Adventure</span>
|
||||
@ -246,7 +245,7 @@ https://templatemo.com/tm-589-lugx-gaming
|
||||
<div class="col-lg-2 col-md-6 col-sm-6">
|
||||
<div class="item">
|
||||
<div class="thumb">
|
||||
<a href="product-details.html"><img src="assets/images/top-game-02.jpg" alt=""></a>
|
||||
<a href="product-details.html"><img src="/themes/template2/assets/images/top-game-02.jpg" alt=""></a>
|
||||
</div>
|
||||
<div class="down-content">
|
||||
<span class="category">Adventure</span>
|
||||
@ -258,7 +257,7 @@ https://templatemo.com/tm-589-lugx-gaming
|
||||
<div class="col-lg-2 col-md-6 col-sm-6">
|
||||
<div class="item">
|
||||
<div class="thumb">
|
||||
<a href="product-details.html"><img src="assets/images/top-game-03.jpg" alt=""></a>
|
||||
<a href="product-details.html"><img src="/themes/template2/assets/images/top-game-03.jpg" alt=""></a>
|
||||
</div>
|
||||
<div class="down-content">
|
||||
<span class="category">Adventure</span>
|
||||
@ -411,12 +410,12 @@ https://templatemo.com/tm-589-lugx-gaming
|
||||
|
||||
<!-- Scripts -->
|
||||
<!-- Bootstrap core JavaScript -->
|
||||
<script src="vendor/jquery/jquery.min.js"></script>
|
||||
<script src="vendor/bootstrap/js/bootstrap.min.js"></script>
|
||||
<script src="assets/js/isotope.min.js"></script>
|
||||
<script src="assets/js/owl-carousel.js"></script>
|
||||
<script src="assets/js/counter.js"></script>
|
||||
<script src="assets/js/custom.js"></script>
|
||||
<script src="/themes/template2/vendor/jquery/jquery.min.js"></script>
|
||||
<script src="/themes/template2/vendor/bootstrap/js/bootstrap.min.js"></script>
|
||||
<script src="/themes/template2/assets/js/isotope.min.js"></script>
|
||||
<script src="/themes/template2/assets/js/owl-carousel.js"></script>
|
||||
<script src="/themes/template2/assets/js/counter.js"></script>
|
||||
<script src="/themes/template2/assets/js/custom.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -5,3 +5,6 @@ use think\facade\Route;
|
||||
Route::get('think', function () {
|
||||
return 'hello,ThinkPHP8!';
|
||||
});
|
||||
|
||||
// 新闻中心 API - 获取租户新闻
|
||||
Route::get('getCenterNews', 'app\index\controller\Article\NewsCenterController@getCenterNews');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user