no message

This commit is contained in:
kuaifan 2024-10-19 10:40:42 +08:00
parent f983146501
commit 3cd00e1343
18 changed files with 199 additions and 102 deletions

View File

@ -992,7 +992,7 @@ class ApproveController extends AbstractController
'is_finished' => $process['is_finished'],
'data' => $data
];
$msgData['desc'] = match ($type) {
$msgData['title'] = match ($type) {
'approve_reviewer' => '待你审批',
'approve_notifier' => '审批通知',
'approve_comment_notifier' => '审批评论通知',

View File

@ -1092,7 +1092,7 @@ class FileController extends AbstractController
//
WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [
'type' => 'file_download',
'desc' => '文件下载打包已完成',
'title' => '文件下载打包已完成',
'name' => $fileName,
'size' => filesize($zipPath),
'url' => $fileUrl,

View File

@ -1688,12 +1688,11 @@ class ProjectTask extends AbstractModel
}
$dataId = $this->parent_id ?: $this->id;
$taskHtml = "<span class=\"mention task\" data-id=\"{$dataId}\">#{$this->name}</span>";
$text = match ($type) {
1 => "您的任务 {$taskHtml} 即将超时。",
2 => "您的任务 {$taskHtml} 已经超时。",
3 => "您的任务 {$taskHtml} 时间已修改。",
default => "您有一个新任务 {$taskHtml}",
1 => "(*)即将超时",
2 => "(*)已经超时",
3 => "(*)时间已修改",
default => "您有一个新任务",
};
/** @var User $user */
@ -1711,8 +1710,15 @@ class ProjectTask extends AbstractModel
$dialog = WebSocketDialog::checkUserDialog($botUser, $receiver->userid);
if ($dialog) {
ProjectTaskPushLog::createInstance($data)->save();
WebSocketDialogMsg::sendMsg(null, $dialog->id, 'text', [
'text' => str_replace("您的任务", $replace, $text) . $suffix
WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [
'type' => 'task_list',
'title' => str_replace("(*)", $replace, $text) . $suffix,
'list' => [
[
'id' => $dataId,
'name' => $this->name,
]
],
], in_array($type, [0, 3]) ? $userid : $botUser->userid);
}
}
@ -1720,11 +1726,12 @@ class ProjectTask extends AbstractModel
/**
* 移动任务
* @param int $project_id
* @param int $column_id
* @param int $projectId
* @param int $columnId
* @param int $flowItemId
* @param array $owner
* @param array $assist
* @param string $completeAt
* @return bool
*/
public function moveTask(int $projectId, int $columnId,int $flowItemId = 0,array $owner = [], array $assist = [], string $completeAt='')

View File

@ -250,11 +250,14 @@ class UserBot extends AbstractModel
};
$sendMsg = function($type, $checkin) use ($alreadyTip, $getJokeSoup, $botUser, $nowDate) {
$cacheKey = "Checkin::sendMsg-{$nowDate}-{$type}:" . $checkin['userid'];
$typeDesc = $type == "up" ? "上班" : "下班";
$typeContent = $type == "up" ? "上班" : "下班";
if (Cache::get($cacheKey) === "yes") {
if ($alreadyTip && $dialog = WebSocketDialog::checkUserDialog($botUser, $checkin['userid'])) {
$text = "<p>" . Doo::translate("今日已{$typeDesc}打卡,无需重复打卡。") . "</p>";
WebSocketDialogMsg::sendMsg(null, $dialog->id, 'text', ['text' => $text], $botUser->userid, false, false, $type != "up");
$text = "今日已{$typeContent}打卡,无需重复打卡。";
WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [
'type' => 'content',
'content' => $text,
], $botUser->userid, false, false, $type != "up");
}
return;
}
@ -263,12 +266,19 @@ class UserBot extends AbstractModel
if ($dialog = WebSocketDialog::checkUserDialog($botUser, $checkin['userid'])) {
$hi = date("H:i");
$remark = $checkin['remark'] ? " ({$checkin['remark']})": "";
$text = "<p>{$typeDesc}" . Doo::translate("打卡成功,打卡时间") . ": {$hi}{$remark}</p>";
$suff = $getJokeSoup($type);
if ($suff) {
$text = "{$text}<p>----------</p><p>{$suff}</p>";
}
WebSocketDialogMsg::sendMsg(null, $dialog->id, 'text', ['text' => $text], $botUser->userid, false, false, $type != "up");
$subcontent = $getJokeSoup($type);
WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [
'type' => 'content',
'content' => [
[
'content' => "{$typeContent}打卡成功,打卡时间: {$hi}{$remark}"
], [
'content' => $subcontent,
'language' => false,
'style' => 'padding-top:4px;opacity:0.4',
]
],
], $botUser->userid, false, false, $type != "up");
}
};
if ($timeAdvance <= Base::time() && Base::time() < $timeEnd) {

View File

@ -591,7 +591,7 @@ class WebSocketDialogMsg extends AbstractModel
return $data['msg']['notice'];
case 'template':
return Doo::translate($data['msg']['desc'] ?: '未知消息类型');
return $this->previewTemplateMsg($data['msg']);
default:
$action = Doo::translate("未知的消息");
@ -617,6 +617,26 @@ class WebSocketDialogMsg extends AbstractModel
return "[{$action}] {$msg['name']}";
}
/**
* 预览模板消息
* @param $msg
* @return string
*/
private function previewTemplateMsg($msg)
{
if (!empty($msg['title_raw'])) {
return $msg['title_raw'];
}
if (!empty($msg['title'])) {
return Doo::translate($msg['title']);
}
if ($msg['type'] === 'content' && is_string($msg['content']) && $msg['content'] !== '') {
return Doo::translate($msg['content']);
}
return Doo::translate('未知的消息');
}
/**
* 生成关键词
* @return string

View File

@ -96,8 +96,8 @@ class BotReceiveMsgTask extends AbstractTask
$text = UserBot::checkinBotQuickMsg($command, $msg->userid);
if ($text) {
WebSocketDialogMsg::sendMsg(null, $msg->dialog_id, 'template', [
'type' => 'desc',
'desc' => $text,
'type' => 'content',
'content' => $text,
], $botUser->userid, false, false, true); // todo 未能在任务end事件来发送任务
}
}
@ -106,8 +106,8 @@ class BotReceiveMsgTask extends AbstractTask
$text = UserBot::anonBotQuickMsg($command);
if ($text) {
WebSocketDialogMsg::sendMsg(null, $msg->dialog_id, 'template', [
'type' => 'desc',
'desc' => $text,
'type' => 'content',
'content' => $text,
], $botUser->userid, false, false, true); // todo 未能在任务end事件来发送任务
}
}
@ -120,8 +120,8 @@ class BotReceiveMsgTask extends AbstractTask
} else {
$text = "非常抱歉,我不是你的机器人,无法完成你的指令。";
WebSocketDialogMsg::sendMsg(null, $msg->dialog_id, 'template', [
'type' => 'desc',
'desc' => $text,
'type' => 'content',
'content' => $text,
], $botUser->userid, false, false, true); // todo 未能在任务end事件来发送任务
return;
}
@ -129,7 +129,7 @@ class BotReceiveMsgTask extends AbstractTask
$array = Base::newTrim(explode(" ", "{$command} "));
$type = $array[0];
$data = [];
$desc = "";
$content = "";
if (!$isManager && in_array($type, ['/list', '/newbot'])) {
return; // 这些操作仅支持【机器人管理】机器人
}
@ -152,7 +152,7 @@ class BotReceiveMsgTask extends AbstractTask
->orderByDesc('id')
->get();
if ($data->isEmpty()) {
$desc = "您没有创建机器人。";
$content = "您没有创建机器人。";
}
break;
@ -164,7 +164,7 @@ class BotReceiveMsgTask extends AbstractTask
$botId = $isManager ? $array[1] : $botUser->userid;
$data = $this->botManagerOne($botId, $msg->userid);
if (!$data) {
$desc = "机器人不存在。";
$content = "机器人不存在。";
}
break;
@ -177,25 +177,25 @@ class BotReceiveMsgTask extends AbstractTask
->where('users.bot', 1)
->where('user_bots.userid', $msg->userid)
->count() >= 50) {
$desc = "超过最大创建数量。";
$content = "超过最大创建数量。";
break;
}
if (strlen($array[1]) < 2 || strlen($array[1]) > 20) {
$desc = "机器人名称由2-20个字符组成。";
$content = "机器人名称由2-20个字符组成。";
break;
}
$data = User::botGetOrCreate("user-" . Base::generatePassword(), [
'nickname' => $array[1]
], $msg->userid);
if (empty($data)) {
$desc = "创建失败。";
$content = "创建失败。";
break;
}
$dialog = WebSocketDialog::checkUserDialog($data, $msg->userid);
if ($dialog) {
WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [
'type' => '/hello',
'desc' => '创建成功。',
'title' => '创建成功。',
'data' => $data,
], $data->userid); // todo 未能在任务end事件来发送任务
}
@ -208,7 +208,7 @@ class BotReceiveMsgTask extends AbstractTask
$botId = $isManager ? $array[1] : $botUser->userid;
$nameString = $isManager ? $array[2] : $array[1];
if (strlen($nameString) < 2 || strlen($nameString) > 20) {
$desc = "机器人名称由2-20个字符组成。";
$content = "机器人名称由2-20个字符组成。";
break;
}
$data = $this->botManagerOne($botId, $msg->userid);
@ -218,7 +218,7 @@ class BotReceiveMsgTask extends AbstractTask
$data->pinyin = Base::cn2pinyin($nameString);
$data->save();
} else {
$desc = "机器人不存在。";
$content = "机器人不存在。";
}
break;
@ -232,7 +232,7 @@ class BotReceiveMsgTask extends AbstractTask
if ($data) {
$data->deleteUser('delete bot');
} else {
$desc = "机器人不存在。";
$content = "机器人不存在。";
}
break;
@ -245,7 +245,7 @@ class BotReceiveMsgTask extends AbstractTask
if ($data) {
User::generateToken($data);
} else {
$desc = "机器人不存在。";
$content = "机器人不存在。";
}
break;
@ -260,7 +260,7 @@ class BotReceiveMsgTask extends AbstractTask
$data->password = Doo::md5s(Base::generatePassword(32), $data->encrypt);
$data->save();
} else {
$desc = "机器人不存在。";
$content = "机器人不存在。";
}
break;
@ -281,7 +281,7 @@ class BotReceiveMsgTask extends AbstractTask
$data->clear_day = $userBot->clear_day;
$data->clear_at = $userBot->clear_at; // 这两个参数只是作为输出,所以不保存
} else {
$desc = "机器人不存在。";
$content = "机器人不存在。";
}
break;
@ -293,7 +293,7 @@ class BotReceiveMsgTask extends AbstractTask
$webhookUrl = $isManager ? $array[2] : $array[1];
$data = $this->botManagerOne($botId, $msg->userid);
if (strlen($webhookUrl) > 255) {
$desc = "webhook地址最长仅支持255个字符。";
$content = "webhook地址最长仅支持255个字符。";
} elseif ($data) {
$userBot = UserBot::whereBotId($botId)->whereUserid($msg->userid)->first();
if ($userBot) {
@ -304,7 +304,7 @@ class BotReceiveMsgTask extends AbstractTask
$data->webhook_url = $userBot->webhook_url ?: '-';
$data->webhook_num = $userBot->webhook_num; // 这两个参数只是作为输出,所以不保存
} else {
$desc = "机器人不存在。";
$content = "机器人不存在。";
}
break;
@ -325,7 +325,7 @@ class BotReceiveMsgTask extends AbstractTask
->take(20)
->get();
if ($list->isEmpty()) {
$desc = "没有搜索到相关会话。";
$content = "没有搜索到相关会话。";
} else {
$list->transform(function (WebSocketDialog $item) use ($data) {
return $item->formatData($data->userid);
@ -333,23 +333,23 @@ class BotReceiveMsgTask extends AbstractTask
$data->list = $list; // 这个参数只是作为输出,所以不保存
}
} else {
$desc = "机器人不存在。";
$content = "机器人不存在。";
}
break;
}
//
if ($desc) {
if ($content) {
$msgData = [
'type' => 'desc',
'desc' => $desc,
'type' => 'content',
'content' => $content,
];
} else {
$msgData = [
'type' => $type,
'data' => $data,
];
$msgData['desc'] = match ($type) {
$msgData['title'] = match ($type) {
'/hello' => '您好',
'/help' => '帮助指令',
'/list' => '我的机器人',
@ -388,7 +388,7 @@ class BotReceiveMsgTask extends AbstractTask
$serverUrl = 'http://' . env('APP_IPPR') . '.3';
$userBot = null;
$extras = [];
$errorDesc = null;
$errorContent = null;
switch ($botUser->email) {
// ChatGPT 机器人
case 'ai-openai@bot.system':
@ -402,10 +402,10 @@ class BotReceiveMsgTask extends AbstractTask
'chunk_size' => 7,
];
if (empty($extras['openai_key'])) {
$errorDesc = '机器人未启用。';
$errorContent = '机器人未启用。';
} elseif (in_array($this->client['platform'], ['win', 'mac', 'web'])
&& !Base::judgeClientVersion("0.29.11", $this->client['version'])) {
$errorDesc = '当前客户端版本低所需版本≥v0.29.11)。';
$errorContent = '当前客户端版本低所需版本≥v0.29.11)。';
}
break;
// Claude 机器人
@ -418,10 +418,10 @@ class BotReceiveMsgTask extends AbstractTask
'server_url' => $serverUrl,
];
if (empty($extras['claude_token'])) {
$errorDesc = '机器人未启用。';
$errorContent = '机器人未启用。';
} elseif (in_array($this->client['platform'], ['win', 'mac', 'web'])
&& !Base::judgeClientVersion("0.29.11", $this->client['version'])) {
$errorDesc = '当前客户端版本低所需版本≥v0.29.11)。';
$errorContent = '当前客户端版本低所需版本≥v0.29.11)。';
}
break;
// Wenxin 机器人
@ -435,10 +435,10 @@ class BotReceiveMsgTask extends AbstractTask
'server_url' => $serverUrl,
];
if (empty($extras['wenxin_key'])) {
$errorDesc = '机器人未启用。';
$errorContent = '机器人未启用。';
} elseif (in_array($this->client['platform'], ['win', 'mac', 'web'])
&& !Base::judgeClientVersion("0.29.11", $this->client['version'])) {
$errorDesc = '当前客户端版本低所需版本≥v0.29.12)。';
$errorContent = '当前客户端版本低所需版本≥v0.29.12)。';
}
break;
// QianWen 机器人
@ -451,10 +451,10 @@ class BotReceiveMsgTask extends AbstractTask
'server_url' => $serverUrl,
];
if (empty($extras['qianwen_key'])) {
$errorDesc = '机器人未启用。';
$errorContent = '机器人未启用。';
} elseif (in_array($this->client['platform'], ['win', 'mac', 'web'])
&& !Base::judgeClientVersion("0.29.11", $this->client['version'])) {
$errorDesc = '当前客户端版本低所需版本≥v0.29.12)。';
$errorContent = '当前客户端版本低所需版本≥v0.29.12)。';
}
break;
// Gemini 机器人
@ -469,10 +469,10 @@ class BotReceiveMsgTask extends AbstractTask
'server_url' => $serverUrl,
];
if (empty($extras['gemini_key'])) {
$errorDesc = '机器人未启用。';
$errorContent = '机器人未启用。';
} elseif (in_array($this->client['platform'], ['win', 'mac', 'web'])
&& !Base::judgeClientVersion("0.29.11", $this->client['version'])) {
$errorDesc = '当前客户端版本低所需版本≥v0.29.12)。';
$errorContent = '当前客户端版本低所需版本≥v0.29.12)。';
}
break;
// 智谱清言 机器人
@ -485,10 +485,10 @@ class BotReceiveMsgTask extends AbstractTask
'server_url' => $serverUrl,
];
if (empty($extras['zhipu_key'])) {
$errorDesc = '机器人未启用。';
$errorContent = '机器人未启用。';
} elseif (in_array($this->client['platform'], ['win', 'mac', 'web'])
&& !Base::judgeClientVersion("0.29.11", $this->client['version'])) {
$errorDesc = '当前客户端版本低所需版本≥v0.29.12)。';
$errorContent = '当前客户端版本低所需版本≥v0.29.12)。';
}
break;
// 其他机器人
@ -497,10 +497,10 @@ class BotReceiveMsgTask extends AbstractTask
$webhookUrl = $userBot?->webhook_url;
break;
}
if ($errorDesc) {
if ($errorContent) {
WebSocketDialogMsg::sendMsg(null, $msg->dialog_id, 'template', [
'type' => 'desc',
'desc' => $errorDesc,
'type' => 'content',
'content' => $errorContent,
], $botUser->userid, false, false, true); // todo 未能在任务end事件来发送任务
return;
}

View File

@ -84,11 +84,28 @@ class CheckinRemindTask extends AbstractTask
$dialog = WebSocketDialog::checkUserDialog($botUser, $user->userid);
if ($dialog) {
if ($type === 'exceed') {
$text = "<p><strong style='color:red'>" . Doo::translate("缺卡提醒") . "</strong>" . Doo::translate("上班时间到了,你还没有打卡哦~") . "</p>";
$title = '缺卡提醒';
$style = 'color:#f55;';
$content = '上班时间到了,你还没有打卡哦~';
} else {
$text = "<p><strong>" . Doo::translate("打卡提醒") . "</strong>" . Doo::translate("快到上班时间了,别忘了打卡哦~") . "</p>";
$title = '打卡提醒';
$style = '';
$content = '快到上班时间了,别忘了打卡哦~';
}
WebSocketDialogMsg::sendMsg(null, $dialog->id, 'text', ['text' => $text], $botUser->userid);
WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [
'type' => 'content',
'title' => $title,
'content' => [
[
'content' => $title,
'style' => $style . 'font-weight:bold',
],
[
'content' => $content,
'style' => 'padding-top:4px;opacity:0.4',
],
],
], $botUser->userid);
}
}
});

View File

@ -6,7 +6,6 @@ use App\Models\User;
use App\Module\Base;
use App\Models\Project;
use App\Models\ProjectTask;
use App\Models\ProjectUser;
use Carbon\Carbon;
use App\Models\WebSocketDialogMsg;
use Illuminate\Support\Facades\Cache;
@ -64,8 +63,8 @@ class UnclaimedTaskRemindTask extends AbstractTask
return;
}
WebSocketDialogMsg::sendMsg(null, $project->dialog_id, 'template', [
'type' => 'task_unclaimed',
'desc' => '任务待领取',
'type' => 'task_list',
'title' => '任务待领取',
'list' => $projectTasks->map(function ($item) {
return [
'id' => $item->id,

View File

@ -411,7 +411,7 @@ import {MarkdownPreview} from "../store/markdown";
case 'notice':
return data.msg.notice
case 'template':
return $A.L(data.msg.desc || '未知消息类型')
return $A.templateMsgSimpleDesc(data.msg)
default:
return `[${$A.L('未知的消息')}]`
}
@ -440,6 +440,24 @@ import {MarkdownPreview} from "../store/markdown";
return `[${$A.L('文件')}] ${msg.name}`
},
/**
* 模板消息简单描述
* @param msg
* @returns {string|*}
*/
templateMsgSimpleDesc(msg) {
if (msg.title_raw) {
return msg.title_raw
}
if (msg.title) {
return $A.L(msg.title)
}
if (msg.type === 'content' && typeof msg.content === 'string' && msg.content !== '') {
return $A.L(msg.content)
}
return $A.L('未知的消息')
},
/**
* 获取文件标题
* @param file

View File

@ -0,0 +1,39 @@
<template>
<div>
<p v-for="(item, index) in items" :key="index" :style="item.style">{{ item.content }}</p>
</div>
</template>
<script lang="ts">
export default {
props: {
msg: Object,
},
data() {
return {};
},
computed: {
items({msg}) {
const {content} = msg;
if ($A.isArray(content)) {
return content.map(item => this.formatContent(item))
} else {
return [this.formatContent(content)];
}
},
},
methods: {
formatContent(item) {
if ($A.isJson(item)) {
return {
content: item.language === false ? item.content : this.$L(item.content),
style: item.style || {},
};
}
return {
content: this.$L(item),
style: {},
};
},
},
}
</script>

View File

@ -1,16 +0,0 @@
<template>
<div>
{{$L(msg.desc)}}
</div>
</template>
<script lang="ts">
export default {
props: {
msg: Object,
},
data() {
return {};
},
methods: {},
}
</script>

View File

@ -24,10 +24,10 @@ import ApproveNotifier from "./approve-notifier.vue";
import ApproveCommentNotifier from "./approve-comment-notifier.vue";
import ApproveSubmitter from "./approve-submitter.vue";
import TaskUnclaimed from "./task-unclaimed.vue";
import TaskList from "./task-list.vue";
import FileDownload from "./file-download.vue";
import Desc from "./desc.vue";
import Content from "./content.vue";
import Other from "./other.vue";
export default {
@ -76,13 +76,13 @@ export default {
case 'approve_submitter':
return ApproveSubmitter;
case 'task_unclaimed':
return TaskUnclaimed;
case 'task_list':
return TaskList;
case 'file_download':
return FileDownload;
case 'desc':
return Desc;
case 'content':
return Content;
default:
return Other;
}

View File

@ -3,7 +3,7 @@
{{$L("不支持的指令")}} <span class="warning-color">{{msg.type}}</span>{{$L("你可以发送")}} <span class="mark-color">/help</span> {{$L("查看帮助菜单")}}
</div>
<div v-else>
{{$L("未知消息类型")}}
{{$L("未知消息")}}
</div>
</template>

View File

@ -1,6 +1,6 @@
<template>
<div>
<p>{{$L("任务待领取")}}</p>
<p>{{$L(msg.desc)}}</p>
<p>&nbsp;</p>
<p v-for="item in msg.list">

View File

@ -1,5 +1,5 @@
<template>
<div class="content-unknown">{{$L("未知的消息类型")}}</div>
<div class="content-unknown">{{$L("未知的消息")}}</div>
</template>
<script lang="ts">
export default {

View File

@ -3306,9 +3306,10 @@ export default {
data = this.operateItem
}
$A.modalConfirm({
title: '下载文件',
language: false,
title: this.$L('下载文件'),
okText: this.$L('立即下载'),
content: `${data.msg.name} (${$A.bytesToSize(data.msg.size)})`,
okText: '立即下载',
onOk: () => {
this.$store.dispatch('downUrl', $A.apiUrl(`dialog/msg/download?msg_id=${data.id}`))
}

View File

@ -1698,9 +1698,10 @@ export default {
downFile(file) {
$A.modalConfirm({
title: '下载文件',
language: false,
title: this.$L('下载文件'),
okText: this.$L('立即下载'),
content: `${file.name} (${$A.bytesToSize(file.size)})`,
okText: '立即下载',
onOk: () => {
this.$store.dispatch('downUrl', $A.apiUrl(`project/task/filedown?file_id=${file.id}`))
}

View File

@ -1300,9 +1300,10 @@ export default {
return;
}
$A.modalConfirm({
title: '下载文件',
language: false,
title: this.$L('下载文件'),
okText: this.$L('立即下载'),
content: `${item.name}.${item.ext} (${$A.bytesToSize(item.size)})`,
okText: '立即下载',
onOk: () => {
this.$store.dispatch('downUrl', $A.apiUrl(`file/content?id=${item.id}&down=yes`))
}