Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
basic-uniapp-v3
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
1
合并请求
1
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Basic
basic-uniapp-v3
Commits
2a2d7e73
提交
2a2d7e73
authored
4月 30, 2026
作者:
吴佳伟
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: 优化登录页面样式
上级
77b370ed
显示空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
57 行增加
和
113 行删除
+57
-113
login.vue
src/pages/login/login.vue
+57
-113
没有找到文件。
src/pages/login/login.vue
浏览文件 @
2a2d7e73
...
...
@@ -28,7 +28,6 @@
const
readConfirmShow
=
ref
<
boolean
>
(
false
)
const
form
=
ref
()
const
showSlide
=
ref
(
false
)
const
loginMode
=
ref
(
1
)
// 1: 验证码登录, 2: 密码登录
const
slideType
=
ref
<
'sms'
|
'login'
>
(
'login'
)
...
...
@@ -71,35 +70,8 @@
],
},
],
pwdLoginRules
:
[
{
name
:
'username'
,
rule
:
[
'required'
],
msg
:
[
'请输入账号'
],
},
{
name
:
'password'
,
rule
:
[
'required'
],
msg
:
[
'请输入密码'
],
},
{
name
:
'read'
,
validator
:
[
{
msg
:
'请阅读并同意服务协议和隐私政策'
,
method
:
(
value
:
boolean
)
=>
{
if
(
!
value
)
{
readConfirmShow
.
value
=
true
}
return
value
},
},
],
},
],
data
:
{
username
:
''
,
password
:
''
,
code
:
''
,
read
:
false
,
},
...
...
@@ -110,17 +82,11 @@
if
(
isDevMode
())
{
model
.
form
.
data
.
username
=
'admin'
model
.
form
.
data
.
password
=
'Yiring=2026#@!'
model
.
form
.
data
.
read
=
true
}
function
switchMode
(
mode
:
number
)
{
loginMode
.
value
=
mode
}
function
login
()
{
const
rules
=
loginMode
.
value
===
1
?
model
.
form
.
codeLoginRules
:
model
.
form
.
pwdLoginRules
form
?.
value
.
validator
(
model
.
form
.
data
,
rules
).
then
(
async
(
res
:
{
isPassed
:
boolean
})
=>
{
form
?.
value
.
validator
(
model
.
form
.
data
,
model
.
form
.
codeLoginRules
).
then
(
async
(
res
:
{
isPassed
:
boolean
})
=>
{
if
(
res
.
isPassed
)
{
// 登录前先做滑动验证 (Requirement 7)
slideType
.
value
=
'login'
...
...
@@ -132,7 +98,8 @@
function
smsCode
()
{
form
?.
value
.
validator
(
model
.
form
.
data
,
model
.
form
.
phoneRules
).
then
(
async
(
res
:
{
isPassed
:
boolean
})
=>
{
if
(
res
.
isPassed
)
{
if
(
model
.
countdown
>
0
)
return
if
(
model
.
countdown
>
0
)
return
slideType
.
value
=
'sms'
showSlide
.
value
=
true
}
...
...
@@ -165,7 +132,6 @@
function
doLogin
()
{
model
.
loading
=
true
if
(
loginMode
.
value
===
1
)
{
// 验证码登录
const
params
=
{
mobile
:
model
.
form
.
data
.
username
,
...
...
@@ -174,16 +140,6 @@
API
.
phoneLogin
(
params
)
.
then
(
handleLoginSuccess
)
.
finally
(()
=>
(
model
.
loading
=
false
))
}
else
{
// 密码登录
const
params
=
{
username
:
model
.
form
.
data
.
username
,
password
:
model
.
form
.
data
.
password
,
}
API
.
sysLogin
(
params
)
.
then
(
handleLoginSuccess
)
.
finally
(()
=>
(
model
.
loading
=
false
))
}
}
async
function
handleLoginSuccess
(
body
:
any
)
{
...
...
@@ -199,7 +155,8 @@
}
function
startCountdown
()
{
if
(
countdownTimer
)
clearInterval
(
countdownTimer
)
if
(
countdownTimer
)
clearInterval
(
countdownTimer
)
model
.
countdown
=
60
countdownTimer
=
setInterval
(()
=>
{
model
.
countdown
--
...
...
@@ -248,7 +205,7 @@
<!-- 顶部设计:数智化农场全景感 -->
<view
class=
"header-visual"
>
<image
class=
"header-scene"
src=
"/static/images/login/farm_base_bg.png"
mode=
"aspectFill"
/>
<view
class=
"header-overlay"
></view
>
<view
class=
"header-overlay"
/
>
<!-- 顶部装饰元素:漂浮的气象/农业设备(体现数智感) -->
<image
class=
"float-icon device-1"
src=
"/static/images/nongchang/device1.png"
mode=
"aspectFit"
/>
...
...
@@ -259,10 +216,6 @@
<view
class=
"close-btn"
@
click=
"goHome"
>
<fui-icon
name=
"close"
:size=
"48"
color=
"#fff"
/>
</view>
<view
class=
"switch-action"
@
click=
"switchMode(loginMode === 1 ? 2 : 1)"
>
<text>
{{
loginMode
===
1
?
'密码登录'
:
'验证码登录'
}}
</text>
<fui-icon
name=
"arrowright"
:size=
"24"
color=
"#fff"
/>
</view>
</view>
<!-- 品牌标识与数智概览 -->
...
...
@@ -286,17 +239,17 @@
<fui-form
ref=
"form"
top=
"0"
:padding=
"['0', '0']"
background=
"transparent"
>
<view
class=
"card-header"
>
<text
class=
"welcome-text"
>
您好,欢迎登录
</text>
<view
class=
"green-line"
></view
>
<view
class=
"green-line"
/
>
</view>
<!-- 输入区域 -->
<view
class=
"input-fields"
>
<view
class=
"field-item"
>
<text
class=
"field-label"
>
{{
loginMode
===
1
?
'手机号'
:
'账号'
}}
</text>
<text
class=
"field-label"
>
手机号
</text>
<fui-input
v-model=
"model.form.data.username"
:padding=
"['24rpx', '0']"
:placeholder=
"loginMode === 1 ? '请输入手机号' : '请输入账号'
"
placeholder=
"请输入手机号
"
backgroundColor=
"transparent"
borderColor=
"#F0F0F0"
borderBottom
...
...
@@ -305,7 +258,7 @@
/>
</view>
<view
class=
"field-item"
v-if=
"loginMode === 1"
>
<view
class=
"field-item"
>
<text
class=
"field-label"
>
验证码
</text>
<view
class=
"code-inner"
>
<fui-input
...
...
@@ -324,21 +277,6 @@
<
/view
>
<
/view
>
<
/view
>
<
view
class
=
"field-item"
v
-
if
=
"loginMode === 2"
>
<
text
class
=
"field-label"
>
密码
<
/text
>
<
fui
-
input
v
-
model
=
"model.form.data.password"
type
=
"password"
:
padding
=
"['24rpx', '0']"
placeholder
=
"请输入密码"
backgroundColor
=
"transparent"
borderColor
=
"#F0F0F0"
borderBottom
height
=
"110rpx"
size
=
"34"
/>
<
/view
>
<
/view
>
<!--
登录决策
-->
...
...
@@ -371,7 +309,11 @@
@
change
=
"(e) => (model.form.data.read = e.checked)"
/>
<
view
class
=
"policy-text"
>
同意
<
text
class
=
"link"
@
click
.
stop
=
"Link.to(Link.services, '服务协议')"
>
《服务协议》
<
/text>与<text class="link" @click.stop="Link.to
(
Link.privacy, '隐私政策'
)
">《隐私政策》</
text
>
同意
<
text
class
=
"link"
@
click
.
stop
=
"Link.to(Link.services, '服务协议')"
>
《服务协议》
<
/tex
t
>
与
<
text
class
=
"link"
@
click
.
stop
=
"Link.to(Link.privacy, '隐私政策')"
>
《隐私政策》
<
/tex
t
>
<
/view
>
<
/fui-label
>
<
/fui-checkbox-group
>
...
...
@@ -381,13 +323,16 @@
<
/view
>
<!--
装饰底部:泥土与天空的呼应
-->
<
view
class
=
"footer-aesthetic"
><
/view
>
<
view
class
=
"footer-aesthetic"
/
>
<!--
功能弹窗
-->
<
fui
-
modal
:
show
=
"readConfirmShow"
title
=
"服务协议及隐私保护"
:
buttons
=
"[{ text: '不同意', plain: true
}
, { text: '同意', plain: false, color: '#fff'
}
]"
:
buttons
=
"[
{ text: '不同意', plain: true
}
,
{ text: '同意', plain: false, color: '#fff'
}
,
]"
@
click
=
"onReadConfirm"
>
<
view
class
=
"modal-notice"
>
...
...
@@ -403,6 +348,19 @@
<
/template
>
<
style
lang
=
"less"
scoped
>
@
keyframes
float
-
slow
{
0
%
,
100
%
{
transform
:
translateY
(
0
)
rotate
(
15
deg
);
}
50
%
{
transform
:
translateY
(
-
20
rpx
)
rotate
(
10
deg
);
}
}
.
login
-
page
{
min
-
height
:
100
vh
;
background
-
color
:
#
f7faf8
;
...
...
@@ -433,14 +391,14 @@
height
:
100
%
;
top
:
0
;
left
:
0
;
background
:
linear
-
gradient
(
180
deg
,
rgb
a
(
93
,
182
,
111
,
0.4
)
0
%
,
rgba
(
76
,
175
,
80
,
0.8
)
100
%
);
background
:
linear
-
gradient
(
180
deg
,
rgb
(
93
182
111
/
40
%
)
0
%
,
rgb
(
76
175
80
/
80
%
)
100
%
);
}
/* 漂浮装饰:增强数智感 */
.
float
-
icon
{
position
:
absolute
;
opacity
:
0.6
;
filter
:
drop
-
shadow
(
0
4
rpx
10
rpx
rgb
a
(
0
,
0
,
0
,
0.2
));
filter
:
drop
-
shadow
(
0
4
rpx
10
rpx
rgb
(
0
0
0
/
20
%
));
&
.
device
-
1
{
width
:
120
rpx
;
...
...
@@ -450,6 +408,7 @@
transform
:
rotate
(
15
deg
);
animation
:
float
-
slow
4
s
ease
-
in
-
out
infinite
;
}
&
.
device
-
2
{
width
:
100
rpx
;
height
:
100
rpx
;
...
...
@@ -464,20 +423,9 @@
position
:
relative
;
z
-
index
:
10
;
display
:
flex
;
justify
-
content
:
space
-
between
;
justify
-
content
:
flex
-
start
;
align
-
items
:
center
;
padding
:
20
rpx
40
rpx
;
.
switch
-
action
{
color
:
#
fff
;
font
-
size
:
28
rpx
;
display
:
flex
;
align
-
items
:
center
;
background
:
rgba
(
255
,
255
,
255
,
0.2
);
padding
:
10
rpx
24
rpx
;
border
-
radius
:
40
rpx
;
backdrop
-
filter
:
blur
(
4
px
);
}
}
.
brand
-
hero
{
...
...
@@ -496,7 +444,7 @@
display
:
flex
;
align
-
items
:
center
;
justify
-
content
:
center
;
box
-
shadow
:
0
16
rpx
32
rpx
rgb
a
(
0
,
0
,
0
,
0.15
);
box
-
shadow
:
0
16
rpx
32
rpx
rgb
(
0
0
0
/
15
%
);
.
logo
-
img
{
width
:
100
rpx
;
...
...
@@ -513,7 +461,7 @@
font
-
size
:
48
rpx
;
font
-
weight
:
800
;
letter
-
spacing
:
4
rpx
;
text
-
shadow
:
0
4
rpx
8
rpx
rgb
a
(
0
,
0
,
0
,
0.2
);
text
-
shadow
:
0
4
rpx
8
rpx
rgb
(
0
0
0
/
20
%
);
}
.
app
-
slogan
{
...
...
@@ -543,33 +491,34 @@
}
.
aesthetic
-
card
{
background
:
#
fff
fff
;
background
:
#
fff
;
border
-
radius
:
56
rpx
;
padding
:
80
rpx
50
rpx
6
0
rpx
;
box
-
shadow
:
0
20
rpx
60
rpx
rgb
a
(
0
,
0
,
0
,
0.08
);
padding
:
50
rpx
50
rpx
4
0
rpx
;
box
-
shadow
:
0
20
rpx
60
rpx
rgb
(
0
0
0
/
8
%
);
.
card
-
header
{
margin
-
bottom
:
60
rpx
;
margin
-
bottom
:
36
rpx
;
.
welcome
-
text
{
font
-
size
:
40
rpx
;
font
-
size
:
36
rpx
;
font
-
weight
:
bold
;
color
:
#
333
;
}
.
green
-
line
{
width
:
60
rpx
;
height
:
8
rpx
;
background
:
#
5
DB66F
;
background
:
#
5
db66f
;
border
-
radius
:
4
rpx
;
margin
-
top
:
1
6
rpx
;
margin
-
top
:
1
2
rpx
;
}
}
.
field
-
item
{
margin
-
bottom
:
44
rpx
;
margin
-
bottom
:
30
rpx
;
.
field
-
label
{
font
-
size
:
2
6
rpx
;
font
-
size
:
2
4
rpx
;
color
:
#
999
;
margin
-
left
:
4
rpx
;
}
...
...
@@ -581,9 +530,9 @@
.
sms
-
trigger
{
white
-
space
:
nowrap
;
font
-
size
:
2
8
rpx
;
color
:
#
5
DB66F
;
padding
:
1
6
rpx
32
rpx
;
font
-
size
:
2
6
rpx
;
color
:
#
5
db66f
;
padding
:
1
2
rpx
24
rpx
;
background
:
#
f1f9f2
;
border
-
radius
:
50
rpx
;
margin
-
left
:
20
rpx
;
...
...
@@ -599,10 +548,10 @@
}
.
action
-
footer
{
margin
-
top
:
8
0
rpx
;
margin
-
top
:
5
0
rpx
;
.
secondary
-
links
{
margin
-
top
:
40
rpx
;
margin
-
top
:
28
rpx
;
text
-
align
:
center
;
.
auto
-
hint
{
...
...
@@ -624,7 +573,7 @@
}
.
policy
-
wrapper
{
margin
-
top
:
8
0
rpx
;
margin
-
top
:
5
0
rpx
;
.
policy
-
label
{
display
:
flex
;
...
...
@@ -639,7 +588,7 @@
}
.
link
{
color
:
#
5
DB66F
;
color
:
#
5
db66f
;
font
-
weight
:
500
;
}
}
...
...
@@ -650,7 +599,7 @@
line
-
height
:
1.8
;
.
link
-
inline
{
color
:
#
5
DB66F
;
color
:
#
5
db66f
;
font
-
weight
:
bold
;
}
}
...
...
@@ -659,9 +608,4 @@
flex
:
1
;
background
:
linear
-
gradient
(
180
deg
,
#
f7faf8
0
%
,
#
edf3ef
100
%
);
}
@
keyframes
float
-
slow
{
0
%
,
100
%
{
transform
:
translateY
(
0
)
rotate
(
15
deg
);
}
50
%
{
transform
:
translateY
(
-
20
rpx
)
rotate
(
10
deg
);
}
}
<
/style
>
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论