xto-fronted 0.1.2 → 0.1.4

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 (60) hide show
  1. package/.env.development +3 -0
  2. package/.env.production +3 -0
  3. package/bin/cli.js +103 -0
  4. package/index.html +13 -0
  5. package/package.json +16 -3
  6. package/public/vite.svg +10 -0
  7. package/src/App.vue +20 -0
  8. package/src/api/auth.ts +35 -0
  9. package/src/api/menu.ts +13 -0
  10. package/src/api/system.ts +65 -0
  11. package/src/api/user.ts +12 -0
  12. package/src/assets/styles/_dark.scss +407 -0
  13. package/src/assets/styles/_reset.scss +126 -0
  14. package/src/assets/styles/_root.scss +140 -0
  15. package/src/assets/styles/_transition.scss +119 -0
  16. package/src/assets/styles/_variables.scss +45 -0
  17. package/src/assets/styles/index.scss +187 -0
  18. package/src/components/Layout/Footer.vue +17 -0
  19. package/src/components/Layout/Header.vue +335 -0
  20. package/src/components/Layout/Sidebar.vue +213 -0
  21. package/src/components/Layout/Tabs.vue +20 -0
  22. package/src/components/Layout/index.vue +62 -0
  23. package/src/composables/index.ts +9 -0
  24. package/src/composables/useApp.ts +170 -0
  25. package/src/composables/useAuth.ts +70 -0
  26. package/src/composables/useForm.ts +79 -0
  27. package/src/composables/useMenu.ts +141 -0
  28. package/src/composables/useTable.ts +97 -0
  29. package/src/config/index.ts +19 -0
  30. package/src/directives/permission.ts +41 -0
  31. package/src/enums/index.ts +63 -0
  32. package/src/env.d.ts +17 -0
  33. package/src/index.ts +44 -0
  34. package/src/main.ts +34 -0
  35. package/src/router/dynamicRoutes.ts +163 -0
  36. package/src/router/index.ts +71 -0
  37. package/src/router/staticRoutes.ts +43 -0
  38. package/src/stores/app.ts +145 -0
  39. package/src/stores/auth.ts +45 -0
  40. package/src/stores/index.ts +15 -0
  41. package/src/stores/menu.ts +158 -0
  42. package/src/stores/user.ts +41 -0
  43. package/src/types/api.d.ts +103 -0
  44. package/src/types/global.d.ts +45 -0
  45. package/src/types/router.d.ts +48 -0
  46. package/src/types/xto.d.ts +149 -0
  47. package/src/utils/auth.ts +86 -0
  48. package/src/utils/permission.ts +30 -0
  49. package/src/utils/request.ts +126 -0
  50. package/src/utils/storage.ts +72 -0
  51. package/src/views/dashboard/index.vue +32 -0
  52. package/src/views/error/403.vue +57 -0
  53. package/src/views/error/404.vue +57 -0
  54. package/src/views/login/index.vue +141 -0
  55. package/src/views/system/menu/index.vue +32 -0
  56. package/src/views/system/role/index.vue +32 -0
  57. package/src/views/system/user/index.vue +32 -0
  58. package/tsconfig.json +26 -0
  59. package/tsconfig.node.json +11 -0
  60. package/vite.config.ts +139 -0
@@ -0,0 +1,3 @@
1
+ VITE_APP_NAME=analysis-web
2
+ VITE_APP_ID=DBU-CONTENT-ANALYSIS
3
+ VITE_APP_CLIENT_ID=Tineco
@@ -0,0 +1,3 @@
1
+ VITE_APP_NAME=analysis-web
2
+ VITE_APP_ID=DBU-CONTENT-ANALYSIS
3
+ VITE_APP_CLIENT_ID=Tineco
package/bin/cli.js ADDED
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * xto-fronted CLI
5
+ * 用于初始化前端项目脚手架
6
+ */
7
+
8
+ const { execSync } = require('child_process')
9
+ const { existsSync, mkdirSync, cpSync, writeFileSync } = require('fs')
10
+ const { resolve, basename } = require('path')
11
+
12
+ // 获取命令行参数
13
+ const args = process.argv.slice(2)
14
+ const targetDir = args[0] || 'my-app'
15
+ const targetPath = resolve(process.cwd(), targetDir)
16
+
17
+ console.log('\n🚀 创建项目:', targetDir)
18
+ console.log('📁 目标路径:', targetPath)
19
+
20
+ // 模板目录(CLI 所在目录的上级目录)
21
+ const templateDir = resolve(__dirname, '..')
22
+
23
+ // 创建目标目录
24
+ if (existsSync(targetPath)) {
25
+ console.error('❌ 目录已存在:', targetPath)
26
+ process.exit(1)
27
+ }
28
+
29
+ mkdirSync(targetPath, { recursive: true })
30
+
31
+ // 需要复制的文件和目录
32
+ const filesToCopy = [
33
+ 'src',
34
+ 'public',
35
+ 'index.html',
36
+ 'vite.config.ts',
37
+ 'tsconfig.json',
38
+ 'tsconfig.node.json',
39
+ '.env.development',
40
+ '.env.production'
41
+ ]
42
+
43
+ // 复制文件
44
+ filesToCopy.forEach(file => {
45
+ const src = resolve(templateDir, file)
46
+ const dest = resolve(targetPath, file)
47
+ if (existsSync(src)) {
48
+ cpSync(src, dest, { recursive: true })
49
+ console.log('✅ 复制:', file)
50
+ }
51
+ })
52
+
53
+ // 创建 package.json
54
+ const packageJson = {
55
+ name: basename(targetPath),
56
+ version: '0.0.1',
57
+ private: true,
58
+ type: 'module',
59
+ scripts: {
60
+ dev: 'vite',
61
+ build: 'vue-tsc && vite build',
62
+ preview: 'vite preview'
63
+ },
64
+ dependencies: {
65
+ '@xto/base': '^0.1.0',
66
+ '@xto/feedback': '^0.1.0',
67
+ '@xto/form': '^0.1.0',
68
+ '@xto/navigation': '^0.1.0',
69
+ 'axios': '^1.6.8',
70
+ 'pinia': '^2.1.7',
71
+ 'vue': '^3.4.21',
72
+ 'vue-router': '^4.3.0'
73
+ },
74
+ devDependencies: {
75
+ '@types/node': '^20.11.30',
76
+ '@vitejs/plugin-vue': '^5.0.4',
77
+ 'sass': '^1.72.0',
78
+ 'sass-embedded': '^1.72.0',
79
+ 'typescript': '^5.4.2',
80
+ 'vite': '^5.2.0',
81
+ 'vue-tsc': '^2.0.6'
82
+ }
83
+ }
84
+
85
+ writeFileSync(
86
+ resolve(targetPath, 'package.json'),
87
+ JSON.stringify(packageJson, null, 2)
88
+ )
89
+ console.log('✅ 创建: package.json')
90
+
91
+ // 安装依赖
92
+ console.log('\n📦 安装依赖...')
93
+ try {
94
+ execSync('npm install', { cwd: targetPath, stdio: 'inherit' })
95
+ console.log('✅ 依赖安装完成')
96
+ } catch (error) {
97
+ console.log('⚠️ 依赖安装失败,请手动运行: npm install')
98
+ }
99
+
100
+ console.log('\n✨ 项目创建成功!')
101
+ console.log('\n👉 接下来执行:')
102
+ console.log(` cd ${targetDir}`)
103
+ console.log(' npm run dev\n')
package/index.html ADDED
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Xto Demo - 后台管理系统</title>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="/src/main.ts"></script>
12
+ </body>
13
+ </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xto-fronted",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "XTO 前端应用脚手架,封装登录、退出、菜单渲染等统一逻辑",
@@ -15,8 +15,20 @@
15
15
  },
16
16
  "./style.css": "./dist/style.css"
17
17
  },
18
+ "bin": {
19
+ "create-xto-app": "./bin/cli.js"
20
+ },
18
21
  "files": [
19
- "dist"
22
+ "dist",
23
+ "src",
24
+ "public",
25
+ "bin",
26
+ "index.html",
27
+ "vite.config.ts",
28
+ "tsconfig.json",
29
+ "tsconfig.node.json",
30
+ ".env.production",
31
+ ".env.development"
20
32
  ],
21
33
  "scripts": {
22
34
  "dev": "vite",
@@ -63,7 +75,8 @@
63
75
  "xto",
64
76
  "scaffold",
65
77
  "login",
66
- "menu"
78
+ "menu",
79
+ "cli"
67
80
  ],
68
81
  "author": "",
69
82
  "license": "MIT",
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 256 256">
2
+ <defs>
3
+ <linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="100%">
4
+ <stop offset="0%" style="stop-color:#409eff;stop-opacity:1" />
5
+ <stop offset="100%" style="stop-color:#67c23a;stop-opacity:1" />
6
+ </linearGradient>
7
+ </defs>
8
+ <rect width="256" height="256" rx="32" fill="url(#gradient)"/>
9
+ <text x="128" y="160" text-anchor="middle" fill="white" font-size="120" font-weight="bold" font-family="Arial">X</text>
10
+ </svg>
package/src/App.vue ADDED
@@ -0,0 +1,20 @@
1
+ <script setup lang="ts">
2
+ import { useAppStore } from '@/stores/app'
3
+
4
+ const appStore = useAppStore()
5
+ </script>
6
+
7
+ <template>
8
+ <div class="app" :class="{ dark: appStore.isDark }">
9
+ <router-view />
10
+ </div>
11
+ </template>
12
+
13
+ <style lang="scss">
14
+ .app {
15
+ width: 100%;
16
+ height: 100%;
17
+ background-color: var(--bg-color-page);
18
+ transition: background-color 0.3s;
19
+ }
20
+ </style>
@@ -0,0 +1,35 @@
1
+ /**
2
+ * 认证 API
3
+ */
4
+
5
+ import { http } from '@/utils/request'
6
+ import type { ApiResponse } from '@/utils/request'
7
+ import type { LoginResult } from '@/types/api'
8
+ import config from '@/config'
9
+
10
+ // 登录参数
11
+ export interface LoginParams {
12
+ uid: string
13
+ password: string
14
+ }
15
+
16
+ // 登录
17
+ export function login(data: LoginParams): Promise<ApiResponse<LoginResult>> {
18
+ return http.post<LoginResult>('/user/v1.0/login/by-domain', {
19
+ appId: config.appId,
20
+ clientId: config.clientId,
21
+ uid: data.uid,
22
+ password: data.password,
23
+ code: true
24
+ })
25
+ }
26
+
27
+ // 退出登录
28
+ export function logout(): Promise<ApiResponse<null>> {
29
+ return http.put<null>('/user/v1.0/user/logout')
30
+ }
31
+
32
+ // 根据 code 登录
33
+ export function loginByCode(appId: string, code: string): Promise<ApiResponse<LoginResult>> {
34
+ return http.get<LoginResult>(`/user/v1.0/login/by-code?appId=${appId}&code=${code}`)
35
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * 菜单 API
3
+ */
4
+
5
+ import { http } from '@/utils/request'
6
+ import type { ApiResponse } from '@/utils/request'
7
+ import type { RemoteMenuItem } from '@/types/api'
8
+ import config from '@/config'
9
+
10
+ // 获取用户菜单
11
+ export function getUserMenu(): Promise<ApiResponse<RemoteMenuItem[]>> {
12
+ return http.get<RemoteMenuItem[]>(`/user/v1.0/menu/get-menu?appId=${config.appId}`)
13
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * 系统管理 API
3
+ */
4
+
5
+ import { http, type PageParams, type PageResponse } from '@/utils/request'
6
+ import type { RoleInfo, MenuItem } from '@/types/api'
7
+
8
+ // ========== 角色管理 ==========
9
+
10
+ // 获取角色列表
11
+ export function getRoleList(params: PageParams & { status?: number; keyword?: string }) {
12
+ return http.get<PageResponse<RoleInfo>>('/role/list', { params })
13
+ }
14
+
15
+ // 获取角色详情
16
+ export function getRoleDetail(id: string | number) {
17
+ return http.get<RoleInfo>(`/role/${id}`)
18
+ }
19
+
20
+ // 创建角色
21
+ export function createRole(data: Partial<RoleInfo>) {
22
+ return http.post<RoleInfo>('/role', data)
23
+ }
24
+
25
+ // 更新角色
26
+ export function updateRole(id: string | number, data: Partial<RoleInfo>) {
27
+ return http.put<RoleInfo>(`/role/${id}`, data)
28
+ }
29
+
30
+ // 删除角色
31
+ export function deleteRole(id: string | number) {
32
+ return http.delete(`/role/${id}`)
33
+ }
34
+
35
+ // 更新角色状态
36
+ export function updateRoleStatus(id: string | number, status: number) {
37
+ return http.patch(`/role/${id}/status`, { status })
38
+ }
39
+
40
+ // ========== 菜单管理 ==========
41
+
42
+ // 获取菜单列表
43
+ export function getMenuList() {
44
+ return http.get<MenuItem[]>('/menu/list')
45
+ }
46
+
47
+ // 获取菜单树
48
+ export function getMenuTree() {
49
+ return http.get<MenuItem[]>('/menu/tree')
50
+ }
51
+
52
+ // 创建菜单
53
+ export function createMenu(data: Partial<MenuItem>) {
54
+ return http.post<MenuItem>('/menu', data)
55
+ }
56
+
57
+ // 更新菜单
58
+ export function updateMenu(id: string | number, data: Partial<MenuItem>) {
59
+ return http.put<MenuItem>(`/menu/${id}`, data)
60
+ }
61
+
62
+ // 删除菜单
63
+ export function deleteMenu(id: string | number) {
64
+ return http.delete(`/menu/${id}`)
65
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * 用户 API
3
+ */
4
+
5
+ import { http } from '@/utils/request'
6
+ import type { ApiResponse } from '@/utils/request'
7
+ import type { UserInfo } from '@/types/api'
8
+
9
+ // 获取当前用户信息
10
+ export function getCurrentUser(): Promise<ApiResponse<UserInfo>> {
11
+ return http.get<UserInfo>('/user/v1.0/user/get-me')
12
+ }