feat: 新增转发至AI开启新会话

This commit is contained in:
kuaifan 2025-04-07 01:20:58 +08:00
parent d144b06c1f
commit c5948c4171
3 changed files with 110 additions and 40 deletions

View File

@ -3183,6 +3183,7 @@ class DialogController extends AbstractController
* @apiName session_create
*
* @apiParam {Number} dialog_id 对话ID
* @apiParam {Number} [userid] 用户ID dialog_id 二选一userid 优先)
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
@ -3190,11 +3191,16 @@ class DialogController extends AbstractController
*/
public function session__create()
{
User::auth();
$user = User::auth();
//
$dialog_id = intval(Request::input('dialog_id'));
$userid = intval(Request::input('userid'));
//
$dialog = WebSocketDialog::checkDialog($dialog_id);
if ($userid) {
$dialog = WebSocketDialog::checkUserDialog($user, $userid);
} else {
$dialog = WebSocketDialog::checkDialog($dialog_id);
}
//
if ($dialog->type != 'user') {
return Base::retError('当前对话不支持');
@ -3208,9 +3214,7 @@ class DialogController extends AbstractController
return Base::retError('当前对话不支持');
}
//
$session = WebSocketDialogSession::whereDialogId($dialog->id)
->whereTitle('')
->first();
$session = WebSocketDialogSession::whereDialogId($dialog->id)->whereTitle('')->first();
if ($session) {
$dialog->session_id = $session->id;
$dialog->save();

View File

@ -61,13 +61,19 @@
:disabled="loading"
clearable/>
</div>
<ul class="radio-group">
<li v-if="aiUser.length > 0" :class="{selected: ainew}">
<Icon @click="onAinew" class="radio-icon" :type="ainew ? 'ios-checkmark-circle' : 'ios-radio-button-off'"/>
<span class="radio-label">{{ $L('AI开启新会话') }}</span>
</li>
<li v-if="!senderHidden" :class="{selected: !sender}">
<Icon @click="onSender" class="radio-icon" :type="sender ? 'ios-radio-button-off' : 'ios-checkmark-circle'"/>
<span class="radio-label">{{ $L('不显示原发送者信息') }}</span>
</li>
</ul>
</div>
</div>
<template #footer>
<div v-if="!senderHidden" class="forwarder-wrapper-footer" :class="{selected: !sender}" @click="onSender">
<Icon class="user-modal-icon" :type="sender ? 'ios-radio-button-off' : 'ios-checkmark-circle'" />
<span class="forward-text-tip">{{$L('不显示原发送者信息')}}</span>
</div>
<Button type="primary" :loading="loading" @click="onSubmit">
{{$L('确定')}}
<template v-if="forwardTo.length > 0">({{forwardTo.length}})</template>
@ -79,6 +85,7 @@
<script>
import DialogItem from "../DialogItem.vue";
import ChatInput from "../ChatInput/index.vue";
import {mapState} from "vuex";
export default {
components: {ChatInput, DialogItem},
@ -128,12 +135,21 @@ export default {
loading: false,
message: '', //
sender: true, //
ainew: true, // AI
sender: true, //
}
},
computed: {
...mapState(['cacheUserBasic']),
aiUser({forwardTo, cacheUserBasic}) {
const users = forwardTo.filter(item => item.type !== 'group');
return users.filter(user => {
const cachedUser = cacheUserBasic.find(item => item.userid === user.userid);
return cachedUser && cachedUser.bot && /^ai-(.*?)@bot\.system/.test(cachedUser.email);
});
}
},
watch: {
@ -145,6 +161,7 @@ export default {
if (!val) {
this.loading = false;
this.message = '';
this.ainew = true;
this.sender = true;
}
}
@ -167,6 +184,13 @@ export default {
this.$emit('on-other', ...args);
},
onAinew() {
if (this.loading) {
return
}
this.ainew = !this.ainew
},
onSender() {
if (this.loading) {
return
@ -174,7 +198,7 @@ export default {
this.sender = !this.sender
},
onSubmit() {
async onSubmit() {
if (this.loading) {
return
}
@ -188,9 +212,17 @@ export default {
if (!this.senderHidden) {
data.sender = this.sender
}
//
this.loading = true
try {
await this.onAiNew()
} catch (e) {
this.loading = false
return
}
//
const before = this.beforeSubmit(data);
if (before && before.then) {
this.loading = true
before.then(() => {
this.hide()
}).catch(_ => {
@ -199,10 +231,41 @@ export default {
this.loading = false
})
} else {
this.loading = false
this.hide()
}
},
onAiNew() {
return new Promise((resolve, reject) => {
if (this.aiUser.length === 0 || !this.ainew) {
return resolve();
}
const processQueue = async () => {
try {
for (const user of this.aiUser) {
await this.$store.dispatch("call", {
url: 'dialog/session/create',
data: {
userid: user.userid,
},
});
}
resolve();
} catch (error) {
$A.modalError({
language: false,
content: this.$L("AI开启新会话失败") + `: ${error.msg || error}`,
});
reject(error);
}
};
processQueue();
});
},
hide() {
this.show = false
}

View File

@ -88,39 +88,42 @@
background: #f7f7f7;
}
}
}
}
}
.ivu-modal-footer {
display: flex;
justify-content: flex-end;
gap: 20px;
.radio-group {
z-index: 2;
display: flex;
flex-direction: column;
.forwarder-wrapper-footer {
flex: 1;
width: 0;
display: flex;
line-height: 34px;
cursor: pointer;
> li {
display: flex;
align-items: center;
line-height: 22px;
margin-bottom: 8px;
.user-modal-icon {
flex-shrink: 0;
font-size: 22px;
margin-right: 5px;
color: rgba($primary-desc-color, 0.7);
margin-top: 6px;
}
.radio-icon {
flex-shrink: 0;
font-size: 22px;
color: rgba($primary-desc-color, 0.7);
cursor: pointer;
}
.forward-text-tip {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.radio-label {
padding-left: 6px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&.selected {
.user-modal-icon {
color: $primary-color;
&.selected {
.radio-icon {
color: $primary-color;
}
}
&:last-child {
margin-bottom: 16px;
}
}
}
}
}