feat: 适配5.x后端,重构前端架构
主要变更: 1. 重构API目录结构,采用模块化设计,适配5.x后端接口规范 2. 优化布局组件,提升用户界面体验 3. 增强国际化支持,完善多语言配置 4. 新增权限控制功能,支持前端路由权限管理 5. 优化认证流程,支持JWT认证机制 6. 新增中间件和插件,提升系统扩展性 7. 优化状态管理,采用更清晰的模块化设计 8. 新增搜索框、广告等组件,丰富页面功能 9. 更改包管理工具从npm到pnpm,提升依赖管理效率 10. 完善配置系统,支持多环境配置 适配5.x后端特性: - 采用新的API接口规范 - 支持JWT认证机制 - 适配后端权限控制体系 - 支持后端国际化接口 - 优化数据交互方式
This commit is contained in:
+103
-9
@@ -1,4 +1,5 @@
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import storage from '@/utils/storage'
|
||||
|
||||
// 定义语言文件模块接口
|
||||
interface LanguageFileModule {
|
||||
@@ -10,12 +11,26 @@ function isLanguageFileModule(module: any): module is LanguageFileModule {
|
||||
return module && typeof module === 'object' && 'default' in module && typeof module.default === 'object'
|
||||
}
|
||||
|
||||
// 递归处理嵌套结构
|
||||
const flattenMessages = (obj: any, path: string = '') => {
|
||||
let result: Record<string, string> = {}
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
const newPath = path ? `${path}.${key}` : key
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
Object.assign(result, flattenMessages(value, newPath))
|
||||
} else {
|
||||
result[newPath] = String(value)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// 自动扫描加载所有语言文件
|
||||
const loadAllLanguageFiles = () => {
|
||||
const messages: Record<string, Record<string, any>> = {}
|
||||
|
||||
try {
|
||||
// 加载所有语言文件
|
||||
// 加载所有语言文件(包括子目录)
|
||||
const languageFiles = import.meta.glob('~/lang/**/*.json', {
|
||||
eager: true
|
||||
}) as Record<string, LanguageFileModule>
|
||||
@@ -28,16 +43,92 @@ const loadAllLanguageFiles = () => {
|
||||
|
||||
if (langIndex >= 0 && pathParts.length > langIndex + 1) {
|
||||
const langCode = pathParts[langIndex + 1] ?? ''
|
||||
const fileName = (pathParts[pathParts.length - 1] ?? '').replace('.json', '')
|
||||
|
||||
if (langCode && fileName) {
|
||||
if (langCode) {
|
||||
if (!messages[langCode]) {
|
||||
messages[langCode] = {}
|
||||
}
|
||||
// 直接合并所有文件内容到对应语言下
|
||||
messages[langCode] = {
|
||||
...messages[langCode],
|
||||
...module.default
|
||||
|
||||
// 只使用文件名作为键前缀,不包含目录名
|
||||
const fileName = (pathParts[pathParts.length - 1] ?? '').replace('.json', '')
|
||||
const fileKey = fileName
|
||||
|
||||
// 处理嵌套结构
|
||||
const flattenedMessages = flattenMessages(module.default)
|
||||
|
||||
// 如果有文件键前缀,添加到所有消息键前
|
||||
if (fileKey) {
|
||||
const prefixedMessages: Record<string, string> = {}
|
||||
for (const [key, value] of Object.entries(flattenedMessages)) {
|
||||
prefixedMessages[`${fileKey}.${key}`] = value
|
||||
}
|
||||
messages[langCode] = {
|
||||
...messages[langCode],
|
||||
...prefixedMessages
|
||||
}
|
||||
} else {
|
||||
// 没有前缀,直接合并
|
||||
messages[langCode] = {
|
||||
...messages[langCode],
|
||||
...flattenedMessages
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 加载 apps 目录下的语言文件
|
||||
const appsLanguageFiles = import.meta.glob('~/apps/**/lang/**/*.json', {
|
||||
eager: true
|
||||
}) as Record<string, LanguageFileModule>
|
||||
|
||||
// 处理 apps 语言文件
|
||||
for (const [filePath, module] of Object.entries(appsLanguageFiles)) {
|
||||
if (isLanguageFileModule(module)) {
|
||||
const pathParts = filePath.split('/')
|
||||
const appsIndex = pathParts.indexOf('apps')
|
||||
const langIndex = pathParts.indexOf('lang')
|
||||
|
||||
if (appsIndex >= 0 && langIndex >= 0 && pathParts.length > langIndex + 1) {
|
||||
const langCode = pathParts[langIndex + 1] ?? ''
|
||||
|
||||
if (langCode) {
|
||||
if (!messages[langCode]) {
|
||||
messages[langCode] = {}
|
||||
}
|
||||
|
||||
// 提取模块名(apps目录下的子目录名)
|
||||
const moduleName = pathParts[appsIndex + 1] ?? ''
|
||||
|
||||
// 只使用文件名作为键前缀,不包含目录名
|
||||
const fileName = (pathParts[pathParts.length - 1] ?? '').replace('.json', '')
|
||||
|
||||
// 构建文件键,包含模块名前缀
|
||||
let fileKey = moduleName
|
||||
if (fileName) {
|
||||
fileKey = `${moduleName}.${fileName}`
|
||||
}
|
||||
|
||||
// 处理嵌套结构
|
||||
const flattenedMessages = flattenMessages(module.default)
|
||||
|
||||
// 如果有文件键前缀,添加到所有消息键前
|
||||
if (fileKey) {
|
||||
const prefixedMessages: Record<string, string> = {}
|
||||
for (const [key, value] of Object.entries(flattenedMessages)) {
|
||||
prefixedMessages[`${fileKey}.${key}`] = value
|
||||
}
|
||||
messages[langCode] = {
|
||||
...messages[langCode],
|
||||
...prefixedMessages
|
||||
}
|
||||
} else {
|
||||
// 没有前缀,直接合并
|
||||
messages[langCode] = {
|
||||
...messages[langCode],
|
||||
...flattenedMessages
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,9 +157,12 @@ export default defineNuxtPlugin((NuxtApp) => {
|
||||
// 加载所有语言消息
|
||||
const messages = loadAllLanguageFiles()
|
||||
|
||||
// 从存储中读取语言设置,默认为 zh-cn
|
||||
const savedLocale = storage.get('lang') ?? 'zh-cn'
|
||||
|
||||
const i18n = createI18n({
|
||||
legacy: false, // 使用Composition API
|
||||
locale: 'zh-cn', // 默认语言
|
||||
locale: savedLocale, // 使用存储中的语言设置
|
||||
fallbackLocale: 'zh-cn', // 回退语言
|
||||
globalInjection: true, // 全局注入
|
||||
messages: messages,
|
||||
@@ -84,4 +178,4 @@ export default defineNuxtPlugin((NuxtApp) => {
|
||||
getI18n: () => i18n
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user