mirror of
https://github.com/kuaifan/dootask.git
synced 2026-03-07 09:57:37 +00:00
feat: 搜索会话消息
This commit is contained in:
parent
f34a391aec
commit
032b02c1ec
@ -370,7 +370,7 @@ class DialogController extends AbstractController
|
||||
* @apiName msg__list
|
||||
*
|
||||
* @apiParam {Number} dialog_id 对话ID
|
||||
* @apiParam {Number} msg_id 消息ID
|
||||
* @apiParam {Number} [msg_id] 消息ID
|
||||
* @apiParam {Number} [position_id] 此消息ID前后的数据
|
||||
* @apiParam {Number} [prev_id] 此消息ID之前的数据
|
||||
* @apiParam {Number} [next_id] 此消息ID之后的数据
|
||||
@ -492,6 +492,43 @@ class DialogController extends AbstractController
|
||||
return Base::retSuccess('success', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/search 10. 搜索消息位置
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup dialog
|
||||
* @apiName msg__search
|
||||
*
|
||||
* @apiParam {Number} dialog_id 对话ID
|
||||
* @apiParam {String} key 搜索关键词
|
||||
*
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
* @apiSuccess {Object} data 返回数据
|
||||
*/
|
||||
public function msg__search()
|
||||
{
|
||||
User::auth();
|
||||
//
|
||||
$dialog_id = intval(Request::input('dialog_id'));
|
||||
$key = trim(Request::input('key'));
|
||||
//
|
||||
if (empty($key)) {
|
||||
return Base::retError('关键词不能为空');
|
||||
}
|
||||
//
|
||||
WebSocketDialog::checkDialog($dialog_id);
|
||||
//
|
||||
$data = WebSocketDialogMsg::whereDialogId($dialog_id)
|
||||
->where('key', 'LIKE', "%{$key}%")
|
||||
->take(200)
|
||||
->pluck('id');
|
||||
return Base::retSuccess('success', [
|
||||
'data' => $data
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/one 10. 获取单条消息
|
||||
*
|
||||
|
||||
@ -74,6 +74,9 @@
|
||||
@command="onDialogMenu">
|
||||
<i class="taskfont dialog-menu-icon"></i>
|
||||
<EDropdownMenu v-slot="dropdown">
|
||||
<EDropdownItem command="searchMsg">
|
||||
<div>{{$L('搜索消息')}}</div>
|
||||
</EDropdownItem>
|
||||
<EDropdownItem v-if="dialogData.type === 'user'" command="openCreate">
|
||||
<div>{{$L('创建群组')}}</div>
|
||||
</EDropdownItem>
|
||||
@ -103,11 +106,29 @@
|
||||
</template>
|
||||
</EDropdownMenu>
|
||||
</EDropdown>
|
||||
|
||||
<!--搜索框-->
|
||||
<div v-if="searchShow" class="dialog-search">
|
||||
<div class="search-location">
|
||||
<i class="taskfont" @click="onSearchSwitch('prev')"></i>
|
||||
<i class="taskfont" @click="onSearchSwitch('next')"></i>
|
||||
</div>
|
||||
<div class="search-input">
|
||||
<Input ref="searchInput" v-model="searchKey" :placeholder="$L('搜索消息')" @on-keyup="onSearchKeyup" clearable>
|
||||
<div class="search-pre" slot="prefix">
|
||||
<Loading v-if="searchLoad > 0"/>
|
||||
<Icon v-else type="ios-search" />
|
||||
</div>
|
||||
</Input>
|
||||
<div v-if="searchLoad === 0 && searchResult.length > 0" class="search-total" slot="append">{{searchLocation}}/{{searchResult.length}}</div>
|
||||
</div>
|
||||
<div class="search-cancel" @click="onSearchKeyup(null)">{{$L('取消')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
<!--顶部提示-->
|
||||
<!--跳转提示-->
|
||||
<div v-if="positionMsg" class="dialog-position" :class="{'down': tagShow}">
|
||||
<div class="position-label" @click="onPositionMark">
|
||||
<Icon v-if="positionLoad > 0" type="ios-loading" class="icon-loading"></Icon>
|
||||
@ -523,6 +544,12 @@ export default {
|
||||
pasteFile: [],
|
||||
pasteItem: [],
|
||||
|
||||
searchShow: false,
|
||||
searchKey: '',
|
||||
searchLoad: 0,
|
||||
searchLocation: 1,
|
||||
searchResult: [],
|
||||
|
||||
createGroupShow: false,
|
||||
createGroupData: {},
|
||||
createGroupLoad: 0,
|
||||
@ -759,7 +786,7 @@ export default {
|
||||
},
|
||||
|
||||
tagShow() {
|
||||
return this.msgTags.length > 1 && this.windowScrollY === 0
|
||||
return this.msgTags.length > 1 && this.windowScrollY === 0 && !this.searchShow
|
||||
},
|
||||
|
||||
scrollerClass() {
|
||||
@ -900,6 +927,46 @@ export default {
|
||||
}).catch(_ => {})
|
||||
},
|
||||
|
||||
searchKey(key) {
|
||||
if (!key) {
|
||||
return
|
||||
}
|
||||
this.searchLoad++
|
||||
setTimeout(_ => {
|
||||
if (this.searchKey === key) {
|
||||
this.searchLoad++
|
||||
this.searchResult = []
|
||||
this.searchLocation = 0
|
||||
this.$store.dispatch("call", {
|
||||
url: 'dialog/msg/search',
|
||||
data: {
|
||||
dialog_id: this.dialogId,
|
||||
key,
|
||||
},
|
||||
}).then(({data}) => {
|
||||
if (this.searchKey !== key) {
|
||||
return
|
||||
}
|
||||
this.searchResult = data.data
|
||||
this.searchLocation = this.searchResult.length
|
||||
}).finally(_ => {
|
||||
this.searchLoad--
|
||||
});
|
||||
}
|
||||
this.searchLoad--
|
||||
}, 600)
|
||||
},
|
||||
|
||||
searchLocation(position) {
|
||||
if (position === 0) {
|
||||
return
|
||||
}
|
||||
const id = this.searchResult[position - 1]
|
||||
if (id) {
|
||||
this.onPositionId(id)
|
||||
}
|
||||
},
|
||||
|
||||
dialogSearchMsgId() {
|
||||
this.onSearchMsgId();
|
||||
},
|
||||
@ -1645,6 +1712,13 @@ export default {
|
||||
|
||||
onDialogMenu(cmd) {
|
||||
switch (cmd) {
|
||||
case "searchMsg":
|
||||
this.searchShow = true
|
||||
this.$nextTick(_ => {
|
||||
this.$refs.searchInput.focus()
|
||||
})
|
||||
break;
|
||||
|
||||
case "openCreate":
|
||||
const userids = [this.userId]
|
||||
if (this.dialogData.dialog_user && this.userId != this.dialogData.dialog_user.userid) {
|
||||
@ -2423,6 +2497,37 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
onSearchSwitch(type) {
|
||||
if (this.searchResult.length === 0) {
|
||||
return
|
||||
}
|
||||
if (this.searchLocation === 1 && this.searchResult.length === 1) {
|
||||
this.onPositionId(this.searchResult[0])
|
||||
return
|
||||
}
|
||||
if (type === 'prev') {
|
||||
if (this.searchLocation <= 1) {
|
||||
this.searchLocation = this.searchResult.length
|
||||
} else {
|
||||
this.searchLocation--
|
||||
}
|
||||
} else {
|
||||
if (this.searchLocation >= this.searchResult.length) {
|
||||
this.searchLocation = 1
|
||||
} else {
|
||||
this.searchLocation++
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onSearchKeyup(e) {
|
||||
if (e === null || e.keyCode === 27) {
|
||||
this.searchShow = false
|
||||
this.searchKey = ''
|
||||
this.searchResult = []
|
||||
}
|
||||
},
|
||||
|
||||
onPositionMark() {
|
||||
if (this.positionLoad > 0) {
|
||||
return;
|
||||
|
||||
@ -346,6 +346,70 @@
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dialog-search {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 1px;
|
||||
z-index: 1;
|
||||
background-color: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.search-location {
|
||||
margin-left: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
> i {
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
padding: 0 6px;
|
||||
}
|
||||
}
|
||||
.search-input {
|
||||
flex: 1;
|
||||
margin-left: 12px;
|
||||
border-radius: 12px;
|
||||
background-color: #F7F7F7;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.search-pre {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.common-loading {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.ivu-input {
|
||||
border-color: transparent;
|
||||
background-color: transparent;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.search-total {
|
||||
padding-right: 12px;
|
||||
}
|
||||
}
|
||||
.search-cancel {
|
||||
cursor: pointer;
|
||||
padding: 0 18px;
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user