no message

This commit is contained in:
kuaifan 2022-04-15 13:13:34 +08:00
parent 522ca02b36
commit c6e693392c
7 changed files with 243 additions and 54 deletions

View File

@ -650,6 +650,7 @@ class DialogController extends AbstractController
* @apiName group__user * @apiName group__user
* *
* @apiParam {Number} dialog_id 会话ID * @apiParam {Number} dialog_id 会话ID
* @apiParam {Number} [getuser] 获取会员详情1: 返回会员昵称、邮箱等基本信息0: 默认不返回)
* *
* @apiSuccess {Number} ret 返回状态码1正确、0错误 * @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述) * @apiSuccess {String} msg 返回信息(错误描述)
@ -660,10 +661,22 @@ class DialogController extends AbstractController
User::auth(); User::auth();
// //
$dialog_id = intval(Request::input('dialog_id')); $dialog_id = intval(Request::input('dialog_id'));
$getuser = intval(Request::input('getuser', 0));
// //
$dialog = WebSocketDialog::checkDialog($dialog_id); $dialog = WebSocketDialog::checkDialog($dialog_id);
// //
return Base::retSuccess('success', $dialog->dialogUser); $data = $dialog->dialogUser->toArray();
if ($getuser === 1) {
$array = [];
foreach ($data as $item) {
$res = User::userid2basic($item['userid']);
if ($res) {
$array[] = array_merge($item, $res->toArray());
}
}
$data = $array;
}
return Base::retSuccess('success', $data);
} }
/** /**

View File

@ -4,36 +4,21 @@
</div> </div>
</template> </template>
<style lang="scss">
.chat-input-wrapper {
display: inline-block;
width: 100%;
.ql-editor {
padding: 4px 7px;
font-size: 14px;
max-height: 100px;
&.ql-blank {
&::before {
left: 7px;
right: 7px;
color: #ccc;
font-style: normal;
}
}
}
}
</style>
<script> <script>
import Quill from 'quill'; import Quill from 'quill';
import "quill/dist/quill.snow.css";
import "quill-mention"; import "quill-mention";
import "quill-mention/dist/quill.mention.min.css";
export default { export default {
name: 'ChatInput', name: 'ChatInput',
props: { props: {
dialogId: {
type: Number,
default: 0
},
taskId: {
type: Number,
default: 0
},
value: { value: {
type: [String, Number], type: [String, Number],
default: '' default: ''
@ -52,18 +37,23 @@ export default {
}, },
options: { options: {
type: Object, type: Object,
required: false,
default: () => ({}) default: () => ({})
}, },
maxlength: { maxlength: {
type: Number type: Number
}, },
defaultMenuOrientation: {
type: String,
default: "top"
},
}, },
data() { data() {
return { return {
quill: null, quill: null,
_content: '', _content: '',
_options: {}, _options: {},
userList: null,
}; };
}, },
mounted() { mounted() {
@ -85,24 +75,24 @@ export default {
} }
} }
}, },
// Watch disabled change // Watch disabled change
disabled(newVal) { disabled(newVal) {
if (this.quill) { if (this.quill) {
this.quill.enable(!newVal) this.quill.enable(!newVal)
} }
} },
// Reset userList
dialogId() {
this.userList = null;
},
taskId() {
this.userList = null;
},
}, },
methods: { methods: {
init() { init() {
const atValues = [
{ id: 1, value: "Fredrik Sundqvist" },
{ id: 2, value: "Patrik Sjölin" }
];
const hashValues = [
{ id: 3, value: "Fredrik Sundqvist 2" },
{ id: 4, value: "Patrik Sjölin 2" }
];
// Options // Options
this._options = Object.assign({ this._options = Object.assign({
theme: null, theme: null,
@ -137,26 +127,36 @@ export default {
}, },
mention: { mention: {
mentionDenotationChars: ["@", "#"], mentionDenotationChars: ["@", "#"],
source: function(searchTerm, renderList, mentionChar) { defaultMenuOrientation: this.defaultMenuOrientation,
let values; renderItem: (data) => {
if (data.disabled === true) {
if (mentionChar === "@") { return `<div class="mention-item-disabled">${data.value}</div>`;
values = atValues;
} else {
values = hashValues;
} }
if (data.id === 0) {
if (searchTerm.length === 0) { return `<div class="mention-item-at">@</div><div class="mention-item-name">${data.value}</div><div class="mention-item-tip">${this.$L('提示所有成员')}</div>`;
renderList(values, searchTerm);
} else {
const matches = [];
for (let i = 0; i < values.length; i++)
if (
~values[i].value.toLowerCase().indexOf(searchTerm.toLowerCase())
)
matches.push(values[i]);
renderList(matches, searchTerm);
} }
if (data.avatar) {
return `<div class="mention-item-img${data.online ? ' online' : ''}"><img src="${data.avatar}"/><em></em></div><div class="mention-item-name">${data.value}</div>`;
}
return `<div class="mention-item-name">${data.value}</div>`;
},
renderLoading: () => {
return "Loading...";
},
source: (searchTerm, renderList, mentionChar) => {
this.getSource(mentionChar).then(values => {
if (searchTerm.length === 0) {
renderList(values, searchTerm);
} else {
const matches = [];
for (let i = 0; i < values.length; i++) {
if (~values[i].value.toLowerCase().indexOf(searchTerm.toLowerCase())) {
matches.push(values[i]);
}
}
renderList(matches, searchTerm);
}
})
} }
} }
} }
@ -213,6 +213,61 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.quill && this.quill.blur() this.quill && this.quill.blur()
}) })
},
getSource(mentionChar) {
return new Promise(resolve => {
switch (mentionChar) {
case "@": // @
if (this.userList !== null) {
resolve(this.userList)
return;
}
if (this.dialogId > 0) {
// ID
this.$store.dispatch("call", {
url: 'dialog/group/user',
data: {
dialog_id: this.dialogId,
getuser: 1
}
}).then(({data}) => {
if (data.length > 0) {
this.userList = [
{ id: 0, value: this.$L('所有人') },
{ id: 0, value: this.$L('会话内成员'), disabled: true },
];
this.userList.push(...data.map(item => {
return {
id: item.userid,
value: item.nickname,
avatar: item.userimg,
online: item.online,
}
}))
} else {
this.userList = [];
}
resolve(this.userList)
}).catch(_ => {
resolve([]);
});
return;
} else if (this.taskId > 0) {
// ID todo
return;
}
break;
case "#": // # todo
resolve([
{ id: 3, value: "Fredrik Sundqvist 2" },
{ id: 4, value: "Patrik Sjölin 2" }
])
break;
}
resolve([])
})
} }
} }
} }

View File

@ -86,6 +86,7 @@
<ChatInput <ChatInput
ref="input" ref="input"
class="dialog-input" class="dialog-input"
:dialog-id="dialogId"
v-model="msgText" v-model="msgText"
:maxlength="20000" :maxlength="20000"
@on-focus="onEventFocus" @on-focus="onEventFocus"

View File

@ -400,6 +400,7 @@
<div class="no-input"> <div class="no-input">
<ChatInput <ChatInput
class="dialog-input" class="dialog-input"
:task-id="taskId"
v-model="msgText" v-model="msgText"
:disabled="sendLoad > 0" :disabled="sendLoad > 0"
:maxlength="20000" :maxlength="20000"

View File

@ -1,4 +1,5 @@
@import "auto-tip"; @import "auto-tip";
@import "chat-input";
@import "circle"; @import "circle";
@import "drawer-overlay"; @import "drawer-overlay";
@import "img-update"; @import "img-update";

View File

@ -0,0 +1,108 @@
@import "~quill/dist/quill.snow.css";
@import "~quill-mention/dist/quill.mention.min.css";
.chat-input-wrapper {
display: inline-block;
width: 100%;
.ql-editor {
padding: 4px 7px;
font-size: 14px;
max-height: 200px;
img {
max-width: 150px;
max-height: 150px;
}
&.ql-blank {
&::before {
left: 7px;
right: 7px;
color: #ccc;
font-style: normal;
}
}
}
.ql-mention-list-container {
width: auto;
min-width: 200px;
max-width: 300px;
max-height: 500px;
.ql-mention-list-item {
padding: 0 12px;
display: flex;
align-items: center;
.mention-item-at {
width: 28px;
height: 28px;
line-height: 28px;
border-radius: 50%;
text-align: center;
color: #ffffff;
background-color: #8bcf70;
overflow: hidden;
}
.mention-item-img {
position: relative;
display: flex;
align-items: center;
justify-content: center;
> img {
width: 28px;
height: 28px;
border-radius: 50%;
overflow: hidden;
}
> em {
position: absolute;
right: 0;
bottom: 0;
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #ff9900;
border: 1px solid #ffffff;
transform-origin: right bottom;
z-index: 1;
}
&.online {
> em {
background-color: $primary-color;
}
}
}
.mention-item-name {
padding: 0 8px;
font-size: 14px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.mention-item-tip {
color: #8f8f8e;
font-size: 12px;
font-style: normal;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.mention-item-disabled {
color: #8f8f8e;
font-size: 12px;
padding: 0 4px;
line-height: 40px;
}
}
}
}

View File

@ -196,13 +196,23 @@ body.dark-mode-reverse {
> ul { > ul {
> li { > li {
.user-tag { .user-tag {
color: $primary-title-color; color: #1c1917;
} }
} }
} }
} }
} }
.chat-input-wrapper {
.ql-mention-list-container {
.ql-mention-list-item {
.mention-item-at {
color: #1c1917;
}
}
}
}
.file-icon { .file-icon {
&:before { &:before {
background-image: url("../images/file/dark/other.svg"); background-image: url("../images/file/dark/other.svg");