10 changed files with 215 additions and 110 deletions
-
48increment-version.js
-
2src/apis/login.ts
-
83src/app.vue
-
1src/assets/images/login.svg
-
1src/assets/images/password_icon.svg
-
1src/assets/images/user_icon.svg
-
13src/layouts/default.vue
-
12src/stores/systemStore.ts
-
5src/types/system.d.ts
-
157src/views/login/index.vue
@ -1,41 +1,43 @@ |
|||
import fs from 'node:fs'; |
|||
import path, { dirname } from 'node:path'; |
|||
import { fileURLToPath } from 'node:url'; |
|||
import semver from 'semver'; |
|||
import { execSync } from 'child_process'; // 引入 child_process 模块用于执行 Git 命令
|
|||
import { execSync } from 'node:child_process' // 引入 child_process 模块用于执行 Git 命令
|
|||
import fs from 'node:fs' |
|||
import path, { dirname } from 'node:path' |
|||
import { fileURLToPath } from 'node:url' |
|||
import semver from 'semver' |
|||
|
|||
const __filename = fileURLToPath(import.meta.url); |
|||
const __dirname = dirname(__filename); |
|||
const __filename = fileURLToPath(import.meta.url) |
|||
const __dirname = dirname(__filename) |
|||
|
|||
const packagePath = path.resolve(__dirname, 'package.json'); |
|||
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf-8')); |
|||
const packagePath = path.resolve(__dirname, 'package.json') |
|||
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf-8')) |
|||
|
|||
// 读取命令行参数(默认使用 'patch')
|
|||
const versionType = process.argv[2] || 'patch'; |
|||
// eslint-disable-next-line node/prefer-global/process
|
|||
const versionType = process.argv[2] || 'patch' |
|||
|
|||
// 递增版本
|
|||
const newVersion = semver.inc(packageJson.version, versionType); |
|||
const newVersion = semver.inc(packageJson.version, versionType) |
|||
if (!newVersion) { |
|||
throw new Error(`Invalid version type: ${versionType}`); |
|||
throw new Error(`Invalid version type: ${versionType}`) |
|||
} |
|||
|
|||
packageJson.version = newVersion; |
|||
fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2)); |
|||
console.log(`Version updated to: ${newVersion}`); |
|||
packageJson.version = newVersion |
|||
fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2)) |
|||
console.log(`Version updated to: ${newVersion}`) |
|||
|
|||
// 新增:自动提交 package.json 到远程仓库
|
|||
try { |
|||
// 将 package.json 添加到暂存区
|
|||
execSync('git add package.json'); |
|||
console.log('Added package.json to staging area.'); |
|||
execSync('git add package.json') |
|||
console.log('Added package.json to staging area.') |
|||
|
|||
// 提交更改
|
|||
execSync(`git commit -m "fix: Update version to V${newVersion}"`); |
|||
console.log(`Committed changes with message: Update version to ${newVersion}`); |
|||
execSync(`git commit -m "fix: Update version to V${newVersion}"`) |
|||
console.log(`Committed changes with message: Update version to ${newVersion}`) |
|||
|
|||
// 推送到远程仓库
|
|||
execSync('git push'); |
|||
console.log('Pushed changes to remote repository.'); |
|||
} catch (error) { |
|||
console.error('Failed to commit and push changes:', error.message); |
|||
execSync('git push') |
|||
console.log('Pushed changes to remote repository.') |
|||
} |
|||
catch (error) { |
|||
console.error('Failed to commit and push changes:', error.message) |
|||
} |
@ -1,4 +1,4 @@ |
|||
import http from 'libs/http' |
|||
|
|||
export const login = (params: User.Login): Promise<User.User> => http.post('/auth/login', params) |
|||
export const logout = (params: User.Login): Promise<null> => http.post('/auth/logout', params) |
|||
export const logout = (): Promise<null> => http.post('/auth/logout') |
1
src/assets/images/login.svg
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1 @@ |
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="32.66561508178711" height="39.13572692871094" viewBox="0 0 32.66561508178711 39.13572692871094"><g><path d="M29.768,16.829C29.4345,16.829,27.5584,16.8498,27.204,16.8498L27.204,10.9347C27.204,4.37387,22.9722,0.0208277,16.3641,0C9.75591,0,5.4408,4.58215,5.4408,10.9347L5.4408,16.7873C5.21149,16.7873,2.8142,16.8082,2.60574,16.8082C1.02145,16.8082,0,18.162,0,19.6199L0,36.2615C0,37.9069,0.87553,39.1357,2.56405,39.1357L29.8514,39.1357C31.1647,39.1357,32.6656,37.9485,32.6656,35.8033L32.6656,19.9948C32.6656,18.3703,32.1236,16.829,29.768,16.829ZM19.9704,31.7626C19.9704,33.8246,18.3444,35.4908,16.3432,35.4908C14.342,35.4908,12.716,33.8246,12.716,31.7626L12.716,31.7001C12.716,30.3255,13.4456,29.1175,14.5296,28.4718L14.5296,21.5986C14.5296,20.6197,15.3009,20.5155,16.2598,20.5155C17.2188,20.5155,18.1568,20.6197,18.1568,21.5986L18.1568,28.4718C19.2408,29.1175,19.9704,30.3255,19.9704,31.7001L19.9704,31.7626ZM23.6185,16.7873L9.08884,16.7873L9.08884,9.28927C9.08884,5.68603,13.1121,3.7282,16.1348,3.7282L16.8018,3.7282C19.8245,3.7282,23.6185,5.54024,23.6185,9.28927L23.6185,16.7873Z" fill="#1989FA" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></svg> |
@ -0,0 +1 @@ |
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="33.87468338012695" height="33.84542465209961" viewBox="0 0 33.87468338012695 33.84542465209961"><g><path d="M33.8747,32.442C33.8747,25.5468,28.9971,19.6889,22.2628,17.6265C24.8808,15.9057,26.6152,12.9605,26.6152,9.61666C26.6152,4.31204,22.275,0,16.9373,0C11.5996,0,7.25944,4.31204,7.25944,9.61259C7.25944,12.9565,8.99389,15.9017,11.6118,17.6224C4.87763,19.6889,0,25.5427,0,32.442L0,33.8454L33.8747,33.8454L33.8747,32.4623L33.8747,32.442Z" fill="#1989FA" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></svg> |
@ -1,102 +1,113 @@ |
|||
<script setup lang="ts"> |
|||
import { login } from 'apis/login' |
|||
import logo from 'assets/images/logo.svg' |
|||
import password from 'assets/images/password_icon.svg' |
|||
import user from 'assets/images/user_icon.svg' |
|||
import { setToken } from 'libs/token' |
|||
import { useSystemStore } from 'stores/systemStore' |
|||
import { onBeforeUnmount, onMounted, ref } from 'vue' |
|||
import { ref } from 'vue' |
|||
import { useRouter } from 'vue-router' |
|||
|
|||
const router = useRouter() |
|||
|
|||
const progress = ref(0) |
|||
let timer: any = null |
|||
const version = __APP_VERSION__ |
|||
const sys = useSystemStore() |
|||
|
|||
const startProgress = () => { |
|||
timer = setInterval(() => { |
|||
const randomStep = Math.floor(Math.random() * 9 + 1) |
|||
const formRef = ref() |
|||
|
|||
progress.value = Math.min(progress.value + randomStep, 100) |
|||
const rules = { |
|||
username: [ |
|||
{ required: true, message: '请输入用户名', trigger: 'blur' }, |
|||
{ min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' }, |
|||
], |
|||
password: [ |
|||
{ required: true, message: '请输入密码', trigger: 'blur' }, |
|||
{ min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' }, |
|||
], |
|||
} |
|||
|
|||
if (progress.value >= 100) { |
|||
clearInterval(timer) |
|||
setToken('111') |
|||
useSystemStore().updateSystemUser({ username: '管理员' }) |
|||
router.push('/') |
|||
login({ username: 'admin', password: '12345' }).then((res) => { |
|||
setToken('111') |
|||
useSystemStore().updateSystemUser({ username: res.username }) |
|||
router.push('/') |
|||
}) |
|||
const loginHandle = async () => { |
|||
formRef.value.validate(async (valid: any) => { |
|||
if (!valid) { |
|||
return |
|||
} |
|||
}, 100) |
|||
const res = await login(sys.loginForm) |
|||
setToken('login success') |
|||
sys.updateSystemUser({ username: res.username }) |
|||
await router.push('/') |
|||
}) |
|||
} |
|||
onMounted(() => { |
|||
startProgress() |
|||
}) |
|||
|
|||
// login({ username: 'admin', password: '12345' }).then((res: any) => { |
|||
// setToken(res) |
|||
// |
|||
// }) |
|||
|
|||
// 组件卸载时清理定时器 |
|||
onBeforeUnmount(() => { |
|||
clearInterval(timer) |
|||
}) |
|||
</script> |
|||
|
|||
<template> |
|||
<div> |
|||
<!-- 进度条容器 --> |
|||
<div class="progress-container"> |
|||
<div class="progress-bar" :style="{ width: `${progress}%` }" /> |
|||
<div class="progress-text"> |
|||
v{{ version }}系统初始化中 {{ progress }}% |
|||
<div class="login-box"> |
|||
<div class="login-box-content"> |
|||
<img :src="logo" alt=""> |
|||
<div class="title"> |
|||
长春黄金研究院有限公司 |
|||
</div> |
|||
<el-form ref="formRef" :model="sys.loginForm" :rules="rules" style="width: 100%"> |
|||
<div class="input-title"> |
|||
用户名 |
|||
</div> |
|||
<el-form-item> |
|||
<el-input v-model="sys.loginForm.username" size="large" placeholder="请输入用户名"> |
|||
<template #prepend> |
|||
<img class="input-icon" :src="user" alt=""> |
|||
</template> |
|||
</el-input> |
|||
</el-form-item> |
|||
<div class="input-title"> |
|||
密码 |
|||
</div> |
|||
<el-form-item> |
|||
<el-input v-model="sys.loginForm.password" size="large" placeholder="请输入密码" type="password"> |
|||
<template #prepend> |
|||
<img class="input-icon" :src="password" alt=""> |
|||
</template> |
|||
</el-input> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<ft-button type="primary" style="width: 100%; margin: 20px 0 0;" :click-handle="loginHandle"> |
|||
登录 |
|||
</ft-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<style scoped lang="scss"> |
|||
.login-container { |
|||
.login-box { |
|||
background: url("assets/images/login.svg") no-repeat center; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
height: 100vh; |
|||
background: #f0f2f5; |
|||
} |
|||
img { |
|||
width: 600px; |
|||
position: absolute; |
|||
top: 40%; |
|||
right: 20%; |
|||
} |
|||
|
|||
.progress-container { |
|||
width: 50%; |
|||
height: 20px; |
|||
background: #e4e7ed; |
|||
border-radius: 30px; |
|||
position: relative; |
|||
top: 90%; |
|||
margin: 0 auto; |
|||
align-items: center; |
|||
.login-box-content { |
|||
padding: 50px 50px; |
|||
background: linear-gradient(180deg, rgba(250, 252, 255, 0.51) 0%, rgba(255, 255, 255, 0.52) 100%); |
|||
border-radius: 10px; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: center; |
|||
align-items: center; |
|||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.05); |
|||
img { |
|||
width: 50px; |
|||
} |
|||
.title{ |
|||
color: #8799AB; |
|||
font-weight: 500; |
|||
font-size: 18px; |
|||
margin: 15px 0 30px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.progress-bar { |
|||
height: 100%; |
|||
background: linear-gradient(90deg, #1989FA, #096ae0); |
|||
border-radius: 30px; |
|||
transition: width 0.3s ease; |
|||
.input-icon { |
|||
width: 15px !important; |
|||
} |
|||
|
|||
.progress-text { |
|||
position: absolute; |
|||
top: 50%; |
|||
left: 50%; |
|||
transform: translate(-50%, -50%); |
|||
color: #fff; |
|||
.input-title { |
|||
font-size: 14px; |
|||
font-weight: 500; |
|||
color: #2C3E59; |
|||
margin-bottom: 10px; |
|||
} |
|||
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue