<template>
|
<div class="page-container">
|
<div class="outer-container">
|
<div class="left-container">
|
<div class="logo-container"><img src="@/assets/page/languageModel/logo.png"></div>
|
<div class="manage-history-container">
|
<div @click="createNewConversation"
|
:class="[isAtNewConversation?'create-history-container-active':'',isDeletingBatch?'fold-create-history-container':'expand-create-history-container']"
|
class="create-new-conversation">
|
<a-icon type="plus"></a-icon>
|
<span v-if="!isDeletingBatch">新增会话</span>
|
</div>
|
<div @click="expandDeleteBatchContainer"
|
:class="[isDeletingBatch?'expand-delete-batch-container':'fold-delete-batch-container',chatHistoryList.length===0?'disable-expand':'']"
|
class="delete-batch-container">
|
<a-icon type="delete" v-if="!isDeletingBatch"/>
|
<template v-else>
|
<div class="expand-delete-batch-inner">
|
<div class="select-all-button">
|
<label class="checkbox-custom">
|
<input type="checkbox" @change="allHistoryCheckedChange"
|
id="select-all-checkbox"></input>
|
<span class="check-mark"></span>
|
<div>全选</div>
|
</label>
|
</div>
|
<div class="split-line"></div>
|
<a-popover placement="top" :visible="deleteBatchPopVisible" trigger="click"
|
:getPopupContainer="node=>node.parentNode" overlayClassName="delete-batch-popover">
|
<template slot="content">
|
<div class="popover-content">
|
<div>删除后无法恢复,是否继续删除?</div>
|
<div>
|
<button class="cancel-delete-button" @click="deleteBatchPopVisible=false">取消</button>
|
<button id="confirm-delete-batch-button" @click="confirmDeleteBatchConversation">删除
|
</button>
|
</div>
|
</div>
|
</template>
|
<div @click="deleteBatchConversation" id="delete-batch-button"
|
:class="[checkedConversationIdList.length?'able-delete-button':'disable-delete-button']">
|
<a-icon type="delete"/>
|
<div>删除</div>
|
</div>
|
</a-popover>
|
<div class="split-line"></div>
|
<div @click.stop="cancelDeleteBatchConversation">
|
<a-icon type="close"/>
|
<div>退出</div>
|
</div>
|
</div>
|
</template>
|
</div>
|
</div>
|
<div class="chat-history-container">
|
<div v-for="(item,index) in chatHistoryList" :key="item.id"
|
:class="[item.id===activeHistoryIndex?'single-history-active':'',item.inputVisible?'input-visible-class':'']"
|
@click="switchToCurrentConversation(item,$event)"
|
@mouseenter="item.iconVisible=true"
|
@mouseleave="item.iconVisible=false">
|
<!--input放置在popover中无法使用功能-->
|
<label v-if="isDeletingBatch" class="checkbox-custom">
|
<input type="checkbox" v-model="checkedConversationIdList" :value="item.id"
|
@change="singleHistoryCheckedChange"/>
|
<span class="check-mark"></span>
|
</label>
|
|
|
<a-popover placement="top" :visible="item.deletePopVisible" trigger="click"
|
:getPopupContainer="node=>node.parentNode">
|
<template slot="content">
|
<div class="popover-content">
|
<div>删除后无法恢复,是否继续删除?</div>
|
<div>
|
<button class="cancel-delete-button" @click="cancelDeleteConversation(item,$event)">取消</button>
|
<button @click="confirmDeleteConversation(item,index)" id="delete-conversation-button">删除</button>
|
</div>
|
</div>
|
</template>
|
<template v-if="!item.inputVisible">
|
<div class="conversation-title">{{item.title}}</div>
|
<div class="icon-container hover-icon-container" v-show="!isDeletingBatch">
|
<a-icon type="edit" @click.stop="editConversationTitle(item)"/>
|
<a-icon type="delete" @click.stop="deleteConversation(item)"
|
@blur="cancelDeleteConversation(item,$event)"/>
|
</div>
|
</template>
|
|
<template v-else>
|
<input id="edit-input" v-model="editedConversationTitle"
|
@keydown.enter="confirmEditConversationTitle(item,$event)"
|
@blur="cancelEditConversationTitle(item,$event)"
|
maxlength="15">
|
</input>
|
<div class="icon-container">
|
<a-icon type="check" @click.stop="confirmEditConversationTitle(item,$event)"/>
|
<a-icon type="close"/>
|
</div>
|
</template>
|
</a-popover>
|
</div>
|
</div>
|
</div>
|
|
<div class="right-container">
|
<div class="conversation-container">
|
<div v-for="item in currentConversation.messages" class="single-conversation" :id="'id'+item.index">
|
<div v-if="item.role==='user'" class="user-question">
|
<div class="avatar">
|
<a-avatar :src="getAvatar()"/>
|
</div>
|
<div class="content">{{item.content}}</div>
|
</div>
|
<div v-else class="assistant-answer">
|
<div class="avatar">
|
<img src="@/assets/page/languageModel/ai-avatar.png"/>
|
</div>
|
<div class="content">{{item.content}}</div>
|
</div>
|
</div>
|
</div>
|
<div class="input-container" :class="[textareaFocused?'input-container-active':'']">
|
<textarea v-model="inputQuestion" :placeholder="textareaPlaceholder"
|
@keydown.enter="sendQuestion($event)" @focus="textareaFocused=true"
|
@blur="textareaFocused=false"></textarea>
|
<img src="@/assets/page/languageModel/send-message.png" @click="sendQuestion($event)" v-if="!isResponding">
|
<a-icon type="loading" class="loading-icon" v-else/>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import { getFileAccessHttpUrl } from '@/api/manage'
|
import { mapGetters } from 'vuex'
|
import { message } from 'ant-design-vue'
|
import { randomUUID } from '@/utils/util'
|
|
message.config({
|
maxCount: 1,
|
duration: 2
|
})
|
|
export default {
|
name: 'LanguageModel',
|
components: {},
|
data() {
|
return {
|
chatHistoryList: [],
|
checkedConversationIdList: [],
|
deleteBatchPopVisible: false,
|
currentConversation: {
|
id: '683a65fd-8feb-4446-ad32-714c4785f667',
|
messages: [
|
{
|
'role': 'user',
|
'content': '你是谁?你是谁你是谁你是谁你是谁你是谁你是谁你是谁你是谁你是谁你是谁你是谁你是谁你是谁你是谁你是谁你是谁你是谁'
|
},
|
{
|
'role': 'assistant',
|
'content': '我是26中生涯指导师小爱'
|
},
|
{
|
'role': 'user',
|
'content': '你都能做些什么?'
|
},
|
{
|
'role': 'assistant',
|
'content': '我能站在未来视角帮助同学们做好生涯规划指导。'
|
},
|
{
|
'role': 'user',
|
'content': '今天天气如何?'
|
},
|
{
|
'role': 'assistant',
|
'content': '我是26中生涯指导师小爱'
|
},
|
{
|
'role': 'user',
|
'content': '你都能做些什么?'
|
},
|
{
|
'role': 'assistant',
|
'content': '我能站在未来视角帮助同学们做好生涯规划指导。'
|
}
|
],
|
stream: false,
|
max_tokens: 500,
|
iconVisible: false,
|
inputVisible: false,
|
deletePopVisible: false
|
},
|
// currentConversation: {},
|
isAtNewConversation: false,
|
isDeletingBatch: false,
|
activeHistoryIndex: null,
|
editingHistoryIndex: null,
|
deletingHistoryIndex: null,
|
iconVisible: false,
|
inputVisible: false,
|
editedConversationTitle: '',
|
deletePopVisible: false,
|
conversationContainer: null,
|
inputQuestion: '',
|
textareaPlaceholder: 'Enter发送,Shift+Enter换行',
|
textareaFocused: false,
|
isResponding: false
|
}
|
},
|
|
watch: {
|
deleteBatchPopVisible: {
|
handler(val) {
|
if (val) {
|
document.addEventListener('click', this.handleDocumentClick)
|
} else {
|
document.removeEventListener('click', this.handleDocumentClick)
|
}
|
}
|
}
|
},
|
mounted() {
|
this.getConversationByApi()
|
this.conversationContainer = document.querySelector('.conversation-container')
|
},
|
methods: {
|
...mapGetters(['avatar']),
|
|
/* 调用接口获取当前会话记录 */
|
getConversationByApi() {
|
this.currentConversation.title = this.currentConversation.messages[0].content.slice(0, 15)
|
this.chatHistoryList.push(this.currentConversation)
|
this.activeHistoryIndex = this.chatHistoryList[0].id
|
if (!this.chatHistoryList.length) this.textareaPlaceholder = '请尝试问我:你是谁?'
|
},
|
|
/* 创建一个新会话 */
|
createNewConversation() {
|
if (this.isAtNewConversation) this.$message.info('当前已是最新对话')
|
this.isAtNewConversation = true
|
this.currentConversation = {
|
id: randomUUID(),
|
title: '',
|
messages: [],
|
stream: true,
|
max_tokens: 500,
|
iconVisible: false,
|
inputVisible: false,
|
deletePopVisible: false
|
}
|
// 新建会话时取消原先被选中的历史对话,更清晰告诉用户现在界面处于新建对话中
|
if (this.activeHistoryIndex !== null) this.activeHistoryIndex = null
|
this.textareaPlaceholder = '请尝试问我:你是谁?'
|
},
|
|
/* 点击全选按钮后改变勾选后触发 */
|
allHistoryCheckedChange(event) {
|
// event.target.indeterminate = true
|
if (event.target.checked) {
|
this.checkedConversationIdList = this.chatHistoryList.map(item => item.id)
|
} else {
|
this.checkedConversationIdList = []
|
}
|
console.log('触发全选', event.target.checked)
|
},
|
|
/* 点击历史记录中多选框改变勾选后触发 */
|
singleHistoryCheckedChange() {
|
// 仅在批量删除展开时获取到
|
const selectAllCheckbox = document.getElementById('select-all-checkbox')
|
|
if (this.checkedConversationIdList.length > 0) {
|
if (this.checkedConversationIdList.length !== this.chatHistoryList.length) {
|
console.log('触发未全选中', selectAllCheckbox.indeterminate)
|
this.$nextTick(() => selectAllCheckbox.indeterminate = true)
|
} else {
|
console.log('触发全被选中', selectAllCheckbox)
|
// document.getElementById('select-all-checkbox').indeterminate = false
|
this.$nextTick(() => {
|
selectAllCheckbox.indeterminate = false
|
selectAllCheckbox.checked = true
|
})
|
}
|
} else {
|
selectAllCheckbox.indeterminate = false
|
selectAllCheckbox.checked = false
|
}
|
},
|
|
/* 点击批量删除会话图标时展开批量管理区域 */
|
expandDeleteBatchContainer() {
|
if (this.chatHistoryList.length === 0) return
|
this.isDeletingBatch = true
|
},
|
|
/* 点击红色图标批量删除按钮后触发 */
|
deleteBatchConversation() {
|
if (!this.checkedConversationIdList.length) return
|
this.deleteBatchPopVisible = !this.deleteBatchPopVisible
|
},
|
|
/* 点击文档空白关闭批量删除popover */
|
handleDocumentClick(e) {
|
const popover = document.querySelector('.delete-batch-popover')
|
const button = document.getElementById('delete-batch-button')
|
if (popover && !popover.contains(e.target) && !button.contains(e.target)) this.deleteBatchPopVisible = false
|
},
|
|
/* 确认批量删除对话 */
|
confirmDeleteBatchConversation() {
|
if (this.checkedConversationIdList.includes(this.activeHistoryIndex)) this.createNewConversation()
|
this.chatHistoryList = this.chatHistoryList.filter(item => !this.checkedConversationIdList.includes(item.id))
|
this.$message.success('删除成功')
|
const timer = setTimeout(() => {
|
this.cancelDeleteBatchConversation()
|
clearTimeout(timer)
|
})
|
},
|
|
/* 取消批量删除会话功能 */
|
cancelDeleteBatchConversation() {
|
this.deleteBatchPopVisible = false
|
this.isDeletingBatch = false
|
this.checkedConversationIdList = []
|
},
|
|
/* 切换至当前点击会话 */
|
switchToCurrentConversation(record, event = {}) {
|
if (event.target && event.target.type === 'checkbox') return //点击多选按钮避免传递给此事件
|
if (record.inputVisible) return // 当条会话正在被修改时再次点击本条会话无反馈
|
// 关闭点击编辑按钮后的输入框
|
if (this.editingHistoryIndex !== null && this.editingHistoryIndex !== record.id) this.cancelEditConversationTitle(this.chatHistoryList.find(item => item.id === this.editingHistoryIndex))
|
// 关闭所有确认删除弹窗
|
if (this.deletingHistoryIndex !== null) this.cancelDeleteConversation(this.chatHistoryList.find(item => item.id === this.deletingHistoryIndex))
|
|
this.activeHistoryIndex = record.id
|
this.currentConversation = this.chatHistoryList.find(item => item.id === record.id)
|
this.isAtNewConversation = false
|
|
// 切换对话时更改提问输入框提示文字
|
if (record.messages.length > 0) this.textareaPlaceholder = 'Enter发送,Shift+Enter换行'
|
},
|
|
/* 点击编辑会话标题按钮时触发 */
|
editConversationTitle(record) {
|
// 仅开启最后一次点击编辑按钮后的输入框
|
if (this.editingHistoryIndex !== null && this.editingHistoryIndex !== record.id) this.cancelEditConversationTitle(this.chatHistoryList.find(item => item.id === this.editingHistoryIndex))
|
// 进入编辑后关闭所有确认删除弹窗
|
if (this.deletingHistoryIndex !== null) this.cancelDeleteConversation(this.chatHistoryList.find(item => item.id === this.deletingHistoryIndex))
|
|
this.editingHistoryIndex = record.id
|
record.inputVisible = true
|
this.editedConversationTitle = record.title
|
this.$nextTick(() => document.getElementById('edit-input').focus())
|
},
|
|
/* 点击单个删除会话按钮时触发 */
|
deleteConversation(record) {
|
// 点击删除按钮时关闭所有正在编辑的输入框
|
if (this.editingHistoryIndex !== null) {
|
this.cancelEditConversationTitle(this.chatHistoryList.find(item => item.id === this.editingHistoryIndex))
|
return
|
}
|
// 仅可使用最后一次点击删除按钮的功能
|
if (this.deletingHistoryIndex !== null && this.deletingHistoryIndex !== record.id) this.cancelDeleteConversation(this.chatHistoryList.find(item => item.id === this.deletingHistoryIndex))
|
|
record.deletePopVisible = !record.deletePopVisible
|
this.deletingHistoryIndex = record.id
|
},
|
|
/* 确认编辑会话标题 */
|
confirmEditConversationTitle(record, event) {
|
record.title = this.editedConversationTitle
|
this.cancelEditConversationTitle(record, event)
|
},
|
|
/* 确认删除会话时触发 */
|
confirmDeleteConversation(record, index) {
|
this.chatHistoryList = this.chatHistoryList.filter(item => item.id !== this.deletingHistoryIndex)
|
|
if (this.chatHistoryList.length > 0) {
|
// 判断当前会话是不是要删除的会话
|
if (this.activeHistoryIndex === record.id) {
|
if (this.chatHistoryList[index]) {
|
console.log('删除非最后一条')
|
this.currentConversation = this.chatHistoryList[index]
|
this.activeHistoryIndex = this.chatHistoryList[index].id
|
} else {
|
console.log('删除最后一条')
|
this.currentConversation = this.chatHistoryList[this.chatHistoryList.length - 1]
|
this.activeHistoryIndex = this.chatHistoryList[this.chatHistoryList.length - 1].id
|
}
|
}
|
} else {
|
console.log('删除前只有一条')
|
this.activeHistoryIndex = null
|
this.createNewConversation()
|
}
|
record.deletePopVisible = false
|
this.deletingHistoryIndex = null
|
this.$message.success('删除成功!')
|
},
|
|
/* 取消编辑会话标题时触发 */
|
cancelEditConversationTitle(record, event) {
|
// 失去焦点事件时若点击的元素是确认编辑按钮则不进行失去焦点事件,直接进入确认编辑事件
|
if (event.relatedTarget && event.relatedTarget.className === 'anticon anticon-check') return
|
record.inputVisible = false
|
this.editingHistoryIndex = null
|
},
|
|
/* 取消删除会话时触发 */
|
cancelDeleteConversation(record, event) {
|
// 失去焦点事件时若点击的元素是确认删除按钮则不进行失去焦点事件,直接进入确认删除事件
|
if (event.relatedTarget && event.relatedTarget.id === 'delete-conversation-button') return
|
record.deletePopVisible = false
|
this.deletingHistoryIndex = null
|
},
|
|
/* 获取用户头像 */
|
getAvatar() {
|
return getFileAccessHttpUrl(this.avatar())
|
},
|
|
/* 向模型提问 */
|
sendQuestion(e) {
|
//监测是否按下shift键
|
if (!e.shiftKey) {
|
e.preventDefault()
|
if (this.isResponding) {
|
this.$message.error('请等待机器人回复后再发送哦~')
|
return
|
}
|
if (!this.inputQuestion) {
|
this.$message.error('你没有输入内容哦')
|
return
|
}
|
|
const newQuestion = {
|
role: 'user',
|
content: this.inputQuestion
|
}
|
this.currentConversation.messages.push(newQuestion)
|
|
// 当新建对话时需先提问再讲对话加入到历史记录中
|
if (this.currentConversation.messages.length === 1) {
|
this.currentConversation.title = newQuestion.content.slice(0, 15)
|
this.chatHistoryList.unshift(this.currentConversation)
|
if (this.isDeletingBatch) this.singleHistoryCheckedChange()
|
this.switchToCurrentConversation(this.currentConversation)
|
}
|
|
this.isResponding = true
|
const response = {
|
role: 'assistant',
|
content: '这个问题我也不太清楚'
|
}
|
setTimeout(() => {
|
this.currentConversation.messages.push(response)
|
this.inputQuestion = ''
|
this.isResponding = false
|
this.$nextTick(() => {
|
this.conversationContainer.scrollTo({ top: 9999999999999999999999999999, behavior: 'smooth' })
|
})
|
}, 1000)
|
}
|
}
|
}
|
}
|
</script>
|
|
<style scoped lang="less">
|
@main-container-background: rgba(255, 255, 255, .8);
|
@container-border-radius: 12px;
|
@container-padding: 10px;
|
@single-history-edit-border: 3px solid #ABC0CC;
|
@single-history-hover-background: #f1f1f1;
|
@single-history-active-background: #e5ebed;
|
@input-container-border: 3px solid #B8CAD5;
|
@user-question-background: #e5ebed;
|
@assistant-answer-background: #F0F5F5;
|
@conversation-content-container-box-shadow: 2px 2px 10px 0px #ddd;
|
@input-container-box-shadow: 2px 2px 10px 0px #ABC0CC;
|
|
.page-container {
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
font-size: 18px;
|
height: 100%;
|
font-family: ali_r_main;
|
|
.outer-container {
|
width: 100%;
|
height: 690px;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
|
.left-container {
|
width: 20%;
|
height: 100%;
|
background-color: @main-container-background;
|
border-radius: @container-border-radius;
|
padding: @container-padding;
|
margin-right: 25px;
|
display: flex;
|
flex-direction: column;
|
justify-content: space-between;
|
|
.logo-container {
|
height: 80px;
|
img {
|
width: 100%;
|
height: 100%;
|
}
|
}
|
|
.manage-history-container {
|
margin: 20px 0 15px;
|
display: flex;
|
|
& > div {
|
border: 1px solid #d9d9d9;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
cursor: pointer;
|
color: #585258;
|
transition: box-shadow .2s ease-in-out;
|
|
&:hover {
|
box-shadow: @conversation-content-container-box-shadow;
|
}
|
}
|
|
.create-new-conversation {
|
margin-right: 10px;
|
|
&.create-history-container-active {
|
border: 1px solid transparent;
|
background-color: @single-history-active-background;
|
|
&:hover {
|
box-shadow: none;
|
}
|
}
|
|
&.fold-create-history-container {
|
flex: none;
|
width: 40px;
|
height: 40px;
|
border-radius: 50%;
|
}
|
|
&.expand-create-history-container {
|
flex: 1;
|
height: 100%;
|
border-radius: 20px;
|
|
.anticon {
|
margin-right: 10px;
|
}
|
}
|
}
|
|
.delete-batch-container {
|
&.expand-delete-batch-container {
|
flex: 1;
|
border-radius: 20px;
|
cursor: default;
|
box-shadow: none;
|
|
.expand-delete-batch-inner {
|
display: flex;
|
justify-content: space-evenly;
|
align-items: center;
|
height: 100%;
|
width: 100%;
|
|
& > div {
|
display: flex;
|
align-items: center;
|
|
&.select-all-button {
|
height: 100%;
|
}
|
|
&.able-delete-button {
|
color: #D9737A;
|
}
|
|
&.disable-delete-button {
|
color: #bbb;
|
cursor: not-allowed !important;
|
}
|
|
&:not(.split-line) {
|
cursor: pointer;
|
}
|
|
.anticon {
|
margin-right: 10px;
|
}
|
|
&.split-line {
|
width: 1px;
|
background-color: #000;
|
height: 50%;
|
}
|
}
|
}
|
}
|
|
&.fold-delete-batch-container {
|
width: 40px;
|
height: 40px;
|
border-radius: 50%;
|
}
|
|
&.disable-expand {
|
cursor: not-allowed;
|
&:hover {
|
box-shadow: none;
|
}
|
}
|
}
|
}
|
|
.chat-history-container {
|
flex: 1;
|
overflow: auto;
|
|
& > div {
|
border: 3px solid transparent;
|
border-radius: 10px;
|
padding: 10px 20px;
|
cursor: pointer;
|
display: flex;
|
align-items: center;
|
|
& > span {
|
display: flex;
|
justify-content: space-between;
|
position: relative;
|
flex: 1;
|
|
.conversation-title {
|
flex: 1;
|
overflow: hidden;
|
white-space: nowrap;
|
}
|
|
.hover-icon-container {
|
// display:none的消失方式会让点击删除弹出的popover卡片无法点击空白处消失
|
opacity: 0;
|
position: absolute;
|
right: 0;
|
}
|
|
.icon-container {
|
.anticon {
|
padding: 4px;
|
font-size: 16px;
|
border-radius: 8px;
|
margin-left: 5px;
|
|
&:hover {
|
background-color: rgba(0, 0, 0, .1);
|
}
|
}
|
}
|
|
#edit-input {
|
flex: 1;
|
height: 100%;
|
border: none;
|
outline: none;
|
padding: 1px 0;
|
letter-spacing: 1px;
|
background-color: transparent;
|
}
|
}
|
|
&:not(:last-child) {
|
margin-bottom: 8px;
|
}
|
|
&:hover {
|
background-color: @single-history-hover-background;
|
.icon-container {
|
opacity: 1;
|
background-color: @single-history-hover-background;
|
}
|
}
|
|
&.single-history-active {
|
background-color: @single-history-active-background;
|
&:hover {
|
.icon-container {
|
background-color: @single-history-active-background;
|
}
|
}
|
}
|
|
&.input-visible-class {
|
background-color: @main-container-background;
|
border: @single-history-edit-border;
|
&:hover {
|
.icon-container {
|
background-color: transparent;
|
}
|
}
|
|
}
|
}
|
}
|
|
/deep/ .ant-popover {
|
padding-bottom: 10px;
|
|
.ant-popover-arrow {
|
display: none;
|
}
|
|
.ant-popover-inner {
|
border-radius: @container-border-radius;
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
.ant-popover-inner-content {
|
padding: 12px 16px;
|
|
.popover-content {
|
font-size: 16px;
|
font-weight: bold;
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
font-family: ali_r_main;
|
|
& > div {
|
width: 100%;
|
display: flex;
|
justify-content: space-evenly;
|
margin-top: 10px;
|
|
button {
|
border: none;
|
padding: 5px 30px;
|
border-radius: 20px;
|
font-weight: bold;
|
cursor: pointer;
|
outline: none;
|
}
|
|
.cancel-delete-button {
|
background-color: #D9D9D9;
|
}
|
|
#delete-conversation-button, #confirm-delete-batch-button {
|
background-color: #7295AB;
|
color: #fff;
|
font-weight: normal;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
.checkbox-custom {
|
height: 100%;
|
position: relative;
|
display: flex;
|
justify-content: flex-end;
|
align-items: center;
|
cursor: pointer;
|
-webkit-user-select: none;
|
-moz-user-select: none;
|
-ms-user-select: none;
|
user-select: none;
|
|
input {
|
position: absolute;
|
opacity: 0;
|
cursor: pointer;
|
height: 0;
|
width: 0;
|
|
&:checked ~ .check-mark {
|
background-color: #7295AB;
|
border: none;
|
|
&:after {
|
display: block;
|
}
|
}
|
|
&:indeterminate ~ .check-mark {
|
background-color: #fff;
|
border: 1px solid #818181;
|
|
&:after {
|
display: block;
|
width: 10px;
|
height: 3px;
|
background: #818181;
|
border-radius: 12px;
|
}
|
}
|
}
|
|
.check-mark {
|
position: relative;
|
height: 16px;
|
width: 16px;
|
background-color: transparent;
|
border: 1px solid #818181;
|
border-radius: 50%;
|
margin-right: 10px;
|
|
&:after {
|
content: "";
|
position: absolute;
|
display: none;
|
top: 50%;
|
left: 50%;
|
width: 8px;
|
height: 8px;
|
border-radius: 50%;
|
background: #fff;
|
transform: translate(-50%, -50%);
|
}
|
|
&:hover {
|
border: 3px solid #7295AB;
|
}
|
}
|
}
|
}
|
|
.right-container {
|
width: 60%;
|
height: 100%;
|
border-radius: @container-border-radius;
|
display: flex;
|
flex-direction: column;
|
justify-content: space-between;
|
|
.conversation-container {
|
height: 570px;
|
background-color: @main-container-background;
|
padding: @container-padding*2;
|
border-radius: @container-border-radius;
|
margin-bottom: 25px;
|
overflow: auto;
|
display: flex;
|
flex-direction: column;
|
|
.single-conversation {
|
& > div {
|
display: flex;
|
flex-direction: column;
|
|
&.user-question {
|
align-items: flex-end;
|
.content {
|
background-color: @user-question-background;
|
}
|
}
|
|
&.assistant-answer {
|
align-items: flex-start;
|
|
.content {
|
background-color: @assistant-answer-background;
|
}
|
}
|
|
.avatar {
|
margin-bottom: 5px;
|
|
/deep/ .ant-avatar, img {
|
width: 35px;
|
height: 35px;
|
line-height: 35px;
|
}
|
}
|
|
.content {
|
max-width: 80%;
|
box-shadow: @conversation-content-container-box-shadow;
|
border-radius: @container-border-radius;
|
padding: @container-padding;
|
}
|
}
|
|
&:not(:first-child) {
|
padding-top: @container-padding*2;
|
}
|
}
|
}
|
|
.input-container {
|
flex: 1;
|
background-color: @main-container-background;
|
border-radius: @container-border-radius;
|
padding: @container-padding*2;
|
border: 3px solid transparent;
|
display: flex;
|
align-items: center;
|
box-shadow: none;
|
transition: all .2s linear;
|
|
textarea {
|
flex: 1;
|
outline: none;
|
border: none;
|
background-color: transparent;
|
width: 100%;
|
height: 100%;
|
resize: none;
|
margin-right: 10px;
|
}
|
|
img {
|
width: 35px;
|
height: 35px;
|
cursor: pointer;
|
}
|
|
.loading-icon {
|
font-size: 35px;
|
}
|
|
&:hover {
|
box-shadow: @input-container-box-shadow;
|
}
|
|
&.input-container-active {
|
box-shadow: @input-container-box-shadow;
|
}
|
}
|
}
|
}
|
}
|
</style>
|