initial commit

This commit is contained in:
Mr.April
2026-01-16 22:04:48 +08:00
parent 28cc3ec005
commit c5244e2b75
95 changed files with 27633 additions and 0 deletions
+18
View File
@@ -0,0 +1,18 @@
import { defineStore } from 'pinia'
interface App {
route: string
}
const useAppStore = defineStore('app', {
state: (): App => {
return {
route: ''
}
},
actions: {
}
})
export default useAppStore
+46
View File
@@ -0,0 +1,46 @@
import { defineStore } from 'pinia'
import { getLoginConfig } from '@/api/auth'
interface loginConfig {
is_username: number | boolean,
is_mobile: number | boolean,
is_auth_register: number | boolean,
is_bind_mobile: number | boolean,
agreement_show: number | boolean
}
interface Config {
login: loginConfig
}
export const useConfigStore = defineStore('config', {
state: (): Config => {
return {
login: {
is_username: 1,
is_mobile: 0,
is_auth_register: 1,
is_bind_mobile: 0,
agreement_show: 0
},
}
},
actions: {
async getLoginConfig(router: any = null) {
await getLoginConfig().then(({ data }:any) => {
this.login.is_username = parseInt(data.is_username)
this.login.is_mobile = parseInt(data.is_mobile)
this.login.is_auth_register = parseInt(data.is_auth_register)
this.login.is_bind_mobile = parseInt(data.is_bind_mobile)
this.login.agreement_show = parseInt(data.agreement_show)
if(data && router && router.currentRoute.value.path === '/site/close'){
navigateTo('/', { replace: true })
}
}).catch(() => {
})
}
}
})
export default useConfigStore
+12
View File
@@ -0,0 +1,12 @@
// 会员资料
export const MEMBER_KEY = 'member'
// 当前语言
export const LANG = 'lang'
// 是否开启暗黑模式
export const ISDARK = 'is-dark'
// 会员 token 在请求 headers 的字段名
export const MEMBER_TOKEN_KEY = 'member-token'
+10
View File
@@ -0,0 +1,10 @@
/**
* 全局公用的变量
*/
import type { Globals } from './interface'
export const globals: Globals = {
lazy: null,
unique: ref(0),
loadLangHandle: {},
}
+76
View File
@@ -0,0 +1,76 @@
export interface Globals {
// 防抖计时器
lazy: NodeJS.Timeout | null
// 随机数生成时的唯一性自增种子
unique: Ref<number>
// 语言包懒加载句柄
loadLangHandle: Record<string, any>
}
export interface Menus {
id: number
name: string
type: string
path?: string
title: string
url: string
icon: string
meta: {
/**
* 在 meta 中存储多个可能用到的属性
* 兼容 RouteRecordRaw 和 RouteLocationNormalizedLoaded 类型
*/
id: number
type: string
menu_type: 'tab' | 'link' | 'iframe'
}
children: Menus[]
}
export interface SiteConfig {
site_name: string
record_number?: string
version: string
upload: {
mode: string
[key: string]: any
}
head_nav: Menus[]
initialize: boolean
user_initialize: boolean
}
export interface Member {
id: number|string
username: string
nickname: string
email: string
mobile: string
gender: number
birthday: string
money: number
score: number
avatar: string
last_login_time: string
last_login_ip: string
motto: string
token: string
refresh_token: string
}
export interface PersonalCenter {
// 是否开启会员中心
open: boolean
// 从后台加载到的会员中心菜单数据
user_menus: Menus[]
// 是否显示一级菜单标题(当有多个一级菜单分组时显示)
show_headline: boolean
// 权限节点
auth_node: Map<string, string[]>
// 收缩布局(小屏设备)
shrink: boolean
// 菜单展开状态(小屏设备)
menu_expand: boolean
// 顶栏会员菜单下拉项
nav_user_menus: Menus[]
}
+71
View File
@@ -0,0 +1,71 @@
import { defineStore } from 'pinia'
import { MEMBER_KEY } from './constant/keys'
import { getMemberProfile } from '~/api/member'
interface Member {
token: string | null
info: Record<string, any> | null,
loginPopup:boolean
}
const info={
"id": 1001,
"username": "john_doe",
"nickname": "John",
"email": "john.doe@example.com",
"mobile": "13800138000",
"gender": 1,
"birthday": "1990-05-15",
"money": 1500.5,
"score": 2500,
"avatar": "",
"last_login_time": "2024-05-20T14:30:00Z",
"last_login_ip": "192.168.1.100",
"motto": "Stay curious, keep learning",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMDAxIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
"refresh_token": "rt_abc123def456ghi789jkl012mno345pqr678stu901vwx234yz"
}
export const useMemberStore = defineStore('member', {
state: (): Member => {
return {
token: useCookie('token').value||'',
info: info,
loginPopup:false
}
},
actions: {
async setToken(token: string) {
this.token = token
useCookie('token').value = token
await this.getMemberInfo()
},
async getMemberInfo() {
if (!this.token) return
await getMemberProfile()
.then((res: any) => {
this.info = res.data
})
.catch((err) => {
this.logout()
})
},
logout() {
if (!this.token) return
this.token = ''
this.info = null
useCookie('token').value = null
// logout().then().catch()
},
logOpen(){
this.loginPopup = true
},
logClose(){
this.loginPopup = false
}
}
})
+393
View File
@@ -0,0 +1,393 @@
import { defineStore } from 'pinia'
import type { PersonalCenter, Menus } from '~/stores/interface'
// 顶栏会员菜单下拉项(nav_user_menus)- 动态菜单
const navUserMenus: Menus[] = [
{
"id": 101,
"name": "dashboard",
"type": "menu",
"path": "/member/dashboard",
"title": "仪表盘",
"url": "",
"icon": "i-dashboard",
"meta": {
"id": 101,
"type": "menu",
"menu_type": "tab"
},
"children": []
},
{
"id": 102,
"name": "orders",
"type": "menu",
"path": "/member/orders",
"title": "我的订单",
"url": "",
"icon": "i-shopping-cart",
"meta": {
"id": 102,
"type": "menu",
"menu_type": "tab"
},
"children": []
},
{
"id": 103,
"name": "wallet",
"type": "menu",
"path": "/member/wallet",
"title": "我的钱包",
"url": "",
"icon": "i-wallet",
"meta": {
"id": 103,
"type": "menu",
"menu_type": "tab"
},
"children": []
},
{
"id": 104,
"name": "messages",
"type": "menu",
"path": "/member/messages",
"title": "消息中心",
"url": "",
"icon": "i-message",
"meta": {
"id": 104,
"type": "menu",
"menu_type": "tab"
},
"children": []
}
]
// 会员中心菜单(user_menus)- 完整的会员中心菜单结构
const userMenus: Menus[] = [
{
"id": 1,
"name": "member_center",
"type": "directory",
"path": "/member",
"title": "会员中心",
"url": "",
"icon": "i-user",
"meta": {
"id": 1,
"type": "directory",
"menu_type": "tab"
},
"children": [
{
"id": 11,
"name": "profile",
"type": "menu",
"path": "/member/profile",
"title": "个人资料",
"url": "",
"icon": "i-profile",
"meta": {
"id": 11,
"type": "menu",
"menu_type": "tab"
},
"children": []
},
{
"id": 12,
"name": "security",
"type": "menu",
"path": "/member/security",
"title": "安全设置",
"url": "",
"icon": "i-shield",
"meta": {
"id": 12,
"type": "menu",
"menu_type": "tab"
},
"children": []
},
{
"id": 13,
"name": "notification",
"type": "menu",
"path": "/member/notification",
"title": "通知设置",
"url": "",
"icon": "i-bell",
"meta": {
"id": 13,
"type": "menu",
"menu_type": "tab"
},
"children": []
}
]
},
{
"id": 2,
"name": "order_management",
"type": "directory",
"path": "/member/orders",
"title": "订单管理",
"url": "",
"icon": "i-shopping-cart",
"meta": {
"id": 2,
"type": "directory",
"menu_type": "tab"
},
"children": [
{
"id": 21,
"name": "order_list",
"type": "menu",
"path": "/member/orders/list",
"title": "订单列表",
"url": "",
"icon": "i-list",
"meta": {
"id": 21,
"type": "menu",
"menu_type": "tab"
},
"children": []
},
{
"id": 22,
"name": "order_history",
"type": "menu",
"path": "/member/orders/history",
"title": "历史订单",
"url": "",
"icon": "i-history",
"meta": {
"id": 22,
"type": "menu",
"menu_type": "tab"
},
"children": []
},
{
"id": 23,
"name": "refund_orders",
"type": "menu",
"path": "/member/orders/refund",
"title": "退款订单",
"url": "",
"icon": "i-refresh",
"meta": {
"id": 23,
"type": "menu",
"menu_type": "tab"
},
"children": []
}
]
},
{
"id": 3,
"name": "finance",
"type": "directory",
"path": "/member/finance",
"title": "财务管理",
"url": "",
"icon": "i-wallet",
"meta": {
"id": 3,
"type": "directory",
"menu_type": "tab"
},
"children": [
{
"id": 31,
"name": "balance",
"type": "menu",
"path": "/member/finance/balance",
"title": "账户余额",
"url": "",
"icon": "i-money",
"meta": {
"id": 31,
"type": "menu",
"menu_type": "tab"
},
"children": []
},
{
"id": 32,
"name": "recharge",
"type": "menu",
"path": "/member/finance/recharge",
"title": "在线充值",
"url": "",
"icon": "i-credit-card",
"meta": {
"id": 32,
"type": "menu",
"menu_type": "tab"
},
"children": []
},
{
"id": 33,
"name": "transaction",
"type": "menu",
"path": "/member/finance/transaction",
"title": "交易记录",
"url": "",
"icon": "i-file-text",
"meta": {
"id": 33,
"type": "menu",
"menu_type": "tab"
},
"children": []
}
]
},
{
"id": 4,
"name": "support",
"type": "directory",
"path": "/member/support",
"title": "客服支持",
"url": "",
"icon": "i-headphones",
"meta": {
"id": 4,
"type": "directory",
"menu_type": "tab"
},
"children": [
{
"id": 41,
"name": "help_center",
"type": "menu",
"path": "/member/support/help",
"title": "帮助中心",
"url": "",
"icon": "i-help-circle",
"meta": {
"id": 41,
"type": "menu",
"menu_type": "tab"
},
"children": []
},
{
"id": 42,
"name": "contact_us",
"type": "menu",
"path": "/member/support/contact",
"title": "联系我们",
"url": "",
"icon": "i-phone",
"meta": {
"id": 42,
"type": "menu",
"menu_type": "tab"
},
"children": []
},
{
"id": 43,
"name": "feedback",
"type": "menu",
"path": "/member/support/feedback",
"title": "意见反馈",
"url": "",
"icon": "i-message-square",
"meta": {
"id": 43,
"type": "menu",
"menu_type": "tab"
},
"children": []
}
]
}
]
export const usePersonalCenterStore = defineStore('personal-center', () => {
const state: PersonalCenter = reactive({
open: true,
user_menus: userMenus,
show_headline: true,
auth_node: new Map(),
shrink: false,
menu_expand: false,
nav_user_menus: navUserMenus,
})
const setNavUserMenus = (menus: Menus[]) => {
state.nav_user_menus = menus
}
const mergeNavUserMenus = (menus: Menus[]) => {
state.nav_user_menus = [...state.nav_user_menus, ...menus]
}
const setAuthNode = (key: string, data: string[]) => {
state.auth_node.set(key, data)
}
const mergeAuthNode = (authNode: Map<string, string[]>) => {
state.auth_node = new Map([...state.auth_node, ...authNode])
}
const setUserMenus = (menus: Menus[]): void => {
state.user_menus = encodeRoutesURI(menus)
}
const setShowHeadline = (show: boolean): void => {
state.show_headline = show
}
const setShrink = (shrink: boolean) => {
state.shrink = shrink
}
const setStatus = (status: boolean) => {
state.open = status
}
const toggleMenuExpand = (expand = !state.menu_expand) => {
state.menu_expand = expand
}
return {
state,
setAuthNode,
setNavUserMenus,
mergeNavUserMenus,
mergeAuthNode,
setUserMenus,
setShowHeadline,
setShrink,
setStatus,
toggleMenuExpand,
}
})
function encodeRoutesURI(data: Menus[]) {
data.forEach((item) => {
if (item.meta.menu_type == 'iframe') {
item.path = '/user/iframe/' + encodeURIComponent(item.path)
}
if (item.children && item.children.length) {
item.children = encodeRoutesURI(item.children)
}
})
return data
}
+239
View File
@@ -0,0 +1,239 @@
import { defineStore } from 'pinia'
import storage from '@/utils/storage'
import type { Menus } from './interface'
interface System {
lang: string
site: Record<string, any>
}
// 支持的语言列表
const availableLanguages = [
{ name: 'zh-cn', value: '中文' },
{ name: 'en', value: 'English' }
]
const menus = [
{
"id": 1,
"name": "community",
"type": "menu",
"path": "https://madong.tech",
"title": "社区",
"url": "https://www.baidu.com",
"icon": "i-dashboard",
"meta": {
"id": 1,
"type": "menu",
"menu_type": "tab"
}
},
{
"id": 2,
"name": "community",
"type": "menu",
"path": "/",
"title": "模块市场",
"url": "",
"icon": "i-dashboard",
"meta": {
"id": 2,
"type": "menu",
"menu_type": "tab"
}
},
{
"id": 3,
"name": "docs",
"type": "menu",
"path": "/",
"title": "文档",
"url": "",
"icon": "i-dashboard",
"meta": {
"id": 3,
"type": "menu",
"menu_type": "tab"
}
},
{
"id": 4,
"name": "demo",
"type": "directory",
"title": "演示站",
"url": "",
"icon": "i-settings",
"meta": {
"id": 4,
"type": "directory",
"menu_type": "tab"
},
"children": [
{
"id": 201,
"name": "demo1",
"type": "page",
"path": "/demo/test1",
"title": "演示站1",
"url": "",
"icon": "i-users",
"meta": {
"id": 201,
"type": "page",
"menu_type": "tab"
},
"children": []
},
{
"id": 202,
"name": "demo2",
"type": "page",
"path": "/demo/test2",
"title": "演示站2",
"url": "",
"icon": "i-users",
"meta": {
"id": 202,
"type": "page",
"menu_type": "tab"
},
"children": []
}
]
},
{
"id": 5,
"name": "code",
"type": "directory",
"title": "代码仓库",
"url": "",
"icon": "i-link",
"meta": {
"id": 5,
"type": "directory",
"menu_type": "tab"
},
"children": [
{
"id": 501,
"name": "gitee",
"type": "page",
"path": "/code/gitee",
"title": "Gitee",
"url": "https://gitee.com",
"icon": "i-book",
"meta": {
"id": 501,
"type": "page",
"menu_type": "link"
},
"children": []
},
{
"id": 502,
"name": "github",
"type": "page",
"path": "/external/support",
"title": "GitHub",
"url": "https://github.com",
"icon": "i-help-circle",
"meta": {
"id": 502,
"type": "page",
"menu_type": "link"
},
"children": []
}
]
}
] as Menus[]
export const useSystemStore = defineStore('system', {
state: (): System => {
return {
lang: storage.get('lang') ?? 'zh-cn',
site: {
site_name: '通用多应用管理系统后台框架',
record_number: 'test',
version: 'v1.0.1',
upload: {
mode: 'local',
},
head_nav: menus,
initialize: false,
user_initialize: false,
}
}
},
getters: {
/**
* 获取支持的语言列表
*/
getLanguages: () => availableLanguages,
/**
* 获取当前语言信息
*/
getCurrentLanguage: (state) => {
return availableLanguages.find(lang => lang.code === state.lang) || availableLanguages[0]
}
},
actions: {
/**
* 切换语言
* @param name 语言名称
*/
setLanguage(name: string) {
// 验证语言代码是否支持
if (!availableLanguages.some(lang => lang.name === name)) {
console.warn(`不支持的语言代码: ${name}`)
return false
}
this.lang = name
// 保存到本地存储
storage.set({ key: 'lang', data: name })
// 触发 i18n 语言切换
this.updateI18nLocale(name)
// 触发语言切换事件,让组件重新渲染
this.triggerLanguageChange()
return true
},
/**
* 更新 i18n 语言设置
* @param locale 语言代码
*/
updateI18nLocale(locale: string) {
// 获取 i18n 实例并切换语言
const nuxtApp = useNuxtApp()
const i18n = (nuxtApp as any).$i18n
if (i18n && i18n.locale !== locale) {
i18n.locale = locale
}
},
/**
* 触发语言切换事件
*/
triggerLanguageChange() {
// 触发自定义事件,通知组件重新渲染
if (process.client) {
window.dispatchEvent(new CustomEvent('languageChanged', {
detail: { locale: this.lang }
}))
}
},
async getSiteInfoFn() {
// 原有逻辑保持不变
}
}
})