diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..35410ca
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..03d9549
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..1a4017e
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/next-10398.iml b/.idea/next-10398.iml
new file mode 100644
index 0000000..24643cc
--- /dev/null
+++ b/.idea/next-10398.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/next.config.ts b/next.config.ts
index e9ffa30..1617a52 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -1,7 +1,68 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
- /* config options here */
+ images: {
+ remotePatterns: [
+ // OSS 图片域名
+ {
+ protocol: 'https',
+ hostname: 'oss.wsdns.cn',
+ port: '',
+ pathname: '/**',
+ },
+ {
+ protocol: 'http',
+ hostname: 'oss.wsdns.cn',
+ port: '',
+ pathname: '/**',
+ },
+ // API 服务器图片
+ {
+ protocol: 'https',
+ hostname: 'cms-api.websoft.top',
+ port: '',
+ pathname: '/**',
+ },
+ {
+ protocol: 'http',
+ hostname: 'cms-api.websoft.top',
+ port: '',
+ pathname: '/**',
+ },
+ // 常见的图片 CDN 域名
+ {
+ protocol: 'https',
+ hostname: '*.aliyuncs.com',
+ port: '',
+ pathname: '/**',
+ },
+ {
+ protocol: 'https',
+ hostname: '*.qiniudn.com',
+ port: '',
+ pathname: '/**',
+ },
+ {
+ protocol: 'https',
+ hostname: '*.qiniu.com',
+ port: '',
+ pathname: '/**',
+ },
+ // 本地开发
+ {
+ protocol: 'http',
+ hostname: 'localhost',
+ port: '',
+ pathname: '/**',
+ },
+ {
+ protocol: 'https',
+ hostname: 'localhost',
+ port: '',
+ pathname: '/**',
+ },
+ ],
+ },
};
export default nextConfig;
diff --git a/src/api/bszx/bszxBm/index.ts b/src/api/bszx/bszxBm/index.ts
index f1cb134..2c25bfd 100644
--- a/src/api/bszx/bszxBm/index.ts
+++ b/src/api/bszx/bszxBm/index.ts
@@ -10,7 +10,7 @@ export async function pageBszxBm(params: BszxBmParam) {
const res = await request.get>>(
MODULES_API_URL + '/bszx/bszx-bm/page',
{
- params: params as Record
+ params
}
);
if (res.data.code === 0) {
@@ -26,7 +26,7 @@ export async function listBszxBm(params?: BszxBmParam) {
const res = await request.get>(
MODULES_API_URL + '/bszx/bszx-bm',
{
- params: params as Record
+ params
}
);
if (res.data.code === 0 && res.data.data) {
diff --git a/src/api/cms/cmsArticle/index.ts b/src/api/cms/cmsArticle/index.ts
index f8feab8..63974a2 100644
--- a/src/api/cms/cmsArticle/index.ts
+++ b/src/api/cms/cmsArticle/index.ts
@@ -7,11 +7,11 @@ import {MODULES_API_URL} from '@/config/setting';
* 分页查询文章
*/
export async function pageCmsArticle(params: CmsArticleParam) {
- const res = await request.get>>(
- MODULES_API_URL + '/cms/cms-article/page',
- {
- params
- }
+ const res = await request.get>(
+ MODULES_API_URL + '/cms/cms-article/page',
+ {
+ params
+ }
);
if (res.data.code === 0) {
return res.data.data;
diff --git a/src/api/index.ts b/src/api/index.ts
index bb82dc6..85c01ed 100644
--- a/src/api/index.ts
+++ b/src/api/index.ts
@@ -3,38 +3,30 @@
* 基于 Fetch API 的现代化请求库
*/
+import { APP_CONFIG } from '@/config/setting';
+
// ==================== 基础类型定义 ====================
/**
* 接口统一返回结果
*/
-export interface ApiResult {
+export interface ApiResult {
// 状态码
code: number;
// 状态信息
message?: string;
// 返回数据
data?: T;
- // 是否成功
- success?: boolean;
- // 时间戳
- timestamp?: string;
}
/**
* 分页查询统一结果
*/
-export interface PageResult {
+export interface PageResult {
// 返回数据
list: T[];
// 总数量
count: number;
- // 当前页
- page?: number;
- // 每页数量
- limit?: number;
- // 总页数
- totalPages?: number;
}
/**
@@ -49,7 +41,7 @@ export interface PageParam {
sort?: string;
sortNum?: string;
// 排序方式, asc升序, desc降序
- order?: 'asc' | 'desc';
+ order?: string;
// 租户ID
tenantId?: number;
// 企业ID
@@ -57,7 +49,7 @@ export interface PageParam {
// 商户ID
merchantId?: number;
merchantName?: string;
- categoryIds?: number[];
+ categoryIds?: any;
// 商品分类
categoryId?: number;
categoryName?: string;
@@ -217,6 +209,26 @@ export class ApiClient {
};
}
+ /**
+ * 为请求数据添加租户ID
+ */
+ private addTenantIdToData(data?: unknown): unknown {
+ // 如果数据为空或不是对象,直接返回
+ if (!data || typeof data !== 'object' || data instanceof FormData) {
+ return data;
+ }
+
+ // 如果是普通对象,添加租户ID
+ if (data.constructor === Object || Array.isArray(data)) {
+ return {
+ ...data as Record
+ };
+ }
+
+ // 其他情况直接返回
+ return data;
+ }
+
/**
* 核心请求方法
*/
@@ -251,6 +263,9 @@ export class ApiClient {
}
}
+ // 添加租户ID头
+ (requestConfig.headers as Record)['TenantId'] = APP_CONFIG.TENANT_ID;
+
// 添加请求体
if (data && ['POST', 'PUT', 'PATCH'].includes(method)) {
if (data instanceof FormData) {
@@ -315,11 +330,16 @@ export class ApiClient {
* GET 请求
*/
async get(url: string, params?: Record, config?: RequestConfig): Promise> {
- if (params) {
+ // 合并租户ID到查询参数
+ const mergedParams: Record = {
+ ...params
+ };
+
+ if (mergedParams) {
const searchParams = new URLSearchParams();
- Object.keys(params).forEach((key) => {
- if (params[key] !== undefined && params[key] !== null) {
- searchParams.append(key, String(params[key]));
+ Object.keys(mergedParams).forEach((key) => {
+ if (mergedParams[key] !== undefined && mergedParams[key] !== null) {
+ searchParams.append(key, String(mergedParams[key]));
}
});
url += `?${searchParams.toString()}`;
@@ -331,14 +351,18 @@ export class ApiClient {
* POST 请求
*/
async post(url: string, data?: unknown, config?: RequestConfig): Promise> {
- return this.request(url, 'POST', data, config);
+ // 为对象数据添加租户ID
+ const mergedData = this.addTenantIdToData(data);
+ return this.request(url, 'POST', mergedData, config);
}
/**
* PUT 请求
*/
async put(url: string, data?: unknown, config?: RequestConfig): Promise> {
- return this.request(url, 'PUT', data, config);
+ // 为对象数据添加租户ID
+ const mergedData = this.addTenantIdToData(data);
+ return this.request(url, 'PUT', mergedData, config);
}
/**
@@ -352,7 +376,9 @@ export class ApiClient {
* PATCH 请求
*/
async patch(url: string, data?: unknown, config?: RequestConfig): Promise> {
- return this.request(url, 'PATCH', data, config);
+ // 为对象数据添加租户ID
+ const mergedData = this.addTenantIdToData(data);
+ return this.request(url, 'PATCH', mergedData, config);
}
}
diff --git a/src/api/system/parameter/index.ts b/src/api/system/parameter/index.ts
index 54ee4b1..158338f 100644
--- a/src/api/system/parameter/index.ts
+++ b/src/api/system/parameter/index.ts
@@ -10,7 +10,7 @@ export async function pageParameter(params: ParameterParam) {
const res = await request.get>>(
SERVER_API_URL + '/system/parameter/page',
{
- params: params as Record
+ params
}
);
if (res.data.code === 0) {
diff --git a/src/app/globals.css b/src/app/globals.css
index a2dc41e..b49f4f5 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -1,26 +1,240 @@
-@import "tailwindcss";
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+/* 企业官网全局样式 */
:root {
- --background: #ffffff;
- --foreground: #171717;
+ --primary-color: #2563eb;
+ --primary-dark: #1d4ed8;
+ --secondary-color: #64748b;
+ --accent-color: #f59e0b;
+ --text-primary: #1f2937;
+ --text-secondary: #6b7280;
+ --text-light: #9ca3af;
+ --bg-primary: #ffffff;
+ --bg-secondary: #f8fafc;
+ --bg-dark: #1f2937;
+ --border-color: #e5e7eb;
}
-@theme inline {
- --color-background: var(--background);
- --color-foreground: var(--foreground);
- --font-sans: var(--font-geist-sans);
- --font-mono: var(--font-geist-mono);
+* {
+ box-sizing: border-box;
+ padding: 0;
+ margin: 0;
}
-@media (prefers-color-scheme: dark) {
- :root {
- --background: #0a0a0a;
- --foreground: #ededed;
- }
+html,
+body {
+ max-width: 100vw;
+ overflow-x: hidden;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
+ sans-serif;
+ line-height: 1.6;
+ color: var(--text-primary);
}
body {
- background: var(--background);
- color: var(--foreground);
- font-family: Arial, Helvetica, sans-serif;
+ background-color: var(--bg-primary);
+}
+
+a {
+ color: inherit;
+ text-decoration: none;
+ transition: color 0.3s ease;
+}
+
+a:hover {
+ color: var(--primary-color);
+}
+
+/* 通用组件样式 */
+.container {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 0 1rem;
+}
+
+.btn {
+ @apply inline-flex items-center justify-center px-6 py-3 text-sm font-medium rounded-lg transition-all duration-300 cursor-pointer;
+}
+
+.btn-primary {
+ @apply bg-blue-600 text-white hover:bg-blue-700 focus:ring-4 focus:ring-blue-200;
+}
+
+.btn-secondary {
+ @apply bg-gray-100 text-gray-900 hover:bg-gray-200 focus:ring-4 focus:ring-gray-100;
+}
+
+.btn-outline {
+ @apply border-2 border-blue-600 text-blue-600 hover:bg-blue-600 hover:text-white focus:ring-4 focus:ring-blue-200;
+}
+
+.card {
+ @apply bg-white rounded-lg shadow-md overflow-hidden transition-shadow duration-300 hover:shadow-lg;
+}
+
+.section-padding {
+ @apply py-16 lg:py-24;
+}
+
+.section-title {
+ @apply text-3xl lg:text-4xl font-bold text-center mb-4;
+}
+
+.section-subtitle {
+ @apply text-lg text-gray-600 text-center mb-12 max-w-2xl mx-auto;
+}
+
+/* 导航栏样式 */
+.navbar {
+ @apply bg-white shadow-sm border-b border-gray-100 sticky top-0 z-50;
+}
+
+.navbar-brand {
+ @apply text-2xl font-bold text-blue-600;
+}
+
+.navbar-nav {
+ @apply flex items-center space-x-8;
+}
+
+.navbar-link {
+ @apply text-gray-700 hover:text-blue-600 font-medium transition-colors duration-300;
+}
+
+.navbar-link.active {
+ @apply text-blue-600;
+}
+
+/* 英雄区域样式 */
+.hero {
+ @apply bg-gradient-to-br from-blue-50 to-indigo-100 py-20 lg:py-32;
+}
+
+.hero-title {
+ @apply text-4xl lg:text-6xl font-bold text-gray-900 mb-6;
+}
+
+.hero-subtitle {
+ @apply text-xl lg:text-2xl text-gray-600 mb-8 max-w-3xl;
+}
+
+/* 特色区域样式 */
+.feature-card {
+ @apply text-center p-8 rounded-lg bg-white shadow-sm hover:shadow-md transition-shadow duration-300;
+}
+
+.feature-icon {
+ @apply w-16 h-16 mx-auto mb-6 text-blue-600;
+}
+
+.feature-title {
+ @apply text-xl font-semibold mb-4;
+}
+
+.feature-description {
+ @apply text-gray-600;
+}
+
+/* 文章卡片样式 */
+.article-card {
+ @apply bg-white rounded-lg shadow-sm overflow-hidden hover:shadow-md transition-shadow duration-300;
+}
+
+.article-image {
+ @apply w-full h-48 object-cover;
+}
+
+.article-content {
+ @apply p-6;
+}
+
+.article-category {
+ @apply inline-block px-3 py-1 text-xs font-medium bg-blue-100 text-blue-800 rounded-full mb-3;
+}
+
+.article-title {
+ @apply text-xl font-semibold mb-3 hover:text-blue-600 transition-colors duration-300;
+}
+
+.article-excerpt {
+ @apply text-gray-600 mb-4 line-clamp-3;
+}
+
+.article-meta {
+ @apply flex items-center justify-between text-sm text-gray-500;
+}
+
+/* 页脚样式 */
+.footer {
+ @apply bg-gray-900 text-white py-12;
+}
+
+.footer-section {
+ @apply mb-8 lg:mb-0;
+}
+
+.footer-title {
+ @apply text-lg font-semibold mb-4;
+}
+
+.footer-link {
+ @apply text-gray-300 hover:text-white transition-colors duration-300;
+}
+
+/* 响应式样式 */
+@media (max-width: 768px) {
+ .container {
+ padding: 0 1rem;
+ }
+
+ .hero-title {
+ @apply text-3xl lg:text-4xl;
+ }
+
+ .hero-subtitle {
+ @apply text-lg;
+ }
+
+ .section-title {
+ @apply text-2xl lg:text-3xl;
+ }
+}
+
+/* 动画效果 */
+@keyframes fadeInUp {
+ from {
+ opacity: 0;
+ transform: translateY(30px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+.fade-in-up {
+ animation: fadeInUp 0.6s ease-out;
+}
+
+/* 加载动画 */
+.loading {
+ @apply inline-block w-6 h-6 border-2 border-gray-300 border-t-blue-600 rounded-full animate-spin;
+}
+
+/* 文本截断 */
+.line-clamp-2 {
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+.line-clamp-3 {
+ display: -webkit-box;
+ -webkit-line-clamp: 3;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index f7fa87e..c6bd764 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,20 +1,25 @@
import type { Metadata } from "next";
-import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
-
-const geistSans = Geist({
- variable: "--font-geist-sans",
- subsets: ["latin"],
-});
-
-const geistMono = Geist_Mono({
- variable: "--font-geist-mono",
- subsets: ["latin"],
-});
+import Header from "@/components/layout/Header";
+import Footer from "@/components/layout/Footer";
export const metadata: Metadata = {
- title: "Create Next App",
- description: "Generated by create next app",
+ title: "企业官网 - 专业的企业解决方案服务商",
+ description: "我们致力于为企业提供全方位的数字化转型服务,以创新技术驱动业务增长,助力企业在数字时代取得成功。",
+ keywords: "企业官网,数字化转型,企业服务,解决方案,技术服务",
+ authors: [{ name: "企业官网" }],
+ robots: "index, follow",
+ openGraph: {
+ title: "企业官网 - 专业的企业解决方案服务商",
+ description: "我们致力于为企业提供全方位的数字化转型服务,以创新技术驱动业务增长,助力企业在数字时代取得成功。",
+ type: "website",
+ locale: "zh_CN",
+ },
+};
+
+export const viewport = {
+ width: 'device-width',
+ initialScale: 1,
};
export default function RootLayout({
@@ -23,11 +28,11 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
-
-
- {children}
+
+
+
+ {children}
+
);
diff --git a/src/app/page.tsx b/src/app/page.tsx
index e68abe6..470f326 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,103 +1,26 @@
-import Image from "next/image";
+import HeroSection from '@/components/sections/HeroSection';
+import FeaturesSection from '@/components/sections/FeaturesSection';
+import AboutSection from '@/components/sections/AboutSection';
+import ArticlesSection from '@/components/sections/ArticlesSection';
+import ContactSection from '@/components/sections/ContactSection';
export default function Home() {
return (
-
-
-
-
- -
- Get started by editing{" "}
-
- src/app/page.tsx
-
- .
-
- -
- Save and see your changes instantly.
-
-
+
+ {/* 英雄区域 */}
+
-
-
-
-
+ {/* 特色服务 */}
+
+
+ {/* 关于我们 */}
+
+
+ {/* 最新文章 */}
+
+
+ {/* 联系我们 */}
+
+
);
}
diff --git a/src/config/setting.ts b/src/config/setting.ts
index a195274..0d8c2e8 100644
--- a/src/config/setting.ts
+++ b/src/config/setting.ts
@@ -8,7 +8,7 @@
/**
* 服务器 API 地址
*/
-export const SERVER_API_URL = 'https://cms-api.websoft.top/api';
+export const SERVER_API_URL = 'https://server.gxwebsoft.com/api';
/**
* 模块 API 地址
@@ -28,16 +28,16 @@ export const UPLOAD_API_URL = 'https://cms-api.websoft.top/api/upload';
export const ENV_CONFIG = {
// 当前环境
NODE_ENV: process.env.NODE_ENV || 'development',
-
+
// 是否为开发环境
isDevelopment: process.env.NODE_ENV === 'development',
-
+
// 是否为生产环境
isProduction: process.env.NODE_ENV === 'production',
-
+
// API 基础地址(可通过环境变量覆盖)
API_BASE_URL: process.env.NEXT_PUBLIC_API_URL || SERVER_API_URL,
-
+
// 上传地址(可通过环境变量覆盖)
UPLOAD_URL: process.env.NEXT_PUBLIC_UPLOAD_URL || UPLOAD_API_URL,
} as const;
@@ -50,42 +50,45 @@ export const ENV_CONFIG = {
export const APP_CONFIG = {
// 应用名称
APP_NAME: '内容管理系统',
-
+
// 应用版本
APP_VERSION: '1.0.0',
-
+
// 应用描述
APP_DESCRIPTION: '基于 Next.js 的内容管理系统',
-
+
// 默认语言
DEFAULT_LANG: 'zh-CN',
-
+
// 支持的语言
SUPPORTED_LANGS: ['zh-CN', 'en-US'],
-
+
// 默认分页大小
DEFAULT_PAGE_SIZE: 10,
-
+
// 最大分页大小
MAX_PAGE_SIZE: 100,
-
+
// 请求超时时间(毫秒)
REQUEST_TIMEOUT: 10000,
-
+
// Token 过期时间(毫秒)
TOKEN_EXPIRE_TIME: 24 * 60 * 60 * 1000, // 24小时
-
+
+ // 租户ID配置
+ TENANT_ID: process.env.NEXT_PUBLIC_TENANT_ID || '10398',
+
// 文件上传限制
UPLOAD_LIMITS: {
// 图片文件大小限制(字节)
IMAGE_MAX_SIZE: 5 * 1024 * 1024, // 5MB
-
+
// 文档文件大小限制(字节)
DOCUMENT_MAX_SIZE: 10 * 1024 * 1024, // 10MB
-
+
// 支持的图片格式
IMAGE_TYPES: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
-
+
// 支持的文档格式
DOCUMENT_TYPES: [
'application/pdf',
@@ -106,16 +109,16 @@ export const APP_CONFIG = {
export const ROUTE_CONFIG = {
// 登录页面
LOGIN_PAGE: '/login',
-
+
// 首页
HOME_PAGE: '/',
-
+
// 404 页面
NOT_FOUND_PAGE: '/404',
-
+
// 无权限页面
FORBIDDEN_PAGE: '/403',
-
+
// 服务器错误页面
ERROR_PAGE: '/500',
} as const;
@@ -128,10 +131,10 @@ export const ROUTE_CONFIG = {
export const CACHE_CONFIG = {
// 用户信息缓存时间(毫秒)
USER_INFO_CACHE_TIME: 30 * 60 * 1000, // 30分钟
-
+
// 菜单缓存时间(毫秒)
MENU_CACHE_TIME: 60 * 60 * 1000, // 1小时
-
+
// 字典缓存时间(毫秒)
DICT_CACHE_TIME: 24 * 60 * 60 * 1000, // 24小时
} as const;
@@ -144,19 +147,19 @@ export const CACHE_CONFIG = {
export const THEME_CONFIG = {
// 默认主题
DEFAULT_THEME: 'light',
-
+
// 支持的主题
THEMES: ['light', 'dark', 'auto'],
-
+
// 主色调
PRIMARY_COLOR: '#1890ff',
-
+
// 成功色
SUCCESS_COLOR: '#52c41a',
-
+
// 警告色
WARNING_COLOR: '#faad14',
-
+
// 错误色
ERROR_COLOR: '#f5222d',
} as const;
diff --git a/src/utils/request.ts b/src/utils/request.ts
index d58a5d4..fef1b86 100644
--- a/src/utils/request.ts
+++ b/src/utils/request.ts
@@ -12,8 +12,8 @@ const request = {
/**
* GET 请求
*/
- get: (url: string, options?: { params?: Record } & RequestConfig): Promise<{ data: ApiResult }> => {
- return apiRequest.get(url, options?.params, options).then(data => ({ data }));
+ get: (url: string, options?: { params?: unknown } & RequestConfig): Promise<{ data: ApiResult }> => {
+ return apiRequest.get(url, options?.params as Record, options).then(data => ({ data }));
},
/**
diff --git a/tsconfig.json b/tsconfig.json
index c133409..fd8d7e7 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -13,6 +13,7 @@
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
+ "baseUrl": ".",
"plugins": [
{
"name": "next"