修复若干bug

This commit is contained in:
李志强 2026-01-27 10:08:03 +08:00
parent a81314ff75
commit 40f5926ba4
13 changed files with 154 additions and 155 deletions

View File

@ -3,5 +3,5 @@ NODE_ENV = 'development'
# 应用配置
VITE_APP_TITLE = '美天科技 - 官网'
# VITE_APP_API_URL = 'http://localhost:8000' # 接口基础URL
VITE_APP_API_URL = 'http://backapi.yunzer.cn'
# VITE_APP_API_URL = 'http://localhost:8000'
VITE_APP_API_URL = 'https://backend.yunzer.cn'

View File

@ -3,4 +3,4 @@ NODE_ENV = 'production'
# 应用配置
VITE_APP_TITLE = '美天科技 - 官网'
VITE_APP_API_URL = 'https://api.your-production-domain.com' # 生产环境接口基础URL
VITE_APP_API_URL = 'https://backend.yunzer.cn' # 生产环境接口基础URL

18
package-lock.json generated
View File

@ -21,6 +21,7 @@
"devDependencies": {
"@babel/eslint-parser": "^7.28.5",
"@eslint/js": "^9.39.2",
"@types/jquery": "^3.5.33",
"@types/node": "^24.10.4",
"@types/swiper": "^5.4.3",
"@types/terser": "^3.8.1",
@ -2093,6 +2094,16 @@
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
"license": "MIT"
},
"node_modules/@types/jquery": {
"version": "3.5.33",
"resolved": "https://registry.npmmirror.com/@types/jquery/-/jquery-3.5.33.tgz",
"integrity": "sha512-SeyVJXlCZpEki5F0ghuYe+L+PprQta6nRZqhONt9F13dWBtR/ftoaIbdRQ7cis7womE+X2LKhsDdDtkkDhJS6g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/sizzle": "*"
}
},
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.15.tgz",
@ -2132,6 +2143,13 @@
"undici-types": "~7.16.0"
}
},
"node_modules/@types/sizzle": {
"version": "2.3.10",
"resolved": "https://registry.npmmirror.com/@types/sizzle/-/sizzle-2.3.10.tgz",
"integrity": "sha512-TC0dmN0K8YcWEAEfiPi5gJP14eJe30TTGjkvek3iM/1NdHHsdCA/Td6GvNndMOo/iSnIsZ4HuuhrYPDAmbxzww==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/svgo": {
"version": "2.6.4",
"resolved": "https://registry.npmmirror.com/@types/svgo/-/svgo-2.6.4.tgz",

View File

@ -27,6 +27,7 @@
"devDependencies": {
"@babel/eslint-parser": "^7.28.5",
"@eslint/js": "^9.39.2",
"@types/jquery": "^3.5.33",
"@types/node": "^24.10.4",
"@types/swiper": "^5.4.3",
"@types/terser": "^3.8.1",

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

9
src/env.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
/* src/env.d.ts */
declare module '*.vue' {
import type { DefineComponent } from 'vue'
// 这里的 DefineComponent 会告诉 TS 所有 .vue 文件都是合法的 Vue 组件
const component: DefineComponent<{}, {}, any>
export default component
}
declare module 'swiper/css'
declare module 'swiper/css/*'

View File

@ -15,26 +15,26 @@ Object.keys(viewsModules).forEach((relativePath) => {
// 1. 别名格式: @/views/newsCenter/companyNews/index.vue
const aliasPath = relativePath.replace('../views', '@/views')
pathMap.set(aliasPath, viewsModules[relativePath])
pathMap.set(aliasPath, viewsModules[relativePath]!)
// 2. 数据库格式: /views/newsCenter/companyNews/index.vue 或 /newsCenter/companyNews/index.vue
const dbPath1 = relativePath.replace('../views', '/views')
pathMap.set(dbPath1, viewsModules[relativePath])
pathMap.set(dbPath1, viewsModules[relativePath]!)
const dbPath2 = relativePath.replace('../views/', '/')
pathMap.set(dbPath2, viewsModules[relativePath])
pathMap.set(dbPath2, viewsModules[relativePath]!)
// 3. 相对路径格式: newsCenter/companyNews/index.vue
const relativePathFormat = relativePath.replace('../views/', '')
pathMap.set(relativePathFormat, viewsModules[relativePath])
pathMap.set(relativePathFormat, viewsModules[relativePath]!)
// 4. 原始相对路径也保留
pathMap.set(relativePath, viewsModules[relativePath])
pathMap.set(relativePath, viewsModules[relativePath]!)
// 5. 如果路径包含 views/,也添加不带 views/ 的格式
if (relativePath.includes('views/')) {
const withoutViews = relativePath.replace('../views/', '')
if (withoutViews !== relativePathFormat) {
pathMap.set(withoutViews, viewsModules[relativePath])
pathMap.set(withoutViews, viewsModules[relativePath]!)
}
}
})

View File

@ -50,7 +50,8 @@ import darkImage from '@/assets/images/404/404-dark.png'
import lightImage from '@/assets/images/404/404-light.gif'
// jQuery
import type { JQueryStatic } from 'jquery'
type JQueryStatic = any;
// Modernizr
interface ModernizrStatic {
@ -72,10 +73,6 @@ declare global {
useRouter()
const isDark = ref(false)
const toggleTheme = () => {
document.body.classList.toggle('dark-theme', isDark.value)
}
onMounted(() => {
// Initialize theme
document.body.classList.toggle('dark-theme', isDark.value)

View File

@ -139,14 +139,15 @@ import Footer from '@/views/components/footer.vue'
import { getKingdeeNewsDetail, getCompanyNewsDetail } from '@/api/newscenter'
const route = useRoute()
const article = ref({})
const relatedArticles = ref([])
const article = ref<any>({})
const relatedArticles = ref<any[]>([])
const nextPreviousArticles = ref<{
previous?: { id: number; title: string }
next?: { id: number; title: string }
}>({})
const loading = ref(true)
const { proxy } = getCurrentInstance()
const instance = getCurrentInstance()
const proxy = instance?.proxy as any
const router = useRouter()
const contentRef = ref<HTMLElement | null>(null)
const VITE_APP_API_URL = import.meta.env.VITE_APP_API_URL
@ -242,11 +243,11 @@ onMounted(async () => {
const path = route.path
if (path.includes('companyNews')) {
res = await getCompanyNewsDetail(id)
res = await getCompanyNewsDetail(id as string)
} else if (path.includes('kingdeeNews')) {
res = await getKingdeeNewsDetail(id)
res = await getKingdeeNewsDetail(id as string)
} else {
res = await getKingdeeNewsDetail(id)
res = await getKingdeeNewsDetail(id as string)
}
if (res.code === 200) {

View File

@ -150,7 +150,9 @@
<div class="solutions">
<div class="title">
<span class="text-4xl">行业解决方案</span>
<span class="text-xl">&nbsp;&nbsp;/&nbsp;&nbsp;INDUSTRY SOLUTIONS</span>
<span class="text-xl">
&nbsp;&nbsp;/&nbsp;&nbsp;INDUSTRY SOLUTIONS
</span>
</div>
<div class="solutions-container" v-if="solutions.length >= 4">
<!-- 第一行两个大卡片 -->
@ -215,18 +217,34 @@
</div>
<!-- 平台数据 -->
<div class="mt20 newsfoot" ref="platformRef"
style="background: url('/src/assets/images/indexImg/about_b1.png') no-repeat center bottom;background-size: cover;display: flex;align-items: center;">
<div style="width: 1200px;margin: 0 auto;">
<div style="display: flex;justify-content: space-between;">
<div style="text-align: center" v-for="item in platformStats" :key="item.id">
<div
class="mt20 newsfoot"
ref="platformRef"
style="
background: url('/src/assets/images/indexImg/about_b1.png') no-repeat
center bottom;
background-size: cover;
display: flex;
align-items: center;
"
>
<div style="width: 1200px; margin: 0 auto">
<div style="display: flex; justify-content: space-between">
<div
style="text-align: center"
v-for="item in platformStats"
:key="item.id"
>
<div>
<span >
<span style="font-size: 48px;font-weight: bold;">{{ item.current }}</span>
<span style="font-size: 48px;font-weight: bold;">+</span>{{ item.unit }}
<span>
<span style="font-size: 48px; font-weight: bold">
{{ item.current }}
</span>
<span style="font-size: 48px; font-weight: bold">+</span>
{{ item.unit }}
</span>
<br />
<span style="font-size: 20px;">{{ item.label }}</span>
<span style="font-size: 20px">{{ item.label }}</span>
</div>
</div>
</div>
@ -242,11 +260,10 @@
<div class="partners-content">
<div class="partner-inner" v-for="url in partnerImages">
<el-image :key="url" :src="url" lazy/>
<el-image :key="url" :src="url" lazy />
</div>
</div>
</div>
</main>
<Footer />
</div>
@ -305,18 +322,8 @@ const bannerSlides = [
},
]
const swiperRef = ref()
const onSwiper = (swiper: any) => {
swiperRef.value = swiper
}
const onSlideChange = () => {
// console.log('slide change')
}
//
const newsData = ref([])
const newsData = ref<any[]>([])
//
const loading = ref(false)
//
@ -385,7 +392,6 @@ const solutions = ref([
},
])
//
const activeNewsIndex = ref<number>(0)
@ -413,7 +419,6 @@ const stopAutoScroll = (): void => {
}
}
onMounted(() => {
startAutoScroll()
fetchNewsData()
loadImagesWithOptions()
@ -424,21 +429,17 @@ const handleMoreNewsClick = () => {
// console.log('more news clicked')
}
const partnerImages = ref([])
const partnerImages = ref<any[]>([])
// TODO
const loadImagesWithOptions = async () => {
try {
//
const modules = import.meta.glob(
'/src/assets/images/indexImg/partner/*',
{
eager: true,
query: '?url',
import: 'default'
}
)
const modules = import.meta.glob('/src/assets/images/indexImg/partner/*', {
eager: true,
query: '?url',
import: 'default',
})
const images = []
for (const path in modules) {
@ -468,8 +469,7 @@ const platformRef = ref<HTMLElement | null>(null)
let observer: IntersectionObserver | null = null
let hasAnimated = false
const animateNumber = (item:object) => {
const animateNumber = (item: any) => {
const step = Math.ceil(item.target / 40)
const timer = setInterval(() => {
item.current += step
@ -482,13 +482,13 @@ const animateNumber = (item:object) => {
onMounted(() => {
observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting && !hasAnimated) {
hasAnimated = true
platformStats.value.forEach(animateNumber)
}
},
{ threshold: 0.3 }
([entry]) => {
if (entry?.isIntersecting && !hasAnimated) {
hasAnimated = true
platformStats.value.forEach(animateNumber)
}
},
{ threshold: 0.3 },
)
if (platformRef.value) {
@ -499,7 +499,6 @@ onMounted(() => {
onUnmounted(() => {
observer?.disconnect()
})
</script>
<style lang="scss" scoped>
@ -594,8 +593,6 @@ onUnmounted(() => {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
}
}
/* 分页器样式 */
@ -909,7 +906,7 @@ onUnmounted(() => {
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
//&::before {
//background: rgba(24, 144, 255, 0.8);
//background: rgba(24, 144, 255, 0.8);
//}
.solution-overlay {
@ -1040,8 +1037,7 @@ onUnmounted(() => {
color: #fff;
}
.partners{
.partners {
.title {
display: flex;
align-items: center;
@ -1049,14 +1045,14 @@ onUnmounted(() => {
padding: 40px 0;
}
.partners-content{
.partners-content {
max-width: 1200px;
margin: 0 auto;
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-gap: 20px 20px;
.partner-inner{
.partner-inner {
padding: 1.5rem 2.375rem;
margin: -1px;
background-color: #fff;
@ -1065,7 +1061,6 @@ onUnmounted(() => {
height: 100px;
display: flex;
align-items: center;
}
.partner-inner:hover {
@ -1074,5 +1069,4 @@ onUnmounted(() => {
}
}
}
</style>

View File

@ -20,7 +20,7 @@ import Footer from '@/views/components/footer.vue'
import { getKingdeeNewsDetail, getCompanyNewsDetail } from '@/api/newscenter'
const route = useRoute()
const article = ref({})
const article = ref<any>({})
const loading = ref(true)
onMounted(async () => {
@ -32,11 +32,11 @@ onMounted(async () => {
const path = route.path
if (path.includes('companyNews')) {
res = await getCompanyNewsDetail(id)
res = await getCompanyNewsDetail(id as string)
} else if (path.includes('kingdeeNews')) {
res = await getKingdeeNewsDetail(id)
res = await getKingdeeNewsDetail(id as string)
} else {
res = await getKingdeeNewsDetail(id)
res = await getKingdeeNewsDetail(id as string)
}
if (res.code === 200) {

View File

@ -1,74 +1,65 @@
<script setup lang="ts">
import { ref,reactive } from "vue";
import Header from "@/views/components/header.vue";
import Footer from "@/views/components/footer.vue";
import { VideoPlay } from "@element-plus/icons-vue";
import { ref } from 'vue'
import Header from '@/views/components/header.
import Footer from '@/views/components/footer.vue'
import { VideoPlay } from '@element-plus/icons-vue'
const activeIndex = ref(0);
const activeIndex = ref(0)
const industryTabs = [
{
title: "制造行业",
icon: "src/assets/images/solution/14194311qxyp.png",
iconActive: "src/assets/images/solution/15172752x7hf.png",
title: '制造行业',
icon: 'src/assets/images/solution/14194311qxyp.png',
iconActive: 'src/assets/images/solution/15172752x7hf.png',
contents: [
{ title: "制造业概述", route: "/solution/manufacture" },
{ title: "电子行业", route: "/solution/electronics" }
]
{ title: '制造业概述', route: '/solution/manufacture' },
{ title: '电子行业', route: '/solution/electronics' },
],
},
{
title: "服务行业",
icon: "@/assets/icons/zz1.png",
iconActive: "@/assets/icons/zz1.png",
contents: [
{ title: "服务行业概述", route: "/solution/service" }
]
title: '服务行业',
icon: '@/assets/icons/zz1.png',
iconActive: '@/assets/icons/zz1.png',
contents: [{ title: '服务行业概述', route: '/solution/service' }],
},
{
title: "批发与零售",
icon: new URL("@/assets/icons/zf1.png", import.meta.url).href,
iconActive: new URL("@/assets/icons/zf2.png", import.meta.url).href,
contents: [
{ title: "贸易零售", route: "/solution/government" }
]
title: '批发与零售',
icon: new URL('@/assets/icons/zf1.png', import.meta.url).href,
iconActive: new URL('@/assets/icons/zf2.png', import.meta.url).href,
contents: [{ title: '贸易零售', route: '/solution/government' }],
},
{
title: "建筑与房地产",
icon: new URL("@/assets/icons/yy1.png", import.meta.url).href,
iconActive: new URL("@/assets/icons/yy2.png", import.meta.url).href,
contents: [
{ title: "建筑行业", route: "/solution/medical" }
]
title: '建筑与房地产',
icon: new URL('@/assets/icons/yy1.png', import.meta.url).href,
iconActive: new URL('@/assets/icons/yy2.png', import.meta.url).href,
contents: [{ title: '建筑行业', route: '/solution/medical' }],
},
{
title: "快速消费品",
icon: new URL("@/assets/icons/qc1.png", import.meta.url).href,
iconActive: new URL("@/assets/icons/qc2.png", import.meta.url).href,
contents: [
{ title: "食品行业", route: "/solution/auto" }
]
}
];
title: '快速消费品',
icon: new URL('@/assets/icons/qc1.png', import.meta.url).href,
iconActive: new URL('@/assets/icons/qc2.png', import.meta.url).href,
contents: [{ title: '食品行业', route: '/solution/auto' }],
},
]
const caseList = [
{
id: 111,
title: '碧桂园:数字化驱动业务创新',
desc:
'碧桂园集团,是中国最大的新型城镇化住宅开发商。采用集中及标准化的运营模式,业务包含物业发展、建安、装修、物业管理、物业投资、酒店开发和管理,以及现代农业、机器人。\n',
image: 'http://backapi.yunzer.cn/storage/uploads/2026/01/20/696ee14c17458.jpg'
desc: '碧桂园集团,是中国最大的新型城镇化住宅开发商。采用集中及标准化的运营模式,业务包含物业发展、建安、装修、物业管理、物业投资、酒店开发和管理,以及现代农业、机器人。\n',
image:
'http://backapi.yunzer.cn/storage/uploads/2026/01/20/696ee14c17458.jpg',
},
{
id: 114,
title: '四川路桥:“财务共享助力业务腾飞”',
desc:
'四川路桥建设集团股份有限公司是国有控股上市公司中国500强企业于2003年3月在上海证券交易所挂牌交易是四川省交通系统首家A股上市企业母公司为四川省铁路产业投资集团公司。',
image: 'http://backapi.yunzer.cn/storage/uploads/2026/01/20/696eec54c8e64.png'
}
desc: '四川路桥建设集团股份有限公司是国有控股上市公司中国500强企业于2003年3月在上海证券交易所挂牌交易是四川省交通系统首家A股上市企业母公司为四川省铁路产业投资集团公司。',
image:
'http://backapi.yunzer.cn/storage/uploads/2026/01/20/696eec54c8e64.png',
},
]
/* 视频弹窗 */
const showVideo = ref(false);
const showVideo = ref(false)
</script>
<template>
@ -95,18 +86,9 @@ const showVideo = ref(false);
class="tab-item"
@mouseenter="activeIndex = index"
>
<div
class="tab-box"
:class="{ active: activeIndex === index }"
>
<img
:src="tab.icon"
v-show="activeIndex !== index"
/>
<img
:src="tab.iconActive"
v-show="activeIndex === index"
/>
<div class="tab-box" :class="{ active: activeIndex === index }">
<img :src="tab.icon" v-show="activeIndex !== index" />
<img :src="tab.iconActive" v-show="activeIndex === index" />
<p class="text-xl">{{ tab.title }}</p>
</div>
</div>
@ -115,13 +97,13 @@ const showVideo = ref(false);
<!-- 内容区 -->
<div class="industry-content">
<router-link
v-for="(item, i) in industryTabs[activeIndex].contents"
v-for="(item, i) in industryTabs[activeIndex]?.contents"
:key="i"
:to="item.route"
class="content-card"
>
<div class="card-img">
<img src="@/assets/images/noimage.png">
<img src="@/assets/images/noimage.png" />
</div>
<div class="flex-1">
<p class="card-title">{{ item.title }}</p>
@ -170,21 +152,13 @@ const showVideo = ref(false);
</router-link>
</div>
<div>
<el-link type="primary" underline="never">
更多客户成功故事
</el-link>
<el-link type="primary" underline="never">更多客户成功故事</el-link>
</div>
</div>
</div>
<el-dialog v-model="showVideo" width="800px">
<video
src=""
controls
autoplay
style="width:100%"
/>
<video src="" controls autoplay style="width: 100%" />
</el-dialog>
<Footer />
@ -193,7 +167,8 @@ const showVideo = ref(false);
<style scoped lang="scss">
.banner {
height: 360px;
background: url("@/assets/images/solution/solution.png") center / cover no-repeat;
background: url('@/assets/images/solution/solution.png') center / cover
no-repeat;
color: #fff;
.banner-inner {
@ -282,8 +257,6 @@ const showVideo = ref(false);
}
}
.banner-center {
width: 100%;
height: 400px;
@ -292,7 +265,8 @@ const showVideo = ref(false);
flex-direction: column;
align-items: center;
justify-content: center;
background: url(@/assets/images/solution/banner-center-pc.png) center center no-repeat;
background: url(@/assets/images/solution/banner-center-pc.png) center center
no-repeat;
.banner-center-container {
width: 1200px;
text-align: start;
@ -344,7 +318,7 @@ const showVideo = ref(false);
.con3-list-box-content {
padding: 24px;
flex: 1;
background-color: #F6F6F6;
background-color: #f6f6f6;
}
.con3-list-content-title {

View File

@ -4,6 +4,12 @@
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"types": ["vite/client"],
/* */
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
/* Linting */
"strict": true,
"noUnusedLocals": true,