mirror of
https://github.com/kuaifan/dootask.git
synced 2026-06-24 00:02:13 +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/shapes-14-6-5.min.js
|
||||
drawio/webapp/js/stencils.min.js
|
||||
drawio/webapp/math/es5/core.js
|
||||
drawio/webapp/math/es5/input/asciimath.js
|
||||
drawio/webapp/math/es5/input/tex.js
|
||||
drawio/webapp/math/es5/output/svg.js
|
||||
drawio/webapp/math/es5/output/svg/fonts/tex.js
|
||||
drawio/webapp/styles/grapheditor.css
|
||||
|
||||
minder/css/chunk-vendors.fe9c56c6.css
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1257,6 +1257,51 @@ class DialogController extends AbstractController
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} api/dialog/msg/sendapprove 发送审批通知卡片
|
||||
*
|
||||
* @apiDescription 需要token身份。以「审批助手」机器人身份向指定用户发送审批模板卡片
|
||||
* (由 approve 插件调用,卡片仅展示、不与旧审批系统有数据关联)。
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup dialog
|
||||
* @apiName msg__sendapprove
|
||||
*
|
||||
* @apiParam {Number} to_userid 接收用户ID
|
||||
* @apiParam {String} type 卡片类型:approve_reviewer / approve_notifier / approve_submitter / approve_comment_notifier
|
||||
* @apiParam {String} [action] 动作:start / pass / refuse / withdraw(按类型取用)
|
||||
* @apiParam {Number} [is_finished] 是否已结束(0/1)
|
||||
* @apiParam {Object} data 卡片数据
|
||||
* @apiParam {String} [title] 消息标题(会话列表预览用)
|
||||
*/
|
||||
public function msg__sendapprove()
|
||||
{
|
||||
$user = User::auth();
|
||||
$toUserid = intval(Request::input('to_userid'));
|
||||
$type = trim(Request::input('type'));
|
||||
$action = trim(Request::input('action'));
|
||||
$isFinished = intval(Request::input('is_finished'));
|
||||
$data = Base::json2array(Request::input('data'));
|
||||
$title = trim(Request::input('title'));
|
||||
//
|
||||
$allow = ['approve_reviewer', 'approve_notifier', 'approve_submitter', 'approve_comment_notifier'];
|
||||
if ($toUserid <= 0 || !in_array($type, $allow)) {
|
||||
return Base::retError('参数错误');
|
||||
}
|
||||
$botUser = User::botGetOrCreate('approval-alert');
|
||||
$dialog = WebSocketDialog::checkUserDialog($botUser, $toUserid);
|
||||
if (empty($dialog)) {
|
||||
return Base::retError('无法创建对话');
|
||||
}
|
||||
$msgData = [
|
||||
'type' => $type,
|
||||
'action' => $action ?: null,
|
||||
'is_finished' => $isFinished,
|
||||
'data' => $data,
|
||||
'title' => $title,
|
||||
];
|
||||
return WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', $msgData, $botUser->userid, false, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} api/dialog/msg/sendrecord 发送语音
|
||||
*
|
||||
|
||||
@ -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;
|
||||
|
||||
use App\Models\ApproveProcInstHistory;
|
||||
use App\Models\User;
|
||||
use App\Models\UserCheckinRecord;
|
||||
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()) {
|
||||
continue; // 3天内没有打卡
|
||||
}
|
||||
if (ApproveProcInstHistory::userIsLeave($user->userid)) {
|
||||
continue; // 请假、外出
|
||||
}
|
||||
$dialog = WebSocketDialog::checkUserDialog($botUser, $user->userid);
|
||||
if ($dialog) {
|
||||
if ($type === 'exceed') {
|
||||
|
||||
@ -20,9 +20,6 @@ return [
|
||||
// 创始人密码修改开关:设为 'disabled' 时禁止修改创始人密码(User 模型)
|
||||
'password_owner' => env('PASSWORD_OWNER'),
|
||||
|
||||
// 审批流服务地址:审批微服务的内部访问 URL(ApproveController)
|
||||
'flow_url' => env('FLOW_URL'),
|
||||
|
||||
// Manticore 全文搜索服务主机(ManticoreBase)
|
||||
'search_host' => env('SEARCH_HOST', 'search'),
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "DooTask",
|
||||
"version": "1.7.90",
|
||||
"version": "1.7.91",
|
||||
"codeVerson": 237,
|
||||
"description": "DooTask is task management system.",
|
||||
"scripts": {
|
||||
|
||||
@ -447,7 +447,6 @@ export default {
|
||||
'/api/dialog/msg/download', // 会话文件
|
||||
'/api/project/task/filedown', // 任务文件
|
||||
'/api/file/download/pack', // 文件打包下载
|
||||
'/api/approve/down', // 审批导出下载
|
||||
'/api/project/task/down', // 任务导出下载
|
||||
'/api/system/checkin/down' // 签到导出下载
|
||||
];
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
<Badge class="tabbar-badge" :overflow-count="999" :text="msgUnreadMention"/>
|
||||
</template>
|
||||
<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>
|
||||
</li>
|
||||
</ul>
|
||||
@ -54,7 +54,7 @@ export default {
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['cacheDialogs', 'reportUnreadNumber', 'approveUnreadNumber']),
|
||||
...mapState(['cacheDialogs', 'reportUnreadNumber']),
|
||||
...mapGetters(['dashboardTask']),
|
||||
|
||||
/**
|
||||
@ -138,7 +138,7 @@ export default {
|
||||
},
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
|
||||
@ -82,7 +82,6 @@
|
||||
<DropdownItem name="allUser">{{$L('团队管理')}}</DropdownItem>
|
||||
<DropdownItem name="exportTask">{{$L('导出任务统计')}}</DropdownItem>
|
||||
<DropdownItem name="exportOverdueTask">{{$L('导出超期任务')}}</DropdownItem>
|
||||
<DropdownItem name="exportApprove">{{$L('导出审批数据')}}</DropdownItem>
|
||||
<DropdownItem name="exportCheckin">{{$L('导出签到数据')}}</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
@ -126,10 +125,6 @@
|
||||
v-else-if="item.path === 'workReport' && reportUnreadNumber > 0"
|
||||
class="manage-menu-report-badge"
|
||||
:count="reportUnreadNumber"/>
|
||||
<Badge
|
||||
v-else-if="item.path === 'approve' && approveUnreadNumber > 0"
|
||||
class="manage-menu-report-badge"
|
||||
:count="approveUnreadNumber"/>
|
||||
</div>
|
||||
</DropdownItem>
|
||||
</template>
|
||||
@ -162,7 +157,7 @@
|
||||
<li @click="toggleRoute('application')" :class="classNameRoute('application')">
|
||||
<i class="taskfont"></i>
|
||||
<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 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>
|
||||
@ -389,9 +384,6 @@
|
||||
<!--导出签到数据-->
|
||||
<CheckinExport v-model="exportCheckinShow"/>
|
||||
|
||||
<!--导出审批数据-->
|
||||
<ApproveExport v-model="exportApproveShow"/>
|
||||
|
||||
<!--任务详情-->
|
||||
<TaskModal ref="taskModal"/>
|
||||
|
||||
@ -457,16 +449,6 @@
|
||||
<ProjectArchived v-if="archivedProjectShow"/>
|
||||
</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">
|
||||
<MobileTabbar v-if="mobileTabbar" @on-click="onTabbarClick"/>
|
||||
@ -495,14 +477,11 @@ import DialogModal from "./manage/components/DialogModal";
|
||||
import TaskModal from "./manage/components/TaskModal";
|
||||
import CheckinExport from "./manage/components/CheckinExport";
|
||||
import TaskExport from "./manage/components/TaskExport";
|
||||
import ApproveExport from "./manage/components/ApproveExport";
|
||||
import ComplaintManagement from "./manage/components/ComplaintManagement";
|
||||
import MicroApps from "../components/MicroApps";
|
||||
import ResizeLine from "../components/ResizeLine.vue";
|
||||
import UserSelect from "../components/UserSelect.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 emitter from "../store/events";
|
||||
import SearchBox from "../components/SearchBox.vue";
|
||||
@ -514,14 +493,11 @@ import DepartmentOwnerView from "./manage/components/DepartmentOwnerView.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Approve,
|
||||
SearchBox,
|
||||
ApproveDetails,
|
||||
ImgUpload,
|
||||
UserSelect,
|
||||
TaskExport,
|
||||
CheckinExport,
|
||||
ApproveExport,
|
||||
TaskModal,
|
||||
DialogModal,
|
||||
MobileTabbar,
|
||||
@ -568,7 +544,6 @@ export default {
|
||||
|
||||
exportTaskShow: false,
|
||||
exportCheckinShow: false,
|
||||
exportApproveShow: false,
|
||||
|
||||
projectKeyValue: '',
|
||||
projectKeyLoading: 0,
|
||||
@ -600,10 +575,6 @@ export default {
|
||||
|
||||
complaintShow: false,
|
||||
|
||||
approveShow: false,
|
||||
approveDetails: {id: 0},
|
||||
approveDetailsShow: false,
|
||||
|
||||
taskBrowseLoading: false,
|
||||
taskBrowseHistory: [],
|
||||
|
||||
@ -621,7 +592,6 @@ export default {
|
||||
emitter.on('addTask', this.onAddTask);
|
||||
emitter.on('createGroup', this.onCreateGroup);
|
||||
emitter.on('dialogMsgPush', this.addDialogMsg);
|
||||
emitter.on('approveDetails', this.openApproveDetails);
|
||||
emitter.on('openReport', this.openReport);
|
||||
emitter.on('openFavorite', this.openFavorite);
|
||||
emitter.on('openRecent', this.openRecent);
|
||||
@ -634,14 +604,12 @@ export default {
|
||||
this.$store.dispatch("getUserInfo").catch(_ => {})
|
||||
this.$store.dispatch("getTaskPriority", 1000)
|
||||
this.$store.dispatch("getReportUnread", 1000)
|
||||
this.$store.dispatch("getApproveUnread", 1000)
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
emitter.off('addTask', this.onAddTask);
|
||||
emitter.off('createGroup', this.onCreateGroup);
|
||||
emitter.off('dialogMsgPush', this.addDialogMsg);
|
||||
emitter.off('approveDetails', this.openApproveDetails);
|
||||
emitter.off('openReport', this.openReport);
|
||||
emitter.off('openFavorite', this.openFavorite);
|
||||
emitter.off('openRecent', this.openRecent);
|
||||
@ -671,7 +639,6 @@ export default {
|
||||
'clientDownloadUrl',
|
||||
|
||||
'reportUnreadNumber',
|
||||
'approveUnreadNumber',
|
||||
|
||||
'dialogIns',
|
||||
'formOptions',
|
||||
@ -1112,9 +1079,6 @@ export default {
|
||||
case 'exportCheckin':
|
||||
this.exportCheckinShow = true;
|
||||
return;
|
||||
case 'exportApprove':
|
||||
this.exportApproveShow = true;
|
||||
return;
|
||||
case 'workReport':
|
||||
this.openReport(this.reportUnreadNumber > 0 ? 'receive' : 'my');
|
||||
return;
|
||||
@ -1132,11 +1096,6 @@ export default {
|
||||
$A.reloadUrl()
|
||||
});
|
||||
return;
|
||||
case 'approve':
|
||||
if (this.menu.findIndex((m) => m.path == path) > -1) {
|
||||
this.goForward({name: 'manage-approve'});
|
||||
}
|
||||
return;
|
||||
case 'complaint':
|
||||
this.complaintShow = true;
|
||||
return;
|
||||
@ -1201,10 +1160,7 @@ export default {
|
||||
},
|
||||
|
||||
classNameRoute(path) {
|
||||
let name = this.routeName
|
||||
if (name == 'manage-approve') {
|
||||
name = `manage-application`
|
||||
}
|
||||
const name = this.routeName
|
||||
return {
|
||||
"active": name === `manage-${path}`,
|
||||
};
|
||||
@ -1678,13 +1634,6 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
openApproveDetails(id) {
|
||||
this.approveDetailsShow = true;
|
||||
this.$nextTick(() => {
|
||||
this.approveDetails = {id};
|
||||
})
|
||||
},
|
||||
|
||||
openReport(tab) {
|
||||
this.workReportTab = tab;
|
||||
this.workReportShow = true;
|
||||
@ -1706,9 +1655,6 @@ export default {
|
||||
case 'overdue':
|
||||
this.exportOverdueTask();
|
||||
break;
|
||||
case 'approve':
|
||||
this.exportApproveShow = true;
|
||||
break;
|
||||
case 'checkin':
|
||||
this.exportCheckinShow = true;
|
||||
break;
|
||||
@ -1776,9 +1722,6 @@ export default {
|
||||
|
||||
onTabbarClick(act, params = '') {
|
||||
switch (act) {
|
||||
case 'approve':
|
||||
this.approveShow = true
|
||||
break;
|
||||
case 'createGroup':
|
||||
this.onAddMenu('group')
|
||||
break;
|
||||
|
||||
@ -97,7 +97,6 @@
|
||||
v-if="!sortingMode"
|
||||
@click.stop="handleCardClick(card, 'badge')"
|
||||
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"/>
|
||||
</div>
|
||||
</div>
|
||||
@ -528,7 +527,6 @@ export default {
|
||||
'userInfo',
|
||||
'userIsAdmin',
|
||||
'reportUnreadNumber',
|
||||
'approveUnreadNumber',
|
||||
'cacheDialogs',
|
||||
'windowOrientation',
|
||||
'windowPortrait',
|
||||
@ -543,7 +541,6 @@ export default {
|
||||
applyList() {
|
||||
const list = [
|
||||
// 常用应用
|
||||
{value: "approve", label: "审批中心", sort: 30, show: this.microAppsIds.includes('approve')},
|
||||
{value: "favorite", label: "我的收藏", sort: 45},
|
||||
{value: "recent", label: "最近打开", sort: 47},
|
||||
{value: "report", label: "工作报告", sort: 50},
|
||||
@ -985,7 +982,6 @@ export default {
|
||||
const list = [
|
||||
{label: this.$L('导出任务统计'), value: 'task'},
|
||||
{label: this.$L('导出超期任务'), value: 'overdue'},
|
||||
{label: this.$L('导出审批数据'), value: 'approve'},
|
||||
{label: this.$L('导出签到数据'), value: 'checkin'},
|
||||
];
|
||||
this.$store.commit('menu/operation', {
|
||||
@ -1037,9 +1033,6 @@ export default {
|
||||
showBadge(item, type) {
|
||||
let num = 0;
|
||||
switch (type) {
|
||||
case 'approve':
|
||||
num = this.approveUnreadNumber;
|
||||
break;
|
||||
case 'report':
|
||||
num = this.reportUnreadNumber;
|
||||
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 v-if="msg.data.thumb" v-html="imageHtml(msg.data.thumb)"></p>
|
||||
</div>
|
||||
<div class="btn-raw no-dark-content">
|
||||
<button class="ivu-btn ivu-btn-grey">{{$L('查看详情')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@ -2,16 +2,13 @@
|
||||
<div class="open-approve-details" :data-id="msg.data.id">
|
||||
<b>{{ $L(`抄送 ${msg.data.nickname} 提交的「${msg.data.proc_def_name}」记录`) }}</b>
|
||||
<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>
|
||||
<b>{{$L("详情")}}</b>
|
||||
<p v-if="$A.strExists(msg.data.proc_def_name, '请假') && msg.data.type">{{$L("假期类型")}}:{{ $L(msg.data.type) }}</p>
|
||||
<p>{{$L("开始时间")}}:{{ msg.data.start_time }} ({{ $L(msg.data.start_day_of_week) }})</p>
|
||||
<p>{{$L("结束时间")}}:{{ msg.data.end_time }} ({{ $L(msg.data.end_day_of_week) }})</p>
|
||||
<p>{{$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>
|
||||
<p v-if="msg.data.type">{{$L("类型")}}:{{ $L(msg.data.type) }}</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 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 v-if="msg.data.description">{{$L("事由")}}:{{ msg.data.description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -2,23 +2,15 @@
|
||||
<div class="open-approve-details" :data-id="msg.data.id">
|
||||
<b>{{ $L(`${msg.data.nickname} 提交的「${msg.data.proc_def_name}」待你审批`) }}</b>
|
||||
<div class="cause">
|
||||
<p>{{$L("状态")}}:<b>{{ $L(statusText) }}</b></p>
|
||||
<p>{{$L("申请人")}}:<span class="mark-color">@{{ msg.data.nickname }}</span> {{ msg.data.department }}</p>
|
||||
<b>{{$L("详情")}}</b>
|
||||
<p v-if="$A.strExists(msg.data.proc_def_name, '请假') && msg.data.type">{{$L("假期类型")}}:{{ $L(msg.data.type) }}</p>
|
||||
<p>{{$L("开始时间")}}:{{ msg.data.start_time }} ({{ $L(msg.data.start_day_of_week) }})</p>
|
||||
<p>{{$L("结束时间")}}:{{ msg.data.end_time }} ({{ $L(msg.data.end_day_of_week) }})</p>
|
||||
<p>{{$L("事由")}}:{{ msg.data.description }}</p>
|
||||
<p v-if="msg.data.type">{{$L("类型")}}:{{ $L(msg.data.type) }}</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 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 v-if="msg.data.description">{{$L("事由")}}:{{ msg.data.description }}</p>
|
||||
<p v-if="msg.data.thumb" v-html="imageHtml(msg.data.thumb)"></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>
|
||||
<template v-else>
|
||||
<button class="ivu-btn ivu-btn-primary">{{$L("同意")}}</button>
|
||||
<button class="ivu-btn ivu-btn-error">{{$L("拒绝")}}</button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -30,6 +22,16 @@ export default {
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
computed: {
|
||||
statusText({msg}) {
|
||||
switch (msg.action) {
|
||||
case 'pass': return '已同意';
|
||||
case 'refuse': return '已拒绝';
|
||||
case 'withdraw': return '已撤销';
|
||||
default: return '待审批';
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
imageHtml(info) {
|
||||
const data = $A.imageRatioHandle({
|
||||
|
||||
@ -2,17 +2,13 @@
|
||||
<div class="open-approve-details" :data-id="msg.data.id">
|
||||
<b>{{ $L(title) }}</b>
|
||||
<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>
|
||||
<b>{{$L("详情")}}</b>
|
||||
<p v-if="$A.strExists(msg.data.proc_def_name, '请假') && msg.data.type">{{$L("假期类型")}}:{{ $L(msg.data.type) }}</p>
|
||||
<p>{{$L("开始时间")}}:{{ msg.data.start_time }} ({{ $L(msg.data.start_day_of_week) }})</p>
|
||||
<p>{{$L("结束时间")}}:{{ msg.data.end_time }} ({{ $L(msg.data.end_day_of_week) }})</p>
|
||||
<p>{{$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>
|
||||
<p v-if="msg.data.type">{{$L("类型")}}:{{ $L(msg.data.type) }}</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 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 v-if="msg.data.description">{{$L("事由")}}:{{ msg.data.description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -28,7 +24,15 @@ export default {
|
||||
computed: {
|
||||
title({msg}) {
|
||||
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: {},
|
||||
}
|
||||
|
||||
@ -44,7 +44,6 @@
|
||||
<h2 class="user-select-auto" @click="onViewDetail" v-html="transformEmojiToHtml(dialogData.name)"></h2>
|
||||
<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.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-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>
|
||||
@ -915,8 +914,6 @@ export default {
|
||||
scrollIng: 0,
|
||||
scrollGroup: null,
|
||||
|
||||
approvaUserStatus: '',
|
||||
|
||||
observers: [],
|
||||
msgChangeCache: {},
|
||||
|
||||
@ -1664,8 +1661,6 @@ export default {
|
||||
if (this.autoFocus) {
|
||||
this.inputFocus()
|
||||
}
|
||||
//
|
||||
this.getUserApproveStatus()
|
||||
},
|
||||
|
||||
/**
|
||||
@ -3822,10 +3817,6 @@ export default {
|
||||
this.handleOpenMicroApp(clickElement);
|
||||
return;
|
||||
}
|
||||
if (clickElement.classList.contains('open-approve-details')) {
|
||||
emitter.emit('approveDetails', clickElement.getAttribute("data-id"));
|
||||
return;
|
||||
}
|
||||
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) {
|
||||
try {
|
||||
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("getTaskPriority", 1000);
|
||||
dispatch("getReportUnread", 1000);
|
||||
dispatch("getApproveUnread", 1000);
|
||||
dispatch("getProjectsForDepartmentOwnerView").catch(() => {});
|
||||
dispatch("getTaskForDashboard");
|
||||
dispatch("dialogMsgRead");
|
||||
@ -679,34 +678,6 @@ export default {
|
||||
}, 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
|
||||
@ -5026,17 +4997,6 @@ export default {
|
||||
}
|
||||
})(msgDetail);
|
||||
break;
|
||||
|
||||
/**
|
||||
* 流程审批
|
||||
*/
|
||||
case "approve":
|
||||
(function ({action}) {
|
||||
if (action == 'unread') {
|
||||
dispatch("getApproveUnread", 1000)
|
||||
}
|
||||
})(msgDetail);
|
||||
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: {},
|
||||
|
||||
// 审批待办未读数量
|
||||
approveUnreadNumber: 0,
|
||||
|
||||
// 会议
|
||||
meetingWindow: {
|
||||
show: false,
|
||||
|
||||
@ -1523,7 +1523,6 @@
|
||||
}
|
||||
|
||||
.cause {
|
||||
border-bottom: 1px solid #e3e3e3;
|
||||
border-top: 1px solid #e3e3e3;
|
||||
padding-bottom: 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\ReportController;
|
||||
use App\Http\Controllers\Api\SystemController;
|
||||
use App\Http\Controllers\Api\ApproveController;
|
||||
use App\Http\Controllers\Api\AssistantController;
|
||||
use App\Http\Controllers\Api\ProjectController;
|
||||
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}/{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}/{action}', AssistantController::class);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user