create-jnrs-vue 1.2.11
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/LICENSE +21 -0
- package/README.md +61 -0
- package/bin/create.mjs +221 -0
- package/bin/upgrade.mjs +40 -0
- package/jnrs-template-vue/.env.development +13 -0
- package/jnrs-template-vue/.env.production +4 -0
- package/jnrs-template-vue/.prettierrc.json +12 -0
- package/jnrs-template-vue/README.md +48 -0
- package/jnrs-template-vue/auto-imports.d.ts +17 -0
- package/jnrs-template-vue/components.d.ts +51 -0
- package/jnrs-template-vue/eslint.config.ts +40 -0
- package/jnrs-template-vue/index.html +13 -0
- package/jnrs-template-vue/package.json +55 -0
- package/jnrs-template-vue/public/favicon.ico +0 -0
- package/jnrs-template-vue/public/system/menu.json +137 -0
- package/jnrs-template-vue/src/App.vue +45 -0
- package/jnrs-template-vue/src/api/common/index.ts +28 -0
- package/jnrs-template-vue/src/api/demos/index.ts +155 -0
- package/jnrs-template-vue/src/api/request.ts +53 -0
- package/jnrs-template-vue/src/api/system/index.ts +107 -0
- package/jnrs-template-vue/src/api/user/index.ts +12 -0
- package/jnrs-template-vue/src/assets/fonts/.keep +0 -0
- package/jnrs-template-vue/src/assets/fonts/AlibabaPuHuiTi-Regular.woff2 +0 -0
- package/jnrs-template-vue/src/assets/fonts/AlimamaShuHeiTi-Bold.woff2 +0 -0
- package/jnrs-template-vue/src/assets/images/common/403.png +0 -0
- package/jnrs-template-vue/src/assets/images/common/404.png +0 -0
- package/jnrs-template-vue/src/assets/images/common/avatar.png +0 -0
- package/jnrs-template-vue/src/assets/images/common/jnrs-white.svg +1 -0
- package/jnrs-template-vue/src/assets/styles/animation.scss +0 -0
- package/jnrs-template-vue/src/assets/styles/common.scss +39 -0
- package/jnrs-template-vue/src/assets/styles/fonts.scss +27 -0
- package/jnrs-template-vue/src/assets/styles/index.scss +5 -0
- package/jnrs-template-vue/src/assets/styles/init.scss +41 -0
- package/jnrs-template-vue/src/assets/styles/root.scss +13 -0
- package/jnrs-template-vue/src/components/common/CardTable.vue +90 -0
- package/jnrs-template-vue/src/components/common/DictTag.vue +74 -0
- package/jnrs-template-vue/src/components/common/ImageView.vue +144 -0
- package/jnrs-template-vue/src/components/common/PdfView.vue +115 -0
- package/jnrs-template-vue/src/components/select/SelectManager.vue +26 -0
- package/jnrs-template-vue/src/directives/permissions.ts +28 -0
- package/jnrs-template-vue/src/layout/BlankLayout.vue +15 -0
- package/jnrs-template-vue/src/layout/RouterTabs /344/277/256/345/244/215/350/267/257/347/224/261/350/267/263/350/275/254/346/220/272/345/270/246/345/217/202/346/225/260/351/227/256/351/242/230.vue" +150 -0
- package/jnrs-template-vue/src/layout/RouterTabs.vue +142 -0
- package/jnrs-template-vue/src/layout/SideMenu.vue +208 -0
- package/jnrs-template-vue/src/layout/SideMenuItem.vue +38 -0
- package/jnrs-template-vue/src/layout/TopHeader.vue +184 -0
- package/jnrs-template-vue/src/layout/index.vue +71 -0
- package/jnrs-template-vue/src/locales/en.ts +14 -0
- package/jnrs-template-vue/src/locales/index.ts +23 -0
- package/jnrs-template-vue/src/locales/zhCn.ts +14 -0
- package/jnrs-template-vue/src/main.ts +31 -0
- package/jnrs-template-vue/src/router/index.ts +77 -0
- package/jnrs-template-vue/src/router/routes.ts +48 -0
- package/jnrs-template-vue/src/types/env.d.ts +12 -0
- package/jnrs-template-vue/src/types/index.ts +81 -0
- package/jnrs-template-vue/src/types/webSocket.ts +19 -0
- package/jnrs-template-vue/src/utils/file.ts +56 -0
- package/jnrs-template-vue/src/utils/packages.ts +116 -0
- package/jnrs-template-vue/src/utils/permissions.ts +16 -0
- package/jnrs-template-vue/src/views/common/403.vue +52 -0
- package/jnrs-template-vue/src/views/common/404.vue +52 -0
- package/jnrs-template-vue/src/views/demos/crud/index.vue +355 -0
- package/jnrs-template-vue/src/views/demos/simpleTable/index.vue +41 -0
- package/jnrs-template-vue/src/views/demos/unitTest/RequestPage.vue +137 -0
- package/jnrs-template-vue/src/views/demos/unitTest/index.vue +131 -0
- package/jnrs-template-vue/src/views/home/index.vue +9 -0
- package/jnrs-template-vue/src/views/lingshuSmart/editorPage.vue +9 -0
- package/jnrs-template-vue/src/views/login/index.vue +314 -0
- package/jnrs-template-vue/src/views/system/dict/index.vue +161 -0
- package/jnrs-template-vue/src/views/system/menu/index.vue +43 -0
- package/jnrs-template-vue/src/views/system/mine/baseInfo.vue +108 -0
- package/jnrs-template-vue/src/views/system/mine/index.vue +83 -0
- package/jnrs-template-vue/src/views/system/mine/securitySettings.vue +105 -0
- package/jnrs-template-vue/src/views/system/role/editDialog.vue +94 -0
- package/jnrs-template-vue/src/views/system/role/index.vue +41 -0
- package/jnrs-template-vue/src/views/visual/index.vue +143 -0
- package/jnrs-template-vue/tsconfig.json +25 -0
- package/jnrs-template-vue/vite.config.ts +71 -0
- package/jnrs-template-vue/viteMockServe/fail.ts +38 -0
- package/jnrs-template-vue/viteMockServe/file/mock-pdf.pdf +0 -0
- package/jnrs-template-vue/viteMockServe/file/mock-png-0.png +0 -0
- package/jnrs-template-vue/viteMockServe/file/mock-png-1.png +0 -0
- package/jnrs-template-vue/viteMockServe/file.ts +67 -0
- package/jnrs-template-vue/viteMockServe/index.ts +87 -0
- package/jnrs-template-vue/viteMockServe/json/detailsRes.json +56 -0
- package/jnrs-template-vue/viteMockServe/json/dictItemRes.json +27 -0
- package/jnrs-template-vue/viteMockServe/json/dictRes.json +21 -0
- package/jnrs-template-vue/viteMockServe/json/loginRes_admin.json +157 -0
- package/jnrs-template-vue/viteMockServe/json/loginRes_user.json +713 -0
- package/jnrs-template-vue/viteMockServe/json/roleRes.json +37 -0
- package/jnrs-template-vue/viteMockServe/json/tableRes.json +390 -0
- package/jnrs-template-vue/viteMockServe/success.ts +39 -0
- package/package.json +41 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 JNRS Tech Co., Ltd.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# create-jnrs-vue
|
|
2
|
+
|
|
3
|
+
## ✨ 介绍
|
|
4
|
+
巨能前端工程化开发,Vue 项目模板脚手架
|
|
5
|
+
|
|
6
|
+
## 💻 技术栈
|
|
7
|
+
TypeScript、Vue3 生态
|
|
8
|
+
|
|
9
|
+
## 🧩 安装使用说明
|
|
10
|
+
新项目默认名称为 jnrs-template-vue
|
|
11
|
+
```shell
|
|
12
|
+
# ✅ 正确用法
|
|
13
|
+
# 创建新项目
|
|
14
|
+
pnpm create jnrs-template-vue@latest
|
|
15
|
+
# 在当前目录下创建项目
|
|
16
|
+
pnpm create jnrs-template-vue@latest .
|
|
17
|
+
|
|
18
|
+
# 安装依赖/启动开发/打包构建
|
|
19
|
+
pnpm i
|
|
20
|
+
pnpm dev
|
|
21
|
+
pnpm build
|
|
22
|
+
|
|
23
|
+
# 升级模板
|
|
24
|
+
运行 `pnpm upgrade-jnrs-vue` 将项目配置升级到最新模板版本(注意:请检查 breaking changes)。
|
|
25
|
+
|
|
26
|
+
# ❌ 错误用法
|
|
27
|
+
pnpm add create-jnrs-vue
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 📂 模板项目主要结构
|
|
31
|
+
```Text
|
|
32
|
+
jnrs-template-vue/
|
|
33
|
+
├── viteMockServe/ # Mock 服务配置
|
|
34
|
+
├── public/ # 静态资源
|
|
35
|
+
├── src/ # 源码目录
|
|
36
|
+
│ ├── components/ # Vue 组件
|
|
37
|
+
│ ├── composables/ # 组合式函数
|
|
38
|
+
│ ├── layout/ # 布局
|
|
39
|
+
│ ├── views/ # 页面视图
|
|
40
|
+
│ ├── router/ # 路由配置
|
|
41
|
+
│ ├── api/ # 接口定义(已含 request 实例)
|
|
42
|
+
│ ├── types/ # 类型定义
|
|
43
|
+
│ ├── store/ # 状态管理
|
|
44
|
+
│ ├── utils/ # 工具函数
|
|
45
|
+
│ ├── locales/ # 国际化
|
|
46
|
+
│ └── main.ts # 应用入口
|
|
47
|
+
├── index.html # HTML 入口文件
|
|
48
|
+
├── eslint.config.js # ESLint 配置文件
|
|
49
|
+
├── package.json # 包管理配置
|
|
50
|
+
└── vite.config.ts # Vite 构建配置
|
|
51
|
+
├── tsconfig.json # TypeScript 配置
|
|
52
|
+
├── auto-imports.d.ts # 自动导入类型声明
|
|
53
|
+
├── components.d.ts # 全局组件类型声明
|
|
54
|
+
├── README.md # 项目文档
|
|
55
|
+
├── .env.development # 开发环境变量
|
|
56
|
+
├── .env.production # 生产环境变量
|
|
57
|
+
├── .gitignore # Git 忽略规则
|
|
58
|
+
├── .prettierrc.json # Prettier 格式化配置
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
|
package/bin/create.mjs
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @Author : TanRui
|
|
3
|
+
* @WeChat : Tan578853789
|
|
4
|
+
* @File : create.mjs
|
|
5
|
+
* @Date : 2026/01/01
|
|
6
|
+
* @Desc. : 脚手架创建脚本(支持 workspace:* 依赖选择)
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { fileURLToPath } from 'url'
|
|
10
|
+
import { dirname, join, relative } from 'path'
|
|
11
|
+
import { promises as fs, existsSync } from 'fs'
|
|
12
|
+
import { execSync } from 'child_process'
|
|
13
|
+
import minimist from 'minimist'
|
|
14
|
+
import prompts from 'prompts'
|
|
15
|
+
|
|
16
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
17
|
+
const __dirname = dirname(__filename)
|
|
18
|
+
|
|
19
|
+
// 检测系统中可用的包管理器
|
|
20
|
+
function detectAvailablePackageManagers() {
|
|
21
|
+
const available = []
|
|
22
|
+
try {
|
|
23
|
+
execSync('pnpm --version', { stdio: 'ignore' })
|
|
24
|
+
available.push('pnpm')
|
|
25
|
+
} catch {}
|
|
26
|
+
try {
|
|
27
|
+
execSync('yarn --version', { stdio: 'ignore' })
|
|
28
|
+
available.push('yarn')
|
|
29
|
+
} catch {}
|
|
30
|
+
try {
|
|
31
|
+
execSync('npm --version', { stdio: 'ignore' })
|
|
32
|
+
available.push('npm')
|
|
33
|
+
} catch {}
|
|
34
|
+
return available.length ? available : ['npm']
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function getInstallCommand(packageManager) {
|
|
38
|
+
switch (packageManager) {
|
|
39
|
+
case 'pnpm':
|
|
40
|
+
return ['pnpm', 'install']
|
|
41
|
+
case 'yarn':
|
|
42
|
+
return ['yarn']
|
|
43
|
+
default:
|
|
44
|
+
return ['npm', 'install']
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function getRunCommand(packageManager, script) {
|
|
49
|
+
if (!packageManager || packageManager === 'skip') return `pnpm ${script}` // fallback for skip
|
|
50
|
+
switch (packageManager) {
|
|
51
|
+
case 'pnpm':
|
|
52
|
+
return `pnpm ${script}`
|
|
53
|
+
case 'yarn':
|
|
54
|
+
return `yarn ${script}`
|
|
55
|
+
case 'npm':
|
|
56
|
+
return `npm run ${script}`
|
|
57
|
+
default:
|
|
58
|
+
return `npm run ${script}`
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function isValidPackageName(projectName) {
|
|
63
|
+
return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(projectName)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function toValidPackageName(projectName) {
|
|
67
|
+
return projectName
|
|
68
|
+
.trim()
|
|
69
|
+
.toLowerCase()
|
|
70
|
+
.replace(/\s+/g, '-')
|
|
71
|
+
.replace(/^[._]/, '')
|
|
72
|
+
.replace(/[^a-z0-9-~@/._]/g, '-')
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 提取 workspace:* 依赖
|
|
76
|
+
function extractWorkspaceDeps(pkg) {
|
|
77
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies }
|
|
78
|
+
const workspaceDeps = Object.entries(deps)
|
|
79
|
+
.filter(([_, value]) => value === 'workspace:*')
|
|
80
|
+
.map(([name]) => name)
|
|
81
|
+
return workspaceDeps
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async function main() {
|
|
85
|
+
const argv = minimist(process.argv.slice(2), { string: ['_'] })
|
|
86
|
+
let targetDir = argv._[0]
|
|
87
|
+
|
|
88
|
+
// 新增:判断是否使用当前目录
|
|
89
|
+
const isCurrentDir = targetDir === '.'
|
|
90
|
+
|
|
91
|
+
if (!targetDir) {
|
|
92
|
+
const { name } = await prompts({
|
|
93
|
+
type: 'text',
|
|
94
|
+
name: 'name',
|
|
95
|
+
message: '项目名称:',
|
|
96
|
+
initial: 'jnrs-template-vue',
|
|
97
|
+
validate: (input) => {
|
|
98
|
+
if (!input) return '请输入项目名称!'
|
|
99
|
+
if (existsSync(input)) return '目录已存在!'
|
|
100
|
+
if (!isValidPackageName(input)) {
|
|
101
|
+
return '包名称无效!请使用小写字母、连字符,不要使用特殊字符'
|
|
102
|
+
}
|
|
103
|
+
return true
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
if (!name) process.exit(1)
|
|
107
|
+
targetDir = name
|
|
108
|
+
} else if (!isCurrentDir) {
|
|
109
|
+
if (!isValidPackageName(targetDir)) {
|
|
110
|
+
console.error('❌ 无效的项目名称:', targetDir)
|
|
111
|
+
console.error(' 包名称必须有效(小写、无空格等)')
|
|
112
|
+
process.exit(1)
|
|
113
|
+
}
|
|
114
|
+
if (existsSync(join(process.cwd(), targetDir))) {
|
|
115
|
+
console.error(`❌ 目录 "${targetDir}" 已存在!`)
|
|
116
|
+
process.exit(1)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const root = isCurrentDir ? process.cwd() : join(process.cwd(), targetDir.trim())
|
|
121
|
+
const templateDir = join(__dirname, '..', 'jnrs-template-vue')
|
|
122
|
+
|
|
123
|
+
await fs.cp(templateDir, root, { recursive: true })
|
|
124
|
+
|
|
125
|
+
const pkgPath = join(root, 'package.json')
|
|
126
|
+
const pkg = JSON.parse(await fs.readFile(pkgPath, 'utf8'))
|
|
127
|
+
|
|
128
|
+
const pkgName = isCurrentDir
|
|
129
|
+
? toValidPackageName(process.cwd().split(/[\\/]/).pop() || 'jnrs-template-vue')
|
|
130
|
+
: toValidPackageName(targetDir)
|
|
131
|
+
|
|
132
|
+
pkg.name = pkgName
|
|
133
|
+
|
|
134
|
+
// ===== 新增逻辑:处理 workspace:* 依赖 =====
|
|
135
|
+
const allWorkspaceDeps = extractWorkspaceDeps(pkg)
|
|
136
|
+
let selectedWorkspaceDeps = []
|
|
137
|
+
|
|
138
|
+
if (allWorkspaceDeps.length > 0) {
|
|
139
|
+
const defaultSelected = ['@jnrs/shared', '@jnrs/vue-core'].filter((dep) => allWorkspaceDeps.includes(dep))
|
|
140
|
+
|
|
141
|
+
const { selected } = await prompts({
|
|
142
|
+
type: 'multiselect',
|
|
143
|
+
name: 'selected',
|
|
144
|
+
message: '请选择要包含的 workspace 依赖(默认选中常用模块):',
|
|
145
|
+
choices: allWorkspaceDeps.map((dep) => ({
|
|
146
|
+
title: dep,
|
|
147
|
+
value: dep,
|
|
148
|
+
selected: defaultSelected.includes(dep)
|
|
149
|
+
})),
|
|
150
|
+
instructions: false
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
selectedWorkspaceDeps = selected || []
|
|
154
|
+
|
|
155
|
+
// 移除未选中的 workspace 依赖
|
|
156
|
+
for (const section of ['dependencies', 'devDependencies']) {
|
|
157
|
+
if (!pkg[section]) continue
|
|
158
|
+
for (const dep of Object.keys(pkg[section])) {
|
|
159
|
+
if (pkg[section][dep] === 'workspace:*' && !selectedWorkspaceDeps.includes(dep)) {
|
|
160
|
+
delete pkg[section][dep]
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// ===== 结束新增逻辑 =====
|
|
166
|
+
|
|
167
|
+
await fs.writeFile(pkgPath, JSON.stringify(pkg, null, 2))
|
|
168
|
+
|
|
169
|
+
// 检测可用包管理器
|
|
170
|
+
const availablePMs = detectAvailablePackageManagers()
|
|
171
|
+
const pmChoices = [...availablePMs.map((pm) => ({ title: pm, value: pm })), { title: '跳过安装依赖', value: 'skip' }]
|
|
172
|
+
|
|
173
|
+
const { selected: selectedPM } = await prompts({
|
|
174
|
+
type: 'select',
|
|
175
|
+
name: 'selected',
|
|
176
|
+
message: '请选择包管理器来安装依赖:',
|
|
177
|
+
choices: pmChoices,
|
|
178
|
+
initial: 0
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
if (!selectedPM) process.exit(1)
|
|
182
|
+
|
|
183
|
+
let packageManager = 'pnpm'
|
|
184
|
+
if (selectedPM !== 'skip') {
|
|
185
|
+
packageManager = selectedPM
|
|
186
|
+
console.log(`\n📦 使用 ${packageManager} 安装依赖项中...\n`)
|
|
187
|
+
const [cmd, ...args] = getInstallCommand(packageManager)
|
|
188
|
+
try {
|
|
189
|
+
execSync(`${cmd} ${args.join(' ')}`, {
|
|
190
|
+
cwd: root,
|
|
191
|
+
stdio: 'inherit',
|
|
192
|
+
env: { ...process.env, FORCE_COLOR: '1' }
|
|
193
|
+
})
|
|
194
|
+
} catch (e) {
|
|
195
|
+
console.error(
|
|
196
|
+
`\n⚠️ 安装依赖失败。请手动运行:\n cd ${relative(process.cwd(), root)} && ${cmd} ${args.join(' ')}`
|
|
197
|
+
)
|
|
198
|
+
process.exit(1)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// 成功提示
|
|
203
|
+
const relativePath = relative(process.cwd(), root)
|
|
204
|
+
const devCmd = getRunCommand(packageManager, 'dev')
|
|
205
|
+
|
|
206
|
+
console.log(`\n✅ 项目创建成功! 👌`)
|
|
207
|
+
console.log(`\n👉 cd ${relativePath}`)
|
|
208
|
+
if (selectedPM === 'skip') {
|
|
209
|
+
const fallbackPM = availablePMs[0] || 'npm'
|
|
210
|
+
const [cmd, ...args] = getInstallCommand(fallbackPM)
|
|
211
|
+
console.log(`\n👉 手动安装依赖:`)
|
|
212
|
+
console.log(` ${cmd} ${args.join(' ')}`)
|
|
213
|
+
}
|
|
214
|
+
console.log(` ${devCmd}\n`)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
main().catch((err) => {
|
|
218
|
+
console.error(`\n🚨 Error: ${err.message}`)
|
|
219
|
+
console.trace(err)
|
|
220
|
+
process.exit(1)
|
|
221
|
+
})
|
package/bin/upgrade.mjs
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @Author : TanRui
|
|
3
|
+
* @WeChat : Tan578853789
|
|
4
|
+
* @File : upgrade.mjs
|
|
5
|
+
* @Date : 2026/03/11
|
|
6
|
+
* @Desc. : 脚手架升级脚本
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { execSync } from 'child_process'
|
|
10
|
+
import { cpSync, readFileSync, writeFileSync } from 'fs'
|
|
11
|
+
import { join } from 'path'
|
|
12
|
+
|
|
13
|
+
console.log('🔄 正在拉取最新模板...')
|
|
14
|
+
|
|
15
|
+
// 1. 临时创建一个最新版模板
|
|
16
|
+
execSync('pnpm create jnrs-template-vue@latest ./_temp_new --force', {
|
|
17
|
+
stdio: 'inherit'
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
// 2. 安静地复制关键配置文件(不覆盖 src/)
|
|
21
|
+
const filesToSync = ['package.json', 'vite.config.ts', '.eslintrc.cjs', '.prettierrc', 'tsconfig.json', 'index.html']
|
|
22
|
+
|
|
23
|
+
for (const file of filesToSync) {
|
|
24
|
+
try {
|
|
25
|
+
cpSync(join('_temp_new', file), file, { force: true })
|
|
26
|
+
console.log(`✅ 同步: ${file}`)
|
|
27
|
+
} catch (e) {
|
|
28
|
+
console.warn(`⚠️ 跳过: ${file} (可能不存在)`)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 3. 提示用户手动处理依赖和业务代码
|
|
33
|
+
console.log('\n🔧 请运行:')
|
|
34
|
+
console.log(' pnpm install')
|
|
35
|
+
console.log('\n📝 注意:')
|
|
36
|
+
console.log(' - 检查 package.json 差异')
|
|
37
|
+
console.log(' - src/ 目录未自动更新,请手动合并新功能')
|
|
38
|
+
|
|
39
|
+
// 4. 清理临时目录
|
|
40
|
+
execSync('rm -rf _temp_new')
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
ENV = 'development'
|
|
2
|
+
|
|
3
|
+
# 是否是 mock 模式
|
|
4
|
+
VITE_USE_MOCK = true
|
|
5
|
+
|
|
6
|
+
# 后端接口基地址 - 开发环境
|
|
7
|
+
# VITE_BASE_URL = '192.168.1.120:6001'
|
|
8
|
+
VITE_BASE_URL = '192.168.1.112:5010'
|
|
9
|
+
|
|
10
|
+
# 应用运行主机(置空默认为 localhost)
|
|
11
|
+
VITE_APP_HOST = ''
|
|
12
|
+
# 应用运行端口(0 为自动分配)
|
|
13
|
+
VITE_APP_PORT = 5788
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# jnrs-template-vue
|
|
2
|
+
|
|
3
|
+
## ✨ 介绍
|
|
4
|
+
巨能前端工程化开发,Vue 项目信息化管理系统
|
|
5
|
+
|
|
6
|
+
## 💻 技术栈
|
|
7
|
+
TypeScript、Vue3 生态
|
|
8
|
+
|
|
9
|
+
## 🧩 安装使用说明
|
|
10
|
+
```shell
|
|
11
|
+
pnpm i
|
|
12
|
+
pnpm dev
|
|
13
|
+
pnpm build
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
#### 项目结构
|
|
17
|
+
```Text
|
|
18
|
+
jnrs-template-vue/
|
|
19
|
+
├── viteMockServe/ # Mock 服务配置
|
|
20
|
+
├── public/ # 静态资源
|
|
21
|
+
├── src/ # 源码目录
|
|
22
|
+
│ ├── components/ # Vue 组件
|
|
23
|
+
│ ├── composables/ # 组合式函数
|
|
24
|
+
│ ├── layout/ # 布局
|
|
25
|
+
│ ├── views/ # 页面视图
|
|
26
|
+
│ ├── router/ # 路由配置
|
|
27
|
+
│ ├── api/ # 接口定义(已含 request 实例)
|
|
28
|
+
│ ├── types/ # 类型定义
|
|
29
|
+
│ ├── store/ # 状态管理
|
|
30
|
+
│ ├── utils/ # 工具函数
|
|
31
|
+
│ ├── locales/ # 国际化
|
|
32
|
+
│ └── main.ts # 应用入口
|
|
33
|
+
├── index.html # HTML 入口文件
|
|
34
|
+
├── eslint.config.js # ESLint 配置文件
|
|
35
|
+
├── package.json # 包管理配置
|
|
36
|
+
└── vite.config.ts # Vite 构建配置
|
|
37
|
+
├── tsconfig.json # TypeScript 配置
|
|
38
|
+
├── auto-imports.d.ts # 自动导入类型声明
|
|
39
|
+
├── components.d.ts # 全局组件类型声明
|
|
40
|
+
├── README.md # 项目文档
|
|
41
|
+
├── .env.development # 开发环境变量
|
|
42
|
+
├── .env.production # 生产环境变量
|
|
43
|
+
├── .gitignore # Git 忽略规则
|
|
44
|
+
├── .prettierrc.json # Prettier 格式化配置
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## ⚠️ 注意事项
|
|
48
|
+
- layout 中使用了 KeepAlive 内置组件进行组件实例缓存,使用生命周期进行如“副作用清理“时注意用 onActivated / onDeactivated 替代 onMounted / onUnmounted
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
/* prettier-ignore */
|
|
3
|
+
// @ts-nocheck
|
|
4
|
+
// noinspection JSUnusedGlobalSymbols
|
|
5
|
+
// Generated by unplugin-auto-import
|
|
6
|
+
// biome-ignore lint: disable
|
|
7
|
+
export {}
|
|
8
|
+
declare global {
|
|
9
|
+
const ElButton: typeof import('element-plus/es').ElButton
|
|
10
|
+
const ElCheckbox: typeof import('element-plus/es').ElCheckbox
|
|
11
|
+
const ElMessage: typeof import('element-plus/es').ElMessage
|
|
12
|
+
const ElMessageBox: typeof import('element-plus/es').ElMessageBox
|
|
13
|
+
const ElOption: typeof import('element-plus/es').ElOption
|
|
14
|
+
const ElSwitch: typeof import('element-plus/es').ElSwitch
|
|
15
|
+
const ElTableColumn: typeof import('element-plus/es').ElTableColumn
|
|
16
|
+
const vLoading: typeof import('element-plus/es').ElLoadingDirective
|
|
17
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
// biome-ignore lint: disable
|
|
4
|
+
// oxlint-disable
|
|
5
|
+
// ------
|
|
6
|
+
// Generated by unplugin-vue-components
|
|
7
|
+
// Read more: https://github.com/vuejs/core/pull/3399
|
|
8
|
+
|
|
9
|
+
export {}
|
|
10
|
+
|
|
11
|
+
/* prettier-ignore */
|
|
12
|
+
declare module 'vue' {
|
|
13
|
+
export interface GlobalComponents {
|
|
14
|
+
ElAside: typeof import('element-plus/es')['ElAside']
|
|
15
|
+
ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
|
16
|
+
ElBadge: typeof import('element-plus/es')['ElBadge']
|
|
17
|
+
ElButton: typeof import('element-plus/es')['ElButton']
|
|
18
|
+
ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
|
|
19
|
+
ElCard: typeof import('element-plus/es')['ElCard']
|
|
20
|
+
ElCascader: typeof import('element-plus/es')['ElCascader']
|
|
21
|
+
ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
|
|
22
|
+
ElContainer: typeof import('element-plus/es')['ElContainer']
|
|
23
|
+
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
|
|
24
|
+
ElDatePickerPanel: typeof import('element-plus/es')['ElDatePickerPanel']
|
|
25
|
+
ElDialog: typeof import('element-plus/es')['ElDialog']
|
|
26
|
+
ElForm: typeof import('element-plus/es')['ElForm']
|
|
27
|
+
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
|
28
|
+
ElHeader: typeof import('element-plus/es')['ElHeader']
|
|
29
|
+
ElIcon: typeof import('element-plus/es')['ElIcon']
|
|
30
|
+
ElInput: typeof import('element-plus/es')['ElInput']
|
|
31
|
+
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
|
32
|
+
ElMain: typeof import('element-plus/es')['ElMain']
|
|
33
|
+
ElMenu: typeof import('element-plus/es')['ElMenu']
|
|
34
|
+
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
|
|
35
|
+
ElOption: typeof import('element-plus/es')['ElOption']
|
|
36
|
+
ElPopover: typeof import('element-plus/es')['ElPopover']
|
|
37
|
+
ElSelect: typeof import('element-plus/es')['ElSelect']
|
|
38
|
+
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
|
|
39
|
+
ElSwitch: typeof import('element-plus/es')['ElSwitch']
|
|
40
|
+
ElTable: typeof import('element-plus/es')['ElTable']
|
|
41
|
+
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
|
42
|
+
ElTabPane: typeof import('element-plus/es')['ElTabPane']
|
|
43
|
+
ElTabs: typeof import('element-plus/es')['ElTabs']
|
|
44
|
+
ElTag: typeof import('element-plus/es')['ElTag']
|
|
45
|
+
ElUpload: typeof import('element-plus/es')['ElUpload']
|
|
46
|
+
ElWatermark: typeof import('element-plus/es')['ElWatermark']
|
|
47
|
+
}
|
|
48
|
+
export interface GlobalDirectives {
|
|
49
|
+
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { fileURLToPath } from 'node:url'
|
|
2
|
+
import { dirname } from 'node:path'
|
|
3
|
+
import { globalIgnores } from 'eslint/config'
|
|
4
|
+
import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript'
|
|
5
|
+
import pluginVue from 'eslint-plugin-vue'
|
|
6
|
+
import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'
|
|
7
|
+
import parser from '@typescript-eslint/parser'
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
10
|
+
const __dirname = dirname(__filename)
|
|
11
|
+
|
|
12
|
+
export default defineConfigWithVueTs(
|
|
13
|
+
{
|
|
14
|
+
name: 'app/files-to-lint',
|
|
15
|
+
files: ['**/*.{ts,mts,tsx,vue}'],
|
|
16
|
+
languageOptions: {
|
|
17
|
+
parser: parser,
|
|
18
|
+
parserOptions: {
|
|
19
|
+
tsconfigRootDir: __dirname
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
rules: {
|
|
23
|
+
// 禁止使用 any 类型(显式和隐式)
|
|
24
|
+
'@typescript-eslint/no-explicit-any': 'error',
|
|
25
|
+
'vue/multi-word-component-names': [
|
|
26
|
+
'error',
|
|
27
|
+
{
|
|
28
|
+
ignores: ['index', '403', '404']
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
'vue/block-order': ['error', { order: ['script', 'template', 'style'] }]
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']),
|
|
36
|
+
|
|
37
|
+
pluginVue.configs['flat/essential'],
|
|
38
|
+
vueTsConfigs.recommended,
|
|
39
|
+
skipFormatting
|
|
40
|
+
)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" href="/favicon.ico" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>jnrs-template-vue</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="app"></div>
|
|
11
|
+
<script type="module" src="/src/main.ts"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "jnrs-template-vue",
|
|
3
|
+
"version": "1.2.11",
|
|
4
|
+
"description": "JNRS 信息化管理系统",
|
|
5
|
+
"author": "talia_tan",
|
|
6
|
+
"private": true,
|
|
7
|
+
"type": "module",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": "^20.19.0 || >=22.12.0"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"dev": "vite",
|
|
13
|
+
"build": "run-p type-check \"build-only {@}\" --",
|
|
14
|
+
"build-only": "vite build",
|
|
15
|
+
"preview": "vite preview",
|
|
16
|
+
"type-check": "vue-tsc --build",
|
|
17
|
+
"lint": "eslint . --fix",
|
|
18
|
+
"format": "prettier --write src/"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@element-plus/icons-vue": "^2.3.2",
|
|
22
|
+
"@jnrs/shared": "1.1.14",
|
|
23
|
+
"@jnrs/vue-core": "1.2.9",
|
|
24
|
+
"@jnrs/lingshu-smart": "2.2.4",
|
|
25
|
+
"@vueuse/core": "^14.1.0",
|
|
26
|
+
"element-plus": "^2.13.3",
|
|
27
|
+
"pinia": "^3.0.4",
|
|
28
|
+
"pinia-plugin-persistedstate": "^4.7.1",
|
|
29
|
+
"vue": "^3.5.25",
|
|
30
|
+
"vue-i18n": "^11.2.8"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@tsconfig/node22": "^22.0.5",
|
|
34
|
+
"@types/node": "^22.19.1",
|
|
35
|
+
"@typescript-eslint/parser": "^8.48.1",
|
|
36
|
+
"@vitejs/plugin-vue": "^6.0.2",
|
|
37
|
+
"@vue/eslint-config-prettier": "^10.2.0",
|
|
38
|
+
"@vue/eslint-config-typescript": "^14.6.0",
|
|
39
|
+
"@vue/tsconfig": "^0.8.1",
|
|
40
|
+
"eslint": "^9.39.1",
|
|
41
|
+
"eslint-plugin-vue": "~10.4.0",
|
|
42
|
+
"jiti": "^2.6.1",
|
|
43
|
+
"npm-run-all2": "^8.0.4",
|
|
44
|
+
"prettier": "3.6.2",
|
|
45
|
+
"sass": "^1.94.2",
|
|
46
|
+
"typescript": "~5.9.3",
|
|
47
|
+
"unplugin-auto-import": "^20.3.0",
|
|
48
|
+
"unplugin-vue-components": "^29.2.0",
|
|
49
|
+
"vite": "^7.2.2",
|
|
50
|
+
"vite-plugin-compression": "^0.5.1",
|
|
51
|
+
"vite-plugin-mock": "^3.0.2",
|
|
52
|
+
"vite-plugin-vue-devtools": "^8.0.5",
|
|
53
|
+
"vue-tsc": "^3.1.5"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
Binary file
|