mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
feat: 对话演示适配移动端和部分类型优化
This commit is contained in:
parent
7d2f4fe7c7
commit
49451b4c0a
|
|
@ -0,0 +1,4 @@
|
|||
export enum DeviceType {
|
||||
Mobile = 'Mobile',
|
||||
Desktop = 'Desktop'
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
export enum hitHandlingMethod {
|
||||
optimization = '模型优化',
|
||||
directly_return = '直接回答'
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
export enum TeamEnum {
|
||||
MANAGE = 'MANAGE',
|
||||
USE = 'USE',
|
||||
DATASET = 'DATASET',
|
||||
APPLICATION = 'APPLICATION'
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
import { watch, onBeforeMount, onMounted, onBeforeUnmount } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import useStore from '@/stores'
|
||||
import { DeviceType } from '@/enums/common'
|
||||
/** 参考 Bootstrap 的响应式设计 WIDTH = 600 */
|
||||
const WIDTH = 600
|
||||
|
||||
/** 根据大小变化重新布局 */
|
||||
export default () => {
|
||||
const { common } = useStore()
|
||||
const _isMobile = () => {
|
||||
const rect = document.body.getBoundingClientRect()
|
||||
return rect.width - 1 < WIDTH
|
||||
}
|
||||
|
||||
const _resizeHandler = () => {
|
||||
if (!document.hidden) {
|
||||
const isMobile = _isMobile()
|
||||
common.toggleDevice(isMobile ? DeviceType.Mobile : DeviceType.Desktop)
|
||||
}
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
window.addEventListener('resize', _resizeHandler)
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
if (_isMobile()) {
|
||||
common.toggleDevice(DeviceType.Mobile)
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('resize', _resizeHandler)
|
||||
})
|
||||
}
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
import { defineStore } from 'pinia'
|
||||
import { DeviceType } from '@/enums/common'
|
||||
|
||||
export interface commonTypes {
|
||||
breadcrumb: any
|
||||
paginationConfig: any | null
|
||||
search: any
|
||||
device: string
|
||||
}
|
||||
|
||||
const useCommonStore = defineStore({
|
||||
|
|
@ -12,7 +14,8 @@ const useCommonStore = defineStore({
|
|||
breadcrumb: null,
|
||||
// 搜索和分页缓存
|
||||
paginationConfig: {},
|
||||
search: {}
|
||||
search: {},
|
||||
device: DeviceType.Desktop
|
||||
}),
|
||||
actions: {
|
||||
saveBreadcrumb(data: any) {
|
||||
|
|
@ -23,6 +26,12 @@ const useCommonStore = defineStore({
|
|||
},
|
||||
saveCondition(val: string, data: any) {
|
||||
this.search[val] = data
|
||||
},
|
||||
toggleDevice(value: DeviceType) {
|
||||
this.device = value
|
||||
},
|
||||
isMobile() {
|
||||
return this.device === DeviceType.Mobile
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
<span>历史记录</span>
|
||||
</div>
|
||||
|
||||
<el-scrollbar>
|
||||
<el-scrollbar max-height="300">
|
||||
<div class="p-8">
|
||||
<common-list
|
||||
:data="chatLogeData"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="chat-pc" v-loading="loading">
|
||||
<div class="chat-pc" :class="classObj" v-loading="loading">
|
||||
<div class="chat-pc__header">
|
||||
<h4 class="ml-24">{{ applicationDetail?.name }}</h4>
|
||||
</div>
|
||||
|
|
@ -65,20 +65,38 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="collapse">
|
||||
<el-button size="small" @click="isCollapse = !isCollapse">
|
||||
<el-icon> <component :is="isCollapse ? 'Fold' : 'Expand'" /></el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, onMounted, nextTick } from 'vue'
|
||||
import { reactive, ref, onMounted, nextTick, computed } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import applicationApi from '@/api/application'
|
||||
import useStore from '@/stores'
|
||||
import useResize from '@/layout/hooks/useResize'
|
||||
useResize()
|
||||
const route = useRoute()
|
||||
|
||||
const {
|
||||
params: { accessToken }
|
||||
} = route as any
|
||||
|
||||
const { application, user, log } = useStore()
|
||||
const { application, user, log, common } = useStore()
|
||||
|
||||
const isCollapse = ref(false)
|
||||
|
||||
const classObj = computed(() => {
|
||||
return {
|
||||
mobile: common.isMobile(),
|
||||
hideLeft: !isCollapse.value,
|
||||
openLeft: isCollapse.value
|
||||
}
|
||||
})
|
||||
|
||||
const newObj = {
|
||||
id: 'new',
|
||||
|
|
@ -149,6 +167,9 @@ function newChat() {
|
|||
}
|
||||
currentChatId.value = 'new'
|
||||
currentChatName.value = '新建对话'
|
||||
if (common.isMobile()) {
|
||||
isCollapse.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function getChatLog(id: string) {
|
||||
|
|
@ -198,6 +219,9 @@ const clickListHandle = (item: any) => {
|
|||
getChatRecord()
|
||||
}
|
||||
}
|
||||
if (common.isMobile()) {
|
||||
isCollapse.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function refresh(id: string) {
|
||||
|
|
@ -247,7 +271,6 @@ onMounted(() => {
|
|||
}
|
||||
.right-height {
|
||||
height: calc(100vh - var(--app-header-height) * 2 - 24px);
|
||||
overflow: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -278,5 +301,44 @@ onMounted(() => {
|
|||
max-width: var(--app-chat-width, 860px);
|
||||
margin: 0 auto;
|
||||
}
|
||||
.collapse {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
// 适配移动端
|
||||
.mobile {
|
||||
.chat-pc {
|
||||
&__right {
|
||||
width: 100%;
|
||||
}
|
||||
&__left {
|
||||
display: none;
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
.collapse {
|
||||
display: block;
|
||||
position: fixed;
|
||||
bottom: 90px;
|
||||
z-index: 99;
|
||||
}
|
||||
&.openLeft {
|
||||
.chat-pc {
|
||||
&__left {
|
||||
display: block;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
z-index: 99;
|
||||
height: calc(100vh - var(--app-header-height) + 6px);
|
||||
}
|
||||
}
|
||||
.collapse {
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: 90px;
|
||||
right: 0;
|
||||
z-index: 99;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ import { useRoute } from 'vue-router'
|
|||
import type { FormInstance } from 'element-plus'
|
||||
import documentApi from '@/api/document'
|
||||
import { MsgSuccess } from '@/utils/message'
|
||||
import { hitHandlingMethod } from '../utils'
|
||||
import { hitHandlingMethod } from '@/enums/document'
|
||||
|
||||
const route = useRoute()
|
||||
const {
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@
|
|||
</div>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
{{ hitHandlingMethod[row.hit_handling_method] }}
|
||||
{{ hitHandlingMethod[row.hit_handling_method as keyof typeof hitHandlingMethod] }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="create_time" label="创建时间" width="175">
|
||||
|
|
@ -227,7 +227,7 @@ import SyncWebDialog from '@/views/dataset/component/SyncWebDialog.vue'
|
|||
import SelectDatasetDialog from './component/SelectDatasetDialog.vue'
|
||||
import { numberFormat } from '@/utils/utils'
|
||||
import { datetimeFormat } from '@/utils/time'
|
||||
import { hitHandlingMethod } from './utils'
|
||||
import { hitHandlingMethod } from '@/enums/document'
|
||||
import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message'
|
||||
import useStore from '@/stores'
|
||||
const router = useRouter()
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
export const hitHandlingMethod: any = {
|
||||
optimization: '模型优化',
|
||||
directly_return: '直接回答'
|
||||
}
|
||||
|
|
@ -60,7 +60,6 @@ import { ref, watch, onMounted } from 'vue'
|
|||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import { MsgSuccess } from '@/utils/message'
|
||||
import TeamApi from '@/api/team'
|
||||
// import UserApi from '@/api/user'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
|
|
@ -70,11 +69,9 @@ const memberForm = ref({
|
|||
users: []
|
||||
})
|
||||
|
||||
// const SelectRemoteRef = ref()
|
||||
const addMemberFormRef = ref<FormInstance>()
|
||||
|
||||
const loading = ref<boolean>(false)
|
||||
// const userOptions = ref<Array<any>>([])
|
||||
|
||||
const rules = ref<FormRules>({
|
||||
users: [
|
||||
|
|
@ -96,21 +93,6 @@ watch(dialogVisible, (bool) => {
|
|||
}
|
||||
})
|
||||
|
||||
// const remoteMethod = (query: string) => {
|
||||
// if (query) {
|
||||
// setTimeout(() => {
|
||||
// getUser(query)
|
||||
// }, 200)
|
||||
// } else {
|
||||
// userOptions.value = []
|
||||
// }
|
||||
// }
|
||||
|
||||
// const changeSelectHandle = () => {
|
||||
// SelectRemoteRef.value.query = ''
|
||||
// SelectRemoteRef.value.blur()
|
||||
// }
|
||||
|
||||
const open = () => {
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@
|
|||
<template #default="{ row }">
|
||||
<el-checkbox
|
||||
:disabled="props.manage"
|
||||
v-model="row.operate[MANAGE]"
|
||||
@change="checkedOperateChange(MANAGE, row)"
|
||||
v-model="row.operate[TeamEnum.MANAGE]"
|
||||
@change="checkedOperateChange(TeamEnum.MANAGE, row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
|
@ -62,8 +62,8 @@
|
|||
<template #default="{ row }">
|
||||
<el-checkbox
|
||||
:disabled="props.manage"
|
||||
v-model="row.operate[USE]"
|
||||
@change="checkedOperateChange(USE, row)"
|
||||
v-model="row.operate[TeamEnum.USE]"
|
||||
@change="checkedOperateChange(TeamEnum.USE, row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, watch, computed } from 'vue'
|
||||
import { MANAGE, USE, DATASET, APPLICATION } from './../utils'
|
||||
import { TeamEnum } from '@/enums/team'
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
|
|
@ -85,13 +85,13 @@ const props = defineProps({
|
|||
manage: Boolean
|
||||
})
|
||||
|
||||
const isDataset = computed(() => props.type === DATASET)
|
||||
const isApplication = computed(() => props.type === APPLICATION)
|
||||
const isDataset = computed(() => props.type === TeamEnum.DATASET)
|
||||
const isApplication = computed(() => props.type === TeamEnum.APPLICATION)
|
||||
|
||||
const emit = defineEmits(['update:data'])
|
||||
const allChecked: any = ref({
|
||||
[MANAGE]: false,
|
||||
[USE]: false
|
||||
[TeamEnum.MANAGE]: false,
|
||||
[TeamEnum.USE]: false
|
||||
})
|
||||
|
||||
const filterText = ref('')
|
||||
|
|
@ -123,10 +123,10 @@ function handleCheckAllChange(val: string | number | boolean, Name: string | num
|
|||
}
|
||||
}
|
||||
function checkedOperateChange(Name: string | number, row: any) {
|
||||
if (Name === MANAGE && row.operate[MANAGE]) {
|
||||
if (Name === TeamEnum.MANAGE && row.operate[TeamEnum.MANAGE]) {
|
||||
props.data.map((item: any) => {
|
||||
if (item.id === row.id) {
|
||||
item.operate[USE] = true
|
||||
item.operate[TeamEnum.USE] = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -145,4 +145,3 @@ onMounted(() => {
|
|||
})
|
||||
</script>
|
||||
<style lang="scss" scope></style>
|
||||
../utils
|
||||
|
|
@ -82,7 +82,7 @@ import type { TeamMember } from '@/api/type/team'
|
|||
import CreateMemberDialog from './component/CreateMemberDialog.vue'
|
||||
import PermissionSetting from './component/PermissionSetting.vue'
|
||||
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||
import { DATASET, APPLICATION, isManage } from './utils'
|
||||
import { TeamEnum } from '@/enums/team'
|
||||
|
||||
const CreateMemberRef = ref<InstanceType<typeof CreateMemberDialog>>()
|
||||
const loading = ref(false)
|
||||
|
|
@ -94,18 +94,18 @@ const currentType = ref<String>('')
|
|||
|
||||
const filterText = ref('')
|
||||
|
||||
const activeName = ref(DATASET)
|
||||
const activeName = ref(TeamEnum.DATASET)
|
||||
const tableHeight = ref(0)
|
||||
|
||||
const settingTags = reactive([
|
||||
{
|
||||
label: '知识库',
|
||||
value: DATASET,
|
||||
value: TeamEnum.DATASET,
|
||||
data: [] as any
|
||||
},
|
||||
{
|
||||
label: '应用',
|
||||
value: APPLICATION,
|
||||
value: TeamEnum.APPLICATION,
|
||||
data: [] as any
|
||||
}
|
||||
])
|
||||
|
|
@ -118,6 +118,10 @@ watch(filterText, (val) => {
|
|||
}
|
||||
})
|
||||
|
||||
function isManage(type: String) {
|
||||
return type === 'manage'
|
||||
}
|
||||
|
||||
function submitPermissions() {
|
||||
rLoading.value = true
|
||||
const obj: any = {
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
export const MANAGE = 'MANAGE'
|
||||
export const USE = 'USE'
|
||||
export const DATASET = 'DATASET'
|
||||
export const APPLICATION = 'APPLICATION'
|
||||
|
||||
export function isManage(type: String) {
|
||||
return type === 'manage'
|
||||
}
|
||||
Loading…
Reference in New Issue