diff --git a/app/Http/Controllers/Api/DialogController.php b/app/Http/Controllers/Api/DialogController.php index 69f2f1431..e1350d045 100755 --- a/app/Http/Controllers/Api/DialogController.php +++ b/app/Http/Controllers/Api/DialogController.php @@ -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. 获取单条消息 * diff --git a/resources/assets/js/pages/manage/components/DialogWrapper.vue b/resources/assets/js/pages/manage/components/DialogWrapper.vue index 4dd194fef..f68867753 100644 --- a/resources/assets/js/pages/manage/components/DialogWrapper.vue +++ b/resources/assets/js/pages/manage/components/DialogWrapper.vue @@ -74,6 +74,9 @@ @command="onDialogMenu"> + +
{{$L('搜索消息')}}
+
{{$L('创建群组')}}
@@ -103,11 +106,29 @@
+ + + - +
@@ -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; diff --git a/resources/assets/sass/pages/components/dialog-wrapper.scss b/resources/assets/sass/pages/components/dialog-wrapper.scss index 4e09791e3..e3a0cf0c3 100644 --- a/resources/assets/sass/pages/components/dialog-wrapper.scss +++ b/resources/assets/sass/pages/components/dialog-wrapper.scss @@ -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; + } + } } }