Files
novalon-website/docs/plans/2026-02-26-website-feature-completion.md
T

32 KiB
Raw Blame History

网站功能补全实施计划

For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

Goal: 实现网站联系表单邮件发送、服务详情、产品详情、新闻动态完整功能、隐私政策和服务条款页面

Architecture: 采用 Next.js App Router 架构,使用 Resend API 发送邮件,服务详情使用模态框展示,产品详情和新闻详情使用动态路由页面,隐私政策和服务条款使用静态页面。

Tech Stack: Next.js 16, React 19, TypeScript, Resend SDK, Radix UI Dialog, Framer Motion, Zod


实施阶段概览

阶段 1: 联系表单邮件发送(高优先级)

  • 创建 API Route 处理表单提交
  • 实现邮件模板生成
  • 配置环境变量和安全措施
  • 修改前端组件集成 API

阶段 2: 服务详情功能(中优先级)

  • 扩展服务数据结构
  • 创建服务详情模态框组件
  • 修改服务卡片添加交互

阶段 3: 产品详情功能(中优先级)

  • 扩展产品数据结构
  • 创建产品详情页面
  • 创建产品列表页面(可选)
  • 修改产品卡片添加链接

阶段 4: 新闻动态完整功能(中优先级)

  • 扩展新闻数据结构
  • 创建新闻列表页面
  • 完善新闻详情页面
  • 修改新闻卡片添加链接

阶段 5: 隐私政策和服务条款(低优先级)

  • 创建隐私政策页面
  • 创建服务条款页面
  • 修改 Footer 链接

阶段 1: 联系表单邮件发送

Task 1.1: 创建邮件模板工具

Files:

  • Create: src/lib/email-templates.ts

Step 1: 创建邮件模板文件

import { COMPANY_INFO } from './constants';

export interface ContactFormData {
  name: string;
  phone: string;
  email: string;
  message: string;
}

export function generateNotificationEmail(data: ContactFormData): string {
  const submitTime = new Date().toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
  });

  return `
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>官网留言通知</title>
  <style>
    body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; line-height: 1.6; color: #333; margin: 0; padding: 20px; }
    .container { max-width: 600px; margin: 0 auto; background: #fff; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
    .header { background: linear-gradient(135deg, #C41E3A 0%, #1C1C1C 100%); color: #fff; padding: 30px; text-align: center; }
    .header h1 { margin: 0; font-size: 24px; }
    .content { padding: 30px; }
    .info-card { background: #F5F5F5; padding: 20px; border-radius: 6px; margin-bottom: 20px; }
    .info-item { margin-bottom: 12px; }
    .info-label { font-weight: 600; color: #666; font-size: 14px; }
    .info-value { color: #333; font-size: 16px; margin-top: 4px; }
    .message-box { background: #FFFBF5; padding: 20px; border-left: 4px solid #C41E3A; border-radius: 4px; margin-top: 20px; }
    .message-label { font-weight: 600; color: #C41E3A; margin-bottom: 10px; }
    .message-content { color: #333; white-space: pre-wrap; }
    .footer { background: #F5F5F5; padding: 20px; text-align: center; color: #666; font-size: 14px; }
    .cta-button { display: inline-block; background: #C41E3A; color: #fff; text-decoration: none; padding: 12px 24px; border-radius: 4px; margin-top: 20px; }
  </style>
</head>
<body>
  <div class="container">
    <div class="header">
      <h1>📧 官网留言通知</h1>
      <p style="margin: 10px 0 0 0; opacity: 0.9;">${COMPANY_INFO.name}</p>
    </div>
    <div class="content">
      <div class="info-card">
        <div class="info-item">
          <div class="info-label">客户姓名</div>
          <div class="info-value">${data.name}</div>
        </div>
        <div class="info-item">
          <div class="info-label">联系电话</div>
          <div class="info-value">${data.phone}</div>
        </div>
        <div class="info-item">
          <div class="info-label">电子邮箱</div>
          <div class="info-value">${data.email}</div>
        </div>
        <div class="info-item">
          <div class="info-label">提交时间</div>
          <div class="info-value">${submitTime}</div>
        </div>
      </div>
      <div class="message-box">
        <div class="message-label">💬 留言内容</div>
        <div class="message-content">${data.message}</div>
      </div>
      <div style="text-align: center; margin-top: 30px;">
        <a href="mailto:${data.email}" class="cta-button">📩 快速回复</a>
      </div>
    </div>
    <div class="footer">
      <p>此邮件来自 ${COMPANY_INFO.name} 官网联系表单</p>
      <p style="margin: 5px 0 0 0;">${COMPANY_INFO.address}</p>
    </div>
  </div>
</body>
</html>
  `.trim();
}

export function generateConfirmationEmail(data: ContactFormData): string {
  return `
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>感谢您的留言</title>
  <style>
    body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; line-height: 1.6; color: #333; margin: 0; padding: 20px; }
    .container { max-width: 600px; margin: 0 auto; background: #fff; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
    .header { background: linear-gradient(135deg, #C41E3A 0%, #1C1C1C 100%); color: #fff; padding: 40px 30px; text-align: center; }
    .header h1 { margin: 0; font-size: 28px; }
    .header p { margin: 10px 0 0 0; opacity: 0.9; }
    .content { padding: 30px; }
    .success-icon { text-align: center; font-size: 60px; margin-bottom: 20px; }
    .message { background: #FFFBF5; padding: 20px; border-radius: 6px; border-left: 4px solid #C41E3A; margin: 20px 0; }
    .contact-info { background: #F5F5F5; padding: 20px; border-radius: 6px; margin-top: 20px; }
    .contact-item { display: flex; align-items: center; margin-bottom: 12px; }
    .contact-icon { width: 24px; height: 24px; margin-right: 12px; }
    .footer { background: #F5F5F5; padding: 20px; text-align: center; color: #666; font-size: 14px; }
  </style>
</head>
<body>
  <div class="container">
    <div class="header">
      <h1>✅ 感谢您的留言</h1>
      <p>${COMPANY_INFO.name}</p>
    </div>
    <div class="content">
      <div class="success-icon">🎉</div>
      <p style="font-size: 18px; text-align: center; margin-bottom: 20px;">
        尊敬的 <strong>${data.name}</strong>,您好!
      </p>
      <p style="text-align: center; color: #666;">
        我们已收到您的留言,感谢您对${COMPANY_INFO.name}的关注与支持!
      </p>
      <div class="message">
        <p style="margin: 0; font-weight: 600; color: #C41E3A;">📋 您的留言内容</p>
        <p style="margin: 10px 0 0 0; color: #333;">${data.message}</p>
      </div>
      <div style="text-align: center; margin: 20px 0;">
        <p style="color: #C41E3A; font-weight: 600;">⏰ 预计回复时间:2小时内</p>
        <p style="color: #666; font-size: 14px; margin-top: 8px;">工作日 9:00 - 18:00</p>
      </div>
      <div class="contact-info">
        <p style="margin: 0 0 15px 0; font-weight: 600;">📞 联系我们</p>
        <div class="contact-item">
          <span class="contact-icon">📧</span>
          <span>${COMPANY_INFO.email}</span>
        </div>
        <div class="contact-item">
          <span class="contact-icon">📱</span>
          <span>${COMPANY_INFO.phone}</span>
        </div>
        <div class="contact-item">
          <span class="contact-icon">📍</span>
          <span>${COMPANY_INFO.address}</span>
        </div>
      </div>
    </div>
    <div class="footer">
      <p>© ${new Date().getFullYear()} ${COMPANY_INFO.name}. All rights reserved.</p>
    </div>
  </div>
</body>
</html>
  `.trim();
}

Step 2: 验证文件创建成功

Run: ls -la src/lib/email-templates.ts

Expected: 文件已创建

Step 3: Commit

git add src/lib/email-templates.ts
git commit -m "feat: add email templates for contact form"

Task 1.2: 创建 API Route

Files:

  • Create: src/app/api/contact/route.ts

Step 1: 创建 API Route 文件

import { NextRequest, NextResponse } from 'next/server';
import { Resend } from 'resend';
import { z } from 'zod';
import { generateNotificationEmail, generateConfirmationEmail } from '@/lib/email-templates';
import { COMPANY_INFO } from '@/lib/constants';

const contactFormSchema = z.object({
  name: z.string().min(2, '姓名至少需要2个字符').max(50, '姓名不能超过50个字符'),
  phone: z.string().regex(/^1[3-9]\d{9}$/, '请输入有效的手机号码'),
  email: z.string().email('请输入有效的邮箱地址'),
  message: z.string().min(10, '留言内容至少需要10个字符').max(1000, '留言内容不能超过1000字符'),
  csrfToken: z.string().min(1, 'CSRF Token 不能为空'),
});

type ContactFormData = z.infer<typeof contactFormSchema>;

const resend = new Resend(process.env.RESEND_API_KEY);

export async function POST(request: NextRequest) {
  try {
    const body = await request.json();

    const result = contactFormSchema.safeParse(body);

    if (!result.success) {
      const errors = result.error.flatten().fieldErrors;
      return NextResponse.json(
        {
          success: false,
          message: '表单验证失败',
          errors,
        },
        { status: 400 }
      );
    }

    const data: ContactFormData = result.data;

    const companyEmail = process.env.COMPANY_EMAIL || COMPANY_INFO.email;

    const [notificationResult, confirmationResult] = await Promise.all([
      resend.emails.send({
        from: `${COMPANY_INFO.name} <noreply@novalon.cn>`,
        to: [companyEmail],
        subject: `[官网留言] 来自 ${data.name} 的咨询`,
        html: generateNotificationEmail(data),
      }),
      resend.emails.send({
        from: `${COMPANY_INFO.name} <noreply@novalon.cn>`,
        to: [data.email],
        subject: `感谢您的留言 - ${COMPANY_INFO.name}`,
        html: generateConfirmationEmail(data),
      }),
    ]);

    if (notificationResult.error) {
      console.error('Notification email failed:', notificationResult.error);
      return NextResponse.json(
        {
          success: false,
          message: '邮件发送失败,请稍后重试',
        },
        { status: 500 }
      );
    }

    if (confirmationResult.error) {
      console.error('Confirmation email failed:', confirmationResult.error);
    }

    return NextResponse.json({
      success: true,
      message: '邮件发送成功',
    });
  } catch (error) {
    console.error('Contact form error:', error);
    return NextResponse.json(
      {
        success: false,
        message: '服务器错误,请稍后重试',
      },
      { status: 500 }
    );
  }
}

Step 2: 验证文件创建成功

Run: ls -la src/app/api/contact/route.ts

Expected: 文件已创建

Step 3: Commit

git add src/app/api/contact/route.ts
git commit -m "feat: add contact form API route with Resend integration"

Task 1.3: 配置环境变量

Files:

  • Create: .env.local
  • Modify: .gitignore

Step 1: 创建环境变量文件

cat > .env.local << 'EOF'
# Resend API 配置
RESEND_API_KEY=re_xxxxxxxxxxxxxx

# 邮件接收配置
COMPANY_EMAIL=contact@novalon.cn

# 环境标识
NODE_ENV=development
EOF

Step 2: 验证文件创建成功

Run: cat .env.local

Expected: 环境变量文件已创建

Step 3: 更新 .gitignore

Read: .gitignore

Add at end of file:

# Environment variables
.env.local
.env.*.local

Step 4: 验证 .gitignore 更新

Run: tail -5 .gitignore

Expected: 包含 .env.local 相关规则

Step 5: Commit

git add .env.local .gitignore
git commit -m "chore: add environment variables and update gitignore"

Task 1.4: 修改联系表单组件集成 API

Files:

  • Modify: src/components/sections/contact-section.tsx

Step 1: 修改 handleSubmit 函数

Replace: existing handleSubmit function with:

async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
  e.preventDefault();
  
  const storedToken = getCSRFTokenFromStorage();
  if (!storedToken) {
    setToastMessage('安全验证失败,请刷新页面重试。');
    setToastType('error');
    setShowToast(true);
    return;
  }
  
  const result = contactFormSchema.safeParse(formData);
  
  if (!result.success) {
    const fieldErrors: FormErrors = {};
    result.error.issues.forEach((issue) => {
      const field = issue.path[0] as keyof ContactFormData;
      fieldErrors[field] = issue.message;
    });
    setErrors(fieldErrors);
    return;
  }

  setIsSubmitting(true);
  
  try {
    const response = await fetch('/api/contact', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        ...formData,
        csrfToken: storedToken,
      }),
    });

    const data = await response.json();

    if (!response.ok) {
      throw new Error(data.message || '提交失败');
    }

    const newCsrfToken = generateCSRFToken();
    setCSRFTokenToStorage(newCsrfToken);
    
    setIsSubmitting(false);
    setIsSubmitted(true);
    setToastMessage(data.message || '表单提交成功!我们会尽快与您联系。');
    setToastType('success');
    setShowToast(true);
  } catch (error) {
    setIsSubmitting(false);
    const errorMessage = error instanceof Error ? error.message : '提交失败,请稍后重试。';
    setToastMessage(errorMessage);
    setToastType('error');
    setShowToast(true);
  }
}

Step 2: 验证修改

Run: npm run lint

Expected: 无 lint 错误

Step 3: Commit

git add src/components/sections/contact-section.tsx
git commit -m "feat: integrate contact form with API route"

阶段 2: 服务详情功能

Task 2.1: 扩展服务数据结构

Files:

  • Modify: src/lib/constants.ts

Step 1: 扩展 SERVICES 数据

Replace: existing SERVICES array with:

export const SERVICES = [
  {
    id: 'software',
    title: '软件开发',
    description: '提供定制化软件开发服务,包括Web应用、移动应用、企业管理系统等',
    icon: 'Code',
    details: {
      overview: '我们拥有经验丰富的开发团队,能够根据客户需求定制开发各类软件系统。从需求分析、方案设计到开发实施、测试部署,我们提供全流程的软件开发服务,确保交付高质量的软件产品。',
      features: [
        '需求分析与方案设计',
        'UI/UX 设计',
        '前端开发(React/Vue',
        '后端开发(Node.js/Python',
        '数据库设计与优化',
        '测试与部署',
      ],
      benefits: [
        '量身定制的解决方案',
        '高质量代码交付',
        '完善的售后服务',
        '灵活的开发周期',
      ],
      process: [
        { title: '需求调研', description: '深入了解客户业务需求,明确项目目标和范围' },
        { title: '方案设计', description: '制定技术方案和实施计划,进行原型设计' },
        { title: '开发实施', description: '按照敏捷开发模式,分阶段交付功能' },
        { title: '测试验收', description: '全面测试确保质量,客户验收确认' },
        { title: '上线运维', description: '部署上线,提供持续的技术支持' },
      ],
    },
  },
  {
    id: 'cloud',
    title: '云服务',
    description: '提供云计算解决方案,包括云架构设计、云迁移、云运维等服务',
    icon: 'Cloud',
    details: {
      overview: '帮助企业实现云原生转型,提供从云架构设计、云迁移实施到云运维管理的全栈云服务。我们熟悉主流云平台(阿里云、腾讯云、AWS等),能够根据企业需求选择最适合的云解决方案。',
      features: [
        '云架构设计与咨询',
        '云迁移实施',
        '容器化与微服务',
        'DevOps 自动化',
        '云安全与合规',
        '云成本优化',
      ],
      benefits: [
        '提升系统可扩展性',
        '降低IT基础设施成本',
        '提高业务敏捷性',
        '增强数据安全性',
      ],
      process: [
        { title: '云评估', description: '评估现有系统,制定云迁移策略' },
        { title: '架构设计', description: '设计云原生架构,选择合适的服务' },
        { title: '迁移实施', description: '平滑迁移应用和数据,最小化业务中断' },
        { title: '优化调优', description: '优化资源配置,提升性能和成本效益' },
        { title: '运维监控', description: '7×24小时监控,确保系统稳定运行' },
      ],
    },
  },
  {
    id: 'data',
    title: '数据分析',
    description: '提供大数据分析服务,帮助企业挖掘数据价值,支持决策制定',
    icon: 'BarChart3',
    details: {
      overview: '通过数据采集、清洗、分析和可视化,帮助企业从海量数据中挖掘有价值的信息。我们提供从数据平台搭建、数据分析模型构建到数据可视化的全流程数据服务。',
      features: [
        '数据采集与集成',
        '数据仓库建设',
        '数据分析与建模',
        '数据可视化',
        '实时数据监控',
        '预测分析',
      ],
      benefits: [
        '数据驱动决策',
        '发现业务洞察',
        '提升运营效率',
        '优化客户体验',
      ],
      process: [
        { title: '数据评估', description: '评估数据现状,明确分析需求' },
        { title: '平台搭建', description: '搭建数据仓库和分析平台' },
        { title: '模型构建', description: '构建数据分析模型和算法' },
        { title: '可视化开发', description: '开发数据可视化仪表盘' },
        { title: '持续优化', description: '持续优化模型,提升分析准确性' },
      ],
    },
  },
  {
    id: 'security',
    title: '信息安全',
    description: '提供信息安全咨询和解决方案,保护企业数据资产安全',
    icon: 'Shield',
    details: {
      overview: '为企业提供全方位的信息安全解决方案,包括安全评估、安全加固、安全监控等。我们帮助企业建立完善的安全防护体系,保护企业数据资产和业务系统安全。',
      features: [
        '安全评估与审计',
        '安全加固与防护',
        '安全监控与响应',
        '数据加密与脱敏',
        '身份认证与授权',
        '安全培训与咨询',
      ],
      benefits: [
        '降低安全风险',
        '满足合规要求',
        '保护数据资产',
        '提升安全意识',
      ],
      process: [
        { title: '安全评估', description: '全面评估系统安全现状,识别安全风险' },
        { title: '方案设计', description: '制定安全加固方案和应急响应计划' },
        { title: '安全实施', description: '部署安全防护措施,加固系统安全' },
        { title: '监控响应', description: '7×24小时安全监控,及时响应安全事件' },
        { title: '持续改进', description: '定期安全审计,持续优化安全策略' },
      ],
    },
  },
] as const;

Step 2: 验证修改

Run: npm run lint

Expected: 无 lint 错误

Step 3: Commit

git add src/lib/constants.ts
git commit -m "feat: extend services data with detailed information"

Task 2.2: 创建服务详情模态框组件

Files:

  • Create: src/components/services/service-detail-modal.tsx
  • Create: src/lib/types.ts

Step 1: 创建类型定义文件

export interface Service {
  id: string;
  title: string;
  description: string;
  icon: string;
  details?: {
    overview: string;
    features: string[];
    benefits: string[];
    process: Array<{
      title: string;
      description: string;
    }>;
  };
}

export interface Product {
  id: string;
  title: string;
  description: string;
  image: string;
  category: string;
  features: string[];
  benefits: string[];
  details?: {
    overview: string;
    screenshots: string[];
    detailedFeatures: Array<{
      name: string;
      description: string;
      icon: string;
    }>;
    scenarios: string[];
    techStack: string[];
    pricing: {
      type: string;
      startingFrom: string;
      includes: string;
    };
  };
}

export interface News {
  id: string;
  slug: string;
  title: string;
  excerpt: string;
  date: string;
  category: string;
  image: string;
  content: string;
  author?: string;
  views?: number;
  tags?: string[];
  featured?: boolean;
}

Step 2: 创建模态框组件

'use client';

import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Check, ArrowRight } from 'lucide-react';
import { SERVICES } from '@/lib/constants';

interface ServiceDetailModalProps {
  serviceId: string | null;
  open: boolean;
  onOpenChange: (open: boolean) => void;
}

export function ServiceDetailModal({ serviceId, open, onOpenChange }: ServiceDetailModalProps) {
  if (!serviceId) return null;

  const service = SERVICES.find((s) => s.id === serviceId);
  if (!service || !service.details) return null;

  const { details } = service;

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-3xl max-h-[90vh] overflow-y-auto">
        <DialogHeader>
          <DialogTitle className="text-2xl">{service.title}</DialogTitle>
        </DialogHeader>

        <div className="space-y-6">
          <div>
            <h3 className="text-lg font-semibold mb-3">服务概述</h3>
            <p className="text-[#5C5C5C] leading-relaxed">{details.overview}</p>
          </div>

          <div>
            <h3 className="text-lg font-semibold mb-3">核心功能</h3>
            <ul className="space-y-2">
              {details.features.map((feature, idx) => (
                <li key={idx} className="flex items-start gap-2">
                  <Check className="w-5 h-5 text-[#C41E3A] flex-shrink-0 mt-0.5" />
                  <span className="text-[#3D3D3D]">{feature}</span>
                </li>
              ))}
            </ul>
          </div>

          <div>
            <h3 className="text-lg font-semibold mb-3">服务优势</h3>
            <ul className="space-y-2">
              {details.benefits.map((benefit, idx) => (
                <li key={idx} className="flex items-start gap-2">
                  <ArrowRight className="w-5 h-5 text-[#C41E3A] flex-shrink-0 mt-0.5" />
                  <span className="text-[#3D3D3D]">{benefit}</span>
                </li>
              ))}
            </ul>
          </div>

          <div>
            <h3 className="text-lg font-semibold mb-3">服务流程</h3>
            <div className="space-y-4">
              {details.process.map((step, idx) => (
                <div key={idx} className="flex gap-4">
                  <div className="flex-shrink-0 w-8 h-8 rounded-full bg-[#C41E3A] text-white flex items-center justify-center font-semibold">
                    {idx + 1}
                  </div>
                  <div className="flex-1">
                    <h4 className="font-semibold text-[#1C1C1C] mb-1">{step.title}</h4>
                    <p className="text-sm text-[#5C5C5C]">{step.description}</p>
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
}

Step 3: 验证文件创建

Run: ls -la src/components/services/service-detail-modal.tsx src/lib/types.ts

Expected: 文件已创建

Step 4: Commit

git add src/components/services/service-detail-modal.tsx src/lib/types.ts
git commit -m "feat: add service detail modal component"

Task 2.3: 修改服务卡片添加交互

Files:

  • Modify: src/components/sections/services-section.tsx

Step 1: 添加状态和交互逻辑

Add after imports:

import { useState } from 'react';
import { ServiceDetailModal } from '@/components/services/service-detail-modal';

Add inside component before return statement:

const [selectedService, setSelectedService] = useState<string | null>(null);
const [isModalOpen, setIsModalOpen] = useState(false);

const handleServiceClick = (serviceId: string) => {
  setSelectedService(serviceId);
  setIsModalOpen(true);
};

const handleViewAllServices = () => {
  setSelectedService('all');
  setIsModalOpen(true);
};

Replace: Card component with:

<Card 
  className="p-6 h-full group cursor-pointer border-[#E5E5E5] hover:border-[#1C1C1C]"
  onClick={() => handleServiceClick(service.id)}
>

Replace: "查看全部服务" Button with:

<Button 
  variant="outline" 
  size="lg" 
  className="group"
  onClick={handleViewAllServices}
>
  查看全部服务
  <ArrowRight className="ml-2 w-4 h-4 transition-transform group-hover:translate-x-1" />
</Button>

Add before closing </section> tag:

<ServiceDetailModal
  serviceId={selectedService}
  open={isModalOpen}
  onOpenChange={setIsModalOpen}
/>

Step 2: 验证修改

Run: npm run lint

Expected: 无 lint 错误

Step 3: Commit

git add src/components/sections/services-section.tsx
git commit -m "feat: add service detail modal interaction"

阶段 3: 产品详情功能

Task 3.1: 扩展产品数据结构

Files:

  • Modify: src/lib/constants.ts

Step 1: 扩展 PRODUCTS 数据

Replace: existing PRODUCTS array with detailed product data including overview, screenshots, detailedFeatures, scenarios, techStack, and pricing for each product.

Step 2: 验证修改

Run: npm run lint

Expected: 无 lint 错误

Step 3: Commit

git add src/lib/constants.ts
git commit -m "feat: extend products data with detailed information"

Task 3.2: 创建产品详情页面

Files:

  • Create: src/app/(marketing)/products/[id]/page.tsx

Step 1: 创建产品详情页面

Create product detail page with sections for overview, features, scenarios, tech stack, pricing, and CTA.

Step 2: 验证文件创建

Run: ls -la src/app/\(marketing\)/products/\[id\]/page.tsx

Expected: 文件已创建

Step 3: Commit

git add src/app/\(marketing\)/products/\[id\]/page.tsx
git commit -m "feat: add product detail page"

Task 3.3: 创建产品列表页面

Files:

  • Create: src/app/(marketing)/products/page.tsx

Step 1: 创建产品列表页面

Create products list page with grid layout and links to detail pages.

Step 2: 验证文件创建

Run: ls -la src/app/\(marketing\)/products/page.tsx

Expected: 文件已创建

Step 3: Commit

git add src/app/\(marketing\)/products/page.tsx
git commit -m "feat: add products list page"

Task 3.4: 修改产品卡片添加链接

Files:

  • Modify: src/components/sections/products-section.tsx

Step 1: 添加 Link 组件导入

Add to imports:

import Link from 'next/link';

Step 2: 修改 Card 组件

Replace: Card component with Link wrapper.

Step 3: 验证修改

Run: npm run lint

Expected: 无 lint 错误

Step 4: Commit

git add src/components/sections/products-section.tsx
git commit -m "feat: add product detail links"

阶段 4: 新闻动态完整功能

Task 4.1: 扩展新闻数据结构

Files:

  • Modify: src/lib/constants.ts

Step 1: 扩展 NEWS 数据

Replace: existing NEWS array with detailed news data including slug, author, views, tags, and featured fields.

Step 2: 验证修改

Run: npm run lint

Expected: 无 lint 错误

Step 3: Commit

git add src/lib/constants.ts
git commit -m "feat: extend news data with detailed information"

Task 4.2: 创建新闻列表页面

Files:

  • Create: src/app/(marketing)/news/page.tsx

Step 1: 创建新闻列表页面

Create news list page with category filtering, search, and grid layout.

Step 2: 验证文件创建

Run: ls -la src/app/\(marketing\)/news/page.tsx

Expected: 文件已创建

Step 3: Commit

git add src/app/\(marketing\)/news/page.tsx
git commit -m "feat: add news list page with filtering and search"

Task 4.3: 完善新闻详情页面

Files:

  • Modify: src/app/(marketing)/news/[slug]/page.tsx

Step 1: 完善新闻详情页面

Update news detail page with full content display, related news, and sharing functionality.

Step 2: 验证修改

Run: npm run lint

Expected: 无 lint 错误

Step 3: Commit

git add src/app/\(marketing\)/news/\[slug\]/page.tsx
git commit -m "feat: enhance news detail page"

Task 4.4: 修改新闻卡片添加链接

Files:

  • Modify: src/components/sections/news-section.tsx

Step 1: 修改新闻卡片链接

Update news cards to link to detail pages using slug.

Step 2: 验证修改

Run: npm run lint

Expected: 无 lint 错误

Step 3: Commit

git add src/components/sections/news-section.tsx
git commit -m "feat: add news detail links"

阶段 5: 隐私政策和服务条款

Task 5.1: 创建隐私政策页面

Files:

  • Create: src/app/(marketing)/privacy/page.tsx

Step 1: 创建隐私政策页面

Create privacy policy page with sections for data collection, usage, sharing, security, cookies, user rights, and contact information.

Step 2: 验证文件创建

Run: ls -la src/app/\(marketing\)/privacy/page.tsx

Expected: 文件已创建

Step 3: Commit

git add src/app/\(marketing\)/privacy/page.tsx
git commit -m "feat: add privacy policy page"

Task 5.2: 创建服务条款页面

Files:

  • Create: src/app/(marketing)/terms/page.tsx

Step 1: 创建服务条款页面

Create terms of service page with sections for service description, user responsibilities, intellectual property, disclaimer, service changes, dispute resolution, applicable law, and updates.

Step 2: 验证文件创建

Run: ls -la src/app/\(marketing\)/terms/page.tsx

Expected: 文件已创建

Step 3: Commit

git add src/app/\(marketing\)/terms/page.tsx
git commit -m "feat: add terms of service page"

Files:

  • Modify: src/components/layout/footer.tsx

Step 1: 更新 Footer 链接

Update privacy policy and terms of service links to point to the new pages.

Step 2: 验证修改

Run: npm run lint

Expected: 无 lint 错误

Step 3: Commit

git add src/components/layout/footer.tsx
git commit -m "feat: update footer links to privacy and terms pages"

测试计划

阶段 1 测试:联系表单邮件发送

  1. 本地测试

    • 启动开发服务器
    • 填写表单并提交
    • 检查邮件是否收到
  2. 验证测试

    • 测试必填字段
    • 测试无效邮箱格式
    • 测试无效手机号
    • 测试留言长度限制
  3. 安全测试

    • 测试 CSRF Token 验证
    • 测试 XSS 攻击防护

阶段 2 测试:服务详情功能

  1. 点击服务卡片打开详情模态框
  2. 验证所有服务都能正常显示
  3. 测试模态框打开和关闭

阶段 3 测试:产品详情功能

  1. 点击产品卡片跳转到详情页
  2. 验证产品详情页面显示完整
  3. 测试返回列表功能

阶段 4 测试:新闻动态功能

  1. 点击新闻卡片跳转到详情页
  2. 测试新闻列表分类筛选
  3. 测试新闻搜索功能

阶段 5 测试:隐私政策和服务条款

  1. 点击 Footer 链接跳转到对应页面
  2. 验证页面内容完整
  3. 测试返回首页功能

完成标准

  • 所有功能实现完成
  • 所有测试通过
  • 代码通过 lint 检查
  • 类型检查通过
  • 构建成功
  • 所有 commit 已完成
  • 文档已更新(如需要)