mirror of
https://github.com/kuaifan/dootask.git
synced 2026-08-01 19:05:55 +00:00
refactor(approve): 移除主仓库内置审批功能,收敛到插件/微应用
删除 ApproveController、ApproveProcInstHistory/ApproveProcMsg 模型、approve 前端页面与导出组件,移除 approve 路由与 flow_url 配置;审批消息模板改为对接 插件侧能力。版本号 1.7.90 → 1.7.91。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2f8dee44c2
commit
97bd58312e
@ -158,11 +158,6 @@ drawio/webapp/js/app.min.js
|
|||||||
drawio/webapp/js/extensions.min.js
|
drawio/webapp/js/extensions.min.js
|
||||||
drawio/webapp/js/shapes-14-6-5.min.js
|
drawio/webapp/js/shapes-14-6-5.min.js
|
||||||
drawio/webapp/js/stencils.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
|
drawio/webapp/styles/grapheditor.css
|
||||||
|
|
||||||
minder/css/chunk-vendors.fe9c56c6.css
|
minder/css/chunk-vendors.fe9c56c6.css
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1257,6 +1257,51 @@ class DialogController extends AbstractController
|
|||||||
return $result;
|
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 发送语音
|
* @api {post} api/dialog/msg/sendrecord 发送语音
|
||||||
*
|
*
|
||||||
|
|||||||
@ -1,99 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Cache;
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use DB;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* App\Models\ApproveProcInstHistory
|
|
||||||
*
|
|
||||||
* @property int $id
|
|
||||||
* @property int $proc_def_id 流程定义ID
|
|
||||||
* @property string|null $proc_def_name 流程定义名
|
|
||||||
* @property string|null $title 标题
|
|
||||||
* @property int|null $department_id 用户部门ID
|
|
||||||
* @property string|null $department 用户部门
|
|
||||||
* @property string|null $company 用户公司
|
|
||||||
* @property string|null $node_id 当前节点
|
|
||||||
* @property string|null $candidate 审批人
|
|
||||||
* @property int|null $task_id 当前任务
|
|
||||||
* @property string|null $start_time 开始时间
|
|
||||||
* @property string|null $end_time 结束时间
|
|
||||||
* @property int|null $duration 持续时间
|
|
||||||
* @property string|null $start_user_id 开始用户ID
|
|
||||||
* @property string|null $start_user_name 开始用户名
|
|
||||||
* @property int|null $is_finished 是否完成
|
|
||||||
* @property string|null $var
|
|
||||||
* @property int $state 当前状态: 0待审批,1审批中,2通过,3拒绝,4撤回
|
|
||||||
* @property string|null $latest_comment
|
|
||||||
* @property string|null $global_comment
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel cancelAppend()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel cancelHidden()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel change($array)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel getKeyValue()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory newModelQuery()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory newQuery()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory query()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel remove()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel saveOrIgnore()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereCandidate($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereCompany($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereDepartment($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereDepartmentId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereDuration($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereEndTime($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereGlobalComment($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereIsFinished($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereLatestComment($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereNodeId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereProcDefId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereProcDefName($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereStartTime($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereStartUserId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereStartUserName($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereState($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereTaskId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereTitle($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcInstHistory whereVar($value)
|
|
||||||
* @mixin \Eloquent
|
|
||||||
*/
|
|
||||||
class ApproveProcInstHistory extends AbstractModel
|
|
||||||
{
|
|
||||||
protected $table = 'approve_proc_inst_history';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取用户审批状态(请假、外出)
|
|
||||||
* @param $userid
|
|
||||||
* @return mixed|null
|
|
||||||
*/
|
|
||||||
public static function getUserApprovalStatus($userid)
|
|
||||||
{
|
|
||||||
if (empty($userid)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return Cache::remember('user_is_leave_' . $userid, Carbon::now()->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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* App\Models\ApproveProcMsg
|
|
||||||
*
|
|
||||||
* @property int $id
|
|
||||||
* @property int|null $proc_inst_id 流程实例ID
|
|
||||||
* @property int|null $userid 会员ID
|
|
||||||
* @property int|null $msg_id 消息ID
|
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
|
||||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel cancelAppend()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel cancelHidden()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel change($array)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel getKeyValue()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcMsg newModelQuery()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcMsg newQuery()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcMsg query()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel remove()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel saveOrIgnore()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcMsg whereCreatedAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcMsg whereId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcMsg whereMsgId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcMsg whereProcInstId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcMsg whereUpdatedAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApproveProcMsg whereUserid($value)
|
|
||||||
* @mixin \Eloquent
|
|
||||||
*/
|
|
||||||
class ApproveProcMsg extends AbstractModel
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace App\Tasks;
|
namespace App\Tasks;
|
||||||
|
|
||||||
use App\Models\ApproveProcInstHistory;
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Models\UserCheckinRecord;
|
use App\Models\UserCheckinRecord;
|
||||||
use App\Models\WebSocketDialog;
|
use App\Models\WebSocketDialog;
|
||||||
@ -80,9 +79,6 @@ class CheckinRemindTask extends AbstractTask
|
|||||||
if (!UserCheckinRecord::whereUserid($user->userid)->where('created_at', '>', Carbon::now()->subDays(3))->exists()) {
|
if (!UserCheckinRecord::whereUserid($user->userid)->where('created_at', '>', Carbon::now()->subDays(3))->exists()) {
|
||||||
continue; // 3天内没有打卡
|
continue; // 3天内没有打卡
|
||||||
}
|
}
|
||||||
if (ApproveProcInstHistory::userIsLeave($user->userid)) {
|
|
||||||
continue; // 请假、外出
|
|
||||||
}
|
|
||||||
$dialog = WebSocketDialog::checkUserDialog($botUser, $user->userid);
|
$dialog = WebSocketDialog::checkUserDialog($botUser, $user->userid);
|
||||||
if ($dialog) {
|
if ($dialog) {
|
||||||
if ($type === 'exceed') {
|
if ($type === 'exceed') {
|
||||||
|
|||||||
@ -20,9 +20,6 @@ return [
|
|||||||
// 创始人密码修改开关:设为 'disabled' 时禁止修改创始人密码(User 模型)
|
// 创始人密码修改开关:设为 'disabled' 时禁止修改创始人密码(User 模型)
|
||||||
'password_owner' => env('PASSWORD_OWNER'),
|
'password_owner' => env('PASSWORD_OWNER'),
|
||||||
|
|
||||||
// 审批流服务地址:审批微服务的内部访问 URL(ApproveController)
|
|
||||||
'flow_url' => env('FLOW_URL'),
|
|
||||||
|
|
||||||
// Manticore 全文搜索服务主机(ManticoreBase)
|
// Manticore 全文搜索服务主机(ManticoreBase)
|
||||||
'search_host' => env('SEARCH_HOST', 'search'),
|
'search_host' => env('SEARCH_HOST', 'search'),
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "DooTask",
|
"name": "DooTask",
|
||||||
"version": "1.7.90",
|
"version": "1.7.91",
|
||||||
"codeVerson": 237,
|
"codeVerson": 237,
|
||||||
"description": "DooTask is task management system.",
|
"description": "DooTask is task management system.",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@ -447,7 +447,6 @@ export default {
|
|||||||
'/api/dialog/msg/download', // 会话文件
|
'/api/dialog/msg/download', // 会话文件
|
||||||
'/api/project/task/filedown', // 任务文件
|
'/api/project/task/filedown', // 任务文件
|
||||||
'/api/file/download/pack', // 文件打包下载
|
'/api/file/download/pack', // 文件打包下载
|
||||||
'/api/approve/down', // 审批导出下载
|
|
||||||
'/api/project/task/down', // 任务导出下载
|
'/api/project/task/down', // 任务导出下载
|
||||||
'/api/system/checkin/down' // 签到导出下载
|
'/api/system/checkin/down' // 签到导出下载
|
||||||
];
|
];
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
<Badge class="tabbar-badge" :overflow-count="999" :text="msgUnreadMention"/>
|
<Badge class="tabbar-badge" :overflow-count="999" :text="msgUnreadMention"/>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="item.name === 'application'">
|
<template v-else-if="item.name === 'application'">
|
||||||
<Badge class="tabbar-badge" :overflow-count="999" :count="reportUnreadNumber + approveUnreadNumber"/>
|
<Badge class="tabbar-badge" :overflow-count="999" :count="reportUnreadNumber"/>
|
||||||
</template>
|
</template>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -54,7 +54,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['cacheDialogs', 'reportUnreadNumber', 'approveUnreadNumber']),
|
...mapState(['cacheDialogs', 'reportUnreadNumber']),
|
||||||
...mapGetters(['dashboardTask']),
|
...mapGetters(['dashboardTask']),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,7 +138,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
activeName() {
|
activeName() {
|
||||||
if (['manage-calendar', 'manage-file', 'manage-setting', 'manage-application', 'manage-approve'].includes(this.routeName)) {
|
if (['manage-calendar', 'manage-file', 'manage-setting', 'manage-application'].includes(this.routeName)) {
|
||||||
return 'application';
|
return 'application';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -82,7 +82,6 @@
|
|||||||
<DropdownItem name="allUser">{{$L('团队管理')}}</DropdownItem>
|
<DropdownItem name="allUser">{{$L('团队管理')}}</DropdownItem>
|
||||||
<DropdownItem name="exportTask">{{$L('导出任务统计')}}</DropdownItem>
|
<DropdownItem name="exportTask">{{$L('导出任务统计')}}</DropdownItem>
|
||||||
<DropdownItem name="exportOverdueTask">{{$L('导出超期任务')}}</DropdownItem>
|
<DropdownItem name="exportOverdueTask">{{$L('导出超期任务')}}</DropdownItem>
|
||||||
<DropdownItem name="exportApprove">{{$L('导出审批数据')}}</DropdownItem>
|
|
||||||
<DropdownItem name="exportCheckin">{{$L('导出签到数据')}}</DropdownItem>
|
<DropdownItem name="exportCheckin">{{$L('导出签到数据')}}</DropdownItem>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
@ -126,10 +125,6 @@
|
|||||||
v-else-if="item.path === 'workReport' && reportUnreadNumber > 0"
|
v-else-if="item.path === 'workReport' && reportUnreadNumber > 0"
|
||||||
class="manage-menu-report-badge"
|
class="manage-menu-report-badge"
|
||||||
:count="reportUnreadNumber"/>
|
:count="reportUnreadNumber"/>
|
||||||
<Badge
|
|
||||||
v-else-if="item.path === 'approve' && approveUnreadNumber > 0"
|
|
||||||
class="manage-menu-report-badge"
|
|
||||||
:count="approveUnreadNumber"/>
|
|
||||||
</div>
|
</div>
|
||||||
</DropdownItem>
|
</DropdownItem>
|
||||||
</template>
|
</template>
|
||||||
@ -162,7 +157,7 @@
|
|||||||
<li @click="toggleRoute('application')" :class="classNameRoute('application')">
|
<li @click="toggleRoute('application')" :class="classNameRoute('application')">
|
||||||
<i class="taskfont"></i>
|
<i class="taskfont"></i>
|
||||||
<div class="menu-title">{{$L('应用')}}</div>
|
<div class="menu-title">{{$L('应用')}}</div>
|
||||||
<Badge class="menu-badge" :overflow-count="999" :text="String((reportUnreadNumber + approveUnreadNumber) || '')"/>
|
<Badge class="menu-badge" :overflow-count="999" :text="String(reportUnreadNumber || '')"/>
|
||||||
</li>
|
</li>
|
||||||
<li v-for="(item, key) in filterMicroAppsMenusMain" :key="key" @click="onTabbarClick('microApp', item)">
|
<li v-for="(item, key) in filterMicroAppsMenusMain" :key="key" @click="onTabbarClick('microApp', item)">
|
||||||
<div class="apply-icon no-dark-content" :style="{backgroundImage: `url(${item.icon})`}"></div>
|
<div class="apply-icon no-dark-content" :style="{backgroundImage: `url(${item.icon})`}"></div>
|
||||||
@ -389,9 +384,6 @@
|
|||||||
<!--导出签到数据-->
|
<!--导出签到数据-->
|
||||||
<CheckinExport v-model="exportCheckinShow"/>
|
<CheckinExport v-model="exportCheckinShow"/>
|
||||||
|
|
||||||
<!--导出审批数据-->
|
|
||||||
<ApproveExport v-model="exportApproveShow"/>
|
|
||||||
|
|
||||||
<!--任务详情-->
|
<!--任务详情-->
|
||||||
<TaskModal ref="taskModal"/>
|
<TaskModal ref="taskModal"/>
|
||||||
|
|
||||||
@ -457,16 +449,6 @@
|
|||||||
<ProjectArchived v-if="archivedProjectShow"/>
|
<ProjectArchived v-if="archivedProjectShow"/>
|
||||||
</DrawerOverlay>
|
</DrawerOverlay>
|
||||||
|
|
||||||
<!--审批中心-->
|
|
||||||
<DrawerOverlay v-model="approveShow" placement="right" :size="1380" class-name="approve-drawer">
|
|
||||||
<Approve v-if="approveShow"/>
|
|
||||||
</DrawerOverlay>
|
|
||||||
|
|
||||||
<!--审批详情-->
|
|
||||||
<DrawerOverlay v-model="approveDetailsShow" placement="right" :size="600">
|
|
||||||
<ApproveDetails v-if="approveDetailsShow" :data="approveDetails"/>
|
|
||||||
</DrawerOverlay>
|
|
||||||
|
|
||||||
<!--移动端选项卡-->
|
<!--移动端选项卡-->
|
||||||
<transition name="mobile-slide">
|
<transition name="mobile-slide">
|
||||||
<MobileTabbar v-if="mobileTabbar" @on-click="onTabbarClick"/>
|
<MobileTabbar v-if="mobileTabbar" @on-click="onTabbarClick"/>
|
||||||
@ -495,14 +477,11 @@ import DialogModal from "./manage/components/DialogModal";
|
|||||||
import TaskModal from "./manage/components/TaskModal";
|
import TaskModal from "./manage/components/TaskModal";
|
||||||
import CheckinExport from "./manage/components/CheckinExport";
|
import CheckinExport from "./manage/components/CheckinExport";
|
||||||
import TaskExport from "./manage/components/TaskExport";
|
import TaskExport from "./manage/components/TaskExport";
|
||||||
import ApproveExport from "./manage/components/ApproveExport";
|
|
||||||
import ComplaintManagement from "./manage/components/ComplaintManagement";
|
import ComplaintManagement from "./manage/components/ComplaintManagement";
|
||||||
import MicroApps from "../components/MicroApps";
|
import MicroApps from "../components/MicroApps";
|
||||||
import ResizeLine from "../components/ResizeLine.vue";
|
import ResizeLine from "../components/ResizeLine.vue";
|
||||||
import UserSelect from "../components/UserSelect.vue";
|
import UserSelect from "../components/UserSelect.vue";
|
||||||
import ImgUpload from "../components/ImgUpload.vue";
|
import ImgUpload from "../components/ImgUpload.vue";
|
||||||
import Approve from "./manage/approve/index.vue";
|
|
||||||
import ApproveDetails from "./manage/approve/details.vue";
|
|
||||||
import notificationKoro from "notification-koro1";
|
import notificationKoro from "notification-koro1";
|
||||||
import emitter from "../store/events";
|
import emitter from "../store/events";
|
||||||
import SearchBox from "../components/SearchBox.vue";
|
import SearchBox from "../components/SearchBox.vue";
|
||||||
@ -514,14 +493,11 @@ import DepartmentOwnerView from "./manage/components/DepartmentOwnerView.vue";
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Approve,
|
|
||||||
SearchBox,
|
SearchBox,
|
||||||
ApproveDetails,
|
|
||||||
ImgUpload,
|
ImgUpload,
|
||||||
UserSelect,
|
UserSelect,
|
||||||
TaskExport,
|
TaskExport,
|
||||||
CheckinExport,
|
CheckinExport,
|
||||||
ApproveExport,
|
|
||||||
TaskModal,
|
TaskModal,
|
||||||
DialogModal,
|
DialogModal,
|
||||||
MobileTabbar,
|
MobileTabbar,
|
||||||
@ -568,7 +544,6 @@ export default {
|
|||||||
|
|
||||||
exportTaskShow: false,
|
exportTaskShow: false,
|
||||||
exportCheckinShow: false,
|
exportCheckinShow: false,
|
||||||
exportApproveShow: false,
|
|
||||||
|
|
||||||
projectKeyValue: '',
|
projectKeyValue: '',
|
||||||
projectKeyLoading: 0,
|
projectKeyLoading: 0,
|
||||||
@ -600,10 +575,6 @@ export default {
|
|||||||
|
|
||||||
complaintShow: false,
|
complaintShow: false,
|
||||||
|
|
||||||
approveShow: false,
|
|
||||||
approveDetails: {id: 0},
|
|
||||||
approveDetailsShow: false,
|
|
||||||
|
|
||||||
taskBrowseLoading: false,
|
taskBrowseLoading: false,
|
||||||
taskBrowseHistory: [],
|
taskBrowseHistory: [],
|
||||||
|
|
||||||
@ -621,7 +592,6 @@ export default {
|
|||||||
emitter.on('addTask', this.onAddTask);
|
emitter.on('addTask', this.onAddTask);
|
||||||
emitter.on('createGroup', this.onCreateGroup);
|
emitter.on('createGroup', this.onCreateGroup);
|
||||||
emitter.on('dialogMsgPush', this.addDialogMsg);
|
emitter.on('dialogMsgPush', this.addDialogMsg);
|
||||||
emitter.on('approveDetails', this.openApproveDetails);
|
|
||||||
emitter.on('openReport', this.openReport);
|
emitter.on('openReport', this.openReport);
|
||||||
emitter.on('openFavorite', this.openFavorite);
|
emitter.on('openFavorite', this.openFavorite);
|
||||||
emitter.on('openRecent', this.openRecent);
|
emitter.on('openRecent', this.openRecent);
|
||||||
@ -634,14 +604,12 @@ export default {
|
|||||||
this.$store.dispatch("getUserInfo").catch(_ => {})
|
this.$store.dispatch("getUserInfo").catch(_ => {})
|
||||||
this.$store.dispatch("getTaskPriority", 1000)
|
this.$store.dispatch("getTaskPriority", 1000)
|
||||||
this.$store.dispatch("getReportUnread", 1000)
|
this.$store.dispatch("getReportUnread", 1000)
|
||||||
this.$store.dispatch("getApproveUnread", 1000)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
emitter.off('addTask', this.onAddTask);
|
emitter.off('addTask', this.onAddTask);
|
||||||
emitter.off('createGroup', this.onCreateGroup);
|
emitter.off('createGroup', this.onCreateGroup);
|
||||||
emitter.off('dialogMsgPush', this.addDialogMsg);
|
emitter.off('dialogMsgPush', this.addDialogMsg);
|
||||||
emitter.off('approveDetails', this.openApproveDetails);
|
|
||||||
emitter.off('openReport', this.openReport);
|
emitter.off('openReport', this.openReport);
|
||||||
emitter.off('openFavorite', this.openFavorite);
|
emitter.off('openFavorite', this.openFavorite);
|
||||||
emitter.off('openRecent', this.openRecent);
|
emitter.off('openRecent', this.openRecent);
|
||||||
@ -671,7 +639,6 @@ export default {
|
|||||||
'clientDownloadUrl',
|
'clientDownloadUrl',
|
||||||
|
|
||||||
'reportUnreadNumber',
|
'reportUnreadNumber',
|
||||||
'approveUnreadNumber',
|
|
||||||
|
|
||||||
'dialogIns',
|
'dialogIns',
|
||||||
'formOptions',
|
'formOptions',
|
||||||
@ -1112,9 +1079,6 @@ export default {
|
|||||||
case 'exportCheckin':
|
case 'exportCheckin':
|
||||||
this.exportCheckinShow = true;
|
this.exportCheckinShow = true;
|
||||||
return;
|
return;
|
||||||
case 'exportApprove':
|
|
||||||
this.exportApproveShow = true;
|
|
||||||
return;
|
|
||||||
case 'workReport':
|
case 'workReport':
|
||||||
this.openReport(this.reportUnreadNumber > 0 ? 'receive' : 'my');
|
this.openReport(this.reportUnreadNumber > 0 ? 'receive' : 'my');
|
||||||
return;
|
return;
|
||||||
@ -1132,11 +1096,6 @@ export default {
|
|||||||
$A.reloadUrl()
|
$A.reloadUrl()
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
case 'approve':
|
|
||||||
if (this.menu.findIndex((m) => m.path == path) > -1) {
|
|
||||||
this.goForward({name: 'manage-approve'});
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case 'complaint':
|
case 'complaint':
|
||||||
this.complaintShow = true;
|
this.complaintShow = true;
|
||||||
return;
|
return;
|
||||||
@ -1201,10 +1160,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
classNameRoute(path) {
|
classNameRoute(path) {
|
||||||
let name = this.routeName
|
const name = this.routeName
|
||||||
if (name == 'manage-approve') {
|
|
||||||
name = `manage-application`
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
"active": name === `manage-${path}`,
|
"active": name === `manage-${path}`,
|
||||||
};
|
};
|
||||||
@ -1678,13 +1634,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
openApproveDetails(id) {
|
|
||||||
this.approveDetailsShow = true;
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.approveDetails = {id};
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
openReport(tab) {
|
openReport(tab) {
|
||||||
this.workReportTab = tab;
|
this.workReportTab = tab;
|
||||||
this.workReportShow = true;
|
this.workReportShow = true;
|
||||||
@ -1706,9 +1655,6 @@ export default {
|
|||||||
case 'overdue':
|
case 'overdue':
|
||||||
this.exportOverdueTask();
|
this.exportOverdueTask();
|
||||||
break;
|
break;
|
||||||
case 'approve':
|
|
||||||
this.exportApproveShow = true;
|
|
||||||
break;
|
|
||||||
case 'checkin':
|
case 'checkin':
|
||||||
this.exportCheckinShow = true;
|
this.exportCheckinShow = true;
|
||||||
break;
|
break;
|
||||||
@ -1776,9 +1722,6 @@ export default {
|
|||||||
|
|
||||||
onTabbarClick(act, params = '') {
|
onTabbarClick(act, params = '') {
|
||||||
switch (act) {
|
switch (act) {
|
||||||
case 'approve':
|
|
||||||
this.approveShow = true
|
|
||||||
break;
|
|
||||||
case 'createGroup':
|
case 'createGroup':
|
||||||
this.onAddMenu('group')
|
this.onAddMenu('group')
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -97,7 +97,6 @@
|
|||||||
v-if="!sortingMode"
|
v-if="!sortingMode"
|
||||||
@click.stop="handleCardClick(card, 'badge')"
|
@click.stop="handleCardClick(card, 'badge')"
|
||||||
class="apply-box-top-report">
|
class="apply-box-top-report">
|
||||||
<Badge v-if="showBadge(card.system,'approve')" :overflow-count="999" :count="approveUnreadNumber"/>
|
|
||||||
<Badge v-if="showBadge(card.system,'report')" :overflow-count="999" :count="reportUnreadNumber"/>
|
<Badge v-if="showBadge(card.system,'report')" :overflow-count="999" :count="reportUnreadNumber"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -528,7 +527,6 @@ export default {
|
|||||||
'userInfo',
|
'userInfo',
|
||||||
'userIsAdmin',
|
'userIsAdmin',
|
||||||
'reportUnreadNumber',
|
'reportUnreadNumber',
|
||||||
'approveUnreadNumber',
|
|
||||||
'cacheDialogs',
|
'cacheDialogs',
|
||||||
'windowOrientation',
|
'windowOrientation',
|
||||||
'windowPortrait',
|
'windowPortrait',
|
||||||
@ -543,7 +541,6 @@ export default {
|
|||||||
applyList() {
|
applyList() {
|
||||||
const list = [
|
const list = [
|
||||||
// 常用应用
|
// 常用应用
|
||||||
{value: "approve", label: "审批中心", sort: 30, show: this.microAppsIds.includes('approve')},
|
|
||||||
{value: "favorite", label: "我的收藏", sort: 45},
|
{value: "favorite", label: "我的收藏", sort: 45},
|
||||||
{value: "recent", label: "最近打开", sort: 47},
|
{value: "recent", label: "最近打开", sort: 47},
|
||||||
{value: "report", label: "工作报告", sort: 50},
|
{value: "report", label: "工作报告", sort: 50},
|
||||||
@ -985,7 +982,6 @@ export default {
|
|||||||
const list = [
|
const list = [
|
||||||
{label: this.$L('导出任务统计'), value: 'task'},
|
{label: this.$L('导出任务统计'), value: 'task'},
|
||||||
{label: this.$L('导出超期任务'), value: 'overdue'},
|
{label: this.$L('导出超期任务'), value: 'overdue'},
|
||||||
{label: this.$L('导出审批数据'), value: 'approve'},
|
|
||||||
{label: this.$L('导出签到数据'), value: 'checkin'},
|
{label: this.$L('导出签到数据'), value: 'checkin'},
|
||||||
];
|
];
|
||||||
this.$store.commit('menu/operation', {
|
this.$store.commit('menu/operation', {
|
||||||
@ -1037,9 +1033,6 @@ export default {
|
|||||||
showBadge(item, type) {
|
showBadge(item, type) {
|
||||||
let num = 0;
|
let num = 0;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'approve':
|
|
||||||
num = this.approveUnreadNumber;
|
|
||||||
break;
|
|
||||||
case 'report':
|
case 'report':
|
||||||
num = this.reportUnreadNumber;
|
num = this.reportUnreadNumber;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -1,550 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="approve-details" :style="{'z-index':modalTransferIndex}">
|
|
||||||
<!-- 审批详情 -->
|
|
||||||
<div v-if="datas.id" class="approve-details-box" ref="approveDetailsBox">
|
|
||||||
<h2 class="approve-details-title">
|
|
||||||
<span>{{$L(datas.proc_def_name || '- -')}}</span>
|
|
||||||
<Tag v-if="datas.state == 0" color="cyan">{{$L('待审批')}}</Tag>
|
|
||||||
<Tag v-if="datas.state == 1" color="cyan">{{$L('审批中')}}</Tag>
|
|
||||||
<Tag v-if="datas.state == 2" color="green">{{$L('已通过')}}</Tag>
|
|
||||||
<Tag v-if="datas.state == 3" color="red">{{$L('已拒绝')}}</Tag>
|
|
||||||
<Tag v-if="datas.state == 4" color="red">{{$L('已撤回')}}</Tag>
|
|
||||||
</h2>
|
|
||||||
<h3 class="approve-details-subtitle">
|
|
||||||
<span @click="onAvatar(datas.start_user_id)">
|
|
||||||
<Avatar :src="datas.userimg" size="24"/>
|
|
||||||
</span>
|
|
||||||
<span>{{datas.start_user_name}}</span>
|
|
||||||
</h3>
|
|
||||||
<h3 class="approve-details-subtitle"><span>{{$L('提交于')}} {{datas.start_time}}</span></h3>
|
|
||||||
|
|
||||||
<Divider/>
|
|
||||||
|
|
||||||
<div class="approve-details-text" v-if="(datas.proc_def_name || '').indexOf('请假') !== -1 && datas.var?.type">
|
|
||||||
<h4>{{$L('假期类型')}}</h4>
|
|
||||||
<p>{{$L(datas.var?.type || '- -')}}</p>
|
|
||||||
</div>
|
|
||||||
<div class="approve-details-text">
|
|
||||||
<h4>{{$L('开始时间')}}</h4>
|
|
||||||
<div class="time-text">
|
|
||||||
<span>{{datas.var?.start_time || '- -'}}</span>
|
|
||||||
<span v-if="datas.var?.start_time">({{getWeekday(datas.var?.start_time)}})</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="approve-details-text">
|
|
||||||
<h4>{{$L('结束时间')}}</h4>
|
|
||||||
<div class="time-text">
|
|
||||||
<span>{{datas.var?.end_time || '- -'}}</span>
|
|
||||||
<span v-if="datas.var?.end_time">({{getWeekday(datas.var?.end_time)}})</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="approve-details-text">
|
|
||||||
<h4>{{ $L('时长') }}({{getTimeDifference(datas.var?.start_time,datas.var?.end_time)['unit']}})</h4>
|
|
||||||
<p>{{ datas.var?.start_time ? getTimeDifference(datas.var?.start_time,datas.var?.end_time)['time'] : '- -' }}</p>
|
|
||||||
</div>
|
|
||||||
<div class="approve-details-text">
|
|
||||||
<h4>{{$L('事由')}}</h4>
|
|
||||||
<p class="wrap-text">{{datas.var?.description || '- -'}}</p>
|
|
||||||
</div>
|
|
||||||
<div class="approve-details-text" v-if="datas.var?.other">
|
|
||||||
<h4>{{$L('图片')}}</h4>
|
|
||||||
<div class="img-body">
|
|
||||||
<div v-for="(src,key) in (datas.var.other).split(',')" @click="onViewPicture(src, 1)">
|
|
||||||
<ImgView :src="src" :key="key" class="img-view"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Divider/>
|
|
||||||
|
|
||||||
<h3 class="approve-details-subtitle">{{$L('审批记录')}}</h3>
|
|
||||||
<Timeline class="approve-record-timeline">
|
|
||||||
<template v-for="(item,key) in datas.node_infos">
|
|
||||||
|
|
||||||
<!-- 提交 -->
|
|
||||||
<TimelineItem :key="key" v-if="item.type == 'starter'" color="green">
|
|
||||||
<p class="timeline-title">{{$L('提交')}}</p>
|
|
||||||
<div class="timeline-body">
|
|
||||||
<div class="approve-process-avatar" @click="onAvatar(data.start_user_id || datas.start_user_id)">
|
|
||||||
<Avatar :src="data.userimg || datas.userimg" size="38"/>
|
|
||||||
</div>
|
|
||||||
<div class="approve-process-left">
|
|
||||||
<p class="approve-process-name">{{data.start_user_name || datas.start_user_name}}</p>
|
|
||||||
<p class="approve-process-state">{{$L('已提交')}}</p>
|
|
||||||
</div>
|
|
||||||
<div class="approve-process-right">
|
|
||||||
<p v-if="parseInt(getTimeAgo(item.claim_time)) < showTimeNum">{{ getTimeAgo(item.claim_time) }}</p>
|
|
||||||
<p>{{item.claim_time?.substr(0,16)}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</TimelineItem>
|
|
||||||
|
|
||||||
<!-- 审批 -->
|
|
||||||
<TimelineItem
|
|
||||||
v-if="item.type == 'approver' && item._show"
|
|
||||||
:key="key"
|
|
||||||
:color="item.identitylink ? (item.identitylink?.state > 1 ? '#f03f3f' :'green') : '#ccc'">
|
|
||||||
<p class="timeline-title">{{$L('审批')}}</p>
|
|
||||||
<div class="timeline-body">
|
|
||||||
<div class="approve-process-avatar" @click="onAvatar(item.node_user_list && item.node_user_list[0]?.target_id || item.aprover_id)">
|
|
||||||
<Avatar :src="(item.node_user_list && item.node_user_list[0]?.userimg) || item.userimg" size="38"/>
|
|
||||||
</div>
|
|
||||||
<div class="approve-process-left">
|
|
||||||
<p class="approve-process-name">{{item.approver}}</p>
|
|
||||||
<p v-if="!item.identitylink" class="approve-process-state">
|
|
||||||
<span style="color:#6d6d6d;">{{$L('待审批')}}</span>
|
|
||||||
</p>
|
|
||||||
<p v-else class="approve-process-state">
|
|
||||||
<span v-if="item.identitylink.state==0" style="color:#496dff;">{{$L('审批中')}}</span>
|
|
||||||
<span v-if="item.identitylink.state==1" >{{$L('已通过')}}</span>
|
|
||||||
<span v-if="item.identitylink.state==2" style="color:#f03f3f;">{{$L('已拒绝')}}</span>
|
|
||||||
<span v-if="item.identitylink.state==3" style="color:#f03f3f;">{{$L('已撤回')}}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="approve-process-right">
|
|
||||||
<p v-if="parseInt(getTimeAgo(item.claim_time)) < showTimeNum">
|
|
||||||
{{ item.identitylink?.state==0 ?
|
|
||||||
($L('已等待') + " " + getTimeAgo( datas.node_infos[key-1].claim_time,2)) :
|
|
||||||
(item.claim_time ? getTimeAgo(item.claim_time) : '')
|
|
||||||
}}
|
|
||||||
</p>
|
|
||||||
<p>{{item.claim_time?.substr(0,16)}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p class="comment" v-if="item.identitylink?.comment"><span>“{{ item.identitylink?.is_system ? $L(item.identitylink?.comment) : item.identitylink?.comment }}”</span></p>
|
|
||||||
</TimelineItem>
|
|
||||||
|
|
||||||
<!-- 抄送 -->
|
|
||||||
<TimelineItem :key="key" :color="item.is_finished ? 'green' : '#ccc'" v-if="item.type == 'notifier' && item._show">
|
|
||||||
<p class="timeline-title">{{$L('抄送')}}</p>
|
|
||||||
<div class="timeline-body">
|
|
||||||
<Avatar :src="$A.mainUrl('images/avatar/default_approval.png')" size="38"/>
|
|
||||||
<div class="approve-process-left">
|
|
||||||
<p class="approve-process-name">{{$L('系统')}}</p>
|
|
||||||
<p class="approve-process-desc">{{$L('自动抄送')}}
|
|
||||||
<span style="color: #486fed;">{{ item.node_user_list?.map(h=>h.name).join(',') }}</span>
|
|
||||||
{{$L('共'+item.node_user_list?.length+'人')}}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</TimelineItem>
|
|
||||||
|
|
||||||
<!-- 结束 -->
|
|
||||||
<TimelineItem class="finish" :key="key" :color="item.is_finished ? 'green' : '#ccc'" v-if="item.aprover_type == 'end'">
|
|
||||||
<p class="timeline-title">{{$L('结束')}}</p>
|
|
||||||
<div class="timeline-body">
|
|
||||||
<Avatar :src="$A.mainUrl('images/avatar/default_approval.png')" size="38"/>
|
|
||||||
<div class="approve-process-left">
|
|
||||||
<p class="approve-process-name">{{$L('系统')}}</p>
|
|
||||||
<p class="approve-process-desc"> {{ datas.is_finished ? $L('已结束') : $L('未结束') }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</TimelineItem>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
</Timeline>
|
|
||||||
|
|
||||||
<template v-if="$A.arrayLength(datas.global_comments) > 0">
|
|
||||||
<Divider/>
|
|
||||||
<h3 class="approve-details-subtitle">{{$L('全文评论')}}</h3>
|
|
||||||
<div class="approve-record-comment">
|
|
||||||
<List :split="false" :border="false">
|
|
||||||
<ListItem v-for="(item, key) in datas.global_comments" :key="key">
|
|
||||||
<div>
|
|
||||||
<div class="top">
|
|
||||||
<span @click="onAvatar(item.user_id)">
|
|
||||||
<Avatar :src="item.userimg" size="38"/>
|
|
||||||
</span>
|
|
||||||
<div>
|
|
||||||
<p>{{ item.nickname }}</p>
|
|
||||||
<p class="time">{{ item.created_at }}</p>
|
|
||||||
</div>
|
|
||||||
<span>{{ getTimeAgo(item.created_at) }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="content">
|
|
||||||
{{ getContent(item.content) }}
|
|
||||||
</div>
|
|
||||||
<div class="content" style="display: flex; gap: 10px;">
|
|
||||||
<div v-for="(src, k) in getPictures(item.content)" :key="k" @click="onViewPicture(src, 2)">
|
|
||||||
<ImgView :src="getPictureThumb(src)" :error-src="src" class="img-view"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ListItem>
|
|
||||||
</List>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--审批操作-->
|
|
||||||
<div v-if="datas.id" class="approve-operation">
|
|
||||||
<Button type="primary" v-if="isShowAgreeBtn && !loadIng" @click="approve(1)">{{$L('同意')}}</Button>
|
|
||||||
<Button type="error" v-if="isShowAgreeBtn && !loadIng" @click="approve(2)">{{$L('拒绝')}}</Button>
|
|
||||||
<Button type="warning" v-if="isShowWarningBtn && !loadIng" @click="revocation">{{$L('撤销')}}</Button>
|
|
||||||
<Button type="error" v-if="isShowDeleteBtn && !loadIng" @click="remove">{{$L('删除')}}</Button>
|
|
||||||
<Button type="primary" @click="comment" :loading="loadIng > 0" ghost>+{{$L('添加评论')}}</Button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--加载中-->
|
|
||||||
<div v-if="loadIng > 0" class="approve-load">
|
|
||||||
<Loading/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--评论-->
|
|
||||||
<Modal v-model="commentShow" :title="$L('评论')" :mask-closable="false" class="page-approve-initiate">
|
|
||||||
<Form ref="initiateRef" :model="commentData" :rules="commentRule" v-bind="formOptions" @submit.native.prevent>
|
|
||||||
<FormItem prop="content" :label="$L('内容')">
|
|
||||||
<Input type="textarea" v-model="commentData.content"></Input>
|
|
||||||
</FormItem>
|
|
||||||
<FormItem prop="pictures" :label="$L('图片')">
|
|
||||||
<ImgUpload v-model="commentData.pictures" :num="3" :width="2048" :height="2048" whcut="percentage"/>
|
|
||||||
</FormItem>
|
|
||||||
</Form>
|
|
||||||
<div slot="footer" class="adaption">
|
|
||||||
<Button type="default" @click="commentShow=false">{{$L('取消')}}</Button>
|
|
||||||
<Button type="primary" :loading="commentLoad > 0" @click="confirmComment">{{$L('确认')}}</Button>
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import ImgView from "../../../components/ImgView";
|
|
||||||
import ImgUpload from "../../../components/ImgUpload";
|
|
||||||
import emitter from "../../../store/events";
|
|
||||||
import {mapState} from "vuex";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "ApproveDetails",
|
|
||||||
components: {ImgView, ImgUpload},
|
|
||||||
props: {
|
|
||||||
data: {
|
|
||||||
type: Object,
|
|
||||||
default() {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
datas: {},
|
|
||||||
loadIng: 0,
|
|
||||||
showTimeNum: 24,
|
|
||||||
modalTransferIndex: window.modalTransferIndex,
|
|
||||||
|
|
||||||
commentLoad: 0,
|
|
||||||
commentShow: false,
|
|
||||||
commentData: {
|
|
||||||
content: "",
|
|
||||||
pictures: []
|
|
||||||
},
|
|
||||||
commentRule: {
|
|
||||||
content: {type: 'string', required: true, message: this.$L('请输入内容!'), trigger: 'change'},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
'$route'(to, from) {
|
|
||||||
if (to.name == 'manage-approve-details') {
|
|
||||||
this.init()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
handler(newValue, oldValue) {
|
|
||||||
if (newValue.id) {
|
|
||||||
this.getInfo()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
deep: true
|
|
||||||
},
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState(['formOptions', 'userIsAdmin']),
|
|
||||||
|
|
||||||
isShowAgreeBtn() {
|
|
||||||
return (this.datas.candidate || '').split(',').indexOf(this.userId + '') != -1 && !this.datas.is_finished
|
|
||||||
},
|
|
||||||
isShowWarningBtn() {
|
|
||||||
let is = (this.userId == this.datas.start_user_id) && this.datas?.is_finished != true;
|
|
||||||
(this.datas.node_infos || []).map(h => {
|
|
||||||
if (h.type != 'starter' && h.is_finished == true && h.identitylink?.userid != this.userId) {
|
|
||||||
is = false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return is;
|
|
||||||
},
|
|
||||||
// 仅已结束的审批(已通过2/已拒绝3/已撤回4)可删,且仅发起人或管理员
|
|
||||||
isShowDeleteBtn() {
|
|
||||||
return (this.userId == this.datas.start_user_id || this.userIsAdmin)
|
|
||||||
&& [2, 3, 4].includes(Number(this.datas.state));
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.init()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
init() {
|
|
||||||
this.modalTransferIndex = ++window.modalTransferIndex
|
|
||||||
if (this.$route.query.id) {
|
|
||||||
this.getInfo()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 把时间转成几小时前
|
|
||||||
getTimeAgo(time, type) {
|
|
||||||
const timeDiff = $A.dayjs().unix() - $A.dayjs(time).unix(); // convert to seconds
|
|
||||||
if (timeDiff < 60) {
|
|
||||||
return type == 2 ? "0" + this.$L('分钟') : this.$L('刚刚');
|
|
||||||
} else if (timeDiff < 3600) {
|
|
||||||
const minutes = Math.floor(timeDiff / 60);
|
|
||||||
return type == 2 ? `${minutes}${this.$L('分钟')}` : `${minutes} ${this.$L('分钟前')}`;
|
|
||||||
} else if (timeDiff < 3600 * 24) {
|
|
||||||
const hours = Math.floor(timeDiff / 3600);
|
|
||||||
return type == 2 ? `${hours}${this.$L('小时')}` : `${hours} ${this.$L('小时前')}`;
|
|
||||||
} else if (timeDiff < 3600 * 24 * 30) {
|
|
||||||
const days = Math.floor(timeDiff / 3600 / 24);
|
|
||||||
return type == 2 ? `${days + 1}${this.$L('天')}` : `${days + 1} ${this.$L('天前')}`;
|
|
||||||
} else {
|
|
||||||
const days = Math.floor(timeDiff / 3600 / 720);
|
|
||||||
return type == 2 ? `${days + 1}${this.$L('月')}` : `${days + 1} ${this.$L('月前')}`;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 时间转为周几
|
|
||||||
getWeekday(dateString) {
|
|
||||||
return this.$L(['周日', '周一', '周二', '周三', '周四', '周五', '周六'][$A.dayjs(dateString).day()]);
|
|
||||||
},
|
|
||||||
// 获取时间差
|
|
||||||
getTimeDifference(startTime, endTime) {
|
|
||||||
const currentTime = $A.dayjs(endTime);
|
|
||||||
const endTimes = $A.dayjs(startTime);
|
|
||||||
const timeDiff = currentTime.unix() - endTimes.unix(); // convert to seconds
|
|
||||||
if (timeDiff < 60) {
|
|
||||||
return {time: timeDiff, unit: this.$L('秒')};
|
|
||||||
} else if (timeDiff < 3600) {
|
|
||||||
const minutes = Math.floor(timeDiff / 60);
|
|
||||||
return {time: minutes, unit: this.$L('分钟')};
|
|
||||||
} else if (timeDiff < 3600 * 24) {
|
|
||||||
const hours = Math.floor(timeDiff / 60 / 60 * 10) / 10;
|
|
||||||
return {time: hours, unit: this.$L('小时')};
|
|
||||||
} else {
|
|
||||||
const days = Math.floor(timeDiff / 60 / 60 / 24 * 10) / 10;
|
|
||||||
return {time: days + 1, unit: this.$L('天')};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 获取详情
|
|
||||||
getInfo(isScrollToBottom = false) {
|
|
||||||
this.loadIng++;
|
|
||||||
this.$store.dispatch("call", {
|
|
||||||
method: 'get',
|
|
||||||
url: 'approve/process/detail',
|
|
||||||
data: {
|
|
||||||
id: this.$route.query.id || this.data.id,
|
|
||||||
}
|
|
||||||
}).then(({data}) => {
|
|
||||||
var show = true;
|
|
||||||
data.node_infos = data.node_infos.map(item => {
|
|
||||||
item._show = show;
|
|
||||||
if (item.identitylink?.state == 2 || item.identitylink?.state == 3) {
|
|
||||||
show = false;
|
|
||||||
}
|
|
||||||
return item;
|
|
||||||
})
|
|
||||||
this.datas = data
|
|
||||||
isScrollToBottom && this.scrollToBottom();
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
$A.modalError(msg);
|
|
||||||
}).finally(_ => {
|
|
||||||
this.loadIng--;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// 通过
|
|
||||||
approve(type) {
|
|
||||||
$A.modalInput({
|
|
||||||
title: `审批`,
|
|
||||||
placeholder: `请输入审批意见`,
|
|
||||||
type: "textarea",
|
|
||||||
okText: type == 1 ? "同意" : "拒绝",
|
|
||||||
okType: type == 1 ? "primary" : "error",
|
|
||||||
onOk: (desc) => {
|
|
||||||
if (type != 1 && !desc) {
|
|
||||||
return `请输入审批意见`
|
|
||||||
}
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.$store.dispatch("call", {
|
|
||||||
url: 'approve/task/complete',
|
|
||||||
data: {
|
|
||||||
task_id: this.datas.task_id,
|
|
||||||
pass: type == 1,
|
|
||||||
comment: desc,
|
|
||||||
}
|
|
||||||
}).then(({msg}) => {
|
|
||||||
$A.messageSuccess(msg);
|
|
||||||
if (this.routeName == 'manage-approve-details' || this.routeName == 'manage-messenger') {
|
|
||||||
this.getInfo()
|
|
||||||
} else {
|
|
||||||
this.$emit('approve')
|
|
||||||
}
|
|
||||||
resolve()
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
reject(msg)
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// 撤销
|
|
||||||
revocation() {
|
|
||||||
$A.modalConfirm({
|
|
||||||
content: "你确定要撤销吗?",
|
|
||||||
loading: true,
|
|
||||||
okType: "warning",
|
|
||||||
onOk: () => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.$store.dispatch("call", {
|
|
||||||
url: 'approve/task/withdraw',
|
|
||||||
data: {
|
|
||||||
task_id: this.datas.task_id,
|
|
||||||
proc_inst_id: this.datas.id,
|
|
||||||
}
|
|
||||||
}).then(({msg}) => {
|
|
||||||
$A.messageSuccess(msg);
|
|
||||||
resolve();
|
|
||||||
if (this.routeName == 'manage-approve-details' || this.routeName == 'manage-messenger') {
|
|
||||||
this.getInfo()
|
|
||||||
} else {
|
|
||||||
this.$emit('revocation')
|
|
||||||
}
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
reject(msg);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// 删除审批
|
|
||||||
remove() {
|
|
||||||
$A.modalConfirm({
|
|
||||||
content: "删除后不可恢复,确定要删除该审批吗?",
|
|
||||||
loading: true,
|
|
||||||
okType: "error",
|
|
||||||
onOk: () => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.$store.dispatch("call", {
|
|
||||||
url: 'approve/process/delById',
|
|
||||||
method: 'post',
|
|
||||||
data: {
|
|
||||||
proc_inst_id: this.datas.id,
|
|
||||||
}
|
|
||||||
}).then(({msg}) => {
|
|
||||||
$A.messageSuccess(msg);
|
|
||||||
resolve();
|
|
||||||
// 删除后记录已不存在:独立路由返回上一页,嵌入模式通知父级刷新列表
|
|
||||||
if (this.routeName == 'manage-approve-details' || this.routeName == 'manage-messenger') {
|
|
||||||
this.$router.back()
|
|
||||||
} else {
|
|
||||||
this.$emit('revocation')
|
|
||||||
}
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
reject(msg);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// 评论
|
|
||||||
comment() {
|
|
||||||
this.commentData.content = ""
|
|
||||||
this.commentData.pictures = []
|
|
||||||
this.commentShow = true;
|
|
||||||
},
|
|
||||||
// 提交评论
|
|
||||||
confirmComment() {
|
|
||||||
this.commentLoad++;
|
|
||||||
this.$refs["initiateRef"].validate((valid) => {
|
|
||||||
if (valid) {
|
|
||||||
this.$store.dispatch("call", {
|
|
||||||
method: 'post',
|
|
||||||
url: 'approve/process/addGlobalComment',
|
|
||||||
data: {
|
|
||||||
proc_inst_id: this.$route.query.id || this.data.id,
|
|
||||||
content: JSON.stringify({
|
|
||||||
'content': this.commentData.content,
|
|
||||||
'pictures': this.commentData.pictures.map(h => {
|
|
||||||
return h.path;
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}).then(({msg}) => {
|
|
||||||
$A.messageSuccess("添加成功");
|
|
||||||
this.getInfo(true)
|
|
||||||
this.commentShow = false;
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
$A.modalError(msg);
|
|
||||||
}).finally(_ => {
|
|
||||||
this.commentLoad--;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.commentLoad--;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 滚动到容器底部
|
|
||||||
scrollToBottom() {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs.approveDetailsBox?.scrollTo({
|
|
||||||
top: container.scrollHeight + 1000,
|
|
||||||
behavior: 'smooth'
|
|
||||||
});
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 获取内容
|
|
||||||
getContent(content) {
|
|
||||||
try {
|
|
||||||
return JSON.parse(content).content || ''
|
|
||||||
} catch (error) {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 获取图片
|
|
||||||
getPictures(content) {
|
|
||||||
try {
|
|
||||||
return JSON.parse(content).pictures || []
|
|
||||||
} catch (error) {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 获取图片缩略图
|
|
||||||
getPictureThumb(src) {
|
|
||||||
if (!/\.(png|jpg|jpeg)$/.test(src)) {
|
|
||||||
return src
|
|
||||||
}
|
|
||||||
return $A.thumbRestore(src) + '_thumb.' + src.split('.').pop()
|
|
||||||
},
|
|
||||||
// 打开图片
|
|
||||||
onViewPicture(currentUrl, type) {
|
|
||||||
const datas = [];
|
|
||||||
if (type == 1) {
|
|
||||||
datas.push(...this.datas.var.other.split(','))
|
|
||||||
}
|
|
||||||
if (type == 2) {
|
|
||||||
this.datas.global_comments.map(h => {
|
|
||||||
datas.push(...this.getPictures(h.content))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const list = datas.map(src => {
|
|
||||||
return {
|
|
||||||
src: $A.mainUrl(src)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.$store.dispatch("previewImage", {index: $A.mainUrl(currentUrl), list})
|
|
||||||
},
|
|
||||||
// 点击头像
|
|
||||||
onAvatar(userid) {
|
|
||||||
if (!/^\d+$/.test(userid)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
emitter.emit('openUser', userid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@ -1,739 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="page-approve">
|
|
||||||
<PageTitle :title="$L('审批中心')"/>
|
|
||||||
<div class="approve-wrapper" ref="fileWrapper">
|
|
||||||
<div class="approve-head">
|
|
||||||
<div class="approve-nav">
|
|
||||||
<h1>{{$L('审批中心')}}</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Button v-show="showType == 1 && isShowIcon" @click="addApply" :loading="addLoadIng" type="primary" shape="circle" icon="md-add" class="ivu-btn-icon-only"></Button>
|
|
||||||
<Button v-if="showType == 1 && !isShowIcon" :loading="addLoadIng" type="primary" @click="addApply">
|
|
||||||
<span> {{$L("添加申请")}} </span>
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Button v-show="showType == 1 && userIsAdmin && !isShowIcon" @click="exportApproveShow = true">
|
|
||||||
<span> {{$L("导出审批数据")}} </span>
|
|
||||||
</Button>
|
|
||||||
<Button v-if="showType == 1 && userIsAdmin && isShowIcon" @click="exportApproveShow = true" shape="circle" class="ivu-btn-icon-only">
|
|
||||||
<i class="taskfont"></i>
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Button v-if="userIsAdmin && !isShowIcon" @click="showType = showType == 1 ? 2 : 1">
|
|
||||||
<span> {{ showType == 1 ? $L("流程设置") : $L("返回") }} </span>
|
|
||||||
</Button>
|
|
||||||
<Button v-if="userIsAdmin && isShowIcon" @click="showType = showType == 1 ? 2 : 1" shape="circle" class="ivu-btn-icon-only">
|
|
||||||
<i v-if="showType == 1" class="taskfont"></i>
|
|
||||||
<i v-if="showType == 2" class="taskfont"></i>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Tabs class="page-approve-tabs" v-show="showType==1" :value="tabsValue" @on-click="tabsClick" size="small">
|
|
||||||
<TabPane :label="$L('待办') + (unreadTotal > 0 ? ('('+unreadTotal+')') : '')" name="unread" style="height: 100%;">
|
|
||||||
<div class="approve-main-search">
|
|
||||||
<div>
|
|
||||||
<Select v-model="approvalType" @on-change="tabsClick(false,0)">
|
|
||||||
<Option v-for="item in approvalList" :value="item.value" :key="item.value">{{ item.label }}</Option>
|
|
||||||
</Select>
|
|
||||||
<Input v-model="approvalName" :placeholder="$L('请输入用户名')" ></Input>
|
|
||||||
<Button v-show="!isShowIcon" type="primary" :loading="loadIng" icon="ios-search" @click="tabsClick(false,0)">{{ $L('搜索') }}</Button>
|
|
||||||
<Button v-show="isShowIcon" type="primary" :loading="loadIng" icon="ios-search" @click="tabsClick(false,0)" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="loadIng && unreadList.length==0" class="approve-load">
|
|
||||||
<Loading/>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="unreadList.length==0" class="noData">{{ $L('暂无数据')}}</div>
|
|
||||||
<div v-else class="approve-mains">
|
|
||||||
<div class="approve-main-left">
|
|
||||||
<div class="approve-main-list" @scroll="handleScroll">
|
|
||||||
<div @click.stop="clickList(item,key)" v-for="(item,key) in unreadList">
|
|
||||||
<list :class="{ 'approve-list-active': item._active }" :data="item"></list>
|
|
||||||
</div>
|
|
||||||
<div class="load" v-if="unreadList.length < unreadTotal">
|
|
||||||
<Loading/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="approve-main-right">
|
|
||||||
<ApproveDetails v-if="!detailsShow && tabsValue=='unread'" :data="details" @approve="tabsClick" @revocation="tabsClick"></ApproveDetails>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</TabPane>
|
|
||||||
<TabPane :label="$L('已办')" name="done">
|
|
||||||
<div class="approve-main-search">
|
|
||||||
<div>
|
|
||||||
<Select v-model="approvalType" @on-change="tabsClick(false,0)">
|
|
||||||
<Option v-for="item in approvalList" :value="item.value" :key="item.value">{{ item.label }}</Option>
|
|
||||||
</Select>
|
|
||||||
<Input v-model="approvalName" :placeholder="$L('请输入用户名')"></Input>
|
|
||||||
<Button v-show="!isShowIcon" type="primary" :loading="loadIng" icon="ios-search" @click="tabsClick(false,0)">{{ $L('搜索') }}</Button>
|
|
||||||
<Button v-show="isShowIcon" type="primary" :loading="loadIng" icon="ios-search" @click="tabsClick(false,0)"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="loadIng && doneList.length==0" class="approve-load">
|
|
||||||
<Loading/>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="doneList.length==0" class="noData">{{$L('暂无数据')}}</div>
|
|
||||||
<div v-else class="approve-mains">
|
|
||||||
<div class="approve-main-left">
|
|
||||||
<div class="approve-main-list" @scroll="handleScroll">
|
|
||||||
<div @click.stop="clickList(item,key)" v-for="(item,key) in doneList" >
|
|
||||||
<list :class="{ 'approve-list-active': item._active }" :data="item"></list>
|
|
||||||
</div>
|
|
||||||
<div class="load" v-if="doneList.length < doneTotal">
|
|
||||||
<Loading/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="approve-main-right">
|
|
||||||
<ApproveDetails v-if="!detailsShow && tabsValue=='done'" :data="details" @approve="tabsClick" @revocation="tabsClick"></ApproveDetails>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</TabPane>
|
|
||||||
<TabPane :label="$L('抄送我')" name="notify">
|
|
||||||
<div class="approve-main-search">
|
|
||||||
<div class="approve-main-search">
|
|
||||||
<div>
|
|
||||||
<Select v-model="approvalType" @on-change="tabsClick(false,0)">
|
|
||||||
<Option v-for="item in approvalList" :value="item.value" :key="item.value">{{ item.label }}</Option>
|
|
||||||
</Select>
|
|
||||||
<Input v-model="approvalName" :placeholder="$L('请输入用户名')"></Input>
|
|
||||||
<Button v-show="!isShowIcon" type="primary" :loading="loadIng" icon="ios-search" @click="tabsClick(false,0)">{{ $L('搜索') }}</Button>
|
|
||||||
<Button v-show="isShowIcon" type="primary" :loading="loadIng" icon="ios-search" @click="tabsClick(false,0)"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="loadIng && notifyList.length==0" class="approve-load">
|
|
||||||
<Loading/>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="notifyList.length==0" class="noData">{{$L('暂无数据')}}</div>
|
|
||||||
<div v-else class="approve-mains">
|
|
||||||
<div class="approve-main-left">
|
|
||||||
<div class="approve-main-list" @scroll="handleScroll">
|
|
||||||
<div @click.stop="clickList(item,key)" v-for="(item,key) in notifyList">
|
|
||||||
<list :class="{ 'approve-list-active': item._active }" :data="item"></list>
|
|
||||||
</div>
|
|
||||||
<div class="load" v-if="notifyList.length < notifyTotal">
|
|
||||||
<Loading/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="approve-main-right">
|
|
||||||
<ApproveDetails v-if="!detailsShow && tabsValue=='notify'" :data="details" @approve="tabsClick" @revocation="tabsClick"></ApproveDetails>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</TabPane>
|
|
||||||
<TabPane :label="$L('已发起')" name="initiated">
|
|
||||||
<div class="approve-main-search">
|
|
||||||
<div>
|
|
||||||
<Select v-model="approvalType" @on-change="tabsClick(false,0)">
|
|
||||||
<Option v-for="item in approvalList" :value="item.value" :key="item.value">{{ item.label }}</Option>
|
|
||||||
</Select>
|
|
||||||
<Select v-model="searchState" @on-change="tabsClick(false,0)">
|
|
||||||
<Option v-for="item in searchStateList" :value="item.value" :key="item.value">{{ item.label }}</Option>
|
|
||||||
</Select>
|
|
||||||
<Input v-model="approvalName" :placeholder="$L('请输入用户名')"></Input>
|
|
||||||
<Button v-show="!isShowIcon" type="primary" :loading="loadIng" icon="ios-search" @click="tabsClick(false,0)">{{ $L('搜索') }}</Button>
|
|
||||||
<Button v-show="isShowIcon" type="primary" :loading="loadIng" icon="ios-search" @click="tabsClick(false,0)"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="loadIng && initiatedList.length==0" class="approve-load">
|
|
||||||
<Loading/>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="initiatedList.length==0" class="noData">{{$L('暂无数据')}}</div>
|
|
||||||
<div v-else class="approve-mains">
|
|
||||||
<div class="approve-main-left">
|
|
||||||
<div class="approve-main-list" @scroll="handleScroll">
|
|
||||||
<div @click.stop="clickList(item,key)" v-for="(item,key) in initiatedList">
|
|
||||||
<list :class="{ 'approve-list-active': item._active }" :data="item"></list>
|
|
||||||
</div>
|
|
||||||
<div class="load" v-if="initiatedList.length < initiatedTotal">
|
|
||||||
<Loading/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="approve-main-right">
|
|
||||||
<ApproveDetails v-if="!detailsShow && tabsValue=='initiated'" :data="details" @approve="tabsClick" @revocation="tabsClick"></ApproveDetails>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</TabPane>
|
|
||||||
</Tabs>
|
|
||||||
|
|
||||||
<ApproveSetting v-show="showType!=1"/>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--详情-->
|
|
||||||
<DrawerOverlay v-model="detailsShow" placement="right" :size="600">
|
|
||||||
<ApproveDetails v-if="detailsShow" :data="details" @approve="tabsClick" @revocation="tabsClick"></ApproveDetails>
|
|
||||||
</DrawerOverlay>
|
|
||||||
|
|
||||||
<!--发起-->
|
|
||||||
<Modal v-model="addShow" :title="$L(addTitle)" :mask-closable="false" class="page-approve-initiate">
|
|
||||||
<Form ref="initiateRef" :model="addData" :rules="addRule" v-bind="formOptions" @submit.native.prevent>
|
|
||||||
<FormItem v-if="departmentList.length>1" prop="department_id" :label="$L('选择部门')">
|
|
||||||
<Select v-model="addData.department_id" :placeholder="$L('请选择部门')">
|
|
||||||
<Option v-for="(item, index) in departmentList" :value="item.id" :key="index">{{ item.name }}</Option>
|
|
||||||
</Select>
|
|
||||||
</FormItem>
|
|
||||||
<FormItem prop="applyType" :label="$L('申请类型')">
|
|
||||||
<Select v-model="addData.applyType" :placeholder="$L('请选择申请类型')">
|
|
||||||
<Option v-for="(item, index) in procdefList" :value="item.name" :key="index">{{ $L(item.name) }}</Option>
|
|
||||||
</Select>
|
|
||||||
</FormItem>
|
|
||||||
<FormItem v-if="$A.strExists(addData.applyType, '请假')" prop="type" :label="$L('假期类型')">
|
|
||||||
<Select v-model="addData.type" :placeholder="$L('请选择假期类型')">
|
|
||||||
<Option v-for="(item, index) in selectTypes" :value="item" :key="index">{{ $L(item) }}</Option>
|
|
||||||
</Select>
|
|
||||||
</FormItem>
|
|
||||||
<FormItem prop="startTime" :label="$L('开始时间')">
|
|
||||||
<div style="display: flex;gap: 3px;">
|
|
||||||
<DatePicker type="date" format="yyyy-MM-dd"
|
|
||||||
v-model="addData.startTime"
|
|
||||||
:editable="false"
|
|
||||||
@on-change="(e)=>{ addData.startTime = e }"
|
|
||||||
:placeholder="$L('请选择开始时间')"
|
|
||||||
style="flex: 1;min-width: 122px;"
|
|
||||||
></DatePicker>
|
|
||||||
<Select v-model="addData.startTimeHour" style="max-width: 100px;">
|
|
||||||
<Option v-for="(item,index) in 24" :value="item-1 < 10 ? '0'+(item-1) : item-1 " :key="index">{{item-1 < 10 ? '0' : ''}}{{item-1}}</Option>
|
|
||||||
</Select>
|
|
||||||
<Select v-model="addData.startTimeMinute" style="max-width: 100px;">
|
|
||||||
<Option value="00">00</Option>
|
|
||||||
<Option value="30">30</Option>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
</FormItem>
|
|
||||||
<FormItem prop="endTime" :label="$L('结束时间')">
|
|
||||||
<div style="display: flex;gap: 3px;">
|
|
||||||
<DatePicker type="date" format="yyyy-MM-dd"
|
|
||||||
v-model="addData.endTime"
|
|
||||||
:editable="false"
|
|
||||||
@on-change="(e)=>{ addData.endTime = e }"
|
|
||||||
:placeholder="$L('请选择结束时间')"
|
|
||||||
style="flex: 1;min-width: 122px;"
|
|
||||||
></DatePicker>
|
|
||||||
<Select v-model="addData.endTimeHour" style="max-width: 100px;">
|
|
||||||
<Option v-for="(item,index) in 24" :value="item-1 < 10 ? '0'+(item-1) : ((item-1)+'') " :key="index">{{item-1 < 10 ? '0' : ''}}{{item-1}}</Option>
|
|
||||||
</Select>
|
|
||||||
<Select v-model="addData.endTimeMinute" style="max-width: 100px;">
|
|
||||||
<Option value="00">00</Option>
|
|
||||||
<Option value="30">30</Option>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
</FormItem>
|
|
||||||
<FormItem prop="description" :label="$L('事由')">
|
|
||||||
<Input type="textarea" v-model="addData.description"></Input>
|
|
||||||
</FormItem>
|
|
||||||
<FormItem prop="other" :label="$L('图片')">
|
|
||||||
<ImgUpload v-model="addData.other" :num="3" :width="2048" :height="2048" whcut="percentage"/>
|
|
||||||
</FormItem>
|
|
||||||
</Form>
|
|
||||||
<div slot="footer" class="adaption">
|
|
||||||
<Button type="default" @click="addShow=false">{{$L('取消')}}</Button>
|
|
||||||
<Button type="primary" :loading="loadIng > 0" @click="onInitiate">{{$L('确认')}}</Button>
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
|
|
||||||
<!--导出审批数据-->
|
|
||||||
<ApproveExport v-model="exportApproveShow"/>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import list from "./list.vue";
|
|
||||||
import ApproveDetails from "./details.vue";
|
|
||||||
import DrawerOverlay from "../../../components/DrawerOverlay";
|
|
||||||
import ImgUpload from "../../../components/ImgUpload";
|
|
||||||
import ApproveSetting from "./setting";
|
|
||||||
import ApproveExport from "../components/ApproveExport";
|
|
||||||
import {mapState} from 'vuex'
|
|
||||||
import emitter from "../../../store/events";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {list, ApproveDetails, DrawerOverlay, ImgUpload, ApproveSetting, ApproveExport},
|
|
||||||
name: "approve",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
showType: 1,
|
|
||||||
exportApproveShow: false,
|
|
||||||
isShowIcon: false,
|
|
||||||
modalTransferIndex: window.modalTransferIndex,
|
|
||||||
|
|
||||||
procdefList: [],
|
|
||||||
page: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
total: 0,
|
|
||||||
noText: '',
|
|
||||||
loadIng: false,
|
|
||||||
addLoadIng: false,
|
|
||||||
|
|
||||||
tabsValue: "",
|
|
||||||
//
|
|
||||||
approvalType: "all",
|
|
||||||
approvalName: "",
|
|
||||||
approvalList: [
|
|
||||||
{value: "all", label: this.$L("全部审批")},
|
|
||||||
],
|
|
||||||
searchState: "all",
|
|
||||||
searchStateList: [
|
|
||||||
{value: "all", label: this.$L("全部状态")},
|
|
||||||
{value: 1, label: this.$L("审批中")},
|
|
||||||
{value: 2, label: this.$L("已通过")},
|
|
||||||
{value: 3, label: this.$L("已拒绝")},
|
|
||||||
{value: 4, label: this.$L("已撤回")}
|
|
||||||
],
|
|
||||||
//
|
|
||||||
unreadList: [],
|
|
||||||
unreadPage: 1,
|
|
||||||
unreadTotal: 0,
|
|
||||||
unreadLoad: false,
|
|
||||||
//
|
|
||||||
doneList: [],
|
|
||||||
donePage: 1,
|
|
||||||
doneLoad: false,
|
|
||||||
doneTotal: 0,
|
|
||||||
//
|
|
||||||
notifyList: [],
|
|
||||||
notifyPage: 1,
|
|
||||||
notifyLoad: false,
|
|
||||||
notifyTotal: 0,
|
|
||||||
//
|
|
||||||
initiatedList: [],
|
|
||||||
initiatedPage: 1,
|
|
||||||
initiatedLoad: false,
|
|
||||||
initiatedTotal: 0,
|
|
||||||
//
|
|
||||||
details: {},
|
|
||||||
detailsShow: false,
|
|
||||||
//
|
|
||||||
addTitle: '',
|
|
||||||
addShow: false,
|
|
||||||
startTimeOpen: false,
|
|
||||||
endTimeOpen: false,
|
|
||||||
addData: {
|
|
||||||
department_id: 0,
|
|
||||||
applyType: '',
|
|
||||||
type: '',
|
|
||||||
startTime: "2023-04-20",
|
|
||||||
startTimeHour: "09",
|
|
||||||
startTimeMinute: "00",
|
|
||||||
endTime: "2023-04-20",
|
|
||||||
endTimeHour: "18",
|
|
||||||
endTimeMinute: "00",
|
|
||||||
other: ""
|
|
||||||
},
|
|
||||||
addRule: {
|
|
||||||
department_id: {type: 'number', required: true, message: this.$L('请选择部门!'), trigger: 'change'},
|
|
||||||
applyType: {type: 'string', required: true, message: this.$L('请选择申请类型!'), trigger: 'change'},
|
|
||||||
type: {type: 'string', required: true, message: this.$L('请选择假期类型!'), trigger: 'change'},
|
|
||||||
startTime: {type: 'string', required: true, message: this.$L('请选择开始时间!'), trigger: 'change'},
|
|
||||||
endTime: {type: 'string', required: true, message: this.$L('请选择结束时间!'), trigger: 'change'},
|
|
||||||
description: {type: 'string', required: true, message: this.$L('请输入事由!'), trigger: 'change'},
|
|
||||||
},
|
|
||||||
selectTypes: ["年假", "事假", "病假", "调休", "产假", "陪产假", "婚假", "丧假", "哺乳假", "产检假", "其他"],
|
|
||||||
|
|
||||||
//
|
|
||||||
showDateTime: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState(['userInfo', 'userIsAdmin', 'windowWidth', 'formOptions']),
|
|
||||||
departmentList() {
|
|
||||||
let departmentNames = (this.userInfo.department_name || '').split(',');
|
|
||||||
return (this.userInfo.department || []).map((h, index) => {
|
|
||||||
return {
|
|
||||||
id: h,
|
|
||||||
name: departmentNames[index]
|
|
||||||
};
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
'$route'(to) {
|
|
||||||
if (to.name == 'manage-approve') {
|
|
||||||
this.init()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
addShow(val) {
|
|
||||||
if (!val) {
|
|
||||||
this.addData.other = ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
showType(val) {
|
|
||||||
if (val == 1) {
|
|
||||||
this.init()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
windowWidth(val) {
|
|
||||||
this.isShowIcon = val < 515
|
|
||||||
}
|
|
||||||
},
|
|
||||||
activated() {
|
|
||||||
this.showType = 1
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.tabsValue = "unread"
|
|
||||||
this.init()
|
|
||||||
emitter.on('websocketMsg', this.onWebsocketMsg)
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
emitter.off('websocketMsg', this.onWebsocketMsg)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
init() {
|
|
||||||
this.tabsClick()
|
|
||||||
this.getProcdefList()
|
|
||||||
if (this.tabsValue != 'unread') {
|
|
||||||
this.getUnreadList();
|
|
||||||
}
|
|
||||||
this.addData.department_id = this.userInfo.department[0] || 0;
|
|
||||||
this.addData.startTime = this.addData.endTime = $A.daytz().format('YYYY-MM-DD');
|
|
||||||
this.isShowIcon = this.windowWidth < 515
|
|
||||||
},
|
|
||||||
|
|
||||||
// 收到websocket消息
|
|
||||||
onWebsocketMsg(info) {
|
|
||||||
const {type, action, mode, data} = info;
|
|
||||||
switch (type) {
|
|
||||||
case 'approve':
|
|
||||||
if (action == 'unread') {
|
|
||||||
this.tabsClick();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'dialog':
|
|
||||||
if (mode == 'add' && data?.msg?.text?.indexOf('open-approve-details') != -1) {
|
|
||||||
this.tabsClick();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 获取流程列表
|
|
||||||
getProcdefList() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.$store.dispatch("call", {
|
|
||||||
url: 'approve/procdef/all',
|
|
||||||
method: 'post',
|
|
||||||
}).then(({data}) => {
|
|
||||||
this.procdefList = data.rows || [];
|
|
||||||
this.approvalList = this.procdefList.map(h => {
|
|
||||||
return {value: h.name, label: this.$L(h.name)}
|
|
||||||
})
|
|
||||||
this.approvalList.unshift({value: "all", label: this.$L("全部审批")})
|
|
||||||
resolve()
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
$A.modalError(msg);
|
|
||||||
reject()
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// tab切换事件
|
|
||||||
tabsClick(val, time = 1000) {
|
|
||||||
if (!val && this.__tabsClick && time > 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.__tabsClick = setTimeout(() => {
|
|
||||||
this.__tabsClick = null;
|
|
||||||
}, time)
|
|
||||||
this.tabsValue = val || this.tabsValue
|
|
||||||
if (val) {
|
|
||||||
this.approvalType = this.searchState = "all"
|
|
||||||
this.approvalName = ""
|
|
||||||
}
|
|
||||||
//
|
|
||||||
this.detailsShow = false;
|
|
||||||
this.loadIng = true;
|
|
||||||
//
|
|
||||||
if (this.tabsValue == 'unread') {
|
|
||||||
if (val === false) {
|
|
||||||
this.unreadPage = 1;
|
|
||||||
this.unreadList = [];
|
|
||||||
}
|
|
||||||
this.getUnreadList();
|
|
||||||
}
|
|
||||||
if (this.tabsValue == 'done') {
|
|
||||||
if (val === false) {
|
|
||||||
this.donePage = 1;
|
|
||||||
this.doneList = [];
|
|
||||||
}
|
|
||||||
this.getDoneList();
|
|
||||||
}
|
|
||||||
if (this.tabsValue == 'notify') {
|
|
||||||
if (val === false) {
|
|
||||||
this.notifyPage = 1;
|
|
||||||
this.notifyList = [];
|
|
||||||
}
|
|
||||||
this.getNotifyList();
|
|
||||||
}
|
|
||||||
if (this.tabsValue == 'initiated') {
|
|
||||||
if (val === false) {
|
|
||||||
this.initiatedPage = 1;
|
|
||||||
this.initiatedList = [];
|
|
||||||
}
|
|
||||||
this.getInitiatedList();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 列表点击事件
|
|
||||||
clickList(item) {
|
|
||||||
this.unreadList.map(h => {
|
|
||||||
h._active = false;
|
|
||||||
})
|
|
||||||
this.doneList.map(h => {
|
|
||||||
h._active = false;
|
|
||||||
})
|
|
||||||
this.notifyList.map(h => {
|
|
||||||
h._active = false;
|
|
||||||
})
|
|
||||||
this.initiatedList.map(h => {
|
|
||||||
h._active = false;
|
|
||||||
})
|
|
||||||
//
|
|
||||||
if (window.innerWidth < 426) {
|
|
||||||
emitter.emit('approveDetails', item.id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (window.innerWidth < 1010) {
|
|
||||||
this.detailsShow = true;
|
|
||||||
} else {
|
|
||||||
item._active = true;
|
|
||||||
}
|
|
||||||
this.details = {}
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.details = item
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// 下拉加载
|
|
||||||
handleScroll(e) {
|
|
||||||
if (e.target.scrollTop + e.target.clientHeight >= e.target.scrollHeight) {
|
|
||||||
if (this.tabsValue == 'unread' && !this.unreadLoad && this.unreadList.length < this.unreadTotal) {
|
|
||||||
this.unreadLoad = true;
|
|
||||||
this.unreadPage = this.unreadPage + 1;
|
|
||||||
this.getUnreadList('scroll');
|
|
||||||
}
|
|
||||||
if (this.tabsValue == 'done' && !this.doneLoad && this.doneList.length < this.doneTotal) {
|
|
||||||
this.doneLoad = true;
|
|
||||||
this.donePage = this.donePage + 1;
|
|
||||||
this.getDoneList('scroll');
|
|
||||||
}
|
|
||||||
if (this.tabsValue == 'notify' && !this.notifyLoad && this.notifyList.length < this.notifyTotal) {
|
|
||||||
this.notifyLoad = true;
|
|
||||||
this.notifyPage = this.notifyPage + 1;
|
|
||||||
this.getNotifyList('scroll');
|
|
||||||
}
|
|
||||||
if (this.tabsValue == 'initiated' && !this.initiatedLoad && this.initiatedList.length < this.initiatedTotal) {
|
|
||||||
this.initiatedLoad = true;
|
|
||||||
this.initiatedPage = this.initiatedPage + 1;
|
|
||||||
this.getInitiatedList('scroll');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 获取待办列表
|
|
||||||
getUnreadList(type = 'init') {
|
|
||||||
this.$store.dispatch("call", {
|
|
||||||
method: 'get',
|
|
||||||
url: 'approve/process/findTask',
|
|
||||||
data: {
|
|
||||||
page: type == 'scroll' ? this.unreadPage : 1,
|
|
||||||
page_size: type == 'scroll' ? this.pageSize : this.unreadPage * this.pageSize,
|
|
||||||
proc_def_name: this.approvalType == 'all' ? '' : this.approvalType,
|
|
||||||
username: this.approvalName,
|
|
||||||
}
|
|
||||||
}).then(({data}) => {
|
|
||||||
this.updateData('unread', data, type)
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
$A.modalError(msg);
|
|
||||||
}).finally(_ => {
|
|
||||||
this.loadIng = false;
|
|
||||||
this.unreadLoad = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// 获取已办列表
|
|
||||||
getDoneList(type = 'init') {
|
|
||||||
this.$store.dispatch("call", {
|
|
||||||
method: 'get',
|
|
||||||
url: 'approve/procHistory/findTask',
|
|
||||||
data: {
|
|
||||||
page: type == 'scroll' ? this.donePage : 1,
|
|
||||||
page_size: type == 'scroll' ? this.pageSize : this.donePage * this.pageSize,
|
|
||||||
proc_def_name: this.approvalType == 'all' ? '' : this.approvalType,
|
|
||||||
username: this.approvalName,
|
|
||||||
}
|
|
||||||
}).then(({data}) => {
|
|
||||||
this.updateData('done', data, type)
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
$A.modalError(msg);
|
|
||||||
}).finally(_ => {
|
|
||||||
this.loadIng = false;
|
|
||||||
this.doneLoad = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// 获取抄送列表
|
|
||||||
getNotifyList(type) {
|
|
||||||
this.$store.dispatch("call", {
|
|
||||||
method: 'get',
|
|
||||||
url: 'approve/procHistory/findProcNotify',
|
|
||||||
data: {
|
|
||||||
page: type == 'scroll' ? this.notifyPage : 1,
|
|
||||||
page_size: type == 'scroll' ? this.pageSize : this.notifyPage * this.pageSize,
|
|
||||||
proc_def_name: this.approvalType == 'all' ? '' : this.approvalType,
|
|
||||||
username: this.approvalName,
|
|
||||||
}
|
|
||||||
}).then(({data}) => {
|
|
||||||
this.updateData('notify', data, type)
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
$A.modalError(msg);
|
|
||||||
}).finally(_ => {
|
|
||||||
this.loadIng = false;
|
|
||||||
this.notifyLoad = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// 获取我发起的
|
|
||||||
getInitiatedList(type) {
|
|
||||||
this.$store.dispatch("call", {
|
|
||||||
method: 'post',
|
|
||||||
url: 'approve/process/startByMyselfAll',
|
|
||||||
data: {
|
|
||||||
page: type == 'scroll' ? this.initiatedPage : 1,
|
|
||||||
page_size: type == 'scroll' ? this.pageSize : this.initiatedPage * this.pageSize,
|
|
||||||
proc_def_name: this.approvalType == 'all' ? '' : this.approvalType,
|
|
||||||
state: this.searchState == 'all' ? '' : this.searchState,
|
|
||||||
username: this.approvalName,
|
|
||||||
}
|
|
||||||
}).then(({data}) => {
|
|
||||||
this.updateData('initiated', data, type)
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
$A.modalError(msg);
|
|
||||||
}).finally(_ => {
|
|
||||||
this.loadIng = false;
|
|
||||||
this.initiatedLoad = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// 添加申请
|
|
||||||
addApply() {
|
|
||||||
this.addLoadIng = true;
|
|
||||||
this.$store.dispatch("call", {
|
|
||||||
url: 'users/basic',
|
|
||||||
data: {
|
|
||||||
userid: [this.userInfo.userid]
|
|
||||||
},
|
|
||||||
checkAuth: false
|
|
||||||
}).then(({data}) => {
|
|
||||||
this.addData.department_id = data[0]?.department[0] || 0;
|
|
||||||
this.getProcdefList().then(_ => {
|
|
||||||
this.addTitle = this.$L("添加申请");
|
|
||||||
this.addShow = true;
|
|
||||||
this.addLoadIng = false;
|
|
||||||
}).catch(_ => {
|
|
||||||
this.addLoadIng = false;
|
|
||||||
});
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
this.addLoadIng = false;
|
|
||||||
$A.modalError(msg);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// 更新数据
|
|
||||||
updateData(key, data, type) {
|
|
||||||
let listKey = key + 'List'
|
|
||||||
this[key + 'Total'] = data.total;
|
|
||||||
type != 'scroll' ? (this[listKey] = data.rows) : data.rows.map(h => {
|
|
||||||
if (this[listKey].map(item => {
|
|
||||||
return item.id
|
|
||||||
}).indexOf(h.id) == -1) {
|
|
||||||
this[listKey].push(h)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (window.innerWidth > 1010) {
|
|
||||||
let activeIndex = this[listKey].map((h, index) => h._active ? index : -1).filter(h => h > -1)[0] || 0
|
|
||||||
if (this[listKey].length > 0) {
|
|
||||||
this[listKey][activeIndex]._active = true;
|
|
||||||
if (this.tabsValue == key) {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.details = this[listKey][activeIndex] || {}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 提交发起
|
|
||||||
onInitiate() {
|
|
||||||
this.$refs.initiateRef.validate((valid) => {
|
|
||||||
if (valid) {
|
|
||||||
this.loadIng = true;
|
|
||||||
var obj = JSON.parse(JSON.stringify(this.addData))
|
|
||||||
|
|
||||||
obj.startTime = obj.startTime + " " + obj.startTimeHour + ":" + obj.startTimeMinute;
|
|
||||||
obj.endTime = obj.endTime + " " + obj.endTimeHour + ":" + obj.endTimeMinute;
|
|
||||||
|
|
||||||
if (this.addData.other) {
|
|
||||||
obj.other = this.addData.other.map((o) => {
|
|
||||||
return o.path
|
|
||||||
}).join(',')
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$store.dispatch("call", {
|
|
||||||
url: 'approve/process/start',
|
|
||||||
data: {
|
|
||||||
proc_name: obj.applyType,
|
|
||||||
department_id: obj.department_id,
|
|
||||||
var: JSON.stringify(obj),
|
|
||||||
},
|
|
||||||
method: 'post',
|
|
||||||
}).then(({data, msg}) => {
|
|
||||||
$A.messageSuccess(msg);
|
|
||||||
this.addShow = false;
|
|
||||||
this.$refs.initiateRef.resetFields();
|
|
||||||
this.tabsValue = 'initiated';
|
|
||||||
this.initiatedList.map(h => {
|
|
||||||
h._active = false;
|
|
||||||
})
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.tabsClick(false, 0);
|
|
||||||
})
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
$A.modalError(msg);
|
|
||||||
}).finally(_ => {
|
|
||||||
this.loadIng = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.page-approve .approve-details {
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-approve .ivu-tabs-nav {
|
|
||||||
display: flex;
|
|
||||||
width: 350px;
|
|
||||||
@media (width <= 1010px) {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ivu-tabs-tab {
|
|
||||||
font-size: 15px;
|
|
||||||
flex: 1;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-approve-initiate .ivu-modal-body {
|
|
||||||
padding: 16px 22px 2px !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="approve-list">
|
|
||||||
<h2>
|
|
||||||
<span class="list-name">{{$L(data.proc_def_name)}}</span>
|
|
||||||
<Tag v-if="data.state == 0" color="cyan">{{$L('待审批')}}</Tag>
|
|
||||||
<Tag v-if="data.state == 1" color="cyan">{{$L('审批中')}}</Tag>
|
|
||||||
<Tag v-if="data.state == 2" color="green">{{$L('已通过')}}</Tag>
|
|
||||||
<Tag v-if="data.state == 3" color="red">{{$L('已拒绝')}}</Tag>
|
|
||||||
<Tag v-if="data.state == 4" color="red">{{$L('已撤回')}}</Tag>
|
|
||||||
</h2>
|
|
||||||
<p v-if="$A.strExists(data.proc_def_name, '请假') && data.var?.type">{{$L('假期类型')}}:<span>{{$L(data.var?.type)}}</span></p>
|
|
||||||
<p>{{$L('开始时间')}}:<span>{{data.var?.start_time}}</span></p>
|
|
||||||
<p>{{$L('结束时间')}}:<span>{{data.var?.end_time}}</span></p>
|
|
||||||
<div class="list-member">
|
|
||||||
<span>
|
|
||||||
<Avatar :src="data.userimg" size="20"/>
|
|
||||||
{{ data.start_user_name }}
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
{{$L('发起时间')}}:{{data.start_time}}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "list",
|
|
||||||
props: {
|
|
||||||
data: {
|
|
||||||
type: Object,
|
|
||||||
default() {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@ -1,176 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="page-approve-setting">
|
|
||||||
<Row class="approve-row" :gutter="16">
|
|
||||||
<Col :xxl="{ span: 6 }" :xl="{ span: 8 }" :lg="{ span: 12 }" :sm="{ span: 12 }" :xs="{ span: 24 }" >
|
|
||||||
<div class="approve-col-box approve-col-add" @click="add">
|
|
||||||
<Icon type="md-add" />
|
|
||||||
</div>
|
|
||||||
</Col>
|
|
||||||
<Col v-for="(item, key) in list" :xxl="{ span: 6 }" :xl="{ span: 8 }" :lg="{ span: 12 }" :sm="{ span: 12 }" :xs="{ span: 24 }" :key="key">
|
|
||||||
<div class="approve-col-box approve-col-for" @click="edit(item)">
|
|
||||||
<p>{{$L('流程名称')}}:<span class="approve-name">{{$L(item.name)}}</span></p>
|
|
||||||
<Divider class="divider"/>
|
|
||||||
<div class="approve-button-box" @click.stop="edit(item)">
|
|
||||||
<p>{{$L('已发布')}}</p>
|
|
||||||
<p class="icon-warp" @click.stop="change(item)" >
|
|
||||||
<Icon type="md-trash" size="16" class="delcon"/>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<!--设置流程-->
|
|
||||||
<DrawerOverlay v-model="approvalSettingShow" placement="right" :size="1200">
|
|
||||||
<iframe :src="iframeSrc"></iframe>
|
|
||||||
</DrawerOverlay>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import DrawerOverlay from "../../../components/DrawerOverlay";
|
|
||||||
import store from '../../../store/state'
|
|
||||||
import {languageName} from "../../../language";
|
|
||||||
export default {
|
|
||||||
name: "ApproveSetting",
|
|
||||||
components: {DrawerOverlay},
|
|
||||||
data(){
|
|
||||||
return{
|
|
||||||
value:false,
|
|
||||||
loadIng:0,
|
|
||||||
approvalSettingShow: false,
|
|
||||||
iframeSrc:"",
|
|
||||||
name:"",
|
|
||||||
list:[]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
approvalSettingShow(val) {
|
|
||||||
if (val) {
|
|
||||||
this.iframeSrc = $A.mainUrl(`approve/#/?name=${this.name}&token=${store.userToken}&lang=${languageName}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
window.addEventListener('message', this.saveSuccess)
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
window.removeEventListener("message", this.saveSuccess);
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 获取列表数据
|
|
||||||
getList(){
|
|
||||||
this.$store.dispatch("call", {
|
|
||||||
url: 'approve/procdef/all',
|
|
||||||
method: 'post',
|
|
||||||
}).then(({data}) => {
|
|
||||||
this.list = data.rows;
|
|
||||||
data.rows.forEach((h,index) => {
|
|
||||||
this.list.forEach((o,index) => {
|
|
||||||
if(o.name == h.name){
|
|
||||||
o.issue = true;
|
|
||||||
o.id = h.id;
|
|
||||||
o.version = h.version;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
$A.modalError(msg);
|
|
||||||
}).finally(_ => {
|
|
||||||
this.loadIng--;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// 保存成功回调
|
|
||||||
saveSuccess(e){
|
|
||||||
if (typeof e.data === 'string') {
|
|
||||||
let propsBody = JSON.parse(e.data);
|
|
||||||
if( propsBody.method == "saveSuccess" ) {
|
|
||||||
this.getList();
|
|
||||||
this.list.forEach((h,index) => {
|
|
||||||
if(h.name == this.name){
|
|
||||||
h.issue = true;
|
|
||||||
this.$set(this.list,index,h)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.approvalSettingShow = false;
|
|
||||||
$A.messageSuccess('发布成功');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 添加
|
|
||||||
add(){
|
|
||||||
$A.modalInput({
|
|
||||||
title: `添加流程`,
|
|
||||||
placeholder: `请输入流程名称`,
|
|
||||||
okText: "确定",
|
|
||||||
onOk: (desc) => {
|
|
||||||
if (!desc) {
|
|
||||||
return `请输入流程名称`
|
|
||||||
}
|
|
||||||
this.name = desc
|
|
||||||
this.approvalSettingShow = true;
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// 编辑
|
|
||||||
edit(item){
|
|
||||||
this.name = item.name
|
|
||||||
this.approvalSettingShow = true;
|
|
||||||
},
|
|
||||||
// 变更
|
|
||||||
change(item){
|
|
||||||
this.$nextTick(()=>{
|
|
||||||
item.issue = true;
|
|
||||||
$A.modalConfirm({
|
|
||||||
title: '删除',
|
|
||||||
content: '将会清空流程数据,此操作不可恢复',
|
|
||||||
onOk: () => {
|
|
||||||
this.del(item)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// 删除数据
|
|
||||||
del(item){
|
|
||||||
if(!item.id){
|
|
||||||
item.issue = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
this.$store.dispatch("call", {
|
|
||||||
url: 'approve/procdef/del',
|
|
||||||
data: {id: item.id},
|
|
||||||
method: 'post',
|
|
||||||
}).then(({data}) => {
|
|
||||||
item.issue = false;
|
|
||||||
this.getList();
|
|
||||||
$A.messageSuccess('成功');
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
$A.modalError(msg);
|
|
||||||
}).finally(_ => {
|
|
||||||
this.loadIng--;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
iframe{
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
border: 0;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
.delcon{
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
padding: 5px !important;
|
|
||||||
}
|
|
||||||
.delcon:hover{
|
|
||||||
color: #ed4014 !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,124 +0,0 @@
|
|||||||
<template>
|
|
||||||
<Modal
|
|
||||||
v-model="show"
|
|
||||||
:title="$L('导出审批数据')"
|
|
||||||
:mask-closable="false">
|
|
||||||
<Form ref="exportTask" :model="formData" v-bind="formOptions" @submit.native.prevent>
|
|
||||||
<FormItem :label="$L('审批类型')">
|
|
||||||
<Select v-model="formData.proc_def_name" @on-open-change="getProcName" :placeholder="$L('请选择类型')">
|
|
||||||
<Option v-for="(item, key) in procList" :value="item.name" :key="key" >{{ $L(item.name) }}</Option>
|
|
||||||
</Select>
|
|
||||||
</FormItem>
|
|
||||||
<FormItem :label="$L('时间范围')">
|
|
||||||
<DatePicker
|
|
||||||
v-model="formData.date"
|
|
||||||
type="daterange"
|
|
||||||
format="yyyy/MM/dd"
|
|
||||||
style="width:100%"
|
|
||||||
:placeholder="$L('请选择时间')"/>
|
|
||||||
<div class="form-tip form-quick-select">
|
|
||||||
<span>{{$L('快捷选择')}}:</span>
|
|
||||||
<em @click="formData.date=dateShortcuts('prev')">{{$L('上个月')}}</em>
|
|
||||||
<em @click="formData.date=dateShortcuts('this')">{{$L('这个月')}}</em>
|
|
||||||
</div>
|
|
||||||
</FormItem>
|
|
||||||
<FormItem prop="type" :label="$L('导出类型')">
|
|
||||||
<RadioGroup v-model="formData.is_finished">
|
|
||||||
<Radio label="0">{{$L('未完成')}}</Radio>
|
|
||||||
<Radio label="1">{{$L('已完成')}}</Radio>
|
|
||||||
</RadioGroup>
|
|
||||||
</FormItem>
|
|
||||||
</Form>
|
|
||||||
<div slot="footer" class="adaption">
|
|
||||||
<Button type="default" @click="show=false">{{$L('取消')}}</Button>
|
|
||||||
<Button type="primary" :loading="loadIng > 0" @click="onExport">{{$L('导出')}}</Button>
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {mapState} from "vuex";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "ApproveExport",
|
|
||||||
props: {
|
|
||||||
value: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
show: this.value,
|
|
||||||
loadIng: 0,
|
|
||||||
formData: {
|
|
||||||
proc_def_name: '',
|
|
||||||
date: [],
|
|
||||||
is_finished:'1',
|
|
||||||
},
|
|
||||||
procList:[],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
|
||||||
value(v) {
|
|
||||||
this.show = v;
|
|
||||||
},
|
|
||||||
show(v) {
|
|
||||||
this.value !== v && this.$emit("input", v)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
...mapState(['formOptions']),
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
dateShortcuts(act) {
|
|
||||||
if (act === 'prev') {
|
|
||||||
return [
|
|
||||||
$A.daytz().subtract(1, 'month').startOf('month').format('YYYY-MM-DD'),
|
|
||||||
$A.daytz().subtract(1, 'month').endOf('month').format('YYYY-MM-DD'),
|
|
||||||
];
|
|
||||||
} else if (act === 'this') {
|
|
||||||
return [
|
|
||||||
$A.daytz().startOf('month').format('YYYY-MM-DD'),
|
|
||||||
$A.daytz().endOf('month').format('YYYY-MM-DD'),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getProcName(){
|
|
||||||
this.loadIng++;
|
|
||||||
this.$store.dispatch("call", {
|
|
||||||
url: 'approve/procdef/all',
|
|
||||||
method: 'post'
|
|
||||||
}).then(({data}) => {
|
|
||||||
this.procList = data['rows'];
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
$A.modalError(msg);
|
|
||||||
}).finally(_ => {
|
|
||||||
this.loadIng--;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onExport() {
|
|
||||||
if (this.loadIng > 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.loadIng++;
|
|
||||||
this.$store.dispatch("call", {
|
|
||||||
url: 'approve/export',
|
|
||||||
data: this.formData,
|
|
||||||
}).then(() => {
|
|
||||||
this.show = false;
|
|
||||||
$A.modalSuccess('正在打包,请留意系统消息。');
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
$A.modalError(msg);
|
|
||||||
}).finally(_ => {
|
|
||||||
this.loadIng--;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@ -7,9 +7,6 @@
|
|||||||
<p>{{ msg.data.comment_content }}</p>
|
<p>{{ msg.data.comment_content }}</p>
|
||||||
<p v-if="msg.data.thumb" v-html="imageHtml(msg.data.thumb)"></p>
|
<p v-if="msg.data.thumb" v-html="imageHtml(msg.data.thumb)"></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-raw no-dark-content">
|
|
||||||
<button class="ivu-btn ivu-btn-grey">{{$L('查看详情')}}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@ -2,16 +2,13 @@
|
|||||||
<div class="open-approve-details" :data-id="msg.data.id">
|
<div class="open-approve-details" :data-id="msg.data.id">
|
||||||
<b>{{ $L(`抄送 ${msg.data.nickname} 提交的「${msg.data.proc_def_name}」记录`) }}</b>
|
<b>{{ $L(`抄送 ${msg.data.nickname} 提交的「${msg.data.proc_def_name}」记录`) }}</b>
|
||||||
<div class="cause">
|
<div class="cause">
|
||||||
|
<p>{{$L("状态")}}:<b>{{ msg.is_finished ? $L("已完成") : $L("审批中") }}</b></p>
|
||||||
<p>{{$L("申请人")}}:<span class="mark-color">@{{ msg.data.nickname }}</span> {{ msg.data.department }}</p>
|
<p>{{$L("申请人")}}:<span class="mark-color">@{{ msg.data.nickname }}</span> {{ msg.data.department }}</p>
|
||||||
<b>{{$L("详情")}}</b>
|
<b>{{$L("详情")}}</b>
|
||||||
<p v-if="$A.strExists(msg.data.proc_def_name, '请假') && msg.data.type">{{$L("假期类型")}}:{{ $L(msg.data.type) }}</p>
|
<p v-if="msg.data.type">{{$L("类型")}}:{{ $L(msg.data.type) }}</p>
|
||||||
<p>{{$L("开始时间")}}:{{ msg.data.start_time }} ({{ $L(msg.data.start_day_of_week) }})</p>
|
<p v-if="msg.data.start_time">{{$L("开始时间")}}:{{ msg.data.start_time }}<template v-if="msg.data.start_day_of_week"> ({{ $L(msg.data.start_day_of_week) }})</template></p>
|
||||||
<p>{{$L("结束时间")}}:{{ msg.data.end_time }} ({{ $L(msg.data.end_day_of_week) }})</p>
|
<p v-if="msg.data.end_time">{{$L("结束时间")}}:{{ msg.data.end_time }}<template v-if="msg.data.end_day_of_week"> ({{ $L(msg.data.end_day_of_week) }})</template></p>
|
||||||
<p>{{$L("事由")}}:{{ msg.data.description }}</p>
|
<p v-if="msg.data.description">{{$L("事由")}}:{{ msg.data.description }}</p>
|
||||||
</div>
|
|
||||||
<div class="btn-raw no-dark-content">
|
|
||||||
<button v-if="msg.is_finished" class="ivu-btn ivu-btn-grey">{{$L("已同意")}}</button>
|
|
||||||
<button v-else class="ivu-btn ivu-btn-grey">{{$L("查看详情")}}</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -2,23 +2,15 @@
|
|||||||
<div class="open-approve-details" :data-id="msg.data.id">
|
<div class="open-approve-details" :data-id="msg.data.id">
|
||||||
<b>{{ $L(`${msg.data.nickname} 提交的「${msg.data.proc_def_name}」待你审批`) }}</b>
|
<b>{{ $L(`${msg.data.nickname} 提交的「${msg.data.proc_def_name}」待你审批`) }}</b>
|
||||||
<div class="cause">
|
<div class="cause">
|
||||||
|
<p>{{$L("状态")}}:<b>{{ $L(statusText) }}</b></p>
|
||||||
<p>{{$L("申请人")}}:<span class="mark-color">@{{ msg.data.nickname }}</span> {{ msg.data.department }}</p>
|
<p>{{$L("申请人")}}:<span class="mark-color">@{{ msg.data.nickname }}</span> {{ msg.data.department }}</p>
|
||||||
<b>{{$L("详情")}}</b>
|
<b>{{$L("详情")}}</b>
|
||||||
<p v-if="$A.strExists(msg.data.proc_def_name, '请假') && msg.data.type">{{$L("假期类型")}}:{{ $L(msg.data.type) }}</p>
|
<p v-if="msg.data.type">{{$L("类型")}}:{{ $L(msg.data.type) }}</p>
|
||||||
<p>{{$L("开始时间")}}:{{ msg.data.start_time }} ({{ $L(msg.data.start_day_of_week) }})</p>
|
<p v-if="msg.data.start_time">{{$L("开始时间")}}:{{ msg.data.start_time }}<template v-if="msg.data.start_day_of_week"> ({{ $L(msg.data.start_day_of_week) }})</template></p>
|
||||||
<p>{{$L("结束时间")}}:{{ msg.data.end_time }} ({{ $L(msg.data.end_day_of_week) }})</p>
|
<p v-if="msg.data.end_time">{{$L("结束时间")}}:{{ msg.data.end_time }}<template v-if="msg.data.end_day_of_week"> ({{ $L(msg.data.end_day_of_week) }})</template></p>
|
||||||
<p>{{$L("事由")}}:{{ msg.data.description }}</p>
|
<p v-if="msg.data.description">{{$L("事由")}}:{{ msg.data.description }}</p>
|
||||||
<p v-if="msg.data.thumb" v-html="imageHtml(msg.data.thumb)"></p>
|
<p v-if="msg.data.thumb" v-html="imageHtml(msg.data.thumb)"></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-raw no-dark-content">
|
|
||||||
<button v-if="msg.action === 'pass'" class="ivu-btn ivu-btn-grey">{{$L("已同意")}}</button>
|
|
||||||
<button v-else-if="msg.action === 'refuse'" class="ivu-btn ivu-btn-grey rejected">{{$L("已拒绝")}}</button>
|
|
||||||
<button v-else-if="msg.action === 'withdraw'" class="ivu-btn ivu-btn-grey revoked">{{$L("已撤销")}}</button>
|
|
||||||
<template v-else>
|
|
||||||
<button class="ivu-btn ivu-btn-primary">{{$L("同意")}}</button>
|
|
||||||
<button class="ivu-btn ivu-btn-error">{{$L("拒绝")}}</button>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -30,6 +22,16 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
statusText({msg}) {
|
||||||
|
switch (msg.action) {
|
||||||
|
case 'pass': return '已同意';
|
||||||
|
case 'refuse': return '已拒绝';
|
||||||
|
case 'withdraw': return '已撤销';
|
||||||
|
default: return '待审批';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
imageHtml(info) {
|
imageHtml(info) {
|
||||||
const data = $A.imageRatioHandle({
|
const data = $A.imageRatioHandle({
|
||||||
|
|||||||
@ -2,17 +2,13 @@
|
|||||||
<div class="open-approve-details" :data-id="msg.data.id">
|
<div class="open-approve-details" :data-id="msg.data.id">
|
||||||
<b>{{ $L(title) }}</b>
|
<b>{{ $L(title) }}</b>
|
||||||
<div class="cause">
|
<div class="cause">
|
||||||
|
<p>{{$L("状态")}}:<b>{{ $L(statusText) }}</b></p>
|
||||||
<p>{{$L("申请人")}}:<span class="mark-color">@{{ msg.data.start_nickname }}</span> {{ msg.data.department }}</p>
|
<p>{{$L("申请人")}}:<span class="mark-color">@{{ msg.data.start_nickname }}</span> {{ msg.data.department }}</p>
|
||||||
<b>{{$L("详情")}}</b>
|
<b>{{$L("详情")}}</b>
|
||||||
<p v-if="$A.strExists(msg.data.proc_def_name, '请假') && msg.data.type">{{$L("假期类型")}}:{{ $L(msg.data.type) }}</p>
|
<p v-if="msg.data.type">{{$L("类型")}}:{{ $L(msg.data.type) }}</p>
|
||||||
<p>{{$L("开始时间")}}:{{ msg.data.start_time }} ({{ $L(msg.data.start_day_of_week) }})</p>
|
<p v-if="msg.data.start_time">{{$L("开始时间")}}:{{ msg.data.start_time }}<template v-if="msg.data.start_day_of_week"> ({{ $L(msg.data.start_day_of_week) }})</template></p>
|
||||||
<p>{{$L("结束时间")}}:{{ msg.data.end_time }} ({{ $L(msg.data.end_day_of_week) }})</p>
|
<p v-if="msg.data.end_time">{{$L("结束时间")}}:{{ msg.data.end_time }}<template v-if="msg.data.end_day_of_week"> ({{ $L(msg.data.end_day_of_week) }})</template></p>
|
||||||
<p>{{$L("事由")}}:{{ msg.data.description }}</p>
|
<p v-if="msg.data.description">{{$L("事由")}}:{{ msg.data.description }}</p>
|
||||||
</div>
|
|
||||||
<div class="btn-raw no-dark-content">
|
|
||||||
<button v-if="msg.action === 'pass'" class="ivu-btn ivu-btn-grey">{{$L("已同意")}}</button>
|
|
||||||
<button v-else-if="msg.action === 'refuse'" class="ivu-btn ivu-btn-grey rejected">{{$L("已拒绝")}}</button>
|
|
||||||
<button v-else-if="msg.action === 'withdraw'" class="ivu-btn ivu-btn-grey revoked">{{$L("已撤销")}}</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -28,7 +24,15 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
title({msg}) {
|
title({msg}) {
|
||||||
return msg.action === 'pass' ? `您发起的「${msg.data.proc_def_name}」已通过` : `您发起的「${msg.data.proc_def_name}」被 ${msg.data.nickname} 拒绝`
|
return msg.action === 'pass' ? `您发起的「${msg.data.proc_def_name}」已通过` : `您发起的「${msg.data.proc_def_name}」被 ${msg.data.nickname} 拒绝`
|
||||||
}
|
},
|
||||||
|
statusText({msg}) {
|
||||||
|
switch (msg.action) {
|
||||||
|
case 'pass': return '已通过';
|
||||||
|
case 'refuse': return '已拒绝';
|
||||||
|
case 'withdraw': return '已撤销';
|
||||||
|
default: return '处理中';
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {},
|
methods: {},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,7 +44,6 @@
|
|||||||
<h2 class="user-select-auto" @click="onViewDetail" v-html="transformEmojiToHtml(dialogData.name)"></h2>
|
<h2 class="user-select-auto" @click="onViewDetail" v-html="transformEmojiToHtml(dialogData.name)"></h2>
|
||||||
<em v-if="peopleNum > 0" @click="onDialogMenu('groupInfo')">({{peopleNum}})</em>
|
<em v-if="peopleNum > 0" @click="onDialogMenu('groupInfo')">({{peopleNum}})</em>
|
||||||
<Tag v-if="dialogData.bot" class="after" :fade="false">{{$L('机器人')}}</Tag>
|
<Tag v-if="dialogData.bot" class="after" :fade="false">{{$L('机器人')}}</Tag>
|
||||||
<Tag v-if="dialogData.type === 'user' && approvaUserStatus" class="after" color="red" :fade="false">{{$L(approvaUserStatus)}}</Tag>
|
|
||||||
<Tag v-if="dialogData.group_type=='all'" class="after pointer" :fade="false" @on-click="onDialogMenu('groupInfo')">{{$L('全员')}}</Tag>
|
<Tag v-if="dialogData.group_type=='all'" class="after pointer" :fade="false" @on-click="onDialogMenu('groupInfo')">{{$L('全员')}}</Tag>
|
||||||
<Tag v-else-if="dialogData.group_type=='department'" class="after pointer" :fade="false" @on-click="onDialogMenu('groupInfo')">{{$L('部门')}}</Tag>
|
<Tag v-else-if="dialogData.group_type=='department'" class="after pointer" :fade="false" @on-click="onDialogMenu('groupInfo')">{{$L('部门')}}</Tag>
|
||||||
<div v-if="msgLoadIng > 0 && allMsgs.length > 0" class="load"><Loading/></div>
|
<div v-if="msgLoadIng > 0 && allMsgs.length > 0" class="load"><Loading/></div>
|
||||||
@ -915,8 +914,6 @@ export default {
|
|||||||
scrollIng: 0,
|
scrollIng: 0,
|
||||||
scrollGroup: null,
|
scrollGroup: null,
|
||||||
|
|
||||||
approvaUserStatus: '',
|
|
||||||
|
|
||||||
observers: [],
|
observers: [],
|
||||||
msgChangeCache: {},
|
msgChangeCache: {},
|
||||||
|
|
||||||
@ -1664,8 +1661,6 @@ export default {
|
|||||||
if (this.autoFocus) {
|
if (this.autoFocus) {
|
||||||
this.inputFocus()
|
this.inputFocus()
|
||||||
}
|
}
|
||||||
//
|
|
||||||
this.getUserApproveStatus()
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3822,10 +3817,6 @@ export default {
|
|||||||
this.handleOpenMicroApp(clickElement);
|
this.handleOpenMicroApp(clickElement);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (clickElement.classList.contains('open-approve-details')) {
|
|
||||||
emitter.emit('approveDetails', clickElement.getAttribute("data-id"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
clickElement = clickElement.parentElement;
|
clickElement = clickElement.parentElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4565,27 +4556,6 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
async getUserApproveStatus() {
|
|
||||||
this.approvaUserStatus = ''
|
|
||||||
if (this.dialogData.type !== 'user' || this.dialogData.bot) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const isInstalled = await this.$store.dispatch("isMicroAppInstalled", 'approve');
|
|
||||||
if (!isInstalled) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.$store.dispatch("call", {
|
|
||||||
url: 'approve/user/status',
|
|
||||||
data: {
|
|
||||||
userid: this.dialogData.dialog_user.userid,
|
|
||||||
}
|
|
||||||
}).then(({data}) => {
|
|
||||||
this.approvaUserStatus = data;
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
$A.messageError(msg);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
async shakeToMsgId(id) {
|
async shakeToMsgId(id) {
|
||||||
try {
|
try {
|
||||||
const element = await $A.findElementWithRetry(() => this.$refs.scroller.$el.querySelector(`[data-id="${id}"]`)?.querySelector(".dialog-head"));
|
const element = await $A.findElementWithRetry(() => this.$refs.scroller.$el.querySelector(`[data-id="${id}"]`)?.querySelector(".dialog-head"));
|
||||||
|
|||||||
40
resources/assets/js/store/actions.js
vendored
40
resources/assets/js/store/actions.js
vendored
@ -648,7 +648,6 @@ export default {
|
|||||||
dispatch("getDialogTodo", 0).catch(() => {});
|
dispatch("getDialogTodo", 0).catch(() => {});
|
||||||
dispatch("getTaskPriority", 1000);
|
dispatch("getTaskPriority", 1000);
|
||||||
dispatch("getReportUnread", 1000);
|
dispatch("getReportUnread", 1000);
|
||||||
dispatch("getApproveUnread", 1000);
|
|
||||||
dispatch("getProjectsForDepartmentOwnerView").catch(() => {});
|
dispatch("getProjectsForDepartmentOwnerView").catch(() => {});
|
||||||
dispatch("getTaskForDashboard");
|
dispatch("getTaskForDashboard");
|
||||||
dispatch("dialogMsgRead");
|
dispatch("dialogMsgRead");
|
||||||
@ -679,34 +678,6 @@ export default {
|
|||||||
}, typeof timeout === "number" ? timeout : 1000)
|
}, typeof timeout === "number" ? timeout : 1000)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取审批待办未读数量
|
|
||||||
* @param state
|
|
||||||
* @param dispatch
|
|
||||||
* @param timeout
|
|
||||||
*/
|
|
||||||
getApproveUnread({state, dispatch}, timeout) {
|
|
||||||
window.__getApproveUnread && clearTimeout(window.__getApproveUnread)
|
|
||||||
window.__getApproveUnread = setTimeout(() => {
|
|
||||||
if (state.userId === 0) {
|
|
||||||
state.approveUnreadNumber = 0;
|
|
||||||
} else {
|
|
||||||
dispatch("call", {
|
|
||||||
url: 'approve/process/doto'
|
|
||||||
}).then(({data}) => {
|
|
||||||
state.approveUnreadNumber = data.total || 0;
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
if( msg.indexOf("404 not found") !== -1){
|
|
||||||
$A.modalInfo({
|
|
||||||
title: '版本过低',
|
|
||||||
content: '服务器版本过低,请升级服务器。',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, typeof timeout === "number" ? timeout : 1000)
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取/更新会员信息
|
* 获取/更新会员信息
|
||||||
* @param dispatch
|
* @param dispatch
|
||||||
@ -5026,17 +4997,6 @@ export default {
|
|||||||
}
|
}
|
||||||
})(msgDetail);
|
})(msgDetail);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/**
|
|
||||||
* 流程审批
|
|
||||||
*/
|
|
||||||
case "approve":
|
|
||||||
(function ({action}) {
|
|
||||||
if (action == 'unread') {
|
|
||||||
dispatch("getApproveUnread", 1000)
|
|
||||||
}
|
|
||||||
})(msgDetail);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
3
resources/assets/js/store/state.js
vendored
3
resources/assets/js/store/state.js
vendored
@ -272,9 +272,6 @@ export default {
|
|||||||
// 系统设置
|
// 系统设置
|
||||||
systemConfig: {},
|
systemConfig: {},
|
||||||
|
|
||||||
// 审批待办未读数量
|
|
||||||
approveUnreadNumber: 0,
|
|
||||||
|
|
||||||
// 会议
|
// 会议
|
||||||
meetingWindow: {
|
meetingWindow: {
|
||||||
show: false,
|
show: false,
|
||||||
|
|||||||
@ -1523,7 +1523,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.cause {
|
.cause {
|
||||||
border-bottom: 1px solid #e3e3e3;
|
|
||||||
border-top: 1px solid #e3e3e3;
|
border-top: 1px solid #e3e3e3;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
|||||||
@ -9,7 +9,6 @@ use App\Http\Controllers\Api\DialogController;
|
|||||||
use App\Http\Controllers\Api\PublicController;
|
use App\Http\Controllers\Api\PublicController;
|
||||||
use App\Http\Controllers\Api\ReportController;
|
use App\Http\Controllers\Api\ReportController;
|
||||||
use App\Http\Controllers\Api\SystemController;
|
use App\Http\Controllers\Api\SystemController;
|
||||||
use App\Http\Controllers\Api\ApproveController;
|
|
||||||
use App\Http\Controllers\Api\AssistantController;
|
use App\Http\Controllers\Api\AssistantController;
|
||||||
use App\Http\Controllers\Api\ProjectController;
|
use App\Http\Controllers\Api\ProjectController;
|
||||||
use App\Http\Controllers\Api\ComplaintController;
|
use App\Http\Controllers\Api\ComplaintController;
|
||||||
@ -52,9 +51,6 @@ Route::prefix('api')->middleware(['webapi'])->group(function () {
|
|||||||
// 公开接口
|
// 公开接口
|
||||||
Route::any('public/{method}', PublicController::class);
|
Route::any('public/{method}', PublicController::class);
|
||||||
Route::any('public/{method}/{action}', PublicController::class);
|
Route::any('public/{method}/{action}', PublicController::class);
|
||||||
// 审批
|
|
||||||
Route::any('approve/{method}', ApproveController::class);
|
|
||||||
Route::any('approve/{method}/{action}', ApproveController::class);
|
|
||||||
// 助手
|
// 助手
|
||||||
Route::any('assistant/{method}', AssistantController::class);
|
Route::any('assistant/{method}', AssistantController::class);
|
||||||
Route::any('assistant/{method}/{action}', AssistantController::class);
|
Route::any('assistant/{method}/{action}', AssistantController::class);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user