Compare commits

...

3 Commits

Author SHA1 Message Date
6d405b5367 Feature: 新增界面-公司简介 2025-08-18 17:16:35 +08:00
bf19fc9d35 Fix: 调整代码结构 2025-08-18 14:39:19 +08:00
5f0d13c122 Fix: 调整Strapi类型 2025-08-18 12:04:32 +08:00
9 changed files with 134 additions and 113 deletions

View File

@ -0,0 +1,3 @@
<template>
<p>还没做</p>
</template>

102
app/pages/about/index.vue Normal file
View File

@ -0,0 +1,102 @@
<template>
<div>
<el-breadcrumb class="breadcrumb" separator="/">
<el-breadcrumb-item class="text-sm opacity-50" :to="{ path: $localePath('/') }">
{{ $t('navigation.home') }}
</el-breadcrumb-item>
<el-breadcrumb-item class="text-sm opacity-50">
{{ $t('about-us') }}
</el-breadcrumb-item>
</el-breadcrumb>
<div class="content">
<markdown-renderer :content="content || ''" />
</div>
<el-divider content-position="left">更多信息</el-divider>
<div class="button-group">
<NuxtLink :to="$localePath('/about/contact-us')">
<el-card class="card-button">
<el-icon class="icon" size="80"><ElIconService /></el-icon>
<br>
联系信息
</el-card>
</NuxtLink>
</div>
</div>
</template>
<script setup lang="ts">
const { findOne } = useStrapi()
const { getStrapiLocale } = useLocalizations()
const strapiLocale = getStrapiLocale()
const content = ref<string>('')
onMounted(async () => {
try {
const response = await findOne<StrapiCompanyProfile>('company-profile', undefined, {
populate: '*',
locale: strapiLocale,
})
if (response.data) {
content.value = response.data.content || ''
} else {
console.warn('No company profile data found')
}
} catch (error) {
console.error('Failed to fetch company profile:', error)
}
})
</script>
<style scoped>
.breadcrumb {
padding: 1rem 1rem;
}
.content {
padding: 1rem;
margin-bottom: 2rem;
}
:deep(.markdown-body p) {
text-indent: 2em;
}
:deep(.markdown-body h2) {
text-align: center;
}
:deep(.el-divider__text) {
color: var(--el-color-info);
font-size: 1em;
}
.button-group {
display: flex;
justify-content: left;
margin-top: 2rem;
margin-left: 2rem;
}
.card-button {
width: 20%;
min-width: 200px;
padding: 20px;
margin: 0 auto;
cursor: pointer;
text-align: center;
font-size: 1.5em;
}
.card-button:hover {
transform: translateY(-4px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}
.icon {
padding: 10px;
}
</style>

View File

@ -97,7 +97,6 @@ onMounted(async () => {
populate: '*',
locale: strapiLocale,
})
if (response.data) {
const item = response.data
production.value = {
@ -108,7 +107,7 @@ onMounted(async () => {
production_specs: item.production_specs,
production_image: item.production_image,
documentId: item.documentId,
}
documents: item.documents || [] }
}
} catch (error) {
console.error('Failed to fetch production:', error)
@ -139,10 +138,6 @@ useHead({
margin-bottom: 2rem;
}
.breadcrumb-item {
color: var(--el-text-color-regular);
}
.production-header {
display: grid;
grid-template-columns: 1fr 1fr;

View File

@ -1,95 +0,0 @@
<template>
<div class="production-detail">
<div>
<el-breadcrumb class="breadcrumb" separator="/">
<el-breadcrumb-item class="text-sm" :to="{ path: '/' }">
{{ $t('navigation.home') }}
</el-breadcrumb-item>
<el-breadcrumb-item class="text-sm" :to="{ path: '/' }">
{{ $t('productions') }}
</el-breadcrumb-item>
<el-breadcrumb-item class="text-sm" :to="{ path: '/' }">
示例
</el-breadcrumb-item>
</el-breadcrumb>
<div class="production-header">
<div class="production-image">
<el-empty description="产品图片" class="border" />
</div>
<div class="production-info">
<h1>产品名称</h1>
<p class="summary">产品描述...</p>
</div>
</div>
<div class="production-content">
<el-tabs v-model="activeName" class="production-tabs">
<el-tab-pane label="产品详情" name="details">
<p>这里是产品的详细描述内容...</p>
</el-tab-pane>
<el-tab-pane label="技术规格" name="specs">
<p>这里是产品的技术规格内容...</p>
</el-tab-pane>
<el-tab-pane label="常见问题" name="faq">
<p>这里是产品的常见问题内容...</p>
</el-tab-pane>
<el-tab-pane label="相关资料" name="resources">
<p>这里是产品的相关资料内容...</p>
</el-tab-pane>
</el-tabs>
</div>
</div>
</div>
</template>
<script setup lang="ts">
const activeName = ref('details')
</script>
<style scoped lang="scss">
.production-detail {
min-height: 60vh;
}
.breadcrumb {
padding: 0rem 1rem;
margin-bottom: 2rem;
}
.breadcrumb-item {
color: var(--el-color-info);
}
.production-header {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 3rem;
margin-bottom: 3rem;
}
.production-image .el-empty {
width: 100%;
height: 400px;
border-radius: 8px;
}
.production-info h1 {
color: var(--el-color-text);
margin-top: 2rem;
margin-bottom: 1rem;
font-size: 2rem;
}
.production-info p {
color: var(--el-color-info);
font-size: 1rem;
line-height: 1.6;
margin-bottom: 2rem;
}
.el-tab-pane {
margin-top: 1rem;
}
</style>

View File

@ -7,18 +7,13 @@ export interface StrapiEntity {
locale?: string;
}
export interface StrapiImage {
export interface StrapiMedia {
id: number;
url: string;
ext?: string;
name?: string;
alternativeText?: string;
caption?: string;
width?: number;
height?: number;
formats?: {
small?: StrapiImageFormat;
medium?: StrapiImageFormat;
thumbnail?: StrapiImageFormat;
}
}
export interface StrapiImageFormat {
@ -28,6 +23,16 @@ export interface StrapiImageFormat {
size: number;
}
export interface StrapiImage extends StrapiMedia {
width?: number;
height?: number;
formats?: {
small?: StrapiImageFormat;
medium?: StrapiImageFormat;
thumbnail?: StrapiImageFormat;
}
}
export interface StrapiResponse<T> {
data: T;
meta?: {

View File

@ -1,2 +1,3 @@
export * from './common';
export * from './production';
export * from './production';
export * from './singleTypes';

View File

@ -1,4 +1,4 @@
import type { StrapiEntity, StrapiImage } from './common';
import type { StrapiEntity, StrapiImage, StrapiMedia } from './common';
export interface ProductionType extends StrapiEntity {
type: string;
@ -11,4 +11,5 @@ export interface Production extends StrapiEntity {
production_image?: StrapiImage;
production_details?: string;
production_specs?: string | object;
documents?: StrapiMedia[];
}

View File

@ -0,0 +1,3 @@
export interface StrapiCompanyProfile extends StrapiEntity {
content: string;
}

View File

@ -1,5 +1,4 @@
import MarkdownIt from 'markdown-it';
import DOMPurify from 'dompurify';
const md = new MarkdownIt({
html: true,
@ -10,6 +9,13 @@ const md = new MarkdownIt({
export function renderMarkdown(content: string): string {
const dirtyHtml = md.render(content);
return DOMPurify.sanitize(dirtyHtml)
if (typeof window !== 'undefined') {
import('dompurify').then((DOMPurify => {
return DOMPurify.default.sanitize(dirtyHtml)
}))
}
return dirtyHtml
}