perf: 优化数据结构

This commit is contained in:
kuaifan 2025-04-07 13:40:55 +08:00
parent 3334abfb8f
commit d7902b4d08
5 changed files with 126 additions and 26 deletions

View File

@ -17,7 +17,7 @@
:key="key" :key="key"
:command="item.value" :command="item.value"
:divided="!!item.divided" :divided="!!item.divided"
:disabled="active === item.value || !!item.disabled"> :disabled="(active === item.value && !activeClick) || !!item.disabled">
<div class="item-box"> <div class="item-box">
<div class="item">{{item.label}}</div> <div class="item">{{item.label}}</div>
<div v-if="tickShow" class="tick"> <div v-if="tickShow" class="tick">
@ -40,6 +40,7 @@ export default {
list: [], // : [{label: '', value: ''}] list: [], // : [{label: '', value: ''}]
active: '', // active: '', //
activeClick: false, //
onUpdate: null, // onUpdate: null, //
scrollHide: true, // scrollHide: true, //
tickShow: true, // tickShow: true, //
@ -81,6 +82,7 @@ export default {
} }
this.list = data.list; this.list = data.list;
this.active = data.active && this.list.find(item => item.value === data.active) ? data.active : ''; this.active = data.active && this.list.find(item => item.value === data.active) ? data.active : '';
this.activeClick = typeof data.activeClick === "boolean" ? data.activeClick : false;
this.onUpdate = typeof data.onUpdate === "function" ? data.onUpdate : null; this.onUpdate = typeof data.onUpdate === "function" ? data.onUpdate : null;
this.scrollHide = typeof data.scrollHide === "boolean" ? data.scrollHide : true; this.scrollHide = typeof data.scrollHide === "boolean" ? data.scrollHide : true;
this.tickShow = typeof data.tickShow === "boolean" ? data.tickShow : true; this.tickShow = typeof data.tickShow === "boolean" ? data.tickShow : true;

View File

@ -54,9 +54,9 @@
{{$L(dialogData.online_state === true ? '在线' : dialogData.online_state)}} {{$L(dialogData.online_state === true ? '在线' : dialogData.online_state)}}
</li> </li>
</ul> </ul>
<ul v-if="tagShow" class="title-tags scrollbar-hidden"> <ul v-if="typeShow" class="title-types scrollbar-hidden">
<li <li
v-for="item in msgTags" v-for="item in msgTypes"
:key="item.type" :key="item.type"
:class="{ :class="{
[item.type || 'msg']: true, [item.type || 'msg']: true,
@ -64,7 +64,7 @@
}" }"
@click="onMsgType(item.type)"> @click="onMsgType(item.type)">
<i class="no-dark-content"></i> <i class="no-dark-content"></i>
<span>{{$L(item.label)}}</span> <span>{{item.label}}</span>
</li> </li>
</ul> </ul>
</div> </div>
@ -972,33 +972,33 @@ export default {
return '发送文件' return '发送文件'
}, },
msgTags({dialogData}) { msgTypes({dialogData}) {
const array = [ const array = [
{type: '', label: '消息'}, {type: '', label: this.$L('消息')},
]; ];
if (dialogData.has_tag) { if (dialogData.has_tag) {
array.push({type: 'tag', label: '标注'}) array.push({type: 'tag', label: this.$L('标注')})
} }
if (dialogData.has_todo) { if (dialogData.has_todo) {
array.push({type: 'todo', label: '事项'}) array.push({type: 'todo', label: this.$L('事项')})
} }
if (dialogData.has_image) { if (dialogData.has_image) {
array.push({type: 'image', label: '图片'}) array.push({type: 'image', label: this.$L('图片')})
} }
if (dialogData.has_file) { if (dialogData.has_file) {
array.push({type: 'file', label: '文件'}) array.push({type: 'file', label: this.$L('文件')})
} }
if (dialogData.has_link) { if (dialogData.has_link) {
array.push({type: 'link', label: '链接'}) array.push({type: 'link', label: this.$L('链接')})
} }
if (dialogData.group_type === 'project') { if (dialogData.group_type === 'project') {
array.push({type: 'project', label: '打开项目'}) array.push({type: 'project', label: this.$L('打开项目')})
} }
if (dialogData.group_type === 'task') { if (dialogData.group_type === 'task') {
array.push({type: 'task', label: '打开任务'}) array.push({type: 'task', label: this.$L('打开任务')})
} }
if (dialogData.group_type === 'okr') { if (dialogData.group_type === 'okr') {
array.push({type: 'okr', label: '打开OKR'}) array.push({type: 'okr', label: this.$L('打开OKR')})
} }
return array return array
}, },
@ -1032,8 +1032,8 @@ export default {
return this.todoList.length > 0 && this.isDefaultSize && this.quoteId === 0 return this.todoList.length > 0 && this.isDefaultSize && this.quoteId === 0
}, },
tagShow() { typeShow() {
return this.msgTags.length > 1 && this.isDefaultSize && !this.searchShow return this.msgTypes.length > 1 && this.isDefaultSize && !this.searchShow
}, },
topShow() { topShow() {
@ -1050,7 +1050,7 @@ export default {
navClass() { navClass() {
return { return {
'completed': $A.dialogCompleted(this.dialogData), 'completed': $A.dialogCompleted(this.dialogData),
'tagged': this.tagShow 'tagged': this.typeShow
} }
}, },
@ -1261,6 +1261,7 @@ export default {
msgType() { msgType() {
this.onGetMsgClear() this.onGetMsgClear()
this.$emit('on-type-change', this.msgType)
}, },
searchKey(key) { searchKey(key) {

View File

@ -435,16 +435,26 @@
class="task-resize" class="task-resize"
placement="right" placement="right"
v-model="taskDialogWidth" v-model="taskDialogWidth"
:min="220" :min="300"
:max="900" :max="900"
:reverse="true"/> :reverse="true"/>
<template v-if="hasOpenDialog"> <template v-if="hasOpenDialog">
<DialogWrapper v-if="taskId > 0" ref="dialog" :dialog-id="taskDetail.dialog_id"> <DialogWrapper
v-if="taskId > 0"
ref="dialog"
:dialog-id="taskDetail.dialog_id"
@on-type-change="onTypeChange">
<div slot="head" class="head"> <div slot="head" class="head">
<Icon class="icon" type="ios-chatbubbles-outline" /> <Icon class="icon" type="ios-chatbubbles-outline" />
<div class="nav"> <div class="nav">
<p :class="{active:navActive=='dialog'}" @click="navActive='dialog'">{{$L('聊天')}}</p> <div class="nav-item nav-chat" :class="{active:navActive=='dialog'}" @click="navActive='dialog'">
<p :class="{active:navActive=='log'}" @click="navActive='log'">{{$L('动态')}}</p> {{$L('聊天')}}
<span v-if="msgTypes.length > 1" class="msg-type" @click.stop="openTypeClick">
<i class="taskfont">&#xe740;</i>
<em v-if="msgType">{{getTypeLabel(msgType)}}</em>
</span>
</div>
<div class="nav-item" :class="{active:navActive=='log'}" @click="navActive='log'">{{$L('动态')}}</div>
<div v-if="navActive=='log'" class="refresh"> <div v-if="navActive=='log'" class="refresh">
<Loading v-if="logLoadIng"/> <Loading v-if="logLoadIng"/>
<Icon v-else type="ios-refresh" @click="getLogLists"></Icon> <Icon v-else type="ios-refresh" @click="getLogLists"></Icon>
@ -663,6 +673,7 @@ export default {
msgText: '', msgText: '',
msgFile: [], msgFile: [],
msgRecord: {}, msgRecord: {},
msgType: '',
navActive: 'dialog', navActive: 'dialog',
logLoadIng: false, logLoadIng: false,
@ -740,6 +751,7 @@ export default {
'cacheProjects', 'cacheProjects',
'cacheColumns', 'cacheColumns',
'cacheTasks', 'cacheTasks',
'cacheDialogs',
'taskContents', 'taskContents',
'taskFiles', 'taskFiles',
@ -966,7 +978,36 @@ export default {
&& !taskDetail.complete_at && !taskDetail.complete_at
&& taskDetail.end_at && taskDetail.end_at
&& taskDetail.end_at != mainEndAt && taskDetail.end_at != mainEndAt
} },
dialogData({taskDetail}) {
if (!taskDetail.dialog_id) {
return {}
}
return this.cacheDialogs.find(({id}) => id == taskDetail.dialog_id) || {}
},
msgTypes({dialogData}) {
const array = [
{value: '', label: this.$L('全部')},
];
if (dialogData.has_tag) {
array.push({value: 'tag', label: this.$L('标注')})
}
if (dialogData.has_todo) {
array.push({value: 'todo', label: this.$L('事项')})
}
if (dialogData.has_image) {
array.push({value: 'image', label: this.$L('图片')})
}
if (dialogData.has_file) {
array.push({value: 'file', label: this.$L('文件')})
}
if (dialogData.has_link) {
array.push({value: 'link', label: this.$L('链接')})
}
return array
},
}, },
watch: { watch: {
@ -2043,6 +2084,36 @@ export default {
]; ];
// //
this.updateData('tag', mergedTags); this.updateData('tag', mergedTags);
},
getTypeLabel(type) {
this.msgTypes.some(item => {
if (item.value === type) {
type = item.label
return true
}
})
return type
},
onTypeChange(type) {
this.msgType = type
},
openTypeClick(event) {
if (this.msgTypes.length === 0) {
return
}
this.$store.state.menuOperation = {
event,
list: this.msgTypes,
active: this.msgType,
activeClick: true,
onUpdate: (type) => {
this.navActive = 'dialog'
this.$refs.dialog?.onMsgType(type)
}
}
} }
} }
} }

View File

@ -262,7 +262,7 @@
} }
} }
.title-tags { .title-types {
display: flex; display: flex;
align-items: center; align-items: center;
@ -2618,7 +2618,7 @@ body.window-portrait {
display: flex; display: flex;
justify-content: center; justify-content: center;
} }
.title-tags { .title-types {
position: absolute; position: absolute;
left: 0; left: 0;
right: 0; right: 0;

View File

@ -618,7 +618,7 @@
padding-left: 18px; padding-left: 18px;
font-weight: 500; font-weight: 500;
color: $primary-text-color; color: $primary-text-color;
> p { .nav-item {
display: flex; display: flex;
align-items: center; align-items: center;
margin-right: 24px; margin-right: 24px;
@ -630,6 +630,32 @@
color: #555555; color: #555555;
cursor: default; cursor: default;
} }
&.nav-chat {
.msg-type {
display: flex;
align-items: center;
padding-left: 6px;
opacity: 0.8;
transition: opacity 0.2s;
cursor: pointer;
&:hover {
opacity: 1;
}
.taskfont {
display: inline-block;
font-size: 12px;
padding-top: 1px;
font-weight: normal;
opacity: 0.9;
}
> em {
padding-left: 4px;
font-style: normal;
font-size: 12px;
font-weight: normal;
}
}
}
} }
.refresh { .refresh {
display: flex; display: flex;
@ -801,7 +827,7 @@
} }
.nav { .nav {
padding-left: 0; padding-left: 0;
> p { .nav-item {
margin-right: 28px; margin-right: 28px;
&.active { &.active {
font-size: 18px; font-size: 18px;