Compare commits
13 Commits
4.0.0
...
newstartvi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b26ce04f0 | ||
|
|
cd6abcea3b | ||
|
|
18bfe171c0 | ||
|
|
f57b7cb2ae | ||
|
|
06b4766c7f | ||
|
|
6a6ecfd51f | ||
|
|
7d34946fb5 | ||
|
|
f3aaf89d25 | ||
|
|
bacb60fb43 | ||
|
|
5c2a9ab91b | ||
|
|
b4869ac005 | ||
|
|
1ce63eaf10 | ||
|
|
f5758abf93 |
12
README.md
12
README.md
@ -10,20 +10,26 @@ This template should help get you started developing with Vue 3 in Vite.
|
||||
|
||||
See [Vite Configuration Reference](https://vitejs.dev/config/).
|
||||
|
||||
## Project Setup
|
||||
## 安装依赖
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compile and Hot-Reload for Development
|
||||
### 测试运行(热更新)
|
||||
|
||||
```sh
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Compile and Minify for Production
|
||||
### 构建项目
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
|
||||
### 将文件同步至CDN
|
||||
|
||||
```sh
|
||||
npm run upload-assets
|
||||
```
|
||||
|
||||
@ -25,5 +25,6 @@
|
||||
"@vitejs/plugin-vue": "^4.0.0",
|
||||
"esno": "^4.8.0",
|
||||
"vite": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
||||
}
|
||||
|
||||
19
public/.htaccess
Normal file
19
public/.htaccess
Normal file
@ -0,0 +1,19 @@
|
||||
<IfModule mod_rewrite.c>
|
||||
# 开启URL重写引擎
|
||||
RewriteEngine On
|
||||
|
||||
# 规则 1: 处理根路径
|
||||
# 当用户请求确切的根路径 (例如 http://yourdomain.com/) 时
|
||||
# 内部重写到 start.html。
|
||||
# ^$ 匹配空路径 (即根目录)。[L] 表示这是最后一条规则,如果匹配成功则停止处理。
|
||||
RewriteRule ^$ /start.html [L]
|
||||
|
||||
# 规则 2: 处理其他所有路径 (标准的SPA规则)
|
||||
# 在处理其他路径之前,先确保请求的不是一个真实存在的文件或目录。
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
|
||||
# 如果以上条件满足 (不是文件或目录),
|
||||
# 则将请求重写到 index.html,让Vue Router处理。
|
||||
RewriteRule . /index.html [L]
|
||||
</IfModule>
|
||||
28
public/web.config
Normal file
28
public/web.config
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<system.webServer>
|
||||
<rewrite>
|
||||
<rules>
|
||||
<!-- 规则 1: 将根路径请求重写到 start.html -->
|
||||
<!-- 这个规则匹配空路径 (根目录) -->
|
||||
<rule name="Rewrite root to start.html" stopProcessing="true">
|
||||
<match url="^$" />
|
||||
<action type="Rewrite" url="/start.html" />
|
||||
</rule>
|
||||
|
||||
<!-- 规则 2: 将所有其他未匹配的请求重写到 index.html (标准SPA规则) -->
|
||||
<!-- 这个规则匹配所有内容,但有条件限制 -->
|
||||
<rule name="Rewrite all others to index.html" stopProcessing="true">
|
||||
<match url=".*" />
|
||||
<conditions logicalGrouping="MatchAll">
|
||||
<!-- 条件1: 请求的URL不是一个物理文件 -->
|
||||
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
|
||||
<!-- 条件2: 请求的URL不是一个物理目录 -->
|
||||
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
|
||||
</conditions>
|
||||
<action type="Rewrite" url="/index.html" />
|
||||
</rule>
|
||||
</rules>
|
||||
</rewrite>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
@ -8,6 +8,7 @@
|
||||
import { TosClient } from '@volcengine/tos-sdk';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
|
||||
// 配置信息
|
||||
@ -73,7 +74,10 @@ async function getAllFiles(dirPath: string, fileList: string[] = []): Promise<st
|
||||
async function uploadFile(filePath: string, basePath: string): Promise<void> {
|
||||
try {
|
||||
// 计算相对路径作为对象键名
|
||||
const key = filePath.replace(basePath, '').replace(/^\//, '');
|
||||
let key = filePath.replace(basePath, '').replace(/^[\/\\]/, '');
|
||||
// 将Windows路径分隔符转换为正斜杠
|
||||
key = key.replace(/\\/g, '/');
|
||||
|
||||
const contentType = getContentType(filePath);
|
||||
const fileContent = fs.readFileSync(filePath);
|
||||
|
||||
@ -89,6 +93,7 @@ async function uploadFile(filePath: string, basePath: string): Promise<void> {
|
||||
console.log(`上传成功: ${key}, 请求ID: ${response.requestId}`);
|
||||
} catch (error) {
|
||||
console.error(`上传文件 ${filePath} 失败:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,11 +119,10 @@ async function uploadDirectory(dirPath: string): Promise<void> {
|
||||
|
||||
// 主函数
|
||||
async function main() {
|
||||
// 使用 import.meta.url 替代 __dirname (ES 模块兼容)
|
||||
const currentFileUrl = import.meta.url;
|
||||
const currentFilePath = new URL(currentFileUrl).pathname;
|
||||
const currentDir = path.dirname(currentFilePath);
|
||||
const assetsDir = path.resolve(currentDir, '../dist/assets');
|
||||
// ES 模块中获取当前文件目录的正确方式
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const assetsDir = path.resolve(__dirname, '../dist/assets');
|
||||
console.log(`开始上传目录: ${assetsDir}`);
|
||||
await uploadDirectory(assetsDir);
|
||||
}
|
||||
@ -128,4 +132,3 @@ main().catch(error => {
|
||||
console.error('程序执行失败:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
|
||||
@ -142,7 +142,51 @@ const { breakpoint } = useBootstrapBreakpoint();
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Aboutus"
|
||||
name: "Aboutus",
|
||||
mounted() {
|
||||
this.$nextTick(function() {
|
||||
this.handleMediaLoad();
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
handleMediaLoad: function() {
|
||||
const container = document.getElementById('aboutusbanner');
|
||||
|
||||
if (container) {
|
||||
// 处理视频加载
|
||||
const video = document.getElementById('abtbannervideo');
|
||||
if (video) {
|
||||
const handleVideoReady = () => {
|
||||
container.classList.add('video-loaded');
|
||||
video.removeEventListener('loadedmetadata', handleVideoReady);
|
||||
video.removeEventListener('canplay', handleVideoReady);
|
||||
};
|
||||
|
||||
video.addEventListener('loadedmetadata', handleVideoReady);
|
||||
video.addEventListener('canplay', handleVideoReady);
|
||||
|
||||
if (video.videoWidth > 0) {
|
||||
handleVideoReady();
|
||||
}
|
||||
}
|
||||
|
||||
// 处理图片加载(移动端GIF)
|
||||
const img = document.querySelector('#aboutusbanner .videoimg');
|
||||
if (img) {
|
||||
const handleImageReady = () => {
|
||||
container.classList.add('video-loaded');
|
||||
img.removeEventListener('load', handleImageReady);
|
||||
};
|
||||
|
||||
img.addEventListener('load', handleImageReady);
|
||||
|
||||
if (img.complete && img.naturalWidth > 0) {
|
||||
handleImageReady();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@ -9,7 +9,8 @@ export default {
|
||||
psginfo:null,
|
||||
error:null,
|
||||
isLoading: false,
|
||||
cmsroot: '${this.$axios.defaults.baseURL}'
|
||||
// cmsroot: '${this.$axios.defaults.baseURL}'
|
||||
cmsroot: 'https://cdn.kdesign.top'
|
||||
}
|
||||
},
|
||||
setup() {
|
||||
@ -54,6 +55,20 @@ export default {
|
||||
}else{
|
||||
|
||||
}
|
||||
},
|
||||
getImageUrl(url) {
|
||||
if (!url) return '';
|
||||
|
||||
// 如果是完整的URL(以http或https开头),去掉域名部分,转换成相对路径
|
||||
if (url.startsWith('http://') || url.startsWith('https://')) {
|
||||
// 提<EFBFBD><EFBFBD><EFBFBD>路径部分(去掉协议和域名)
|
||||
const urlObj = new URL(url);
|
||||
const relativePath = urlObj.pathname;
|
||||
return `${this.$axios.defaults.baseCDNURL}${relativePath}`;
|
||||
} else {
|
||||
// 如果是相对路径,直接拼接CDN URL
|
||||
return `${this.$axios.defaults.baseCDNURL}${url}`;
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@ -75,9 +90,9 @@ export default {
|
||||
<template>
|
||||
<div id="passageroot" class="pageroot" v-if="psginfo">
|
||||
<div id="passagebanner" class="pagebanner">
|
||||
<img :src="`${this.$axios.defaults.baseURL}${psginfo.mobileheadimage.url}`"
|
||||
<img :src="getImageUrl(psginfo.mobileheadimage?.url)"
|
||||
v-if="breakpoint==='xs'||breakpoint==='sm'" alt="" id="bannerimg"/>
|
||||
<img :src="`${this.$axios.defaults.baseURL}${psginfo.headimage.url}`"
|
||||
<img :src="getImageUrl(psginfo.headimage?.url)"
|
||||
v-else alt="" id="bannerimg"/>
|
||||
<div id="bannercontentfill"
|
||||
style="width: 100%;height: 100%;
|
||||
@ -119,11 +134,11 @@ export default {
|
||||
<div v-for="(item, index) in psginfo.images" :key="index"
|
||||
class="imglistitem"
|
||||
style="width: 100%; height: auto;">
|
||||
<img :src="`${this.$axios.defaults.baseURL}${item.url}`" v-if="item.mime.startsWith('image',0)" alt="" />
|
||||
<img :src="getImageUrl(item.url)" v-if="item.mime.startsWith('image',0)" alt="" />
|
||||
<video v-else-if="item.mime.startsWith('video',0)" controls="controls">
|
||||
<source :src="`${this.$axios.defaults.baseURL}${item.url}`" type="video/mp4">
|
||||
<source :src="`${this.$axios.defaults.baseURL}${item.url}`" type="video/ogg">
|
||||
<source :src="`${this.$axios.defaults.baseURL}${item.url}`" type="video/webm">
|
||||
<source :src="getImageUrl(item.url)" type="video/mp4">
|
||||
<source :src="getImageUrl(item.url)" type="video/ogg">
|
||||
<source :src="getImageUrl(item.url)" type="video/webm">
|
||||
</video>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -11,9 +11,6 @@ const { breakpoint } = useBootstrapBreakpoint();
|
||||
<template>
|
||||
<div class="pageroot" id="examplesprocessroot">
|
||||
<div id="examplebanner" class="videorootbanner">
|
||||
<!-- <img v-if="$isMobile.android.phone||$isMobile.android.tablet"-->
|
||||
<!-- src="/ExpVideoPreload.png"-->
|
||||
<!-- class="videoimg"/>-->
|
||||
<video v-if="breakpoint==='xs'||breakpoint==='sm'||breakpoint==='md'"
|
||||
controls=""
|
||||
id="expbannervideo"
|
||||
@ -23,7 +20,6 @@ const { breakpoint } = useBootstrapBreakpoint();
|
||||
<source :src="ExpVideo" type="video/mp4"></source>
|
||||
</video>
|
||||
<video v-else
|
||||
:poster="ExpVideoPreload"
|
||||
id="expbannervideo"
|
||||
muted autoplay="autoplay"
|
||||
loop="loop" playsinline webkit-playsinline
|
||||
@ -52,7 +48,36 @@ const { breakpoint } = useBootstrapBreakpoint();
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
export default {
|
||||
name: "Examples"
|
||||
name: "Examples",
|
||||
mounted() {
|
||||
this.$nextTick(function() {
|
||||
this.handleVideoLoad();
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
handleVideoLoad: function() {
|
||||
const video = document.getElementById('expbannervideo');
|
||||
const container = document.getElementById('examplebanner');
|
||||
|
||||
if (video && container) {
|
||||
// 优化:使用loadedmetadata事件,这是视频尺寸信息可用的最早时机
|
||||
const handleVideoReady = () => {
|
||||
container.classList.add('video-loaded');
|
||||
// 移除事件监听器避免重复触发
|
||||
video.removeEventListener('loadedmetadata', handleVideoReady);
|
||||
video.removeEventListener('canplay', handleVideoReady);
|
||||
};
|
||||
|
||||
video.addEventListener('loadedmetadata', handleVideoReady);
|
||||
video.addEventListener('canplay', handleVideoReady);
|
||||
|
||||
// 如果视频已经有尺寸信息,立即触发
|
||||
if (video.videoWidth > 0) {
|
||||
handleVideoReady();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@ -2,21 +2,6 @@
|
||||
<!--<div class="pageroot" style="background-color: white;">-->
|
||||
<div v-if="this.error==null" id="examplelist">
|
||||
<div id="typegrid">
|
||||
<!-- <a href="/Examples" style="text-decoration: none;">-->
|
||||
<!-- <div class="typebar"-->
|
||||
<!-- :class="{-->
|
||||
<!-- active: (!$route.query.type || $route.query.type === '')}">-->
|
||||
<!-- 全部-->
|
||||
<!-- </div>-->
|
||||
<!-- </a>-->
|
||||
<!-- <a v-for="(item, index) in this.types"-->
|
||||
<!-- :key="index":href="`/Examples?type=${item}`"-->
|
||||
<!-- style="text-decoration: none;">-->
|
||||
<!-- <div class="typebar"-->
|
||||
<!-- :class="{ active: ($route.query.type === item)}">-->
|
||||
<!-- {{item}}-->
|
||||
<!-- </div>-->
|
||||
<!-- </a>-->
|
||||
<router-link to="/Examples" style="text-decoration: none;">
|
||||
<div class="typebar"
|
||||
:class="{
|
||||
@ -25,7 +10,7 @@
|
||||
</div>
|
||||
</router-link>
|
||||
<router-link v-for="(item, index) in this.types"
|
||||
:key="index":to="{ name: 'Examples', query: {type:item} }"
|
||||
:key="index" :to="{ name: 'Examples', query: {type:item} }"
|
||||
style="text-decoration: none;">
|
||||
<div class="typebar"
|
||||
:class="{ active: ($route.query.type === item)}">
|
||||
@ -41,14 +26,21 @@
|
||||
:href="`/ExampleItem?createdAt=${item.createdAt}`"
|
||||
>
|
||||
<div class="listblock">
|
||||
<img :src="`${this.$axios.defaults.baseURL}${item.headimage.formats.large.url}`" alt="" />
|
||||
<div class="itemtext">
|
||||
<span class="upspan">
|
||||
{{item.brandname_cn}}
|
||||
</span>
|
||||
<span class="downspan">
|
||||
{{item.projectname_cn}}
|
||||
</span>
|
||||
<img
|
||||
:src="getImageUrl(item.headimage)"
|
||||
alt=""
|
||||
@error="handleImageError"
|
||||
/>
|
||||
|
||||
<div id="itemon">
|
||||
<div class="itemtext">
|
||||
<span class="upspan">
|
||||
{{item.brandname_cn}}
|
||||
</span>
|
||||
<span class="downspan">
|
||||
{{item.projectname_cn}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
@ -80,10 +72,10 @@ export default {
|
||||
if (Array.isArray(resp)) {
|
||||
this.types = resp;
|
||||
if (this.types.length === 0) {
|
||||
this.error = "返回的数组为空";
|
||||
this.error = "返回的数组为<EFBFBD><EFBFBD><EFBFBD>";
|
||||
}
|
||||
} else {
|
||||
this.error = "返回的数据不是数组";
|
||||
this.error = "返回的<EFBFBD><EFBFBD><EFBFBD>据不是数组";
|
||||
this.types = [];
|
||||
}
|
||||
})
|
||||
@ -108,7 +100,7 @@ export default {
|
||||
reqarg='/api/examples?fields=id,brandname_cn,projectname_cn,createdAt&populate=headimage&filters[example_type]='+type+'&sort=createdAt:desc';
|
||||
}
|
||||
if (this.$route.name != 'Examples'){
|
||||
let reqarg='/api/examples?fields=id,brandname_cn,projectname_cn,createdAt&populate=headimage&pagination[page]=1&pagination[pageSize]=5&sort=createdAt:desc';
|
||||
reqarg='/api/examples?fields=id,brandname_cn,projectname_cn,createdAt&populate=headimage&pagination[page]=1&pagination[pageSize]=5&sort=createdAt:desc';
|
||||
}
|
||||
axios.get(reqarg)
|
||||
.then(response =>{
|
||||
@ -134,6 +126,24 @@ export default {
|
||||
.finally(() => {
|
||||
this.isLoading = false;
|
||||
});
|
||||
},
|
||||
getImageUrl(image) {
|
||||
const url = image.url;
|
||||
|
||||
// 如果是完整的URL(以http或https开头),去掉域名部分,转换成相对路径
|
||||
if (url.startsWith('http://') || url.startsWith('https://')) {
|
||||
// 提取路径部分(去掉协议和域名)
|
||||
const urlObj = new URL(url);
|
||||
const relativePath = urlObj.pathname;
|
||||
return `${this.$axios.defaults.baseCDNURL}${relativePath}`;
|
||||
} else {
|
||||
// 如果是相对路径,直接拼接CDN URL
|
||||
return `${this.$axios.defaults.baseCDNURL}${url}`;
|
||||
}
|
||||
},
|
||||
handleImageError(event) {
|
||||
// 处理图片加载错误的逻辑
|
||||
event.target.src = 'path/to/default/image.jpg'; // 替换为默认图片的路径
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@ -155,6 +165,16 @@ export default {
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "src/publicstyle.scss";
|
||||
#itemon{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0,0,0,0.3);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#listmain{
|
||||
display: grid;
|
||||
@include media-breakpoint-between(xs, md) {
|
||||
@ -188,6 +208,9 @@ export default {
|
||||
}
|
||||
}
|
||||
.listblock img {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 0;
|
||||
@include media-breakpoint-between(xs, md){
|
||||
width: 100%;
|
||||
@ -230,7 +253,7 @@ export default {
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
grid-template-columns: repeat(4,minmax(0,300px)) !important;
|
||||
grid-template-columns: repeat(4,1fr) !important;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
|
||||
@ -19,18 +19,14 @@ const { breakpoint } = useBootstrapBreakpoint();
|
||||
<template>
|
||||
<div id="homepageroot" class="pageroot">
|
||||
<div id="homepagebanner" class="videorootbanner">
|
||||
<!-- <img v-if="$isMobile.android.phone||$isMobile.android.tablet"-->
|
||||
<!-- src="/bannervideopreload.png"-->
|
||||
<!-- class="videoimg"/>-->
|
||||
<video v-if="breakpoint==='xs'||breakpoint==='sm'||breakpoint==='md'"
|
||||
:poster="bannervideopreload" controls=""
|
||||
id="bannervideo" muted autoplay="autoplay" loop="loop"
|
||||
playsinline webkit-playsinline
|
||||
class="bannervideos"
|
||||
x5-video-player-type="h5-page">
|
||||
<source :src="HpgVideo" type="video/mp4"></source>
|
||||
</video>
|
||||
<video v-else :poster="bannervideopreload"
|
||||
<video v-else
|
||||
id="bannervideo" muted autoplay="autoplay" loop="loop"
|
||||
playsinline webkit-playsinline
|
||||
class="bannervideos"
|
||||
@ -179,6 +175,7 @@ export default {
|
||||
mounted() {
|
||||
this.$nextTick(function() {
|
||||
this.video_autoplay();
|
||||
this.handleVideoLoad();
|
||||
});
|
||||
},
|
||||
methods:{
|
||||
@ -190,6 +187,28 @@ export default {
|
||||
video.play();
|
||||
}
|
||||
});
|
||||
},
|
||||
handleVideoLoad: function() {
|
||||
const video = document.getElementById('bannervideo');
|
||||
const container = document.getElementById('homepagebanner');
|
||||
|
||||
if (video && container) {
|
||||
// 优化:使用loadedmetadata事件,这是视频尺寸信息可用的最早时机
|
||||
const handleVideoReady = () => {
|
||||
container.classList.add('video-loaded');
|
||||
// 移除事件监听器避免重复触发
|
||||
video.removeEventListener('loadedmetadata', handleVideoReady);
|
||||
video.removeEventListener('canplay', handleVideoReady);
|
||||
};
|
||||
|
||||
video.addEventListener('loadedmetadata', handleVideoReady);
|
||||
video.addEventListener('canplay', handleVideoReady);
|
||||
|
||||
// 如果视频已经有尺寸信息,立即触发
|
||||
if (video.videoWidth > 0) {
|
||||
handleVideoReady();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ const { breakpoint } = useBootstrapBreakpoint();
|
||||
|
||||
<template>
|
||||
<div class="pageroot" id="serviceprocessroot">
|
||||
<div id="serviceprocessbanner" class="videorootbanner">
|
||||
<div id="serviceprocessbanner">
|
||||
<img class="videoimg" :src="Newbanner"/>
|
||||
<div id="expbanner" class="bannerovervideo">
|
||||
<div class="bannercontent">
|
||||
@ -96,7 +96,34 @@ const { breakpoint } = useBootstrapBreakpoint();
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "ServiceProcess"
|
||||
name: "ServiceProcess",
|
||||
mounted() {
|
||||
this.$nextTick(function() {
|
||||
this.handleImageLoad();
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
handleImageLoad: function() {
|
||||
const img = document.querySelector('#serviceprocessbanner .videoimg');
|
||||
const container = document.getElementById('serviceprocessbanner');
|
||||
|
||||
if (img && container) {
|
||||
// 图片加载完成后的处理
|
||||
const handleImageReady = () => {
|
||||
container.classList.add('video-loaded');
|
||||
// 移除事件监听器避免重复触发
|
||||
img.removeEventListener('load', handleImageReady);
|
||||
};
|
||||
|
||||
img.addEventListener('load', handleImageReady);
|
||||
|
||||
// 如果图片已经加载完成
|
||||
if (img.complete && img.naturalWidth > 0) {
|
||||
handleImageReady();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -104,9 +131,18 @@ export default {
|
||||
@import "src/publicstyle.scss";
|
||||
|
||||
#serviceprocessbanner{
|
||||
width: 100% !important;
|
||||
background-color: black !important;
|
||||
position: relative !important;
|
||||
z-index: 0 !important;
|
||||
overflow: hidden !important;
|
||||
|
||||
@include media-breakpoint-between(xs, md) {
|
||||
aspect-ratio: 1.92;
|
||||
}
|
||||
@include media-breakpoint-up(md){
|
||||
aspect-ratio: 2.62026969;
|
||||
}
|
||||
}
|
||||
|
||||
#blackchart{
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
<div v-for="item in logos"
|
||||
class="partneritempanel" id="ptn01">
|
||||
<div class="partnerlogodiv">
|
||||
<img :src="`${this.$axios.defaults.baseURL}${item.url}`" alt="" />
|
||||
<img :src="getImageUrl(item.url)" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -44,6 +44,20 @@ export default {
|
||||
console.error(err);
|
||||
this.logos = [];
|
||||
});
|
||||
},
|
||||
getImageUrl(url) {
|
||||
if (!url) return '';
|
||||
|
||||
// 如果是完整的URL(以http或https开头),去掉域名部分,转换成相对路径
|
||||
if (url.startsWith('http://') || url.startsWith('https://')) {
|
||||
// 提取路径部分(去掉协议和域名)
|
||||
const urlObj = new URL(url);
|
||||
const relativePath = urlObj.pathname;
|
||||
return `${this.$axios.defaults.baseCDNURL}${relativePath}`;
|
||||
} else {
|
||||
// 如果是相对路径,直接拼接CDN URL
|
||||
return `${this.$axios.defaults.baseCDNURL}${url}`;
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
@ -11,6 +11,7 @@ import 'bootstrap/dist/js/bootstrap.bundle.min.js'
|
||||
|
||||
const app = createApp(App)
|
||||
axios.defaults.baseURL = 'https://cms.kdesign.top'
|
||||
axios.defaults.baseCDNURL = 'https://cdn.kdesign.top'
|
||||
// axios.defaults.baseURL = 'http://localhost:8082'
|
||||
// 全局挂载 axios,所有组件都可以 this.$axios 访问
|
||||
app.config.globalProperties.$axios = axios
|
||||
|
||||
@ -35,12 +35,43 @@
|
||||
}
|
||||
|
||||
.videorootbanner{
|
||||
width: 100%;
|
||||
height: auto;
|
||||
background-color: black;
|
||||
position: relative;
|
||||
z-index: 0; // 明确设置父容器z-index
|
||||
overflow: hidden; // 帮助创建新的堆叠上下文
|
||||
width: 100% !important;
|
||||
background-color: black !important;
|
||||
position: relative !important;
|
||||
z-index: 0 !important;
|
||||
overflow: hidden !important;
|
||||
|
||||
// 始终保持固定的aspect-ratio作为占位,确保立即渲染
|
||||
@include media-breakpoint-between(xs, md) {
|
||||
aspect-ratio: 1.92 !important;
|
||||
}
|
||||
@include media-breakpoint-up(md){
|
||||
aspect-ratio: 2.62026969 !important;
|
||||
}
|
||||
|
||||
// 视频/图片元素的默认样式
|
||||
video, .videoimg {
|
||||
position: absolute !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
object-fit: cover !important;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
// 当媒体加载完成后,重新调整容器和媒体尺寸
|
||||
&.video-loaded {
|
||||
aspect-ratio: unset !important; // 移除固定比例
|
||||
height: auto !important; // 高度自适应
|
||||
|
||||
video, .videoimg {
|
||||
position: static !important; // 改为文档流布局
|
||||
width: 100% !important; // 宽度占满
|
||||
height: auto !important; // 高度自适应
|
||||
object-fit: contain !important; // 保持媒体比例,完整显示
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bannervideos{
|
||||
|
||||
@ -5,6 +5,7 @@ import fs from 'fs'
|
||||
|
||||
export default defineConfig({
|
||||
base: process.env.NODE_ENV === 'production' ? 'https://cdn.kdesign.top/' : '/',
|
||||
// base: '/',
|
||||
plugins: [
|
||||
vue(),
|
||||
// 添加自定义中间件来处理根路径
|
||||
@ -37,6 +38,11 @@ export default defineConfig({
|
||||
input: {
|
||||
main: fileURLToPath(new URL('./index.html', import.meta.url)),
|
||||
start: fileURLToPath(new URL('./start.html', import.meta.url))
|
||||
},
|
||||
output: {
|
||||
chunkFileNames: 'assets/[name]-[hash].js',
|
||||
entryFileNames: 'assets/[name]-[hash].js',
|
||||
assetFileNames: 'assets/[name]-[hash].[ext]'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user