初步完成工作流
This commit is contained in:
parent
1fe4e80f82
commit
b895eec69c
@ -170,19 +170,6 @@ class ProjectController extends AbstractController
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
"project_flow_item": [ // 工作流
|
|
||||||
{
|
|
||||||
"id": 9,
|
|
||||||
"project_id": 2,
|
|
||||||
"flow_id": 3,
|
|
||||||
"name": "待处理",
|
|
||||||
"status": "start",
|
|
||||||
"turns": [9,10,11,12],
|
|
||||||
"userids": [],
|
|
||||||
"sort": 0
|
|
||||||
}
|
|
||||||
],
|
|
||||||
|
|
||||||
"task_num": 9,
|
"task_num": 9,
|
||||||
"task_complete": 0,
|
"task_complete": 0,
|
||||||
"task_percent": 0,
|
"task_percent": 0,
|
||||||
@ -200,7 +187,6 @@ class ProjectController extends AbstractController
|
|||||||
$project = Project::userProject($project_id);
|
$project = Project::userProject($project_id);
|
||||||
$data = array_merge($project->toArray(), $project->getTaskStatistics($user->userid), [
|
$data = array_merge($project->toArray(), $project->getTaskStatistics($user->userid), [
|
||||||
'project_user' => $project->projectUser,
|
'project_user' => $project->projectUser,
|
||||||
'project_flow_item' => $project->projectFlowItem
|
|
||||||
]);
|
]);
|
||||||
//
|
//
|
||||||
return Base::retSuccess('success', $data);
|
return Base::retSuccess('success', $data);
|
||||||
@ -1216,6 +1202,7 @@ class ProjectController extends AbstractController
|
|||||||
* @apiParam {String} [p_name] 优先级相关(子任务不支持)
|
* @apiParam {String} [p_name] 优先级相关(子任务不支持)
|
||||||
* @apiParam {String} [p_color] 优先级相关(子任务不支持)
|
* @apiParam {String} [p_color] 优先级相关(子任务不支持)
|
||||||
*
|
*
|
||||||
|
* @apiParam {Number} [flow_item_id] 任务状态,工作流状态ID
|
||||||
* @apiParam {String|false} [complete_at] 完成时间(如:2020-01-01 00:00,false表示未完成)
|
* @apiParam {String|false} [complete_at] 完成时间(如:2020-01-01 00:00,false表示未完成)
|
||||||
*
|
*
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
@ -1442,26 +1429,73 @@ class ProjectController extends AbstractController
|
|||||||
//
|
//
|
||||||
$task_id = intval(Request::input('task_id'));
|
$task_id = intval(Request::input('task_id'));
|
||||||
//
|
//
|
||||||
$projectTask = ProjectTask::select(['id', 'flow_item_id', 'flow_item_name', 'project_id'])->find($task_id);
|
$projectTask = ProjectTask::select(['id', 'project_id', 'complete_at', 'flow_item_id', 'flow_item_name'])->find($task_id);
|
||||||
if (empty($projectTask)) {
|
if (empty($projectTask)) {
|
||||||
return Base::retError('任务不存在', [ 'task_id' => $task_id ], -4002);
|
return Base::retError('任务不存在', [ 'task_id' => $task_id ], -4002);
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
$projectFlowItem = [];
|
$projectFlowItem = $projectTask->flow_item_id ? ProjectFlowItem::with(['projectFlow'])->find($projectTask->flow_item_id) : null;
|
||||||
$turnBuilder = ProjectFlowItem::select(['id', 'name']);
|
if ($projectFlowItem?->projectFlow) {
|
||||||
if ($projectTask->flow_item_id) {
|
$projectFlow = $projectFlowItem->projectFlow;
|
||||||
$projectFlowItem = ProjectFlowItem::select(['id', 'name', 'turns'])->find($projectTask->flow_item_id);
|
} else {
|
||||||
|
$projectFlow = ProjectFlow::whereProjectId($projectTask->project_id)->first();
|
||||||
}
|
}
|
||||||
|
if (empty($projectFlow)) {
|
||||||
|
return Base::retSuccess('success', [
|
||||||
|
'task_id' => $projectTask->id,
|
||||||
|
'flow_item_id' => 0,
|
||||||
|
'flow_item_name' => '',
|
||||||
|
'turns' => [],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
$turns = ProjectFlowItem::select(['id', 'name', 'status', 'turns'])->whereFlowId($projectFlow->id)->orderBy('sort')->get();
|
||||||
if (empty($projectFlowItem)) {
|
if (empty($projectFlowItem)) {
|
||||||
$data = [
|
$data = [
|
||||||
'id' => 0,
|
'task_id' => $projectTask->id,
|
||||||
'name' => '',
|
'flow_item_id' => 0,
|
||||||
'turns' => $turnBuilder->whereProjectId($projectTask->project_id)->get()
|
'flow_item_name' => '',
|
||||||
|
'turns' => $turns,
|
||||||
];
|
];
|
||||||
|
$assign = null;
|
||||||
|
if ($projectTask->complete_at) {
|
||||||
|
// 赋一个结束状态
|
||||||
|
foreach ($turns as $turn) {
|
||||||
|
if ($turn->status == 'end' || preg_match("/complete|done|完成/i", $turn->name)) {
|
||||||
|
$assign = $turn;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (empty($data['flow_item_id'])) {
|
||||||
|
foreach ($turns as $turn) {
|
||||||
|
if ($turn->status == 'end') {
|
||||||
|
$assign = $turn;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 赋一个开始状态
|
||||||
|
foreach ($turns as $turn) {
|
||||||
|
if ($turn->status == 'start') {
|
||||||
|
$assign = $turn;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($assign) {
|
||||||
|
$data['flow_item_id'] = $assign->id;
|
||||||
|
$data['flow_item_name'] = $assign->name;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$data = $projectFlowItem->toArray();
|
$data = [
|
||||||
$data['turns'] = $turnBuilder->whereIn('id', $data['turns'])->get();
|
'task_id' => $projectTask->id,
|
||||||
|
'flow_item_id' => $projectFlowItem->id,
|
||||||
|
'flow_item_name' => $projectFlowItem->name,
|
||||||
|
'turns' => $turns,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
//
|
||||||
return Base::retSuccess('success', $data);
|
return Base::retSuccess('success', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,8 +26,6 @@ use Request;
|
|||||||
* @property-read int $owner_userid
|
* @property-read int $owner_userid
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectColumn[] $projectColumn
|
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectColumn[] $projectColumn
|
||||||
* @property-read int|null $project_column_count
|
* @property-read int|null $project_column_count
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectFlowItem[] $projectFlowItem
|
|
||||||
* @property-read int|null $project_flow_item_count
|
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectLog[] $projectLog
|
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectLog[] $projectLog
|
||||||
* @property-read int|null $project_log_count
|
* @property-read int|null $project_log_count
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectUser[] $projectUser
|
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectUser[] $projectUser
|
||||||
@ -101,14 +99,6 @@ class Project extends AbstractModel
|
|||||||
return $this->hasMany(ProjectUser::class, 'project_id', 'id')->orderBy('id');
|
return $this->hasMany(ProjectUser::class, 'project_id', 'id')->orderBy('id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
|
||||||
*/
|
|
||||||
public function projectFlowItem(): \Illuminate\Database\Eloquent\Relations\HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(projectFlowItem::class, 'project_id', 'id')->orderBy('sort');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询所有项目(与正常查询多返回owner字段)
|
* 查询所有项目(与正常查询多返回owner字段)
|
||||||
* @param self $query
|
* @param self $query
|
||||||
|
@ -17,6 +17,7 @@ use App\Module\Base;
|
|||||||
* @property int|null $sort 排序
|
* @property int|null $sort 排序
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
* @property \Illuminate\Support\Carbon|null $created_at
|
||||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||||
|
* @property-read \App\Models\ProjectFlow|null $projectFlow
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem newModelQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem newModelQuery()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem newQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem newQuery()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem query()
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem query()
|
||||||
@ -63,6 +64,14 @@ class ProjectFlowItem extends AbstractModel
|
|||||||
return Base::json2array($value);
|
return Base::json2array($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
||||||
|
*/
|
||||||
|
public function projectFlow(): \Illuminate\Database\Eloquent\Relations\HasOne
|
||||||
|
{
|
||||||
|
return $this->hasOne(ProjectFlow::class, 'id', 'flow_id');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool|null
|
* @return bool|null
|
||||||
*/
|
*/
|
||||||
|
@ -473,6 +473,45 @@ class ProjectTask extends AbstractModel
|
|||||||
public function updateTask($data, &$updateProject = false, &$updateContent = false, &$updateSubTask = false)
|
public function updateTask($data, &$updateProject = false, &$updateContent = false, &$updateSubTask = false)
|
||||||
{
|
{
|
||||||
AbstractModel::transaction(function () use ($data, &$updateProject, &$updateContent, &$updateSubTask) {
|
AbstractModel::transaction(function () use ($data, &$updateProject, &$updateContent, &$updateSubTask) {
|
||||||
|
// 工作流
|
||||||
|
if (Arr::exists($data, 'flow_item_id')) {
|
||||||
|
if ($this->flow_item_id == $data['flow_item_id']) {
|
||||||
|
throw new ApiException('任务状态未发生改变');
|
||||||
|
}
|
||||||
|
$currentFlowItem = null;
|
||||||
|
$newFlowItem = ProjectFlowItem::whereProjectId($this->project_id)->find(intval($data['flow_item_id']));
|
||||||
|
if (empty($newFlowItem) || empty($newFlowItem->projectFlow)) {
|
||||||
|
throw new ApiException('任务状态不存在');
|
||||||
|
}
|
||||||
|
if ($this->flow_item_id) {
|
||||||
|
// 判断符合流转
|
||||||
|
$currentFlowItem = ProjectFlowItem::find($this->flow_item_id);
|
||||||
|
if ($currentFlowItem && !in_array($currentFlowItem->id, $newFlowItem->turns)) {
|
||||||
|
throw new ApiException("当前状态[{$currentFlowItem->name}]不可流转到[{$newFlowItem->name}]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($newFlowItem->status == 'end') {
|
||||||
|
// 判断自动完成
|
||||||
|
if (!$this->complete_at) {
|
||||||
|
$data['complete_at'] = date("Y-m-d H:i");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 判断自动打开
|
||||||
|
if ($this->complete_at) {
|
||||||
|
$data['complete_at'] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($newFlowItem->userids) {
|
||||||
|
// 判断自动添加负责人
|
||||||
|
if (!Arr::exists($data, 'owner')) {
|
||||||
|
$data['owner'] = $this->taskUser->pluck('userid')->toArray();
|
||||||
|
}
|
||||||
|
$data['owner'] = array_values(array_unique(array_merge($data['owner'], $newFlowItem->userids)));
|
||||||
|
}
|
||||||
|
$this->flow_item_id = $newFlowItem->id;
|
||||||
|
$this->flow_item_name = $newFlowItem->status . "|" . $newFlowItem->name;
|
||||||
|
$this->addLog("修改{任务}状态:{$currentFlowItem?->name} => {$newFlowItem->name}");
|
||||||
|
}
|
||||||
// 状态
|
// 状态
|
||||||
if (Arr::exists($data, 'complete_at')) {
|
if (Arr::exists($data, 'complete_at')) {
|
||||||
if (Base::isDate($data['complete_at'])) {
|
if (Base::isDate($data['complete_at'])) {
|
||||||
|
@ -151,7 +151,7 @@
|
|||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
:styles="{
|
:styles="{
|
||||||
width: '90%',
|
width: '90%',
|
||||||
maxWidth: taskData.dialog_id ? '1200px' : '640px'
|
maxWidth: taskData.dialog_id ? '1200px' : '700px'
|
||||||
}"
|
}"
|
||||||
@on-visible-change="taskVisibleChange"
|
@on-visible-change="taskVisibleChange"
|
||||||
footer-hide>
|
footer-hide>
|
||||||
|
@ -125,6 +125,9 @@ export default {
|
|||||||
if (data.sub_top === true) {
|
if (data.sub_top === true) {
|
||||||
task.title = `[${this.$L('子任务')}] ${task.title}`
|
task.title = `[${this.$L('子任务')}] ${task.title}`
|
||||||
}
|
}
|
||||||
|
if (data.flow_item_name) {
|
||||||
|
task.title = `[${data.flow_item_name}] ${task.title}`
|
||||||
|
}
|
||||||
if (data.overdue) {
|
if (data.overdue) {
|
||||||
task.title = `[${this.$L('超期')}] ${task.title}`
|
task.title = `[${this.$L('超期')}] ${task.title}`
|
||||||
task.color = "#f56c6c"
|
task.color = "#f56c6c"
|
||||||
|
@ -151,9 +151,14 @@
|
|||||||
:style="item.color ? {backgroundColor: item.color} : {}"
|
:style="item.color ? {backgroundColor: item.color} : {}"
|
||||||
@click="openTask(item)">
|
@click="openTask(item)">
|
||||||
<div :class="['task-head', item.desc ? 'has-desc' : '']">
|
<div :class="['task-head', item.desc ? 'has-desc' : '']">
|
||||||
<div class="task-title"><pre>{{item.name}}</pre></div>
|
<div class="task-title">
|
||||||
|
<!--工作流状态-->
|
||||||
|
<span v-if="item.flow_item_name" :class="item.flow_item_status" @click.stop="openMenu(item)">{{item.flow_item_name}}</span>
|
||||||
|
<!--任务描述-->
|
||||||
|
<pre>{{item.name}}</pre>
|
||||||
|
</div>
|
||||||
<div class="task-menu" @click.stop="">
|
<div class="task-menu" @click.stop="">
|
||||||
<TaskMenu :task="item" icon="ios-more"/>
|
<TaskMenu :ref="`taskMenu_${item.id}`" :task="item" icon="ios-more"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="item.desc" class="task-desc"><pre v-html="item.desc"></pre></div>
|
<div v-if="item.desc" class="task-desc"><pre v-html="item.desc"></pre></div>
|
||||||
@ -1108,6 +1113,13 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
openMenu(task) {
|
||||||
|
const el = this.$refs[`taskMenu_${task.id}`];
|
||||||
|
if (el) {
|
||||||
|
el[0].show()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
taskIsHidden(task) {
|
taskIsHidden(task) {
|
||||||
const {name, desc, complete_at} = task;
|
const {name, desc, complete_at} = task;
|
||||||
const {searchText} = this;
|
const {searchText} = this;
|
||||||
|
@ -2,7 +2,10 @@
|
|||||||
<!--子任务-->
|
<!--子任务-->
|
||||||
<li v-if="ready && taskDetail.parent_id > 0">
|
<li v-if="ready && taskDetail.parent_id > 0">
|
||||||
<div class="subtask-icon">
|
<div class="subtask-icon">
|
||||||
<TaskMenu :task="taskDetail" :load-status="taskDetail.loading === true"/>
|
<TaskMenu :ref="`taskMenu_${taskDetail.id}`" :task="taskDetail" :load-status="taskDetail.loading === true"/>
|
||||||
|
</div>
|
||||||
|
<div v-if="taskDetail.flow_item_name" class="subtask-flow">
|
||||||
|
<span :class="taskDetail.flow_item_status" @click.stop="openMenu(taskDetail)">{{taskDetail.flow_item_name}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="subtask-name">
|
<div class="subtask-name">
|
||||||
<Input
|
<Input
|
||||||
@ -61,7 +64,10 @@
|
|||||||
<div v-else-if="ready" v-show="taskDetail.id > 0" :class="{'task-detail':true, 'open-dialog': hasOpenDialog, 'completed': taskDetail.complete_at}">
|
<div v-else-if="ready" v-show="taskDetail.id > 0" :class="{'task-detail':true, 'open-dialog': hasOpenDialog, 'completed': taskDetail.complete_at}">
|
||||||
<div class="task-info">
|
<div class="task-info">
|
||||||
<div class="head">
|
<div class="head">
|
||||||
<TaskMenu :task="taskDetail" class="icon" size="medium" :color-show="false" quick-completed/>
|
<TaskMenu :ref="`taskMenu_${taskDetail.id}`" :task="taskDetail" class="icon" size="medium" :color-show="false"/>
|
||||||
|
<div v-if="taskDetail.flow_item_name" class="flow">
|
||||||
|
<span :class="taskDetail.flow_item_status" @click.stop="openMenu(taskDetail)">{{taskDetail.flow_item_name}}</span>
|
||||||
|
</div>
|
||||||
<div class="nav">
|
<div class="nav">
|
||||||
<p v-if="projectName"><span>{{projectName}}</span></p>
|
<p v-if="projectName"><span>{{projectName}}</span></p>
|
||||||
<p v-if="columnName"><span>{{columnName}}</span></p>
|
<p v-if="columnName"><span>{{columnName}}</span></p>
|
||||||
@ -1096,6 +1102,13 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
openMenu(task) {
|
||||||
|
const el = this.$refs[`taskMenu_${task.id}`];
|
||||||
|
if (el) {
|
||||||
|
el.show()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
openNewWin() {
|
openNewWin() {
|
||||||
let config = {
|
let config = {
|
||||||
parent: null,
|
parent: null,
|
||||||
|
@ -4,10 +4,11 @@
|
|||||||
trigger="click"
|
trigger="click"
|
||||||
:size="size"
|
:size="size"
|
||||||
placement="bottom"
|
placement="bottom"
|
||||||
@command="dropTask">
|
@command="dropTask"
|
||||||
|
@visible-change="visibleChange">
|
||||||
<slot name="icon">
|
<slot name="icon">
|
||||||
<div class="task-menu-icon">
|
<div class="task-menu-icon">
|
||||||
<div v-if="loadIng" class="loading"><Loading /></div>
|
<div v-if="loadIng" class="loading"><Loading/></div>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<Icon v-if="task.complete_at" class="completed" :type="completedIcon" />
|
<Icon v-if="task.complete_at" class="completed" :type="completedIcon" />
|
||||||
<Icon v-else :type="icon" class="uncomplete"/>
|
<Icon v-else :type="icon" class="uncomplete"/>
|
||||||
@ -15,33 +16,61 @@
|
|||||||
</div>
|
</div>
|
||||||
</slot>
|
</slot>
|
||||||
<EDropdownMenu slot="dropdown" class="task-menu-more-dropdown">
|
<EDropdownMenu slot="dropdown" class="task-menu-more-dropdown">
|
||||||
<EDropdownItem v-if="task.complete_at" command="uncomplete">
|
<li class="task-menu-more-warp" :class="size">
|
||||||
<div class="item red">
|
<ul>
|
||||||
<Icon type="md-checkmark-circle-outline" />{{$L('标记未完成')}}
|
<EDropdownItem v-if="!flow" class="load-flow" disabled>
|
||||||
</div>
|
<div class="load-flow-warp">
|
||||||
</EDropdownItem>
|
<Loading/>
|
||||||
<EDropdownItem v-else command="complete">
|
</div>
|
||||||
<div class="item">
|
</EDropdownItem>
|
||||||
<Icon type="md-radio-button-off" />{{$L('完成')}}
|
<template v-else-if="turns.length > 0">
|
||||||
</div>
|
<EDropdownItem v-for="item in turns" :key="item.id" :command="`turn::${item.id}`">
|
||||||
</EDropdownItem>
|
<div class="item flow">
|
||||||
<EDropdownItem v-if="task.parent_id === 0" command="archived">
|
<Icon v-if="item.id == task.flow_item_id && flow.auto_assign !== true" class="check" type="md-checkmark-circle-outline" />
|
||||||
<div class="item">
|
<Icon v-else type="md-radio-button-off" />
|
||||||
<Icon type="ios-filing" />{{$L('归档')}}
|
<div class="flow-name" :class="item.status">{{item.name}}</div>
|
||||||
</div>
|
</div>
|
||||||
</EDropdownItem>
|
</EDropdownItem>
|
||||||
<EDropdownItem command="remove">
|
</template>
|
||||||
<div class="item hover-del">
|
<template v-else>
|
||||||
<Icon type="md-trash" />{{$L('删除')}}
|
<EDropdownItem v-if="task.complete_at" command="uncomplete">
|
||||||
</div>
|
<div class="item red">
|
||||||
</EDropdownItem>
|
<Icon type="md-checkmark-circle-outline" />{{$L('标记未完成')}}
|
||||||
<template v-if="task.parent_id === 0 && colorShow">
|
</div>
|
||||||
<EDropdownItem v-for="(c, k) in $store.state.taskColorList" :key="k" :divided="k==0" :command="c">
|
</EDropdownItem>
|
||||||
<div class="item">
|
<EDropdownItem v-else command="complete">
|
||||||
<i class="taskfont" :style="{color:c.color||'#f9f9f9'}" v-html="c.color == task.color ? '' : ''"></i>{{$L(c.name)}}
|
<div class="item">
|
||||||
</div>
|
<Icon type="md-radio-button-off" />{{$L('完成')}}
|
||||||
</EDropdownItem>
|
</div>
|
||||||
</template>
|
</EDropdownItem>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-if="task.parent_id === 0">
|
||||||
|
<EDropdownItem :divided="turns.length > 0" command="archived">
|
||||||
|
<div class="item">
|
||||||
|
<Icon type="ios-filing" />{{$L('归档')}}
|
||||||
|
</div>
|
||||||
|
</EDropdownItem>
|
||||||
|
<EDropdownItem command="remove">
|
||||||
|
<div class="item hover-del">
|
||||||
|
<Icon type="md-trash" />{{$L('删除')}}
|
||||||
|
</div>
|
||||||
|
</EDropdownItem>
|
||||||
|
<template v-if="colorShow">
|
||||||
|
<EDropdownItem v-for="(c, k) in taskColorList" :key="k" :divided="k==0" :command="c">
|
||||||
|
<div class="item">
|
||||||
|
<i class="taskfont" :style="{color:c.color||'#f9f9f9'}" v-html="c.color == task.color ? '' : ''"></i>{{$L(c.name)}}
|
||||||
|
</div>
|
||||||
|
</EDropdownItem>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
<EDropdownItem v-else command="remove" :divided="turns.length > 0">
|
||||||
|
<div class="item">
|
||||||
|
<Icon type="md-trash" />{{$L('删除')}}
|
||||||
|
</div>
|
||||||
|
</EDropdownItem>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
</EDropdownMenu>
|
</EDropdownMenu>
|
||||||
</EDropdown>
|
</EDropdown>
|
||||||
</template>
|
</template>
|
||||||
@ -66,10 +95,6 @@ export default {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
quickCompleted: { // 如果没有任务流是快速完成
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
size: {
|
size: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'small'
|
default: 'small'
|
||||||
@ -89,7 +114,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['taskLoading']),
|
...mapState(['taskColorList', 'taskLoading', 'taskFlows', 'taskFlowItems']),
|
||||||
|
|
||||||
loadIng() {
|
loadIng() {
|
||||||
if (this.loadStatus) {
|
if (this.loadStatus) {
|
||||||
@ -97,7 +122,22 @@ export default {
|
|||||||
}
|
}
|
||||||
const load = this.taskLoading.find(({id}) => id == this.task.id);
|
const load = this.taskLoading.find(({id}) => id == this.task.id);
|
||||||
return load && load.num > 0
|
return load && load.num > 0
|
||||||
}
|
},
|
||||||
|
|
||||||
|
flow() {
|
||||||
|
return this.taskFlows.find(({task_id}) => task_id == this.task.id);
|
||||||
|
},
|
||||||
|
|
||||||
|
turns() {
|
||||||
|
if (!this.flow) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
let item = this.taskFlowItems.find(({id}) => id == this.flow.flow_item_id);
|
||||||
|
if (!item) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return this.taskFlowItems.filter(({id}) => item.turns.includes(id))
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
show() {
|
show() {
|
||||||
@ -118,13 +158,20 @@ export default {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if ($A.leftExists(command, 'turn::')) {
|
||||||
|
// 修改工作流状态
|
||||||
|
let flow_item_id = $A.leftDelete(command, 'turn::');
|
||||||
|
if (flow_item_id == this.task.flow_item_id) return;
|
||||||
|
this.updateTask({
|
||||||
|
flow_item_id
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case 'complete':
|
case 'complete':
|
||||||
if (this.task.complete_at) return;
|
if (this.task.complete_at) return;
|
||||||
this.updateTask({
|
this.updateTask({
|
||||||
complete_at: $A.formatDate("Y-m-d H:i:s")
|
complete_at: $A.formatDate("Y-m-d H:i:s")
|
||||||
}).then(() => {
|
|
||||||
// 已完成
|
|
||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -132,8 +179,6 @@ export default {
|
|||||||
if (!this.task.complete_at) return;
|
if (!this.task.complete_at) return;
|
||||||
this.updateTask({
|
this.updateTask({
|
||||||
complete_at: false
|
complete_at: false
|
||||||
}).then(() => {
|
|
||||||
// 已未完成
|
|
||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -144,6 +189,12 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
visibleChange(visible) {
|
||||||
|
if (visible) {
|
||||||
|
this.$store.dispatch("getTaskFlow", this.task.id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
updateTask(updata) {
|
updateTask(updata) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (this.loadIng) {
|
if (this.loadIng) {
|
||||||
|
@ -11,8 +11,13 @@
|
|||||||
@click="getSublist(item)"/>
|
@click="getSublist(item)"/>
|
||||||
<TaskMenu :ref="`taskMenu_${item.id}`" :task="item"/>
|
<TaskMenu :ref="`taskMenu_${item.id}`" :task="item"/>
|
||||||
<div class="item-title" @click="openTask(item)">
|
<div class="item-title" @click="openTask(item)">
|
||||||
|
<!--工作流状态-->
|
||||||
|
<span v-if="item.flow_item_name" :class="item.flow_item_status" @click.stop="openMenu(item)">{{item.flow_item_name}}</span>
|
||||||
|
<!--是否子任务-->
|
||||||
<span v-if="item.sub_top === true">{{$L('子任务')}}</span>
|
<span v-if="item.sub_top === true">{{$L('子任务')}}</span>
|
||||||
|
<!--有多少个子任务-->
|
||||||
<span v-if="item.sub_my && item.sub_my.length > 0">+{{item.sub_my.length}}</span>
|
<span v-if="item.sub_my && item.sub_my.length > 0">+{{item.sub_my.length}}</span>
|
||||||
|
<!--任务描述-->
|
||||||
{{item.name}}
|
{{item.name}}
|
||||||
</div>
|
</div>
|
||||||
<div class="item-icons" @click="openTask(item)">
|
<div class="item-icons" @click="openTask(item)">
|
||||||
@ -240,6 +245,13 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
openMenu(task) {
|
||||||
|
const el = this.$refs[`taskMenu_${task.id}`];
|
||||||
|
if (el) {
|
||||||
|
el[0].show()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
ownerUser(list) {
|
ownerUser(list) {
|
||||||
return list.filter(({owner}) => owner == 1).sort((a, b) => {
|
return list.filter(({owner}) => owner == 1).sort((a, b) => {
|
||||||
return a.id - b.id;
|
return a.id - b.id;
|
||||||
|
@ -40,14 +40,19 @@
|
|||||||
v-if="item.p_name"
|
v-if="item.p_name"
|
||||||
class="priority-color"
|
class="priority-color"
|
||||||
:style="{backgroundColor:item.p_color}"></em>
|
:style="{backgroundColor:item.p_color}"></em>
|
||||||
<TaskMenu :task="item">
|
<TaskMenu :ref="`taskMenu_${item.id}`" :task="item">
|
||||||
<div slot="icon" class="drop-icon" @click.stop="">
|
<div slot="icon" class="drop-icon" @click.stop="">
|
||||||
<i class="taskfont" v-html="item.complete_at ? '' : ''"></i>
|
<i class="taskfont" v-html="item.complete_at ? '' : ''"></i>
|
||||||
</div>
|
</div>
|
||||||
</TaskMenu>
|
</TaskMenu>
|
||||||
<div class="item-title">
|
<div class="item-title">
|
||||||
|
<!--工作流状态-->
|
||||||
|
<span v-if="item.flow_item_name" :class="item.flow_item_status" @click.stop="openMenu(item)">{{item.flow_item_name}}</span>
|
||||||
|
<!--是否子任务-->
|
||||||
<span v-if="item.sub_top === true">{{$L('子任务')}}</span>
|
<span v-if="item.sub_top === true">{{$L('子任务')}}</span>
|
||||||
|
<!--有多少个子任务-->
|
||||||
<span v-if="item.sub_my && item.sub_my.length > 0">+{{item.sub_my.length}}</span>
|
<span v-if="item.sub_my && item.sub_my.length > 0">+{{item.sub_my.length}}</span>
|
||||||
|
<!--任务描述-->
|
||||||
{{item.name}}
|
{{item.name}}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="item.desc" class="item-icon">
|
<div v-if="item.desc" class="item-icon">
|
||||||
@ -140,6 +145,13 @@ export default {
|
|||||||
this.$store.dispatch("openTask", task)
|
this.$store.dispatch("openTask", task)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
openMenu(task) {
|
||||||
|
const el = this.$refs[`taskMenu_${task.id}`];
|
||||||
|
if (el) {
|
||||||
|
el[0].show()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
expiresFormat(date) {
|
expiresFormat(date) {
|
||||||
return $A.countDownFormat(date, this.nowTime)
|
return $A.countDownFormat(date, this.nowTime)
|
||||||
},
|
},
|
||||||
|
68
resources/assets/js/store/actions.js
vendored
68
resources/assets/js/store/actions.js
vendored
@ -524,9 +524,6 @@ export default {
|
|||||||
if (typeof data.project_user === "undefined") {
|
if (typeof data.project_user === "undefined") {
|
||||||
data.project_user = []
|
data.project_user = []
|
||||||
}
|
}
|
||||||
if (typeof data.project_flow_item === "undefined") {
|
|
||||||
data.project_flow_item = []
|
|
||||||
}
|
|
||||||
state.cacheProjects.push(data);
|
state.cacheProjects.push(data);
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -857,6 +854,9 @@ export default {
|
|||||||
});
|
});
|
||||||
} else if ($A.isJson(data)) {
|
} else if ($A.isJson(data)) {
|
||||||
data._time = $A.Time();
|
data._time = $A.Time();
|
||||||
|
if (data.flow_item_name && data.flow_item_name.indexOf("|") !== -1) {
|
||||||
|
[data.flow_item_status, data.flow_item_name] = data.flow_item_name.split("|")
|
||||||
|
}
|
||||||
let index = state.cacheTasks.findIndex(({id}) => id == data.id);
|
let index = state.cacheTasks.findIndex(({id}) => id == data.id);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
state.cacheTasks.splice(index, 1, Object.assign({}, state.cacheTasks[index], data));
|
state.cacheTasks.splice(index, 1, Object.assign({}, state.cacheTasks[index], data));
|
||||||
@ -1135,7 +1135,7 @@ export default {
|
|||||||
reject({msg: 'Parameter error'});
|
reject({msg: 'Parameter error'});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dispatch("taskLoadAdd", task_id)
|
dispatch("taskLoadStart", task_id)
|
||||||
dispatch("call", {
|
dispatch("call", {
|
||||||
url: 'project/task/remove',
|
url: 'project/task/remove',
|
||||||
data: {
|
data: {
|
||||||
@ -1143,12 +1143,12 @@ export default {
|
|||||||
},
|
},
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
dispatch("forgetTask", task_id)
|
dispatch("forgetTask", task_id)
|
||||||
dispatch("taskLoadSub", task_id)
|
dispatch("taskLoadEnd", task_id)
|
||||||
resolve(result)
|
resolve(result)
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
dispatch("getTaskOne", task_id);
|
dispatch("getTaskOne", task_id);
|
||||||
dispatch("taskLoadSub", task_id)
|
dispatch("taskLoadEnd", task_id)
|
||||||
reject(e)
|
reject(e)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -1167,7 +1167,7 @@ export default {
|
|||||||
reject({msg: 'Parameter error'});
|
reject({msg: 'Parameter error'});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dispatch("taskLoadAdd", task_id)
|
dispatch("taskLoadStart", task_id)
|
||||||
dispatch("call", {
|
dispatch("call", {
|
||||||
url: 'project/task/archived',
|
url: 'project/task/archived',
|
||||||
data: {
|
data: {
|
||||||
@ -1175,12 +1175,12 @@ export default {
|
|||||||
},
|
},
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
dispatch("forgetTask", task_id)
|
dispatch("forgetTask", task_id)
|
||||||
dispatch("taskLoadSub", task_id)
|
dispatch("taskLoadEnd", task_id)
|
||||||
resolve(result)
|
resolve(result)
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
dispatch("getTaskOne", task_id)
|
dispatch("getTaskOne", task_id)
|
||||||
dispatch("taskLoadSub", task_id)
|
dispatch("taskLoadEnd", task_id)
|
||||||
reject(e)
|
reject(e)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -1378,18 +1378,18 @@ export default {
|
|||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
const post = $A.cloneJSON($A.date2string(data));
|
const post = $A.cloneJSON($A.date2string(data));
|
||||||
//
|
//
|
||||||
dispatch("taskLoadAdd", post.task_id)
|
dispatch("taskLoadStart", post.task_id)
|
||||||
dispatch("call", {
|
dispatch("call", {
|
||||||
url: 'project/task/update',
|
url: 'project/task/update',
|
||||||
data: post,
|
data: post,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
dispatch("taskLoadSub", post.task_id)
|
dispatch("taskLoadEnd", post.task_id)
|
||||||
dispatch("saveTask", result.data)
|
dispatch("saveTask", result.data)
|
||||||
resolve(result)
|
resolve(result)
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
dispatch("taskLoadSub", post.task_id)
|
dispatch("taskLoadEnd", post.task_id)
|
||||||
dispatch("getTaskOne", post.task_id);
|
dispatch("getTaskOne", post.task_id);
|
||||||
reject(e)
|
reject(e)
|
||||||
});
|
});
|
||||||
@ -1401,7 +1401,7 @@ export default {
|
|||||||
* @param state
|
* @param state
|
||||||
* @param task_id
|
* @param task_id
|
||||||
*/
|
*/
|
||||||
taskLoadAdd({state}, task_id) {
|
taskLoadStart({state}, task_id) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const load = state.taskLoading.find(({id}) => id == task_id)
|
const load = state.taskLoading.find(({id}) => id == task_id)
|
||||||
if (!load) {
|
if (!load) {
|
||||||
@ -1420,7 +1420,7 @@ export default {
|
|||||||
* @param state
|
* @param state
|
||||||
* @param task_id
|
* @param task_id
|
||||||
*/
|
*/
|
||||||
taskLoadSub({state}, task_id) {
|
taskLoadEnd({state}, task_id) {
|
||||||
const load = state.taskLoading.find(({id}) => id == task_id)
|
const load = state.taskLoading.find(({id}) => id == task_id)
|
||||||
if (!load) {
|
if (!load) {
|
||||||
state.taskLoading.push({
|
state.taskLoading.push({
|
||||||
@ -1432,6 +1432,46 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取任务流程信息
|
||||||
|
* @param state
|
||||||
|
* @param dispatch
|
||||||
|
* @param task_id
|
||||||
|
* @returns {Promise<unknown>}
|
||||||
|
*/
|
||||||
|
getTaskFlow({state, dispatch}, task_id) {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
dispatch("call", {
|
||||||
|
url: 'project/task/flow',
|
||||||
|
data: {
|
||||||
|
task_id: task_id
|
||||||
|
},
|
||||||
|
}).then(result => {
|
||||||
|
let {data} = result
|
||||||
|
data.turns.some(item => {
|
||||||
|
let index = state.taskFlowItems.findIndex(({id}) => id == item.id);
|
||||||
|
if (index > -1) {
|
||||||
|
state.taskFlowItems.splice(index, 1, item);
|
||||||
|
} else {
|
||||||
|
state.taskFlowItems.push(item);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//
|
||||||
|
delete data.turns;
|
||||||
|
let index = state.taskFlows.findIndex(({task_id}) => task_id == data.task_id);
|
||||||
|
if (index > -1) {
|
||||||
|
state.taskFlows.splice(index, 1, data);
|
||||||
|
} else {
|
||||||
|
state.taskFlows.push(data);
|
||||||
|
}
|
||||||
|
resolve(result)
|
||||||
|
}).catch(e => {
|
||||||
|
console.error(e);
|
||||||
|
reject(e);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取任务优先级预设数据
|
* 获取任务优先级预设数据
|
||||||
* @param state
|
* @param state
|
||||||
|
4
resources/assets/js/store/getters.js
vendored
4
resources/assets/js/store/getters.js
vendored
@ -84,6 +84,10 @@ export default {
|
|||||||
end_at: task.end_at,
|
end_at: task.end_at,
|
||||||
complete_at: task.complete_at,
|
complete_at: task.complete_at,
|
||||||
|
|
||||||
|
flow_item_id: task.flow_item_id,
|
||||||
|
flow_item_name: task.flow_item_name,
|
||||||
|
flow_item_status: task.flow_item_status,
|
||||||
|
|
||||||
sub_top: true,
|
sub_top: true,
|
||||||
sub_my: [],
|
sub_my: [],
|
||||||
});
|
});
|
||||||
|
6
resources/assets/js/store/state.js
vendored
6
resources/assets/js/store/state.js
vendored
@ -67,8 +67,14 @@ state.taskId = 0;
|
|||||||
state.taskContents = [];
|
state.taskContents = [];
|
||||||
state.taskFiles = [];
|
state.taskFiles = [];
|
||||||
state.taskLogs = [];
|
state.taskLogs = [];
|
||||||
|
|
||||||
|
// 任务等待状态
|
||||||
state.taskLoading = [];
|
state.taskLoading = [];
|
||||||
|
|
||||||
|
// 任务流程信息
|
||||||
|
state.taskFlows = [];
|
||||||
|
state.taskFlowItems = [];
|
||||||
|
|
||||||
// 任务优先级
|
// 任务优先级
|
||||||
state.taskPriority = [];
|
state.taskPriority = [];
|
||||||
|
|
||||||
|
6
resources/assets/sass/element.scss
vendored
6
resources/assets/sass/element.scss
vendored
@ -31,12 +31,6 @@ $--dropdown-menuItem-hover-color: #606266;
|
|||||||
color: #f00;
|
color: #f00;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.hover-del {
|
|
||||||
color: #f00;
|
|
||||||
> i {
|
|
||||||
color: #f00;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,7 +352,35 @@
|
|||||||
.task-title {
|
.task-title {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding-top: 1px;
|
padding-top: 1px;
|
||||||
|
> span {
|
||||||
|
float: left;
|
||||||
|
font-size: 12px;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 18px;
|
||||||
|
padding: 0 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
color: #8bcf70;
|
||||||
|
border: 1px solid #8bcf70;
|
||||||
|
margin-right: 4px;
|
||||||
|
text-align: center;
|
||||||
|
&.start {
|
||||||
|
background-color: rgba(38, 38, 38, 0.05);
|
||||||
|
border-color: rgba(38, 38, 38, 0.05);
|
||||||
|
color: #595959;
|
||||||
|
}
|
||||||
|
&.progress {
|
||||||
|
background-color: rgba(27, 154, 238, 0.1);
|
||||||
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
|
color: #0171c2;
|
||||||
|
}
|
||||||
|
&.end {
|
||||||
|
background-color: rgba(21, 173, 49, 0.1);
|
||||||
|
border-color: rgba(21, 173, 49, 0.1);
|
||||||
|
color: #038a24;
|
||||||
|
}
|
||||||
|
}
|
||||||
> pre {
|
> pre {
|
||||||
|
display: block;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
@ -682,16 +710,32 @@
|
|||||||
> span {
|
> span {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
|
min-width: 20px;
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
padding: 0 3px;
|
padding: 0 2px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
color: #8bcf70;
|
color: #8bcf70;
|
||||||
background-color: rgba(139, 207, 112, 0);
|
|
||||||
border: 1px solid #8bcf70;
|
border: 1px solid #8bcf70;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
margin-top: 3px;
|
margin-top: 3px;
|
||||||
margin-right: 3px;
|
margin-right: 3px;
|
||||||
|
text-align: center;
|
||||||
|
&.start {
|
||||||
|
background-color: rgba(38, 38, 38, 0.05);
|
||||||
|
border-color: rgba(38, 38, 38, 0.05);
|
||||||
|
color: #595959;
|
||||||
|
}
|
||||||
|
&.progress {
|
||||||
|
background-color: rgba(27, 154, 238, 0.1);
|
||||||
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
|
color: #0171c2;
|
||||||
|
}
|
||||||
|
&.end {
|
||||||
|
background-color: rgba(21, 173, 49, 0.1);
|
||||||
|
border-color: rgba(21, 173, 49, 0.1);
|
||||||
|
color: #038a24;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.item-icons {
|
.item-icons {
|
||||||
|
@ -45,6 +45,37 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.flow {
|
||||||
|
margin-left: 18px;
|
||||||
|
margin-right: -3px;
|
||||||
|
> span {
|
||||||
|
font-size: 14px;
|
||||||
|
height: 26px;
|
||||||
|
line-height: 24px;
|
||||||
|
padding: 0 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #8bcf70;
|
||||||
|
border: 1px solid #8bcf70;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
&.start {
|
||||||
|
background-color: rgba(38, 38, 38, 0.05);
|
||||||
|
border-color: rgba(38, 38, 38, 0.05);
|
||||||
|
color: #595959;
|
||||||
|
}
|
||||||
|
&.progress {
|
||||||
|
background-color: rgba(27, 154, 238, 0.1);
|
||||||
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
|
color: #0171c2;
|
||||||
|
}
|
||||||
|
&.end {
|
||||||
|
background-color: rgba(21, 173, 49, 0.1);
|
||||||
|
border-color: rgba(21, 173, 49, 0.1);
|
||||||
|
color: #038a24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.nav {
|
.nav {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -54,6 +85,9 @@
|
|||||||
width: 0;
|
width: 0;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
> p {
|
> p {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -263,11 +297,12 @@
|
|||||||
.subtask-time {
|
.subtask-time {
|
||||||
.clock {
|
.clock {
|
||||||
transform: translateX(0);
|
transform: translateX(0);
|
||||||
opacity: 0.8;
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.subtask-icon {
|
.subtask-icon {
|
||||||
|
padding-top: 1px;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 26px;
|
height: 26px;
|
||||||
line-height: 26px;
|
line-height: 26px;
|
||||||
@ -276,9 +311,39 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
.subtask-flow {
|
||||||
|
> span {
|
||||||
|
font-size: 12px;
|
||||||
|
height: 18px;
|
||||||
|
min-width: 20px;
|
||||||
|
line-height: 16px;
|
||||||
|
padding: 0 2px;
|
||||||
|
border-radius: 3px;
|
||||||
|
color: #8bcf70;
|
||||||
|
border: 1px solid #8bcf70;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 3px;
|
||||||
|
text-align: center;
|
||||||
|
&.start {
|
||||||
|
background-color: rgba(38, 38, 38, 0.05);
|
||||||
|
border-color: rgba(38, 38, 38, 0.05);
|
||||||
|
color: #595959;
|
||||||
|
}
|
||||||
|
&.progress {
|
||||||
|
background-color: rgba(27, 154, 238, 0.1);
|
||||||
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
|
color: #0171c2;
|
||||||
|
}
|
||||||
|
&.end {
|
||||||
|
background-color: rgba(21, 173, 49, 0.1);
|
||||||
|
border-color: rgba(21, 173, 49, 0.1);
|
||||||
|
color: #038a24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.subtask-name {
|
.subtask-name {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
margin-right: 16px;
|
margin-right: 8px;
|
||||||
display: flex;
|
display: flex;
|
||||||
.ivu-input {
|
.ivu-input {
|
||||||
margin: -2px 0;
|
margin: -2px 0;
|
||||||
|
@ -28,21 +28,119 @@
|
|||||||
|
|
||||||
.task-menu-more-dropdown {
|
.task-menu-more-dropdown {
|
||||||
> li {
|
> li {
|
||||||
.item {
|
&.task-menu-more-warp {
|
||||||
display: flex;
|
list-style: none;
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
> i {
|
> ul {
|
||||||
width: 18px;
|
max-height: 320px;
|
||||||
height: 18px;
|
overflow: auto;
|
||||||
line-height: 18px;
|
|
||||||
font-size: 18px;
|
|
||||||
margin-right: 8px;
|
|
||||||
padding: 0;
|
|
||||||
color: #bbbbbb;
|
|
||||||
|
|
||||||
&.ivu-icon {
|
&::-webkit-scrollbar {
|
||||||
font-size: 16px;
|
display: none
|
||||||
|
}
|
||||||
|
|
||||||
|
> li {
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
> i {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
line-height: 18px;
|
||||||
|
font-size: 18px;
|
||||||
|
margin-right: 8px;
|
||||||
|
padding: 0;
|
||||||
|
color: #bbbbbb;
|
||||||
|
|
||||||
|
&.ivu-icon {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.flow {
|
||||||
|
padding: 4px 0;
|
||||||
|
|
||||||
|
> i {
|
||||||
|
margin-right: 3px;
|
||||||
|
|
||||||
|
&.check {
|
||||||
|
color: $primary-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.flow-name {
|
||||||
|
border-radius: 4px;
|
||||||
|
white-space: nowrap;
|
||||||
|
padding: 0 5px;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 12px;
|
||||||
|
background: #f4f4f4;
|
||||||
|
color: #595959;
|
||||||
|
|
||||||
|
&.start {
|
||||||
|
background-color: rgba(38, 38, 38, 0.05);
|
||||||
|
border-color: rgba(38, 38, 38, 0.05);
|
||||||
|
color: #595959;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.progress {
|
||||||
|
background-color: rgba(27, 154, 238, 0.1);
|
||||||
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
|
color: #0171c2;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.end {
|
||||||
|
background-color: rgba(21, 173, 49, 0.1);
|
||||||
|
border-color: rgba(21, 173, 49, 0.1);
|
||||||
|
color: #038a24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.load-flow {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 8px;
|
||||||
|
|
||||||
|
.load-flow-warp {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.medium {
|
||||||
|
> ul {
|
||||||
|
> li {
|
||||||
|
.flow {
|
||||||
|
.flow-name {
|
||||||
|
height: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
padding: 0 7px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.large {
|
||||||
|
> ul {
|
||||||
|
> li {
|
||||||
|
.flow {
|
||||||
|
.flow-name {
|
||||||
|
font-size: 13px;
|
||||||
|
height: 30px;
|
||||||
|
line-height: 30px;
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
24
resources/assets/sass/pages/page-dashboard.scss
vendored
24
resources/assets/sass/pages/page-dashboard.scss
vendored
@ -136,16 +136,32 @@
|
|||||||
> span {
|
> span {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
|
min-width: 20px;
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
padding: 0 3px;
|
padding: 0 2px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
color: #8bcf70;
|
color: #8bcf70;
|
||||||
background-color: rgba(139, 207, 112, 0);
|
|
||||||
border: 1px solid #8bcf70;
|
border: 1px solid #8bcf70;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
margin-top: 2px;
|
margin-top: 3px;
|
||||||
margin-right: 2px;
|
margin-right: 3px;
|
||||||
|
text-align: center;
|
||||||
|
&.start {
|
||||||
|
background-color: rgba(38, 38, 38, 0.05);
|
||||||
|
border-color: rgba(38, 38, 38, 0.05);
|
||||||
|
color: #595959;
|
||||||
|
}
|
||||||
|
&.progress {
|
||||||
|
background-color: rgba(27, 154, 238, 0.1);
|
||||||
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
|
color: #0171c2;
|
||||||
|
}
|
||||||
|
&.end {
|
||||||
|
background-color: rgba(21, 173, 49, 0.1);
|
||||||
|
border-color: rgba(21, 173, 49, 0.1);
|
||||||
|
color: #038a24;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.item-icon {
|
.item-icon {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user