Initial commit: One Pipe System

完整的管理系统,包含账户管理、卡片管理、套餐管理、财务管理等功能模块。

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
sexygoat
2026-01-22 16:35:33 +08:00
commit 222e5bb11a
495 changed files with 145440 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
/**
* 存储相关工具函数统一导出
*/
export * from './storage'
export * from './storage-config'
export * from './storage-key-manager'

View File

@@ -0,0 +1,92 @@
/**
* 存储配置管理
* 统一管理存储相关的常量和配置项
*/
export class StorageConfig {
/** 当前应用版本 */
static readonly CURRENT_VERSION = __APP_VERSION__
/** 存储键前缀 */
static readonly STORAGE_PREFIX = 'sys-v'
/** 版本键名 */
static readonly VERSION_KEY = 'sys-version'
/** 跳过升级检查的版本 */
static readonly SKIP_UPGRADE_VERSION = '1.0.0'
/** 升级处理延迟时间(毫秒) */
static readonly UPGRADE_DELAY = 1000
/** 登出延迟时间(毫秒) */
static readonly LOGOUT_DELAY = 1000
/**
* 生成版本化的存储键名
* @param storeId 存储ID
* @param version 版本号,默认使用当前版本
*/
static generateStorageKey(storeId: string, version: string = this.CURRENT_VERSION): string {
return `${this.STORAGE_PREFIX}${version}-${storeId}`
}
/**
* 生成旧版本的存储键名(不带分隔符)
* @param version 版本号,默认使用当前版本
*/
static generateLegacyKey(version: string = this.CURRENT_VERSION): string {
return `${this.STORAGE_PREFIX}${version}`
}
/**
* 创建存储键匹配的正则表达式
* @param storeId 存储ID
*/
static createKeyPattern(storeId: string): RegExp {
return new RegExp(`^${this.STORAGE_PREFIX}[^-]+-${storeId}$`)
}
/**
* 创建当前版本存储键匹配的正则表达式
*/
static createCurrentVersionPattern(): RegExp {
return new RegExp(`^${this.STORAGE_PREFIX}${this.CURRENT_VERSION}-`)
}
/**
* 创建任意版本存储键匹配的正则表达式
*/
static createVersionPattern(): RegExp {
return new RegExp(`^${this.STORAGE_PREFIX}`)
}
/**
* 检查是否为当前版本的键
*/
static isCurrentVersionKey(key: string): boolean {
return key.startsWith(`${this.STORAGE_PREFIX}${this.CURRENT_VERSION}`)
}
/**
* 检查是否为版本化的键
*/
static isVersionedKey(key: string): boolean {
return key.startsWith(this.STORAGE_PREFIX)
}
/**
* 从存储键中提取版本号
*/
static extractVersionFromKey(key: string): string | null {
const match = key.match(new RegExp(`^${this.STORAGE_PREFIX}([^-]+)`))
return match ? match[1] : null
}
/**
* 从存储键中提取存储ID
*/
static extractStoreIdFromKey(key: string): string | null {
const match = key.match(new RegExp(`^${this.STORAGE_PREFIX}[^-]+-(.+)$`))
return match ? match[1] : null
}
}

View File

@@ -0,0 +1,66 @@
import { StorageConfig } from '@/utils/storage'
/**
* 存储键名管理器
* 负责处理版本化的存储键名生成和数据迁移
*/
export class StorageKeyManager {
/**
* 获取当前版本的存储键名
*/
private getCurrentVersionKey(storeId: string): string {
return StorageConfig.generateStorageKey(storeId)
}
/**
* 检查当前版本的数据是否存在
*/
private hasCurrentVersionData(key: string): boolean {
return localStorage.getItem(key) !== null
}
/**
* 查找其他版本的同名存储键
*/
private findExistingKey(storeId: string): string | null {
const storageKeys = Object.keys(localStorage)
const pattern = StorageConfig.createKeyPattern(storeId)
return storageKeys.find((key) => pattern.test(key) && localStorage.getItem(key)) || null
}
/**
* 将数据从旧版本迁移到当前版本
*/
private migrateData(fromKey: string, toKey: string): void {
try {
const existingData = localStorage.getItem(fromKey)
if (existingData) {
localStorage.setItem(toKey, existingData)
console.info(`[Storage] 已迁移数据: ${fromKey} → ${toKey}`)
}
} catch (error) {
console.warn(`[Storage] 数据迁移失败: ${fromKey}`, error)
}
}
/**
* 获取持久化存储的键名(支持自动数据迁移)
*/
getStorageKey(storeId: string): string {
const currentKey = this.getCurrentVersionKey(storeId)
// 优先使用当前版本的数据
if (this.hasCurrentVersionData(currentKey)) {
return currentKey
}
// 查找并迁移其他版本的数据
const existingKey = this.findExistingKey(storeId)
if (existingKey) {
this.migrateData(existingKey, currentKey)
}
return currentKey
}
}

View File

@@ -0,0 +1,216 @@
import { ElMessage } from 'element-plus'
import { router } from '@/router'
import { useUserStore } from '@/store/modules/user'
import { StorageConfig } from '@/utils/storage/storage-config'
import { RoutesAlias } from '@/router/routesAlias'
/**
* 存储兼容性管理器
* 负责处理不同版本间的存储兼容性检查和数据验证
*/
class StorageCompatibilityManager {
/**
* 获取系统版本号
*/
getSystemVersion(): string | null {
return localStorage.getItem(StorageConfig.VERSION_KEY)
}
/**
* 获取系统存储数据(兼容旧格式)
*/
getSystemStorage(): any {
const version = this.getSystemVersion() || StorageConfig.CURRENT_VERSION
const legacyKey = StorageConfig.generateLegacyKey(version)
const data = localStorage.getItem(legacyKey)
return data ? JSON.parse(data) : null
}
/**
* 检查当前版本是否有存储数据
*/
private hasCurrentVersionStorage(): boolean {
const storageKeys = Object.keys(localStorage)
const currentVersionPattern = StorageConfig.createCurrentVersionPattern()
return storageKeys.some(
(key) => currentVersionPattern.test(key) && localStorage.getItem(key) !== null
)
}
/**
* 检查是否存在任何版本的存储数据
*/
private hasAnyVersionStorage(): boolean {
const storageKeys = Object.keys(localStorage)
const versionPattern = StorageConfig.createVersionPattern()
return storageKeys.some((key) => versionPattern.test(key) && localStorage.getItem(key) !== null)
}
/**
* 获取旧格式的本地存储数据
*/
private getLegacyStorageData(): Record<string, any> {
try {
const systemStorage = this.getSystemStorage()
return systemStorage || {}
} catch (error) {
console.warn('[Storage] 解析旧格式存储数据失败:', error)
return {}
}
}
/**
* 显示存储错误消息
*/
private showStorageError(): void {
ElMessage({
type: 'error',
offset: 40,
duration: 5000,
message: '系统检测到本地数据异常,请重新登录系统恢复使用!'
})
}
/**
* 执行系统登出
*/
private performSystemLogout(): void {
setTimeout(() => {
try {
localStorage.clear()
useUserStore().logOut()
router.push(RoutesAlias.Login)
console.info('[Storage] 已执行系统登出')
} catch (error) {
console.error('[Storage] 系统登出失败:', error)
}
}, StorageConfig.LOGOUT_DELAY)
}
/**
* 处理存储异常
*/
private handleStorageError(): void {
this.showStorageError()
this.performSystemLogout()
}
/**
* 检查是否在登录页面
*/
private isOnLoginPage(): boolean {
return location.href.includes(RoutesAlias.Login)
}
/**
* 验证存储数据完整性
*/
validateStorageData(): boolean {
// 如果在登录页面,跳过验证
if (this.isOnLoginPage()) {
return true
}
try {
// 优先检查新版本存储结构
if (this.hasCurrentVersionStorage()) {
console.debug('[Storage] 发现当前版本存储数据')
return true
}
// 检查是否有任何版本的存储数据
if (this.hasAnyVersionStorage()) {
console.debug('[Storage] 发现其他版本存储数据,可能需要迁移')
return true
}
// 检查旧版本存储结构
const legacyData = this.getLegacyStorageData()
if (Object.keys(legacyData).length === 0) {
console.warn('[Storage] 未发现任何存储数据,需要重新登录')
this.performSystemLogout()
return false
}
console.debug('[Storage] 发现旧版本存储数据')
return true
} catch (error) {
console.error('[Storage] 存储数据验证失败:', error)
this.handleStorageError()
return false
}
}
/**
* 检查存储是否为空
*/
isStorageEmpty(): boolean {
// 检查新版本存储结构
if (this.hasCurrentVersionStorage()) {
return false
}
// 检查是否有任何版本的存储数据
if (this.hasAnyVersionStorage()) {
return false
}
// 检查旧版本存储结构
const legacyData = this.getLegacyStorageData()
return Object.keys(legacyData).length === 0
}
/**
* 检查存储兼容性
*/
checkCompatibility(): boolean {
try {
const isValid = this.validateStorageData()
const isEmpty = this.isStorageEmpty()
if (isValid || isEmpty) {
console.debug('[Storage] 存储兼容性检查通过')
return true
}
console.warn('[Storage] 存储兼容性检查失败')
return false
} catch (error) {
console.error('[Storage] 兼容性检查异常:', error)
return false
}
}
}
// 创建存储兼容性管理器实例
const storageManager = new StorageCompatibilityManager()
/**
* 获取系统存储数据
*/
export function getSystemStorage(): any {
return storageManager.getSystemStorage()
}
/**
* 获取系统版本号
*/
export function getSysVersion(): string | null {
return storageManager.getSystemVersion()
}
/**
* 验证本地存储数据
*/
export function validateStorageData(): boolean {
return storageManager.validateStorageData()
}
/**
* 检查存储兼容性
*/
export function checkStorageCompatibility(): boolean {
return storageManager.checkCompatibility()
}