diff --git a/.prefetch b/.prefetch
index abb24d7b6..a2f74609a 100644
--- a/.prefetch
+++ b/.prefetch
@@ -158,11 +158,6 @@ drawio/webapp/js/app.min.js
drawio/webapp/js/extensions.min.js
drawio/webapp/js/shapes-14-6-5.min.js
drawio/webapp/js/stencils.min.js
-drawio/webapp/math/es5/core.js
-drawio/webapp/math/es5/input/asciimath.js
-drawio/webapp/math/es5/input/tex.js
-drawio/webapp/math/es5/output/svg.js
-drawio/webapp/math/es5/output/svg/fonts/tex.js
drawio/webapp/styles/grapheditor.css
minder/css/chunk-vendors.fe9c56c6.css
diff --git a/app/Http/Controllers/Api/ApproveController.php b/app/Http/Controllers/Api/ApproveController.php
deleted file mode 100755
index d5929bced..000000000
--- a/app/Http/Controllers/Api/ApproveController.php
+++ /dev/null
@@ -1,1267 +0,0 @@
-flow_url = config('dootask.flow_url') ?: 'http://approve';
- }
-
- /**
- * @api {get} api/approve/verifyToken 验证APi登录
- *
- * @apiDescription 需要token身份
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName verifyToken
- *
- * @apiSuccess {String} version
- * @apiSuccess {String} publish
- */
- public function verifyToken()
- {
- try {
- $user = User::auth();
- $user->checkAdmin();
- return Base::retSuccess('成功');
- } catch (\Throwable $th) {
- return response('身份无效', 400)->header('Content-Type', 'text/plain');
- }
- }
-
- /**
- * @api {post} api/approve/procdef/all 查询流程定义
- *
- * @apiDescription 需要token身份
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName procdef__all
- *
- * @apiQuery {String} name 流程名称
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function procdef__all()
- {
- User::auth();
- $data['name'] = Request::input('name');
- $ret = Ihttp::ihttp_post($this->flow_url . '/api/v1/workflow/procdef/findAll', json_encode($data));
- $procdef = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$procdef || $procdef['status'] != 200 || $ret['ret'] == 0) {
- // info($ret);
- return Base::retError($procdef['message'] ?? '查询失败');
- }
- return Base::retSuccess('success', Base::arrayKeyToUnderline($procdef['data']));
- }
-
- /**
- * @api {get} api/approve/procdef/del 删除流程定义
- *
- * @apiDescription 需要token身份
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName procdef__del
- *
- * @apiQuery {String} id 流程ID
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function procdef__del()
- {
- User::auth('admin');
- $data['id'] = Request::input('id');
- $ret = Ihttp::ihttp_get($this->flow_url . '/api/v1/workflow/procdef/delById?' . http_build_query($data));
- $procdef = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$procdef || $procdef['status'] != 200) {
- return Base::retError($procdef['message'] ?? '删除失败');
- }
- return Base::retSuccess('success', Base::arrayKeyToUnderline($procdef['data']));
- }
-
- /**
- * @api {post} api/approve/process/start 启动流程(审批中)
- *
- * @apiDescription 需要token身份
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName process__start
- *
- * @apiQuery {String} proc_name 流程名称
- * @apiQuery {Number} department_id 部门ID
- * @apiQuery {Array} [var] 启动流程类型信息(格式:[{type,startTime,endTime,description}])
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function process__start()
- {
- $user = User::auth();
- $data['userid'] = (string)$user->userid;
- $data['department_id'] = intval(Request::input('department_id'));
- $data['proc_name'] = Request::input('proc_name');
- //
- $var = json_decode(Request::input('var'), true);
- $data['var'] = $var;
- $ret = Ihttp::ihttp_post($this->flow_url . '/api/v1/workflow/process/start', json_encode(Base::arrayKeyToCamel($data)));
- $process = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$process || $process['status'] != 200) {
- return Base::retError($process['message'] ?? '启动失败');
- }
- //
- $process = Base::arrayKeyToUnderline($process['data']);
- $process = $this->getProcessById($process['id']); //获取最新的流程信息
- if ($process['candidate']) {
- $userid = explode(',', $process['candidate']);
- $toUser = User::whereIn('userid', $userid)->get()->toArray();
- $botUser = User::botGetOrCreate('approval-alert');
- if (empty($botUser)) {
- return Base::retError('审批机器人不存在');
- }
- foreach ($toUser as $val) {
- if ($val['bot']) {
- continue;
- }
- $dialog = WebSocketDialog::checkUserDialog($botUser, $val['userid']);
- if (empty($dialog)) {
- continue;
- }
- $this->approveMsg('approve_reviewer', $dialog, $botUser, $val, $process, 'start');
- }
- // 抄送人
- $notifier = $this->handleProcessNode($process);
- if ($notifier) {
- foreach ($notifier as $val) {
- $dialog = WebSocketDialog::checkUserDialog($botUser, $val['target_id']);
- $this->approveMsg('approve_notifier', $dialog, $botUser, $process, $process);
- }
- }
- }
-
- return Base::retSuccess('创建成功', $process);
- }
-
- /**
- * @api {post} api/approve/process/addGlobalComment 添加全局评论
- *
- * @apiDescription 需要token身份
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName process__addGlobalComment
- *
- * @apiQuery {Number} proc_inst_id 流程实例ID
- * @apiQuery {String} content 评论内容
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function process__addGlobalComment()
- {
- $user = User::auth();
- $data['proc_inst_id'] = intval(Request::input('proc_inst_id'));
- $data['userid'] = (string)$user->userid;
- $data['content'] = Request::input('content'); //内容+图片
-
- $processInst = $this->getProcessById($data['proc_inst_id']);
-
- $ret = Ihttp::ihttp_post($this->flow_url . '/api/v1/workflow/process/addGlobalComment', json_encode(Base::arrayKeyToCamel($data)));
- $process = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$process || $process['status'] != 200) {
- return Base::retError($process['message'] ?? '添加失败');
- }
-
- // 推送通知
- $botUser = User::botGetOrCreate('approval-alert');
- foreach ($processInst['userids'] as $id) {
- if ($id != $user->userid) {
- $dialog = WebSocketDialog::checkUserDialog($botUser, $id);
- $processInst['comment_user_id'] = $user->userid;
- $processInst['comment_contents'] = json_decode($data['content'], true) ?? [];
- $this->approveMsg('approve_comment_notifier', $dialog, $botUser, $processInst, $processInst);
- }
- }
-
- $res = Base::arrayKeyToUnderline($process['data']);
- return Base::retSuccess('success', $res);
- }
-
- /**
- * @api {post} api/approve/task/complete 审批
- *
- * @apiDescription 需要token身份
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName task__complete
- *
- * @apiQuery {Number} task_id 流程ID
- * @apiQuery {String} pass 标题 [true-通过,false-拒绝]
- * @apiQuery {String} comment 评论
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function task__complete()
- {
- $user = User::auth();
- $data['userid'] = (string)$user->userid;
- $data['task_id'] = intval(Request::input('task_id'));
- $data['pass'] = Request::input('pass');
- $data['comment'] = Request::input('comment');
- $ret = Ihttp::ihttp_post($this->flow_url . '/api/v1/workflow/task/complete', json_encode(Base::arrayKeyToCamel($data)));
- $task = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$task || $task['status'] != 200) {
- return Base::retError($task['message'] ?? '审批失败');
- }
- //
- $task = Base::arrayKeyToUnderline($task['data']);
- $pass = $data['pass'] == 'true' ? 'pass' : 'refuse';
- $process = $this->getProcessById($task['proc_inst_id']);
- $botUser = User::botGetOrCreate('approval-alert');
- if (empty($botUser)) {
- return Base::retError('审批机器人不存在');
- }
- // 在流程信息关联的用户中查找
- $toUser = ApproveProcMsg::where('proc_inst_id', $process['id'])->get()->toArray();
- foreach ($toUser as $val) {
- $dialog = WebSocketDialog::checkUserDialog($botUser, $val['userid']);
- if (empty($dialog)) {
- continue;
- }
- $this->approveMsg('approve_reviewer', $dialog, $botUser, $val, $process, $pass);
- }
- // 发起人
- if ($process['is_finished']) {
- $dialog = WebSocketDialog::checkUserDialog($botUser, $process['start_user_id']);
- if (!empty($dialog)) {
- $this->approveMsg('approve_submitter', $dialog, $botUser, ['userid' => $data['userid']], $process, $pass);
- }
- } else if ($process['candidate']) {
- // 下个审批人
- $userid = explode(',', $process['candidate']);
- $toUser = User::whereIn('userid', $userid)->get()->toArray();
- foreach ($toUser as $val) {
- if ($val['bot']) {
- continue;
- }
- $dialog = WebSocketDialog::checkUserDialog($botUser, $val['userid']);
- if (empty($dialog)) {
- continue;
- }
- $this->approveMsg('approve_reviewer', $dialog, $botUser, $val, $process, 'start');
- }
- }
-
- // 抄送人
- $notifier = $this->handleProcessNode($process);
- if ($notifier && $pass == 'pass') {
- foreach ($notifier as $val) {
- $dialog = WebSocketDialog::checkUserDialog($botUser, $val['target_id']);
- if (!empty($dialog)) {
- $this->approveMsg('approve_notifier', $dialog, $botUser, $process, $process);
- }
- }
- }
- return Base::retSuccess($pass == 'pass' ? '已通过' : '已拒绝', $task);
- }
-
- /**
- * @api {post} api/approve/task/withdraw 撤回
- *
- * @apiDescription 需要token身份
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName task__withdraw
- *
- * @apiQuery {Number} task_id 流程ID
- * @apiQuery {Number} proc_inst_id 流程实例ID
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function task__withdraw()
- {
- $user = User::auth();
- $data['userid'] = (string)$user->userid;
- $data['task_id'] = intval(Request::input('task_id'));
- $data['proc_inst_id'] = intval(Request::input('proc_inst_id'));
- $ret = Ihttp::ihttp_post($this->flow_url . '/api/v1/workflow/task/withdraw', json_encode(Base::arrayKeyToCamel($data)));
- $task = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$task || $task['status'] != 200) {
- return Base::retError($task['message'] ?? '撤回失败');
- }
- //
- $process = $this->getProcessById($data['proc_inst_id']);
- $botUser = User::botGetOrCreate('approval-alert');
- if (empty($botUser)) {
- return Base::retError('审批机器人不存在');
- }
- // 在流程信息关联的用户中查找
- $toUser = ApproveProcMsg::where('proc_inst_id', $process['id'])->get()->toArray();
- foreach ($toUser as $val) {
- $dialog = WebSocketDialog::checkUserDialog($botUser, $val['userid']);
- if (empty($dialog)) {
- continue;
- }
- //发送撤回提醒
- $this->approveMsg('approve_reviewer', $dialog, $botUser, $val, $process, 'withdraw');
- }
- return Base::retSuccess('已撤回', Base::arrayKeyToUnderline($task['data']));
- }
-
- /**
- * @api {post} api/approve/process/delById 删除审批(流程实例)
- *
- * @apiDescription 需要token身份;仅可删除已结束的审批,且仅发起人或管理员可删
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName process__delById
- *
- * @apiQuery {Number} proc_inst_id 流程实例ID
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function process__delById()
- {
- $user = User::auth();
- $data['userid'] = (string)$user->userid;
- $data['proc_inst_id'] = intval(Request::input('proc_inst_id'));
- $data['is_admin'] = $user->isAdmin();
- if ($data['proc_inst_id'] <= 0) {
- return Base::retError('参数错误');
- }
- $ret = Ihttp::ihttp_post($this->flow_url . '/api/v1/workflow/process/delById', json_encode(Base::arrayKeyToCamel($data)));
- $task = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$task || $task['status'] != 200) {
- return Base::retError($task['message'] ?? '删除失败');
- }
- return Base::retSuccess('已删除');
- }
-
- /**
- * @api {post} api/approve/process/findTask 查询需要我审批的流程(审批中)
- *
- * @apiDescription 需要token身份
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName process__findTask
- *
- * @apiQuery {String} proc_def_name 流程名称
- * @apiQuery {String} sort 排序[asc升序,desc降序]
- * @apiQuery {Number} page 页码
- * @apiQuery {Number} page_size 每页条数
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function process__findTask()
- {
- $user = User::auth();
- $data['userid'] = (string)$user->userid;
- $data['username'] = Request::input('username');
- $data['procName'] = Request::input('proc_def_name');
- $data['sort'] = Request::input('sort');
- $data['pageIndex'] = intval(Request::input('page'));
- $data['pageSize'] = intval(Request::input('page_size'));
- $ret = Ihttp::ihttp_post($this->flow_url . '/api/v1/workflow/process/findTask', json_encode(Base::arrayKeyToCamel($data)));
- $process = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$process || $process['status'] != 200) {
- return Base::retError($process['message'] ?? '查询失败');
- }
- //
- $res = Base::arrayKeyToUnderline($process['data']);
- foreach ($res['rows'] as &$val) {
- $info = User::whereUserid($val['start_user_id'])->first();
- if (!$info) {
- continue;
- }
- $val['userimg'] = User::getAvatar($info->userid, $info->userimg, $info->email, $info->nickname);
- }
- return Base::retSuccess('success', $res);
- }
-
- /**
- * @api {post} api/approve/process/startByMyselfAll 查询我启动的流程(全部)
- *
- * @apiDescription 需要token身份
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName process__startByMyselfAll
- *
- * @apiQuery {String} proc_def_name 流程分类
- * @apiQuery {String} state 流程状态[0全部,1审批中,2通过,3拒绝,4撤回]
- * @apiQuery {Number} page 页码
- * @apiQuery {Number} page_size 每页条数
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function process__startByMyselfAll()
- {
- $user = User::auth();
- $data['userid'] = (string)$user->userid;
- $data['username'] = Request::input('username');
- $data['procName'] = Request::input('proc_def_name'); //分类
- $data['state'] = intval(Request::input('state')); //状态
- $data['pageIndex'] = intval(Request::input('page'));
- $data['pageSize'] = intval(Request::input('page_size'));
- $ret = Ihttp::ihttp_post($this->flow_url . '/api/v1/workflow/process/startByMyselfAll', json_encode($data));
- $process = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$process || $process['status'] != 200) {
- return Base::retError($process['message'] ?? '查询失败');
- }
- //
- $res = Base::arrayKeyToUnderline($process['data']);
- foreach ($res['rows'] as &$val) {
- $info = User::whereUserid($val['start_user_id'])->first();
- if (!$info) {
- continue;
- }
- $val['userimg'] = User::getAvatar($info->userid, $info->userimg, $info->email, $info->nickname);
- }
- return Base::retSuccess('success', $res);
- }
-
- /**
- * @api {post} api/approve/process/startByMyself 查询我启动的流程(审批中)
- *
- * @apiDescription 需要token身份
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName process__startByMyself
- *
- * @apiQuery {Number} page 页码
- * @apiQuery {Number} page_size 每页条数
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function process__startByMyself()
- {
- $user = User::auth();
- $data['userid'] = (string)$user->userid;
- $data['pageIndex'] = intval(Request::input('page'));
- $data['pageSize'] = intval(Request::input('page_size'));
- $ret = Ihttp::ihttp_post($this->flow_url . '/api/v1/workflow/process/startByMyself', json_encode($data));
- $process = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$process || $process['status'] != 200) {
- return Base::retError($process['message'] ?? '查询失败');
- }
- //
- $res = Base::arrayKeyToUnderline($process['data']);
- foreach ($res['rows'] as &$val) {
- $info = User::whereUserid($val['start_user_id'])->first();
- if (!$info) {
- continue;
- }
- $val['userimg'] = User::getAvatar($info->userid, $info->userimg, $info->email, $info->nickname);
- }
- return Base::retSuccess('success', $res);
- }
-
- /**
- * @api {post} api/approve/process/findProcNotify 查询抄送我的流程(审批中)
- *
- * @apiDescription 需要token身份
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName process__findProcNotify
- *
- * @apiQuery {Number} userid 用户ID
- * @apiQuery {String} proc_def_name 流程分类
- * @apiQuery {String} sort 排序[asc升序,desc降序]
- * @apiQuery {Number} page 页码
- * @apiQuery {Number} page_size 每页条数
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function process__findProcNotify()
- {
- $user = User::auth();
- $data['userid'] = (string)$user->userid;
- $data['procName'] = Request::input('proc_def_name');
- $data['sort'] = Request::input('sort');
- $data['pageIndex'] = intval(Request::input('page'));
- $data['pageSize'] = intval(Request::input('page_size'));
-
- $ret = Ihttp::ihttp_post($this->flow_url . '/api/v1/workflow/process/findProcNotify', json_encode($data));
- $process = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$process || $process['status'] != 200) {
- return Base::retError($process['message'] ?? '查询失败');
- }
- //
- $res = Base::arrayKeyToUnderline($process['data']);
- foreach ($res['rows'] as &$val) {
- $info = User::whereUserid($val['start_user_id'])->first();
- if (!$info) {
- continue;
- }
- $val['userimg'] = User::getAvatar($info->userid, $info->userimg, $info->email, $info->nickname);
- }
- return Base::retSuccess('success', $res);
- }
-
- /**
- * @api {get} api/approve/identitylink/findParticipant 查询流程实例的参与者(审批中)
- *
- * @apiDescription 需要token身份
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName identitylink__findParticipant
- *
- * @apiQuery {Number} proc_inst_id 流程实例ID
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function identitylink__findParticipant()
- {
- User::auth();
- $proc_inst_id = Request::input('proc_inst_id');
- $ret = Ihttp::ihttp_get($this->flow_url . '/api/v1/workflow/identitylink/findParticipant?procInstId=' . $proc_inst_id);
- $identitylink = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$identitylink || $identitylink['status'] != 200) {
- return Base::retError($identitylink['message'] ?? '查询失败');
- }
- //
- $res = Base::arrayKeyToUnderline($identitylink['data']);
- foreach ($res as &$val) {
- $info = User::whereUserid($val['userid'])->first();
- if (!$info) {
- continue;
- }
- $val['userimg'] = User::getAvatar($info->userid, $info->userimg, $info->email, $info->nickname);
- }
- return Base::retSuccess('success', $res);
- }
-
- /**
- * @api {post} api/approve/procHistory/findTask 查询需要我审批的流程(已结束)
- *
- * @apiDescription 需要token身份
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName procHistory__findTask
- *
- * @apiQuery {String} proc_def_name 流程分类
- * @apiQuery {String} sort 排序[asc升序,desc降序]
- * @apiQuery {Number} page 页码
- * @apiQuery {Number} page_size 每页条数
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function procHistory__findTask()
- {
- $user = User::auth();
- $data['userid'] = (string)$user->userid;
- $data['username'] = Request::input('username');
- $data['procName'] = Request::input('proc_def_name');
- $data['sort'] = Request::input('sort');
- $data['pageIndex'] = intval(Request::input('page'));
- $data['pageSize'] = intval(Request::input('page_size'));
- $ret = Ihttp::ihttp_post($this->flow_url . '/api/v1/workflow/procHistory/findTask', json_encode(Base::arrayKeyToCamel($data)));
- $process = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$process || $process['status'] != 200) {
- return Base::retError($process['message'] ?? '查询失败');
- }
- //
- $res = Base::arrayKeyToUnderline($process['data']);
- foreach ($res['rows'] as &$val) {
- $info = User::whereUserid($val['start_user_id'])->first();
- if (!$info) {
- continue;
- }
- $val['userimg'] = User::getAvatar($info->userid, $info->userimg, $info->email, $info->nickname);
- }
- return Base::retSuccess('success', $res);
- }
-
- /**
- * @api {post} api/approve/procHistory/startByMyself 查询我启动的流程(已结束)
- *
- * @apiDescription 需要token身份
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName procHistory__startByMyself
- *
- * @apiQuery {Number} page 页码
- * @apiQuery {Number} page_size 每页条数
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function procHistory__startByMyself()
- {
- $user = User::auth();
- $data['userid'] = (string)$user->userid;
- $data['pageIndex'] = intval(Request::input('page'));
- $data['pageSize'] = intval(Request::input('page_size'));
- $ret = Ihttp::ihttp_post($this->flow_url . '/api/v1/workflow/procHistory/startByMyself', json_encode($data));
- $process = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$process || $process['status'] != 200) {
- return Base::retError($process['message'] ?? '查询失败');
- }
- //
- $res = Base::arrayKeyToUnderline($process['data']);
- foreach ($res['rows'] as &$val) {
- $info = User::whereUserid($val['start_user_id'])->first();
- if (!$info) {
- continue;
- }
- $val['userimg'] = User::getAvatar($info->userid, $info->userimg, $info->email, $info->nickname);
- }
- return Base::retSuccess('success', $res);
- }
-
- /**
- * @api {post} api/approve/procHistory/findProcNotify 查询抄送我的流程(已结束)
- *
- * @apiDescription 需要token身份
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName procHistory__findProcNotify
- *
- * @apiQuery {String} proc_def_name 流程分类
- * @apiQuery {String} sort 排序[asc升序,desc降序]
- * @apiQuery {Number} page 页码
- * @apiQuery {Number} page_size 每页条数
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function procHistory__findProcNotify()
- {
- $user = User::auth();
- $data['userid'] = (string)$user->userid;
- $data['username'] = Request::input('username');
- $data['procName'] = Request::input('proc_def_name');
- $data['sort'] = Request::input('sort');
- $data['pageIndex'] = intval(Request::input('page'));
- $data['pageSize'] = intval(Request::input('page_size'));
-
- $ret = Ihttp::ihttp_post($this->flow_url . '/api/v1/workflow/procHistory/findProcNotify', json_encode($data));
- $process = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$process || $process['status'] != 200) {
- return Base::retError($process['message'] ?? '查询失败');
- }
- //
- $res = Base::arrayKeyToUnderline($process['data']);
- foreach ($res['rows'] as &$val) {
- $info = User::whereUserid($val['start_user_id'])->first();
- if (!$info) {
- continue;
- }
- $val['userimg'] = User::getAvatar($info->userid, $info->userimg, $info->email, $info->nickname);
- }
- return Base::retSuccess('success', $res);
- }
-
- /**
- * @api {get} api/approve/identitylinkHistory/findParticipant 查询流程实例的参与者(已结束)
- *
- * @apiDescription 需要token身份
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName identitylinkHistory__findParticipant
- *
- * @apiQuery {Number} proc_inst_id 流程实例ID
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function identitylinkHistory__findParticipant()
- {
- User::auth();
- $proc_inst_id = Request::input('proc_inst_id');
- $ret = Ihttp::ihttp_get($this->flow_url . '/api/v1/workflow/identitylinkHistory/findParticipant?procInstId=' . $proc_inst_id);
- $identitylink = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$identitylink || $identitylink['status'] != 200) {
- return Base::retError($identitylink['message'] ?? '查询失败');
- }
- //
- $res = Base::arrayKeyToUnderline($identitylink['data']);
- foreach ($res as &$val) {
- $info = User::whereUserid($val['userid'])->first();
- if (!$info) {
- continue;
- }
- $val['userimg'] = User::getAvatar($info->userid, $info->userimg, $info->email, $info->nickname);
- }
- return Base::retSuccess('success', $res);
- }
-
- /**
- * @api {get} api/approve/process/detail 根据流程ID查询流程详情
- *
- * @apiDescription 需要token身份
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName process__detail
- *
- * @apiQuery {Number} id 流程ID
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function process__detail()
- {
- User::auth();
- $data['id'] = intval(Request::input('id'));
- $approve = $this->getProcessById($data['id']);
- return Base::retSuccess('success', $approve);
- }
-
- /**
- * @api {post} api/approve/export 导出数据
- *
- * @apiDescription 需要token身份
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName export
- *
- * @apiQuery {String} proc_def_name 流程分类
- * @apiQuery {String} state 流程状态[0全部,1审批中,2通过,3拒绝,4撤回]
- * @apiQuery {String} is_finished 是否完成
- * @apiQuery {Array} [date] 指定日期范围,如:['2020-12-12', '2020-12-30']
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function export()
- {
- $user = User::auth('admin');
- $name = $data['procName'] = Request::input('proc_def_name'); //分类
- $data['state'] = intval(Request::input('state')); //状态
- $data['isFinished'] = intval(Request::input('is_finished')); //是否完成
- $date = Request::input('date');
- $data['startTime'] = $date[0]; //开始时间
- $data['endTime'] = Carbon::parse($date[1])->addDay()->toDateString(); //结束时间 + 1天
- //
- if (empty($name) || empty($date)) {
- return Base::retError('参数错误');
- }
- if (!(is_array($date) && Timer::isDate($date[0]) && Timer::isDate($date[1]))) {
- return Base::retError('日期选择错误');
- }
- if (Carbon::parse($date[1])->timestamp - Carbon::parse($date[0])->timestamp > 35 * 86400) {
- return Base::retError('日期范围限制最大35天');
- }
- $botUser = User::botGetOrCreate('system-msg');
- if (empty($botUser)) {
- return Base::retError('系统机器人不存在');
- }
- $dialog = WebSocketDialog::checkUserDialog($botUser, $user->userid);
- //
- $doo = Doo::load();
- go(function () use ($doo, $data, $user, $botUser, $dialog) {
- Coroutine::sleep(1);
- //
- $content = [];
- $content[] = [
- 'content' => '导出审批数据已完成',
- 'style' => 'font-weight: bold;padding-bottom: 4px;',
- ];
- //
- $ret = Ihttp::ihttp_post($this->flow_url . '/api/v1/workflow/process/findAllProcIns', json_encode($data));
- $process = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$process || $process['status'] != 200) {
- $content[] = [
- 'content' => $process['message'] ?? '查询失败',
- 'style' => 'color: #ff0000;',
- ];
- WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [
- 'type' => 'content',
- 'title' => $content[0]['content'],
- 'content' => $content,
- ], $botUser->userid, true, false, true);
- return;
- }
- //
- $res = Base::arrayKeyToUnderline($process['data']);
- //
- $headings = [];
- $headings[] = $doo->translate('申请编号');
- $headings[] = $doo->translate('标题');
- $headings[] = $doo->translate('申请状态');
- $headings[] = $doo->translate('发起时间');
- $headings[] = $doo->translate('完成时间');
- $headings[] = $doo->translate('发起人工号');
- $headings[] = $doo->translate('发起人User ID');
- $headings[] = $doo->translate('发起人姓名');
- $headings[] = $doo->translate('发起人部门');
- $headings[] = $doo->translate('发起人部门ID');
- $headings[] = $doo->translate('部门负责人');
- $headings[] = $doo->translate('历史审批人');
- $headings[] = $doo->translate('历史办理人');
- $headings[] = $doo->translate('审批记录');
- $headings[] = $doo->translate('当前处理人');
- $headings[] = $doo->translate('审批节点');
- $headings[] = $doo->translate('审批人数');
- $headings[] = $doo->translate('审批耗时');
- $headings[] = $doo->translate('假期类型');
- $headings[] = $doo->translate('开始时间');
- $headings[] = $doo->translate('结束时间');
- $headings[] = $doo->translate('时长');
- $headings[] = $doo->translate('请假事由');
- $headings[] = $doo->translate('请假单位');
- //
- $datas = [];
- foreach ($res as $val) {
- //
- $nickname = Base::filterEmoji($val['start_user_name']);
- $participant = $this->getUserProcessParticipantById($val['id']); // 获取参与人
- $participant = $this->handleParticipant($val, $participant['data']); // 处理参与人返回数据
- //
- $job_number = ''; // 发起人工号
- $department_leader = User::userid2nickname(UserDepartment::find(1, ['owner_userid'])['owner_userid']); // 部门负责人
- $historical_approver = $participant['historical_approver'] ?? ''; // 历史审批人
- $historical_agent = ''; // 历史办理人
- $approval_record = $participant['approval_record'] ?? ''; // 审批记录
- $current_handler = !$val['is_finished'] ? implode(',', User::whereIn('userid', explode(';', $val['candidate']))->pluck('nickname')->toArray()) : ''; // 当前处理人
- $approved_node = $participant['approved_node'] ?? 0; // 审批节点
- $approved_num = $participant['approved_num'] ?? 0; // 审批人数
- // 计算审批耗时
- $startTime = Carbon::parse($val['start_time'])->timestamp;
- $endTime = $val['end_time'] ? Carbon::parse($val['end_time'])->timestamp : time();
- $approval_time = $doo->translate(Timer::timeDiff($startTime, $endTime)); // 审批耗时
- // 计算时长
- $varStartTime = Carbon::parse($val['var']['start_time']);
- $varEndTime = Carbon::parse($val['var']['end_time']);
- $duration = $varEndTime->floatDiffInHours($varStartTime);
- $duration_unit = $doo->translate('小时'); // 时长单位
- $datas[] = [
- $val['id'], // 申请编号
- $val['proc_def_name'], // 标题
- $this->getStateDescription($val['state']), // 申请状态
- $val['start_time'], // 发起时间
- $val['end_time'], // 完成时间
- $job_number, // 发起人工号
- $val['start_user_id'], // 发起人User ID
- $nickname, // 发起人姓名
- $val['department'], // 发起人部门
- $val['department_id'], // 发起人部门ID
- $department_leader, // 部门负责人
- $historical_approver, // 历史审批人
- $historical_agent, // 历史办理人
- $approval_record, // 审批记录
- $current_handler, // 当前处理人
- $approved_node, // 审批节点
- $approved_num, // 审批人数
- $approval_time, // 审批耗时
- $val['var']['type'], // 假期类型
- $val['var']['start_time'], // 开始时间
- $val['var']['end_time'], // 结束时间
- $duration, // 时长
- $val['var']['description'], // 请假事由
- $duration_unit, // 请假单位
- ];
- }
- if (empty($datas)) {
- $content[] = [
- 'content' => '没有任何数据',
- 'style' => 'color: #ff0000;',
- ];
- WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [
- 'type' => 'content',
- 'title' => $content[0]['content'],
- 'content' => $content,
- ], $botUser->userid, true, false, true);
- return;
- }
- //
- $title = $doo->translate("审批记录");
- $sheets = [
- BillExport::create()->setTitle($title)->setHeadings($headings)->setData($datas)->setStyles(["A1:Y1" => ["font" => ["bold" => true]]])
- ];
- //
- $fileName = $title . '_' . Timer::time() . '.xlsx';
- $filePath = "temp/approve/export/" . date("Ym", Timer::time());
- $export = new BillMultipleExport($sheets);
- $res = $export->store($filePath . "/" . $fileName);
- if ($res != 1) {
- $content[] = [
- 'content' => "导出失败,{$fileName}!",
- 'style' => 'color: #ff0000;',
- ];
- WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [
- 'type' => 'content',
- 'title' => $content[0]['content'],
- 'content' => $content,
- ], $botUser->userid, true, false, true);
- return;
- }
- $xlsPath = storage_path("app/" . $filePath . "/" . $fileName);
- $zipFile = "app/" . $filePath . "/" . Base::rightDelete($fileName, '.xlsx') . ".zip";
- $zipPath = storage_path($zipFile);
- if (file_exists($zipPath)) {
- Base::deleteDirAndFile($zipPath, true);
- }
- try {
- Base::zipAddFiles($zipPath, $xlsPath);
- } catch (\Throwable) {
- }
- //
- if (file_exists($zipPath)) {
- $key = Down::cache_encode([
- 'file' => $zipFile,
- ]);
- $fileUrl = Base::fillUrl('api/approve/down?key=' . $key);
- WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [
- 'type' => 'file_download',
- 'title' => '导出审批数据已完成',
- 'name' => $fileName,
- 'size' => filesize($zipPath),
- 'url' => $fileUrl,
- ], $botUser->userid, true, false, true);
- } else {
- $content[] = [
- 'content' => "打包失败,请稍后再试...",
- 'style' => 'color: #ff0000;',
- ];
- WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [
- 'type' => 'content',
- 'title' => $content[0]['content'],
- 'content' => $content,
- ], $botUser->userid, true, false, true);
- }
- });
- //
- WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [
- 'type' => 'content',
- 'content' => '正在导出审批数据,请稍等...',
- ], $botUser->userid, true, false, true);
- //
- return Base::retSuccess('success');
- }
-
- protected function getStateDescription($state)
- {
- $state_map = array(
- 0 => '全部',
- 1 => '审批中',
- 2 => '通过',
- 3 => '拒绝',
- 4 => '撤回'
- );
- return $state_map[$state] ?? '';
- }
-
- /**
- * @api {get} api/approve/down 下载导出的审批数据
- *
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName down
- *
- * @apiParam {String} key 通过export接口得到的下载钥匙
- *
- * @apiSuccess {File} data 返回数据(直接下载文件)
- */
- public function down()
- {
- $array = Down::cache_decode();
- $file = $array['file'];
- if (empty($file) || !file_exists(storage_path($file))) {
- return Base::ajaxError("文件不存在!", [], 0, 403);
- }
- return Response::download(storage_path($file));
- }
-
- // 处理参与人返回数据
- protected function handleParticipant($process, $participant)
- {
- // 如果空
- if (empty($participant)) {
- return [];
- }
- $res = [];
- $historical_approver = [];
- $approved_node = 0; // 审批节点
- $approved_num = 0; // 审批人数
- foreach ($participant as $val) {
- // 如果是审批人
- if ($val['type'] == 'participant') {
- if ($val['step'] != 0) {
- // 过滤掉空的审批意见
- if ($val['comment'] == '' || in_array($val['username'], $historical_approver)) {
- continue;
- }
- $historical_approver = array_unique(array_merge($historical_approver, explode(',', $val['username'])));
- $approved_node++;
- $approved_num++;
- }
- // 审批记录
- $name = $val['username'] . '|';
- $call = $val['step'] == 0 ? '发起审批' . '|' : '同意' . '|';
- $time = $val['step'] == 0 ? $process['start_time'] . '|' : '';
- $comment = $val['step'] == 0 ? '' : ($val['comment'] ?? '') . '|';
- $res['approval_record'] .= $name . $call . $time . $comment;
- }
- }
- $res['historical_approver'] = trim(implode(';', $historical_approver), ';');
- $res['approved_node'] = $approved_node;
- $res['approved_num'] = $approved_num;
- $res['historical_agent'] = $res['historical_approver'];
- return $res;
- }
-
- // 审批机器人消息
- protected function approveMsg($type, $dialog, $botUser, $toUser, $process, $action = null)
- {
- $data = [
- 'id' => $process['id'],
- 'nickname' => User::userid2nickname($type == 'approve_submitter' ? $toUser['userid'] : $process['start_user_id']),
- 'start_nickname' => User::userid2nickname($process['start_user_id']),
- 'proc_def_name' => $process['proc_def_name'],
- 'department' => $process['department'],
- 'type' => $process['var']['type'],
- 'start_time' => $process['var']['start_time'],
- 'start_day_of_week' => '周' . Timer::getWeek(Carbon::parse($process['var']['start_time'])->timestamp),
- 'end_time' => $process['var']['end_time'],
- 'end_day_of_week' => '周' . Timer::getWeek(Carbon::parse($process['var']['end_time'])->timestamp),
- 'description' => $process['var']['description'],
- 'comment_nickname' => $process['comment_user_id'] ? User::userid2nickname($process['comment_user_id']) : '',
- 'comment_content' => $process['comment_contents']['content'] ?? '',
- 'comment_pictures' => $process['comment_contents']['pictures'] ?? []
- ];
- $thumb = null;
- if ($type === 'approve_reviewer') {
- $thumb = $process['var']['other'];
- } elseif ($type === 'approve_comment_notifier') {
- $thumb = $data['comment_pictures'] ? $data['comment_pictures'][0] : null;
- }
- if ($thumb && file_exists(public_path($thumb))) {
- $imageSize = getimagesize(public_path($thumb));
- $data['thumb'] = [
- 'url' => Base::fillUrl($thumb),
- 'width' => $imageSize[0],
- 'height' => $imageSize[1]
- ];
- }
- $msgAction = null;
- $msgData = [
- 'type' => $type,
- 'action' => $action,
- 'is_finished' => $process['is_finished'],
- 'data' => $data
- ];
- $msgData['title'] = match ($type) {
- 'approve_reviewer' => $data['nickname'] . " 提交的「{$data['proc_def_name']}」待你审批",
- 'approve_notifier' => "抄送 {$data['nickname']} 提交的「{$data['proc_def_name']}」记录",
- 'approve_comment_notifier' => $data['comment_nickname'] . " 评论了 {$data['nickname']} 的「{$data['proc_def_name']}」审批",
- 'approve_submitter' => $action == 'pass' ? "您发起的「{$data['proc_def_name']}」已通过" : "您发起的「{$data['proc_def_name']}」被 {$data['nickname']} 拒绝",
- default => '不支持的指令',
- };
- if ($action == 'withdraw' || $action == 'pass' || $action == 'refuse') {
- // 任务完成,给发起人发送消息
- if ($type == 'approve_submitter' && $action != 'withdraw') {
- return WebSocketDialogMsg::sendMsg($msgAction, $dialog->id, 'template', $msgData, $botUser->userid, false, false, true);
- }
- // 查找最后一条消息msg_id
- $msgAction = 'change-' . $toUser['msg_id'];
- }
- //
- $msg = WebSocketDialogMsg::sendMsg($msgAction, $dialog->id, 'template', $msgData, $process['start_user_id'], false, false, true);
- // 关联信息
- if ($action == 'start') {
- $proc_msg = new ApproveProcMsg();
- $proc_msg->proc_inst_id = $process['id'];
- $proc_msg->msg_id = $msg['data']->id;
- $proc_msg->userid = $toUser['userid'];
- $proc_msg->save();
- }
- // 更新审批 未读数量
- if ($type == 'approve_reviewer' && $toUser['userid']) {
- $params = [
- 'userid' => [$toUser['userid'], User::userid()],
- 'msg' => [
- 'type' => 'approve',
- 'action' => 'unread',
- 'userid' => $toUser['userid'],
- ]
- ];
- Task::deliver(new PushTask($params, false));
- }
- return true;
- }
-
- // 根据ID获取流程
- protected function getProcessById($id)
- {
- $data['id'] = intval($id);
- $ret = Ihttp::ihttp_get($this->flow_url . "/api/v1/workflow/process/findById?" . http_build_query($data));
- $process = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$process || $process['status'] != 200) {
- throw new ApiException($process['message'] ?? '查询失败');
- }
- //
- $res = Base::arrayKeyToUnderline($process['data']);
- $res['userids'] = [];
- foreach ($res['node_infos'] as &$val) {
- if (isset($val['node_user_list'])) {
- $node = $val['node_user_list'];
- foreach ($node as $k => &$item) {
- $info = User::whereUserid($item['target_id'])->first();
- if (!$info) {
- continue;
- }
- $val['node_user_list'][$k]['userimg'] = User::getAvatar($info->userid, $info->userimg, $info->email, $info->nickname);
- $res['userids'][] = $item['target_id'];
- }
- } else if ($val['aprover_id']) {
- $info = User::whereUserid($val['aprover_id'])->first();
- $val['userimg'] = $info ? User::getAvatar($info->userid, $info->userimg, $info->email, $info->nickname) : '';
- $res['userids'][] = $val['aprover_id'];
- }
- }
- // 全局评论
- unset($res['global_comment']);
- if (isset($res['global_comments'])) {
- foreach ($res['global_comments'] as $k => $globalComment) {
- $info = User::whereUserid($globalComment['user_id'])->first();
- if (!$info) {
- continue;
- }
- $res['global_comments'][$k]['userimg'] = User::getAvatar($info->userid, $info->userimg, $info->email, $info->nickname);
- $res['global_comments'][$k]['nickname'] = $info->nickname;
- }
- } else {
- $res['global_comments'] = [];
- }
- $info = User::whereUserid($res['start_user_id'])->first();
- $res['userimg'] = $info ? User::getAvatar($info->userid, $info->userimg, $info->email, $info->nickname) : '';
- //
- $res['userids'][] = $info->userid;
- $res['userids'] = array_unique($res['userids']);
- //
- return $res;
- }
-
- // 处理流程节点返回是否有抄送人
- protected function handleProcessNode($process)
- {
- // 获取流程节点
- $process_node = $process['node_infos'];
- $notifier = [];
- foreach ($process_node as $key => $val) {
- if ($val['type'] == 'notifier') {
- $notifier = array_merge($notifier, $val['node_user_list']);
- }
- // 判断到达的节点
- if ($process['node_id'] == $val['node_id']) {
- break;
- }
- }
- return array_unique($notifier, SORT_REGULAR) ?? [];
- }
-
- // 根据ID查询流程实例的参与者(所有)
- protected function getUserProcessParticipantById($id)
- {
- $data['procInstId'] = intval($id);
- $ret = Ihttp::ihttp_get($this->flow_url . "/api/v1/workflow/identitylink/findParticipantAll?" . http_build_query($data));
- $process = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$process || $process['status'] != 200) {
- throw new ApiException($process['message'] ?? '查询失败');
- }
- return $process;
- }
-
-
- /**
- * @api {get} api/approve/user/status 获取用户审批状态
- *
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName user__status
- *
- * @apiParam {String} userid
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function user__status()
- {
- $userid = intval(Request::input('userid'));
- $status = ApproveProcInstHistory::getUserApprovalStatus($userid);
- return Base::retSuccess('success', $status);
- }
-
- /**
- * @api {get} api/approve/process/doto 查询需要我审批的流程数量
- *
- * @apiDescription 需要token身份
- * @apiVersion 1.0.0
- * @apiGroup approve
- * @apiName process__doto
- *
- * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
- * @apiSuccess {String} msg 返回信息(错误描述)
- * @apiSuccess {Object} data 返回数据
- */
- public function process__doto()
- {
- $user = User::auth();
- $ret = Ihttp::ihttp_get($this->flow_url . '/api/v1/workflow/process/findTaskTotal?userid=' . $user->userid);
- $process = json_decode($ret['ret'] == 1 ? $ret['data'] : '{}', true);
- if (!$process || $process['status'] != 200) {
- return Base::retError($process['message'] ?? '查询失败');
- }
- return Base::retSuccess('success', $process['data']);
- }
-
-}
diff --git a/app/Http/Controllers/Api/DialogController.php b/app/Http/Controllers/Api/DialogController.php
index 96e0fd00a..e06ad0b49 100755
--- a/app/Http/Controllers/Api/DialogController.php
+++ b/app/Http/Controllers/Api/DialogController.php
@@ -1257,6 +1257,51 @@ class DialogController extends AbstractController
return $result;
}
+ /**
+ * @api {post} api/dialog/msg/sendapprove 发送审批通知卡片
+ *
+ * @apiDescription 需要token身份。以「审批助手」机器人身份向指定用户发送审批模板卡片
+ * (由 approve 插件调用,卡片仅展示、不与旧审批系统有数据关联)。
+ * @apiVersion 1.0.0
+ * @apiGroup dialog
+ * @apiName msg__sendapprove
+ *
+ * @apiParam {Number} to_userid 接收用户ID
+ * @apiParam {String} type 卡片类型:approve_reviewer / approve_notifier / approve_submitter / approve_comment_notifier
+ * @apiParam {String} [action] 动作:start / pass / refuse / withdraw(按类型取用)
+ * @apiParam {Number} [is_finished] 是否已结束(0/1)
+ * @apiParam {Object} data 卡片数据
+ * @apiParam {String} [title] 消息标题(会话列表预览用)
+ */
+ public function msg__sendapprove()
+ {
+ $user = User::auth();
+ $toUserid = intval(Request::input('to_userid'));
+ $type = trim(Request::input('type'));
+ $action = trim(Request::input('action'));
+ $isFinished = intval(Request::input('is_finished'));
+ $data = Base::json2array(Request::input('data'));
+ $title = trim(Request::input('title'));
+ //
+ $allow = ['approve_reviewer', 'approve_notifier', 'approve_submitter', 'approve_comment_notifier'];
+ if ($toUserid <= 0 || !in_array($type, $allow)) {
+ return Base::retError('参数错误');
+ }
+ $botUser = User::botGetOrCreate('approval-alert');
+ $dialog = WebSocketDialog::checkUserDialog($botUser, $toUserid);
+ if (empty($dialog)) {
+ return Base::retError('无法创建对话');
+ }
+ $msgData = [
+ 'type' => $type,
+ 'action' => $action ?: null,
+ 'is_finished' => $isFinished,
+ 'data' => $data,
+ 'title' => $title,
+ ];
+ return WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', $msgData, $botUser->userid, false, false, true);
+ }
+
/**
* @api {post} api/dialog/msg/sendrecord 发送语音
*
diff --git a/app/Models/ApproveProcInstHistory.php b/app/Models/ApproveProcInstHistory.php
deleted file mode 100644
index 7ce6ba26b..000000000
--- a/app/Models/ApproveProcInstHistory.php
+++ /dev/null
@@ -1,99 +0,0 @@
-addMinute(), function () use ($userid) {
- return self::where([
- ['start_user_id', '=', $userid],
- [DB::raw("JSON_UNQUOTE(JSON_EXTRACT(var, '$.startTime'))"), '<=', Carbon::now()->toDateTimeString()],
- [DB::raw("JSON_UNQUOTE(JSON_EXTRACT(var, '$.endTime'))"), '>=', Carbon::now()->toDateTimeString()],
- ['state', '=', 2]
- ])->where(function ($query) {
- $query->where('proc_def_name', 'like', '%请假%')
- ->orWhere('proc_def_name', 'like', '%外出%');
- })->orderByDesc('id')->value('proc_def_name');
- });
- }
-
- /**
- * 判断用户是否请假(包含:请假、外出)
- * @param $userid
- * @return bool
- */
- public static function userIsLeave($userid)
- {
- return (bool)self::getUserApprovalStatus($userid);
- }
-}
diff --git a/app/Models/ApproveProcMsg.php b/app/Models/ApproveProcMsg.php
deleted file mode 100644
index 7ac5105cd..000000000
--- a/app/Models/ApproveProcMsg.php
+++ /dev/null
@@ -1,34 +0,0 @@
-userid)->where('created_at', '>', Carbon::now()->subDays(3))->exists()) {
continue; // 3天内没有打卡
}
- if (ApproveProcInstHistory::userIsLeave($user->userid)) {
- continue; // 请假、外出
- }
$dialog = WebSocketDialog::checkUserDialog($botUser, $user->userid);
if ($dialog) {
if ($type === 'exceed') {
diff --git a/config/dootask.php b/config/dootask.php
index dfcecdca3..f5ff4f0f9 100644
--- a/config/dootask.php
+++ b/config/dootask.php
@@ -20,9 +20,6 @@ return [
// 创始人密码修改开关:设为 'disabled' 时禁止修改创始人密码(User 模型)
'password_owner' => env('PASSWORD_OWNER'),
- // 审批流服务地址:审批微服务的内部访问 URL(ApproveController)
- 'flow_url' => env('FLOW_URL'),
-
// Manticore 全文搜索服务主机(ManticoreBase)
'search_host' => env('SEARCH_HOST', 'search'),
diff --git a/package.json b/package.json
index eff33ac89..6e7d7bb32 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "DooTask",
- "version": "1.7.90",
+ "version": "1.7.91",
"codeVerson": 237,
"description": "DooTask is task management system.",
"scripts": {
diff --git a/resources/assets/js/App.vue b/resources/assets/js/App.vue
index e8b24bd4f..0a1331047 100755
--- a/resources/assets/js/App.vue
+++ b/resources/assets/js/App.vue
@@ -447,7 +447,6 @@ export default {
'/api/dialog/msg/download', // 会话文件
'/api/project/task/filedown', // 任务文件
'/api/file/download/pack', // 文件打包下载
- '/api/approve/down', // 审批导出下载
'/api/project/task/down', // 任务导出下载
'/api/system/checkin/down' // 签到导出下载
];
diff --git a/resources/assets/js/components/Mobile/Tabbar.vue b/resources/assets/js/components/Mobile/Tabbar.vue
index 2cb2c8b99..873392a7f 100644
--- a/resources/assets/js/components/Mobile/Tabbar.vue
+++ b/resources/assets/js/components/Mobile/Tabbar.vue
@@ -18,7 +18,7 @@
{{$L(datas.var?.type || '- -')}}
-{{ datas.var?.start_time ? getTimeDifference(datas.var?.start_time,datas.var?.end_time)['time'] : '- -' }}
-{{datas.var?.description || '- -'}}
-{{$L('提交')}}
-{{data.start_user_name || datas.start_user_name}}
-{{$L('已提交')}}
-{{ getTimeAgo(item.claim_time) }}
-{{item.claim_time?.substr(0,16)}}
-{{$L('审批')}}
-{{item.approver}}
-- {{$L('待审批')}} -
-- {{$L('审批中')}} - {{$L('已通过')}} - {{$L('已拒绝')}} - {{$L('已撤回')}} -
-- {{ item.identitylink?.state==0 ? - ($L('已等待') + " " + getTimeAgo( datas.node_infos[key-1].claim_time,2)) : - (item.claim_time ? getTimeAgo(item.claim_time) : '') - }} -
-{{item.claim_time?.substr(0,16)}}
-“{{ item.identitylink?.is_system ? $L(item.identitylink?.comment) : item.identitylink?.comment }}”
-{{$L('抄送')}}
-{{$L('系统')}}
-{{$L('自动抄送')}} - {{ item.node_user_list?.map(h=>h.name).join(',') }} - {{$L('共'+item.node_user_list?.length+'人')}} -
-{{$L('结束')}}
-{{$L('系统')}}
-{{ datas.is_finished ? $L('已结束') : $L('未结束') }}
-{{$L('假期类型')}}:{{$L(data.var?.type)}}
-{{$L('开始时间')}}:{{data.var?.start_time}}
-{{$L('结束时间')}}:{{data.var?.end_time}}
-{{$L('流程名称')}}:{{$L(item.name)}}
-{{ msg.data.comment_content }}
-{{$L("状态")}}:{{ msg.is_finished ? $L("已完成") : $L("审批中") }}
{{$L("申请人")}}:@{{ msg.data.nickname }} {{ msg.data.department }}
{{$L("详情")}} -{{$L("假期类型")}}:{{ $L(msg.data.type) }}
-{{$L("开始时间")}}:{{ msg.data.start_time }} ({{ $L(msg.data.start_day_of_week) }})
-{{$L("结束时间")}}:{{ msg.data.end_time }} ({{ $L(msg.data.end_day_of_week) }})
-{{$L("事由")}}:{{ msg.data.description }}
-{{$L("类型")}}:{{ $L(msg.data.type) }}
+{{$L("开始时间")}}:{{ msg.data.start_time }} ({{ $L(msg.data.start_day_of_week) }})
+{{$L("结束时间")}}:{{ msg.data.end_time }} ({{ $L(msg.data.end_day_of_week) }})
+{{$L("事由")}}:{{ msg.data.description }}
{{$L("状态")}}:{{ $L(statusText) }}
{{$L("申请人")}}:@{{ msg.data.nickname }} {{ msg.data.department }}
{{$L("详情")}} -{{$L("假期类型")}}:{{ $L(msg.data.type) }}
-{{$L("开始时间")}}:{{ msg.data.start_time }} ({{ $L(msg.data.start_day_of_week) }})
-{{$L("结束时间")}}:{{ msg.data.end_time }} ({{ $L(msg.data.end_day_of_week) }})
-{{$L("事由")}}:{{ msg.data.description }}
+{{$L("类型")}}:{{ $L(msg.data.type) }}
+{{$L("开始时间")}}:{{ msg.data.start_time }} ({{ $L(msg.data.start_day_of_week) }})
+{{$L("结束时间")}}:{{ msg.data.end_time }} ({{ $L(msg.data.end_day_of_week) }})
+{{$L("事由")}}:{{ msg.data.description }}
{{$L("状态")}}:{{ $L(statusText) }}
{{$L("申请人")}}:@{{ msg.data.start_nickname }} {{ msg.data.department }}
{{$L("详情")}} -{{$L("假期类型")}}:{{ $L(msg.data.type) }}
-{{$L("开始时间")}}:{{ msg.data.start_time }} ({{ $L(msg.data.start_day_of_week) }})
-{{$L("结束时间")}}:{{ msg.data.end_time }} ({{ $L(msg.data.end_day_of_week) }})
-{{$L("事由")}}:{{ msg.data.description }}
-{{$L("类型")}}:{{ $L(msg.data.type) }}
+{{$L("开始时间")}}:{{ msg.data.start_time }} ({{ $L(msg.data.start_day_of_week) }})
+{{$L("结束时间")}}:{{ msg.data.end_time }} ({{ $L(msg.data.end_day_of_week) }})
+{{$L("事由")}}:{{ msg.data.description }}
-
-
-
-
-
-
-
-
- {{ getTimeAgo(item.created_at) }}
-
-
- {{ getContent(item.content) }}
-
-
-
-
-
-
-
-
-
-{{ item.nickname }}
-{{ item.created_at }}
-