feat: 1.任务移动功能优化,2.导航样式优化

This commit is contained in:
weifashi 2023-12-06 20:08:25 +08:00
parent f5a068fffc
commit 4b7283dbe8
25 changed files with 555 additions and 148 deletions

View File

@ -2166,6 +2166,7 @@ class ProjectController extends AbstractController
* @apiName task__flow
*
* @apiParam {Number} task_id 任务ID
* @apiParam {Number} project_id 项目ID - 存在时只返回这个项目的
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
@ -2176,17 +2177,23 @@ class ProjectController extends AbstractController
User::auth();
//
$task_id = intval(Request::input('task_id'));
$project_id = intval(Request::input('project_id'));
//
$projectTask = ProjectTask::select(['id', 'project_id', 'complete_at', 'flow_item_id', 'flow_item_name'])->withTrashed()->find($task_id);
if (empty($projectTask)) {
return Base::retError('任务不存在', [ 'task_id' => $task_id ], -4002);
}
//
$projectFlowItem = $projectTask->flow_item_id ? ProjectFlowItem::with(['projectFlow'])->find($projectTask->flow_item_id) : null;
if ($projectFlowItem?->projectFlow) {
$projectFlow = $projectFlowItem->projectFlow;
} else {
$projectFlow = ProjectFlow::whereProjectId($projectTask->project_id)->orderByDesc('id')->first();
$projectFlowItem = null;
if($project_id){
$projectFlow = ProjectFlow::whereProjectId($project_id)->orderByDesc('id')->first();
}else{
$projectFlowItem = $projectTask->flow_item_id ? ProjectFlowItem::with(['projectFlow'])->find($projectTask->flow_item_id) : null;
if ($projectFlowItem?->projectFlow) {
$projectFlow = $projectFlowItem->projectFlow;
} else {
$projectFlow = ProjectFlow::whereProjectId($projectTask->project_id)->orderByDesc('id')->first();
}
}
if (empty($projectFlow)) {
return Base::retSuccess('success', [
@ -2250,6 +2257,9 @@ class ProjectController extends AbstractController
* @apiParam {Number} task_id 任务ID
* @apiParam {Number} project_id 项目ID
* @apiParam {Number} column_id 列ID
* @apiParam {Number} flow_item_id 工作流id
* @apiParam {Array} owner 负责人
* @apiParam {Array} assist 协助人
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
@ -2262,6 +2272,9 @@ class ProjectController extends AbstractController
$task_id = intval(Request::input('task_id'));
$project_id = intval(Request::input('project_id'));
$column_id = intval(Request::input('column_id'));
$flow_item_id = intval(Request::input('flow_item_id'));
$owner = Request::input('owner', []);
$assist = Request::input('assist', []);
//
$task = ProjectTask::userTask($task_id);
//
@ -2277,10 +2290,18 @@ class ProjectController extends AbstractController
if (empty($column)) {
return Base::retError('列表不存在');
}
if($flow_item_id){
$flowItem = projectFlowItem::whereProjectId($project->id)->whereId($flow_item_id)->first();
if (empty($flowItem)) {
return Base::retError('任务状态不存在');
}
}
//
$task->moveTask($project_id,$column_id);
$task->moveTask($project_id, $column_id, $flow_item_id, $owner, $assist);
//
return Base::retSuccess('移动成功', ['id' => $task_id]);
$task = ProjectTask::userTask($task_id);
//
return Base::retSuccess('移动成功', $task);
}
/**

View File

@ -1669,11 +1669,19 @@ class ProjectTask extends AbstractModel
* 移动任务
* @param int $project_id
* @param int $column_id
* @param int $flowItemId
* @param array $owner
* @param array $assist
* @return bool
*/
public function moveTask(int $projectId, int $columnId)
public function moveTask(int $projectId, int $columnId,int $flowItemId = 0,array $owner = [], array $assist = [])
{
AbstractModel::transaction(function () use($projectId, $columnId) {
AbstractModel::transaction(function () use($projectId, $columnId, $flowItemId, $owner, $assist) {
$newTaskUser = array_merge($owner, $assist);
//
$this->project_id = $projectId;
$this->column_id = $columnId;
$this->flow_item_id = $flowItemId;
// 任务内容
if($this->content){
$this->content->project_id = $projectId;
@ -1690,13 +1698,22 @@ class ProjectTask extends AbstractModel
$taskTag->save();
}
// 任务用户
$this->updateTask(['owner' => $owner]);
$this->updateTask(['assist' => $assist]);
foreach ($this->taskUser as $taskUser){
$taskUser->project_id = $projectId;
$taskUser->save();
if( in_array($taskUser->id, $newTaskUser) ){
$taskUser->project_id = $projectId;
$taskUser->save();
}
}
//
if($flowItemId){
$flowItem = projectFlowItem::whereProjectId($projectId)->whereId($flowItemId)->first();
$this->flow_item_name = $flowItem->status . "|" . $flowItem->name;
}else{
$this->flow_item_name = '';
}
//
$this->project_id = $projectId;
$this->column_id = $columnId;
$this->save();
//
$this->addLog("移动{任务}");

View File

@ -1425,3 +1425,9 @@ APP推送
转发给:
留言
多选
@我的
移动前
移动后
状态
协助人
未变更移动项

View File

@ -18720,5 +18720,71 @@
"de": "Kommt an die reihe.",
"fr": "DuoXuan",
"id": "DuoXuan"
},
{
"key": "@我的",
"zh": "",
"zh-CHT": "@我的",
"en": "@ My",
"ko": "@ 나의",
"ja": "@私のです",
"de": "Mich hat er mich nie verraten.",
"fr": "@ mon",
"id": "My"
},
{
"key": "移动前",
"zh": "",
"zh-CHT": "移動前",
"en": "Premove",
"ko": "이동 전",
"ja": "移動前です",
"de": "Vor der bewegung",
"fr": "Avant de déménager",
"id": "Sebelum pindah"
},
{
"key": "移动后",
"zh": "",
"zh-CHT": "移動後",
"en": "Post move",
"ko": "이동 후",
"ja": "移動後です",
"de": "Vorwärts und dann vorwärts.",
"fr": "Après le déménagement",
"id": "Setelah pindah"
},
{
"key": "状态",
"zh": "",
"zh-CHT": "狀態",
"en": "Status",
"ko": "상태",
"ja": "状態です",
"de": "Versetzen.",
"fr": "Létat",
"id": "Keadaan"
},
{
"key": "协助人",
"zh": "",
"zh-CHT": "協助人",
"en": "Assist",
"ko": "조력자",
"ja": "協力者です",
"de": "Vorm helfen.",
"fr": "Confraternité",
"id": "Kolaborasi"
},
{
"key": "未变更移动项",
"zh": "",
"zh-CHT": "未變更移動項",
"en": "The move item is not changed",
"ko": "이동 항목이 변경되지 않았습니다",
"ja": "移働項変更ありません",
"de": "Der zeiger wird unverändert gelassen",
"fr": "Article mobile non modifié",
"id": "Tidak mengubah item mobile"
}
]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
if(typeof window.LANGUAGE_DATA==="undefined")window.LANGUAGE_DATA={};window.LANGUAGE_DATA["zh"]=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""]
if(typeof window.LANGUAGE_DATA==="undefined")window.LANGUAGE_DATA={};window.LANGUAGE_DATA["zh"]=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""]

View File

@ -9,7 +9,7 @@
>
<div :class="['manage-box-title', visibleMenu ? 'menu-visible' : '']">
<div class="manage-box-avatar">
<UserAvatar :userid="userId" :size="48" tooltipDisabled/>
<UserAvatar :userid="userId" :size="42" tooltipDisabled/>
</div>
<Badge v-if="!!clientNewVersion" class="manage-box-top-report" dot/>
</div>
@ -135,24 +135,24 @@
<i class="taskfont" @click="settingRoute('version')">&#xe7fb;</i>
</Tooltip>
</li>
<li>
<li @click="onAddShow">
<Tooltip :content="$L('新建项目') + ' ('+mateName+'+B)'" placement="right" transfer :delay="300">
<i class="taskfont" @click="onAddShow">&#xe7b9;</i>
<i class="taskfont">&#xe7b9;</i>
</Tooltip>
</li>
<li>
<li @click="onAddMenu('task')">
<Tooltip :content="$L('新建任务') + ' ('+mateName+'+K)'" placement="right" transfer :delay="300">
<i class="taskfont" @click="onAddMenu('task')">&#xe7b5;</i>
<i class="taskfont">&#xe7b5;</i>
</Tooltip>
</li>
<li>
<li @click="onAddMenu('createMeeting')">
<Tooltip :content="$L('新会议') + ' ('+mateName+'+J)'" placement="right" transfer :delay="300">
<i class="taskfont" @click="onAddMenu('createMeeting')">&#xe7c1;</i>
<i class="taskfont">&#xe7c1;</i>
</Tooltip>
</li>
<li>
<li @click="onAddMenu('joinMeeting')">
<Tooltip :content="$L('加入会议')" placement="right" transfer :delay="300">
<i class="taskfont" @click="onAddMenu('joinMeeting')">&#xe794;</i>
<i class="taskfont">&#xe794;</i>
</Tooltip>
</li>
</ul>

View File

@ -235,11 +235,11 @@
<Scrollbar v-else-if="tabTypeActive === 'table'" class="project-table" enable-x>
<div class="project-table-head">
<Row class="task-row">
<Col span="12"># {{$L('任务名称')}}</Col>
<Col span="3">{{$L('列表')}}</Col>
<Col span="12"><span class="head-title"># {{$L('任务名称')}}</span></Col>
<Col span="3"><span class="head-title">{{$L('列表')}}</span></Col>
<Col span="3">
<div class="sort" @click="onSort('level')">
{{$L('优先级')}}
<span class="head-title">{{$L('优先级')}}</span>
<div class="task-sort">
<Icon :class="{on:sortField=='level' && sortType=='asc'}" type="md-arrow-dropup" />
<Icon :class="{on:sortField=='level' && sortType=='desc'}" type="md-arrow-dropdown" />
@ -249,7 +249,7 @@
<Col span="3">{{$L('负责人')}}</Col>
<Col span="3">
<div class="sort" @click="onSort('end_at')">
{{$L('到期时间')}}
<span class="head-title">{{$L('到期时间')}}</span>
<div class="task-sort">
<Icon :class="{on:sortField=='end_at' && sortType=='asc'}" type="md-arrow-dropup" />
<Icon :class="{on:sortField=='end_at' && sortType=='desc'}" type="md-arrow-dropdown" />

View File

@ -230,10 +230,33 @@
</EDropdown>
</div>
<div class="item-content user">
<span @click="showCisibleDropdown" v-if="taskDetail.visibility == 1" class="visibility-text">{{$L('项目人员可见')}}</span>
<span @click="showCisibleDropdown" v-else-if="taskDetail.visibility == 2" class="visibility-text">{{$L('任务人员可见')}}</span>
<UserSelect
v-else
<EDropdown v-if="taskDetail.visibility == 1 || taskDetail.visibility == 2" trigger="click" placement="bottom" @command="dropVisible">
<span class="visibility-text">{{ taskDetail.visibility == 1 ? $L('项目人员可见') : $L('任务人员可见') }}</span>
<EDropdownMenu slot="dropdown">
<EDropdownItem :command="1">
<div class="task-menu-icon" >
<Icon v-if="taskDetail.visibility == 1" class="completed" :type="'md-checkmark-circle'"/>
<Icon v-else class="uncomplete" :type="'md-radio-button-off'"/>
{{$L('项目人员')}}
</div>
</EDropdownItem>
<EDropdownItem :command="2">
<div class="task-menu-icon" >
<Icon v-if="taskDetail.visibility == 2" class="completed" :type="'md-checkmark-circle'"/>
<Icon v-else class="uncomplete" :type="'md-radio-button-off'"/>
{{$L('任务人员')}}
</div>
</EDropdownItem>
<EDropdownItem :command="3">
<div class="task-menu-icon" >
<Icon v-if="taskDetail.visibility == 3" class="completed" :type="'md-checkmark-circle'"/>
<Icon v-else class="uncomplete" :type="'md-radio-button-off'"/>
{{$L('指定成员')}}
</div>
</EDropdownItem>
</EDropdownMenu>
</EDropdown>
<UserSelect v-else
ref="visibleUserSelectRef"
v-model="taskDetail.visibility_appointor"
:avatar-size="28"

View File

@ -28,6 +28,10 @@ export default {
type: Boolean,
default: true
},
operationShow: {
type: Boolean,
default: true
},
updateBefore: {
type: Boolean,
default: false
@ -48,6 +52,10 @@ export default {
type: String,
default: 'md-checkmark-circle'
},
projectId:{
type: Number,
default: 0
}
},
computed: {
...mapState(['loads', 'taskFlows']),
@ -67,9 +75,11 @@ export default {
task: this.task,
loadStatus: this.loadStatus,
colorShow: this.colorShow,
operationShow: this.operationShow,
updateBefore: this.updateBefore,
disabled: this.disabled,
size: this.size,
projectId: this.projectId,
onUpdate: data => {
this.$emit("on-update", data)
}

View File

@ -1,14 +1,91 @@
<template>
<div class="task-add">
<div class="task-move">
<Cascader
v-model="cascader"
:data="cascaderData"
:clearable="false"
:placeholder="$L('请选择项目')"
:load-data="cascaderLoadData"
@on-input-change="cascaderInputChange"
@on-visible-change="cascaderShow=!cascaderShow"
filterable/>
v-model="cascader"
:data="cascaderData"
:clearable="false"
:placeholder="$L('请选择项目')"
:load-data="cascaderLoadData"
@on-visible-change="cascaderShow=!cascaderShow"
filterable/>
<div class="task-move-content">
<div class="task-move-content-old">
<div class="task-move-title">{{ $L('移动前') }}</div>
<div class="task-move-row">
<span class="label">{{$L('状态')}}:</span>
<div v-if="task.flow_item_name" class="flow">
<span :class="task.flow_item_status">{{task.flow_item_name}}</span>
</div>
</div>
<div class="task-move-row" :class="{'not-flex': windowPortrait}">
<span class="label">{{$L('负责人')}}:</span>
<UserSelect class="item-content user"
v-model="ownerUserids"
:avatar-size="28"
:project-id="task.project_id"
:add-icon="false"
disable
/>
</div>
<div class="task-move-row" :class="{'not-flex': windowPortrait}">
<span class="label">{{$L('协助人')}}:</span>
<UserSelect class="item-content user"
v-model="assistUserids"
:avatar-size="28"
:project-id="task.project_id"
:add-icon="false"
disable
/>
</div>
</div>
<div class="task-move-content-new">
<div class="task-move-title">{{ $L('移动后') }}</div>
<div class="task-move-row">
<span class="label"> {{$L('状态:')}} </span>
<TaskMenu
:ref="`taskMenu_${task.id}`"
:task="tasks"
:project-id="cascader[0]"
:color-show="false"
:operation-show="false"
:load-status="task.loading === true"
@on-update="onStatusUpdate"
/>
<div v-if="updateData.flow.flow_item_name" class="flow">
<span :class="updateData.flow.flow_item_status" @click.stop="openMenu($event, tasks)">{{updateData.flow.flow_item_name}}</span>
</div>
</div>
<div class="task-move-row" :class="{'not-flex': windowPortrait}">
<span class="label">{{$L('负责人:')}}</span>
<div>
<UserSelect
class="item-content user"
v-model="updateData.owner_userids"
:multiple-max="10"
:avatar-size="28"
:project-id="cascader[0]"
:add-icon="false"
/>
</div>
</div>
<div class="task-move-row" :class="{'not-flex': windowPortrait}">
<span class="label">{{$L('协助人:')}}</span>
<div>
<UserSelect
class="item-content user"
v-model="updateData.assist_userids"
:multiple-max="10"
:avatar-size="28"
:project-id="cascader[0]"
:add-icon="false"
/>
</div>
</div>
</div>
</div>
<div class="ivu-modal-footer">
<div class="adaption">
<Button type="default" @click="close">{{$L('取消')}}</Button>
@ -20,9 +97,15 @@
<script>
import {mapState} from "vuex";
import TaskMenu from "./TaskMenu";
import UserSelect from "../../../components/UserSelect.vue";
export default {
name: "TaskMove",
components: {
TaskMenu,
UserSelect,
},
props: {
value: {
type: Boolean,
@ -32,10 +115,10 @@ export default {
type: Object,
default: false
},
},
data() {
return {
tasks: {},
cascader: [],
cascaderShow: false,
cascaderData: [],
@ -44,19 +127,21 @@ export default {
cascaderAlready: [],
loadIng: 0,
beforeClose: [],
flowItemId: 0,
ownerUserids: [],
assistUserids: [],
updateData:{
flow: {},
owner_userids: [],
assist_userids: []
}
}
},
async mounted() {
this.initCascaderData();
},
beforeDestroy() {
this.beforeClose.some(func => {
typeof func === "function" && func()
})
this.beforeClose = [];
this.initData();
},
computed: {
@ -64,20 +149,63 @@ export default {
},
watch: {
task: {
handler: function (val) {
this.cascader = [val.project_id, val.column_id];
},
deep: true,
immediate: true
cascader(val){
this.tasks.flow_item_id = this.flowItemId;
if(val[0] != this.task.project_id){
this.updateData.flow.flow_item_id = 0;
this.updateData.flow.flow_item_name = '';
this.updateData.flow.flow_item_status = '';
}else{
this.updateData.flow.flow_item_id = this.flowItemId;
this.updateData.flow.flow_item_name = this.task.flow_item_name;
this.updateData.flow.flow_item_status = this.task.flow_item_status;
}
//
const projectUserIds = this.cacheProjects.find(project => project.id == val[0])?.project_user?.map(h=>{
return h.userid
}) || [];
//
this.updateData.owner_userids = (this.task.task_user || []).filter(h=>{
return h.owner && projectUserIds.indexOf(h.userid) !== -1
}).sort((a, b) => {
return a.id - b.id;
}).map(h=>{
return h.userid
});
//
this.updateData.assist_userids = (this.task.task_user || []).filter(h=>{
return !h.owner && projectUserIds.indexOf(h.userid) !== -1
}).sort((a, b) => {
return a.id - b.id;
}).map(h=>{
return h.userid
});
},
},
methods: {
/**
* 初始化级联数据
* 初始化数据
*/
initCascaderData() {
initData() {
this.flowItemId = this.task.flow_item_id;
this.cascader = [this.task.project_id, this.task.column_id];
this.ownerUserids = (this.task.task_user || []).filter(h=>{
return h.owner
}).sort((a, b) => {
return a.id - b.id;
}).map(h=>{
return h.userid
});
this.assistUserids = (this.task.task_user || []).filter(h=>{
return !h.owner
}).sort((a, b) => {
return a.id - b.id;
}).map(h=>{
return h.userid
});
this.tasks = JSON.parse(JSON.stringify(this.task));
//
const data = $A.cloneJSON(this.cacheProjects).sort((a, b) => {
if (a.top_at || b.top_at) {
return $A.Date(b.top_at) - $A.Date(a.top_at);
@ -120,32 +248,15 @@ export default {
});
},
cascaderInputChange(key) {
this.cascaderValue = key || "";
//
if (this.cascaderAlready[this.cascaderValue] === true) {
async onConfirm() {
if( this.task.project_id == this.cascader[0] && this.task.column_id == this.cascader[1]){
$A.messageError("未变更移动项");
return;
}
if( !this.updateData.flow.flow_item_id ){
$A.messageError("请选择移动后状态");
return;
}
this.cascaderAlready[this.cascaderValue] = true;
//
setTimeout(() => {
this.cascaderLoading++;
}, 1000)
this.$store.dispatch("getProjects", {
keys: {
name: this.cascaderValue,
},
getcolumn: 'yes'
}).then(() => {
this.cascaderLoading--;
this.initCascaderData();
}).catch(() => {
this.cascaderLoading--;
});
},
async onConfirm() {
this.loadIng++;
this.$store.dispatch("call", {
url: "project/task/move",
@ -153,14 +264,13 @@ export default {
task_id: this.task.id,
project_id: this.cascader[0],
column_id: this.cascader[1],
flow_item_id: this.updateData.flow.flow_item_id,
owner: this.updateData.owner_userids,
assist: this.updateData.assist_userids,
}
}).then(({msg}) => {
}).then(({data,msg}) => {
this.loadIng--;
this.$store.dispatch("saveTask", {
id: this.task.id,
project_id: this.cascader[0],
column_id: this.cascader[1],
});
this.$store.dispatch("saveTask", data);
$A.messageSuccess(msg);
this.close()
}).catch(({msg}) => {
@ -172,6 +282,16 @@ export default {
close() {
this.$emit("input", !this.value)
},
openMenu(event, task) {
const el = this.$refs[`taskMenu_${task.id}`];
el && el.handleClick(event)
},
onStatusUpdate(val) {
this.tasks.flow_item_id = val.flow_item_id;
this.updateData.flow = val
}
}
}
</script>

View File

@ -42,21 +42,23 @@
</template>
<template v-if="task.parent_id === 0">
<EDropdownItem :divided="turns.length > 0" command="archived">
<div class="item">
<Icon type="ios-filing" />{{$L(task.archived_at ? '还原归档' : '归档')}}
</div>
</EDropdownItem>
<EDropdownItem command="move">
<div class="item">
<Icon type="md-move" />{{$L('移动')}}
</div>
</EDropdownItem>
<EDropdownItem command="remove">
<div class="item hover-del">
<Icon type="md-trash" />{{$L('删除')}}
</div>
</EDropdownItem>
<template v-if="operationShow">
<EDropdownItem :divided="turns.length > 0" command="archived">
<div class="item">
<Icon type="ios-filing" />{{$L(task.archived_at ? '还原归档' : '归档')}}
</div>
</EDropdownItem>
<EDropdownItem command="move">
<div class="item">
<Icon type="md-move" />{{$L('移动')}}
</div>
</EDropdownItem>
<EDropdownItem command="remove">
<div class="item hover-del">
<Icon type="md-trash" />{{$L('删除')}}
</div>
</EDropdownItem>
</template>
<template v-if="colorShow">
<EDropdownItem v-for="(c, k) in taskColorList" :key="'c_' + k" :divided="k==0" :command="c">
<div class="item">
@ -65,7 +67,7 @@
</EDropdownItem>
</template>
</template>
<EDropdownItem v-else command="remove" :divided="turns.length > 0">
<EDropdownItem v-else-if="operationShow" command="remove" :divided="turns.length > 0">
<div class="item">
<Icon type="md-trash" />{{$L('删除')}}
</div>
@ -104,9 +106,11 @@ export default {
task: {},
loadStatus: false,
colorShow: true,
operationShow: true,
updateBefore: false,
disabled: false,
size: 'small',
projectId: 0,
onUpdate: null,
element: null,
@ -164,15 +168,17 @@ export default {
this.task = data.task;
this.loadStatus = typeof data.loadStatus === "undefined" ? false : data.loadStatus;
this.colorShow = typeof data.colorShow === "undefined" ? true : data.colorShow;
this.operationShow = typeof data.operationShow === "undefined" ? true : data.operationShow;
this.updateBefore = typeof data.updateBefore === "undefined" ? false : data.updateBefore;
this.disabled = typeof data.disabled === "undefined" ? false : data.disabled;
this.size = typeof data.size === "undefined" ? "small" : data.size;
this.projectId = typeof data.projectId === "undefined" ? 0 : data.projectId;
this.onUpdate = typeof data.onUpdate === "function" ? data.onUpdate : null;
//
this.$refs.icon.focus();
this.updatePopper();
this.show();
this.$store.dispatch("getTaskFlow", this.task.id).finally(this.updatePopper)
this.$store.dispatch("getTaskFlow", {task_id: this.task.id, project_id: this.projectId}).finally(this.updatePopper)
this.setupEventListeners(data.event)
} else {
this.hide();
@ -223,7 +229,9 @@ export default {
}
}
this.updateTask({
flow_item_id
flow_item_id,
flow_item_status: updateFlow.status,
flow_item_name: updateFlow.name
}).then(() => {
if (isComplete) {
completeTemp(true)
@ -291,11 +299,19 @@ export default {
return;
}
//
Object.keys(updata).forEach(key => this.$set(this.task, key, updata[key]));
//
const updateData = Object.assign(updata, {
task_id: this.task.id,
});
if(!this.operationShow){
if (typeof this.onUpdate === "function") {
this.onUpdate(updateData)
}
reject()
return;
}
//
Object.keys(updata).forEach(key => this.$set(this.task, key, updata[key]));
//
this.$store.dispatch("taskUpdate", updateData).then(({data, msg}) => {
$A.messageSuccess(msg);
resolve()

View File

@ -1885,6 +1885,7 @@ export default {
}
return
}
state.taskArchiveView = task_id;
state.taskId = task_id;
if (task_id > 0) {
@ -1904,6 +1905,8 @@ export default {
}
});
});
}else{
state.taskOperation = {};
}
},
@ -2110,14 +2113,16 @@ export default {
* @param state
* @param dispatch
* @param task_id
* @param project_id
* @returns {Promise<unknown>}
*/
getTaskFlow({state, dispatch}, task_id) {
getTaskFlow({state, dispatch}, {task_id, project_id}) {
return new Promise(function (resolve, reject) {
dispatch("call", {
url: 'project/task/flow',
data: {
task_id: task_id
task_id: task_id,
project_id: project_id || 0
},
}).then(result => {
let task = state.cacheTasks.find(({id}) => id == task_id)

View File

@ -22,9 +22,11 @@
@import "task-menu";
@import "task-operation";
@import "task-priority";
@import "task-move";
@import "team-management";
@import "update-log";
@import "task-exist-tips";
@import "project-menu";
@import "calendar";
@import "home-calendar";
@import "home-calendar";

View File

@ -666,6 +666,9 @@
align-items: center;
cursor: pointer;
}
.head-title{
white-space: nowrap;
}
.task-sort {
display: inline-block;
width: 14px;

View File

@ -0,0 +1,105 @@
.task-move {
.task-move-content{
display: flex;
gap: 10px;
margin-top: 16px;
>div{
flex: 1;
padding: 5px;
border-radius: 5px;
.task-move-title{
margin-bottom: 10px;
font-weight: bold;
}
.task-move-row{
padding: 5px 0;
display: flex;
line-height: 36px;
&.not-flex{
display: block;
}
.label{
width: 60px;
min-width: 60px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.task-menu-icon{
padding-right: 5px;
}
.flow {
cursor: pointer;
> span{
font-size: 12px;
height: 18px;
min-width: 20px;
line-height: 16px;
padding: 0 2px;
border-radius: 3px;
color: $primary-color;
border: 1px solid $primary-color;
display: inline-block;
vertical-align: top;
margin-top: 8px;
text-align: center;
&.start {
background-color: rgba($flow-status-start-color, 0.1);
border-color: rgba($flow-status-start-color, 0.1);
color: $flow-status-start-color;
}
&.progress {
background-color: rgba($flow-status-progress-color, 0.1);
border-color: rgba($flow-status-progress-color, 0.1);
color: $flow-status-progress-color;
}
&.test {
background-color: rgba($flow-status-test-color, 0.1);
border-color: rgba($flow-status-test-color, 0.1);
color: $flow-status-test-color;
}
&.end {
background-color: rgba($flow-status-end-color, 0.1);
border-color: rgba($flow-status-end-color, 0.1);
color: $flow-status-end-color;
}
}
}
}
&.task-move-content-old{
.task-move-row{
>div{
opacity: 0.5;
}
.common-user-select > ul > li, .flow{
cursor: initial;
}
}
}
}
}
.ivu-modal-footer {
padding: 26px 0 22px !important;
}
}
body.window-portrait {
.task-move {
.ivu-select-dropdown{
max-width: 100%;
overflow: auto;
.ivu-cascader-menu:last-child{
margin-right: 0px;
}
}
.task-move-row{
.label{
width: auto;
min-width: 50px;
}
}
}
}

View File

@ -38,7 +38,7 @@
width: 1px;
flex: 1;
padding-right: 30px;
height: 41px;
min-height: 41px;
padding-left: 2px;
}
.dashboard-search {

View File

@ -17,7 +17,7 @@
position: relative;
flex-grow: 0;
flex-shrink: 0;
width: 88px;
width: 78px;
height: 100%;
background: #F4F5F7;
display: flex;
@ -27,7 +27,7 @@
.scrollbar-container {
flex: 1;
width: 100%;
margin-top: 16px;
margin-top: 14px;
display: flex;
flex-direction: column;
}
@ -51,9 +51,9 @@
color: #999999;
cursor: pointer;
position: relative;
width: 64px;
width: 56px;
margin: 5px auto;
padding: 8px 4%;
padding: 5px 4%;
border-radius: 8px;
font-size: 12px;
> i {
@ -64,15 +64,13 @@
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-top: -2px;
}
.menu-badge {
transform: scale(0.9);
transform: scale(0.8);
position: absolute;
top: 0;
left: 35px;
}
&:first-child {
margin-top: 12px;
left: 30px;
}
&.active {
background-color: #ffffff;
@ -246,36 +244,51 @@
}
}
.manage-box-new-group {
width: 60%;
margin-top: 16px;
margin-bottom: 20px;
display: flex;
align-items: center;
text-align: center;
margin-bottom: 18px;
ul{
list-style-type: none;
width: 100%;
li{
margin-top: 12px;
color: #999999;
.taskfont{
font-size: 22px;
padding: 4px;
cursor: pointer;
border-radius: 4px;
&:hover{
background-color: #ffffff;
color: #8FCE78;
cursor: pointer;
width: 46px;
height: 46px;
border-radius: 6px;
.ivu-tooltip{
width: 100%;
height: 100%;
.ivu-tooltip-rel{
display: flex;
align-items: center;
justify-content: center;
height: 100%;
width: 100%;
}
}
.taskfont{
font-size: 20px;
border-radius: 4px;
}
&.client-download-update{
margin-bottom: 24px;
a{
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.taskfont{
font-size: 18px;
padding: 0 4px;
font-size: 14px;
background-color: #8FCE78;
color: #ffffff;
}
}
&:hover{
background-color: #ffffff;
color: #8FCE78;
}
}
}
.manage-box-new {
@ -329,8 +342,8 @@
display: flex;
align-items: center;
flex-shrink: 0;
padding: 6px 14px;
margin-top: 27px;
padding: 0 14px;
margin-top: 34px;
border-radius: 8px;
cursor: pointer;
transition: box-shadow 0.3s;
@ -339,8 +352,8 @@
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2);
}
.manage-box-avatar {
width: 48px;
height: 48px;
width: 42px;
height: 42px;
}
> span {
flex: 1;