feat: 支持发送匿名消息

This commit is contained in:
kuaifan 2023-03-05 18:18:57 +08:00
parent 5d5b1000fe
commit aa781a51df
8 changed files with 279 additions and 134 deletions

View File

@ -909,6 +909,59 @@ class DialogController extends AbstractController
});
}
/**
* @api {post} api/dialog/msg/sendanon 16. 发送匿名消息
*
* @apiDescription 需要token身份
* @apiVersion 1.0.0
* @apiGroup dialog
* @apiName msg__sendanon
*
* @apiParam {Number} userid 对方会员ID
* @apiParam {String} text 消息内容
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function msg__sendanon()
{
User::auth();
//
$userid = Base::getPostInt('userid');
$text = trim(Base::getPostValue('text'));
//
$anonMessage = Base::settingFind('system', 'anon_message', 'open');
if ($anonMessage != 'open') {
return Base::retError("匿名消息功能暂停使用");
}
//
$toUser = User::whereUserid($userid)->first();
if (empty($toUser) || $toUser->bot) {
return Base::retError("匿名消息仅允许发送给个人");
}
if ($toUser->isDisable()) {
return Base::retError("对方已离职");
}
$strlen = mb_strlen($text);
if ($strlen < 1) {
return Base::retError('消息内容不能为空');
}
if ($strlen > 2000) {
return Base::retError('消息内容最大不能超过2000字');
}
//
$botUser = User::botGetOrCreate('anon-msg');
if (empty($botUser)) {
return Base::retError('匿名机器人不存在');
}
$dialog = WebSocketDialog::checkUserDialog($botUser, $toUser->userid);
if (empty($dialog)) {
return Base::retError('匿名机器人会话不存在');
}
return WebSocketDialogMsg::sendMsg(null, $dialog->id, 'text', ['text' => "<p>{$text}</p>"], $botUser->userid);
}
/**
* @api {get} api/dialog/msg/readlist 17. 获取消息阅读情况
*

View File

@ -41,7 +41,7 @@ class SystemController extends AbstractController
* @apiParam {String} type
* - get: 获取(默认)
* - all: 获取所有(需要管理员权限)
* - save: 保存设置(参数:['reg', 'reg_identity', 'reg_invite', 'login_code', 'password_policy', 'project_invite', 'chat_information', 'auto_archived', 'archived_day', 'all_group_mute', 'all_group_autoin', 'start_home', 'home_footer']
* - save: 保存设置(参数:['reg', 'reg_identity', 'reg_invite', 'login_code', 'password_policy', 'project_invite', 'chat_information', 'anon_message', 'auto_archived', 'archived_day', 'all_group_mute', 'all_group_autoin', 'start_home', 'home_footer']
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
@ -65,6 +65,7 @@ class SystemController extends AbstractController
'password_policy',
'project_invite',
'chat_information',
'anon_message',
'auto_archived',
'archived_day',
'all_group_mute',
@ -101,6 +102,7 @@ class SystemController extends AbstractController
$setting['password_policy'] = $setting['password_policy'] ?: 'simple';
$setting['project_invite'] = $setting['project_invite'] ?: 'open';
$setting['chat_information'] = $setting['chat_information'] ?: 'optional';
$setting['anon_message'] = $setting['anon_message'] ?: 'open';
$setting['auto_archived'] = $setting['auto_archived'] ?: 'close';
$setting['archived_day'] = floatval($setting['archived_day']) ?: 7;
$setting['all_group_mute'] = $setting['all_group_mute'] ?: 'open';

View File

@ -42,6 +42,9 @@ class VerifyCsrfToken extends Middleware
// 聊天发文件
'api/dialog/msg/sendfile/',
// 聊天发匿名消息
'api/dialog/msg/sendanon/',
// 保存文件内容
'api/file/content/save/',

View File

@ -179,6 +179,15 @@ class User extends AbstractModel
return in_array('temp', $this->identity);
}
/**
* 返回是否禁用帐号(离职)
* @return bool
*/
public function isDisable()
{
return in_array('disable', $this->identity);
}
/**
* 返回是否管理员
* @return bool
@ -575,13 +584,16 @@ class User extends AbstractModel
return Base::fillUrl($userimg);
}
// 机器人头像
if ($email == 'system-msg@bot.system') {
switch ($email) {
case 'system-msg@bot.system':
return url("images/avatar/default_system.png");
} elseif ($email == 'task-alert@bot.system') {
case 'task-alert@bot.system':
return url("images/avatar/default_task.png");
} elseif ($email == 'check-in@bot.system') {
case 'check-in@bot.system':
return url("images/avatar/default_checkin.png");
} elseif ($email == 'bot-manager@bot.system') {
case 'anon-msg@bot.system':
return url("images/avatar/default_anon.png");
case 'bot-manager@bot.system':
return url("images/avatar/default_bot.png");
}
// 生成文字头像
@ -652,14 +664,22 @@ class User extends AbstractModel
])->save();
}
//
if ($key === 'system-msg') {
switch ($key) {
case 'system-msg':
$update['nickname'] = '系统消息';
} elseif ($key === 'task-alert') {
break;
case 'task-alert':
$update['nickname'] = '任务提醒';
} elseif ($key === 'check-in') {
break;
case 'check-in':
$update['nickname'] = '签到打卡';
} elseif ($key === 'bot-manager') {
break;
case 'anon-msg':
$update['nickname'] = '匿名消息';
break;
case 'bot-manager':
$update['nickname'] = '机器人管理';
break;
}
}
if ($update) {

View File

@ -80,10 +80,6 @@
<i class="taskfont">&#xe7c1;</i>
{{$L('新会议')}}
</div>
<div v-if="dialogData.type === 'user' && $isEEUiApp" class="chat-input-popover-item" @click="onToolbar('call')">
<i class="taskfont">&#xe7ba;</i>
{{$L('拨打电话')}}
</div>
<div class="chat-input-popover-item" @click="onToolbar('image')">
<i class="taskfont">&#xe7bc;</i>
{{$L('发送图片')}}
@ -92,6 +88,16 @@
<i class="taskfont">&#xe7c0;</i>
{{$L('上传文件')}}
</div>
<template v-if="dialogData.type === 'user' && !dialogData.bot">
<div v-if="$isEEUiApp" class="chat-input-popover-item" @click="onToolbar('call')">
<i class="taskfont">&#xe7ba;</i>
{{$L('拨打电话')}}
</div>
<div class="chat-input-popover-item" @click="onToolbar('anon')">
<i class="taskfont">&#xe690;</i>
{{$L('匿名消息')}}
</div>
</template>
</EPopover>
</li>
@ -994,9 +1000,10 @@ export default {
});
break;
case 'call':
case 'image':
case 'file':
case 'call':
case 'anon':
this.$emit('on-more', action)
break;
}

View File

@ -1434,14 +1434,17 @@ export default {
onEventMore(e) {
switch (e) {
case 'call':
this.onCallTel()
break;
case 'image':
case 'file':
this.$refs.chatUpload.handleClick()
break;
case 'call':
this.onCallTel()
break;
case 'anon':
this.onAnon()
break;
}
},
@ -1469,6 +1472,43 @@ export default {
});
},
onAnon() {
if (this.dialogData.type !== 'user' || this.dialogData.bot) {
$A.modalWarning("匿名消息仅允许发送给个人");
return
}
$A.modalInput({
title: `发送匿名消息`,
placeholder: `匿名消息将通过匿名机器人发送给对方,绝对不会暴露你的身份`,
inputProps: {
type: 'textarea',
rows: 3,
autosize: { minRows: 3, maxRows: 6 },
maxlength: 2000,
},
okText: "匿名发送",
onOk: (value) => {
if (!value) {
return `请输入消息内容`
}
return new Promise((resolve, reject) => {
this.$store.dispatch("call", {
url: 'dialog/msg/sendanon',
data: {
userid: this.dialogData.dialog_user.userid,
text: value,
},
method: 'post',
}).then(({msg}) => {
resolve(msg)
}).catch(({msg}) => {
reject(msg)
});
})
}
});
},
onEventEmojiVisibleChange(val) {
if (val && this.windowSmall) {
this.onToBottom();

View File

@ -1,6 +1,8 @@
<template>
<div class="setting-component-item">
<Form ref="formDatum" :model="formDatum" label-width="auto" @submit.native.prevent>
<div class="block-setting-box">
<h3>{{ $L('帐号相关') }}</h3>
<FormItem :label="$L('允许注册')" prop="reg">
<RadioGroup v-model="formDatum.reg">
<Radio label="open">{{$L('允许')}}</Radio>
@ -48,6 +50,9 @@
<div v-if="formDatum.password_policy == 'simple'" class="form-tip">{{$L('简单大于或等于6个字符')}}</div>
<div v-else-if="formDatum.password_policy == 'complex'" class="form-tip">{{$L('复杂大于或等于6个字符包含数字、字母大小写或者特殊字符。')}}</div>
</FormItem>
</div>
<div class="block-setting-box">
<h3>{{ $L('项目相关') }}</h3>
<FormItem :label="$L('邀请项目')" prop="projectInvite">
<RadioGroup v-model="formDatum.project_invite">
<Radio label="open">{{$L('开启')}}</Radio>
@ -55,14 +60,6 @@
</RadioGroup>
<div v-if="formDatum.project_invite == 'open'" class="form-tip">{{$L('开启项目管理员可生成链接邀请成员加入项目')}}</div>
</FormItem>
<FormItem :label="$L('聊天资料')" prop="chatInformation">
<RadioGroup v-model="formDatum.chat_information">
<Radio label="optional">{{$L('可选')}}</Radio>
<Radio label="required">{{$L('必填')}}</Radio>
</RadioGroup>
<div v-if="formDatum.chat_information == 'required'" class="form-tip">{{$L('必填发送聊天内容前必须设置昵称电话')}}</div>
<div v-else class="form-tip">{{$L('如果必填,发送聊天前必须设置昵称、电话。')}}</div>
</FormItem>
<FormItem :label="$L('自动归档任务')" prop="autoArchived">
<RadioGroup :value="formDatum.auto_archived" @on-change="formArchived">
<Radio label="open">{{$L('开启')}}</Radio>
@ -78,6 +75,9 @@
<div slot="content">{{$L('任务完成 (*) 天后自动归档。', formDatum.archived_day)}}</div>
</ETooltip>
</FormItem>
</div>
<div class="block-setting-box">
<h3>{{ $L('消息相关') }}</h3>
<FormItem :label="$L('全员群组禁言')" prop="allGroupMute">
<RadioGroup v-model="formDatum.all_group_mute">
<Radio label="open">{{$L('开放')}}</Radio>
@ -96,6 +96,25 @@
<div v-if="formDatum.all_group_autoin == 'yes'" class="form-tip">{{$L('自动注册成功后自动进入全员群')}}</div>
<div v-else-if="formDatum.all_group_autoin == 'no'" class="form-tip">{{$L('关闭:其他成员通过@邀请进入。')}}</div>
</FormItem>
<FormItem :label="$L('聊天资料')" prop="chatInformation">
<RadioGroup v-model="formDatum.chat_information">
<Radio label="optional">{{$L('可选')}}</Radio>
<Radio label="required">{{$L('必填')}}</Radio>
</RadioGroup>
<div v-if="formDatum.chat_information == 'required'" class="form-tip">{{$L('必填发送聊天内容前必须设置昵称电话')}}</div>
<div v-else class="form-tip">{{$L('如果必填,发送聊天前必须设置昵称、电话。')}}</div>
</FormItem>
<FormItem :label="$L('匿名消息')" prop="anonMessage">
<RadioGroup v-model="formDatum.anon_message">
<Radio label="open">{{$L('开启')}}</Radio>
<Radio label="close">{{$L('关闭')}}</Radio>
</RadioGroup>
<div v-if="formDatum.anon_message == 'open'" class="form-tip">{{$L('允许匿名发送消息给其他成员')}}</div>
<div v-else class="form-tip">{{$L('禁止匿名发送消息。')}}</div>
</FormItem>
</div>
<div class="block-setting-box">
<h3>{{ $L('其他设置') }}</h3>
<FormItem :label="$L('是否启动首页')" prop="startHome">
<RadioGroup v-model="formDatum.start_home">
<Radio label="open">{{$L('开启')}}</Radio>
@ -111,6 +130,7 @@
:autosize="{ minRows: 2, maxRows: 8 }"
:placeholder="$L('首页底部:首页底部网站备案号等信息')"/>
</FormItem>
</div>
</Form>
<div class="setting-footer">
<Button :loading="loadIng > 0" type="primary" @click="submitForm">{{$L('提交')}}</Button>

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB