feat: 对话演示适配移动端和部分类型优化
feat: 对话演示适配移动端和部分类型优化
This commit is contained in:
commit
1e5067f849
4
ui/src/enums/common.ts
Normal file
4
ui/src/enums/common.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export enum DeviceType {
|
||||||
|
Mobile = 'Mobile',
|
||||||
|
Desktop = 'Desktop'
|
||||||
|
}
|
||||||
4
ui/src/enums/document.ts
Normal file
4
ui/src/enums/document.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export enum hitHandlingMethod {
|
||||||
|
optimization = '模型优化',
|
||||||
|
directly_return = '直接回答'
|
||||||
|
}
|
||||||
6
ui/src/enums/team.ts
Normal file
6
ui/src/enums/team.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export enum TeamEnum {
|
||||||
|
MANAGE = 'MANAGE',
|
||||||
|
USE = 'USE',
|
||||||
|
DATASET = 'DATASET',
|
||||||
|
APPLICATION = 'APPLICATION'
|
||||||
|
}
|
||||||
36
ui/src/layout/hooks/useResize.ts
Normal file
36
ui/src/layout/hooks/useResize.ts
Normal file
@ -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 { defineStore } from 'pinia'
|
||||||
|
import { DeviceType } from '@/enums/common'
|
||||||
|
|
||||||
export interface commonTypes {
|
export interface commonTypes {
|
||||||
breadcrumb: any
|
breadcrumb: any
|
||||||
paginationConfig: any | null
|
paginationConfig: any | null
|
||||||
search: any
|
search: any
|
||||||
|
device: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const useCommonStore = defineStore({
|
const useCommonStore = defineStore({
|
||||||
@ -12,7 +14,8 @@ const useCommonStore = defineStore({
|
|||||||
breadcrumb: null,
|
breadcrumb: null,
|
||||||
// 搜索和分页缓存
|
// 搜索和分页缓存
|
||||||
paginationConfig: {},
|
paginationConfig: {},
|
||||||
search: {}
|
search: {},
|
||||||
|
device: DeviceType.Desktop
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
saveBreadcrumb(data: any) {
|
saveBreadcrumb(data: any) {
|
||||||
@ -23,6 +26,12 @@ const useCommonStore = defineStore({
|
|||||||
},
|
},
|
||||||
saveCondition(val: string, data: any) {
|
saveCondition(val: string, data: any) {
|
||||||
this.search[val] = data
|
this.search[val] = data
|
||||||
|
},
|
||||||
|
toggleDevice(value: DeviceType) {
|
||||||
|
this.device = value
|
||||||
|
},
|
||||||
|
isMobile() {
|
||||||
|
return this.device === DeviceType.Mobile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -32,7 +32,7 @@
|
|||||||
<span>历史记录</span>
|
<span>历史记录</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-scrollbar>
|
<el-scrollbar max-height="300">
|
||||||
<div class="p-8">
|
<div class="p-8">
|
||||||
<common-list
|
<common-list
|
||||||
:data="chatLogeData"
|
:data="chatLogeData"
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="chat-pc" v-loading="loading">
|
<div class="chat-pc" :class="classObj" v-loading="loading">
|
||||||
<div class="chat-pc__header">
|
<div class="chat-pc__header">
|
||||||
<h4 class="ml-24">{{ applicationDetail?.name }}</h4>
|
<h4 class="ml-24">{{ applicationDetail?.name }}</h4>
|
||||||
</div>
|
</div>
|
||||||
@ -65,20 +65,38 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<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 { useRoute } from 'vue-router'
|
||||||
import applicationApi from '@/api/application'
|
import applicationApi from '@/api/application'
|
||||||
import useStore from '@/stores'
|
import useStore from '@/stores'
|
||||||
|
import useResize from '@/layout/hooks/useResize'
|
||||||
|
useResize()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
const {
|
const {
|
||||||
params: { accessToken }
|
params: { accessToken }
|
||||||
} = route as any
|
} = 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 = {
|
const newObj = {
|
||||||
id: 'new',
|
id: 'new',
|
||||||
@ -149,6 +167,9 @@ function newChat() {
|
|||||||
}
|
}
|
||||||
currentChatId.value = 'new'
|
currentChatId.value = 'new'
|
||||||
currentChatName.value = '新建对话'
|
currentChatName.value = '新建对话'
|
||||||
|
if (common.isMobile()) {
|
||||||
|
isCollapse.value = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChatLog(id: string) {
|
function getChatLog(id: string) {
|
||||||
@ -198,6 +219,9 @@ const clickListHandle = (item: any) => {
|
|||||||
getChatRecord()
|
getChatRecord()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (common.isMobile()) {
|
||||||
|
isCollapse.value = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function refresh(id: string) {
|
function refresh(id: string) {
|
||||||
@ -247,7 +271,6 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
.right-height {
|
.right-height {
|
||||||
height: calc(100vh - var(--app-header-height) * 2 - 24px);
|
height: calc(100vh - var(--app-header-height) * 2 - 24px);
|
||||||
overflow: scroll;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,5 +301,44 @@ onMounted(() => {
|
|||||||
max-width: var(--app-chat-width, 860px);
|
max-width: var(--app-chat-width, 860px);
|
||||||
margin: 0 auto;
|
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>
|
</style>
|
||||||
|
|||||||
@ -86,7 +86,7 @@ import { useRoute } from 'vue-router'
|
|||||||
import type { FormInstance } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
import documentApi from '@/api/document'
|
import documentApi from '@/api/document'
|
||||||
import { MsgSuccess } from '@/utils/message'
|
import { MsgSuccess } from '@/utils/message'
|
||||||
import { hitHandlingMethod } from '../utils'
|
import { hitHandlingMethod } from '@/enums/document'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const {
|
const {
|
||||||
|
|||||||
@ -127,7 +127,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ hitHandlingMethod[row.hit_handling_method] }}
|
{{ hitHandlingMethod[row.hit_handling_method as keyof typeof hitHandlingMethod] }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="create_time" label="创建时间" width="175">
|
<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 SelectDatasetDialog from './component/SelectDatasetDialog.vue'
|
||||||
import { numberFormat } from '@/utils/utils'
|
import { numberFormat } from '@/utils/utils'
|
||||||
import { datetimeFormat } from '@/utils/time'
|
import { datetimeFormat } from '@/utils/time'
|
||||||
import { hitHandlingMethod } from './utils'
|
import { hitHandlingMethod } from '@/enums/document'
|
||||||
import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message'
|
import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message'
|
||||||
import useStore from '@/stores'
|
import useStore from '@/stores'
|
||||||
const router = useRouter()
|
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 type { FormInstance, FormRules } from 'element-plus'
|
||||||
import { MsgSuccess } from '@/utils/message'
|
import { MsgSuccess } from '@/utils/message'
|
||||||
import TeamApi from '@/api/team'
|
import TeamApi from '@/api/team'
|
||||||
// import UserApi from '@/api/user'
|
|
||||||
|
|
||||||
const emit = defineEmits(['refresh'])
|
const emit = defineEmits(['refresh'])
|
||||||
|
|
||||||
@ -70,11 +69,9 @@ const memberForm = ref({
|
|||||||
users: []
|
users: []
|
||||||
})
|
})
|
||||||
|
|
||||||
// const SelectRemoteRef = ref()
|
|
||||||
const addMemberFormRef = ref<FormInstance>()
|
const addMemberFormRef = ref<FormInstance>()
|
||||||
|
|
||||||
const loading = ref<boolean>(false)
|
const loading = ref<boolean>(false)
|
||||||
// const userOptions = ref<Array<any>>([])
|
|
||||||
|
|
||||||
const rules = ref<FormRules>({
|
const rules = ref<FormRules>({
|
||||||
users: [
|
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 = () => {
|
const open = () => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,8 +46,8 @@
|
|||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
:disabled="props.manage"
|
:disabled="props.manage"
|
||||||
v-model="row.operate[MANAGE]"
|
v-model="row.operate[TeamEnum.MANAGE]"
|
||||||
@change="checkedOperateChange(MANAGE, row)"
|
@change="checkedOperateChange(TeamEnum.MANAGE, row)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@ -62,8 +62,8 @@
|
|||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
:disabled="props.manage"
|
:disabled="props.manage"
|
||||||
v-model="row.operate[USE]"
|
v-model="row.operate[TeamEnum.USE]"
|
||||||
@change="checkedOperateChange(USE, row)"
|
@change="checkedOperateChange(TeamEnum.USE, row)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@ -72,7 +72,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, watch, computed } from 'vue'
|
import { ref, onMounted, watch, computed } from 'vue'
|
||||||
import { MANAGE, USE, DATASET, APPLICATION } from './../utils'
|
import { TeamEnum } from '@/enums/team'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: {
|
data: {
|
||||||
@ -85,13 +85,13 @@ const props = defineProps({
|
|||||||
manage: Boolean
|
manage: Boolean
|
||||||
})
|
})
|
||||||
|
|
||||||
const isDataset = computed(() => props.type === DATASET)
|
const isDataset = computed(() => props.type === TeamEnum.DATASET)
|
||||||
const isApplication = computed(() => props.type === APPLICATION)
|
const isApplication = computed(() => props.type === TeamEnum.APPLICATION)
|
||||||
|
|
||||||
const emit = defineEmits(['update:data'])
|
const emit = defineEmits(['update:data'])
|
||||||
const allChecked: any = ref({
|
const allChecked: any = ref({
|
||||||
[MANAGE]: false,
|
[TeamEnum.MANAGE]: false,
|
||||||
[USE]: false
|
[TeamEnum.USE]: false
|
||||||
})
|
})
|
||||||
|
|
||||||
const filterText = ref('')
|
const filterText = ref('')
|
||||||
@ -123,10 +123,10 @@ function handleCheckAllChange(val: string | number | boolean, Name: string | num
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function checkedOperateChange(Name: string | number, row: any) {
|
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) => {
|
props.data.map((item: any) => {
|
||||||
if (item.id === row.id) {
|
if (item.id === row.id) {
|
||||||
item.operate[USE] = true
|
item.operate[TeamEnum.USE] = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -145,4 +145,3 @@ onMounted(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scope></style>
|
<style lang="scss" scope></style>
|
||||||
../utils
|
|
||||||
@ -82,7 +82,7 @@ import type { TeamMember } from '@/api/type/team'
|
|||||||
import CreateMemberDialog from './component/CreateMemberDialog.vue'
|
import CreateMemberDialog from './component/CreateMemberDialog.vue'
|
||||||
import PermissionSetting from './component/PermissionSetting.vue'
|
import PermissionSetting from './component/PermissionSetting.vue'
|
||||||
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||||
import { DATASET, APPLICATION, isManage } from './utils'
|
import { TeamEnum } from '@/enums/team'
|
||||||
|
|
||||||
const CreateMemberRef = ref<InstanceType<typeof CreateMemberDialog>>()
|
const CreateMemberRef = ref<InstanceType<typeof CreateMemberDialog>>()
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
@ -94,18 +94,18 @@ const currentType = ref<String>('')
|
|||||||
|
|
||||||
const filterText = ref('')
|
const filterText = ref('')
|
||||||
|
|
||||||
const activeName = ref(DATASET)
|
const activeName = ref(TeamEnum.DATASET)
|
||||||
const tableHeight = ref(0)
|
const tableHeight = ref(0)
|
||||||
|
|
||||||
const settingTags = reactive([
|
const settingTags = reactive([
|
||||||
{
|
{
|
||||||
label: '知识库',
|
label: '知识库',
|
||||||
value: DATASET,
|
value: TeamEnum.DATASET,
|
||||||
data: [] as any
|
data: [] as any
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '应用',
|
label: '应用',
|
||||||
value: APPLICATION,
|
value: TeamEnum.APPLICATION,
|
||||||
data: [] as any
|
data: [] as any
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
@ -118,6 +118,10 @@ watch(filterText, (val) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function isManage(type: String) {
|
||||||
|
return type === 'manage'
|
||||||
|
}
|
||||||
|
|
||||||
function submitPermissions() {
|
function submitPermissions() {
|
||||||
rLoading.value = true
|
rLoading.value = true
|
||||||
const obj: any = {
|
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
Block a user