mirror of
https://github.com/kuaifan/dootask.git
synced 2026-03-17 19:23:26 +00:00
feat: 支持发送匿名消息
This commit is contained in:
parent
5d5b1000fe
commit
aa781a51df
@ -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. 获取消息阅读情况
|
* @api {get} api/dialog/msg/readlist 17. 获取消息阅读情况
|
||||||
*
|
*
|
||||||
|
|||||||
@ -41,7 +41,7 @@ class SystemController extends AbstractController
|
|||||||
* @apiParam {String} type
|
* @apiParam {String} type
|
||||||
* - get: 获取(默认)
|
* - get: 获取(默认)
|
||||||
* - all: 获取所有(需要管理员权限)
|
* - 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 {Number} ret 返回状态码(1正确、0错误)
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||||
@ -65,6 +65,7 @@ class SystemController extends AbstractController
|
|||||||
'password_policy',
|
'password_policy',
|
||||||
'project_invite',
|
'project_invite',
|
||||||
'chat_information',
|
'chat_information',
|
||||||
|
'anon_message',
|
||||||
'auto_archived',
|
'auto_archived',
|
||||||
'archived_day',
|
'archived_day',
|
||||||
'all_group_mute',
|
'all_group_mute',
|
||||||
@ -101,6 +102,7 @@ class SystemController extends AbstractController
|
|||||||
$setting['password_policy'] = $setting['password_policy'] ?: 'simple';
|
$setting['password_policy'] = $setting['password_policy'] ?: 'simple';
|
||||||
$setting['project_invite'] = $setting['project_invite'] ?: 'open';
|
$setting['project_invite'] = $setting['project_invite'] ?: 'open';
|
||||||
$setting['chat_information'] = $setting['chat_information'] ?: 'optional';
|
$setting['chat_information'] = $setting['chat_information'] ?: 'optional';
|
||||||
|
$setting['anon_message'] = $setting['anon_message'] ?: 'open';
|
||||||
$setting['auto_archived'] = $setting['auto_archived'] ?: 'close';
|
$setting['auto_archived'] = $setting['auto_archived'] ?: 'close';
|
||||||
$setting['archived_day'] = floatval($setting['archived_day']) ?: 7;
|
$setting['archived_day'] = floatval($setting['archived_day']) ?: 7;
|
||||||
$setting['all_group_mute'] = $setting['all_group_mute'] ?: 'open';
|
$setting['all_group_mute'] = $setting['all_group_mute'] ?: 'open';
|
||||||
|
|||||||
@ -42,6 +42,9 @@ class VerifyCsrfToken extends Middleware
|
|||||||
// 聊天发文件
|
// 聊天发文件
|
||||||
'api/dialog/msg/sendfile/',
|
'api/dialog/msg/sendfile/',
|
||||||
|
|
||||||
|
// 聊天发匿名消息
|
||||||
|
'api/dialog/msg/sendanon/',
|
||||||
|
|
||||||
// 保存文件内容
|
// 保存文件内容
|
||||||
'api/file/content/save/',
|
'api/file/content/save/',
|
||||||
|
|
||||||
|
|||||||
@ -179,6 +179,15 @@ class User extends AbstractModel
|
|||||||
return in_array('temp', $this->identity);
|
return in_array('temp', $this->identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回是否禁用帐号(离职)
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isDisable()
|
||||||
|
{
|
||||||
|
return in_array('disable', $this->identity);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回是否管理员
|
* 返回是否管理员
|
||||||
* @return bool
|
* @return bool
|
||||||
@ -575,13 +584,16 @@ class User extends AbstractModel
|
|||||||
return Base::fillUrl($userimg);
|
return Base::fillUrl($userimg);
|
||||||
}
|
}
|
||||||
// 机器人头像
|
// 机器人头像
|
||||||
if ($email == 'system-msg@bot.system') {
|
switch ($email) {
|
||||||
|
case 'system-msg@bot.system':
|
||||||
return url("images/avatar/default_system.png");
|
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");
|
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");
|
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");
|
return url("images/avatar/default_bot.png");
|
||||||
}
|
}
|
||||||
// 生成文字头像
|
// 生成文字头像
|
||||||
@ -652,14 +664,22 @@ class User extends AbstractModel
|
|||||||
])->save();
|
])->save();
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
if ($key === 'system-msg') {
|
switch ($key) {
|
||||||
|
case 'system-msg':
|
||||||
$update['nickname'] = '系统消息';
|
$update['nickname'] = '系统消息';
|
||||||
} elseif ($key === 'task-alert') {
|
break;
|
||||||
|
case 'task-alert':
|
||||||
$update['nickname'] = '任务提醒';
|
$update['nickname'] = '任务提醒';
|
||||||
} elseif ($key === 'check-in') {
|
break;
|
||||||
|
case 'check-in':
|
||||||
$update['nickname'] = '签到打卡';
|
$update['nickname'] = '签到打卡';
|
||||||
} elseif ($key === 'bot-manager') {
|
break;
|
||||||
|
case 'anon-msg':
|
||||||
|
$update['nickname'] = '匿名消息';
|
||||||
|
break;
|
||||||
|
case 'bot-manager':
|
||||||
$update['nickname'] = '机器人管理';
|
$update['nickname'] = '机器人管理';
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($update) {
|
if ($update) {
|
||||||
|
|||||||
@ -80,10 +80,6 @@
|
|||||||
<i class="taskfont"></i>
|
<i class="taskfont"></i>
|
||||||
{{$L('新会议')}}
|
{{$L('新会议')}}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="dialogData.type === 'user' && $isEEUiApp" class="chat-input-popover-item" @click="onToolbar('call')">
|
|
||||||
<i class="taskfont"></i>
|
|
||||||
{{$L('拨打电话')}}
|
|
||||||
</div>
|
|
||||||
<div class="chat-input-popover-item" @click="onToolbar('image')">
|
<div class="chat-input-popover-item" @click="onToolbar('image')">
|
||||||
<i class="taskfont"></i>
|
<i class="taskfont"></i>
|
||||||
{{$L('发送图片')}}
|
{{$L('发送图片')}}
|
||||||
@ -92,6 +88,16 @@
|
|||||||
<i class="taskfont"></i>
|
<i class="taskfont"></i>
|
||||||
{{$L('上传文件')}}
|
{{$L('上传文件')}}
|
||||||
</div>
|
</div>
|
||||||
|
<template v-if="dialogData.type === 'user' && !dialogData.bot">
|
||||||
|
<div v-if="$isEEUiApp" class="chat-input-popover-item" @click="onToolbar('call')">
|
||||||
|
<i class="taskfont"></i>
|
||||||
|
{{$L('拨打电话')}}
|
||||||
|
</div>
|
||||||
|
<div class="chat-input-popover-item" @click="onToolbar('anon')">
|
||||||
|
<i class="taskfont"></i>
|
||||||
|
{{$L('匿名消息')}}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</EPopover>
|
</EPopover>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@ -994,9 +1000,10 @@ export default {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'call':
|
|
||||||
case 'image':
|
case 'image':
|
||||||
case 'file':
|
case 'file':
|
||||||
|
case 'call':
|
||||||
|
case 'anon':
|
||||||
this.$emit('on-more', action)
|
this.$emit('on-more', action)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1434,14 +1434,17 @@ export default {
|
|||||||
|
|
||||||
onEventMore(e) {
|
onEventMore(e) {
|
||||||
switch (e) {
|
switch (e) {
|
||||||
case 'call':
|
|
||||||
this.onCallTel()
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'image':
|
case 'image':
|
||||||
case 'file':
|
case 'file':
|
||||||
this.$refs.chatUpload.handleClick()
|
this.$refs.chatUpload.handleClick()
|
||||||
break;
|
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) {
|
onEventEmojiVisibleChange(val) {
|
||||||
if (val && this.windowSmall) {
|
if (val && this.windowSmall) {
|
||||||
this.onToBottom();
|
this.onToBottom();
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="setting-component-item">
|
<div class="setting-component-item">
|
||||||
<Form ref="formDatum" :model="formDatum" label-width="auto" @submit.native.prevent>
|
<Form ref="formDatum" :model="formDatum" label-width="auto" @submit.native.prevent>
|
||||||
|
<div class="block-setting-box">
|
||||||
|
<h3>{{ $L('帐号相关') }}</h3>
|
||||||
<FormItem :label="$L('允许注册')" prop="reg">
|
<FormItem :label="$L('允许注册')" prop="reg">
|
||||||
<RadioGroup v-model="formDatum.reg">
|
<RadioGroup v-model="formDatum.reg">
|
||||||
<Radio label="open">{{$L('允许')}}</Radio>
|
<Radio label="open">{{$L('允许')}}</Radio>
|
||||||
@ -48,6 +50,9 @@
|
|||||||
<div v-if="formDatum.password_policy == 'simple'" class="form-tip">{{$L('简单:大于或等于6个字符。')}}</div>
|
<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>
|
<div v-else-if="formDatum.password_policy == 'complex'" class="form-tip">{{$L('复杂:大于或等于6个字符,包含数字、字母大小写或者特殊字符。')}}</div>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
</div>
|
||||||
|
<div class="block-setting-box">
|
||||||
|
<h3>{{ $L('项目相关') }}</h3>
|
||||||
<FormItem :label="$L('邀请项目')" prop="projectInvite">
|
<FormItem :label="$L('邀请项目')" prop="projectInvite">
|
||||||
<RadioGroup v-model="formDatum.project_invite">
|
<RadioGroup v-model="formDatum.project_invite">
|
||||||
<Radio label="open">{{$L('开启')}}</Radio>
|
<Radio label="open">{{$L('开启')}}</Radio>
|
||||||
@ -55,14 +60,6 @@
|
|||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
<div v-if="formDatum.project_invite == 'open'" class="form-tip">{{$L('开启:项目管理员可生成链接邀请成员加入项目。')}}</div>
|
<div v-if="formDatum.project_invite == 'open'" class="form-tip">{{$L('开启:项目管理员可生成链接邀请成员加入项目。')}}</div>
|
||||||
</FormItem>
|
</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">
|
<FormItem :label="$L('自动归档任务')" prop="autoArchived">
|
||||||
<RadioGroup :value="formDatum.auto_archived" @on-change="formArchived">
|
<RadioGroup :value="formDatum.auto_archived" @on-change="formArchived">
|
||||||
<Radio label="open">{{$L('开启')}}</Radio>
|
<Radio label="open">{{$L('开启')}}</Radio>
|
||||||
@ -78,6 +75,9 @@
|
|||||||
<div slot="content">{{$L('任务完成 (*) 天后自动归档。', formDatum.archived_day)}}</div>
|
<div slot="content">{{$L('任务完成 (*) 天后自动归档。', formDatum.archived_day)}}</div>
|
||||||
</ETooltip>
|
</ETooltip>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
</div>
|
||||||
|
<div class="block-setting-box">
|
||||||
|
<h3>{{ $L('消息相关') }}</h3>
|
||||||
<FormItem :label="$L('全员群组禁言')" prop="allGroupMute">
|
<FormItem :label="$L('全员群组禁言')" prop="allGroupMute">
|
||||||
<RadioGroup v-model="formDatum.all_group_mute">
|
<RadioGroup v-model="formDatum.all_group_mute">
|
||||||
<Radio label="open">{{$L('开放')}}</Radio>
|
<Radio label="open">{{$L('开放')}}</Radio>
|
||||||
@ -96,6 +96,25 @@
|
|||||||
<div v-if="formDatum.all_group_autoin == 'yes'" class="form-tip">{{$L('自动:注册成功后自动进入全员群。')}}</div>
|
<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>
|
<div v-else-if="formDatum.all_group_autoin == 'no'" class="form-tip">{{$L('关闭:其他成员通过@邀请进入。')}}</div>
|
||||||
</FormItem>
|
</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">
|
<FormItem :label="$L('是否启动首页')" prop="startHome">
|
||||||
<RadioGroup v-model="formDatum.start_home">
|
<RadioGroup v-model="formDatum.start_home">
|
||||||
<Radio label="open">{{$L('开启')}}</Radio>
|
<Radio label="open">{{$L('开启')}}</Radio>
|
||||||
@ -111,6 +130,7 @@
|
|||||||
:autosize="{ minRows: 2, maxRows: 8 }"
|
:autosize="{ minRows: 2, maxRows: 8 }"
|
||||||
:placeholder="$L('首页底部:首页底部网站备案号等信息')"/>
|
:placeholder="$L('首页底部:首页底部网站备案号等信息')"/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
<div class="setting-footer">
|
<div class="setting-footer">
|
||||||
<Button :loading="loadIng > 0" type="primary" @click="submitForm">{{$L('提交')}}</Button>
|
<Button :loading="loadIng > 0" type="primary" @click="submitForm">{{$L('提交')}}</Button>
|
||||||
|
|||||||
BIN
resources/assets/statics/public/images/avatar/default_anon.png
Normal file
BIN
resources/assets/statics/public/images/avatar/default_anon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.3 KiB |
Loading…
x
Reference in New Issue
Block a user