nsgm-cli 2.1.20 → 2.1.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/README.md +40 -0
  2. package/client/components/Button.tsx +2 -4
  3. package/client/components/ClientProviders.tsx +12 -12
  4. package/client/components/LanguageSwitcher.tsx +26 -26
  5. package/client/components/SSRSafeAntdProvider.tsx +7 -7
  6. package/client/components/SuppressHydrationWarnings.tsx +30 -30
  7. package/client/components/__tests__/Button.test.tsx +12 -12
  8. package/client/layout/index.tsx +122 -124
  9. package/client/redux/reducers.ts +2 -2
  10. package/client/redux/store.ts +24 -24
  11. package/client/redux/template/manage/actions.ts +40 -40
  12. package/client/redux/template/manage/reducers.ts +32 -32
  13. package/client/redux/template/manage/types.ts +19 -19
  14. package/client/service/template/manage.ts +29 -29
  15. package/client/styled/common.ts +6 -6
  16. package/client/styled/layout/index.ts +17 -17
  17. package/client/styled/template/manage.ts +19 -19
  18. package/client/utils/common.ts +52 -54
  19. package/client/utils/cookie.ts +30 -30
  20. package/client/utils/fetch.ts +111 -111
  21. package/client/utils/i18n.ts +41 -41
  22. package/client/utils/menu.tsx +11 -12
  23. package/client/utils/navigation.ts +22 -22
  24. package/client/utils/sso.ts +124 -124
  25. package/client/utils/suppressWarnings.ts +17 -17
  26. package/generation/client/utils/menu.tsx +0 -1
  27. package/jest.config.js +4 -4
  28. package/lib/args.js +19 -19
  29. package/lib/cli/app.d.ts +1 -1
  30. package/lib/cli/app.js +2 -2
  31. package/lib/cli/commands/build.d.ts +1 -1
  32. package/lib/cli/commands/build.js +9 -9
  33. package/lib/cli/commands/create.d.ts +1 -1
  34. package/lib/cli/commands/create.js +36 -36
  35. package/lib/cli/commands/delete.d.ts +1 -1
  36. package/lib/cli/commands/delete.js +55 -55
  37. package/lib/cli/commands/export.d.ts +1 -1
  38. package/lib/cli/commands/export.js +12 -12
  39. package/lib/cli/commands/help.d.ts +1 -1
  40. package/lib/cli/commands/help.js +29 -29
  41. package/lib/cli/commands/init.d.ts +1 -1
  42. package/lib/cli/commands/init.js +31 -31
  43. package/lib/cli/commands/server.d.ts +1 -1
  44. package/lib/cli/commands/server.js +12 -12
  45. package/lib/cli/commands/upgrade.d.ts +1 -1
  46. package/lib/cli/commands/upgrade.js +13 -13
  47. package/lib/cli/commands/version.d.ts +1 -1
  48. package/lib/cli/commands/version.js +7 -7
  49. package/lib/cli/index.d.ts +13 -13
  50. package/lib/cli/parser.d.ts +1 -1
  51. package/lib/cli/parser.js +12 -12
  52. package/lib/cli/registry.d.ts +1 -1
  53. package/lib/cli/types.d.ts +2 -2
  54. package/lib/cli/utils/console.d.ts +2 -2
  55. package/lib/cli/utils/console.js +22 -22
  56. package/lib/cli/utils/index.d.ts +2 -2
  57. package/lib/cli/utils/prompt.d.ts +1 -1
  58. package/lib/cli/utils/prompt.js +98 -98
  59. package/lib/constants.js +28 -28
  60. package/lib/generate.d.ts +2 -2
  61. package/lib/generate.js +19 -19
  62. package/lib/generate_create.d.ts +1 -1
  63. package/lib/generate_create.js +38 -38
  64. package/lib/generate_delete.js +63 -63
  65. package/lib/generate_init.js +93 -93
  66. package/lib/generators/base-generator.d.ts +1 -1
  67. package/lib/generators/base-generator.js +23 -23
  68. package/lib/generators/file-generator.js +15 -15
  69. package/lib/generators/generator-factory.d.ts +5 -5
  70. package/lib/generators/i18n-generator.d.ts +1 -1
  71. package/lib/generators/i18n-generator.js +127 -127
  72. package/lib/generators/page-generator.d.ts +1 -1
  73. package/lib/generators/page-generator.js +25 -25
  74. package/lib/generators/resolver-generator.d.ts +1 -1
  75. package/lib/generators/resolver-generator.js +27 -27
  76. package/lib/generators/schema-generator.d.ts +1 -1
  77. package/lib/generators/schema-generator.js +4 -4
  78. package/lib/generators/service-generator.d.ts +1 -1
  79. package/lib/generators/service-generator.js +29 -29
  80. package/lib/generators/sql-generator.d.ts +1 -1
  81. package/lib/generators/sql-generator.js +10 -10
  82. package/lib/index.js +33 -30
  83. package/lib/server/csrf.d.ts +3 -3
  84. package/lib/server/csrf.js +20 -20
  85. package/lib/server/db.d.ts +1 -1
  86. package/lib/server/db.js +21 -21
  87. package/lib/server/graphql.js +26 -26
  88. package/lib/server/plugins/date.d.ts +1 -1
  89. package/lib/server/plugins/date.js +6 -6
  90. package/lib/server/utils/graphql-cache.js +5 -5
  91. package/lib/tsconfig.build.tsbuildinfo +1 -1
  92. package/lib/utils/project-config.d.ts +1 -1
  93. package/lib/utils/project-config.js +20 -20
  94. package/lib/utils.js +3 -3
  95. package/next-env.d.ts +1 -0
  96. package/next.config.js +15 -109
  97. package/package.json +5 -3
  98. package/pages/_app.tsx +62 -65
  99. package/pages/_document.tsx +14 -15
  100. package/pages/_error.tsx +25 -26
  101. package/pages/index.tsx +47 -48
  102. package/pages/login.tsx +64 -64
  103. package/pages/template/manage.tsx +175 -175
@@ -1,4 +1,4 @@
1
- import { ProjectConfig } from '../cli/types/project';
1
+ import { ProjectConfig } from "../cli/types/project";
2
2
  /**
3
3
  * 应用项目配置到生成的文件中
4
4
  */
@@ -52,17 +52,17 @@ function applyProjectConfig(projectPath, config) {
52
52
  */
53
53
  function ensureDefaultFeatures(config) {
54
54
  console.log(`✅ 项目已配置默认功能栈: Next.js + Styled Components + GraphQL + MySQL + TypeScript + ESLint`);
55
- console.log(`✅ 数据库配置: ${config.database ? '已启用' : '未启用'}`);
56
- console.log(`✅ 包含功能: ${config.features.join(', ')}`);
55
+ console.log(`✅ 数据库配置: ${config.database ? "已启用" : "未启用"}`);
56
+ console.log(`✅ 包含功能: ${config.features.join(", ")}`);
57
57
  }
58
58
  /**
59
59
  * 更新 package.json 文件
60
60
  */
61
61
  function updatePackageJson(projectPath, config) {
62
- const packageJsonPath = path.join(projectPath, 'package.json');
62
+ const packageJsonPath = path.join(projectPath, "package.json");
63
63
  if (fs.existsSync(packageJsonPath)) {
64
64
  try {
65
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
65
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
66
66
  // 更新基本信息
67
67
  packageJson.name = config.projectName;
68
68
  packageJson.description = config.description;
@@ -90,49 +90,49 @@ function updatePackageJson(projectPath, config) {
90
90
  * 更新 README.md 文件
91
91
  */
92
92
  function updateReadme(projectPath, config) {
93
- const readmePath = path.join(projectPath, 'README.md');
93
+ const readmePath = path.join(projectPath, "README.md");
94
94
  if (fs.existsSync(readmePath)) {
95
95
  try {
96
- let readmeContent = fs.readFileSync(readmePath, 'utf8');
96
+ let readmeContent = fs.readFileSync(readmePath, "utf8");
97
97
  // 替换项目名称
98
98
  readmeContent = readmeContent.replace(/nsgm-cli-project/g, config.projectName);
99
99
  // 如果有描述,添加到 README 开头
100
- if (config.description && config.description !== 'A NSGM fullstack project') {
100
+ if (config.description && config.description !== "A NSGM fullstack project") {
101
101
  const descriptionSection = `# ${config.projectName}\n\n${config.description}\n\n`;
102
102
  // 检查是否已经有项目名称标题
103
- if (readmeContent.startsWith('# ')) {
103
+ if (readmeContent.startsWith("# ")) {
104
104
  // 替换第一行
105
- const lines = readmeContent.split('\n');
105
+ const lines = readmeContent.split("\n");
106
106
  lines[0] = `# ${config.projectName}`;
107
- if (lines[1] === '' && lines[2] && !lines[2].startsWith('#')) {
107
+ if (lines[1] === "" && lines[2] && !lines[2].startsWith("#")) {
108
108
  lines[2] = config.description;
109
109
  }
110
110
  else {
111
- lines.splice(2, 0, '', config.description);
111
+ lines.splice(2, 0, "", config.description);
112
112
  }
113
- readmeContent = lines.join('\n');
113
+ readmeContent = lines.join("\n");
114
114
  }
115
115
  else {
116
116
  readmeContent = descriptionSection + readmeContent;
117
117
  }
118
118
  }
119
119
  // 添加作者信息
120
- if (config.author && config.author !== 'Your Name') {
120
+ if (config.author && config.author !== "Your Name") {
121
121
  const authorSection = `\n## 作者\n\n${config.author}\n`;
122
122
  readmeContent += authorSection;
123
123
  }
124
124
  // 添加功能说明
125
125
  if (config.features.length > 0) {
126
126
  const featureMap = {
127
- nextjs: 'Next.js 全栈框架',
128
- styled: 'Styled Components CSS-in-JS',
129
- graphql: 'GraphQL API',
130
- mysql: 'MySQL 数据库',
131
- typescript: 'TypeScript 强类型支持',
132
- eslint: 'ESLint 代码质量检查',
127
+ nextjs: "Next.js 全栈框架",
128
+ styled: "Styled Components CSS-in-JS",
129
+ graphql: "GraphQL API",
130
+ mysql: "MySQL 数据库",
131
+ typescript: "TypeScript 强类型支持",
132
+ eslint: "ESLint 代码质量检查",
133
133
  };
134
134
  const featureNames = config.features.map((feature) => featureMap[feature] || feature);
135
- const featuresSection = `\n## 技术栈\n\n${featureNames.map((feature) => `- ${feature}`).join('\n')}\n`;
135
+ const featuresSection = `\n## 技术栈\n\n${featureNames.map((feature) => `- ${feature}`).join("\n")}\n`;
136
136
  readmeContent += featuresSection;
137
137
  }
138
138
  fs.writeFileSync(readmePath, readmeContent);
package/lib/utils.js CHANGED
@@ -84,18 +84,18 @@ const handleReplace = ({ regex, replacement, paths }) => {
84
84
  exports.handleReplace = handleReplace;
85
85
  const replaceInFileAll = async (array, index = 0, callback) => {
86
86
  if (replaceInFileFlag) {
87
- console.log('replaceInFileAll', index);
87
+ console.log("replaceInFileAll", index);
88
88
  const arrayLen = array.length;
89
89
  if (index < arrayLen) {
90
90
  const item = array[index];
91
91
  (0, replace_in_file_1.replaceInFile)(item)
92
92
  .then((changedFiles) => {
93
- console.log('Modified files:', changedFiles);
93
+ console.log("Modified files:", changedFiles);
94
94
  (0, exports.replaceInFileAll)(array, ++index, callback);
95
95
  })
96
96
  .catch((error) => {
97
97
  if (error) {
98
- console.error('Error occurred:', error);
98
+ console.error("Error occurred:", error);
99
99
  }
100
100
  });
101
101
  }
package/next-env.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  /// <reference types="next" />
2
2
  /// <reference types="next/image-types/global" />
3
+ import "./build/types/routes.d.ts";
3
4
 
4
5
  // NOTE: This file should not be edited
5
6
  // see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
package/next.config.js CHANGED
@@ -40,21 +40,19 @@ module.exports = (phase, defaultConfig, options) => {
40
40
  prefix = ''
41
41
  }
42
42
 
43
+ // 设置环境变量用于客户端访问
44
+ process.env.NEXT_PUBLIC_VERSION = version
45
+ process.env.NEXT_PUBLIC_PREFIX = prefix
46
+ process.env.NEXT_PUBLIC_PROTOCOL = protocol
47
+ process.env.NEXT_PUBLIC_HOST = host
48
+ process.env.NEXT_PUBLIC_PORT = port
49
+ process.env.NEXT_PUBLIC_ENV = env
50
+ process.env.NEXT_PUBLIC_IS_EXPORT = phase === PHASE_EXPORT ? 'true' : 'false'
51
+
43
52
  let configObj = {
44
53
  // target: 'serverless',
45
54
  // crossOrign: 'anonymous',
46
55
  i18n,
47
- serverRuntimeConfig: {},
48
- publicRuntimeConfig: {
49
- version,
50
- prefix,
51
- protocol,
52
- host,
53
- port,
54
- env,
55
- phase,
56
- isExport: phase === PHASE_EXPORT,
57
- },
58
56
  transpilePackages: [
59
57
  'antd',
60
58
  '@ant-design',
@@ -90,114 +88,22 @@ module.exports = (phase, defaultConfig, options) => {
90
88
  '127.0.0.1',
91
89
  'localhost',
92
90
  ],
93
- webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
94
- // 抑制服务端渲染时的 useLayoutEffect 警告
95
- if (dev && isServer) {
96
- const originalWarn = console.warn
97
- const originalError = console.error
98
-
99
- console.warn = (...args) => {
100
- const warnMessage = args[0]
101
- if (
102
- typeof warnMessage === 'string' &&
103
- (warnMessage.includes('useLayoutEffect does nothing on the server') ||
104
- warnMessage.includes('Warning: useLayoutEffect does nothing on the server'))
105
- ) {
106
- return
107
- }
108
- originalWarn.apply(console, args)
109
- }
110
-
111
- console.error = (...args) => {
112
- const errorMessage = args[0]
113
- if (
114
- typeof errorMessage === 'string' &&
115
- (errorMessage.includes('useLayoutEffect does nothing on the server') ||
116
- errorMessage.includes('Warning: useLayoutEffect does nothing on the server'))
117
- ) {
118
- return
119
- }
120
- originalError.apply(console, args)
121
- }
122
- }
123
-
124
- // 启用压缩
125
- if (!dev && !isServer) {
126
- config.optimization = {
127
- ...config.optimization,
128
- splitChunks: {
129
- chunks: 'all',
130
- cacheGroups: {
131
- vendor: {
132
- test: /[\\/]node_modules[\\/]/,
133
- name: 'vendors',
134
- chunks: 'all',
135
- enforce: true,
136
- },
137
- antd: {
138
- test: /[\\/]node_modules[\\/](antd|@ant-design)[\\/]/,
139
- name: 'antd',
140
- chunks: 'all',
141
- priority: 10,
142
- },
143
- react: {
144
- test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
145
- name: 'react',
146
- chunks: 'all',
147
- priority: 10,
148
- },
149
- common: {
150
- name: 'common',
151
- minChunks: 2,
152
- chunks: 'all',
153
- priority: 5,
154
- },
155
- },
156
- },
157
- minimize: true,
158
- }
159
-
160
- // 添加分析工具
161
- if (process.env.ANALYZE === 'true') {
162
- const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
163
- config.plugins.push(
164
- new BundleAnalyzerPlugin({
165
- analyzerMode: 'static',
166
- openAnalyzer: false,
167
- })
168
- )
169
- }
170
- }
171
-
172
- // 优化模块解析
173
- config.resolve.alias = {
174
- ...config.resolve.alias,
175
- '@': path.resolve(__dirname, 'client'),
176
- }
177
-
178
- // 支持 TypeScript 路径映射
179
- config.resolve.modules = [path.resolve(__dirname, 'client'), 'node_modules']
180
-
181
- return config
182
- },
91
+ // 使用 Turbopack(Next.js 16 默认)
92
+ turbopack: {},
183
93
  generateBuildId: async () => {
184
94
  return 'nsgm-cli-' + version
185
95
  },
186
- exportPathMap: async function (defaultPathMap, { dev, dir, outDir }) {
187
- if (dev) {
188
- return defaultPathMap
189
- }
190
-
191
- return defaultPathMap
192
- },
193
96
  generateEtags: false,
194
97
  useFileSystemPublicRoutes: true,
195
98
  }
196
99
 
197
100
  if (phase !== PHASE_DEVELOPMENT_SERVER) {
101
+ // 在 Vercel 环境中使用默认的 .next 目录,否则使用 build 目录
102
+ const distDir = process.env.VERCEL ? '.next' : 'build'
103
+
198
104
  configObj = {
199
105
  ...configObj,
200
- distDir: 'build',
106
+ distDir,
201
107
  assetPrefix: prefix,
202
108
  async rewrites() {
203
109
  return [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nsgm-cli",
3
- "version": "2.1.20",
3
+ "version": "2.1.22",
4
4
  "description": "A CLI tool to run Next/Style-components and Graphql/Mysql fullstack project",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -33,7 +33,9 @@
33
33
  "test:coverage": "jest --coverage",
34
34
  "test:watch": "jest --watch",
35
35
  "performance": "./scripts/performance-check.sh",
36
- "generate-password": "node scripts/generate-password-hash.js"
36
+ "generate-password": "node scripts/generate-password-hash.js",
37
+ "vercel-build": "npm run tsbuild && npm run build",
38
+ "vercel-dev": "npm run tsbuild && npm run dev"
37
39
  },
38
40
  "repository": {
39
41
  "type": "git",
@@ -105,7 +107,7 @@
105
107
  "lusca": "1.7.0",
106
108
  "markdown-it": "14.1.0",
107
109
  "mysql2": "3.14.2",
108
- "next": "15.4.4",
110
+ "next": "16.1.0",
109
111
  "next-i18next": "15.3.0",
110
112
  "ora": "8.2.0",
111
113
  "rc-util": "5.44.4",
package/pages/_app.tsx CHANGED
@@ -1,104 +1,104 @@
1
1
  // 必须在所有其他导入之前执行
2
- import '@/utils/suppressWarnings'
3
-
4
- import React, { useEffect, useState } from 'react'
5
- import { Provider } from 'react-redux'
6
- import { Spin } from 'antd'
7
- import { appWithTranslation } from 'next-i18next'
8
- import { useRouter } from 'next/router'
9
- import { useStore } from '@/redux/store'
10
- import { Loading } from '@/styled/common'
11
- import LayoutComponent from '@/layout'
12
- import ClientProviders from '@/components/ClientProviders'
13
- import SuppressHydrationWarnings from '@/components/SuppressHydrationWarnings'
14
- import SSRSafeAntdProvider from '@/components/SSRSafeAntdProvider'
15
- import { login } from '@/utils/sso'
16
- import { getAntdLocale } from '@/utils/i18n'
17
- import { navigateToLogin } from '@/utils/navigation'
18
- import nextI18NextConfig from '../next-i18next.config.js'
19
- import 'antd/dist/reset.css'
2
+ import "@/utils/suppressWarnings";
3
+
4
+ import { useEffect, useState } from "react";
5
+ import { Provider } from "react-redux";
6
+ import { Spin } from "antd";
7
+ import { appWithTranslation } from "next-i18next";
8
+ import { useRouter } from "next/router";
9
+ import { useStore } from "@/redux/store";
10
+ import { Loading } from "@/styled/common";
11
+ import LayoutComponent from "@/layout";
12
+ import ClientProviders from "@/components/ClientProviders";
13
+ import SuppressHydrationWarnings from "@/components/SuppressHydrationWarnings";
14
+ import SSRSafeAntdProvider from "@/components/SSRSafeAntdProvider";
15
+ import { login } from "@/utils/sso";
16
+ import { getAntdLocale } from "@/utils/i18n";
17
+ import { navigateToLogin } from "@/utils/navigation";
18
+ import nextI18NextConfig from "../next-i18next.config.js";
19
+ import "antd/dist/reset.css";
20
20
 
21
21
  const theme = {
22
22
  colors: {
23
- primary: '#0070f3',
23
+ primary: "#0070f3",
24
24
  },
25
- }
25
+ };
26
26
 
27
27
  const App = ({ Component, pageProps }) => {
28
- const store = useStore(pageProps.initialReduxState)
29
- const router = useRouter()
30
- const [ssoUser, setSsoUser] = useState(null)
31
- const [pageLoad, setPageLoad] = useState(false)
32
- const [loginChecked, setLoginChecked] = useState(false)
33
- const [mounted, setMounted] = useState(false)
34
- const [currentLocale, setCurrentLocale] = useState('zh-CN')
28
+ const store = useStore(pageProps.initialReduxState);
29
+ const router = useRouter();
30
+ const [ssoUser, setSsoUser] = useState(null);
31
+ const [pageLoad, setPageLoad] = useState(false);
32
+ const [loginChecked, setLoginChecked] = useState(false);
33
+ const [mounted, setMounted] = useState(false);
34
+ const [currentLocale, setCurrentLocale] = useState("zh-CN");
35
35
 
36
36
  // 检查是否为特殊页面(登录页、错误页)
37
37
  // 避免在服务器端访问 router.pathname
38
38
  const isSpecialPage =
39
- Component.displayName === 'ErrorPage' ||
40
- Component.name === 'ErrorPage' ||
41
- Component.displayName === 'LoginPage' ||
42
- Component.name === 'LoginPage'
39
+ Component.displayName === "ErrorPage" ||
40
+ Component.name === "ErrorPage" ||
41
+ Component.displayName === "LoginPage" ||
42
+ Component.name === "LoginPage";
43
43
 
44
44
  // Get Antd locale based on current locale
45
- const antdLocale = getAntdLocale(currentLocale)
45
+ const antdLocale = getAntdLocale(currentLocale);
46
46
 
47
47
  useEffect(() => {
48
- setMounted(true)
48
+ setMounted(true);
49
49
  // 只在客户端设置当前语言
50
- if (typeof window !== 'undefined') {
51
- const locale = router.locale || 'zh-CN'
52
- setCurrentLocale(locale)
50
+ if (typeof window !== "undefined") {
51
+ const locale = router.locale || "zh-CN";
52
+ setCurrentLocale(locale);
53
53
  }
54
- }, [router.locale])
54
+ }, [router.locale]);
55
55
 
56
56
  useEffect(() => {
57
- if (!mounted) return
57
+ if (!mounted) return;
58
58
 
59
59
  // 对于特殊页面,跳过登录检查
60
60
  if (isSpecialPage) {
61
- setLoginChecked(true)
62
- setPageLoad(true)
63
- return
61
+ setLoginChecked(true);
62
+ setPageLoad(true);
63
+ return;
64
64
  }
65
65
 
66
66
  // 检查当前路径是否为登录页或错误页
67
- const isLoginPage = typeof window !== 'undefined' && window.location.pathname === '/login'
67
+ const isLoginPage = typeof window !== "undefined" && window.location.pathname === "/login";
68
68
  const isErrorPage =
69
- typeof window !== 'undefined' &&
70
- (window.location.pathname === '/404' ||
71
- window.location.pathname === '/500' ||
72
- window.location.pathname === '/_error')
69
+ typeof window !== "undefined" &&
70
+ (window.location.pathname === "/404" ||
71
+ window.location.pathname === "/500" ||
72
+ window.location.pathname === "/_error");
73
73
 
74
74
  // 如果是登录页或错误页,直接设置加载完成,不进行登录检查
75
75
  if (isLoginPage || isErrorPage) {
76
- setLoginChecked(true)
77
- setPageLoad(true)
78
- return
76
+ setLoginChecked(true);
77
+ setPageLoad(true);
78
+ return;
79
79
  }
80
80
 
81
81
  // 检查是否有登录凭证
82
- const hasLoginCookie = typeof window !== 'undefined' && document.cookie.includes('_cas_nsgm')
82
+ const hasLoginCookie = typeof window !== "undefined" && document.cookie.includes("_cas_nsgm");
83
83
 
84
84
  // 如果没有登录凭证,直接跳转到登录页面(保持当前语言)
85
- if (!hasLoginCookie && typeof window !== 'undefined') {
86
- navigateToLogin(router)
87
- return
85
+ if (!hasLoginCookie && typeof window !== "undefined") {
86
+ navigateToLogin(router);
87
+ return;
88
88
  }
89
89
 
90
90
  // 否则执行登录检查
91
91
  login((user: any) => {
92
92
  if (user) {
93
- setSsoUser(user)
93
+ setSsoUser(user);
94
94
  }
95
- setLoginChecked(true)
96
- })
95
+ setLoginChecked(true);
96
+ });
97
97
 
98
98
  setTimeout(() => {
99
- setPageLoad(true)
100
- }, 100)
101
- }, [mounted, isSpecialPage])
99
+ setPageLoad(true);
100
+ }, 100);
101
+ }, [mounted, isSpecialPage]);
102
102
 
103
103
  return (
104
104
  <>
@@ -130,10 +130,7 @@ const App = ({ Component, pageProps }) => {
130
130
  </ClientProviders>
131
131
  </SSRSafeAntdProvider>
132
132
  </>
133
- )
134
- }
133
+ );
134
+ };
135
135
 
136
- // 移除 getInitialProps 以启用静态优化
137
- // 如果需要页面级别的数据获取,请在各个页面中使用 getStaticProps 或 getServerSideProps
138
-
139
- export default appWithTranslation(App, nextI18NextConfig)
136
+ export default appWithTranslation(App, nextI18NextConfig);
@@ -1,10 +1,9 @@
1
- import Document, { Html, Head, Main, NextScript, DocumentContext } from 'next/document'
2
- import React from 'react'
3
- import { ServerStyleSheet } from 'styled-components'
1
+ import Document, { Html, Head, Main, NextScript, DocumentContext } from "next/document";
2
+ import { ServerStyleSheet } from "styled-components";
4
3
 
5
4
  const MyDocument = (props) => {
6
5
  // 从 props 中获取语言信息,如果没有则默认为 zh-CN
7
- const locale = props.locale || 'zh-CN'
6
+ const locale = props.locale || "zh-CN";
8
7
 
9
8
  return (
10
9
  <Html lang={locale}>
@@ -86,31 +85,31 @@ const MyDocument = (props) => {
86
85
  <NextScript />
87
86
  </body>
88
87
  </Html>
89
- )
90
- }
88
+ );
89
+ };
91
90
 
92
91
  // MyDocument.renderDocument = Document.renderDocument
93
92
 
94
93
  MyDocument.getInitialProps = async (ctx: DocumentContext) => {
95
- const sheet = new ServerStyleSheet()
96
- const originalRenderPage = ctx.renderPage
94
+ const sheet = new ServerStyleSheet();
95
+ const originalRenderPage = ctx.renderPage;
97
96
 
98
97
  try {
99
98
  ctx.renderPage = () =>
100
99
  originalRenderPage({
101
100
  enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props} />),
102
- })
101
+ });
103
102
 
104
- const initialProps = await Document?.getInitialProps(ctx)
103
+ const initialProps = await Document?.getInitialProps(ctx);
105
104
 
106
105
  return {
107
106
  ...initialProps,
108
- locale: ctx.locale || 'zh-CN',
107
+ locale: ctx.locale || "zh-CN",
109
108
  styles: [initialProps.styles, sheet.getStyleElement()],
110
- }
109
+ };
111
110
  } finally {
112
- sheet.seal()
111
+ sheet.seal();
113
112
  }
114
- }
113
+ };
115
114
 
116
- export default MyDocument
115
+ export default MyDocument;
package/pages/_error.tsx CHANGED
@@ -1,50 +1,49 @@
1
- import React from 'react'
2
- import { Result, Button } from 'antd'
3
- import { NextPageContext } from 'next'
1
+ import { Result, Button } from "antd";
2
+ import { NextPageContext } from "next";
4
3
 
5
4
  interface ErrorProps {
6
- statusCode?: number
5
+ statusCode?: number;
7
6
  }
8
7
 
9
8
  function ErrorPage({ statusCode }: ErrorProps) {
10
9
  const getErrorMessage = () => {
11
10
  if (statusCode === 404) {
12
- return '页面未找到'
11
+ return "页面未找到";
13
12
  } else if (statusCode === 500) {
14
- return '服务器错误'
13
+ return "服务器错误";
15
14
  }
16
- return '发生了未知错误'
17
- }
15
+ return "发生了未知错误";
16
+ };
18
17
 
19
18
  const getErrorTitle = () => {
20
19
  if (statusCode === 404) {
21
- return '404'
20
+ return "404";
22
21
  } else if (statusCode === 500) {
23
- return '500'
22
+ return "500";
24
23
  }
25
- return '错误'
26
- }
24
+ return "错误";
25
+ };
27
26
 
28
27
  return (
29
28
  <div
30
29
  style={{
31
- minHeight: '100vh',
32
- display: 'flex',
33
- alignItems: 'center',
34
- justifyContent: 'center',
35
- padding: '20px',
30
+ minHeight: "100vh",
31
+ display: "flex",
32
+ alignItems: "center",
33
+ justifyContent: "center",
34
+ padding: "20px",
36
35
  }}
37
36
  >
38
37
  <Result
39
- status={statusCode === 404 ? '404' : '500'}
38
+ status={statusCode === 404 ? "404" : "500"}
40
39
  title={getErrorTitle()}
41
40
  subTitle={getErrorMessage()}
42
41
  extra={
43
42
  <Button
44
43
  type="primary"
45
44
  onClick={() => {
46
- if (typeof window !== 'undefined') {
47
- window.location.href = '/'
45
+ if (typeof window !== "undefined") {
46
+ window.location.href = "/";
48
47
  }
49
48
  }}
50
49
  >
@@ -53,14 +52,14 @@ function ErrorPage({ statusCode }: ErrorProps) {
53
52
  }
54
53
  />
55
54
  </div>
56
- )
55
+ );
57
56
  }
58
57
 
59
58
  ErrorPage.getInitialProps = ({ res, err }: NextPageContext) => {
60
- const statusCode = res ? res.statusCode : err ? err.statusCode : 404
61
- return { statusCode }
62
- }
59
+ const statusCode = res ? res.statusCode : err ? err.statusCode : 404;
60
+ return { statusCode };
61
+ };
63
62
 
64
- ErrorPage.displayName = 'ErrorPage'
63
+ ErrorPage.displayName = "ErrorPage";
65
64
 
66
- export default ErrorPage
65
+ export default ErrorPage;