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;
+ }
+ }
}
}