Browse Source

feat(video): 新增企业视频

master
peijunlei 2 weeks ago
parent
commit
2019537c6c
  1. 1
      config/ui_ids.php
  2. 225
      public/themes/dist_static/static/css/news.css
  3. 42
      public/themes/dist_static/static/js/news2.js
  4. 46
      public/themes/website/1/en/demo/news.html
  5. 46
      public/themes/website/1/zh/demo/news.html

1
config/ui_ids.php

@ -17,6 +17,7 @@ return [
'solution' => ['zh' => 345, 'en' => 716], // 解决方案 'solution' => ['zh' => 345, 'en' => 716], // 解决方案
'support' => ['zh' => 355, 'en' => 724], // 服务支持 'support' => ['zh' => 355, 'en' => 724], // 服务支持
'news' => ['zh' => 361, 'en' => 730], // 新闻动态 'news' => ['zh' => 361, 'en' => 730], // 新闻动态
'news_video' => ['zh' => 757, 'en' => 758], // 企业视频(英文栏目建好后填 en)
'exhibition' => ['zh' => 364, 'en' => 733], // 展会与活动 'exhibition' => ['zh' => 364, 'en' => 733], // 展会与活动
'invest' => ['zh' => 365, 'en' => 734], // 投资者关系 'invest' => ['zh' => 365, 'en' => 734], // 投资者关系
'about' => ['zh' => 371, 'en' => 740], // 关于睿能 'about' => ['zh' => 371, 'en' => 740], // 关于睿能

225
public/themes/dist_static/static/css/news.css

@ -264,6 +264,189 @@
border-top-color: var(--color-primary); border-top-color: var(--color-primary);
} }
/* 企业视频卡片(设计稿) */
.n-grid--video {
gap: 2.5rem;
}
.n-v-card {
display: flex;
flex-direction: column;
width: 100%;
min-width: 0;
padding: 2rem;
border: 1px solid rgba(46, 53, 58, 0.1);
border-radius: 1.5rem;
background: var(--color-white, #fff);
text-align: left;
color: inherit;
cursor: pointer;
font: inherit;
transition: border-color var(--duration-fast) var(--easing), box-shadow var(--duration-fast) var(--easing);
}
.n-v-card__media {
position: relative;
overflow: hidden;
aspect-ratio: 16/9;
border-radius: 1rem;
background: rgba(175, 181, 185, 0.15);
margin-bottom: 2rem;
}
.n-v-card__cover {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
transition: transform var(--duration-normal) var(--easing);
}
.n-v-card__duration {
position: absolute;
left: 1rem;
bottom: 1rem;
z-index: 2;
padding: 0.375rem 0.5rem 0.375rem 0.5rem;
border-radius: 0.5rem;
background: rgba(46, 53, 58, 0.2);
color: var(--color-white, #fff);
font-family: "D-DIN-PRO", "MiSans VF", "PingFang SC", sans-serif;
font-size: var(--font-14);
font-weight: 400;
line-height: var(--font-18);
backdrop-filter: blur(0.25rem);
}
.n-v-card__play {
position: absolute;
top: 50%;
left: 50%;
z-index: 2;
display: flex;
align-items: center;
justify-content: center;
width: 3rem;
height: 3rem;
border-radius: 50%;
background: rgba(255, 255, 255, 0.28);
backdrop-filter: blur(0.375rem);
opacity: 0;
transform: translate(-50%, -50%) scale(0.92);
transition: opacity 0.25s ease, transform 0.25s ease;
}
.n-v-card__play img {
display: block;
width: 1rem;
height: auto;
margin-left: 0.125rem;
}
.n-v-card__title {
margin-bottom: 1rem;
color: var(--color-text);
font-family: "MiSans VF", "PingFang SC", sans-serif;
font-size: var(--font-20);
font-weight: 400;
line-height: var(--font-28);
min-height: 3.5rem;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
transition: color var(--duration-fast) var(--easing);
}
.n-v-card__date {
color: var(--color-text-muted);
font-family: "D-DIN-PRO", "MiSans VF", "PingFang SC", sans-serif;
font-size: var(--font-18);
font-weight: 400;
line-height: var(--font-18);
}
.n-v-card:hover .n-v-card__cover {
transform: scale(1.04);
}
.n-v-card:hover .n-v-card__play {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}
.n-v-card:hover .n-v-card__title {
color: var(--color-primary);
}
.n-v-modal {
position: fixed;
inset: 0;
z-index: 2000;
display: flex;
align-items: center;
justify-content: center;
padding: 1.5rem;
}
.n-v-modal[hidden] {
display: none;
}
.n-v-modal__backdrop {
position: absolute;
inset: 0;
background: rgba(46, 53, 58, 0.72);
}
.n-v-modal__dialog {
position: relative;
z-index: 1;
width: min(60rem, 100%);
overflow: hidden;
border-radius: 1rem;
background: #000;
box-shadow: 0 1.5rem 4rem rgba(0, 0, 0, 0.35);
}
.n-v-modal__head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
padding: 1rem 1.25rem;
background: rgba(0, 0, 0, 0.88);
}
.n-v-modal__title {
margin: 0;
min-width: 0;
color: var(--color-white, #fff);
font-family: "MiSans VF", "PingFang SC", sans-serif;
font-size: var(--font-18);
font-weight: 400;
line-height: var(--font-24);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.n-v-modal__close {
display: inline-flex;
align-items: center;
justify-content: center;
width: 2.25rem;
height: 2.25rem;
padding: 0;
border: 0;
border-radius: 0.5rem;
background: rgba(255, 255, 255, 0.12);
cursor: pointer;
transition: background var(--duration-fast) var(--easing);
}
.n-v-modal__close img {
display: block;
width: 1rem;
height: 1rem;
}
.n-v-modal__close:hover {
background: rgba(255, 255, 255, 0.22);
}
.n-v-modal__body {
aspect-ratio: 16/9;
background: #000;
}
.n-v-modal__video {
display: block;
width: 100%;
height: 100%;
object-fit: contain;
background: #000;
}
@media (max-width: 1439px) { @media (max-width: 1439px) {
.n-page { .n-page {
padding-top: calc(var(--header-h) + 48Px); padding-top: calc(var(--header-h) + 48Px);
@ -335,6 +518,21 @@
font-size: 18Px; font-size: 18Px;
line-height: 28Px; line-height: 28Px;
} }
.n-grid--video {
gap: 24Px;
}
.n-v-card {
gap: 12Px;
padding: 20Px;
border-radius: 20Px;
}
.n-v-card__title {
font-size: 18Px;
line-height: 26Px;
}
.n-v-card__date {
font-size: 14Px;
}
} }
@media (max-width: 576px) { @media (max-width: 576px) {
.n-page { .n-page {
@ -425,4 +623,31 @@
.n-card .n-link { .n-card .n-link {
padding-top: 16Px; padding-top: 16Px;
} }
.n-grid--video {
gap: 16Px;
}
.n-v-card {
gap: 10Px;
padding: 16Px;
border-radius: 16Px;
}
.n-v-card__media {
border-radius: 12Px;
}
.n-v-card__play {
width: 2.5rem;
height: 2.5rem;
}
.n-v-card__duration {
left: 12Px;
bottom: 12Px;
font-size: 12Px;
}
.n-v-card__title {
font-size: 16Px;
line-height: 24Px;
}
.n-v-card__date {
font-size: 13Px;
}
} }

42
public/themes/dist_static/static/js/news2.js

@ -74,10 +74,52 @@ function newsCardClick() {
if (href) window.location.href = href; if (href) window.location.href = href;
}); });
} }
function initNewsVideoModal() {
const modal = document.getElementById("n-v-modal");
const video = document.getElementById("n-v-modal-video");
const titleEl = document.getElementById("n-v-modal-title");
if (!modal || !video || !titleEl) return;
let lastFocus = null;
const openModal = (src, title) => {
if (!src) return;
lastFocus = document.activeElement;
titleEl.textContent = title || (typeof window.t === "function" ? window.t("video.play") : "视频播放");
if (video.getAttribute("src") !== src) video.src = src;
modal.hidden = false;
document.body.style.overflow = "hidden";
if (window.lenis?.stop) window.lenis.stop();
video.play().catch(() => {});
modal.querySelector(".n-v-modal__close")?.focus();
};
const closeModal = () => {
video.pause();
video.removeAttribute("src");
video.load();
modal.hidden = true;
document.body.style.overflow = "";
if (window.lenis?.start) window.lenis.start();
if (lastFocus && typeof lastFocus.focus === "function") lastFocus.focus();
};
document.querySelectorAll(".n-v-card").forEach((card) => {
card.addEventListener("click", () => {
openModal(
card.getAttribute("data-video-src") || "",
card.querySelector(".n-v-card__title")?.textContent?.trim() || ""
);
});
});
modal.querySelectorAll("[data-n-v-modal-close]").forEach((el) => {
el.addEventListener("click", closeModal);
});
document.addEventListener("keydown", (e) => {
if (e.key === "Escape" && !modal.hidden) closeModal();
});
}
$(function() { $(function() {
setActiveNav(); setActiveNav();
newsDetailBackToggle(); newsDetailBackToggle();
initNewsTabs(); initNewsTabs();
newsCardClick(); newsCardClick();
initNewsVideoModal();
}); });
//#endregion //#endregion

46
public/themes/website/1/en/demo/news.html

@ -64,7 +64,8 @@
{include file="components/header"} {include file="components/header"}
<main class="main-news" data-header-dark data-nav="新闻动态"> <main class="main-news" data-header-dark data-nav="新闻动态">
{hcTaglib:category id="361" item="vo" field="id,title,alias"}
{php}$news_root_id = uiId('news');{/php}
{hcTaglib:category id="$news_root_id" item="vo" field="id,title,alias"}
{php} {php}
$news_cate_info = $vo; $news_cate_info = $vo;
$news_cate_info_alias = $vo['alias'] ?? ''; $news_cate_info_alias = $vo['alias'] ?? '';
@ -83,6 +84,8 @@
$news_active_cat = (string)($current_cate_id ?: ($news_cate_info['id'] ?? '')); $news_active_cat = (string)($current_cate_id ?: ($news_cate_info['id'] ?? ''));
} }
$news_all_cat = (string)($news_cate_info['id'] ?? ''); $news_all_cat = (string)($news_cate_info['id'] ?? '');
$news_video_id = (string)uiId('news_video');
$is_news_video = ($news_video_id !== '' && $news_video_id !== '0' && $news_active_cat === $news_video_id);
{/php} {/php}
<a href="{$news_cate_info_alias}?cat={$news_cate_info['id']}" class="n-tabs__item{if $news_active_cat == $news_all_cat} is-active{/if}" role="tab" aria-selected="{if $news_active_cat == $news_all_cat}true{else /}false{/if}" data-cat="{$news_cate_info['id']}">All</a> <a href="{$news_cate_info_alias}?cat={$news_cate_info['id']}" class="n-tabs__item{if $news_active_cat == $news_all_cat} is-active{/if}" role="tab" aria-selected="{if $news_active_cat == $news_all_cat}true{else /}false{/if}" data-cat="{$news_cate_info['id']}">All</a>
{hcTaglib:subcategory pid="$news_cate_info['id']" item="vo" sort=""} {hcTaglib:subcategory pid="$news_cate_info['id']" item="vo" sort=""}
@ -103,7 +106,7 @@
} }
} }
{/php} {/php}
{if $news_has_featured}
{if $news_has_featured && !$is_news_video}
<article class="n-featured"> <article class="n-featured">
<div class="n-featured__swiper swiper"> <div class="n-featured__swiper swiper">
<div class="swiper-wrapper"> <div class="swiper-wrapper">
@ -167,9 +170,9 @@
</article> </article>
{/if} {/if}
<div class="n-grid">
<div class="n-grid{if $is_news_video} n-grid--video{/if}">
{hcTaglib:contentPage2 cid="$current_cate_id" mainField="id,category_id,title,sub_title,thumbnail,content,description,create_time,is_top" subField="" name="hc_content" limit="6" item="content_sub22" isTop="222"}
{hcTaglib:contentPage2 cid="$current_cate_id" mainField="id,category_id,title,sub_title,thumbnail,cover,content,description,create_time,publish_time,is_top" subField="" name="hc_content" limit="6" item="content_sub22" isTop="222"}
{/hcTaglib:contentPage2} {/hcTaglib:contentPage2}
{volist name="hc_content" id="vo_content"} {volist name="hc_content" id="vo_content"}
@ -179,6 +182,21 @@
$create_time_str = $vo_content['publish_time'] ?? $vo_content['create_time']; $create_time_str = $vo_content['publish_time'] ?? $vo_content['create_time'];
{/php} {/php}
{if $is_news_video}
<button type="button" class="n-v-card" data-video-src="{$vo_content['cover']['url'] ?? ''}">
<div class="n-v-card__media">
<img class="n-v-card__cover" src="{$vo_content['thumbnail']['url'] ?? ''}" alt="" width="400" height="225" loading="lazy" />
{notempty name="description"}
<span class="n-v-card__duration">{$description}</span>
{/notempty}
<span class="n-v-card__play" aria-hidden="true">
<img src="data:image/svg+xml,%3csvg%20viewBox='0%200%2013.5386%2016'%20xmlns='http://www.w3.org/2000/svg'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20width='13.538574'%20height='16.000000'%20fill='none'%20customFrame='%23000000'%3e%3cpath%20id='多边形%201'%20d='M8.86093%201.45695L15.1085%2012.0297C15.5024%2012.6963%2015.0219%2013.5384%2014.2476%2013.5384L1.75245%2013.5384C0.978149%2013.5384%200.497614%2012.6963%200.891523%2012.0297L7.13907%201.45695C7.52614%200.801924%208.47387%200.801924%208.86093%201.45695Z'%20fill='rgb(255,255,255)'%20fill-rule='evenodd'%20transform='matrix(0,1,-1,0,13.5386,0)'%20/%3e%3c/svg%3e" alt="" width="14" height="16" />
</span>
</div>
<h3 class="n-v-card__title">{$vo_content.title}</h3>
<time class="n-v-card__date" datetime="{$create_time_str}">{$create_time_str|date='Y-m-d'}</time>
</button>
{else /}
<article class="n-card" data-category="insight"> <article class="n-card" data-category="insight">
<div class="n-card__top"> <div class="n-card__top">
<time class="n-card__date" datetime="{$create_time_str}">{$create_time_str}</time> <time class="n-card__date" datetime="{$create_time_str}">{$create_time_str}</time>
@ -194,6 +212,7 @@
<img src="{$vo_content['thumbnail']['url'] ?? ''}" alt="" loading="lazy" /> <img src="{$vo_content['thumbnail']['url'] ?? ''}" alt="" loading="lazy" />
</div> </div>
</article> </article>
{/if}
{/volist} {/volist}
</div> </div>
@ -201,7 +220,7 @@
{php} {php}
$list_empty = isHcListEmpty($hc_content ?? null); $list_empty = isHcListEmpty($hc_content ?? null);
if ($list_empty) { if ($list_empty) {
$empty_text = 'No matching news';
$empty_text = $is_news_video ? 'No matching videos' : 'No matching news';
} }
{/php} {/php}
{if $list_empty} {if $list_empty}
@ -211,6 +230,23 @@
{$hc_content|raw} {$hc_content|raw}
{/if} {/if}
{if $is_news_video}
<div class="n-v-modal" id="n-v-modal" hidden>
<div class="n-v-modal__backdrop" data-n-v-modal-close></div>
<div class="n-v-modal__dialog" role="dialog" aria-modal="true" aria-labelledby="n-v-modal-title">
<div class="n-v-modal__head">
<h2 class="n-v-modal__title" id="n-v-modal-title">Video</h2>
<button type="button" class="n-v-modal__close" data-n-v-modal-close aria-label="Close">
<img src="data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='16'%20height='16'%20viewBox='0%200%2016%2016'%20fill='none'%3e%3cpath%20d='M1.5%201.5L14.5%2014.5M14.5%201.5L1.5%2014.5'%20stroke='%23fff'%20stroke-width='1.5'%20stroke-linecap='round'/%3e%3c/svg%3e" alt="" width="16" height="16" aria-hidden="true" />
</button>
</div>
<div class="n-v-modal__body">
<video class="n-v-modal__video" id="n-v-modal-video" controls playsinline></video>
</div>
</div>
</div>
{/if}
</div> </div>
</main> </main>
{include file="components/mask"} {include file="components/mask"}

46
public/themes/website/1/zh/demo/news.html

@ -64,7 +64,8 @@
{include file="components/header"} {include file="components/header"}
<main class="main-news" data-header-dark data-nav="新闻动态"> <main class="main-news" data-header-dark data-nav="新闻动态">
{hcTaglib:category id="361" item="vo" field="id,title,alias"}
{php}$news_root_id = uiId('news');{/php}
{hcTaglib:category id="$news_root_id" item="vo" field="id,title,alias"}
{php} {php}
$news_cate_info = $vo; $news_cate_info = $vo;
$news_cate_info_alias = $vo['alias'] ?? ''; $news_cate_info_alias = $vo['alias'] ?? '';
@ -83,6 +84,8 @@
$news_active_cat = (string)($current_cate_id ?: ($news_cate_info['id'] ?? '')); $news_active_cat = (string)($current_cate_id ?: ($news_cate_info['id'] ?? ''));
} }
$news_all_cat = (string)($news_cate_info['id'] ?? ''); $news_all_cat = (string)($news_cate_info['id'] ?? '');
$news_video_id = (string)uiId('news_video');
$is_news_video = ($news_video_id !== '' && $news_video_id !== '0' && $news_active_cat === $news_video_id);
{/php} {/php}
<a href="{$news_cate_info_alias}?cat={$news_cate_info['id']}" class="n-tabs__item{if $news_active_cat == $news_all_cat} is-active{/if}" role="tab" aria-selected="{if $news_active_cat == $news_all_cat}true{else /}false{/if}" data-cat="{$news_cate_info['id']}">全部</a> <a href="{$news_cate_info_alias}?cat={$news_cate_info['id']}" class="n-tabs__item{if $news_active_cat == $news_all_cat} is-active{/if}" role="tab" aria-selected="{if $news_active_cat == $news_all_cat}true{else /}false{/if}" data-cat="{$news_cate_info['id']}">全部</a>
{hcTaglib:subcategory pid="$news_cate_info['id']" item="vo" sort=""} {hcTaglib:subcategory pid="$news_cate_info['id']" item="vo" sort=""}
@ -103,7 +106,7 @@
} }
} }
{/php} {/php}
{if $news_has_featured}
{if $news_has_featured && !$is_news_video}
<article class="n-featured"> <article class="n-featured">
<div class="n-featured__swiper swiper"> <div class="n-featured__swiper swiper">
<div class="swiper-wrapper"> <div class="swiper-wrapper">
@ -167,9 +170,9 @@
</article> </article>
{/if} {/if}
<div class="n-grid">
<div class="n-grid{if $is_news_video} n-grid--video{/if}">
{hcTaglib:contentPage2 cid="$current_cate_id" mainField="id,category_id,title,sub_title,thumbnail,content,description,create_time,is_top" subField="" name="hc_content" limit="6" item="content_sub22" isTop="222"}
{hcTaglib:contentPage2 cid="$current_cate_id" mainField="id,category_id,title,sub_title,thumbnail,cover,content,description,create_time,publish_time,is_top" subField="" name="hc_content" limit="6" item="content_sub22" isTop="222"}
{/hcTaglib:contentPage2} {/hcTaglib:contentPage2}
{volist name="hc_content" id="vo_content"} {volist name="hc_content" id="vo_content"}
@ -179,6 +182,21 @@
$create_time_str = $vo_content['publish_time'] ?? $vo_content['create_time']; $create_time_str = $vo_content['publish_time'] ?? $vo_content['create_time'];
{/php} {/php}
{if $is_news_video}
<button type="button" class="n-v-card" data-video-src="{$vo_content['cover']['url'] ?? ''}">
<div class="n-v-card__media">
<img class="n-v-card__cover" src="{$vo_content['thumbnail']['url'] ?? ''}" alt="" width="400" height="225" loading="lazy" />
{notempty name="description"}
<span class="n-v-card__duration">{$description}</span>
{/notempty}
<span class="n-v-card__play" aria-hidden="true">
<img src="data:image/svg+xml,%3csvg%20viewBox='0%200%2013.5386%2016'%20xmlns='http://www.w3.org/2000/svg'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20width='13.538574'%20height='16.000000'%20fill='none'%20customFrame='%23000000'%3e%3cpath%20id='多边形%201'%20d='M8.86093%201.45695L15.1085%2012.0297C15.5024%2012.6963%2015.0219%2013.5384%2014.2476%2013.5384L1.75245%2013.5384C0.978149%2013.5384%200.497614%2012.6963%200.891523%2012.0297L7.13907%201.45695C7.52614%200.801924%208.47387%200.801924%208.86093%201.45695Z'%20fill='rgb(255,255,255)'%20fill-rule='evenodd'%20transform='matrix(0,1,-1,0,13.5386,0)'%20/%3e%3c/svg%3e" alt="" width="14" height="16" />
</span>
</div>
<h3 class="n-v-card__title">{$vo_content.title}</h3>
<time class="n-v-card__date" datetime="{$create_time_str}">{$create_time_str|date='Y-m-d'}</time>
</button>
{else /}
<article class="n-card" data-category="insight"> <article class="n-card" data-category="insight">
<div class="n-card__top"> <div class="n-card__top">
<time class="n-card__date" datetime="{$create_time_str}">{$create_time_str}</time> <time class="n-card__date" datetime="{$create_time_str}">{$create_time_str}</time>
@ -194,6 +212,7 @@
<img src="{$vo_content['thumbnail']['url'] ?? ''}" alt="" loading="lazy" /> <img src="{$vo_content['thumbnail']['url'] ?? ''}" alt="" loading="lazy" />
</div> </div>
</article> </article>
{/if}
{/volist} {/volist}
</div> </div>
@ -201,7 +220,7 @@
{php} {php}
$list_empty = isHcListEmpty($hc_content ?? null); $list_empty = isHcListEmpty($hc_content ?? null);
if ($list_empty) { if ($list_empty) {
$empty_text = '暂无相关新闻';
$empty_text = $is_news_video ? '暂无相关视频' : '暂无相关新闻';
} }
{/php} {/php}
{if $list_empty} {if $list_empty}
@ -211,6 +230,23 @@
{$hc_content|raw} {$hc_content|raw}
{/if} {/if}
{if $is_news_video}
<div class="n-v-modal" id="n-v-modal" hidden>
<div class="n-v-modal__backdrop" data-n-v-modal-close></div>
<div class="n-v-modal__dialog" role="dialog" aria-modal="true" aria-labelledby="n-v-modal-title">
<div class="n-v-modal__head">
<h2 class="n-v-modal__title" id="n-v-modal-title">视频播放</h2>
<button type="button" class="n-v-modal__close" data-n-v-modal-close aria-label="关闭">
<img src="data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='16'%20height='16'%20viewBox='0%200%2016%2016'%20fill='none'%3e%3cpath%20d='M1.5%201.5L14.5%2014.5M14.5%201.5L1.5%2014.5'%20stroke='%23fff'%20stroke-width='1.5'%20stroke-linecap='round'/%3e%3c/svg%3e" alt="" width="16" height="16" aria-hidden="true" />
</button>
</div>
<div class="n-v-modal__body">
<video class="n-v-modal__video" id="n-v-modal-video" controls playsinline></video>
</div>
</div>
</div>
{/if}
</div> </div>
</main> </main>
{include file="components/mask"} {include file="components/mask"}

Loading…
Cancel
Save