cmpt-huitu-cli 1.0.0
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.
- package/README.md +169 -0
- package/bin/huitu.js +30 -0
- package/package.json +38 -0
- package/src/create.js +127 -0
- package/src/versions.js +23 -0
- package/templates/default/README.md +127 -0
- package/templates/default/eslint.config.js +187 -0
- package/templates/default/index.html +38 -0
- package/templates/default/jsconfig.json +29 -0
- package/templates/default/package.json +56 -0
- package/templates/default/public/.DS_Store +0 -0
- package/templates/default/public/config/envCfg.js +68 -0
- package/templates/default/public/images/favicon.ico +0 -0
- package/templates/default/src/.DS_Store +0 -0
- package/templates/default/src/App.vue +49 -0
- package/templates/default/src/assets/.DS_Store +0 -0
- package/templates/default/src/assets/empty.png +0 -0
- package/templates/default/src/assets/images/.DS_Store +0 -0
- package/templates/default/src/assets/images/404/403_1.png +0 -0
- package/templates/default/src/assets/images/404/404.png +0 -0
- package/templates/default/src/assets/images/404/404_2.png +0 -0
- package/templates/default/src/assets/images/404/404_cloud.png +0 -0
- package/templates/default/src/assets/images/login/img.png +0 -0
- package/templates/default/src/assets/images/login/logo.png +0 -0
- package/templates/default/src/assets/images/login/person.png +0 -0
- package/templates/default/src/components/.DS_Store +0 -0
- package/templates/default/src/components/error/Error.vue +259 -0
- package/templates/default/src/components.d.ts +18 -0
- package/templates/default/src/imports.d.ts +90 -0
- package/templates/default/src/main.js +27 -0
- package/templates/default/src/routers/base.js +41 -0
- package/templates/default/src/routers/guard.js +43 -0
- package/templates/default/src/routers/index.js +36 -0
- package/templates/default/src/routers/modules/example.js +17 -0
- package/templates/default/src/services/.DS_Store +0 -0
- package/templates/default/src/services/login.js +32 -0
- package/templates/default/src/stores/README.md +317 -0
- package/templates/default/src/stores/index/global.js +49 -0
- package/templates/default/src/stores/index/template.js +31 -0
- package/templates/default/src/stores/index.js +14 -0
- package/templates/default/src/stores//344/275/277/347/224/250/347/244/272/344/276/213.vue +94 -0
- package/templates/default/src/styles/index.scss +23 -0
- package/templates/default/src/styles/theme/README.md +52 -0
- package/templates/default/src/styles/theme/variables.scss +62 -0
- package/templates/default/src/utils/RequestCache.js +198 -0
- package/templates/default/src/utils/auth.js +51 -0
- package/templates/default/src/utils/errorCode.js +16 -0
- package/templates/default/src/utils/index.js +519 -0
- package/templates/default/src/utils/requestAxios.js +148 -0
- package/templates/default/src/utils/theme.js +20 -0
- package/templates/default/src/views/About.vue +6 -0
- package/templates/default/src/views/Home.vue +111 -0
- package/templates/default/src/views/login/index.vue +285 -0
- package/templates/default/vite/plugins/autoComponents.js +18 -0
- package/templates/default/vite/plugins/autoImport.js +13 -0
- package/templates/default/vite/plugins/compression.js +24 -0
- package/templates/default/vite/plugins/externals.js +8 -0
- package/templates/default/vite/plugins/index.js +18 -0
- package/templates/default/vite/plugins/visualizer.js +11 -0
- package/templates/default/vite.config.js +185 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# 自定义主题样式
|
|
2
|
+
|
|
3
|
+
此目录用于存放项目特定的样式文件。
|
|
4
|
+
|
|
5
|
+
## 使用说明
|
|
6
|
+
|
|
7
|
+
1. 在此目录下创建你的自定义样式文件,例如:
|
|
8
|
+
- `custom.scss` - 自定义样式
|
|
9
|
+
- `variables.scss` - 项目特定的 CSS 变量
|
|
10
|
+
- `components.scss` - 组件样式覆盖
|
|
11
|
+
|
|
12
|
+
2. 在 `src/styles/index.scss` 中引入你的样式文件:
|
|
13
|
+
```scss
|
|
14
|
+
@import './theme/custom.scss';
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 公共样式
|
|
18
|
+
|
|
19
|
+
公共样式变量和 mixin 已通过 `@huitu/ui` 提供,在 `vite.config.js` 中已全局配置:
|
|
20
|
+
- `variables.scss` - 公共变量(字体大小、颜色等)
|
|
21
|
+
- `mixin.scss` - 公共 mixin(滚动条、统计数据样式等)
|
|
22
|
+
- `reset.scss` - 样式重置(Element Plus 组件样式重置等)
|
|
23
|
+
|
|
24
|
+
这些样式在项目中可以直接使用,无需手动引入。
|
|
25
|
+
|
|
26
|
+
## 示例
|
|
27
|
+
|
|
28
|
+
### 自定义主题变量
|
|
29
|
+
|
|
30
|
+
```scss
|
|
31
|
+
// src/styles/theme/variables.scss
|
|
32
|
+
:root[data-theme="light"] {
|
|
33
|
+
--my-custom-color: #067dff;
|
|
34
|
+
--my-custom-bg: #ffffff;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
:root[data-theme="dark"] {
|
|
38
|
+
--my-custom-color: #e3a000;
|
|
39
|
+
--my-custom-bg: #00192e;
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 自定义组件样式
|
|
44
|
+
|
|
45
|
+
```scss
|
|
46
|
+
// src/styles/theme/components.scss
|
|
47
|
+
.my-custom-component {
|
|
48
|
+
color: var(--my-custom-color);
|
|
49
|
+
background: var(--my-custom-bg);
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @FileDescription: 项目主题变量定义
|
|
3
|
+
* @Author: template
|
|
4
|
+
* @Date: 2026-01-04
|
|
5
|
+
* @Description:
|
|
6
|
+
* 定义项目特定的 CSS 变量
|
|
7
|
+
* reset.scss 中使用的变量需要在此定义
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/* 浅色主题 */
|
|
11
|
+
:root[data-theme="light"] {
|
|
12
|
+
/* 基础颜色 */
|
|
13
|
+
--main-font-color: #333333;
|
|
14
|
+
--main-color: #067dff;
|
|
15
|
+
--stat-font-color: #067dff;
|
|
16
|
+
|
|
17
|
+
/* 表格相关 */
|
|
18
|
+
// --table-head-bg: linear-gradient(180deg, #b2d2ff 0%, #b9daff 100%);
|
|
19
|
+
--table-head-color: #333333;
|
|
20
|
+
// --table-body-bg-color: rgb(205, 235, 255);
|
|
21
|
+
// --table-body-bg: linear-gradient(180deg, rgba(205, 235, 255, 0.74) 0%, rgba(212, 232, 248, 0.73) 100%);
|
|
22
|
+
--table-body-color: #333333;
|
|
23
|
+
// --table-body-border: #b4d3ec;
|
|
24
|
+
--table-body-hover: rgb(30, 137, 255, 0.85);
|
|
25
|
+
// --table-index-bg: #b4d9f6;
|
|
26
|
+
// --table-index-shadow: inset 0px 0px 4px 0px transparent;
|
|
27
|
+
|
|
28
|
+
/* Element Plus 变量覆盖 */
|
|
29
|
+
// --el-table-row-hover-bg-color: var(--table-body-hover);
|
|
30
|
+
|
|
31
|
+
// 强制覆盖 .el-table 内部变量,确保优先级
|
|
32
|
+
.el-table {
|
|
33
|
+
--el-table-row-hover-bg-color: var(--table-body-hover);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* 深色主题 */
|
|
38
|
+
:root[data-theme="dark"] {
|
|
39
|
+
/* 基础颜色 */
|
|
40
|
+
--main-font-color: #ffffff;
|
|
41
|
+
--main-color: #e3a000;
|
|
42
|
+
--stat-font-color: #ffffff;
|
|
43
|
+
|
|
44
|
+
/* 表格相关 */
|
|
45
|
+
// --table-head-bg: linear-gradient(180deg, rgba(1, 49, 78, 1) 0%, rgba(0, 66, 104, 1) 100%);
|
|
46
|
+
--table-head-color: #dff4fc;
|
|
47
|
+
// --table-body-bg-color: rgba(4, 34, 53, 1);
|
|
48
|
+
--table-body-bg: rgba(4, 34, 53, 1);
|
|
49
|
+
--table-body-color: #ffffff;
|
|
50
|
+
// --table-body-border: #030a10;
|
|
51
|
+
--table-body-hover: rgba(0, 136, 221, 0.85);
|
|
52
|
+
// --table-index-bg: rgba(42, 167, 255, 0.74);
|
|
53
|
+
// --table-index-shadow: inset 0px 0px 4px 0px #57ceff;
|
|
54
|
+
|
|
55
|
+
/* Element Plus 变量覆盖 */
|
|
56
|
+
// --el-table-row-hover-bg-color: var(--table-body-hover);
|
|
57
|
+
|
|
58
|
+
// 强制覆盖 .el-table 内部变量,确保优先级
|
|
59
|
+
.el-table {
|
|
60
|
+
--el-table-row-hover-bg-color: var(--table-body-hover);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { ElMessage } from 'element-plus'
|
|
2
|
+
import { axiosInstance } from '@utils/requestAxios.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @FileDescription:Ajax请求缓存类
|
|
6
|
+
* 1、统一处理同一个接口同样的参数、固定时间内(如:60s内)发生多次请求问题;
|
|
7
|
+
* 2、统一请求异常处理问题;
|
|
8
|
+
* 3、统一返回结果处理问题;
|
|
9
|
+
* @Author: yans
|
|
10
|
+
* @Date: 2025-12-26
|
|
11
|
+
* @LastEditors: yans
|
|
12
|
+
* @LastEditTime: 2025-12-30
|
|
13
|
+
* @param {Object} options - 缓存配置
|
|
14
|
+
*/
|
|
15
|
+
class RequestCache {
|
|
16
|
+
// 构造函数
|
|
17
|
+
constructor(options = {}) {
|
|
18
|
+
if (!options.ajax) {
|
|
19
|
+
throw new Error('请求实例未定义!')
|
|
20
|
+
}
|
|
21
|
+
// debugger
|
|
22
|
+
// 缓存配置
|
|
23
|
+
this.cache = new Map()
|
|
24
|
+
this.pendingRequests = new Map() // 临时存放正在进行的ajax请求
|
|
25
|
+
this.ajax = options.ajax // 请求实例
|
|
26
|
+
this.timeOut = options.timeOut || 1000 * 60 * 2 // 默认2分钟缓存
|
|
27
|
+
|
|
28
|
+
// 定时清理过期缓存, 默认3分钟执行一次
|
|
29
|
+
setInterval(() => this.cleanup(), 1000 * 60 * 3)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 获取缓存或发起请求: config: { method:'post', url:'/api/base/getUser', params:{}, data:{} },注意:config.notUseCache这个参数,默认不传递走缓存,如果不用缓存传 notUseCache:true
|
|
33
|
+
async request(config) {
|
|
34
|
+
// 默认都使用缓存,不使用缓存处理
|
|
35
|
+
const useCache = !config.notUseCache
|
|
36
|
+
if (useCache === false) {
|
|
37
|
+
const requestPromise = this.createRequest(config)
|
|
38
|
+
const result = await requestPromise
|
|
39
|
+
return { data: result, fromCache: '新请求' }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 使用缓存逻辑处理
|
|
43
|
+
const key = this.createKey(config)
|
|
44
|
+
const now = Date.now()
|
|
45
|
+
|
|
46
|
+
// 1. 检查是否有缓存且未过期
|
|
47
|
+
if (this.cache.has(key)) {
|
|
48
|
+
const { data, timestamp, timeOut } = this.cache.get(key)
|
|
49
|
+
if (now - timestamp < (timeOut || this.timeOut)) {
|
|
50
|
+
console.log('1、直接返回缓存数据')
|
|
51
|
+
return { data, fromCache: '是' }
|
|
52
|
+
}
|
|
53
|
+
this.cache.delete(key)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// 2. 检查是否有相同的请求正在进行
|
|
57
|
+
if (this.pendingRequests.has(key)) {
|
|
58
|
+
console.log('2、旧请求正在进行,请等待结果...')
|
|
59
|
+
try {
|
|
60
|
+
// 等待正在进行的请求完成
|
|
61
|
+
const result = await this.pendingRequests.get(key)
|
|
62
|
+
|
|
63
|
+
// 针对ajax异常返回的标识数据进行重新处理
|
|
64
|
+
return { data: result === -999.909 ? null : result, fromCache: 'Pending请求' }
|
|
65
|
+
} catch (error) {
|
|
66
|
+
// 如果正在进行请求失败,继续发起新请求
|
|
67
|
+
console.log('2、旧请求失败,错误信息:', error)
|
|
68
|
+
|
|
69
|
+
// 错误信息统一在此提示处理
|
|
70
|
+
const { message } = error
|
|
71
|
+
ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 3. 创建新的请求
|
|
76
|
+
const requestPromise = this.createRequest(config, key)
|
|
77
|
+
this.pendingRequests.set(key, requestPromise)
|
|
78
|
+
console.log('3、新请求正在进行,请等待结果...')
|
|
79
|
+
try {
|
|
80
|
+
const result = await requestPromise
|
|
81
|
+
|
|
82
|
+
// 缓存结果,备注:当result === -999.909的时候有是ajax请求异常,此时不缓存
|
|
83
|
+
if (result !== -999.909)
|
|
84
|
+
this.cache.set(key, {
|
|
85
|
+
data: result,
|
|
86
|
+
timestamp: now,
|
|
87
|
+
timeOut: config.timeOut || this.timeOut,
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
// 针对ajax异常返回的标识数据进行重新处理
|
|
91
|
+
return { data: result === -999.909 ? null : result, fromCache: '新请求' }
|
|
92
|
+
} catch (error) {
|
|
93
|
+
console.log('3、新请求失败,错误信息:', error)
|
|
94
|
+
|
|
95
|
+
// 错误信息统一在此提示处理
|
|
96
|
+
const { message } = error
|
|
97
|
+
ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
|
|
98
|
+
} finally {
|
|
99
|
+
// 清理进行中的请求
|
|
100
|
+
this.pendingRequests.delete(key)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 生成请求的唯一键
|
|
105
|
+
createKey(config) {
|
|
106
|
+
const { method, url, params, data } = config
|
|
107
|
+
|
|
108
|
+
// 规范化参数
|
|
109
|
+
const normalize = (obj) => {
|
|
110
|
+
if (!obj) return ''
|
|
111
|
+
if (typeof obj === 'string') return obj
|
|
112
|
+
return JSON.stringify(obj, Object.keys(obj || {}).sort())
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return `${method?.toLowerCase()}_${url?.toLowerCase()}_${normalize(params)}_${normalize(data)}`
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// 实际发起请求,注意:config.signal这个参数,如果要在vue页面中取消ajax请求,就需要传递该参数
|
|
119
|
+
async createRequest(config, key) {
|
|
120
|
+
if (key) {
|
|
121
|
+
// 先判断有没自带取消请求信号,有就使用自带的,没有就使用系统的
|
|
122
|
+
let signalNew = null
|
|
123
|
+
let timeoutId = null
|
|
124
|
+
if (config.signal) {
|
|
125
|
+
signalNew = config.signal
|
|
126
|
+
} else {
|
|
127
|
+
const controller = new AbortController()
|
|
128
|
+
const timeout = config.timeOut || this.timeOut
|
|
129
|
+
|
|
130
|
+
// 设置超时
|
|
131
|
+
timeoutId = setTimeout(() => {
|
|
132
|
+
controller.abort('请求超时取消')
|
|
133
|
+
}, timeout)
|
|
134
|
+
signalNew = controller.signal
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// 使用系统配置的axios,直接请求且可以取消请求
|
|
138
|
+
try {
|
|
139
|
+
const result = await this.ajax({
|
|
140
|
+
...config,
|
|
141
|
+
signal: signalNew,
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
// 像geojson文件请求或者wfs请求都返回结果是没有data的,所以这里要判断一下
|
|
145
|
+
return result?.data ?? result
|
|
146
|
+
} catch (error) {
|
|
147
|
+
console.log('请求失败,错误信息:', error)
|
|
148
|
+
|
|
149
|
+
// 错误信息统一在此提示处理
|
|
150
|
+
const { message } = error
|
|
151
|
+
ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
|
|
152
|
+
} finally {
|
|
153
|
+
if (timeoutId) clearTimeout(timeoutId)
|
|
154
|
+
}
|
|
155
|
+
} else {
|
|
156
|
+
// 使用用户自己配置的axios,直接请求
|
|
157
|
+
try {
|
|
158
|
+
const result = await this.ajax(config)
|
|
159
|
+
|
|
160
|
+
// 像geojson文件请求或者wfs请求都返回结果是没有data的,所以这里要判断一下
|
|
161
|
+
return result?.data ?? result
|
|
162
|
+
} catch (error) {
|
|
163
|
+
console.log('请求失败,错误信息:', error)
|
|
164
|
+
|
|
165
|
+
// 错误信息统一在此提示处理
|
|
166
|
+
const { message } = error
|
|
167
|
+
ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// 请求报错,返回特殊值进行标识
|
|
172
|
+
return -999.909
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// 自动清理过期缓存
|
|
176
|
+
cleanup() {
|
|
177
|
+
const now = Date.now()
|
|
178
|
+
for (const [key, value] of this.cache.entries()) {
|
|
179
|
+
if (now - value.timestamp > (value.timeOut || this.timeOut)) {
|
|
180
|
+
this.cache.delete(key)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// 手动清除缓存
|
|
186
|
+
clearCache(key) {
|
|
187
|
+
if (key) {
|
|
188
|
+
this.cache.delete(key)
|
|
189
|
+
this.pendingRequests.delete(key)
|
|
190
|
+
} else {
|
|
191
|
+
this.cache.clear()
|
|
192
|
+
this.pendingRequests.clear()
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// ***********创建ajax缓存请求实例, 默认缓存1.5分钟*********** //
|
|
198
|
+
export const cache = new RequestCache({ ajax: axiosInstance, timeOut: 1000 * 60 * 1.5 })
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @FileDescription: 系统登录信息工具类
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { cache } from '@huitu/utils'
|
|
6
|
+
const { session } = cache
|
|
7
|
+
// Token 管理(使用通用前缀)
|
|
8
|
+
export function getToken() {
|
|
9
|
+
return session.get('app_token')
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function setToken(token) {
|
|
13
|
+
return session.set('app_token', token)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function removeToken() {
|
|
17
|
+
return session.remove('app_token')
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Refresh Token 管理
|
|
21
|
+
export function getRefreshToken() {
|
|
22
|
+
return session.get('app_refresh_token')
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function setRefreshToken(token) {
|
|
26
|
+
return session.set('app_refresh_token', token)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function removeRefreshToken() {
|
|
30
|
+
return session.remove('app_refresh_token')
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 用户信息管理(使用通用前缀,避免业务冲突)
|
|
34
|
+
export function getUserInfo() {
|
|
35
|
+
return session.getJSON('app_userInfo')
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function setUserInfo(userInfo) {
|
|
39
|
+
return session.setJSON('app_userInfo', userInfo)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function removeUserInfo() {
|
|
43
|
+
return session.remove('app_userInfo')
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 清除所有登录信息
|
|
47
|
+
export function clearAuth() {
|
|
48
|
+
removeToken()
|
|
49
|
+
removeRefreshToken()
|
|
50
|
+
removeUserInfo()
|
|
51
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @FileDescription: HTTP请求错误码
|
|
3
|
+
* @Author: yans
|
|
4
|
+
* @Date: 2025-10-19
|
|
5
|
+
* @LastEditors: 最后更新作者
|
|
6
|
+
* @LastEditTime: 最后-新时间
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
401: '认证失败,无法访问系统资源',
|
|
11
|
+
403: '当前操作没有权限',
|
|
12
|
+
404: '访问资源不存在',
|
|
13
|
+
500: '服务器异常',
|
|
14
|
+
501: '获取数据失败',
|
|
15
|
+
default: '系统未知错误,请反馈给管理员',
|
|
16
|
+
}
|