Merge pull request #169 from hitosea/pro

Pro
This commit is contained in:
kuaifan 2023-06-28 22:16:03 +08:00 committed by kuaifan
commit b667184c35
11 changed files with 443 additions and 77 deletions

View File

@ -952,6 +952,7 @@ class ApproveController extends AbstractController
$data = [ $data = [
'id' => $process['id'], 'id' => $process['id'],
'nickname' => User::userid2nickname($type == 'approve_submitter' ? $toUser['userid'] : $process['start_user_id']), 'nickname' => User::userid2nickname($type == 'approve_submitter' ? $toUser['userid'] : $process['start_user_id']),
'start_nickname' => User::userid2nickname($process['start_user_id']),
'proc_def_name' => $process['proc_def_name'], 'proc_def_name' => $process['proc_def_name'],
'department' => $process['department'], 'department' => $process['department'],
'type' => $process['var']['type'], 'type' => $process['var']['type'],

View File

@ -16,6 +16,7 @@ use App\Models\ProjectLog;
use App\Models\ProjectTask; use App\Models\ProjectTask;
use App\Models\ProjectTaskFile; use App\Models\ProjectTaskFile;
use App\Models\ProjectTaskFlowChange; use App\Models\ProjectTaskFlowChange;
use App\Models\ProjectTaskUser;
use App\Models\ProjectUser; use App\Models\ProjectUser;
use App\Models\User; use App\Models\User;
use App\Models\WebSocketDialog; use App\Models\WebSocketDialog;
@ -895,8 +896,7 @@ class ProjectController extends AbstractController
public function task__lists() public function task__lists()
{ {
$user = User::auth(); $user = User::auth();
// $userid = $user->userid;
$builder = ProjectTask::with(['taskUser', 'taskTag']);
// //
$parent_id = intval(Request::input('parent_id')); $parent_id = intval(Request::input('parent_id'));
$project_id = intval(Request::input('project_id')); $project_id = intval(Request::input('project_id'));
@ -909,6 +909,12 @@ class ProjectController extends AbstractController
$sorts = Request::input('sorts'); $sorts = Request::input('sorts');
$keys = is_array($keys) ? $keys : []; $keys = is_array($keys) ? $keys : [];
$sorts = is_array($sorts) ? $sorts : []; $sorts = is_array($sorts) ? $sorts : [];
// 任务可见性
$visibility_task_ids = ProjectTask::getVisibleUserids($userid, $project_id);
$builder = ProjectTask::with(['taskUser', 'taskTag']);
$builder->whereIn("project_tasks.id", $visibility_task_ids);
// //
if ($keys['name']) { if ($keys['name']) {
if (Base::isNumber($keys['name'])) { if (Base::isNumber($keys['name'])) {
@ -1341,17 +1347,27 @@ class ProjectController extends AbstractController
*/ */
public function task__one() public function task__one()
{ {
User::auth(); $user = User::auth();
// //
$task_id = intval(Request::input('task_id')); $task_id = intval(Request::input('task_id'));
$archived = Request::input('archived', 'no'); $archived = Request::input('archived', 'no');
// //
$isArchived = str_replace(['all', 'yes', 'no'], [null, false, true], $archived); $isArchived = str_replace(['all', 'yes', 'no'], [null, false, true], $archived);
$task = ProjectTask::userTask($task_id, $isArchived, true, false, ['taskUser', 'taskTag']); $task = ProjectTask::userTask($task_id, $isArchived, true, false, ['taskUser', 'taskTag']);
// 项目可见性
$project_userid = Project::whereId($task->project_id)->value('userid'); // 项目负责人
if ($task->is_all_visible != 1 && $user->userid != $project_userid) {
$visibleUserids = ProjectTaskUser::whereTaskId($task_id)->pluck('userid')->toArray(); // 是否任务负责人、协助人、可见人
$subVisibleUserids = ProjectTaskUser::whereTaskPid($task_id)->pluck('userid')->toArray(); // 是否子任务负责人、协助人
if (!in_array($user->userid, $visibleUserids) && !in_array($user->userid, $subVisibleUserids)) {
return Base::retError('无任务权限');
}
}
// //
$data = $task->toArray(); $data = $task->toArray();
$data['project_name'] = $task->project?->name; $data['project_name'] = $task->project?->name;
$data['column_name'] = $task->projectColumn?->name; $data['column_name'] = $task->projectColumn?->name;
$data['visibility_appointor'] = $task->is_all_visible==1 ? [0] : ProjectTaskUser::whereTaskId($task_id)->whereOwner(2)->pluck('userid');
return Base::retSuccess('success', $data); return Base::retSuccess('success', $data);
} }
@ -1557,7 +1573,7 @@ class ProjectController extends AbstractController
*/ */
public function task__add() public function task__add()
{ {
User::auth(); $user = User::auth();
// //
$data = Request::input(); $data = Request::input();
$project_id = intval($data['project_id']); $project_id = intval($data['project_id']);
@ -1602,6 +1618,17 @@ class ProjectController extends AbstractController
$data = $data->toArray(); $data = $data->toArray();
$data['new_column'] = $newColumn; $data['new_column'] = $newColumn;
} }
if ($data['is_all_visible'] == 1) {
$data['is_visible'] = 1;
} else {
$projectOwner = Project::whereId($data['project_id'])->pluck('userid')->toArray(); // 项目负责人
$taskOwnerAndAssists = ProjectTaskUser::select(['userid', 'owner'])->whereTaskId($data['id'])->pluck('userid')->toArray();
$visibleIds = array_merge($projectOwner, $taskOwnerAndAssists);
$data['is_visible'] = in_array($user->userid, $visibleIds) ? 1 : 0;
}
$task->pushMsg('add', $data); $task->pushMsg('add', $data);
$task->taskPush(null, 0); $task->taskPush(null, 0);
return Base::retSuccess('添加成功', $data); return Base::retSuccess('添加成功', $data);
@ -1640,10 +1667,16 @@ class ProjectController extends AbstractController
'project_id' => $task->project_id, 'project_id' => $task->project_id,
'column_id' => $task->column_id, 'column_id' => $task->column_id,
'times' => [$task->start_at, $task->end_at], 'times' => [$task->start_at, $task->end_at],
'owner' => [User::userid()] 'owner' => [User::userid()],
'is_all_visible' => 0,
]); ]);
$data = ProjectTask::oneTask($task->id); $data = ProjectTask::oneTask($task->id);
$task->pushMsg('add', $data); $projectUserid = Project::whereId($data->project_id)->value('userid');
$pushUserIds = ProjectTaskUser::whereTaskId($task->id)->pluck('userid')->toArray();
$pushUserIds[] = $projectUserid;
foreach ($pushUserIds as $userId) {
$task->pushMsg('add', $data, $userId);
}
return Base::retSuccess('添加成功', $data); return Base::retSuccess('添加成功', $data);
} }
@ -1663,6 +1696,7 @@ class ProjectController extends AbstractController
* @apiParam {String} [content] 任务详情(子任务不支持) * @apiParam {String} [content] 任务详情(子任务不支持)
* @apiParam {String} [color] 背景色(子任务不支持) * @apiParam {String} [color] 背景色(子任务不支持)
* @apiParam {Array} [assist] 修改协助人员(子任务不支持) * @apiParam {Array} [assist] 修改协助人员(子任务不支持)
* @apiParam {Array} [visibility_appointor] 修改可见性人员
* *
* @apiParam {Number} [p_level] 优先级相关(子任务不支持) * @apiParam {Number} [p_level] 优先级相关(子任务不支持)
* @apiParam {String} [p_name] 优先级相关(子任务不支持) * @apiParam {String} [p_name] 优先级相关(子任务不支持)
@ -1679,17 +1713,54 @@ class ProjectController extends AbstractController
{ {
User::auth(); User::auth();
// //
$data = Request::input(); $param = Request::input();
$task_id = intval($data['task_id']); $task_id = intval($param['task_id']);
// //
$task = ProjectTask::userTask($task_id, true, true, 2); $task = ProjectTask::userTask($task_id, true, true, 2);
$taskUser = ProjectTaskUser::select(['userid', 'owner'])->whereTaskId($task_id)->whereIn('owner', [0, 1])->get();
$owners = $taskUser->where('owner', 1)->pluck('userid')->toArray(); // 负责人
$assist = $taskUser->where('owner', 0)->pluck('userid')->toArray(); // 协助人
// 更新任务 // 更新任务
$updateMarking = []; $updateMarking = [];
$task->updateTask($data, $updateMarking); $task->updateTask($param, $updateMarking);
// //
$data = ProjectTask::oneTask($task->id)->toArray(); $data = ProjectTask::oneTask($task->id)->toArray();
$data['update_marking'] = $updateMarking ?: json_decode('{}'); $data['update_marking'] = $updateMarking ?: json_decode('{}');
$data['visibility_appointor'] = $data['is_all_visible'] == 1 ? [0] : ProjectTaskUser::whereTaskId($task->id)->whereOwner(2)->pluck('userid');
$task->pushMsg('update', $data); $task->pushMsg('update', $data);
// 可见性推送
if (Arr::exists($param, 'is_all_visible')) {
if ($data['is_all_visible'] == 1) {
$task->pushMsgVisibleAdd($data);
}
if ($data['is_all_visible'] == 0) {
if ($param['visibility_appointor']) {
$task->pushMsgVisibleUpdate($data);
} else {
$task->pushMsgVisibleRemove();
}
}
} elseif (Arr::exists($param, 'visibility_appointor')) {
if ($param['visibility_appointor']) {
$task->pushMsgVisibleUpdate($data);
} else {
$task->pushMsgVisibleRemove();
}
}
if (Arr::exists($param, 'owner') && $data['is_all_visible'] == 0) {
$subUserids = ProjectTaskUser::whereTaskPid($data['id'])->pluck('userid')->toArray();
$diff = array_diff($owners, $param['owner'], $subUserids);
if ($diff) {
$task->pushMsgVisibleRemove($diff);
}
}
if (Arr::exists($param, 'assist') && $data['is_all_visible'] == 0) {
$diff = array_diff($owners, $param['assist']);
if ($diff) {
$task->pushMsgVisibleRemove($diff);
}
}
// //
return Base::retSuccess('修改成功', $data); return Base::retSuccess('修改成功', $data);
} }

View File

@ -370,6 +370,18 @@ class ProjectTask extends AbstractModel
$p_color = $data['p_color']; $p_color = $data['p_color'];
$top = intval($data['top']); $top = intval($data['top']);
$userid = User::userid(); $userid = User::userid();
$visibility_appoint = $data['visibility_appoint'];
$visibility_appointor = $data['visibility_appointor'];
// 可见性
$visibility_userids = [];
$is_all_visible = 0;
if ($visibility_appoint) {
if (in_array(0, $visibility_appointor)) {
$is_all_visible = 1;
} else {
$visibility_userids = $visibility_appointor;
}
}
// //
if (ProjectTask::whereProjectId($project_id) if (ProjectTask::whereProjectId($project_id)
->whereNull('project_tasks.complete_at') ->whereNull('project_tasks.complete_at')
@ -398,6 +410,7 @@ class ProjectTask extends AbstractModel
'p_level' => $p_level, 'p_level' => $p_level,
'p_name' => $p_name, 'p_name' => $p_name,
'p_color' => $p_color, 'p_color' => $p_color,
'is_all_visible' => $is_all_visible
]); ]);
if ($content) { if ($content) {
$task->desc = Base::getHtml($content, 100); $task->desc = Base::getHtml($content, 100);
@ -462,7 +475,7 @@ class ProjectTask extends AbstractModel
} }
} }
// //
return AbstractModel::transaction(function() use ($assist, $times, $subtasks, $content, $owner, $task) { return AbstractModel::transaction(function() use ($assist, $times, $subtasks, $content, $owner, $task, $visibility_userids) {
$task->save(); $task->save();
$owner = array_values(array_unique($owner)); $owner = array_values(array_unique($owner));
foreach ($owner as $uid) { foreach ($owner as $uid) {
@ -484,6 +497,17 @@ class ProjectTask extends AbstractModel
'owner' => 0, 'owner' => 0,
])->save(); ])->save();
} }
foreach ($visibility_userids as $uid) {
ProjectTaskUser::createInstance([
'project_id' => $task->project_id,
'task_id' => $task->id,
'task_pid' => $task->parent_id ?: $task->id,
'userid' => $uid,
'owner' => 2,
])->save();
}
if ($content) { if ($content) {
ProjectTaskContent::createInstance([ ProjectTaskContent::createInstance([
'project_id' => $task->project_id, 'project_id' => $task->project_id,
@ -691,6 +715,27 @@ class ProjectTask extends AbstractModel
$updateMarking['is_update_project'] = true; $updateMarking['is_update_project'] = true;
$this->syncDialogUser(); $this->syncDialogUser();
} }
// 可见性
if (Arr::exists($data, 'visibility_appointor') || Arr::exists($data, 'is_all_visible')) {
if ($data['is_all_visible'] == 1) {
ProjectTask::whereId($data['task_id'])->update(['is_all_visible' => 1]);
ProjectTaskUser::whereTaskId($data['task_id'])->whereOwner(2)->delete();
} elseif ( isset($data['visibility_appointor']) || $data['is_all_visible'] == 0) {
ProjectTask::whereId($data['task_id'])->update(['is_all_visible' => 0]);
// 覆盖
ProjectTaskUser::whereTaskId($data['task_id'])->whereOwner(2)->delete();
foreach ($data['visibility_appointor'] as $uid) {
ProjectTaskUser::createInstance([
'project_id' => $this->project_id,
'task_id' => $this->id,
'task_pid' => $this->parent_id ?: $this->id,
'userid' => $uid,
'owner' => 2,
])->save();
}
}
}
// 计划时间(原则:子任务时间在主任务时间内) // 计划时间(原则:子任务时间在主任务时间内)
if (Arr::exists($data, 'times')) { if (Arr::exists($data, 'times')) {
$oldAt = [Carbon::parse($this->start_at), Carbon::parse($this->end_at)]; $oldAt = [Carbon::parse($this->start_at), Carbon::parse($this->end_at)];
@ -1372,6 +1417,8 @@ class ProjectTask extends AbstractModel
$userids = $this->project->relationUserids(); $userids = $this->project->relationUserids();
} elseif (!is_array($userid)) { } elseif (!is_array($userid)) {
$userids = [$userid]; $userids = [$userid];
} elseif (is_array($userid)) {
$userids = $userid;
} }
// //
$array = []; $array = [];
@ -1391,8 +1438,8 @@ class ProjectTask extends AbstractModel
]; ];
} }
// 协助人 // 协助人
$assists = $taskUser->pluck('userid')->toArray(); $assists = $taskUser->where('owner', 0)->pluck('userid')->toArray();
$assists = array_intersect($userids, array_diff($assists, $owners)); $assists = array_intersect($userids, $assists);
if ($assists) { if ($assists) {
$array[] = [ $array[] = [
'userid' => array_values($assists), 'userid' => array_values($assists),
@ -1403,13 +1450,20 @@ class ProjectTask extends AbstractModel
]; ];
} }
// 项目成员(其他人) // 项目成员(其他人)
$userids = array_diff($userids, $owners, $assists); if ($data['is_all_visible'] == 1) {
// 全部可见
$userids = array_diff($userids, $owners, $assists);
} else {
// 指定可见
$userids = $taskUser->where('owner', 2)->pluck('userid')->toArray();
}
$data = array_merge($data, [ $data = array_merge($data, [
'owner' => 0, 'owner' => 0,
'assist' => 0, 'assist' => 0,
]); ]);
} }
} }
//
$array[] = [ $array[] = [
'userid' => array_values($userids), 'userid' => array_values($userids),
'data' => $data 'data' => $data
@ -1418,7 +1472,7 @@ class ProjectTask extends AbstractModel
foreach ($array as $item) { foreach ($array as $item) {
$params = [ $params = [
'ignoreFd' => Request::header('fd'), 'ignoreFd' => Request::header('fd'),
'userid' => array_values($item), 'userid' => $item['userid'],
'msg' => [ 'msg' => [
'type' => 'projectTask', 'type' => 'projectTask',
'action' => $action, 'action' => $action,
@ -1430,6 +1484,112 @@ class ProjectTask extends AbstractModel
} }
} }
/**
* 添加可见性任务 推送
* @param array|self $data 发送内容,默认为[id, parent_id, project_id, column_id, dialog_id]
*/
public function pushMsgVisibleAdd($data = null)
{
if (!$this->project) {
return;
}
if ($data === null) {
$data = [
'id' => $this->id,
'parent_id' => $this->parent_id,
'project_id' => $this->project_id,
'column_id' => $this->column_id,
'dialog_id' => $this->dialog_id,
];
} elseif ($data instanceof self) {
$data = $data->toArray();
}
//
$array = [];
if ($this->is_all_visible == 0) {
$userids = ProjectTaskUser::select(['userid', 'owner'])->whereTaskId($this->id)->orWhere('task_pid' , '=', $this->id)->pluck('userid')->toArray();
} else {
$userids = ProjectUser::whereProjectId($this->project_id)->pluck('userid')->toArray(); // 项目成员
}
//
$array[] = [
'userid' => array_values($userids),
'data' => $data
];
//
foreach ($array as $item) {
$params = [
'ignoreFd' => '0',
'userid' => $item['userid'],
'msg' => [
'type' => 'projectTask',
'action' => 'add',
'data' => $item['data'],
]
];
$task = new PushTask($params, false);
Task::deliver($task);
}
}
/**
* 删除可见性任务 推送
* @param array $userids
* @return void
*/
public function pushMsgVisibleRemove(array $userids = [])
{
if (!$this->project) {
return;
}
$data = [
'id' => $this->id,
'parent_id' => $this->parent_id,
'project_id' => $this->project_id,
'column_id' => $this->column_id,
'dialog_id' => $this->dialog_id,
];
//
$array = [];
if (empty($userids)) {
// 默认 项目成员 与 项目负责人,任务负责人、协助人的差集
$projectUserids = ProjectUser::whereProjectId($this->project_id)->pluck('userid')->toArray(); // 项目成员
$projectOwner = Project::whereId($this->project_id)->pluck('userid')->toArray(); // 项目负责人
$taskOwnerAndAssists = ProjectTaskUser::select(['userid', 'owner'])->whereIn('owner', [0, 1])->whereTaskId($this->id)->pluck('userid')->toArray();
$userids = array_diff($projectUserids, $projectOwner, $taskOwnerAndAssists);
}
//
$array[] = [
'userid' => array_values($userids),
'data' => $data
];
//
foreach ($array as $item) {
$params = [
'ignoreFd' => '0',
'userid' => $item['userid'],
'msg' => [
'type' => 'projectTask',
'action' => 'delete',
'data' => $item['data'],
]
];
$task = new PushTask($params, false);
Task::deliver($task);
}
}
/**
* 更新可见性任务 推送
* @param array|self $data 发送内容,默认为[id, parent_id, project_id, column_id, dialog_id]
*/
public function pushMsgVisibleUpdate($data)
{
$this->pushMsgVisibleRemove();
usleep(300);
$this->pushMsgVisibleAdd($data);
}
/** /**
* 任务提醒 * 任务提醒
* @param $userids * @param $userids
@ -1559,4 +1719,27 @@ class ProjectTask extends AbstractModel
// //
return $task; return $task;
} }
/**
* 获取用户任务可见性
* @param $userid
* @param $project_id
* @return array
*/
public static function getVisibleUserids($userid, $project_id = 0)
{
return (new ProjectTask)->setTable('pt')->from('project_tasks as pt')
->leftJoin('project_task_users as b', 'b.task_id', '=', 'pt.id')
->Join('projects as p', 'p.id', '=', 'pt.project_id')
->when($project_id, function ($q) use ($project_id) {
$q->where('pt.project_id', '=', $project_id); // 负责人项目ids
})
->where(function ($q) use ($userid){
$q->where("pt.is_all_visible", '=', 1);
$q->OrWhere("p.userid", '=', $userid);
$q->OrWhere("b.userid", '=', $userid);
})
->pluck("pt.id")
->toArray();
}
} }

View File

@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddProjectTasksIsAllVisible extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
//
Schema::table('project_tasks', function (Blueprint $table) {
if (!Schema::hasColumn('project_tasks', 'is_all_visible')) {
$table->tinyInteger('is_all_visible')->nullable()->default(1)->after('userid')->comment('是否所有人可见');
}
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
Schema::table('project_tasks', function (Blueprint $table) {
$table->dropColumn("avatar");
});
}
}

View File

@ -159,8 +159,8 @@
</div> </div>
<div class="approve-operation"> <div class="approve-operation">
<div style="flex: 1;"></div> <div style="flex: 1;"></div>
<Button type="success" v-if="(datas.candidate || '').split(',').indexOf(userId + '') != -1" @click="approve(1)">{{$L('同意')}}</Button> <Button type="success" v-if="isShowAgreeBtn" @click="approve(1)">{{$L('同意')}}</Button>
<Button type="error" v-if="(datas.candidate || '').split(',').indexOf(userId + '') != -1" @click="approve(2)">{{$L('拒绝')}}</Button> <Button type="error" v-if="isShowAgreeBtn" @click="approve(2)">{{$L('拒绝')}}</Button>
<Button type="warning" v-if="isShowWarningBtn" @click="revocation">{{$L('撤销')}}</Button> <Button type="warning" v-if="isShowWarningBtn" @click="revocation">{{$L('撤销')}}</Button>
<Button @click="comment" type="success" ghost>+{{$L('添加评论')}}</Button> <Button @click="comment" type="success" ghost>+{{$L('添加评论')}}</Button>
</div> </div>
@ -232,6 +232,9 @@ export default {
}, },
}, },
computed: { computed: {
isShowAgreeBtn(){
return (this.datas.candidate || '').split(',').indexOf(this.userId + '') != -1 && !this.datas.is_finished
},
isShowWarningBtn(){ isShowWarningBtn(){
let is = (this.userId == this.datas.start_user_id) && this.datas?.is_finished != true; let is = (this.userId == this.datas.start_user_id) && this.datas?.is_finished != true;
(this.datas.node_infos || []).map(h=>{ (this.datas.node_infos || []).map(h=>{

View File

@ -93,6 +93,21 @@
</ETooltip> </ETooltip>
</div> </div>
</FormItem> </FormItem>
<FormItem :label="$L('可见性')">
<Checkbox disabled v-model="addData.visibility_principal" :true-value="1" :false-value="0">{{$L('任务负责人')}}</Checkbox>
<Checkbox disabled v-model="addData.visibility_assist" :true-value="1" :false-value="0">{{$L('任务协助人')}}</Checkbox>
<RadioGroup v-model="addData.is_all_visible">
<Radio :label=1>{{$L('所有人员')}}</Radio>
<Radio :label=0>{{$L('指定成员')}}</Radio>
</RadioGroup>
<UserSelect
class="item-content user"
v-show="!addData.is_all_visible"
v-model="addData.visibility_appointor"
:avatar-size="28"
:title="$L('选择指定人员')"
:project-id="addData.project_id"/>
</FormItem>
<div class="subtasks"> <div class="subtasks">
<div v-if="addData.subtasks.length > 0" class="sublist"> <div v-if="addData.subtasks.length > 0" class="sublist">
<Row> <Row>
@ -186,6 +201,12 @@ export default {
p_level: 0, p_level: 0,
p_name: '', p_name: '',
p_color: '', p_color: '',
//
visibility_principal: 1,
visibility_assist: 1,
visibility_appoint: 1,
is_all_visible: 1,
visibility_appointor: [],
}, },
cascaderShow: false, cascaderShow: false,

View File

@ -113,6 +113,11 @@ export default {
p_level: 0, p_level: 0,
p_name: '', p_name: '',
p_color: '', p_color: '',
//
visibility_principal: 1,
visibility_assist: 1,
visibility_appoint: 1,
visibility_appointor: [0],
}, },
active: false, active: false,
@ -217,6 +222,11 @@ export default {
p_level: 0, p_level: 0,
p_name: '', p_name: '',
p_color: '', p_color: '',
//
visibility_principal: 1,
visibility_assist: 1,
visibility_appoint: 1,
visibility_appointor: [0],
} }
}).catch(({msg}) => { }).catch(({msg}) => {
$A.modalError(msg); $A.modalError(msg);

View File

@ -1,55 +1,60 @@
<template> <template>
<!--子任务--> <!--子任务-->
<li v-if="ready && taskDetail.parent_id > 0"> <li style="display: block;margin-bottom: 16px;" v-if="ready && taskDetail.parent_id > 0">
<div class="subtask-icon"> <div style="display: flex; margin-left: 6px;">
<TaskMenu <div class="subtask-icon">
:ref="`taskMenu_${taskDetail.id}`" <TaskMenu
:disabled="taskId === 0" :ref="`taskMenu_${taskDetail.id}`"
:task="taskDetail" :disabled="taskId === 0"
:load-status="taskDetail.loading === true" :task="taskDetail"
@on-update="getLogLists"/> :load-status="taskDetail.loading === true"
</div> @on-update="getLogLists"/>
<div v-if="taskDetail.flow_item_name" class="subtask-flow">
<span :class="taskDetail.flow_item_status" @click.stop="openMenu($event, taskDetail)">{{taskDetail.flow_item_name}}</span>
</div>
<div class="subtask-name">
<Input
v-model="taskDetail.name"
ref="name"
type="textarea"
:rows="1"
:autosize="{ minRows: 1, maxRows: 8 }"
:maxlength="255"
enterkeyhint="done"
@on-blur="updateBlur('name')"
@on-keydown="onNameKeydown"/>
</div>
<DatePicker
v-model="timeValue"
:open="timeOpen"
:options="timeOptions"
format="yyyy/MM/dd HH:mm"
type="datetimerange"
class="subtask-time"
placement="bottom-end"
@on-open-change="timeChange"
@on-clear="timeClear"
@on-ok="timeOk"
transfer>
<div v-if="!taskDetail.complete_at && taskDetail.end_at && taskDetail.end_at != mainEndAt" @click="openTime" :class="['time', taskDetail.today ? 'today' : '', taskDetail.overdue ? 'overdue' : '']">
{{expiresFormat(taskDetail.end_at)}}
</div> </div>
<Icon v-else class="clock" type="ios-clock-outline" @click="openTime" /> <div class="subtask-name">
</DatePicker> <Input
<UserSelect v-model="taskDetail.name"
class="subtask-avatar" ref="name"
v-model="ownerData.owner_userid" type="textarea"
:multiple-max="10" :rows="1"
:avatar-size="20" :autosize="{ minRows: 1, maxRows: 8 }"
:title="$L('修改负责人')" :maxlength="255"
:add-icon="false" enterkeyhint="done"
:project-id="taskDetail.project_id" @on-blur="updateBlur('name')"
:before-submit="onOwner"/> @on-keydown="onNameKeydown"/>
</div>
</div>
<div style="display: flex;justify-content: space-between;">
<div style="display: flex;">
<div style="margin-left: 28px;" class="item-label" slot="label">
<i class="taskfont">&#xe6e8;</i>
</div>
<DatePicker
v-model="timeValue"
:open="timeOpen"
:options="timeOptions"
format="yyyy/MM/dd HH:mm"
type="datetimerange"
class="subtask-time"
placement="bottom-end"
@on-open-change="timeChange"
@on-clear="timeClear"
@on-ok="timeOk"
transfer>
<div class="picker-time">
<div @click="openTime" class="time sub-time">{{taskDetail.end_at ? cutTime : '--'}}</div>
</div>
</DatePicker>
</div>
<UserSelect
class="subtask-avatar"
v-model="ownerData.owner_userid"
:multiple-max="10"
:avatar-size="20"
:title="$L('修改负责人')"
:add-icon="false"
:project-id="taskDetail.project_id"
:before-submit="onOwner"/>
</div>
</li> </li>
<!--主任务--> <!--主任务-->
<div <div
@ -200,6 +205,25 @@
:add-icon="false" :add-icon="false"
:before-submit="onAssist"/> :before-submit="onAssist"/>
</FormItem> </FormItem>
<FormItem>
<div class="item-label" slot="label">
<i class="taskfont">&#xe63f;</i>{{$L('可见性')}}
</div>
<Checkbox disabled v-model="visibility_principal" :true-value="1" :false-value="0">{{$L('任务负责人')}}</Checkbox>
<Checkbox disabled v-model="visibility_assist" :true-value="1" :false-value="0">{{$L('任务协助人')}}</Checkbox>
<RadioGroup v-model="taskDetail.is_all_visible">
<Radio :label=1>{{$L('所有人员')}}</Radio>
<Radio :label=0>{{$L('指定成员')}}</Radio>
</RadioGroup>
<UserSelect
class="item-content user"
v-show="!taskDetail.is_all_visible"
v-model="taskDetail.visibility_appointor"
:avatar-size="28"
:title="$L('选择指定人员')"
:project-id="taskDetail.project_id"/>
<Button size="small" type="primary" @click="updateVisible">{{$L('提交修改')}}</Button>
</FormItem>
<FormItem v-if="taskDetail.end_at || timeForce"> <FormItem v-if="taskDetail.end_at || timeForce">
<div class="item-label" slot="label"> <div class="item-label" slot="label">
<i class="taskfont">&#xe6e8;</i>{{$L('截止时间')}} <i class="taskfont">&#xe6e8;</i>{{$L('截止时间')}}
@ -285,11 +309,11 @@
</li> </li>
</ul> </ul>
</FormItem> </FormItem>
<FormItem v-if="subList.length > 0 || addsubForce"> <div v-if="subList.length > 0 || addsubForce">
<div class="item-label" slot="label"> <div class="item-label" slot="label">
<i class="taskfont">&#xe6f0;</i>{{$L('子任务')}} <i class="taskfont">&#xe6f0;</i>{{$L('子任务')}}
</div> </div>
<ul class="item-content subtask"> <ul style="overflow: hidden;" class="item-content subtask">
<TaskDetail <TaskDetail
v-for="(task, key) in subList" v-for="(task, key) in subList"
:ref="`subTask_${task.id}`" :ref="`subTask_${task.id}`"
@ -300,7 +324,7 @@
:can-update-blur="canUpdateBlur"/> :can-update-blur="canUpdateBlur"/>
</ul> </ul>
<ul :class="['item-content', subList.length === 0 ? 'nosub' : '']"> <ul :class="['item-content', subList.length === 0 ? 'nosub' : '']">
<li> <li style="margin-left: 8px;">
<Input <Input
v-if="addsubShow" v-if="addsubShow"
v-model="addsubName" v-model="addsubName"
@ -317,7 +341,7 @@
</div> </div>
</li> </li>
</ul> </ul>
</FormItem> </div>
</Form> </Form>
<div v-if="menuList.length > 0" class="add"> <div v-if="menuList.length > 0" class="add">
<EDropdown <EDropdown
@ -526,7 +550,12 @@ export default {
{key: 'month', label: '每月'}, {key: 'month', label: '每月'},
{key: 'year', label: '每年'}, {key: 'year', label: '每年'},
{key: 'custom', label: '自定义'}, {key: 'custom', label: '自定义'},
] ],
//
visibility_principal: 1,
visibility_assist: 1,
visibility_appoint: 1,
} }
}, },
@ -682,7 +711,7 @@ export default {
if (!$A.isArray(taskDetail.task_user)) { if (!$A.isArray(taskDetail.task_user)) {
return []; return [];
} }
return taskDetail.task_user.filter(({owner}) => owner !== 1).sort((a, b) => { return taskDetail.task_user.filter(({owner}) => owner === 0).sort((a, b) => {
return a.id - b.id; return a.id - b.id;
}); });
}, },
@ -933,6 +962,7 @@ export default {
break; break;
} }
// //
let dataJson = {task_id: this.taskDetail.id}; let dataJson = {task_id: this.taskDetail.id};
($A.isArray(action) ? action : [action]).forEach(key => { ($A.isArray(action) ? action : [action]).forEach(key => {
let newData = this.taskDetail[key]; let newData = this.taskDetail[key];
@ -1488,7 +1518,19 @@ export default {
this.$store.dispatch('downUrl', $A.apiUrl(`project/task/filedown?file_id=${file.id}`)) this.$store.dispatch('downUrl', $A.apiUrl(`project/task/filedown?file_id=${file.id}`))
} }
}); });
},
updateVisible() {
this.updateData(['is_all_visible', 'visibility_appointor'])
} }
} }
} }
</script> </script>
<style scoped>
::v-deep .ivu-poptip-rel {
display: flex;
}
::v-deep .sub-time {
color: #BBBBBB;
}
</style>

View File

@ -1819,7 +1819,9 @@ export default {
data: post, data: post,
method: 'post', method: 'post',
}).then(result => { }).then(result => {
dispatch("addTaskSuccess", result.data) if (result.data.is_visible === 1) {
dispatch("addTaskSuccess", result.data)
}
resolve(result) resolve(result)
}).catch(e => { }).catch(e => {
console.warn(e); console.warn(e);

View File

@ -19,7 +19,7 @@
&:before { &:before {
content: ""; content: "";
position: absolute; position: absolute;
left: 36px; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
height: 1px; height: 1px;
@ -149,9 +149,6 @@
} }
} }
.scroller { .scroller {
margin-left: 28px;
padding-left: 8px;
padding-right: 36px;
.title { .title {
margin-top: 18px; margin-top: 18px;
.ivu-input { .ivu-input {

View File

@ -147,7 +147,7 @@
</div></span> </div></span>
@elseif ($type === 'approve_submitter') @elseif ($type === 'approve_submitter')
<span class="open-approve-details" data-id="{{$data->id}}"><b> @if ($action === 'pass')您发起的「{{$data->proc_def_name}}」已通过 @else您发起的「{{$data->proc_def_name}}」被{{$data->nickname}}拒绝 @endif</b> <span class="open-approve-details" data-id="{{$data->id}}"><b> @if ($action === 'pass')您发起的「{{$data->proc_def_name}}」已通过 @else您发起的「{{$data->proc_def_name}}」被{{$data->nickname}}拒绝 @endif</b>
<div class="cause"><span>申请人:<span style="color:#84c56a">{{'@'}}{{$data->nickname}}</span> {{$data->department}}</span> <div class="cause"><span>申请人:<span style="color:#84c56a">{{'@'}}{{$data->start_nickname}}</span> {{$data->department}}</span>
<b>审批事由</b> <b>审批事由</b>
@if ($data->type) @if ($data->type)
<span>假期类型:{{$data->type}}</span> <span>假期类型:{{$data->type}}</span>