Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
psa-web
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
高滢
psa-web
Commits
c8fb4184
Commit
c8fb4184
authored
Mar 11, 2025
by
高滢
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(标题): 配置
parent
95da1fbf
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
245 additions
and
190 deletions
+245
-190
.env.development
.env.development
+1
-1
.env.production
.env.production
+2
-2
.env.staging
.env.staging
+2
-2
index.html
index.html
+3
-3
package.json
package.json
+1
-1
favicon.png
public/favicon.png
+0
-0
logo.png
src/assets/logo/logo.png
+0
-0
sidebar.scss
src/assets/styles/sidebar.scss
+1
-1
index.vue
src/layout/components/Sidebar/index.vue
+6
-1
login.vue
src/views/login.vue
+229
-179
No files found.
.env.development
View file @
c8fb4184
# 页面标题
# 页面标题
VITE_APP_TITLE =
若依
管理系统
VITE_APP_TITLE =
融创软通PSA
管理系统
# 开发环境配置
# 开发环境配置
VITE_APP_ENV = 'development'
VITE_APP_ENV = 'development'
...
...
.env.production
View file @
c8fb4184
# 页面标题
# 页面标题
VITE_APP_TITLE =
若依
管理系统
VITE_APP_TITLE =
融创软通PSA
管理系统
# 生产环境配置
# 生产环境配置
VITE_APP_ENV = 'production'
VITE_APP_ENV = 'production'
...
...
.env.staging
View file @
c8fb4184
# 页面标题
# 页面标题
VITE_APP_TITLE =
若依
管理系统
VITE_APP_TITLE =
融创软通PSA
管理系统
# 生产环境配置
# 生产环境配置
VITE_APP_ENV = 'staging'
VITE_APP_ENV = 'staging'
...
...
index.html
View file @
c8fb4184
...
@@ -6,8 +6,8 @@
...
@@ -6,8 +6,8 @@
<meta
http-equiv=
"X-UA-Compatible"
content=
"IE=edge,chrome=1"
>
<meta
http-equiv=
"X-UA-Compatible"
content=
"IE=edge,chrome=1"
>
<meta
name=
"renderer"
content=
"webkit"
>
<meta
name=
"renderer"
content=
"webkit"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
>
<link
rel=
"icon"
href=
"/favicon.
ico
"
>
<link
rel=
"icon"
href=
"/favicon.
png
"
>
<title>
若依
管理系统
</title>
<title>
融创软通PSA
管理系统
</title>
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
<style>
<style>
html
,
html
,
...
...
package.json
View file @
c8fb4184
{
{
"name"
:
"ruoyi"
,
"name"
:
"ruoyi"
,
"version"
:
"3.8.9"
,
"version"
:
"3.8.9"
,
"description"
:
"
若依
管理系统"
,
"description"
:
"
融创软通PSA项目
管理系统"
,
"author"
:
"若依"
,
"author"
:
"若依"
,
"license"
:
"
MIT
"
,
"license"
:
"
MIT
"
,
"type"
:
"module"
,
"type"
:
"module"
,
...
...
public/favicon.png
0 → 100644
View file @
c8fb4184
3.66 KB
src/assets/logo/logo.png
View replaced file @
95da1fbf
View file @
c8fb4184
5.53 KB
|
W:
|
H:
3.66 KB
|
W:
|
H:
2-up
Swipe
Onion skin
src/assets/styles/sidebar.scss
View file @
c8fb4184
...
@@ -44,7 +44,7 @@
...
@@ -44,7 +44,7 @@
&
.has-logo
{
&
.has-logo
{
.el-scrollbar
{
.el-scrollbar
{
height
:
calc
(
100%
-
3
00px
);
height
:
calc
(
100%
-
4
00px
);
margin-top
:
80px
;
margin-top
:
80px
;
}
}
}
}
...
...
src/layout/components/Sidebar/index.vue
View file @
c8fb4184
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
/>
/>
</el-menu>
</el-menu>
</el-scrollbar>
</el-scrollbar>
<div
style=
"display: flex;justify-content: cen
ter"
>
<div
class=
"foo
ter"
>
<img
:src=
"comlogo"
class=
"comlogo"
>
<img
:src=
"comlogo"
class=
"comlogo"
>
</div>
</div>
</div>
</div>
...
@@ -81,6 +81,11 @@ const activeMenu = computed(() => {
...
@@ -81,6 +81,11 @@ const activeMenu = computed(() => {
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
.sidebar-container
{
.sidebar-container
{
background-color
:
v-bind
(
getMenuBackground
);
background-color
:
v-bind
(
getMenuBackground
);
.footer
{
position
:
absolute
;
bottom
:
60px
;
left
:
38px
;
}
.avatar
{
.avatar
{
position
:
absolute
;
position
:
absolute
;
top
:
40px
;
top
:
40px
;
...
...
src/views/login.vue
View file @
c8fb4184
<
template
>
<
template
>
<div
class=
"login"
>
<div
class=
"login"
>
<el-form
ref=
"loginRef"
:model=
"loginForm"
:rules=
"loginRules"
class=
"login-form"
>
<el-form
<h3
class=
"title"
>
若依后台管理系统
</h3>
ref=
"loginRef"
:model=
"loginForm"
:rules=
"loginRules"
class=
"login-form"
>
<h3
class=
"title"
>
融创软通PSA管理系统
</h3>
<el-form-item
prop=
"username"
>
<el-form-item
prop=
"username"
>
<el-input
<el-input
v-model=
"loginForm.username"
v-model=
"loginForm.username"
...
@@ -10,7 +15,11 @@
...
@@ -10,7 +15,11 @@
auto-complete=
"off"
auto-complete=
"off"
placeholder=
"账号"
placeholder=
"账号"
>
>
<template
#
prefix
><svg-icon
icon-class=
"user"
class=
"el-input__icon input-icon"
/></
template
>
<template
#
prefix
><svg-icon
icon-class=
"user"
class=
"el-input__icon input-icon"
/></
template
>
</el-input>
</el-input>
</el-form-item>
</el-form-item>
<el-form-item
prop=
"password"
>
<el-form-item
prop=
"password"
>
...
@@ -22,10 +31,14 @@
...
@@ -22,10 +31,14 @@
placeholder=
"密码"
placeholder=
"密码"
@
keyup
.
enter=
"handleLogin"
@
keyup
.
enter=
"handleLogin"
>
>
<
template
#
prefix
><svg-icon
icon-class=
"password"
class=
"el-input__icon input-icon"
/></
template
>
<
template
#
prefix
><svg-icon
icon-class=
"password"
class=
"el-input__icon input-icon"
/></
template
>
</el-input>
</el-input>
</el-form-item>
</el-form-item>
<el-form-item
prop=
"code"
v-if=
"captchaEnabled
"
>
<el-form-item
v-if=
"captchaEnabled"
prop=
"code
"
>
<el-input
<el-input
v-model=
"loginForm.code"
v-model=
"loginForm.code"
size=
"large"
size=
"large"
...
@@ -34,26 +47,40 @@
...
@@ -34,26 +47,40 @@
style=
"width: 63%"
style=
"width: 63%"
@
keyup
.
enter=
"handleLogin"
@
keyup
.
enter=
"handleLogin"
>
>
<
template
#
prefix
><svg-icon
icon-class=
"validCode"
class=
"el-input__icon input-icon"
/></
template
>
<
template
#
prefix
><svg-icon
icon-class=
"validCode"
class=
"el-input__icon input-icon"
/></
template
>
</el-input>
</el-input>
<div
class=
"login-code"
>
<div
class=
"login-code"
>
<img
:src=
"codeUrl"
@
click=
"getCode"
class=
"login-code-img"
/>
<img
:src=
"codeUrl"
class=
"login-code-img"
@
click=
"getCode"
/>
</div>
</div>
</el-form-item>
</el-form-item>
<el-checkbox
v-model=
"loginForm.rememberMe"
style=
"margin:0px 0px 25px 0px;"
>
记住密码
</el-checkbox>
<el-checkbox
<el-form-item
style=
"width:100%;"
>
v-model=
"loginForm.rememberMe"
style=
"margin: 0px 0px 25px 0px"
>
记住密码
</el-checkbox
>
<el-form-item
style=
"width: 100%"
>
<el-button
<el-button
:loading=
"loading"
:loading=
"loading"
size=
"large"
size=
"large"
type=
"primary"
type=
"primary"
style=
"width:100%;
"
style=
"width: 100%
"
@
click
.
prevent=
"handleLogin"
@
click
.
prevent=
"handleLogin"
>
>
<span
v-if=
"!loading"
>
登 录
</span>
<span
v-if=
"!loading"
>
登 录
</span>
<span
v-else
>
登 录 中...
</span>
<span
v-else
>
登 录 中...
</span>
</el-button>
</el-button>
<div
style=
"float: right;"
v-if=
"register"
>
<div
v-if=
"register"
style=
"float: right"
>
<router-link
class=
"link-type"
:to=
"'/register'"
>
立即注册
</router-link>
<router-link
class=
"link-type"
:to=
"'/register'"
>
立即注册
</router-link
>
</div>
</div>
</el-form-item>
</el-form-item>
</el-form>
</el-form>
...
@@ -65,110 +92,133 @@
...
@@ -65,110 +92,133 @@
</template>
</template>
<
script
setup
>
<
script
setup
>
import
{
getCodeImg
}
from
"@/api/login"
;
import
{
getCodeImg
}
from
'@/api/login'
import
Cookies
from
"js-cookie"
;
import
Cookies
from
'js-cookie'
import
{
encrypt
,
decrypt
}
from
"@/utils/jsencrypt"
;
import
{
encrypt
,
decrypt
}
from
'@/utils/jsencrypt'
import
useUserStore
from
'@/store/modules/user'
import
useUserStore
from
'@/store/modules/user'
const
userStore
=
useUserStore
()
const
userStore
=
useUserStore
()
const
route
=
useRoute
()
;
const
route
=
useRoute
()
const
router
=
useRouter
()
;
const
router
=
useRouter
()
const
{
proxy
}
=
getCurrentInstance
()
;
const
{
proxy
}
=
getCurrentInstance
()
const
loginForm
=
ref
({
const
loginForm
=
ref
({
username
:
"admin"
,
username
:
'admin'
,
password
:
"admin123"
,
password
:
'admin123'
,
rememberMe
:
false
,
rememberMe
:
false
,
code
:
""
,
code
:
''
,
uuid
:
""
uuid
:
''
})
;
})
const
loginRules
=
{
const
loginRules
=
{
username
:
[{
required
:
true
,
trigger
:
"blur"
,
message
:
"请输入您的账号"
}],
username
:
[{
required
:
true
,
trigger
:
'blur'
,
message
:
'请输入您的账号'
}],
password
:
[{
required
:
true
,
trigger
:
"blur"
,
message
:
"请输入您的密码"
}],
password
:
[{
required
:
true
,
trigger
:
'blur'
,
message
:
'请输入您的密码'
}],
code
:
[{
required
:
true
,
trigger
:
"change"
,
message
:
"请输入验证码"
}]
code
:
[{
required
:
true
,
trigger
:
'change'
,
message
:
'请输入验证码'
}]
}
;
}
const
codeUrl
=
ref
(
""
);
const
codeUrl
=
ref
(
''
)
const
loading
=
ref
(
false
)
;
const
loading
=
ref
(
false
)
// 验证码开关
// 验证码开关
const
captchaEnabled
=
ref
(
true
)
;
const
captchaEnabled
=
ref
(
true
)
// 注册开关
// 注册开关
const
register
=
ref
(
false
)
;
const
register
=
ref
(
false
)
const
redirect
=
ref
(
undefined
)
;
const
redirect
=
ref
(
undefined
)
watch
(
route
,
(
newRoute
)
=>
{
watch
(
redirect
.
value
=
newRoute
.
query
&&
newRoute
.
query
.
redirect
;
route
,
},
{
immediate
:
true
});
newRoute
=>
{
redirect
.
value
=
newRoute
.
query
&&
newRoute
.
query
.
redirect
},
{
immediate
:
true
}
)
function
handleLogin
()
{
function
handleLogin
()
{
proxy
.
$refs
.
loginRef
.
validate
(
valid
=>
{
proxy
.
$refs
.
loginRef
.
validate
(
valid
=>
{
if
(
valid
)
{
if
(
valid
)
{
loading
.
value
=
true
;
loading
.
value
=
true
// 勾选了需要记住密码设置在 cookie 中设置记住用户名和密码
// 勾选了需要记住密码设置在 cookie 中设置记住用户名和密码
if
(
loginForm
.
value
.
rememberMe
)
{
if
(
loginForm
.
value
.
rememberMe
)
{
Cookies
.
set
(
"username"
,
loginForm
.
value
.
username
,
{
expires
:
30
});
Cookies
.
set
(
'username'
,
loginForm
.
value
.
username
,
{
Cookies
.
set
(
"password"
,
encrypt
(
loginForm
.
value
.
password
),
{
expires
:
30
});
expires
:
30
Cookies
.
set
(
"rememberMe"
,
loginForm
.
value
.
rememberMe
,
{
expires
:
30
});
})
Cookies
.
set
(
'password'
,
encrypt
(
loginForm
.
value
.
password
),
{
expires
:
30
})
Cookies
.
set
(
'rememberMe'
,
loginForm
.
value
.
rememberMe
,
{
expires
:
30
})
}
else
{
}
else
{
// 否则移除
// 否则移除
Cookies
.
remove
(
"username"
);
Cookies
.
remove
(
'username'
)
Cookies
.
remove
(
"password"
);
Cookies
.
remove
(
'password'
)
Cookies
.
remove
(
"rememberMe"
);
Cookies
.
remove
(
'rememberMe'
)
}
}
// 调用action的登录方法
// 调用action的登录方法
userStore
.
login
(
loginForm
.
value
).
then
(()
=>
{
userStore
const
query
=
route
.
query
;
.
login
(
loginForm
.
value
)
const
otherQueryParams
=
Object
.
keys
(
query
).
reduce
((
acc
,
cur
)
=>
{
.
then
(()
=>
{
if
(
cur
!==
"redirect"
)
{
const
query
=
route
.
query
acc
[
cur
]
=
query
[
cur
];
const
otherQueryParams
=
Object
.
keys
(
query
).
reduce
(
(
acc
,
cur
)
=>
{
if
(
cur
!==
'redirect'
)
{
acc
[
cur
]
=
query
[
cur
]
}
}
return
acc
;
return
acc
},
{});
},
router
.
push
({
path
:
redirect
.
value
||
"/"
,
query
:
otherQueryParams
});
{}
}).
catch
(()
=>
{
)
loading
.
value
=
false
;
router
.
push
({
path
:
redirect
.
value
||
'/'
,
query
:
otherQueryParams
})
})
.
catch
(()
=>
{
loading
.
value
=
false
// 重新获取验证码
// 重新获取验证码
if
(
captchaEnabled
.
value
)
{
if
(
captchaEnabled
.
value
)
{
getCode
();
getCode
()
}
}
});
})
}
}
});
})
}
}
function
getCode
()
{
function
getCode
()
{
getCodeImg
().
then
(
res
=>
{
getCodeImg
().
then
(
res
=>
{
captchaEnabled
.
value
=
res
.
captchaEnabled
===
undefined
?
true
:
res
.
captchaEnabled
;
captchaEnabled
.
value
=
res
.
captchaEnabled
===
undefined
?
true
:
res
.
captchaEnabled
if
(
captchaEnabled
.
value
)
{
if
(
captchaEnabled
.
value
)
{
codeUrl
.
value
=
"data:image/gif;base64,"
+
res
.
img
;
codeUrl
.
value
=
'data:image/gif;base64,'
+
res
.
img
loginForm
.
value
.
uuid
=
res
.
uuid
;
loginForm
.
value
.
uuid
=
res
.
uuid
}
}
});
})
}
}
function
getCookie
()
{
function
getCookie
()
{
const
username
=
Cookies
.
get
(
"username"
);
const
username
=
Cookies
.
get
(
'username'
)
const
password
=
Cookies
.
get
(
"password"
);
const
password
=
Cookies
.
get
(
'password'
)
const
rememberMe
=
Cookies
.
get
(
"rememberMe"
);
const
rememberMe
=
Cookies
.
get
(
'rememberMe'
)
loginForm
.
value
=
{
loginForm
.
value
=
{
username
:
username
===
undefined
?
loginForm
.
value
.
username
:
username
,
username
:
username
===
undefined
?
loginForm
.
value
.
username
:
username
,
password
:
password
===
undefined
?
loginForm
.
value
.
password
:
decrypt
(
password
),
password
:
password
===
undefined
?
loginForm
.
value
.
password
:
decrypt
(
password
),
rememberMe
:
rememberMe
===
undefined
?
false
:
Boolean
(
rememberMe
)
rememberMe
:
rememberMe
===
undefined
?
false
:
Boolean
(
rememberMe
)
};
}
}
}
getCode
()
;
getCode
()
getCookie
()
;
getCookie
()
</
script
>
</
script
>
<
style
lang=
'scss'
scoped
>
<
style
lang=
"scss"
scoped
>
.login
{
.login
{
display
:
flex
;
display
:
flex
;
justify-content
:
center
;
justify-content
:
center
;
align-items
:
center
;
align-items
:
center
;
height
:
100%
;
height
:
100%
;
background-image
:
url("../assets/images/login-background.jpg"
)
;
background-image
:
url('../assets/images/login-background.jpg'
)
;
background-size
:
cover
;
background-size
:
cover
;
}
}
.title
{
.title
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment