feat: 任务流转自动负责人支持转让模式
This commit is contained in:
parent
b7417f41c5
commit
e7ae86e261
@ -10,7 +10,7 @@ if (!function_exists('asset_main')) {
|
||||
if (!function_exists('seeders_at')) {
|
||||
function seeders_at($data)
|
||||
{
|
||||
$diff = time() - strtotime("2021-07-01");
|
||||
$diff = time() - strtotime("2021-07-02");
|
||||
$time = strtotime($data) + $diff;
|
||||
return date("Y-m-d H:i:s", $time);
|
||||
}
|
||||
|
@ -1405,6 +1405,60 @@ class ProjectController extends AbstractController
|
||||
return Base::retSuccess('删除成功', ['id' => $task->id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/project/task/resetfromlog 29. 根据日志重置任务
|
||||
*
|
||||
* @apiDescription 需要token身份(限:项目、任务负责人)
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup project
|
||||
* @apiName task__resetfromlog
|
||||
*
|
||||
* @apiParam {Number} task_id 任务ID
|
||||
*
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
* @apiSuccess {Object} data 返回数据
|
||||
*/
|
||||
public function task__resetfromlog()
|
||||
{
|
||||
User::auth();
|
||||
//
|
||||
$id = intval(Request::input('id'));
|
||||
//
|
||||
$projectLog = ProjectLog::find($id);
|
||||
if (empty($projectLog) || empty($projectLog->task_id)) {
|
||||
return Base::retError('记录不存在');
|
||||
}
|
||||
$record = $projectLog->record;
|
||||
//
|
||||
$task = ProjectTask::userTask($projectLog->task_id, null, true);
|
||||
//
|
||||
if ($record['type'] == 'flow') {
|
||||
$newFlowItem = ProjectFlowItem::find(intval($record['flow_item_id']));
|
||||
if (empty($newFlowItem)) {
|
||||
return Base::retError('流程不存在或已被删除');
|
||||
}
|
||||
return AbstractModel::transaction(function() use ($record, $task, $newFlowItem) {
|
||||
$data = array_intersect_key($record, array_flip(['complete_at', 'owner', 'assist']));
|
||||
$currentFlowItem = $task->flow_item_id ? ProjectFlowItem::find($task->flow_item_id) : null;
|
||||
// 更新任务
|
||||
$task->flow_item_id = $newFlowItem->id;
|
||||
$task->flow_item_name = $newFlowItem->name;
|
||||
$updateMarking = [];
|
||||
$task->addLog("重置{任务}状态:{$currentFlowItem?->name} => {$newFlowItem->name}");
|
||||
$task->updateTask($data, $updateMarking);
|
||||
//
|
||||
$data = ProjectTask::oneTask($task->id)->toArray();
|
||||
$data['update_marking'] = $updateMarking ?: json_decode('{}');
|
||||
$task->pushMsg('update', $data);
|
||||
//
|
||||
return Base::retSuccess('重置成功', $data);
|
||||
});
|
||||
} else {
|
||||
return Base::retError('暂不支持此操作');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/project/task/flow 29. 任务工作流信息
|
||||
*
|
||||
@ -1574,6 +1628,7 @@ class ProjectController extends AbstractController
|
||||
'sort' => intval($item['sort']),
|
||||
'turns' => $turns,
|
||||
'userids' => $userids,
|
||||
'usertype' => $item['usertype'],
|
||||
]);
|
||||
if ($flow) {
|
||||
$ids[] = $flow->id;
|
||||
|
@ -14,6 +14,7 @@ use App\Module\Base;
|
||||
* @property string|null $status 状态
|
||||
* @property array $turns 可流转
|
||||
* @property array $userids 自动负责人ID
|
||||
* @property string|null $usertype 流转模式
|
||||
* @property int|null $sort 排序
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
@ -31,6 +32,7 @@ use App\Module\Base;
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereTurns($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereUserids($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereUsertype($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class ProjectFlowItem extends AbstractModel
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Module\Base;
|
||||
|
||||
/**
|
||||
* App\Models\ProjectLog
|
||||
*
|
||||
@ -11,6 +13,7 @@ namespace App\Models;
|
||||
* @property int|null $task_id 项目ID
|
||||
* @property int|null $userid 会员ID
|
||||
* @property string|null $detail 详细信息
|
||||
* @property string|null $record 记录数据
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @property-read \App\Models\User|null $user
|
||||
@ -22,6 +25,7 @@ namespace App\Models;
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereDetail($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereProjectId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereRecord($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereTaskId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereUserid($value)
|
||||
@ -30,6 +34,18 @@ namespace App\Models;
|
||||
class ProjectLog extends AbstractModel
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return array
|
||||
*/
|
||||
public function getRecordAttribute($value)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
return $value;
|
||||
}
|
||||
return Base::json2array($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
||||
*/
|
||||
|
@ -495,6 +495,11 @@ class ProjectTask extends AbstractModel
|
||||
if ($this->flow_item_id == $data['flow_item_id']) {
|
||||
throw new ApiException('任务状态未发生改变');
|
||||
}
|
||||
$recordData = [
|
||||
'type' => 'flow',
|
||||
'flow_item_id' => $this->flow_item_id,
|
||||
'flow_item_name' => $this->flow_item_name,
|
||||
];
|
||||
$currentFlowItem = null;
|
||||
$newFlowItem = ProjectFlowItem::whereProjectId($this->project_id)->find(intval($data['flow_item_id']));
|
||||
if (empty($newFlowItem) || empty($newFlowItem->projectFlow)) {
|
||||
@ -510,24 +515,38 @@ class ProjectTask extends AbstractModel
|
||||
if ($newFlowItem->status == 'end') {
|
||||
// 判断自动完成
|
||||
if (!$this->complete_at) {
|
||||
$recordData['complete_at'] = $this->complete_at;
|
||||
$data['complete_at'] = date("Y-m-d H:i");
|
||||
}
|
||||
} else {
|
||||
// 判断自动打开
|
||||
if ($this->complete_at) {
|
||||
$recordData['complete_at'] = $this->complete_at;
|
||||
$data['complete_at'] = false;
|
||||
}
|
||||
}
|
||||
if ($newFlowItem->userids) {
|
||||
// 判断自动添加负责人
|
||||
if (!Arr::exists($data, 'owner')) {
|
||||
$data['owner'] = $this->taskUser->pluck('userid')->toArray();
|
||||
$recordData['owner'] = $data['owner'] = $this->taskUser->where('owner', 1)->pluck('userid')->toArray();
|
||||
if ($newFlowItem->usertype == "replace") {
|
||||
// 流转模式
|
||||
if ($this->parent_id === 0) {
|
||||
$recordData['assist'] = $data['assist'] = $this->taskUser->where('owner', 0)->pluck('userid')->toArray();
|
||||
$data['assist'] = array_merge($data['assist'], $data['owner']);
|
||||
}
|
||||
$data['owner'] = $newFlowItem->userids;
|
||||
} else {
|
||||
// 添加模式
|
||||
$data['owner'] = array_merge($data['owner'], $newFlowItem->userids);
|
||||
}
|
||||
$data['owner'] = array_values(array_unique($data['owner']));
|
||||
if (isset($data['assist'])) {
|
||||
$data['assist'] = array_values(array_unique(array_diff($data['assist'], $data['owner'])));
|
||||
}
|
||||
$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}");
|
||||
$this->addLog("修改{任务}状态:{$currentFlowItem?->name} => {$newFlowItem->name}", 0, $recordData);
|
||||
}
|
||||
// 状态
|
||||
if (Arr::exists($data, 'complete_at')) {
|
||||
@ -559,7 +578,7 @@ class ProjectTask extends AbstractModel
|
||||
}
|
||||
// 负责人
|
||||
if (Arr::exists($data, 'owner')) {
|
||||
$count = $this->taskUser->count();
|
||||
$count = $this->taskUser->where('owner', 1)->count();
|
||||
$array = [];
|
||||
$owner = is_array($data['owner']) ? $data['owner'] : [$data['owner']];
|
||||
if (count($owner) > 10) {
|
||||
@ -947,18 +966,23 @@ class ProjectTask extends AbstractModel
|
||||
* 添加任务日志
|
||||
* @param string $detail
|
||||
* @param int $userid
|
||||
* @param $record
|
||||
* @return ProjectLog
|
||||
*/
|
||||
public function addLog($detail, $userid = 0)
|
||||
public function addLog($detail, $userid = 0, $record = null)
|
||||
{
|
||||
$detail = str_replace("{任务}", $this->parent_id > 0 ? "子任务" : "任务", $detail);
|
||||
$log = ProjectLog::createInstance([
|
||||
$array = [
|
||||
'project_id' => $this->project_id,
|
||||
'column_id' => $this->column_id,
|
||||
'task_id' => $this->parent_id ?: $this->id,
|
||||
'userid' => $userid ?: User::userid(),
|
||||
'detail' => $detail,
|
||||
]);
|
||||
];
|
||||
if ($record) {
|
||||
$array['record'] = $record;
|
||||
}
|
||||
$log = ProjectLog::createInstance($array);
|
||||
$log->save();
|
||||
return $log;
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ use Carbon\Carbon;
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereUserid($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereUserimg($value)
|
||||
* @mixin \Eloquent
|
||||
* @method static \Database\Factories\UserFactory factory(...$parameters)
|
||||
*/
|
||||
class User extends AbstractModel
|
||||
{
|
||||
|
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
use App\Models\ProjectFlowItem;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class ProjectFlowItemsAddUsertype extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$isAdd = false;
|
||||
Schema::table('project_flow_items', function (Blueprint $table) use (&$isAdd) {
|
||||
if (!Schema::hasColumn('project_flow_items', 'usertype')) {
|
||||
$isAdd = true;
|
||||
$table->string('usertype', 10)->nullable()->default('')->after('userids')->comment('流转模式');
|
||||
}
|
||||
});
|
||||
if ($isAdd) {
|
||||
ProjectFlowItem::where("usertype", "")->update([
|
||||
'usertype' => 'add',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('project_flow_items', function (Blueprint $table) {
|
||||
$table->dropColumn("usertype");
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class ProjectLogsAddRecord extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('project_logs', function (Blueprint $table) {
|
||||
if (!Schema::hasColumn('project_logs', 'record')) {
|
||||
$table->text('record')->nullable()->after('detail')->comment('记录数据');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('project_logs', function (Blueprint $table) {
|
||||
$table->dropColumn("record");
|
||||
});
|
||||
}
|
||||
}
|
@ -14,6 +14,9 @@
|
||||
<div class="log-summary">
|
||||
<span class="log-creator">{{item.user ? item.user.nickname : $L('系统')}}</span>
|
||||
<span class="log-text">{{$L(item.detail)}}</span>
|
||||
<span v-if="operationList(item).length > 0" class="log-operation">
|
||||
<Button v-for="(op, oi) in operationList(item)" :key="oi" size="small" @click="onOperation(op)">{{op.button}}</Button>
|
||||
</span>
|
||||
<span class="log-time">{{item.time.ymd}} {{item.time.segment}} {{item.time.hi}}</span></div>
|
||||
</TimelineItem>
|
||||
</Timeline>
|
||||
@ -123,6 +126,44 @@ export default {
|
||||
this.listPage++;
|
||||
this.getLists();
|
||||
},
|
||||
|
||||
operationList({id, record}) {
|
||||
let list = [];
|
||||
if (!$A.isJson(record)) {
|
||||
return list
|
||||
}
|
||||
if (this.taskId > 0 && record.type === 'flow') {
|
||||
list.push({
|
||||
id,
|
||||
button: '重置',
|
||||
content: `确定重置为【${record.flow_item_name}】吗?`,
|
||||
})
|
||||
}
|
||||
return list;
|
||||
},
|
||||
|
||||
onOperation(item) {
|
||||
$A.modalConfirm({
|
||||
content: item.content,
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
this.$store.dispatch("call", {
|
||||
url: 'project/task/resetfromlog',
|
||||
data: {
|
||||
id: item.id
|
||||
}
|
||||
}).then(({data, msg}) => {
|
||||
$A.messageSuccess(msg);
|
||||
this.$Modal.remove();
|
||||
this.$store.dispatch("saveTask", data);
|
||||
this.getLists(true);
|
||||
}).catch(({msg}) => {
|
||||
$A.modalError(msg, 301);
|
||||
this.$Modal.remove();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -144,7 +144,14 @@
|
||||
<Form :model="userData" label-width="auto" @submit.native.prevent>
|
||||
<FormItem prop="userids" :label="userData.name">
|
||||
<UserInput v-if="userShow" v-model="userData.userids" :project-id="projectId" :multiple-max="5" :placeholder="$L('选择成员')"/>
|
||||
<div class="form-tip">{{$L('任务流转到此流程时自动添加负责人')}}</div>
|
||||
</FormItem>
|
||||
<FormItem prop="usertype" :label="$L('流转模式')">
|
||||
<RadioGroup v-model="userData.usertype">
|
||||
<Radio label="add">{{$L('添加模式')}}</Radio>
|
||||
<Radio label="replace">{{$L('流转模式')}}</Radio>
|
||||
</RadioGroup>
|
||||
<div v-if="userData.usertype=='replace'" class="form-tip">{{$L('流转到此流程时改变负责人,原本的负责人移至协助人员。')}}</div>
|
||||
<div v-else class="form-tip">{{$L('流转到此流程时添加负责人。')}}</div>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer" class="adaption">
|
||||
@ -259,6 +266,7 @@ export default {
|
||||
"status": "start",
|
||||
"turns": [-10, -11, -12, -13],
|
||||
"userids": [],
|
||||
"usertype": 'add',
|
||||
},
|
||||
{
|
||||
"id": -11,
|
||||
@ -266,6 +274,7 @@ export default {
|
||||
"status": "progress",
|
||||
"turns": [-10, -11, -12, -13],
|
||||
"userids": [],
|
||||
"usertype": 'add',
|
||||
},
|
||||
{
|
||||
"id": -12,
|
||||
@ -273,6 +282,7 @@ export default {
|
||||
"status": "end",
|
||||
"turns": [-10, -11, -12, -13],
|
||||
"userids": [],
|
||||
"usertype": 'add',
|
||||
},
|
||||
{
|
||||
"id": -13,
|
||||
@ -280,6 +290,7 @@ export default {
|
||||
"status": "end",
|
||||
"turns": [-10, -11, -12, -13],
|
||||
"userids": [],
|
||||
"usertype": 'add',
|
||||
}
|
||||
]
|
||||
})
|
||||
@ -331,6 +342,7 @@ export default {
|
||||
this.$set(this.userData, 'id', item.id);
|
||||
this.$set(this.userData, 'name', item.name);
|
||||
this.$set(this.userData, 'userids', item.userids);
|
||||
this.$set(this.userData, 'usertype', item.usertype);
|
||||
this.userShow = true;
|
||||
break;
|
||||
|
||||
@ -350,6 +362,7 @@ export default {
|
||||
let item = data.project_flow_item.find(item => item.id == this.userData.id)
|
||||
if (item) {
|
||||
this.$set(item, 'userids', this.userData.userids)
|
||||
this.$set(item, 'usertype', this.userData.usertype)
|
||||
}
|
||||
})
|
||||
},
|
||||
@ -395,6 +408,7 @@ export default {
|
||||
status: 'end',
|
||||
turns,
|
||||
userids: [],
|
||||
usertype: 'add',
|
||||
})
|
||||
data.project_flow_item.some(item => {
|
||||
item.turns.push(id)
|
||||
|
@ -88,6 +88,14 @@
|
||||
.log-text {
|
||||
color: rgba(0,0,0,.54);
|
||||
}
|
||||
.log-operation {
|
||||
> button {
|
||||
font-size: 12px;
|
||||
}
|
||||
> button + button {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
.log-time {
|
||||
color: rgba(0,0,0,.3);
|
||||
font-size: 12px;
|
||||
|
Loading…
x
Reference in New Issue
Block a user