Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
水玉婷
ai-wechat
Commits
87d7af4c
Commit
87d7af4c
authored
Mar 17, 2026
by
水玉婷
Browse files
feat:历史记录样式调整
parent
0bdf9834
Changes
7
Hide whitespace changes
Inline
Side-by-side
index.html
View file @
87d7af4c
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
<head>
<head>
<meta
charset=
"UTF-8"
>
<meta
charset=
"UTF-8"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
>
<title>
国械小智
</title>
<title></title>
<meta
name=
"format-detection"
content=
"telephone=no"
>
<meta
name=
"format-detection"
content=
"telephone=no"
>
<meta
name=
"apple-mobile-web-app-capable"
content=
"yes"
>
<meta
name=
"apple-mobile-web-app-capable"
content=
"yes"
>
<meta
name=
"apple-mobile-web-app-status-bar-style"
content=
"black"
>
<meta
name=
"apple-mobile-web-app-status-bar-style"
content=
"black"
>
...
...
src/assets/chat-ai-line.svg
0 → 100644
View file @
87d7af4c
<svg
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
fill=
"none"
version=
"1.1"
width=
"18"
height=
"18"
viewBox=
"0 0 18 18"
><defs><clipPath
id=
"master_svg0_153_05444"
><rect
x=
"0"
y=
"0"
width=
"18"
height=
"18"
rx=
"0"
/></clipPath></defs><g
clip-path=
"url(#master_svg0_153_05444)"
><path
d=
"M15.53505,6.0960836L15.350101,6.5203438C15.2148,6.8309407,14.7852,6.8309407,14.649826,6.5203438L14.464951,6.0960836C14.135324,5.3396029,13.541625,4.7373083000000005,12.800776,4.407810700000001L12.231001,4.154415800000001C11.922976,4.017398399999999,11.922976,3.5691082,12.231001,3.4320905L12.7689,3.1928556C13.528801,2.8548832,14.133151,2.2302982,14.457076,1.4481231L14.646976,0.9896480400000001C14.779349,0.670117289,15.220652,0.670117289,15.352951,0.9896480400000001L15.542851,1.4481231C15.86685,2.2302982,16.4712,2.8548832,17.231099999999998,3.1928556L17.768927,3.4320905C18.077024,3.5691082,18.077024,4.017398399999999,17.768927,4.154415800000001L17.199225,4.407810700000001C16.458375,4.7373083000000005,15.864676,5.3396029,15.53505,6.0960836ZM7.5,2.2500006L10.5,2.2500006L10.5,3.750001L7.5,3.750001C5.0147173,3.750001,3,5.7647181,3,8.250001000000001C3,10.9575,4.84656,12.724201,9.000000499999999,14.60985L9.000000499999999,12.75L10.5,12.75C12.985275,12.75,15,10.7352762,15,8.250001000000001L16.500000999999997,8.250001000000001C16.500000999999997,11.563725,13.813725,14.25,10.5,14.25L10.5,16.875C6.7500005,15.375,1.5,13.125,1.5,8.250001000000001C1.5,4.9362903,4.18629,2.2500006,7.5,2.2500006Z"
fill=
"#323232"
fill-opacity=
"1"
/></g></svg>
\ No newline at end of file
src/assets/logo2.png
0 → 100644
View file @
87d7af4c
274 KB
src/assets/sidebar-unfold-line.svg
0 → 100644
View file @
87d7af4c
<svg
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
fill=
"none"
version=
"1.1"
width=
"18"
height=
"18"
viewBox=
"0 0 18 18"
><defs><clipPath
id=
"master_svg0_153_04803"
><rect
x=
"18"
y=
"0"
width=
"18"
height=
"18"
rx=
"0"
/></clipPath></defs><g
transform=
"matrix(-1,0,0,1,36,0)"
clip-path=
"url(#master_svg0_153_04803)"
><path
d=
"M21.75,3.75L27.7500005,3.75L27.7500005,14.25L21.75,14.25L21.75,3.75ZM32.25,14.25L29.25,14.25L29.25,3.75L32.25,3.75L32.25,14.25ZM21,2.25C20.58579004,2.25,20.25,2.58579004,20.25,3L20.25,15.000001C20.25,15.414225,20.58579004,15.75,21,15.75L33.000001,15.75C33.414225,15.75,33.75,15.414225,33.75,15.000001L33.75,3C33.75,2.58579004,33.414225,2.25,33.000001,2.25L21,2.25Z"
fill=
"#323232"
fill-opacity=
"1"
/></g></svg>
\ No newline at end of file
src/views/History.vue
View file @
87d7af4c
<
template
>
<
template
>
<div
class=
"history-container"
>
<div
class=
"history-container"
>
<!-- 头部栏 -->
<!-- 头部栏 -->
<div
class=
"history-header"
>
<div
class=
"history-header"
:class=
"
{ 'header-open': isHistoryPanelOpen }"
>
<div
class=
"header-left"
>
<div
class=
"header-left"
>
<button
class=
"menu-button"
@
click=
"toggleHistoryPanel"
>
<img
:src=
"defaultAvatar"
alt=
"avatar"
class=
"avatar-image"
/>
<menu-outlined
/>
<h2
class=
"header-title"
>
{{
appName
||
'
国械小智
'
}}
</h2>
</button>
<div
class=
"menu-button"
@
click=
"toggleHistoryPanel"
>
<h2
class=
"header-title"
>
{{
appName
||
'
国械小智
'
}}
</h2>
<img
:src=
"menuIcon"
alt=
"menu-icon"
class=
"menu-icon"
/>
展开
</div>
</div>
</div>
<div
class=
"header-right"
>
<div
class=
"header-right"
>
<button
class=
"new-chat-button"
@
click=
"createNewChat"
>
<div
class=
"new-chat-button"
@
click=
"createNewChat"
>
<plus-outlined
/>
<img
:src=
"newChatIcon"
alt=
"new-chat-icon"
class=
"new-chat-icon"
/>
</button>
新建会话
</div>
</div>
</div>
</div>
</div>
<!-- 历史记录侧边栏 -->
<!-- 历史记录侧边栏 -->
<div
class=
"history-sidebar"
:class=
"
{ 'sidebar-open': isHistoryPanelOpen }">
<div
class=
"history-sidebar"
:class=
"
{ 'sidebar-open': isHistoryPanelOpen }">
<div
class=
"sidebar-header"
>
<div
class=
"sidebar-header"
>
<h3>
历史记录
</h3>
<h3>
<img
:src=
"defaultAvatar"
alt=
"avatar"
class=
"avatar-image"
/>
{{
appName
||
'
国械小智
'
}}
</h3>
<
button
class=
"close-button"
@
click=
"toggleHistoryPanel"
>
<
div
class=
"close-button"
@
click=
"toggleHistoryPanel"
>
<close-outlined
/>
<img
:src=
"menuIcon"
alt=
"menu-icon"
class=
"menu-icon"
/>
</
button
>
</
div
>
</div>
</div>
<div
class=
"search-box"
>
<div
class=
"search-box"
>
...
@@ -30,7 +33,7 @@
...
@@ -30,7 +33,7 @@
<input
<input
v-model=
"searchKeyword"
v-model=
"searchKeyword"
type=
"text"
type=
"text"
placeholder=
"搜索历史记录
...
"
placeholder=
"搜索历史记录"
@
input=
"filterHistory"
@
input=
"filterHistory"
/>
/>
</div>
</div>
...
@@ -72,14 +75,13 @@
...
@@ -72,14 +75,13 @@
<div
class=
"session-info"
>
<div
class=
"session-info"
>
<div
class=
"session-title"
>
{{
session
.
title
}}
</div>
<div
class=
"session-title"
>
{{
session
.
title
}}
</div>
</div>
</div>
<
button
class=
"delete-button"
@
click.stop=
"deleteSession(session)"
>
<
div
class=
"delete-button"
@
click.stop=
"deleteSession(session)"
>
<delete-outlined
/>
<delete-outlined
/>
</
button
>
</
div
>
</div>
</div>
<!-- 上拉加载更多提示 -->
<!-- 上拉加载更多提示 -->
<div
v-if=
"hasMore && !isLoading && recentSessions.length > 0"
class=
"pull-up-hint"
>
<div
v-if=
"hasMore && !isLoading && recentSessions.length > 0"
class=
"pull-up-hint"
>
<div
class=
"pull-up-icon"
>
↑
</div>
<span>
上拉加载更多历史记录
</span>
<span>
上拉加载更多历史记录
</span>
</div>
</div>
...
@@ -134,10 +136,11 @@ import { ref, computed, onMounted } from 'vue';
...
@@ -134,10 +136,11 @@ import { ref, computed, onMounted } from 'vue';
import
AiChat
from
'
./components/AiChat.vue
'
;
import
AiChat
from
'
./components/AiChat.vue
'
;
import
axios
from
'
../utils/axios
'
;
import
axios
from
'
../utils/axios
'
;
import
{
message
}
from
'
ant-design-vue
'
;
import
{
message
}
from
'
ant-design-vue
'
;
import
defaultAvatar
from
'
@/assets/logo2.png
'
;
import
menuIcon
from
'
@/assets/sidebar-unfold-line.svg
'
import
newChatIcon
from
'
@/assets/chat-ai-line.svg
'
import
{
import
{
MenuOutlined
,
PlusOutlined
,
PlusOutlined
,
CloseOutlined
,
SearchOutlined
,
SearchOutlined
,
DeleteOutlined
,
DeleteOutlined
,
FileSearchOutlined
FileSearchOutlined
...
@@ -264,8 +267,9 @@ const handleStart = (clientY: number, target: HTMLElement, event: Event) => {
...
@@ -264,8 +267,9 @@ const handleStart = (clientY: number, target: HTMLElement, event: Event) => {
return
;
return
;
}
}
// 只有在顶部且没有在滚动时才允许下拉刷新
// 只有在顶部、没有在滚动、且列表可以滚动时才允许下拉刷新
if
(
target
.
scrollTop
===
0
&&
!
isRefreshing
.
value
)
{
const
canScroll
=
target
.
scrollHeight
>
target
.
clientHeight
;
if
(
target
.
scrollTop
===
0
&&
!
isRefreshing
.
value
&&
canScroll
)
{
pullDownStartY
.
value
=
clientY
;
pullDownStartY
.
value
=
clientY
;
isPullingDown
.
value
=
true
;
isPullingDown
.
value
=
true
;
}
}
...
@@ -437,6 +441,9 @@ onMounted(() => {
...
@@ -437,6 +441,9 @@ onMounted(() => {
@import './components/style.less';
@import './components/style.less';
.chat-history {
.chat-history {
height: calc(100vh - 52px);
height: calc(100vh - 52px);
:deep(.chat-header) {
display:none;
}
}
}
// 历史记录容器
// 历史记录容器
...
@@ -455,27 +462,27 @@ onMounted(() => {
...
@@ -455,27 +462,27 @@ onMounted(() => {
align-items: center;
align-items: center;
padding: 12px 20px;
padding: 12px 20px;
background: #ffffff;
background: #ffffff;
border-bottom: 1px solid #e8e8e8;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
z-index: 100;
z-index: 100;
&.header-open {
border-bottom: 1px solid #F2F3F5;
}
.header-left {
.header-left {
display: flex;
display: flex;
align-items: center;
align-items: center;
gap: 12px;
gap: 12px;
.avatar-image {
width: 25px;
height: 18px;
object-fit: cover;
}
.menu-button {
.menu-button {
background: none;
border: none;
padding: 8px;
border-radius: 6px;
cursor: pointer;
cursor: pointer;
color:
#666
;
color:
@gray-7
;
transition: all 0.2s ease;
transition: all 0.2s ease;
margin-left:16px;
&:hover {
img{
background: #f0f0f0;
vertical-align: text-top;
color: #1890ff;
}
}
}
}
...
@@ -492,19 +499,12 @@ onMounted(() => {
...
@@ -492,19 +499,12 @@ onMounted(() => {
display: flex;
display: flex;
align-items: center;
align-items: center;
justify-content: center;
justify-content: center;
width: 32px;
color: @gray-7;
height: 32px;
background: #f0f0f0;
color: #666;
border: none;
border: none;
border-radius: 50%;
cursor: pointer;
cursor: pointer;
transition: all 0.2s ease;
transition: all 0.2s ease;
img{
&:hover {
margin-right: 4px;
background: #e0e0e0;
color: #1890ff;
transform: scale(1.05);
}
}
}
}
}
}
...
@@ -517,7 +517,7 @@ onMounted(() => {
...
@@ -517,7 +517,7 @@ onMounted(() => {
left: -300px;
left: -300px;
width: 300px;
width: 300px;
height: 100vh;
height: 100vh;
background: #
ffffff;
background: #
F2F5F5;
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);
transition: left 0.3s ease;
transition: left 0.3s ease;
z-index: 1000;
z-index: 1000;
...
@@ -532,9 +532,14 @@ onMounted(() => {
...
@@ -532,9 +532,14 @@ onMounted(() => {
display: flex;
display: flex;
justify-content: space-between;
justify-content: space-between;
align-items: center;
align-items: center;
padding: 16px 20px;
padding: 12px 20px;
border-bottom: 1px solid #e8e8e8;
.avatar-image {
width: 25px;
height: 18px;
object-fit: cover;
margin-right: 6px;
}
h3 {
h3 {
font-size: 16px;
font-size: 16px;
font-weight: 600;
font-weight: 600;
...
@@ -558,8 +563,7 @@ onMounted(() => {
...
@@ -558,8 +563,7 @@ onMounted(() => {
}
}
.search-box {
.search-box {
padding: 16px 20px;
padding: 4px 20px 16px;
border-bottom: 1px solid #e8e8e8;
.search-input {
.search-input {
position: relative;
position: relative;
...
@@ -578,6 +582,7 @@ onMounted(() => {
...
@@ -578,6 +582,7 @@ onMounted(() => {
border: 1px solid #d9d9d9;
border: 1px solid #d9d9d9;
border-radius: 6px;
border-radius: 6px;
font-size: 16px;
font-size: 16px;
background: #E8EBEB;
&:focus {
&:focus {
outline: none;
outline: none;
...
@@ -597,9 +602,7 @@ onMounted(() => {
...
@@ -597,9 +602,7 @@ onMounted(() => {
justify-content: space-between;
justify-content: space-between;
align-items: center;
align-items: center;
padding: 12px 20px;
padding: 12px 20px;
border-bottom: 1px solid #f0f0f0;
font-size: 14px;
background: #fafafa;
font-size: 12px;
.total-count {
.total-count {
color: #666;
color: #666;
...
@@ -607,7 +610,7 @@ onMounted(() => {
...
@@ -607,7 +610,7 @@ onMounted(() => {
}
}
.display-count {
.display-count {
color: #
999
;
color: #
1890FF
;
}
}
}
}
...
@@ -625,7 +628,6 @@ onMounted(() => {
...
@@ -625,7 +628,6 @@ onMounted(() => {
padding: 16px;
padding: 16px;
color: #666;
color: #666;
font-size: 14px;
font-size: 14px;
background: #ffffff;
transition: transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
transition: transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
z-index: 1;
z-index: 1;
...
@@ -701,17 +703,17 @@ onMounted(() => {
...
@@ -701,17 +703,17 @@ onMounted(() => {
.history-item {
.history-item {
display: flex;
display: flex;
align-items: center;
align-items: center;
padding:
12
px 20px;
padding:
8
px 20px;
cursor: pointer;
cursor: pointer;
transition: background-color 0.2s ease;
transition: background-color 0.2s ease;
&:hover {
&:hover {
background: #
f5f5f5
;
background: #
D5D8D8
;
}
}
&.active {
&.active {
background: #
e6f7ff
;
background: #
D1E9FF
;
border-right: 3px solid
#1890
ff
;
color:
#1890
FF
;
}
}
.session-info {
.session-info {
...
@@ -722,7 +724,6 @@ onMounted(() => {
...
@@ -722,7 +724,6 @@ onMounted(() => {
font-size: 16px;
font-size: 16px;
font-weight: 500;
font-weight: 500;
color: #333;
color: #333;
margin-bottom: 4px;
white-space: nowrap;
white-space: nowrap;
overflow: hidden;
overflow: hidden;
text-overflow: ellipsis;
text-overflow: ellipsis;
...
@@ -749,13 +750,12 @@ onMounted(() => {
...
@@ -749,13 +750,12 @@ onMounted(() => {
padding: 4px;
padding: 4px;
border-radius: 4px;
border-radius: 4px;
cursor: pointer;
cursor: pointer;
color: #
ccc
;
color: #
323232
;
opacity: 0;
opacity: 0;
transition: all 0.2s ease;
transition: all 0.2s ease;
&:hover {
&:hover {
color: #ff4d4f;
color: #ff4d4f;
background: #fff2f0;
}
}
}
}
...
...
src/views/Login.vue
View file @
87d7af4c
...
@@ -47,12 +47,12 @@ export default {
...
@@ -47,12 +47,12 @@ export default {
}
}
onMounted
(()
=>
{
onMounted
(()
=>
{
//
//
检查是否已登录
// 检查是否已登录
//
const status = wechat.checkLoginStatus()
const
status
=
wechat
.
checkLoginStatus
()
//
if (status.isLoggedIn) {
if
(
status
.
isLoggedIn
)
{
//
router.replace('/')
router
.
replace
(
'
/
'
)
//
return
return
//
}
}
// 执行静默登录
// 执行静默登录
handleLogin
()
handleLogin
()
...
...
src/views/components/AiChat.vue
View file @
87d7af4c
...
@@ -451,9 +451,11 @@ const sendMessage = async (type: MessageType = 'text', params: MessageParams = {
...
@@ -451,9 +451,11 @@ const sendMessage = async (type: MessageType = 'text', params: MessageParams = {
questionLocalAudioFilePath
:
audioUrl
,
questionLocalAudioFilePath
:
audioUrl
,
audioDuration
:
durationTime
,
audioDuration
:
durationTime
,
...
props
.
params
,
...
props
.
params
,
dialogSessionId
:
dialogSessionId
.
value
,
}
:
{
}
:
{
question
:
messageContent
,
question
:
messageContent
,
...
props
.
params
,
...
props
.
params
,
dialogSessionId
:
dialogSessionId
.
value
,
};
};
const
response
=
await
fetch
(
`
${
import
.
meta
.
env
.
VITE_SSE_PATH
}
/ask/app/
${
props
.
params
?.
appId
}
`
,
{
const
response
=
await
fetch
(
`
${
import
.
meta
.
env
.
VITE_SSE_PATH
}
/ask/app/
${
props
.
params
?.
appId
}
`
,
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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